diff options
| author | Szymon Szukalski <szymon@szymonszukalski.com> | 2026-04-09 10:10:25 +1000 |
|---|---|---|
| committer | Szymon Szukalski <szymon@szymonszukalski.com> | 2026-04-09 10:10:25 +1000 |
| commit | 48dcdc4ed105a8a05f1345c0b00fe8c9bf511670 (patch) | |
| tree | aa898ddf53335e92c2b206238ab98a5728303bde /config.org | |
| parent | a9cb41ef7ae6fbd46dc6ff446c86b5df08f324b3 (diff) | |
Extend CRM supplier support
Diffstat (limited to 'config.org')
| -rw-r--r-- | config.org | 61 |
1 files changed, 54 insertions, 7 deletions
@@ -297,8 +297,10 @@ overview mode, direct visits reset back to overview mode, and exiting card view means widening the buffer and restoring that overview. Keep =CURRENT_FOCUS= short and phrase-like so summaries and completion annotations stay readable. Person cards use a flat property model in this order: =ROLE=, =TEAM=, -=MANAGER=, =ENGAGEMENT=, =LOCATION=, and =CURRENT_FOCUS=. =ABBREV= and -=ALIASES= remain optional helpers for lookup and insertion. +=MANAGER=, =ENGAGEMENT=, =SUPPLIER=, =LOCATION=, and =CURRENT_FOCUS=. +=ENGAGEMENT= and =SUPPLIER= both use fixed lookup lists in =ss/crm-add= so +reports stay consistent. =ABBREV= and =ALIASES= remain optional helpers for +lookup and insertion. #+begin_src emacs-lisp (require 'seq) @@ -309,9 +311,17 @@ Person cards use a flat property model in this order: =ROLE=, =TEAM=, (expand-file-name "areas/people/people.org" "~/org/") "Single source of truth for the people CRM.") - (defconst ss/crm-engagement-values - '("permanent" "contractor" "other") - "Allowed engagement values for people cards.") + (defconst ss/crm-engagement-options + '("Perm" "SOW" "SOW Fixed Outcome" "NCS India") + "Canonical engagement values for people cards.") + + (defconst ss/crm-supplier-options + '("Accenture Song" + "INFOSYS TECHNOLOGIES LIMITED" + "MAKK Integrations Pty Ltd" + "NCSI Technologies India Private Limited" + "TECH MAHINDRA LTD") + "Canonical supplier values for people cards.") (defvar ss/crm--cache nil "Cached CRM entries loaded from `ss/crm-file'.") @@ -343,6 +353,10 @@ Person cards use a flat property model in this order: =ROLE=, =TEAM=, "Return the engagement in ENTRY." (plist-get entry :engagement)) + (defun ss/crm--entry-supplier (entry) + "Return the supplier in ENTRY." + (plist-get entry :supplier)) + (defun ss/crm--entry-manager (entry) "Return the manager in ENTRY." (plist-get entry :manager)) @@ -429,6 +443,7 @@ Person cards use a flat property model in this order: =ROLE=, =TEAM=, :team (org-entry-get nil "TEAM") :manager (org-entry-get nil "MANAGER") :engagement (org-entry-get nil "ENGAGEMENT") + :supplier (org-entry-get nil "SUPPLIER") :location (org-entry-get nil "LOCATION") :current-focus (org-entry-get nil "CURRENT_FOCUS") ) @@ -620,6 +635,35 @@ Person cards use a flat property model in this order: =ROLE=, =TEAM=, "People by engagement" #'ss/crm--entry-engagement)) + (defun ss/crm-report-by-supplier () + "Show non-empty suppliers grouped by supplier." + (interactive) + (let ((groups + (sort (seq-group-by + #'ss/crm--entry-supplier + (seq-filter + (lambda (entry) + (not (string-empty-p (or (ss/crm--entry-supplier entry) "")))) + (ss/crm-entries))) + (lambda (left right) + (string< (car left) (car right)))))) + (with-current-buffer (get-buffer-create "*People Report*") + (let ((inhibit-read-only t)) + (erase-buffer) + (org-mode) + (insert "#+title: People by supplier\n\n") + (dolist (group groups) + (insert "* " (car group) "\n") + (dolist (entry (sort (copy-sequence (cdr group)) + (lambda (left right) + (string< (ss/crm--entry-name left) + (ss/crm--entry-name right))))) + (insert "- " (ss/crm--display entry) "\n"))) + (goto-char (point-min)) + (read-only-mode 1) + (view-mode 1)) + (pop-to-buffer (current-buffer))))) + (defun ss/crm-report-by-role () "Show people grouped by role." (interactive) @@ -661,8 +705,9 @@ Person cards use a flat property model in this order: =ROLE=, =TEAM=, (team (ss/crm-read-required-string "Team: ")) (manager (ss/crm-read-required-string "Manager: ")) (engagement (completing-read "Engagement: " - ss/crm-engagement-values nil t nil nil - "permanent")) + ss/crm-engagement-options nil t)) + (supplier (completing-read "Supplier: " + ss/crm-supplier-options nil t)) (location (ss/crm-read-required-string "Location: ")) (current-focus (ss/crm-read-required-string "Current focus: ")) ) @@ -685,6 +730,7 @@ Person cards use a flat property model in this order: =ROLE=, =TEAM=, (ss/crm--property-line "TEAM" team) (ss/crm--property-line "MANAGER" manager) (ss/crm--property-line "ENGAGEMENT" engagement) + (ss/crm--property-line "SUPPLIER" supplier) (ss/crm--property-line "LOCATION" location) (ss/crm--property-line "CURRENT_FOCUS" current-focus) ":END:\n\n" @@ -1005,6 +1051,7 @@ When CREATE is non-nil, create the datetree entry when missing." ("C-c n p" . ss/crm-open) ("C-c n P" . ss/crm-add) ("C-c n R" . ss/crm-report-by-manager) + ("C-c n S" . ss/crm-report-by-supplier) ("C-c n T" . ss/crm-report-by-team)) :config (setq org-directory ss/org-directory |
