@aglyn/plugins-crm 1.0.0-beta.221 → 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 +65 -21
- 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
|
@@ -0,0 +1,698 @@
|
|
|
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
|
+
* DEALS ON THE TRANSFER FRAMEWORK (AGL-3528) — the server half of
|
|
19
|
+
* `crm.deals`.
|
|
20
|
+
*
|
|
21
|
+
* Every field a deal holds, its custom fields and its contact roles, read
|
|
22
|
+
* for an export and written by an import the way the deals import route
|
|
23
|
+
* wrote them — the pipeline and the stage by name, the scope stamp of the
|
|
24
|
+
* importing site, the records band, the org's lists judging each label, the
|
|
25
|
+
* list's search and filter keys — and now FOUND again: a row matches its
|
|
26
|
+
* deal by Aglyn ID or by the external id another CRM gave it, so a file
|
|
27
|
+
* imported twice updates rather than duplicating every deal.
|
|
28
|
+
*
|
|
29
|
+
* The contact, the company and every contact role name records, resolved
|
|
30
|
+
* as lookups (a contact by email, a company by domain or name).
|
|
31
|
+
*
|
|
32
|
+
* A matched deal's pipeline and stage are locked: a stage moves on the
|
|
33
|
+
* board, where the move tells automations and makes a won deal's contact a
|
|
34
|
+
* customer, never as a side effect of a file.
|
|
35
|
+
*=========================================*/ import { checkCrmRecordsQuota, CRM_COLLECTIONS, CRM_FORECAST_CATEGORIES, CRM_FORECAST_CATEGORY_LABELS, crmListFields, crmPicklistDefaultLabel, crmNewRecordListFields, dealContactRoleFields, dealContactRolesOf, dealContactRolesWithPrimary, dealStageForecastCategory, isCrmForecastCategory, isPipelineArchived, judgeDealContactRoles, nameSearchKey } from "@aglyn/aglyn/server";
|
|
36
|
+
import { createResourceUid } from "@aglyn/aglyn/app-utils/create-resource-uid";
|
|
37
|
+
import { buildTransferPlan, planTransferUndo, rankTransferLookupSuggestions, TRANSFER_ID_FIELD, transferLookupNewName } from "@aglyn/aglyn/data-transfer";
|
|
38
|
+
import { crmRecordsQuotaForOrg, restampCrmListFieldsOf } from "@aglyn/tenant-data-admin";
|
|
39
|
+
import { FieldValue } from "firebase-admin/firestore";
|
|
40
|
+
import { DEAL_ALIASES } from "./aliases.js";
|
|
41
|
+
import { addCrmPicklistValues, campaignDirectory, countCrmExport, creationScope, crmCustomDefinitions, crmMemberEmails, crmMembersTarget, crmPicklistLists, crmRecordsRoom, crmTransferEnv, customTransferValues, customWriteValues, eachWithinBudget, failureMessage, IN_LIMIT, isoOf, lookupByField, lookupById, lookupResult, pickValues, plannedValues, readCrmExportPage, requireCrmRecords, requireCrmSuite, requireSite, storedMs, textOf, TransferEngineError, visibleIn } from "./common.js";
|
|
42
|
+
import { companyForName } from "./companies.js";
|
|
43
|
+
import { CRM_MEMBERS_TARGET, CRM_TIMESTAMP_FIELDS, crmCustomTransferFields, DEAL_TRANSFER_DERIVED, DEAL_TRANSFER_FIELDS, DEAL_TRANSFER_GROUPS } from "./fields.js";
|
|
44
|
+
const SUITE_ACT = 'Importing deals';
|
|
45
|
+
/** The currency a deal carries when the file names none — the deal form's own. */ const DEFAULT_CURRENCY = 'usd';
|
|
46
|
+
/** How a deal's status reads in a file. */ const STATUS_LABELS = {
|
|
47
|
+
open: 'Open',
|
|
48
|
+
won: 'Won',
|
|
49
|
+
lost: 'Lost'
|
|
50
|
+
};
|
|
51
|
+
const dealsOf = (env)=>env.orgRef.collection(CRM_COLLECTIONS.deals);
|
|
52
|
+
const contactsOf = (env)=>env.orgRef.collection('contacts');
|
|
53
|
+
/** Every pipeline the site sees, archived ones included (an export names them), in read order. */ async function readPipelines(env) {
|
|
54
|
+
const snapshot = await env.orgRef.collection(CRM_COLLECTIONS.pipelines).get();
|
|
55
|
+
return snapshot.docs.map((doc)=>({
|
|
56
|
+
id: doc.id,
|
|
57
|
+
pipeline: doc.data()
|
|
58
|
+
})).filter((entry)=>visibleIn(env, entry.pipeline.visibleTo)).map((entry)=>{
|
|
59
|
+
var _entry_pipeline_stages;
|
|
60
|
+
return _extends({}, entry, {
|
|
61
|
+
stages: [
|
|
62
|
+
...(_entry_pipeline_stages = entry.pipeline.stages) != null ? _entry_pipeline_stages : []
|
|
63
|
+
].sort((a, b)=>a.order - b.order)
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The pipeline and stage a new deal is filed in: by name (case and spacing
|
|
69
|
+
* aside) among the active pipelines, or the default pipeline and its first
|
|
70
|
+
* open stage when the row names none. `null` names what could not be found.
|
|
71
|
+
*/ export function placeDeal(choices, pipelineName, stageName) {
|
|
72
|
+
var _active_find, _pipeline_stages_find;
|
|
73
|
+
const active = choices.filter((choice)=>!isPipelineArchived(choice.pipeline));
|
|
74
|
+
const pipeline = pipelineName ? active.find((choice)=>{
|
|
75
|
+
var _choice_pipeline_name;
|
|
76
|
+
return nameSearchKey((_choice_pipeline_name = choice.pipeline.name) != null ? _choice_pipeline_name : '') === nameSearchKey(pipelineName);
|
|
77
|
+
}) : (_active_find = active.find((choice)=>choice.pipeline.isDefault)) != null ? _active_find : active.length === 1 ? active[0] : undefined;
|
|
78
|
+
if (!pipeline) {
|
|
79
|
+
return {
|
|
80
|
+
error: pipelineName ? `No pipeline is called “${pipelineName}”.` : 'Name the pipeline: this workspace has several.'
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
const stage = stageName ? pipeline.stages.find((candidate)=>{
|
|
84
|
+
var _candidate_name;
|
|
85
|
+
return nameSearchKey((_candidate_name = candidate.name) != null ? _candidate_name : '') === nameSearchKey(stageName);
|
|
86
|
+
}) : (_pipeline_stages_find = pipeline.stages.find((candidate)=>candidate.kind === 'open')) != null ? _pipeline_stages_find : pipeline.stages[0];
|
|
87
|
+
if (!stage) return {
|
|
88
|
+
error: `“${pipeline.pipeline.name}” has no stage called “${stageName}”.`
|
|
89
|
+
};
|
|
90
|
+
return {
|
|
91
|
+
pipeline,
|
|
92
|
+
stage
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/** A stored day (epoch ms at local noon) as the file reads it, `YYYY-MM-DD`. */ function dayOf(ms) {
|
|
96
|
+
const value = storedMs(ms);
|
|
97
|
+
return value === null ? null : new Date(value).toISOString().slice(0, 10);
|
|
98
|
+
}
|
|
99
|
+
/** A day the file names as the stored epoch: noon UTC, so the calendar day survives every zone. */ function storedDay(value) {
|
|
100
|
+
const text = textOf(value);
|
|
101
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(text)) return null;
|
|
102
|
+
return Date.parse(`${text}T12:00:00.000Z`);
|
|
103
|
+
}
|
|
104
|
+
/** A deal's contact roles as one cell: `email (Role)`, the Primary first, `; ` between. */ function rolesCell(roles, contact) {
|
|
105
|
+
const ordered = [
|
|
106
|
+
...roles
|
|
107
|
+
].sort((a, b)=>Number(b.primary) - Number(a.primary));
|
|
108
|
+
const cell = ordered.map((row)=>{
|
|
109
|
+
var _contact;
|
|
110
|
+
const who = (_contact = contact(row.contactId)) != null ? _contact : row.contactId;
|
|
111
|
+
return row.role ? `${who} (${row.role})` : who;
|
|
112
|
+
}).join('; ');
|
|
113
|
+
return cell || null;
|
|
114
|
+
}
|
|
115
|
+
/** A contact roles cell read back: each person and the role in parentheses after them. */ export function parseRolesCell(value) {
|
|
116
|
+
return textOf(value).split(/[;\n]+/).map((part)=>part.trim()).filter(Boolean).map((part)=>{
|
|
117
|
+
const match = /^(.*?)\s*\(([^)]*)\)\s*$/.exec(part);
|
|
118
|
+
return match ? {
|
|
119
|
+
who: match[1].trim(),
|
|
120
|
+
role: match[2].trim()
|
|
121
|
+
} : {
|
|
122
|
+
who: part,
|
|
123
|
+
role: ''
|
|
124
|
+
};
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* One deal as values by field id. A lookup and an undo read links by id
|
|
129
|
+
* so the plan compares what is stored; an export writes names.
|
|
130
|
+
*/ export function dealTransferValues(id, deal, definitions, names) {
|
|
131
|
+
var _STATUS_LABELS_textOf, _text, _text1;
|
|
132
|
+
const text = (value)=>textOf(value) || null;
|
|
133
|
+
const pipelineId = textOf(deal['pipelineId']);
|
|
134
|
+
const stageId = textOf(deal['stageId']);
|
|
135
|
+
const amount = typeof deal['amountCents'] === 'number' ? deal['amountCents'] : null;
|
|
136
|
+
const currency = String(deal['currency'] || DEFAULT_CURRENCY).toUpperCase();
|
|
137
|
+
const ownerUid = text(deal['ownerUid']);
|
|
138
|
+
const contactId = text(deal['contactId']);
|
|
139
|
+
const companyId = text(deal['companyId']);
|
|
140
|
+
const campaignId = text(deal['campaignId']);
|
|
141
|
+
const roles = dealContactRolesOf(deal);
|
|
142
|
+
const forecast = isCrmForecastCategory(deal['forecastCategory']) ? CRM_FORECAST_CATEGORY_LABELS[deal['forecastCategory']] : null;
|
|
143
|
+
const named = (resolve, fallback, ...args)=>(resolve == null ? void 0 : resolve(...args)) || fallback;
|
|
144
|
+
return _extends({
|
|
145
|
+
title: text(deal['title']),
|
|
146
|
+
externalId: text(deal['externalId']),
|
|
147
|
+
pipeline: pipelineId ? named(names == null ? void 0 : names.pipeline, pipelineId, pipelineId) : null,
|
|
148
|
+
stage: stageId ? named(names == null ? void 0 : names.stage, stageId, pipelineId, stageId) : null,
|
|
149
|
+
status: (_STATUS_LABELS_textOf = STATUS_LABELS[textOf(deal['status'])]) != null ? _STATUS_LABELS_textOf : null,
|
|
150
|
+
amount: amount === null ? null : (names == null ? void 0 : names.display) ? `${(amount / 100).toFixed(2)} ${currency}` : {
|
|
151
|
+
amountMinor: amount,
|
|
152
|
+
currency
|
|
153
|
+
},
|
|
154
|
+
expectedClose: dayOf(deal['expectedCloseAtMs']),
|
|
155
|
+
closedAt: isoOf(deal['closedAtMs']),
|
|
156
|
+
owner: ownerUid ? named(names == null ? void 0 : names.owner, ownerUid, ownerUid) : null,
|
|
157
|
+
contact: contactId ? named(names == null ? void 0 : names.contact, (names == null ? void 0 : names.contact) ? (_text = text(deal['contactName'])) != null ? _text : contactId : contactId, contactId) : null,
|
|
158
|
+
company: companyId ? named(names == null ? void 0 : names.company, (names == null ? void 0 : names.company) ? (_text1 = text(deal['companyName'])) != null ? _text1 : companyId : companyId, companyId) : null,
|
|
159
|
+
contactRoles: rolesCell(roles, (contact)=>{
|
|
160
|
+
var _names_roleContact;
|
|
161
|
+
return names == null ? void 0 : (_names_roleContact = names.roleContact) == null ? void 0 : _names_roleContact.call(names, contact);
|
|
162
|
+
}),
|
|
163
|
+
type: text(deal['type']),
|
|
164
|
+
leadSource: text(deal['leadSource']),
|
|
165
|
+
nextStep: text(deal['nextStep']),
|
|
166
|
+
probability: typeof deal['probability'] === 'number' ? deal['probability'] : null,
|
|
167
|
+
forecastCategory: forecast,
|
|
168
|
+
lostReason: text(deal['lostReason']),
|
|
169
|
+
campaign: campaignId ? named(names == null ? void 0 : names.campaign, campaignId, campaignId) : null,
|
|
170
|
+
notes: text(deal['notes']),
|
|
171
|
+
createdAt: isoOf(deal['createdAt']),
|
|
172
|
+
updatedAt: isoOf(deal['updatedAt'])
|
|
173
|
+
}, customTransferValues(definitions, deal['custom']), {
|
|
174
|
+
[TRANSFER_ID_FIELD]: id
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
/** What a lookup and an undo name in words: the pipeline, the stage and the role contacts. */ async function wordNames(env, deals) {
|
|
178
|
+
const pipelines = deals.length ? await readPipelines(env) : [];
|
|
179
|
+
const ids = [
|
|
180
|
+
...new Set(deals.flatMap((deal)=>dealContactRolesOf(deal).map((row)=>row.contactId)))
|
|
181
|
+
].filter((id)=>!id.includes('/'));
|
|
182
|
+
const emails = new Map();
|
|
183
|
+
for(let at = 0; at < ids.length; at += 500){
|
|
184
|
+
for (const snapshot of (await env.firestore.getAll(...ids.slice(at, at + 500).map((id)=>contactsOf(env).doc(id))))){
|
|
185
|
+
if (snapshot.exists) emails.set(snapshot.id, textOf(snapshot.get('email')));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const campaigns = deals.some((deal)=>textOf(deal['campaignId'])) ? await campaignDirectory(env) : null;
|
|
189
|
+
return {
|
|
190
|
+
pipeline: (id)=>{
|
|
191
|
+
var _pipelines_find;
|
|
192
|
+
return (_pipelines_find = pipelines.find((choice)=>choice.id === id)) == null ? void 0 : _pipelines_find.pipeline.name;
|
|
193
|
+
},
|
|
194
|
+
stage: (pipelineId, stageId)=>{
|
|
195
|
+
var _pipelines_find_stages_find, _pipelines_find;
|
|
196
|
+
return (_pipelines_find = pipelines.find((choice)=>choice.id === pipelineId)) == null ? void 0 : (_pipelines_find_stages_find = _pipelines_find.stages.find((stage)=>stage.id === stageId)) == null ? void 0 : _pipelines_find_stages_find.name;
|
|
197
|
+
},
|
|
198
|
+
roleContact: (id)=>emails.get(id) || undefined,
|
|
199
|
+
campaign: (id)=>campaigns == null ? void 0 : campaigns.names.get(id)
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
/** The deals these ids name, as values. */ async function readDeals(env, ids, definitions) {
|
|
203
|
+
const docs = new Map();
|
|
204
|
+
const wanted = ids.filter((id)=>id && !id.includes('/'));
|
|
205
|
+
for(let at = 0; at < wanted.length; at += 500){
|
|
206
|
+
for (const snapshot of (await env.firestore.getAll(...wanted.slice(at, at + 500).map((id)=>dealsOf(env).doc(id))))){
|
|
207
|
+
const data = snapshot.data();
|
|
208
|
+
if (snapshot.exists && data && visibleIn(env, data['visibleTo'])) docs.set(snapshot.id, data);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const names = await wordNames(env, [
|
|
212
|
+
...docs.values()
|
|
213
|
+
]);
|
|
214
|
+
return new Map([
|
|
215
|
+
...docs
|
|
216
|
+
].map(([id, data])=>[
|
|
217
|
+
id,
|
|
218
|
+
dealTransferValues(id, data, definitions, names)
|
|
219
|
+
]));
|
|
220
|
+
}
|
|
221
|
+
/** A contact the import may link: one the site sees, by id or by email. */ async function contactFor(run, value) {
|
|
222
|
+
const byId = !value.includes('@') && !value.includes('/') ? await contactsOf(run.env).doc(value).get() : null;
|
|
223
|
+
const snapshot = (byId == null ? void 0 : byId.exists) ? byId : (await contactsOf(run.env).where('email', '==', value.trim().toLowerCase()).limit(IN_LIMIT).get()).docs.find((doc)=>visibleIn(run.env, doc.get('visibleTo')));
|
|
224
|
+
if (!snapshot || !snapshot.exists || !visibleIn(run.env, snapshot.get('visibleTo'))) return null;
|
|
225
|
+
return {
|
|
226
|
+
id: snapshot.id,
|
|
227
|
+
name: textOf(snapshot.get('name')) || textOf(snapshot.get('email'))
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* The fields a row's values write to a deal, over the deal as it stands
|
|
232
|
+
* (`current`, empty for a new one): each label judged against the org's
|
|
233
|
+
* lists, a link resolved, a blank clearing (`null`).
|
|
234
|
+
*/ async function dealFields(run, values, current) {
|
|
235
|
+
const fields = {};
|
|
236
|
+
const set = (field, value)=>{
|
|
237
|
+
fields[field] = value === undefined || value === '' ? null : value;
|
|
238
|
+
};
|
|
239
|
+
if ('title' in values) {
|
|
240
|
+
const title = textOf(values['title']).slice(0, 200);
|
|
241
|
+
if (!title) throw new TransferEngineError('invalid', 422, 'A deal needs a title.');
|
|
242
|
+
fields['title'] = title;
|
|
243
|
+
fields['titleLower'] = nameSearchKey(title);
|
|
244
|
+
}
|
|
245
|
+
if ('externalId' in values) set('externalId', textOf(values['externalId']).slice(0, 200) || null);
|
|
246
|
+
if ('amount' in values) {
|
|
247
|
+
const amount = values['amount'];
|
|
248
|
+
if (amount && typeof amount === 'object') {
|
|
249
|
+
fields['amountCents'] = amount.amountMinor;
|
|
250
|
+
fields['currency'] = String(amount.currency || DEFAULT_CURRENCY).toLowerCase();
|
|
251
|
+
} else fields['amountCents'] = null;
|
|
252
|
+
}
|
|
253
|
+
if ('expectedClose' in values) set('expectedCloseAtMs', storedDay(values['expectedClose']));
|
|
254
|
+
if ('owner' in values) set('ownerUid', textOf(values['owner']) || null);
|
|
255
|
+
if ('nextStep' in values) set('nextStep', textOf(values['nextStep']).slice(0, 255) || null);
|
|
256
|
+
if ('probability' in values) {
|
|
257
|
+
const probability = values['probability'];
|
|
258
|
+
if (probability !== null && (typeof probability !== 'number' || probability < 0 || probability > 100)) {
|
|
259
|
+
throw new TransferEngineError('invalid', 422, 'A probability is a percent from 0 to 100.');
|
|
260
|
+
}
|
|
261
|
+
set('probability', probability === null ? null : Math.round(probability));
|
|
262
|
+
}
|
|
263
|
+
if ('forecastCategory' in values) {
|
|
264
|
+
const label = textOf(values['forecastCategory']).toLowerCase();
|
|
265
|
+
const category = CRM_FORECAST_CATEGORIES.find((entry)=>CRM_FORECAST_CATEGORY_LABELS[entry].toLowerCase() === label);
|
|
266
|
+
set('forecastCategory', category != null ? category : null);
|
|
267
|
+
}
|
|
268
|
+
if ('lostReason' in values) set('lostReason', textOf(values['lostReason']).slice(0, 500) || null);
|
|
269
|
+
if ('notes' in values) set('notes', textOf(values['notes']).slice(0, 4000) || null);
|
|
270
|
+
for (const field of [
|
|
271
|
+
'type',
|
|
272
|
+
'leadSource'
|
|
273
|
+
]){
|
|
274
|
+
if (field in values) set(field, textOf(values[field]) || null);
|
|
275
|
+
}
|
|
276
|
+
if ('campaign' in values) {
|
|
277
|
+
var _run_campaigns_byName_get;
|
|
278
|
+
const name = textOf(values['campaign']);
|
|
279
|
+
const id = name ? (_run_campaigns_byName_get = run.campaigns.byName.get(name.toLowerCase())) != null ? _run_campaigns_byName_get : null : null;
|
|
280
|
+
if (name && !id) throw new TransferEngineError('invalid', 422, `No campaign is called “${name}”.`);
|
|
281
|
+
set('campaignId', id);
|
|
282
|
+
}
|
|
283
|
+
if ('company' in values) {
|
|
284
|
+
const value = values['company'];
|
|
285
|
+
if (value === null || value === undefined || value === '') {
|
|
286
|
+
fields['companyId'] = null;
|
|
287
|
+
fields['companyName'] = null;
|
|
288
|
+
} else {
|
|
289
|
+
const create = transferLookupNewName(value);
|
|
290
|
+
const company = create ? await companyForName(run.env, create, run.actorUid, run.companies, run.admit) : await (async ()=>{
|
|
291
|
+
const snapshot = await run.env.orgRef.collection(CRM_COLLECTIONS.companies).doc(String(value)).get();
|
|
292
|
+
return snapshot.exists && visibleIn(run.env, snapshot.get('visibleTo')) ? {
|
|
293
|
+
id: snapshot.id,
|
|
294
|
+
name: textOf(snapshot.get('name'))
|
|
295
|
+
} : null;
|
|
296
|
+
})();
|
|
297
|
+
if (!company) throw new TransferEngineError('invalid', 422, 'The company this row names could not be found or created.');
|
|
298
|
+
fields['companyId'] = company.id;
|
|
299
|
+
fields['companyName'] = company.name;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
// The contact and the roles: the Primary is `contactId`, written together.
|
|
303
|
+
let roles = dealContactRolesOf(current);
|
|
304
|
+
const rolesNamed = 'contactRoles' in values;
|
|
305
|
+
if (rolesNamed) {
|
|
306
|
+
var _run_lists_opportunityContactRole;
|
|
307
|
+
const next = [];
|
|
308
|
+
for (const { who, role } of parseRolesCell(values['contactRoles'])){
|
|
309
|
+
const contact = await contactFor(run, who);
|
|
310
|
+
if (!contact) throw new TransferEngineError('invalid', 422, `No contact this site sees is “${who}”.`);
|
|
311
|
+
if (!next.some((row)=>row.contactId === contact.id)) {
|
|
312
|
+
next.push(_extends({
|
|
313
|
+
contactId: contact.id
|
|
314
|
+
}, role ? {
|
|
315
|
+
role
|
|
316
|
+
} : {}, {
|
|
317
|
+
primary: next.length === 0
|
|
318
|
+
}));
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
const list = (_run_lists_opportunityContactRole = run.lists['opportunityContactRole']) == null ? void 0 : _run_lists_opportunityContactRole.set;
|
|
322
|
+
const judged = list ? judgeDealContactRoles(list, next, roles) : {
|
|
323
|
+
ok: true,
|
|
324
|
+
roles: next
|
|
325
|
+
};
|
|
326
|
+
if (judged.ok === false) throw new TransferEngineError('invalid', 422, judged.error);
|
|
327
|
+
roles = judged.roles;
|
|
328
|
+
}
|
|
329
|
+
if ('contact' in values) {
|
|
330
|
+
const contactId = textOf(values['contact']) || null;
|
|
331
|
+
roles = dealContactRolesWithPrimary(roles, contactId);
|
|
332
|
+
if (!contactId) roles = roles.map((row)=>_extends({}, row, {
|
|
333
|
+
primary: false
|
|
334
|
+
}));
|
|
335
|
+
}
|
|
336
|
+
if (rolesNamed || 'contact' in values) {
|
|
337
|
+
var _ref;
|
|
338
|
+
var _this;
|
|
339
|
+
const { contactRoles, contactId } = dealContactRoleFields(roles);
|
|
340
|
+
fields['contactRoles'] = contactRoles;
|
|
341
|
+
fields['contactId'] = contactId;
|
|
342
|
+
fields['contactName'] = contactId ? (_ref = (_this = await contactFor(run, contactId)) == null ? void 0 : _this.name) != null ? _ref : null : null;
|
|
343
|
+
}
|
|
344
|
+
return fields;
|
|
345
|
+
}
|
|
346
|
+
/** Fields as an update writes them: a cleared field is deleted. */ const asUpdate = (fields)=>Object.fromEntries(Object.entries(fields).map(([key, value])=>[
|
|
347
|
+
key,
|
|
348
|
+
value === null ? FieldValue.delete() : value
|
|
349
|
+
]));
|
|
350
|
+
/** Fields as a create writes them: a cleared field is simply absent. */ const asCreate = (fields)=>Object.fromEntries(Object.entries(fields).filter(([, value])=>value !== null && value !== undefined));
|
|
351
|
+
/** The `crm.deals` hooks. */ export function dealsTransferResource() {
|
|
352
|
+
return {
|
|
353
|
+
async fields (ctx) {
|
|
354
|
+
const env = await crmTransferEnv(ctx);
|
|
355
|
+
return {
|
|
356
|
+
standard: DEAL_TRANSFER_FIELDS,
|
|
357
|
+
derived: DEAL_TRANSFER_DERIVED,
|
|
358
|
+
system: CRM_TIMESTAMP_FIELDS,
|
|
359
|
+
custom: crmCustomTransferFields(await crmCustomDefinitions(env, 'deal'), 'deal'),
|
|
360
|
+
groups: DEAL_TRANSFER_GROUPS
|
|
361
|
+
};
|
|
362
|
+
},
|
|
363
|
+
matchKeys: [
|
|
364
|
+
{
|
|
365
|
+
fieldId: TRANSFER_ID_FIELD,
|
|
366
|
+
normalizer: 'aglynId'
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
fieldId: 'externalId',
|
|
370
|
+
normalizer: 'externalId'
|
|
371
|
+
}
|
|
372
|
+
],
|
|
373
|
+
aliases: DEAL_ALIASES,
|
|
374
|
+
lookupTargets: {
|
|
375
|
+
[CRM_MEMBERS_TARGET]: crmMembersTarget()
|
|
376
|
+
},
|
|
377
|
+
async count (ctx, options) {
|
|
378
|
+
const env = await crmTransferEnv(ctx);
|
|
379
|
+
requireCrmRecords(env, 'deals');
|
|
380
|
+
return countCrmExport(env, dealsOf(env), options, (data)=>visibleIn(env, data['visibleTo'], options.scopeTokens));
|
|
381
|
+
},
|
|
382
|
+
async readPage (ctx, cursor, fieldIds, options) {
|
|
383
|
+
const env = await crmTransferEnv(ctx);
|
|
384
|
+
requireCrmRecords(env, 'deals');
|
|
385
|
+
const definitions = await crmCustomDefinitions(env, 'deal');
|
|
386
|
+
const emails = fieldIds.includes('owner') ? await crmMemberEmails(env.orgId) : new Map();
|
|
387
|
+
const pipelines = fieldIds.some((id)=>id === 'pipeline' || id === 'stage') ? await readPipelines(env) : [];
|
|
388
|
+
const campaigns = fieldIds.includes('campaign') ? await campaignDirectory(env) : null;
|
|
389
|
+
return readCrmExportPage(env, dealsOf(env), cursor, options, (data)=>visibleIn(env, data['visibleTo'], options == null ? void 0 : options.scopeTokens), async (docs)=>{
|
|
390
|
+
// People and companies by the words a file carries: a contact's email, a company's name.
|
|
391
|
+
const contactIds = new Set();
|
|
392
|
+
const companyIds = new Set();
|
|
393
|
+
for (const doc of docs){
|
|
394
|
+
for (const row of dealContactRolesOf(doc.data))contactIds.add(row.contactId);
|
|
395
|
+
const companyId = textOf(doc.data['companyId']);
|
|
396
|
+
if (companyId) companyIds.add(companyId);
|
|
397
|
+
}
|
|
398
|
+
const emailsOf = new Map();
|
|
399
|
+
const companyNames = new Map();
|
|
400
|
+
if (fieldIds.includes('contact') || fieldIds.includes('contactRoles')) {
|
|
401
|
+
const ids = [
|
|
402
|
+
...contactIds
|
|
403
|
+
].filter((id)=>!id.includes('/'));
|
|
404
|
+
for(let at = 0; at < ids.length; at += 500){
|
|
405
|
+
for (const snapshot of (await env.firestore.getAll(...ids.slice(at, at + 500).map((id)=>contactsOf(env).doc(id))))){
|
|
406
|
+
if (snapshot.exists) emailsOf.set(snapshot.id, textOf(snapshot.get('email')));
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
if (fieldIds.includes('company')) {
|
|
411
|
+
const ids = [
|
|
412
|
+
...companyIds
|
|
413
|
+
].filter((id)=>!id.includes('/'));
|
|
414
|
+
for(let at = 0; at < ids.length; at += 500){
|
|
415
|
+
const refs = ids.slice(at, at + 500).map((id)=>env.orgRef.collection(CRM_COLLECTIONS.companies).doc(id));
|
|
416
|
+
for (const snapshot of (await env.firestore.getAll(...refs))){
|
|
417
|
+
if (snapshot.exists) companyNames.set(snapshot.id, textOf(snapshot.get('name')));
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
const names = {
|
|
422
|
+
display: true,
|
|
423
|
+
owner: (uid)=>emails.get(uid),
|
|
424
|
+
contact: (id)=>emailsOf.get(id) || undefined,
|
|
425
|
+
roleContact: (id)=>emailsOf.get(id) || undefined,
|
|
426
|
+
company: (id)=>companyNames.get(id) || undefined,
|
|
427
|
+
campaign: (id)=>campaigns == null ? void 0 : campaigns.names.get(id),
|
|
428
|
+
pipeline: (id)=>{
|
|
429
|
+
var _pipelines_find;
|
|
430
|
+
return (_pipelines_find = pipelines.find((choice)=>choice.id === id)) == null ? void 0 : _pipelines_find.pipeline.name;
|
|
431
|
+
},
|
|
432
|
+
stage: (pipelineId, stageId)=>{
|
|
433
|
+
var _pipelines_find_stages_find, _pipelines_find;
|
|
434
|
+
return (_pipelines_find = pipelines.find((choice)=>choice.id === pipelineId)) == null ? void 0 : (_pipelines_find_stages_find = _pipelines_find.stages.find((stage)=>stage.id === stageId)) == null ? void 0 : _pipelines_find_stages_find.name;
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
return docs.map((doc)=>pickValues(dealTransferValues(doc.id, doc.data, definitions, names), fieldIds));
|
|
438
|
+
});
|
|
439
|
+
},
|
|
440
|
+
async lookup (ctx, requests) {
|
|
441
|
+
const env = await crmTransferEnv(ctx);
|
|
442
|
+
const definitions = await crmCustomDefinitions(env, 'deal');
|
|
443
|
+
const visible = (data)=>visibleIn(env, data['visibleTo']);
|
|
444
|
+
const found = {
|
|
445
|
+
lookup: new Map(),
|
|
446
|
+
docs: new Map()
|
|
447
|
+
};
|
|
448
|
+
for (const request of requests){
|
|
449
|
+
if (request.fieldId === TRANSFER_ID_FIELD) await lookupById(env, dealsOf(env), request, visible, found);
|
|
450
|
+
else if (request.fieldId === 'externalId') {
|
|
451
|
+
await lookupByField(dealsOf(env), request, 'externalId', (value)=>value.trim(), visible, found);
|
|
452
|
+
} else if (request.fieldId === 'title') {
|
|
453
|
+
await lookupByField(dealsOf(env), request, 'titleLower', (value)=>nameSearchKey(value), visible, found);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
const names = await wordNames(env, [
|
|
457
|
+
...found.docs.values()
|
|
458
|
+
]);
|
|
459
|
+
return lookupResult(found, (id, data)=>dealTransferValues(id, data, definitions, names));
|
|
460
|
+
},
|
|
461
|
+
async suggest (ctx, request) {
|
|
462
|
+
const env = await crmTransferEnv(ctx);
|
|
463
|
+
const answer = {};
|
|
464
|
+
for (const value of request.values){
|
|
465
|
+
var _nameSearchKey_split_;
|
|
466
|
+
const first = (_nameSearchKey_split_ = nameSearchKey(value).split(' ')[0]) != null ? _nameSearchKey_split_ : '';
|
|
467
|
+
if (first.length < 2) {
|
|
468
|
+
answer[value] = [];
|
|
469
|
+
continue;
|
|
470
|
+
}
|
|
471
|
+
const snapshot = await dealsOf(env).where('titleLower', '>=', first).where('titleLower', '<', `${first}`).limit(IN_LIMIT).get();
|
|
472
|
+
answer[value] = rankTransferLookupSuggestions(value, snapshot.docs.filter((doc)=>visibleIn(env, doc.get('visibleTo'))).map((doc)=>({
|
|
473
|
+
recordId: doc.id,
|
|
474
|
+
label: textOf(doc.get('title')) || doc.id
|
|
475
|
+
})));
|
|
476
|
+
}
|
|
477
|
+
return answer;
|
|
478
|
+
},
|
|
479
|
+
async picklists (ctx, ids) {
|
|
480
|
+
const env = await crmTransferEnv(ctx);
|
|
481
|
+
return crmPicklistLists(env, ids, await crmCustomDefinitions(env, 'deal'));
|
|
482
|
+
},
|
|
483
|
+
async addPicklistValues (ctx, picklistId, values) {
|
|
484
|
+
await addCrmPicklistValues(await crmTransferEnv(ctx), picklistId, values);
|
|
485
|
+
},
|
|
486
|
+
lockedRules: ()=>[
|
|
487
|
+
{
|
|
488
|
+
fieldId: 'pipeline',
|
|
489
|
+
reason: 'A deal moves between pipelines and stages on the board, where the move tells your automations; an import sets them only on a new deal.',
|
|
490
|
+
forced: {
|
|
491
|
+
mode: 'keepExisting'
|
|
492
|
+
}
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
fieldId: 'stage',
|
|
496
|
+
reason: 'A deal moves between stages on the board, where the move tells your automations; an import sets the stage only on a new deal.',
|
|
497
|
+
forced: {
|
|
498
|
+
mode: 'keepExisting'
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
],
|
|
502
|
+
async plan (ctx, input) {
|
|
503
|
+
const env = await crmTransferEnv(ctx);
|
|
504
|
+
requireCrmSuite(env, SUITE_ACT);
|
|
505
|
+
requireSite(env, 'deals');
|
|
506
|
+
return buildTransferPlan(input);
|
|
507
|
+
},
|
|
508
|
+
async apply (ctx, chunk, writer) {
|
|
509
|
+
const env = await crmTransferEnv(ctx);
|
|
510
|
+
requireCrmSuite(env, SUITE_ACT);
|
|
511
|
+
requireSite(env, 'deals');
|
|
512
|
+
const run = {
|
|
513
|
+
env,
|
|
514
|
+
actorUid: ctx.actorUid,
|
|
515
|
+
definitions: await crmCustomDefinitions(env, 'deal'),
|
|
516
|
+
pipelines: await readPipelines(env),
|
|
517
|
+
lists: await crmPicklistLists(env, [
|
|
518
|
+
'opportunityContactRole',
|
|
519
|
+
'opportunityType'
|
|
520
|
+
], []),
|
|
521
|
+
campaigns: await campaignDirectory(env),
|
|
522
|
+
companies: new Map(),
|
|
523
|
+
admit: crmRecordsRoom(env)
|
|
524
|
+
};
|
|
525
|
+
let counted = null;
|
|
526
|
+
let createdHere = 0;
|
|
527
|
+
const results = [];
|
|
528
|
+
const undo = [];
|
|
529
|
+
await eachWithinBudget(chunk.rows, ()=>writer.timeLeftMs(), async (row)=>{
|
|
530
|
+
const earlier = await writer.alreadyApplied(row.index);
|
|
531
|
+
if (earlier) {
|
|
532
|
+
results.push(earlier);
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
const changed = row.diff.map((change)=>change.fieldId);
|
|
536
|
+
let result;
|
|
537
|
+
let entry;
|
|
538
|
+
try {
|
|
539
|
+
const values = plannedValues(row);
|
|
540
|
+
if (row.verdict === 'update' && row.recordId) {
|
|
541
|
+
var _get;
|
|
542
|
+
const ref = dealsOf(env).doc(row.recordId);
|
|
543
|
+
const current = (await ref.get()).data();
|
|
544
|
+
if (!current || !visibleIn(env, current['visibleTo'])) throw new TransferEngineError('notFound', 404, 'That deal no longer exists.');
|
|
545
|
+
const before = dealTransferValues(ref.id, current, run.definitions);
|
|
546
|
+
const fields = await dealFields(run, values, current);
|
|
547
|
+
const custom = customWriteValues(values, run.definitions, 'deal');
|
|
548
|
+
if ('error' in custom) throw new TransferEngineError('invalid', 422, custom.error);
|
|
549
|
+
await ref.update(_extends({}, asUpdate(fields), Object.fromEntries(Object.entries(custom.values).map(([key, value])=>[
|
|
550
|
+
`custom.${key}`,
|
|
551
|
+
value
|
|
552
|
+
])), crmListFields('deals', _extends({}, current, fields)), {
|
|
553
|
+
updatedAt: FieldValue.serverTimestamp()
|
|
554
|
+
}));
|
|
555
|
+
const after = (_get = (await readDeals(env, [
|
|
556
|
+
ref.id
|
|
557
|
+
], run.definitions)).get(ref.id)) != null ? _get : {};
|
|
558
|
+
result = {
|
|
559
|
+
row: row.index,
|
|
560
|
+
outcome: 'updated',
|
|
561
|
+
recordId: ref.id
|
|
562
|
+
};
|
|
563
|
+
entry = {
|
|
564
|
+
row: row.index,
|
|
565
|
+
recordId: ref.id,
|
|
566
|
+
action: 'updated',
|
|
567
|
+
previous: pickValues(before, changed),
|
|
568
|
+
written: pickValues(after, changed)
|
|
569
|
+
};
|
|
570
|
+
} else {
|
|
571
|
+
var _fields_forecastCategory, _get1;
|
|
572
|
+
const placed = placeDeal(run.pipelines, textOf(values['pipeline']), textOf(values['stage']));
|
|
573
|
+
if ('error' in placed) throw new TransferEngineError('invalid', 422, placed.error);
|
|
574
|
+
counted != null ? counted : counted = await crmRecordsQuotaForOrg(env.org, env.orgRef);
|
|
575
|
+
if (!checkCrmRecordsQuota(env.org, counted.crmRecordsCount + createdHere).allowed) {
|
|
576
|
+
throw new TransferEngineError('invalid', 422, 'The CRM records limit is reached.');
|
|
577
|
+
}
|
|
578
|
+
const fields = asCreate(await dealFields(run, values, {}));
|
|
579
|
+
// A new deal with no Type starts on the list's default, as the deal form does.
|
|
580
|
+
const typeDefault = run.lists['opportunityType'] ? crmPicklistDefaultLabel(run.lists['opportunityType'].set) : null;
|
|
581
|
+
if (!fields['type'] && typeDefault) fields['type'] = typeDefault;
|
|
582
|
+
const custom = customWriteValues(values, run.definitions, 'deal');
|
|
583
|
+
if ('error' in custom) throw new TransferEngineError('invalid', 422, custom.error);
|
|
584
|
+
const { stage } = placed;
|
|
585
|
+
const status = stage.kind === 'won' ? 'won' : stage.kind === 'lost' ? 'lost' : 'open';
|
|
586
|
+
const nowMs = Date.now();
|
|
587
|
+
const scope = creationScope(env, ctx.actorUid);
|
|
588
|
+
const ref = dealsOf(env).doc(createResourceUid());
|
|
589
|
+
const opportunity = {
|
|
590
|
+
forecastCategory: (_fields_forecastCategory = fields['forecastCategory']) != null ? _fields_forecastCategory : dealStageForecastCategory(stage)
|
|
591
|
+
};
|
|
592
|
+
await ref.set(_extends({
|
|
593
|
+
currency: DEFAULT_CURRENCY
|
|
594
|
+
}, fields, opportunity, {
|
|
595
|
+
pipelineId: placed.pipeline.id,
|
|
596
|
+
stageId: stage.id,
|
|
597
|
+
status,
|
|
598
|
+
stageChangedAtMs: nowMs,
|
|
599
|
+
closedAtMs: status === 'open' ? null : nowMs
|
|
600
|
+
}, Object.keys(custom.values).length ? {
|
|
601
|
+
custom: custom.values
|
|
602
|
+
} : {}, scope, crmNewRecordListFields('deals', _extends({}, fields, opportunity, scope))));
|
|
603
|
+
createdHere += 1;
|
|
604
|
+
const after = (_get1 = (await readDeals(env, [
|
|
605
|
+
ref.id
|
|
606
|
+
], run.definitions)).get(ref.id)) != null ? _get1 : {};
|
|
607
|
+
result = {
|
|
608
|
+
row: row.index,
|
|
609
|
+
outcome: 'created',
|
|
610
|
+
recordId: ref.id
|
|
611
|
+
};
|
|
612
|
+
entry = {
|
|
613
|
+
row: row.index,
|
|
614
|
+
recordId: ref.id,
|
|
615
|
+
action: 'created',
|
|
616
|
+
written: pickValues(after, changed)
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
} catch (error) {
|
|
620
|
+
result = _extends({
|
|
621
|
+
row: row.index,
|
|
622
|
+
outcome: 'failed'
|
|
623
|
+
}, row.recordId ? {
|
|
624
|
+
recordId: row.recordId
|
|
625
|
+
} : {}, {
|
|
626
|
+
message: failureMessage(error)
|
|
627
|
+
});
|
|
628
|
+
entry = undefined;
|
|
629
|
+
}
|
|
630
|
+
await writer.markApplied(result, entry);
|
|
631
|
+
results.push(result);
|
|
632
|
+
if (entry) undo.push(entry);
|
|
633
|
+
});
|
|
634
|
+
return {
|
|
635
|
+
results,
|
|
636
|
+
undo
|
|
637
|
+
};
|
|
638
|
+
},
|
|
639
|
+
async revert (ctx, snapshot, decisions) {
|
|
640
|
+
const env = await crmTransferEnv(ctx);
|
|
641
|
+
const run = {
|
|
642
|
+
env,
|
|
643
|
+
actorUid: ctx.actorUid,
|
|
644
|
+
definitions: await crmCustomDefinitions(env, 'deal'),
|
|
645
|
+
pipelines: [],
|
|
646
|
+
lists: {},
|
|
647
|
+
campaigns: await campaignDirectory(env),
|
|
648
|
+
companies: new Map(),
|
|
649
|
+
admit: crmRecordsRoom(env)
|
|
650
|
+
};
|
|
651
|
+
const current = await readDeals(env, snapshot.entries.map((entry)=>entry.recordId), run.definitions);
|
|
652
|
+
const done = [];
|
|
653
|
+
const conflicts = [];
|
|
654
|
+
const touched = [];
|
|
655
|
+
for (const entry of snapshot.entries){
|
|
656
|
+
var _current_get, _data;
|
|
657
|
+
const step = planTransferUndo(entry, (_current_get = current.get(entry.recordId)) != null ? _current_get : null);
|
|
658
|
+
if (step.action === 'conflict' && (decisions == null ? void 0 : decisions[entry.recordId]) !== 'revert') {
|
|
659
|
+
if ((decisions == null ? void 0 : decisions[entry.recordId]) === 'keep') done.push({
|
|
660
|
+
action: 'nothing',
|
|
661
|
+
recordId: entry.recordId,
|
|
662
|
+
why: 'alreadyReverted'
|
|
663
|
+
});
|
|
664
|
+
else conflicts.push(step);
|
|
665
|
+
continue;
|
|
666
|
+
}
|
|
667
|
+
if (step.action === 'nothing') {
|
|
668
|
+
done.push(step);
|
|
669
|
+
continue;
|
|
670
|
+
}
|
|
671
|
+
const ref = dealsOf(env).doc(entry.recordId);
|
|
672
|
+
if (entry.action === 'created') {
|
|
673
|
+
await ref.delete();
|
|
674
|
+
done.push({
|
|
675
|
+
action: 'delete',
|
|
676
|
+
recordId: entry.recordId
|
|
677
|
+
});
|
|
678
|
+
continue;
|
|
679
|
+
}
|
|
680
|
+
const values = step.action === 'restore' || step.action === 'conflict' ? step.values : {};
|
|
681
|
+
const stored = (_data = (await ref.get()).data()) != null ? _data : {};
|
|
682
|
+
const fields = await dealFields(run, values, stored);
|
|
683
|
+
await ref.update(_extends({}, asUpdate(fields), crmListFields('deals', _extends({}, stored, fields)), {
|
|
684
|
+
updatedAt: FieldValue.serverTimestamp()
|
|
685
|
+
}));
|
|
686
|
+
touched.push(ref);
|
|
687
|
+
done.push(step);
|
|
688
|
+
}
|
|
689
|
+
if (touched.length) await restampCrmListFieldsOf(touched, 'deals').catch(()=>undefined);
|
|
690
|
+
return {
|
|
691
|
+
done,
|
|
692
|
+
conflicts
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
//# sourceMappingURL=deals.js.map
|