kiuwan
December 20, 2024, 12:12pm
1
What I’m trying to do
I have aDaily Note like everyone here I assume, I have a task under
Learn
and every time the task is done I want to reward myself $40 Dollar for shopping
I want to build a equation that every time a check my task in my daily note it automatically add $40 dollar to my Shopping Bag, and when I buy new things I could type it in a list and it deduct the money from my shopping bag
Things I have tried
I am using a tracker plug, it successfully did the first part of the job add $40 each time
searchType: task.done
searchTarget: Learning Log
folder: /01-Daily Note
endDate: 31 December, Tuesday
bullet:
title: ""
dataset:
orientation: vertical
range: 700
rangeColor: orange
value: "{{sum()*40}}"
valueUnit: $$
valueColor: white
showMarker: true
markerValue:
markerColor: orange
Rios
December 25, 2024, 6:40pm
2
Here is the solution
// Configuration
const dailyNotesFolder = "your/daily/notes/folder";
const rewardAmount = 40;
const headerToMatch = "Learn";
const showOverallCalculations = true; // Set to false to hide overall calculations
// Function to calculate total earned for a given set of notes
function calculateTotalEarned(notes) {
return notes.reduce((sum, page) => {
if (!page.file.tasks) return sum;
const learnTasks = page.file.tasks.filter(task => task.header && task.header.subpath === headerToMatch);
const completedLearnTasks = learnTasks.filter(task => task.completed);
return sum + (completedLearnTasks.length * rewardAmount);
}, 0);
}
// Function to calculate total spent for a given set of notes
function calculateTotalSpent(notes) {
return notes.reduce((sum, page) => {
if (!page.file.lists) return sum;
const shoppingExpenses = page.file.lists.filter(l => l.section && l.section.subpath === "Shopping Expenses");
const regex = /.+ - ?\$(\d+)/;
let total = 0;
shoppingExpenses.forEach(listItem => {
const match = listItem.text.match(regex);
if (match && match[1]) {
total += parseInt(match[1]);
}
});
return sum + total;
}, 0);
}
// Main execution
(async () => {
let dailyNotes = [];
try {
dailyNotes = dv.pages(`"${dailyNotesFolder}"`);
} catch (error) {
dv.paragraph("Error: Invalid daily notes folder path or folder does not exist.");
console.error("Dataview Error:", error);
return;
}
if (!DataviewAPI.isDataArray(dailyNotes)) {
dv.paragraph("Error: `dv.pages` did not return a valid DataArray.");
return;
}
const dailyNotesArray = dailyNotes.array();
// --- Individual Calculations (Current Note) ---
const activeNote = app.workspace.getActiveFile();
if (!activeNote || activeNote.extension !== "md") {
dv.paragraph("Error: No active markdown file found.");
return;
}
const currentPage = dv.page(activeNote.path);
if (!currentPage) {
dv.paragraph("Error: Could not retrieve data for the current note.");
return;
}
const individualTotalEarned = calculateTotalEarned([currentPage]); // Pass only the current page
const individualTotalSpent = calculateTotalSpent([currentPage]); // Pass only the current page
// Get last recorded balance and change from Dataview output for individual calculations
let individualLastBalance = 0;
let individualLastChange = "";
const dataviewParagraphs = document.querySelectorAll('p');
for (let i = dataviewParagraphs.length - 1; i >= 0; i--) {
const paragraphText = dataviewParagraphs[i].textContent;
if (paragraphText.startsWith('Current Individual Balance: $')) {
individualLastBalance = parseFloat(paragraphText.split('$')[1]);
break;
}
}
for (let i = dataviewParagraphs.length - 1; i >= 0; i--) {
const paragraphText = dataviewParagraphs[i].textContent;
if (paragraphText.startsWith('Individual Last Change: ')) {
individualLastChange = paragraphText.split(': ')[1];
break;
}
}
const individualNetChangeAmount = individualTotalEarned - individualTotalSpent;
const individualNewChange = individualNetChangeAmount !== 0 ? (individualNetChangeAmount > 0 ? "+" : "") + individualNetChangeAmount : individualLastChange;
const individualNewBalance = parseFloat((individualLastBalance + individualNetChangeAmount).toFixed(2));
// --- Display Individual Calculations ---
dv.paragraph("## Shopping Bag");
dv.paragraph("### Current Day");
if (individualNewChange !== individualLastChange || individualLastBalance !== individualNewBalance) {
dv.paragraph(`**Total Earned:** $${individualTotalEarned}`);
dv.paragraph(`**Total Spent:** $${individualTotalSpent}`);
dv.paragraph(`**Current Day Balance:** $${individualNewBalance}`);
} else {
dv.paragraph("No new changes detected for the current note.");
}
// --- Overall Calculations (All Notes) ---
if (showOverallCalculations) {
const overallTotalEarned = calculateTotalEarned(dailyNotesArray); // Pass all daily notes
const overallTotalSpent = calculateTotalSpent(dailyNotesArray); // Pass all daily notes
// Get last recorded balance and change from Dataview output for overall calculations
let overallLastBalance = 0;
let overallLastChange = "";
for (let i = dataviewParagraphs.length - 1; i >= 0; i--) {
const paragraphText = dataviewParagraphs[i].textContent;
if (paragraphText.startsWith('Current Overall Balance: $')) {
overallLastBalance = parseFloat(paragraphText.split('$')[1]);
break;
}
}
for (let i = dataviewParagraphs.length - 1; i >= 0; i--) {
const paragraphText = dataviewParagraphs[i].textContent;
if (paragraphText.startsWith('Overall Last Change: ')) {
overallLastChange = paragraphText.split(': ')[1];
break;
}
}
const overallNetChangeAmount = overallTotalEarned - overallTotalSpent;
const overallNewChange = overallNetChangeAmount !== 0 ? (overallNetChangeAmount > 0 ? "+" : "") + overallNetChangeAmount : overallLastChange;
const overallNewBalance = parseFloat((overallLastBalance + overallNetChangeAmount).toFixed(2));
// --- Display Overall Calculations ---
dv.paragraph("### All Days");
if (overallNewChange !== overallLastChange || overallLastBalance !== overallNewBalance) {
dv.paragraph(`**Total Earned:** $${overallTotalEarned}`);
dv.paragraph(`**Total Spent:** $${overallTotalSpent}`);
dv.paragraph(`**Current Overall Balance:** $${overallNewBalance}`);
} else {
dv.paragraph("No new overall changes detected or invalid folder path.");
}
}
})();
The Result
Note: If you want to hide the all-days calculations, change showOverallCalculations = true;
to false.
holroy
December 26, 2024, 10:59am
3
When and how do you think to update the shopping bag? What is your current syntax for deducting money? Do you ever reset the shopping bag, or will you five years from now still count all tasks and add 40$ to the shopping bag?
And why are your using the Tracker plugin for this kind of task, instead of dataview (or possibly the Tasks plugin (not sure if it can do calculations)).