diff --git a/m1well.Expenses/CHANGELOG.md b/m1well.Expenses/CHANGELOG.md index be62d32b8..e58176205 100644 --- a/m1well.Expenses/CHANGELOG.md +++ b/m1well.Expenses/CHANGELOG.md @@ -1,5 +1,10 @@ # m1well.Expenses Plugin Changelog +## [1.7.0] - 2022-02-10 (@m1well) +### Added +- Add possiblity to do configuration via the new plugin settings section +- But also downwards compatible + ## [1.6.0] - 2022-01-05 (@m1well) ### Changed - Load tracking notes via DataStore to not open them all the time diff --git a/m1well.Expenses/README.md b/m1well.Expenses/README.md index baf89dd2f..444921ff7 100644 --- a/m1well.Expenses/README.md +++ b/m1well.Expenses/README.md @@ -4,8 +4,7 @@ With this plugin you can write down and store your daily/monthly expenses with a This is meant to be used for further analysis. ## Configuration -For a good start and to get the structure, you can just use the example config, -which will be added to the NotePlan `_configuration` on the first usage! +Please use the new plugins settings section. ### Content * `folderPath` @@ -25,12 +24,12 @@ which will be added to the NotePlan `_configuration` on the first usage! * ATTENTION: please don't change this after first tracking * `categories` * Categories of your expenses, e.g. 'Living', 'Groceries', 'Insurances', 'Media' -* `shortcutExpenses` +* `shortcutExpenses` (JSON format) * Shortcuts to skip the input of category and text -* `fixedExpenses` +* `fixedExpenses` (JSON format) * Fixed expenses in your life e.g. the monthly flat rent, the yearly car insurance or the monthly spotify subscription (which is deactivated in the example for show reasons) -### Example +### Example configuration ```json5 { diff --git a/m1well.Expenses/plugin.json b/m1well.Expenses/plugin.json index b4cc3decc..9d8ff2608 100644 --- a/m1well.Expenses/plugin.json +++ b/m1well.Expenses/plugin.json @@ -7,7 +7,7 @@ "plugin.description": "Plugin to track your expenses for further analyis", "plugin.author": "@m1well", "plugin.url": "https://github.com/NotePlan/plugins/blob/main/m1well.Expenses/README.md", - "plugin.version": "1.6.0", + "plugin.version": "1.7.0", "plugin.dependencies": [], "plugin.script": "script.js", "plugin.commands": [ @@ -42,5 +42,76 @@ "jsFunction": "fixedTracking" } ], - "plugin.preferences": [] + "plugin.settings": [ + { + "type": "heading", + "title": "Settings for Expenses Plugin" + }, + { + "key": "folderPath", + "type": "string", + "title": "Path of folder where the expenses notes are stored", + "description": "Set the path where you want to store the notes\n-> just an example folderPath, please adapt to your needs", + "default": "finances", + "required": true + }, + { + "key": "delimiter", + "type": "string", + "title": "Delimiter of note columns", + "description": "Choose the preferred delimiter for your note", + "choices": [";", "%", "TAB"], + "default": ";", + "required": true + }, + { + "key": "dateFormat", + "type": "string", + "title": "Custom date format for the date column", + "description": "Choose custom date format for the date column\n- e.g. one date '2021-12-08'\nSo the format should be like 'yyyy-MM-dd' or 'yyyy-MM'\nATTENTION: don't use your chosen delimiter here", + "default": "yyyy-MM-dd", + "required": true + }, + { + "key": "amountFormat", + "type": "string", + "title": "Format for the amount column", + "description": "Choose 'full' to have always 2 fraction digits with localized separator\nor 'short' to have only rounded numbers without digits", + "choices": ["full", "short"], + "default": "full", + "required": true + }, + { + "key": "columnOrder", + "type": "[string]", + "title": "Order of all columns (comma separated)", + "description": "Choose order for all columns\n- please do that before the first tracking!", + "default": ["date", "category", "text", "amount"], + "required": true + }, + { + "key": "categories", + "type": "[string]", + "title": "Categories for the expenses (comma separated)", + "description": "These are only example categories\n- please adapt to your needs!!", + "default": ["Living", "Groceries", "Insurances", "Mobility", "Media", "Fun"], + "required": true + }, + { + "key": "shortcutExpenses", + "type": "json", + "title": "Shortcut expenses (JSON format)", + "description": "Shortcut expenses with given category - you can also add an amount, then you can insert the shortcut without any question", + "default": "[\n {\n \"category\": \"Mobility\",\n \"text\": \"Refuel\",\n \"amount\": null\n },\n {\n \"category\": \"Groceries\",\n \"text\": \"XYZ Market\",\n \"amount\": null\n },\n {\n \"category\": \"Fun\",\n \"text\": \"Cofe at Starbucks\",\n \"amount\": 8\n }\n]", + "required": true + }, + { + "key": "fixedExpenses", + "type": "json", + "title": "Fixed expenses (JSON format)", + "description": "Fixed expenses with given category and amount for e.g. monthly expenses or 'once a year' expenses", + "default": "[\n {\n \"category\": \"Living\",\n \"text\": \"Flat Rent\",\n \"amount\": 670,\n \"month\": 0,\n \"active\": true\n },\n {\n \"category\": \"Insurances\",\n \"text\": \"Car Insurance\",\n \"amount\": 399,\n \"month\": 1,\n \"active\": true\n },\n {\n \"category\": \"Media\",\n \"text\": \"Spotify\",\n \"amount\": 9.99,\n \"month\": 0,\n \"active\": false\n }\n]", + "required": true + } + ] } diff --git a/m1well.Expenses/src/expenses.js b/m1well.Expenses/src/expenses.js index 1b864dbf6..4e9a0f7d2 100644 --- a/m1well.Expenses/src/expenses.js +++ b/m1well.Expenses/src/expenses.js @@ -235,10 +235,10 @@ const individualTracking = async (): Promise => { } const note = DataStore.projectNoteByTitle(title)?.[0] - const expenseRow = { + const expenseRow: ExpenseTrackingRow = { date: currentDate, category: category.value, - text: text, + text: text ? ((text: any): string) : '', // this is stupid, but now we have to do this cast ... amount: config.amountFormat === 'full' ? amount : Math.round(amount), } if (note) { @@ -362,43 +362,46 @@ const fixedTracking = async (): Promise => { } /** - * provide config from _configuration and cast content to real objects + * provide config from new plugin settings section or the old _configuration file and cast content to real objects * * @private */ -const provideConfig = (): Promise => { - return getOrMakeConfigurationSection( - 'expenses', - EXAMPLE_CONFIG - ) - .then(result => { - if (result == null || Object.keys(result).length === 0) { - logError('expected config could not be found in the _configuration file') - return { - folderPath: '', - delimiter: '', - dateFormat: '', - amountFormat: '', - columnOrder: [], - categories: [], - shortcutExpenses: [], - fixedExpenses: [] - } - } else { - logMessage(`loaded config\n${JSON.stringify(result)}\n`) - const config: Config = { - folderPath: castStringFromMixed(result, CONFIG_KEYS.folderPath), - delimiter: castStringFromMixed(result, CONFIG_KEYS.delimiter), - dateFormat: castStringFromMixed(result, CONFIG_KEYS.dateFormat), - amountFormat: castStringFromMixed(result, CONFIG_KEYS.amountFormat), - columnOrder: castStringArrayFromMixed(result, CONFIG_KEYS.columnOrder), - categories: castStringArrayFromMixed(result, CONFIG_KEYS.categories), - shortcutExpenses: castShortcutExpensesArrayFromMixed(result, CONFIG_KEYS.shortcutExpenses), - fixedExpenses: castFixedExpensesArrayFromMixed(result, CONFIG_KEYS.fixedExpenses), - } - return config +const provideConfig = async (): Promise => { + const fromSettings: Config = DataStore.settings + + if (fromSettings) { + logMessage(`loaded config from settings\n${JSON.stringify(fromSettings)}\n`) + return fromSettings + } else { + // could be remove some times after all use the new settings part + const fromFile = await getOrMakeConfigurationSection('expenses', EXAMPLE_CONFIG) + + if (fromFile == null || Object.keys(fromFile).length === 0) { + logError('expected config could not be found in the _configuration file') + return { + folderPath: '', + delimiter: '', + dateFormat: '', + amountFormat: '', + columnOrder: [], + categories: [], + shortcutExpenses: [], + fixedExpenses: [] } - }) + } else { + logMessage(`loaded config from file\n${JSON.stringify(fromFile)}\n`) + return { + folderPath: castStringFromMixed(fromFile, CONFIG_KEYS.folderPath), + delimiter: castStringFromMixed(fromFile, CONFIG_KEYS.delimiter), + dateFormat: castStringFromMixed(fromFile, CONFIG_KEYS.dateFormat), + amountFormat: castStringFromMixed(fromFile, CONFIG_KEYS.amountFormat), + columnOrder: castStringArrayFromMixed(fromFile, CONFIG_KEYS.columnOrder), + categories: castStringArrayFromMixed(fromFile, CONFIG_KEYS.categories), + shortcutExpenses: castShortcutExpensesArrayFromMixed(fromFile, CONFIG_KEYS.shortcutExpenses), + fixedExpenses: castFixedExpensesArrayFromMixed(fromFile, CONFIG_KEYS.fixedExpenses), + } + } + } } /** diff --git a/m1well.Expenses/src/expensesModels.js b/m1well.Expenses/src/expensesModels.js index 9f230695b..61e9b22a7 100644 --- a/m1well.Expenses/src/expensesModels.js +++ b/m1well.Expenses/src/expensesModels.js @@ -1,6 +1,7 @@ // @flow export type Config = { + useNewSettings?: boolean, // could be remove some times after all use the new settings part folderPath: string, delimiter: string, dateFormat: string, diff --git a/m1well.Expenses/src/index.js b/m1well.Expenses/src/index.js index cc674d0ea..5263901c5 100644 --- a/m1well.Expenses/src/index.js +++ b/m1well.Expenses/src/index.js @@ -3,7 +3,29 @@ // ----------------------------------------------------------------------------- // Plugin to store your expenses for further analyis // Michael Wellner (@m1well) -// v1.6.0, 2022-01-05 +// v1.7.0, 2022-02-10 // ----------------------------------------------------------------------------- +import { migrateConfiguration, updateSettingData } from '../../helpers/NPConfiguration' +import pluginJson from '../../jgclark.DailyJournal/plugin.json' + export { expensesTracking, expensesAggregate, individualTracking, shortcutsTracking, fixedTracking } from './expenses' + +const PLUGIN_ID = 'expenses' + +// refactor previous variables to new types +export async function onUpdateOrInstall(config: any = { silent: false }): Promise { + try { + console.log(`${PLUGIN_ID}: onUpdateOrInstall running`) + // migrate _configuration data to data//settings.json (only executes migration once) + const migrationResult: number = await migrateConfiguration(PLUGIN_ID, pluginJson, config?.silent) + console.log(`${PLUGIN_ID}: onUpdateOrInstall migrateConfiguration code: ${migrationResult}`) + if (migrationResult === 0) { + const updateSettings = updateSettingData(pluginJson) + console.log(`${PLUGIN_ID}: onUpdateOrInstall updateSettingData code: ${updateSettings}`) + } + } catch (error) { + console.log(error) + } + console.log(`${PLUGIN_ID}: onUpdateOrInstall finished`) +}