Accounts

This refers to the organizations that are your customers or potential customers. You’d typically track information about the company such as industry, size, location, and any ongoing projects or deals.

In Obsidian, you can create a note for each company and link it to related notes, such as contacts at the company, opportunities, and interactions. This can help you maintain a holistic view of your relationship with each company.

Relationships

Lean CRM - Structure.png

Fields

Queries

dataview
TABLE WITHOUT ID
	file.link AS "Name",
	Role,
	E-mail,
	choice(main-contact,"✅","❌") AS "Main?",
	choice(Active,"✅","❌") AS "Active?"
FROM "CRM/Contacts"
WHERE Account = this.account
	AND file.name != this.file.name
SORT Name ASC

Open

Table

dataview
TABLE WITHOUT ID
  file.link AS "Opportunity",
  Phase,
  Products AS "Products",
  Value AS "Value",
  Probability AS "Probability",
  weighted-value AS "Weighted"
FROM "CRM/Opportunities"
WHERE Account = this.Account
	AND !contains(Phase, "Closed")
SORT Name ASC

Total value

dataviewjs
const opportunities = dv.pages('"CRM/Opportunities"')
	.where(p => p.Account === dv.current().file.name && !(p.Phase + "").toLowerCase().includes("closed"))
	.array();
const totalValue = opportunities.reduce((total, p) => total + (p.Value || 0), 0);
dv.paragraph( totalValue.toLocaleString());

Won

Table

dataview
TABLE WITHOUT ID
  file.link AS "Opportunity",
  Products AS "Products",
  Value AS "Value"
FROM "CRM/Opportunities"
WHERE Account = this.Account
	AND contains(Phase, "Won")
SORT Name ASC

Total value

dataviewjs
const opportunities = dv.pages('"CRM/Opportunities"')
	.where(p => p.Account === dv.current().file.name && (p.Phase + "").toLowerCase().includes("won"))
	.array();
const totalValue = opportunities.reduce((total, p) => total + (p.Value || 0), 0);
dv.paragraph( totalValue.toLocaleString());

Lost

Table

dataview
TABLE WITHOUT ID
  file.link AS "Opportunity",
  Products AS "Products",
  Value AS "Value"
FROM "CRM/Opportunities"
WHERE Account = this.Account
	AND contains(Phase, "Lost")
SORT Name

Total value

dataviewjs
const opportunities = dv.pages('"CRM/Opportunities"')
	.where(p => p.Account === dv.current().file.name && (p.Phase + "").toLowerCase().includes("lost"))
	.array();
const totalValue = opportunities.reduce((total, p) => total + (p.Value || 0), 0);
dv.paragraph( totalValue.toLocaleString());

Table

dataview
TABLE WITHOUT ID
	file.link AS "Interaction",
	Activity,
	Opportunities AS "Opportunity",
	dateformat(created, "yyyy-MM-dd") AS "Date"
FROM "CRM/Interactions"
WHERE Account = this.Account
SORT Date DESC
LIMIT 10

Lifetime Revenue

Open

dataviewjs
const accountName = dv.current().file.name;
let totalValue = 0;
dv.pages('"CRM/Opportunities"')
	.where(page => page.Account === accountName && page.Phase && !(page.Phase + "").toLowerCase().includes('closed') && page.Value)
	.array()
	.forEach(page => {
		totalValue += page.Value;
	});
dv.paragraph(`${totalValue.toLocaleString()}`);

Won

dataviewjs
const accountName = dv.current().file.name;
let totalValue = 0;
dv.pages('"CRM/Opportunities"')
	.where(page => page.Account === accountName && page.Phase && (page.Phase + "").toLowerCase().includes('won') && page.Value)
	.array()
	.forEach(page => {
		totalValue += page.Value;
	});
dv.paragraph(`${totalValue.toLocaleString()}`);

Lost

dataviewjs
const accountName = dv.current().file.name;
let totalValue = 0;
dv.pages('"CRM/Opportunities"')
	.where(page => page.Account === accountName && page.Phase && (page.Phase + "").toLowerCase().includes('lost') && page.Value)
	.array()
	.forEach(page => {
		totalValue += page.Value;
	});
dv.paragraph(`${totalValue.toLocaleString()}`);

Total

dataviewjs
const accountName = dv.current().file.name;
let totalValue = 0;
dv.pages('"CRM/Opportunities"')
  .where(page => page.Account === accountName && page.Value)
  .array()
  .forEach(page => {
      totalValue += page.Value;
  });
dv.paragraph(`${totalValue.toLocaleString()}`);