import frappe from 'frappejs'; import fs from 'fs'; import { _ } from 'frappejs/utils'; import migrate from './migrate'; import { ipcRenderer } from 'electron'; import { IPC_MESSAGES, IPC_ACTIONS } from './messages'; import SQLite from 'frappejs/backends/sqlite'; import postStart from '../server/postStart'; import router from '@/router'; import Avatar from '@/components/Avatar'; import config from '@/config'; export async function createNewDatabase() { const options = { title: _('Select folder'), defaultPath: 'frappe-books.db', }; let { filePath } = await ipcRenderer.invoke( IPC_ACTIONS.GET_SAVE_FILEPATH, options ); if (filePath) { if (!filePath.endsWith('.db')) { filePath = filePath + '.db'; } if (fs.existsSync(filePath)) { showMessageDialog({ // prettier-ignore message: _('A file exists with the same name and it will be overwritten. Are you sure you want to continue?'), buttons: [ { label: _('Overwrite'), action() { fs.unlinkSync(filePath); return filePath; }, }, { label: _('Cancel'), action() {} }, ], }); } else { return filePath; } } } export async function loadExistingDatabase() { const options = { title: _('Select file'), properties: ['openFile'], filters: [{ name: 'SQLite DB File', extensions: ['db'] }], }; const { filePaths } = await ipcRenderer.invoke( IPC_ACTIONS.GET_OPEN_FILEPATH, options ); if (filePaths && filePaths[0]) { return filePaths[0]; } } export async function connectToLocalDatabase(filepath) { frappe.login('Administrator'); frappe.db = new SQLite({ dbPath: filepath, }); await frappe.db.connect(); await migrate(); await postStart(); // set file info in config let files = config.get('files') || []; if (!files.find((file) => file.filePath === filepath)) { files = [ { companyName: frappe.AccountingSettings.companyName, filePath: filepath, }, ...files, ]; config.set('files', files); } // set last selected file config.set('lastSelectedFilePath', filepath); } export async function showMessageDialog({ message, description, buttons = [], }) { const options = { message, detail: description, buttons: buttons.map((a) => a.label), }; const { response } = await ipcRenderer.invoke( IPC_ACTIONS.GET_DIALOG_RESPONSE, options ); let button = buttons[response]; if (button && button.action) { button.action(); } } export function deleteDocWithPrompt(doc) { return new Promise((resolve) => { showMessageDialog({ message: _('Are you sure you want to delete {0} "{1}"?', [ doc.doctype, doc.name, ]), description: _('This action is permanent'), buttons: [ { label: _('Delete'), action: () => { doc .delete() .then(() => resolve(true)) .catch((e) => { handleErrorWithDialog(e, doc); }); }, }, { label: _('Cancel'), action() { resolve(false); }, }, ], }); }); } export function partyWithAvatar(party) { return { data() { return { imageURL: null, label: null, }; }, components: { Avatar, }, async mounted() { this.imageURL = await frappe.db.getValue('Party', party, 'image'); this.label = party; }, template: `