2
0
mirror of https://github.com/frappe/books.git synced 2025-03-31 23:41:32 +00:00

incr: insert or update .template.html files

- move .template.html files out of fixtures
This commit is contained in:
18alantom 2023-03-07 14:16:19 +05:30
parent dabcbcd2ce
commit eda3bb7576
13 changed files with 161 additions and 7 deletions

View File

@ -5,6 +5,7 @@ extraResources:
[ [
{ from: 'log_creds.txt', to: '../creds/log_creds.txt' }, { from: 'log_creds.txt', to: '../creds/log_creds.txt' },
{ from: 'translations', to: '../translations' }, { from: 'translations', to: '../translations' },
{ from: 'translations', to: '../translations' },
] ]
mac: mac:
type: distribution type: distribution

View File

@ -4,7 +4,7 @@ import {
app, app,
BrowserWindow, BrowserWindow,
BrowserWindowConstructorOptions, BrowserWindowConstructorOptions,
protocol protocol,
} from 'electron'; } from 'electron';
import Store from 'electron-store'; import Store from 'electron-store';
import { autoUpdater } from 'electron-updater'; import { autoUpdater } from 'electron-updater';

41
main/getPrintTemplates.ts Normal file
View File

@ -0,0 +1,41 @@
import fs from 'fs/promises';
import path from 'path';
import { TemplateFile } from 'utils/types';
export async function getTemplates() {
const paths = await getPrintTemplatePaths();
if (!paths) {
return [];
}
const templates: TemplateFile[] = [];
for (const file of paths.files) {
const filePath = path.join(paths.root, file);
const template = await fs.readFile(filePath, 'utf-8');
const { mtime } = await fs.stat(filePath);
templates.push({ template, file, modified: mtime.toISOString() });
}
return templates;
}
async function getPrintTemplatePaths(): Promise<{
files: string[];
root: string;
} | null> {
let root = path.join(process.resourcesPath, `../templates`);
try {
const files = await fs.readdir(root);
return { files, root };
} catch {
root = path.join(__dirname, `../templates`);
}
try {
const files = await fs.readdir(root);
return { files, root };
} catch {
return null;
}
}

View File

@ -10,6 +10,7 @@ import { DatabaseMethod } from '../utils/db/types';
import { IPC_ACTIONS } from '../utils/messages'; import { IPC_ACTIONS } from '../utils/messages';
import { getUrlAndTokenString, sendError } from './contactMothership'; import { getUrlAndTokenString, sendError } from './contactMothership';
import { getLanguageMap } from './getLanguageMap'; import { getLanguageMap } from './getLanguageMap';
import { getTemplates } from './getPrintTemplates';
import { import {
getConfigFilesWithModified, getConfigFilesWithModified,
getErrorHandledReponse, getErrorHandledReponse,
@ -117,7 +118,7 @@ export default function registerIpcMainActionListeners(main: Main) {
); );
ipcMain.handle(IPC_ACTIONS.GET_CREDS, async (event) => { ipcMain.handle(IPC_ACTIONS.GET_CREDS, async (event) => {
return await getUrlAndTokenString(); return getUrlAndTokenString();
}); });
ipcMain.handle(IPC_ACTIONS.DELETE_FILE, async (_, filePath) => { ipcMain.handle(IPC_ACTIONS.DELETE_FILE, async (_, filePath) => {
@ -137,6 +138,10 @@ export default function registerIpcMainActionListeners(main: Main) {
}; };
}); });
ipcMain.handle(IPC_ACTIONS.GET_TEMPLATES, async () => {
return getTemplates();
});
/** /**
* Database Related Actions * Database Related Actions
*/ */

View File

@ -111,6 +111,8 @@ function setOnWindow(isDevelopment: boolean) {
window.fyo = fyo; window.fyo = fyo;
// @ts-ignore // @ts-ignore
window.DateTime = DateTime; window.DateTime = DateTime;
// @ts-ignore
window.ipcRenderer = ipcRenderer;
} }
function getPlatformName(platform: string) { function getPlatformName(platform: string) {

View File

@ -1,6 +1,5 @@
import { Fyo } from 'fyo'; import { Fyo } from 'fyo';
import { ConfigFile, ConfigKeys } from 'fyo/core/types'; import { ConfigFile, ConfigKeys } from 'fyo/core/types';
import { Doc } from 'fyo/model/doc';
import { getRegionalModels, models } from 'models/index'; import { getRegionalModels, models } from 'models/index';
import { ModelNameEnum } from 'models/types'; import { ModelNameEnum } from 'models/types';
import { TargetField } from 'schemas/types'; import { TargetField } from 'schemas/types';
@ -9,6 +8,7 @@ import {
getRandomString, getRandomString,
getValueMapFromList, getValueMapFromList,
} from 'utils/index'; } from 'utils/index';
import { updatePrintTemplates } from './printTemplates';
export async function initializeInstance( export async function initializeInstance(
dbPath: string, dbPath: string,
@ -34,6 +34,7 @@ export async function initializeInstance(
await setInstanceId(fyo); await setInstanceId(fyo);
await setOpenCount(fyo); await setOpenCount(fyo);
await setCurrencySymbols(fyo); await setCurrencySymbols(fyo);
await updatePrintTemplates(fyo);
} }
async function closeDbIfConnected(fyo: Fyo) { async function closeDbIfConnected(fyo: Fyo) {

View File

@ -6,7 +6,7 @@ import { t } from 'fyo';
import { BaseError } from 'fyo/utils/errors'; import { BaseError } from 'fyo/utils/errors';
import { BackendResponse } from 'utils/ipc/types'; import { BackendResponse } from 'utils/ipc/types';
import { IPC_ACTIONS, IPC_MESSAGES } from 'utils/messages'; import { IPC_ACTIONS, IPC_MESSAGES } from 'utils/messages';
import { SelectFileOptions, SelectFileReturn } from 'utils/types'; import { SelectFileOptions, SelectFileReturn, TemplateFile } from 'utils/types';
import { setLanguageMap } from './language'; import { setLanguageMap } from './language';
import { showMessageDialog, showToast } from './ui'; import { showMessageDialog, showToast } from './ui';
@ -14,6 +14,10 @@ export function reloadWindow() {
return ipcRenderer.send(IPC_MESSAGES.RELOAD_MAIN_WINDOW); return ipcRenderer.send(IPC_MESSAGES.RELOAD_MAIN_WINDOW);
} }
export async function getTemplates(): Promise<TemplateFile[]> {
return await ipcRenderer.invoke(IPC_ACTIONS.GET_TEMPLATES);
}
export async function selectFile( export async function selectFile(
options: SelectFileOptions options: SelectFileOptions
): Promise<SelectFileReturn> { ): Promise<SelectFileReturn> {

View File

@ -3,10 +3,14 @@ import { Doc } from 'fyo/model/doc';
import { Invoice } from 'models/baseModels/Invoice/Invoice'; import { Invoice } from 'models/baseModels/Invoice/Invoice';
import { ModelNameEnum } from 'models/types'; import { ModelNameEnum } from 'models/types';
import { FieldTypeEnum, Schema, TargetField } from 'schemas/types'; import { FieldTypeEnum, Schema, TargetField } from 'schemas/types';
import { getSavePath, makePDF } from './ipcCalls'; import { getValueMapFromList } from 'utils/index';
import { TemplateFile } from 'utils/types';
import { getSavePath, getTemplates, makePDF } from './ipcCalls';
import { PrintValues } from './types'; import { PrintValues } from './types';
import { getDocFromNameIfExistsElseNew } from './ui';
type PrintTemplateData = Record<string, unknown>; type PrintTemplateData = Record<string, unknown>;
type TemplateUpdateItem = { name: string; template: string; type: string };
const printSettingsFields = [ const printSettingsFields = [
'logo', 'logo',
@ -256,3 +260,92 @@ function getAllCSSAsStyleElem() {
styleElem.innerHTML = cssTexts.join('\n'); styleElem.innerHTML = cssTexts.join('\n');
return styleElem; return styleElem;
} }
export async function updatePrintTemplates(fyo: Fyo) {
const templateFiles = await getTemplates();
const existingTemplates = (await fyo.db.getAll(ModelNameEnum.PrintTemplate, {
fields: ['name', 'modified'],
filters: { isCustom: false },
})) as { name: string; modified: Date }[];
const nameModifiedMap = getValueMapFromList(
existingTemplates,
'name',
'modified'
);
const updateList: TemplateUpdateItem[] = [];
for (const templateFile of templateFiles) {
const updates = getPrintTemplateUpdateList(
templateFile,
nameModifiedMap,
fyo
);
updateList.push(...updates);
}
for (const { name, type, template } of updateList) {
const doc = await getDocFromNameIfExistsElseNew(
ModelNameEnum.PrintTemplate,
name
);
await doc.set({ name, type, template, isCustom: false });
await doc.sync();
}
}
function getPrintTemplateUpdateList(
{ file, template, modified: modifiedString }: TemplateFile,
nameModifiedMap: Record<string, Date>,
fyo: Fyo
): TemplateUpdateItem[] {
const templateList: TemplateUpdateItem[] = [];
const dbModified = new Date(modifiedString);
for (const { name, type } of getNameAndTypeFromTemplateFile(file, fyo)) {
const fileModified = nameModifiedMap[name];
if (fileModified && dbModified.valueOf() >= fileModified.valueOf()) {
continue;
}
templateList.push({
name,
type,
template,
});
}
return templateList;
}
function getNameAndTypeFromTemplateFile(
file: string,
fyo: Fyo
): { name: string; type: string }[] {
/**
* Template File Name Format:
* TemplateName[.SchemaName].template.html
*
* If the SchemaName is absent then it is assumed
* that the SchemaName is:
* - SalesInvoice
* - PurchaseInvoice
*/
const fileName = file.split('.template.html')[0];
const name = fileName.split('.')[0];
const schemaName = fileName.split('.')[1];
if (schemaName) {
const label = fyo.schemaMap[schemaName]?.label ?? schemaName;
return [{ name: `${name} - ${label}`, type: schemaName }];
}
return [ModelNameEnum.SalesInvoice, ModelNameEnum.PurchaseInvoice].map(
(schemaName) => {
const label = fyo.schemaMap[schemaName]?.label ?? schemaName;
return { name: `${name} - ${label}`, type: schemaName };
}
);
}

View File

@ -22,6 +22,7 @@ export enum IPC_ACTIONS {
SELECT_FILE = 'select-file', SELECT_FILE = 'select-file',
GET_CREDS = 'get-creds', GET_CREDS = 'get-creds',
GET_DB_LIST = 'get-db-list', GET_DB_LIST = 'get-db-list',
GET_TEMPLATES = 'get-templates',
DELETE_FILE = 'delete-file', DELETE_FILE = 'delete-file',
// Database messages // Database messages
DB_CREATE = 'db-create', DB_CREATE = 'db-create',

View File

@ -23,14 +23,18 @@ export interface VersionParts {
beta?: number; beta?: number;
} }
export type Creds = { errorLogUrl: string; telemetryUrl: string; tokenString: string }; export type Creds = {
errorLogUrl: string;
telemetryUrl: string;
tokenString: string;
};
export type UnexpectedLogObject = { export type UnexpectedLogObject = {
name: string; name: string;
message: string; message: string;
stack: string; stack: string;
more: Record<string, unknown>; more: Record<string, unknown>;
} };
export interface SelectFileOptions { export interface SelectFileOptions {
title: string; title: string;
@ -48,3 +52,5 @@ export interface SelectFileReturn {
export type PropertyEnum<T extends Record<string, any>> = { export type PropertyEnum<T extends Record<string, any>> = {
[key in keyof Required<T>]: key; [key in keyof Required<T>]: key;
}; };
export type TemplateFile = { file: string; template: string; modified: string };