feat(core): Add support for CI workflows and update gitignore

This commit is contained in:
2024-07-05 11:03:59 +02:00
commit 7fc8f04be9
35 changed files with 7285 additions and 0 deletions

View File

@ -0,0 +1,205 @@
import * as plugins from '../csvparser.plugins.js';
import * as interfaces from './interfaces/index.js';
export class CsvSpendesk extends plugins.portablefinance.AcCsvParser<any> {
// ========= STATIC ================
/**
* get the SpendeskData from an extracted direcotory
* @param dirPath
*/
public static async fromFile(filePath: string): Promise<CsvSpendesk> {
const reresolvedPath = plugins.path.resolve(filePath);
const fileString = plugins.smartfile.fs.toStringSync(reresolvedPath);
const csvSpendesk = await CsvSpendesk.fromCsvString(fileString);
return csvSpendesk;
}
/**
* get the SpendeskData from an extracted direcotory
* @param dirPath
*/
public static async fromDir(dirPath: string): Promise<CsvSpendesk> {
const foundFiles: string[] = await plugins.smartfile.fs.listFileTree(
dirPath,
'**/Spendesk*',
true
);
if (foundFiles.length === 0) {
throw new Error('no files found!');
}
const csvSpendesks: CsvSpendesk[] = [];
for (const foundFile of foundFiles) {
const fileString = plugins.smartfile.fs.toStringSync(plugins.path.resolve(foundFile));
plugins.path.join(dirPath, foundFile);
csvSpendesks.push(await this.fromFile(foundFile));
}
let returnCsvSpendesk: CsvSpendesk;
for (const csvSpendeskInstance of csvSpendesks) {
if (!returnCsvSpendesk) {
returnCsvSpendesk = csvSpendeskInstance;
} else {
await returnCsvSpendesk.concat(csvSpendeskInstance);
}
}
return returnCsvSpendesk;
}
public static async fromCsvString(csvStringArg: string): Promise<CsvSpendesk> {
// lets parse the data from the directory
const csvInstance = await plugins.smartcsv.Csv.createCsvFromString(csvStringArg, {
headers: true
});
// lets differentiate between payments and credits
const originalTransactionArray: interfaces.ISpendeskOriginalTransaction[] = (await csvInstance.exportAsObject()) as interfaces.ISpendeskOriginalTransaction[];
const paymentsArray: interfaces.ISpendeskTransaction[] = [];
for (const originalTransaction of originalTransactionArray) {
const finalTransaction: interfaces.ISpendeskTransaction = {
// the original transaction
original: originalTransaction,
// assigned later
paymentType: null,
amount: null,
simpleTransaction: null,
transactionHash: null,
// assigned now
currency: originalTransaction.Currency as interfaces.TAvailableCurrencies,
description: originalTransaction.Description,
expenseAccount: originalTransaction['Expense account'],
month: originalTransaction.Month,
payer: originalTransaction.Payer,
paymentDate: new Date(originalTransaction['Payment date']),
paymentMethod: originalTransaction['Payment method'],
paymentState: originalTransaction.State as interfaces.TPaymentState,
settlementDate: new Date(originalTransaction['Settlement date']),
receiptAvailable: (() => {
if ((originalTransaction['Receipt?'] as any) === 'Yes') {
return true;
} else {
return false;
}
})(),
receiptNames: [],
supplier: originalTransaction.Supplier,
team: originalTransaction.Team,
vatAmount: parseFloat(originalTransaction.VAT),
vatPercentage: ((): number => {
if (!originalTransaction.VAT || originalTransaction.VAT === '0') {
return 0;
} else {
const vatAmount = parseFloat(originalTransaction.VAT);
const debitAmount = parseFloat(originalTransaction.Debit);
return Math.round((vatAmount / (debitAmount - vatAmount)) * 100);
}
})()
};
// type
finalTransaction.paymentType = (() => {
let paymentType: interfaces.TPaymentType;
if (parseFloat(finalTransaction.original.Credit) !== 0) {
paymentType = 'Load';
} else if (parseFloat(originalTransaction.Debit) !== 0) {
paymentType = 'Payment';
}
if (originalTransaction.Description.startsWith('FX fee')) {
paymentType = 'FXfee';
}
return paymentType;
})();
// amount
finalTransaction.amount = (() => {
switch (parseFloat(originalTransaction.Credit)) {
case 0:
return -parseFloat(originalTransaction.Debit);
default:
return parseFloat(originalTransaction.Credit);
}
})();
// transaction hash
finalTransaction.transactionHash = await plugins.smarthash.sha265FromObject({
amount: finalTransaction.amount,
transactionDate: finalTransaction.paymentDate,
settlementDate: finalTransaction.settlementDate,
supplier: finalTransaction.supplier
});
// simple transaction
finalTransaction.simpleTransaction = {
accountId: null,
id: finalTransaction.transactionHash,
amount: finalTransaction.amount,
date: finalTransaction.settlementDate,
description: finalTransaction.description,
name: finalTransaction.supplier
};
paymentsArray.push(finalTransaction);
}
const csvSpendeskInstance = new CsvSpendesk(paymentsArray);
return csvSpendeskInstance;
}
/**
* get the SpendeskData from Spendesk.com
* @param dirPath
*/
public static async fromSpendeskCom(dirPath: string) {
// TODO: implement spendesk API
throw new Error(`method is not yet implemented`);
}
// ========= INSTANCE ================
public paymentProviderName: string = 'Spendesk';
public origin: 'api' | 'file' | 'dir';
public updateFunction: (
fromTimeStamp: plugins.smarttime.TimeStamp,
untilTimeStamp: plugins.smarttime.TimeStamp
) => interfaces.ISpendeskTransaction[];
public transactionArray: interfaces.ISpendeskTransaction[];
constructor(transactionArrayArg: interfaces.ISpendeskTransaction[]) {
super();
this.transactionArray = transactionArrayArg;
}
/**
* gets all transactions
*/
public async getTransactions() {
return this.transactionArray;
}
/**
* gets all loads
*/
public async getLoads() {
return this.transactionArray.filter(payment => {
return payment.paymentType === 'Load';
});
}
public async getDebits() {
return this.transactionArray.filter(payment => {
return payment.paymentType === 'Payment';
});
}
/**
* concat this instance's transactions with those of another one
*/
public async concat(csvSpendeskInstance: CsvSpendesk): Promise<CsvSpendesk> {
this.transactionArray = this.transactionArray.concat(csvSpendeskInstance.transactionArray);
return this;
}
}

1
ts/spendesk/index.ts Normal file
View File

@ -0,0 +1 @@
export * from './csv-spendesk.classes.csvspendesk.js';

View File

@ -0,0 +1 @@
export * from './interface.spendesktransaction';

View File

@ -0,0 +1,55 @@
import * as plugins from '../csv-spendesk.plugins';
export type TAvailableCurrencies = 'EUR';
export type TPaymentState = 'Settled';
export type TPaymentType = 'Load' | 'Credit' | 'Payment' | 'FXfee';
export interface ISpendeskOriginalTransaction {
simpleTransaction: plugins.tsclass.ITransaction;
original: any;
'Payment date': string;
'Settlement date': string;
Month: string;
Payer: string;
Team: string;
Description: string;
Supplier: string;
'Expense account': string;
'Payment method': string;
Type: string;
// 'Local amount': number;
// 'Local currency': 'EUR';
Debit: string;
Credit: string;
Currency: string;
VAT: string;
vatPercentage?: string;
State: string;
'Receipt?': string;
'Receipt name(s)': '';
}
export interface ISpendeskTransaction {
simpleTransaction?: plugins.tsclass.ITransaction;
original: ISpendeskOriginalTransaction;
transactionHash: string;
paymentDate: Date;
settlementDate: Date;
month: string;
payer: string;
team: string;
description: string;
supplier: string;
expenseAccount: string;
paymentMethod: string;
paymentType: TPaymentType;
// 'Local amount': number;
// 'Local currency': 'EUR';
amount: number;
currency: TAvailableCurrencies;
vatAmount: number;
vatPercentage?: number;
paymentState: TPaymentState;
receiptAvailable: boolean;
receiptNames: string[];
}