@aglyn/plugins-crm 1.0.0-beta.221 → 1.0.0-beta.223
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-next-activity-column.js +1 -1
- package/src/lib/components/crm-next-activity-column.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/pipeline-card.js +2 -1
- package/src/lib/components/reports/pipeline-card.js.map +1 -1
- 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 +97 -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 +17 -2
- 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-next-activity.d.ts +107 -0
- package/src/lib/model/crm-next-activity.js +140 -0
- package/src/lib/model/crm-next-activity.js.map +1 -0
- package/src/lib/model/crm-recipes.d.ts +40 -0
- package/src/lib/model/crm-recipes.js +259 -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/crm-task-reminders.d.ts +152 -0
- package/src/lib/model/crm-task-reminders.js +161 -0
- package/src/lib/model/crm-task-reminders.js.map +1 -0
- 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/next-activity.d.ts +1 -1
- package/src/lib/model/next-activity.js.map +1 -1
- 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 +78 -34
- 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 +188 -0
- package/src/lib/server/assign-contact-owner.js +446 -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 +140 -0
- package/src/lib/server/automation-steps.js +669 -0
- package/src/lib/server/automation-steps.js.map +1 -0
- package/src/lib/server/capture-contact.d.ts +17 -0
- package/src/lib/server/capture-contact.js +95 -26
- 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-email-activity.d.ts +118 -0
- package/src/lib/server/crm-email-activity.js +148 -0
- package/src/lib/server/crm-email-activity.js.map +1 -0
- package/src/lib/server/crm-inbound-email.js +1 -1
- package/src/lib/server/crm-inbound-email.js.map +1 -1
- package/src/lib/server/crm-next-activity.d.ts +74 -0
- package/src/lib/server/crm-next-activity.js +194 -0
- package/src/lib/server/crm-next-activity.js.map +1 -0
- 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/email-send.js +2 -1
- package/src/lib/server/email-send.js.map +1 -1
- 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 +23 -5
- package/src/lib/server/merge-contacts.js.map +1 -1
- package/src/lib/server/next-activity-routes.js +2 -1
- package/src/lib/server/next-activity-routes.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 +22 -8
- 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 +40 -3
- 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-reminders-route.js +2 -1
- package/src/lib/server/task-reminders-route.js.map +1 -1
- package/src/lib/server/task-routes.js +33 -17
- 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
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright 2026 Aglyn LLC
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/ /*==========================================
|
|
18
|
+
* LEADS ON THE TRANSFER FRAMEWORK (AGL-3528) — the server half of
|
|
19
|
+
* `crm.leads`.
|
|
20
|
+
*
|
|
21
|
+
* A lead is one person an organization's sites captured and nobody has
|
|
22
|
+
* qualified yet: one document per person (`personKey(email)`), seen by the
|
|
23
|
+
* sites that captured them. Every field a lead holds — its own profile of
|
|
24
|
+
* the person and their company as text, its status, owner, lead source,
|
|
25
|
+
* campaigns, notes and custom fields — is read for an export, and an import
|
|
26
|
+
* writes through the door every capture uses (`addHostLead`: the person
|
|
27
|
+
* keyed by address, the lead ceiling, the capturing site's scope), then the
|
|
28
|
+
* working state the old leads import wrote beside it.
|
|
29
|
+
*
|
|
30
|
+
* A lead is QUALIFIED only by converting it, which makes the contact, the
|
|
31
|
+
* company and the deal; a file may set any other status. Do not call is
|
|
32
|
+
* turned on by a file and never off, and the name follows the first and
|
|
33
|
+
* last names once either is set — the rules the lead page keeps.
|
|
34
|
+
*=========================================*/ import { checkVisitorRecordCeiling, CONTACT_EXTRA_PHONE_FIELDS, CRM_LEAD_STATUS_PICKLIST, CRM_LEAD_STATUSES, crmLeadComposedName, crmLeadStatusLabel, LEADS_MAX_PER_HOST, normalizeCompanyWebsite, normalizeCrmLeadTags, normalizePhone, personKey, resolveCrmLeadStatusWrite } from "@aglyn/aglyn/server";
|
|
35
|
+
import { CONTACT_SOURCE_LABELS } from "@aglyn/aglyn/app-utils/contacts";
|
|
36
|
+
import { buildTransferPlan, matchLookupKey, planTransferUndo, TRANSFER_ID_FIELD } from "@aglyn/aglyn/data-transfer";
|
|
37
|
+
import { addHostLeadOutcome, restampCrmListFieldsAt } from "@aglyn/tenant-data-admin";
|
|
38
|
+
import { FieldValue } from "firebase-admin/firestore";
|
|
39
|
+
import { judgeLeadPicklistPatch, readLeadPicklists } from "../server/lead-picklists.js";
|
|
40
|
+
import { readLeadSourcePicklist, resolveLeadSourceWrite } from "../server/lead-source-picklist.js";
|
|
41
|
+
import { readCrmPicklist } from "../server/read-picklist.js";
|
|
42
|
+
import { LEAD_ALIASES } from "./aliases.js";
|
|
43
|
+
import { addCrmPicklistValues, addressFromValues, addressValues, campaignDirectory, countCrmExport, crmCustomDefinitions, crmMemberEmails, crmMembersTarget, crmPicklistLists, crmTransferEnv, customTransferValues, customWriteValues, eachWithinBudget, failureMessage, holdBackChanges, isoOf, lookupById, lookupResult, pickValues, plannedValues, readCrmExportPage, requireCrmSuite, requireSite, textOf, TransferEngineError, visibleIn } from "./common.js";
|
|
44
|
+
import { CRM_MEMBERS_TARGET, CRM_TIMESTAMP_FIELDS, crmCustomTransferFields, LEAD_TRANSFER_DERIVED, LEAD_TRANSFER_FIELDS, LEAD_TRANSFER_GROUPS } from "./fields.js";
|
|
45
|
+
const SUITE_ACT = 'Importing leads';
|
|
46
|
+
/** How an import names itself as a lead's source — the capture surface `import`. */ const LEAD_IMPORT_SOURCE = 'import';
|
|
47
|
+
/** The statuses a file may set: every one but Qualified, which a conversion alone sets. */ const FILE_STATUSES = CRM_LEAD_STATUSES.filter((status)=>status !== 'qualified');
|
|
48
|
+
const leadsOf = (env)=>env.orgRef.collection('leads');
|
|
49
|
+
/** How one capture surface reads in a file. */ function captureSourceLabel(source) {
|
|
50
|
+
if (source === 'signup') return 'Sign-up';
|
|
51
|
+
if (source === 'booking') return 'Booking';
|
|
52
|
+
if (source === 'import') return CONTACT_SOURCE_LABELS.import;
|
|
53
|
+
if (source === 'form') return CONTACT_SOURCE_LABELS.form;
|
|
54
|
+
// A lead entered by hand or over the REST API (AGL-3231).
|
|
55
|
+
if (source === 'manual') return 'Added by hand';
|
|
56
|
+
if (source === 'api') return 'API';
|
|
57
|
+
if (source.startsWith('form:')) return `Form ${source.slice('form:'.length)}`;
|
|
58
|
+
return source;
|
|
59
|
+
}
|
|
60
|
+
/** Every surface that produced a capture — the array, or the older single field. */ function captureSources(lead) {
|
|
61
|
+
const sources = lead['sources'];
|
|
62
|
+
if (Array.isArray(sources) && sources.length) {
|
|
63
|
+
return sources.map((source)=>String(source));
|
|
64
|
+
}
|
|
65
|
+
return typeof lead['source'] === 'string' && lead['source'] ? [
|
|
66
|
+
lead['source']
|
|
67
|
+
] : [];
|
|
68
|
+
}
|
|
69
|
+
/** One lead as values by field id. */ export function leadTransferValues(id, lead, statuses, definitions, names = {}) {
|
|
70
|
+
var _lead_submissionCount, _ref, _lead_firstSeenAtMs, _lead_lastSeenAtMs;
|
|
71
|
+
const text = (value)=>textOf(value) || null;
|
|
72
|
+
const revenue = typeof lead['annualRevenueCents'] === 'number' ? lead['annualRevenueCents'] : null;
|
|
73
|
+
const currency = String(lead['currency'] || 'usd').toUpperCase();
|
|
74
|
+
const ownerUid = text(lead['ownerUid']);
|
|
75
|
+
const campaignIds = Array.isArray(lead['campaignIds']) ? lead['campaignIds'].map(String) : [];
|
|
76
|
+
const captures = Number((_lead_submissionCount = lead['submissionCount']) != null ? _lead_submissionCount : 0);
|
|
77
|
+
return _extends({
|
|
78
|
+
// The name first: a record's label is the first text it holds.
|
|
79
|
+
name: text(lead['name']),
|
|
80
|
+
email: text(lead['email']),
|
|
81
|
+
salutation: text(lead['salutation']),
|
|
82
|
+
firstName: text(lead['firstName']),
|
|
83
|
+
lastName: text(lead['lastName']),
|
|
84
|
+
company: text(lead['company']),
|
|
85
|
+
jobTitle: text(lead['jobTitle']),
|
|
86
|
+
phone: text(lead['phone']),
|
|
87
|
+
mobilePhone: text(lead['mobilePhone']),
|
|
88
|
+
fax: text(lead['fax']),
|
|
89
|
+
doNotCall: lead['doNotCall'] === true,
|
|
90
|
+
website: text(lead['website'])
|
|
91
|
+
}, addressValues('address', lead['address']), {
|
|
92
|
+
status: crmLeadStatusLabel(lead, statuses) || null,
|
|
93
|
+
owner: ownerUid ? (_ref = names.owner == null ? void 0 : names.owner.call(names, ownerUid)) != null ? _ref : ownerUid : null,
|
|
94
|
+
leadSource: text(lead['leadSource']),
|
|
95
|
+
industry: text(lead['industry']),
|
|
96
|
+
rating: text(lead['rating']),
|
|
97
|
+
numberOfEmployees: typeof lead['numberOfEmployees'] === 'number' ? lead['numberOfEmployees'] : null,
|
|
98
|
+
annualRevenue: revenue === null ? null : names.display ? `${(revenue / 100).toFixed(2)} ${currency}` : {
|
|
99
|
+
amountMinor: revenue,
|
|
100
|
+
currency
|
|
101
|
+
},
|
|
102
|
+
tags: Array.isArray(lead['tags']) ? lead['tags'] : [],
|
|
103
|
+
campaigns: campaignIds.map((campaign)=>{
|
|
104
|
+
var _ref;
|
|
105
|
+
return (_ref = names.campaign == null ? void 0 : names.campaign.call(names, campaign)) != null ? _ref : campaign;
|
|
106
|
+
}),
|
|
107
|
+
notes: text(lead['notes']),
|
|
108
|
+
unqualifiedReason: text(lead['unqualifiedReason']),
|
|
109
|
+
sources: captureSources(lead).map(captureSourceLabel),
|
|
110
|
+
firstSeenAt: isoOf((_lead_firstSeenAtMs = lead['firstSeenAtMs']) != null ? _lead_firstSeenAtMs : lead['createdAt']),
|
|
111
|
+
lastSeenAt: isoOf((_lead_lastSeenAtMs = lead['lastSeenAtMs']) != null ? _lead_lastSeenAtMs : lead['createdAt']),
|
|
112
|
+
captures: Number.isFinite(captures) && captures > 0 ? captures : 0,
|
|
113
|
+
convertedAt: isoOf(lead['convertedAtMs']),
|
|
114
|
+
createdAt: isoOf(lead['createdAt']),
|
|
115
|
+
updatedAt: isoOf(lead['updatedAt'])
|
|
116
|
+
}, customTransferValues(definitions, lead['custom']), {
|
|
117
|
+
[TRANSFER_ID_FIELD]: id
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/** The leads these ids name, as values (campaigns by name, so the plan compares what a file carries). */ async function readLeads(run, ids) {
|
|
121
|
+
const out = new Map();
|
|
122
|
+
const wanted = ids.filter((id)=>id && !id.includes('/'));
|
|
123
|
+
for(let at = 0; at < wanted.length; at += 500){
|
|
124
|
+
for (const snapshot of (await run.env.firestore.getAll(...wanted.slice(at, at + 500).map((id)=>leadsOf(run.env).doc(id))))){
|
|
125
|
+
const data = snapshot.data();
|
|
126
|
+
if (snapshot.exists && data && visibleIn(run.env, data['visibleTo'])) {
|
|
127
|
+
out.set(snapshot.id, leadTransferValues(snapshot.id, data, run.statuses, run.definitions, {
|
|
128
|
+
campaign: (id)=>run.campaigns.names.get(id)
|
|
129
|
+
}));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return out;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* The fields a row's values write to a lead, over the lead as it stands;
|
|
137
|
+
* `null` clears. Each value is held to the shape the lead page stores it in.
|
|
138
|
+
*/ function leadFields(run, values, current) {
|
|
139
|
+
var _values_numberOfEmployees, _fields_status;
|
|
140
|
+
const fields = {};
|
|
141
|
+
const text = (key, max = 120)=>textOf(values[key]).slice(0, max) || null;
|
|
142
|
+
for (const key of [
|
|
143
|
+
'company',
|
|
144
|
+
'jobTitle',
|
|
145
|
+
'salutation',
|
|
146
|
+
'industry',
|
|
147
|
+
'rating',
|
|
148
|
+
'unqualifiedReason'
|
|
149
|
+
]){
|
|
150
|
+
if (key in values) fields[key] = text(key);
|
|
151
|
+
}
|
|
152
|
+
for (const key of [
|
|
153
|
+
'firstName',
|
|
154
|
+
'lastName'
|
|
155
|
+
])if (key in values) fields[key] = text(key);
|
|
156
|
+
if ('notes' in values) fields['notes'] = text('notes', 4000);
|
|
157
|
+
for (const key of [
|
|
158
|
+
'phone',
|
|
159
|
+
...CONTACT_EXTRA_PHONE_FIELDS.filter((field)=>field === 'mobilePhone' || field === 'fax')
|
|
160
|
+
]){
|
|
161
|
+
if (!(key in values)) continue;
|
|
162
|
+
const typed = textOf(values[key]);
|
|
163
|
+
const phone = typed ? normalizePhone(typed) : null;
|
|
164
|
+
if (typed && !phone) throw new TransferEngineError('invalid', 422, `“${typed}” is not a phone number.`);
|
|
165
|
+
fields[key] = phone;
|
|
166
|
+
}
|
|
167
|
+
if ('website' in values) {
|
|
168
|
+
const typed = textOf(values['website']);
|
|
169
|
+
const website = typed ? normalizeCompanyWebsite(typed) : null;
|
|
170
|
+
if (typed && !website) throw new TransferEngineError('invalid', 422, `“${typed}” is not a web address.`);
|
|
171
|
+
fields['website'] = website;
|
|
172
|
+
}
|
|
173
|
+
if ('doNotCall' in values) fields['doNotCall'] = values['doNotCall'] === true ? true : null;
|
|
174
|
+
if ('numberOfEmployees' in values) fields['numberOfEmployees'] = (_values_numberOfEmployees = values['numberOfEmployees']) != null ? _values_numberOfEmployees : null;
|
|
175
|
+
if ('annualRevenue' in values) {
|
|
176
|
+
const revenue = values['annualRevenue'];
|
|
177
|
+
fields['annualRevenueCents'] = revenue && typeof revenue === 'object' ? revenue.amountMinor : null;
|
|
178
|
+
fields['currency'] = revenue && typeof revenue === 'object' ? String(revenue.currency).toLowerCase() : null;
|
|
179
|
+
}
|
|
180
|
+
const address = addressFromValues('address', values, current == null ? void 0 : current['address']);
|
|
181
|
+
if (address !== undefined) fields['address'] = address;
|
|
182
|
+
if ('tags' in values) fields['tags'] = normalizeCrmLeadTags(values['tags']);
|
|
183
|
+
if ('owner' in values) fields['ownerUid'] = text('owner', 128);
|
|
184
|
+
if ('status' in values) {
|
|
185
|
+
const label = textOf(values['status']);
|
|
186
|
+
if (label) {
|
|
187
|
+
const write = resolveCrmLeadStatusWrite(run.statuses, label, {
|
|
188
|
+
allowed: FILE_STATUSES,
|
|
189
|
+
current: current
|
|
190
|
+
});
|
|
191
|
+
if (write.ok === false) throw new TransferEngineError('invalid', 422, write.error);
|
|
192
|
+
fields['status'] = write.status;
|
|
193
|
+
fields['statusLabel'] = write.statusLabel;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// A reason is what an unqualified lead was closed for: on any other lead it is not written.
|
|
197
|
+
if ('unqualifiedReason' in fields && ((_fields_status = fields['status']) != null ? _fields_status : current == null ? void 0 : current['status']) !== 'unqualified') {
|
|
198
|
+
delete fields['unqualifiedReason'];
|
|
199
|
+
}
|
|
200
|
+
if ('campaigns' in values) {
|
|
201
|
+
const named = Array.isArray(values['campaigns']) ? values['campaigns'].map((name)=>textOf(name)).filter(Boolean) : [];
|
|
202
|
+
const ids = named.map((name)=>{
|
|
203
|
+
var _run_campaigns_byName_get;
|
|
204
|
+
return (_run_campaigns_byName_get = run.campaigns.byName.get(name.toLowerCase())) != null ? _run_campaigns_byName_get : '';
|
|
205
|
+
});
|
|
206
|
+
const unknown = named.find((_name, at)=>!ids[at]);
|
|
207
|
+
if (unknown) throw new TransferEngineError('invalid', 422, `No campaign is called “${unknown}”.`);
|
|
208
|
+
fields['campaignIds'] = [
|
|
209
|
+
...new Set(ids)
|
|
210
|
+
];
|
|
211
|
+
}
|
|
212
|
+
return fields;
|
|
213
|
+
}
|
|
214
|
+
/** Fields as an update writes them: a cleared field is deleted. */ const asUpdate = (fields)=>Object.fromEntries(Object.entries(fields).map(([key, value])=>[
|
|
215
|
+
key,
|
|
216
|
+
value === null ? FieldValue.delete() : value
|
|
217
|
+
]));
|
|
218
|
+
/**
|
|
219
|
+
* Writes a lead's working state and profile over what it holds, as the lead
|
|
220
|
+
* page writes it: the lead source and the picklists judged against the
|
|
221
|
+
* org's lists, the name composed from its parts, custom values by their
|
|
222
|
+
* definitions, and the list's search and filter keys restamped.
|
|
223
|
+
*/ async function writeLead(run, ref, values, options) {
|
|
224
|
+
var _data;
|
|
225
|
+
const stored = (_data = (await ref.get()).data()) != null ? _data : {};
|
|
226
|
+
const fields = leadFields(run, values, stored);
|
|
227
|
+
if ('leadSource' in values || options.created) {
|
|
228
|
+
const source = resolveLeadSourceWrite(run.leadSources, textOf(values['leadSource']) || undefined, {
|
|
229
|
+
current: stored['leadSource'],
|
|
230
|
+
created: options.created
|
|
231
|
+
});
|
|
232
|
+
if (source.ok === false) throw new TransferEngineError('invalid', 422, source.error);
|
|
233
|
+
if (source.write !== undefined) fields['leadSource'] = source.write;
|
|
234
|
+
else if ('leadSource' in values && !textOf(values['leadSource'])) fields['leadSource'] = null;
|
|
235
|
+
}
|
|
236
|
+
const patch = _extends({}, fields);
|
|
237
|
+
const refused = judgeLeadPicklistPatch(run.picklists, patch, {
|
|
238
|
+
current: stored,
|
|
239
|
+
created: options.created
|
|
240
|
+
});
|
|
241
|
+
const first = Object.entries(refused)[0];
|
|
242
|
+
if (first) throw new TransferEngineError('invalid', 422, String(first[1]));
|
|
243
|
+
const composed = crmLeadComposedName(stored, _extends({}, 'firstName' in fields ? {
|
|
244
|
+
firstName: fields['firstName']
|
|
245
|
+
} : {}, 'lastName' in fields ? {
|
|
246
|
+
lastName: fields['lastName']
|
|
247
|
+
} : {}));
|
|
248
|
+
if (composed) patch['name'] = composed;
|
|
249
|
+
else if ('name' in values && !textOf(stored['firstName']) && !textOf(stored['lastName'])) {
|
|
250
|
+
patch['name'] = textOf(values['name']).slice(0, 120) || null;
|
|
251
|
+
}
|
|
252
|
+
const custom = customWriteValues(values, run.definitions, 'lead');
|
|
253
|
+
if ('error' in custom) throw new TransferEngineError('invalid', 422, custom.error);
|
|
254
|
+
for (const [key, value] of Object.entries(custom.values))patch[`custom.${key}`] = value;
|
|
255
|
+
if (!Object.keys(patch).length) return;
|
|
256
|
+
await ref.update(_extends({}, asUpdate(patch), {
|
|
257
|
+
updatedAt: FieldValue.serverTimestamp()
|
|
258
|
+
}));
|
|
259
|
+
// What the Leads list searches and filters by (AGL-3321).
|
|
260
|
+
await restampCrmListFieldsAt(ref, 'leads');
|
|
261
|
+
}
|
|
262
|
+
/** The `crm.leads` hooks. */ export function leadsTransferResource() {
|
|
263
|
+
const run = async (ctx)=>{
|
|
264
|
+
var _env_hostId;
|
|
265
|
+
const env = await crmTransferEnv(ctx);
|
|
266
|
+
const [statuses, leadSources, picklists, definitions, campaigns] = await Promise.all([
|
|
267
|
+
readCrmPicklist(env.firestore, env.orgId, CRM_LEAD_STATUS_PICKLIST),
|
|
268
|
+
readLeadSourcePicklist(env.firestore, env.orgId),
|
|
269
|
+
readLeadPicklists(env.firestore, env.orgId),
|
|
270
|
+
crmCustomDefinitions(env, 'lead'),
|
|
271
|
+
campaignDirectory(env)
|
|
272
|
+
]);
|
|
273
|
+
return {
|
|
274
|
+
env,
|
|
275
|
+
hostId: (_env_hostId = env.hostId) != null ? _env_hostId : '',
|
|
276
|
+
statuses,
|
|
277
|
+
leadSources,
|
|
278
|
+
picklists,
|
|
279
|
+
definitions,
|
|
280
|
+
campaigns
|
|
281
|
+
};
|
|
282
|
+
};
|
|
283
|
+
return {
|
|
284
|
+
async fields (ctx) {
|
|
285
|
+
const env = await crmTransferEnv(ctx);
|
|
286
|
+
return {
|
|
287
|
+
standard: LEAD_TRANSFER_FIELDS,
|
|
288
|
+
derived: LEAD_TRANSFER_DERIVED,
|
|
289
|
+
system: CRM_TIMESTAMP_FIELDS,
|
|
290
|
+
custom: crmCustomTransferFields(await crmCustomDefinitions(env, 'lead'), 'lead'),
|
|
291
|
+
groups: LEAD_TRANSFER_GROUPS
|
|
292
|
+
};
|
|
293
|
+
},
|
|
294
|
+
matchKeys: [
|
|
295
|
+
{
|
|
296
|
+
fieldId: TRANSFER_ID_FIELD,
|
|
297
|
+
normalizer: 'aglynId'
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
fieldId: 'email',
|
|
301
|
+
normalizer: 'email'
|
|
302
|
+
}
|
|
303
|
+
],
|
|
304
|
+
aliases: LEAD_ALIASES,
|
|
305
|
+
lookupTargets: {
|
|
306
|
+
[CRM_MEMBERS_TARGET]: crmMembersTarget()
|
|
307
|
+
},
|
|
308
|
+
// The people a workspace holds are its own on every plan (AGL-2839).
|
|
309
|
+
async count (ctx, options) {
|
|
310
|
+
const env = await crmTransferEnv(ctx);
|
|
311
|
+
return countCrmExport(env, leadsOf(env), options, (data)=>visibleIn(env, data['visibleTo'], options.scopeTokens));
|
|
312
|
+
},
|
|
313
|
+
async readPage (ctx, cursor, fieldIds, options) {
|
|
314
|
+
const context = await run(ctx);
|
|
315
|
+
const emails = fieldIds.includes('owner') ? await crmMemberEmails(context.env.orgId) : new Map();
|
|
316
|
+
return readCrmExportPage(context.env, leadsOf(context.env), cursor, options, (data)=>visibleIn(context.env, data['visibleTo'], options == null ? void 0 : options.scopeTokens), async (docs)=>docs.map((doc)=>pickValues(leadTransferValues(doc.id, doc.data, context.statuses, context.definitions, {
|
|
317
|
+
owner: (uid)=>emails.get(uid),
|
|
318
|
+
campaign: (id)=>context.campaigns.names.get(id),
|
|
319
|
+
display: true
|
|
320
|
+
}), fieldIds)));
|
|
321
|
+
},
|
|
322
|
+
async lookup (ctx, requests) {
|
|
323
|
+
const context = await run(ctx);
|
|
324
|
+
const visible = (data)=>visibleIn(context.env, data['visibleTo']);
|
|
325
|
+
const found = {
|
|
326
|
+
lookup: new Map(),
|
|
327
|
+
docs: new Map()
|
|
328
|
+
};
|
|
329
|
+
for (const request of requests){
|
|
330
|
+
if (request.fieldId === TRANSFER_ID_FIELD) await lookupById(context.env, leadsOf(context.env), request, visible, found);
|
|
331
|
+
else if (request.fieldId === 'email') {
|
|
332
|
+
// A lead's id IS its person key: one document per person.
|
|
333
|
+
const byKey = new Map();
|
|
334
|
+
for (const value of request.values){
|
|
335
|
+
const key = personKey(value);
|
|
336
|
+
if (key) byKey.set(key, value);
|
|
337
|
+
}
|
|
338
|
+
const keys = [
|
|
339
|
+
...byKey.keys()
|
|
340
|
+
];
|
|
341
|
+
for(let at = 0; at < keys.length; at += 500){
|
|
342
|
+
const page = keys.slice(at, at + 500);
|
|
343
|
+
for (const snapshot of (await context.env.firestore.getAll(...page.map((key)=>leadsOf(context.env).doc(key))))){
|
|
344
|
+
const data = snapshot.data();
|
|
345
|
+
if (!snapshot.exists || !data || !visible(data)) continue;
|
|
346
|
+
found.docs.set(snapshot.id, data);
|
|
347
|
+
found.lookup.set(matchLookupKey(request.fieldId, byKey.get(snapshot.id)), [
|
|
348
|
+
snapshot.id
|
|
349
|
+
]);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return lookupResult(found, (id, data)=>leadTransferValues(id, data, context.statuses, context.definitions, {
|
|
355
|
+
campaign: (campaign)=>context.campaigns.names.get(campaign)
|
|
356
|
+
}));
|
|
357
|
+
},
|
|
358
|
+
async picklists (ctx, ids) {
|
|
359
|
+
const env = await crmTransferEnv(ctx);
|
|
360
|
+
return crmPicklistLists(env, ids, await crmCustomDefinitions(env, 'lead'));
|
|
361
|
+
},
|
|
362
|
+
async addPicklistValues (ctx, picklistId, values) {
|
|
363
|
+
await addCrmPicklistValues(await crmTransferEnv(ctx), picklistId, values);
|
|
364
|
+
},
|
|
365
|
+
lockedRules: ()=>[
|
|
366
|
+
{
|
|
367
|
+
fieldId: 'email',
|
|
368
|
+
reason: 'A lead is the person at this address; a different address is a different lead.',
|
|
369
|
+
forced: {
|
|
370
|
+
mode: 'keepExisting'
|
|
371
|
+
}
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
fieldId: 'status',
|
|
375
|
+
reason: 'A lead becomes Qualified only by converting it, which makes its contact, company and deal.'
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
fieldId: 'doNotCall',
|
|
379
|
+
reason: 'A file can say a person asked not to be called, never that they took it back.',
|
|
380
|
+
forced: {
|
|
381
|
+
mode: 'overwrite'
|
|
382
|
+
}
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
fieldId: 'name',
|
|
386
|
+
reason: 'The name is built from the first and last names once either is set.'
|
|
387
|
+
}
|
|
388
|
+
],
|
|
389
|
+
async plan (ctx, input) {
|
|
390
|
+
const context = await run(ctx);
|
|
391
|
+
requireCrmSuite(context.env, SUITE_ACT);
|
|
392
|
+
requireSite(context.env, 'leads');
|
|
393
|
+
const plan = buildTransferPlan(input);
|
|
394
|
+
return holdBackChanges(plan, (row, change)=>{
|
|
395
|
+
const before = row.recordId ? input.existing.get(row.recordId) : undefined;
|
|
396
|
+
if (change.fieldId === 'status' && textOf(change.after)) {
|
|
397
|
+
const write = resolveCrmLeadStatusWrite(context.statuses, change.after, {
|
|
398
|
+
current: null
|
|
399
|
+
});
|
|
400
|
+
if (write.ok && write.status === 'qualified') return 'Qualified only by converting the lead.';
|
|
401
|
+
}
|
|
402
|
+
if (change.fieldId === 'doNotCall' && (before == null ? void 0 : before['doNotCall']) === true && change.after !== true) {
|
|
403
|
+
return 'Do not call is turned off on the lead’s page, never by a file.';
|
|
404
|
+
}
|
|
405
|
+
if (change.fieldId === 'name') {
|
|
406
|
+
const values = Object.fromEntries(row.diff.map((entry)=>[
|
|
407
|
+
entry.fieldId,
|
|
408
|
+
entry.after
|
|
409
|
+
]));
|
|
410
|
+
const first = 'firstName' in values ? values['firstName'] : before == null ? void 0 : before['firstName'];
|
|
411
|
+
const last = 'lastName' in values ? values['lastName'] : before == null ? void 0 : before['lastName'];
|
|
412
|
+
if (textOf(first) || textOf(last)) return 'Built from the first and last names.';
|
|
413
|
+
}
|
|
414
|
+
return null;
|
|
415
|
+
});
|
|
416
|
+
},
|
|
417
|
+
async apply (ctx, chunk, writer) {
|
|
418
|
+
const context = await run(ctx);
|
|
419
|
+
requireCrmSuite(context.env, SUITE_ACT);
|
|
420
|
+
const { hostId } = requireSite(context.env, 'leads');
|
|
421
|
+
const applyRun = _extends({}, context, {
|
|
422
|
+
hostId
|
|
423
|
+
});
|
|
424
|
+
const hostRef = context.env.firestore.collection('hosts').doc(hostId);
|
|
425
|
+
let counted = null;
|
|
426
|
+
let createdHere = 0;
|
|
427
|
+
const results = [];
|
|
428
|
+
const undo = [];
|
|
429
|
+
await eachWithinBudget(chunk.rows, ()=>writer.timeLeftMs(), async (row)=>{
|
|
430
|
+
const earlier = await writer.alreadyApplied(row.index);
|
|
431
|
+
if (earlier) {
|
|
432
|
+
results.push(earlier);
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
const changed = row.diff.map((change)=>change.fieldId);
|
|
436
|
+
let result;
|
|
437
|
+
let entry;
|
|
438
|
+
try {
|
|
439
|
+
const values = plannedValues(row);
|
|
440
|
+
if (row.verdict === 'update' && row.recordId) {
|
|
441
|
+
var _get;
|
|
442
|
+
const before = (await readLeads(applyRun, [
|
|
443
|
+
row.recordId
|
|
444
|
+
])).get(row.recordId);
|
|
445
|
+
if (!before) throw new TransferEngineError('notFound', 404, 'That lead no longer exists.');
|
|
446
|
+
const ref = leadsOf(context.env).doc(row.recordId);
|
|
447
|
+
await writeLead(applyRun, ref, values, {
|
|
448
|
+
created: false
|
|
449
|
+
});
|
|
450
|
+
const after = (_get = (await readLeads(applyRun, [
|
|
451
|
+
ref.id
|
|
452
|
+
])).get(ref.id)) != null ? _get : {};
|
|
453
|
+
result = {
|
|
454
|
+
row: row.index,
|
|
455
|
+
outcome: 'updated',
|
|
456
|
+
recordId: ref.id
|
|
457
|
+
};
|
|
458
|
+
entry = {
|
|
459
|
+
row: row.index,
|
|
460
|
+
recordId: ref.id,
|
|
461
|
+
action: 'updated',
|
|
462
|
+
previous: pickValues(before, changed),
|
|
463
|
+
written: pickValues(after, changed)
|
|
464
|
+
};
|
|
465
|
+
} else {
|
|
466
|
+
var _data_count, _get1;
|
|
467
|
+
const email = textOf(values['email']);
|
|
468
|
+
const key = personKey(email);
|
|
469
|
+
if (!key) throw new TransferEngineError('invalid', 422, 'Not a valid email address.');
|
|
470
|
+
// Every value read before the door is knocked on, so a row the
|
|
471
|
+
// lead page would refuse files nobody.
|
|
472
|
+
leadFields(applyRun, values, null);
|
|
473
|
+
const custom = customWriteValues(values, context.definitions, 'lead');
|
|
474
|
+
if ('error' in custom) throw new TransferEngineError('invalid', 422, custom.error);
|
|
475
|
+
if (counted === null) counted = Number((_data_count = (await leadsOf(context.env).count().get()).data().count) != null ? _data_count : 0);
|
|
476
|
+
if (checkVisitorRecordCeiling(counted + createdHere, LEADS_MAX_PER_HOST).exceeded) {
|
|
477
|
+
throw new TransferEngineError('invalid', 422, 'This site holds as many leads as it can.');
|
|
478
|
+
}
|
|
479
|
+
// The door every capture goes through: the person keyed by address,
|
|
480
|
+
// the ceiling judged again in its own transaction, the site's scope.
|
|
481
|
+
const outcome = await addHostLeadOutcome({
|
|
482
|
+
hostRef,
|
|
483
|
+
hostId,
|
|
484
|
+
lead: _extends({
|
|
485
|
+
email
|
|
486
|
+
}, textOf(values['name']) ? {
|
|
487
|
+
name: textOf(values['name'])
|
|
488
|
+
} : {}, {
|
|
489
|
+
source: LEAD_IMPORT_SOURCE
|
|
490
|
+
})
|
|
491
|
+
});
|
|
492
|
+
if (!outcome.stored) throw new TransferEngineError('invalid', 422, 'The lead could not be saved; this site may hold as many leads as it can.');
|
|
493
|
+
if (outcome.created) createdHere += 1;
|
|
494
|
+
const ref = leadsOf(context.env).doc(key);
|
|
495
|
+
await writeLead(applyRun, ref, values, {
|
|
496
|
+
created: outcome.created
|
|
497
|
+
});
|
|
498
|
+
const after = (_get1 = (await readLeads(applyRun, [
|
|
499
|
+
ref.id
|
|
500
|
+
])).get(ref.id)) != null ? _get1 : {};
|
|
501
|
+
result = _extends({
|
|
502
|
+
row: row.index,
|
|
503
|
+
outcome: outcome.created ? 'created' : 'updated',
|
|
504
|
+
recordId: ref.id
|
|
505
|
+
}, outcome.created ? {} : {
|
|
506
|
+
message: 'Merged into the lead already holding this address.'
|
|
507
|
+
});
|
|
508
|
+
entry = outcome.created ? {
|
|
509
|
+
row: row.index,
|
|
510
|
+
recordId: ref.id,
|
|
511
|
+
action: 'created',
|
|
512
|
+
written: pickValues(after, changed)
|
|
513
|
+
} : undefined;
|
|
514
|
+
}
|
|
515
|
+
} catch (error) {
|
|
516
|
+
result = _extends({
|
|
517
|
+
row: row.index,
|
|
518
|
+
outcome: 'failed'
|
|
519
|
+
}, row.recordId ? {
|
|
520
|
+
recordId: row.recordId
|
|
521
|
+
} : {}, {
|
|
522
|
+
message: failureMessage(error)
|
|
523
|
+
});
|
|
524
|
+
entry = undefined;
|
|
525
|
+
}
|
|
526
|
+
await writer.markApplied(result, entry);
|
|
527
|
+
results.push(result);
|
|
528
|
+
if (entry) undo.push(entry);
|
|
529
|
+
});
|
|
530
|
+
return {
|
|
531
|
+
results,
|
|
532
|
+
undo
|
|
533
|
+
};
|
|
534
|
+
},
|
|
535
|
+
async revert (ctx, snapshot, decisions) {
|
|
536
|
+
const context = await run(ctx);
|
|
537
|
+
const { hostId } = requireSite(context.env, 'leads');
|
|
538
|
+
const applyRun = _extends({}, context, {
|
|
539
|
+
hostId
|
|
540
|
+
});
|
|
541
|
+
const current = await readLeads(applyRun, snapshot.entries.map((entry)=>entry.recordId));
|
|
542
|
+
const done = [];
|
|
543
|
+
const conflicts = [];
|
|
544
|
+
for (const entry of snapshot.entries){
|
|
545
|
+
var _current_get;
|
|
546
|
+
const step = planTransferUndo(entry, (_current_get = current.get(entry.recordId)) != null ? _current_get : null);
|
|
547
|
+
if (step.action === 'conflict' && (decisions == null ? void 0 : decisions[entry.recordId]) !== 'revert') {
|
|
548
|
+
if ((decisions == null ? void 0 : decisions[entry.recordId]) === 'keep') done.push({
|
|
549
|
+
action: 'nothing',
|
|
550
|
+
recordId: entry.recordId,
|
|
551
|
+
why: 'alreadyReverted'
|
|
552
|
+
});
|
|
553
|
+
else conflicts.push(step);
|
|
554
|
+
continue;
|
|
555
|
+
}
|
|
556
|
+
if (step.action === 'nothing') {
|
|
557
|
+
done.push(step);
|
|
558
|
+
continue;
|
|
559
|
+
}
|
|
560
|
+
const ref = leadsOf(context.env).doc(entry.recordId);
|
|
561
|
+
if (entry.action === 'created') {
|
|
562
|
+
await ref.delete();
|
|
563
|
+
done.push({
|
|
564
|
+
action: 'delete',
|
|
565
|
+
recordId: entry.recordId
|
|
566
|
+
});
|
|
567
|
+
continue;
|
|
568
|
+
}
|
|
569
|
+
await writeLead(applyRun, ref, step.action === 'restore' || step.action === 'conflict' ? step.values : {}, {
|
|
570
|
+
created: false
|
|
571
|
+
});
|
|
572
|
+
done.push(step);
|
|
573
|
+
}
|
|
574
|
+
return {
|
|
575
|
+
done,
|
|
576
|
+
conflicts
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
//# sourceMappingURL=leads.js.map
|