@fin.cx/skr
Version:
SKR03 and SKR04 German accounting standards for double-entry bookkeeping
224 lines • 15.1 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var Account_1;
import * as plugins from './plugins.js';
import { getDb, getDbSync } from './skr.database.js';
const { SmartDataDbDoc, svDb, unI, index, searchable } = plugins.smartdata;
let Account = Account_1 = class Account extends SmartDataDbDoc {
constructor(data) {
super();
if (data) {
this.id = plugins.smartunique.shortId();
this.accountNumber = data.accountNumber || '';
this.accountName = data.accountName || '';
this.accountClass = data.accountClass || 0;
this.accountType = data.accountType || 'asset';
this.skrType = data.skrType || 'SKR03';
this.description = data.description || '';
this.vatRate = data.vatRate || 0;
this.isActive = data.isActive !== undefined ? data.isActive : true;
// Parse account structure from number
if (this.accountNumber && this.accountNumber.length === 4) {
this.accountClass = parseInt(this.accountNumber[0]);
this.accountGroup = parseInt(this.accountNumber[1]);
this.accountSubgroup = parseInt(this.accountNumber[2]);
}
else {
this.accountGroup = 0;
this.accountSubgroup = 0;
}
this.balance = 0;
this.debitTotal = 0;
this.creditTotal = 0;
this.isSystemAccount = true;
this.createdAt = new Date();
this.updatedAt = new Date();
}
}
static async createAccount(data) {
const account = new Account_1(data);
await account.save();
return account;
}
static async getAccountByNumber(accountNumber, skrType) {
const account = await Account_1.getInstance({
accountNumber,
skrType,
});
return account;
}
static async getAccountsByClass(accountClass, skrType) {
const accounts = await Account_1.getInstances({
accountClass,
skrType,
isActive: true,
});
return accounts;
}
static async getAccountsByType(accountType, skrType) {
const accounts = await Account_1.getInstances({
accountType,
skrType,
isActive: true,
});
return accounts;
}
static async searchAccounts(searchTerm, skrType) {
const query = {};
if (skrType) {
query.skrType = skrType;
}
const accounts = await Account_1.getInstances(query);
// Filter by search term
const lowerSearchTerm = searchTerm.toLowerCase();
return accounts.filter((account) => account.accountNumber.includes(searchTerm) ||
account.accountName.toLowerCase().includes(lowerSearchTerm) ||
account.description.toLowerCase().includes(lowerSearchTerm));
}
async updateBalance(debitAmount = 0, creditAmount = 0) {
this.debitTotal += debitAmount;
this.creditTotal += creditAmount;
// Calculate balance based on account type
switch (this.accountType) {
case 'asset':
case 'expense':
// Normal debit accounts
this.balance = this.debitTotal - this.creditTotal;
break;
case 'liability':
case 'equity':
case 'revenue':
// Normal credit accounts
this.balance = this.creditTotal - this.debitTotal;
break;
}
this.updatedAt = new Date();
await this.save();
}
async deactivate() {
this.isActive = false;
this.updatedAt = new Date();
await this.save();
}
async activate() {
this.isActive = true;
this.updatedAt = new Date();
await this.save();
}
getNormalBalance() {
switch (this.accountType) {
case 'asset':
case 'expense':
return 'debit';
case 'liability':
case 'equity':
case 'revenue':
return 'credit';
}
}
async beforeSave() {
// Validate account number format
if (!this.accountNumber || this.accountNumber.length !== 4) {
throw new Error(`Invalid account number format: ${this.accountNumber}. Must be 4 digits.`);
}
// Validate account number is numeric
if (!/^\d{4}$/.test(this.accountNumber)) {
throw new Error(`Account number must contain only digits: ${this.accountNumber}`);
}
// Validate account class matches first digit
const firstDigit = parseInt(this.accountNumber[0]);
if (this.accountClass !== firstDigit) {
throw new Error(`Account class ${this.accountClass} does not match account number ${this.accountNumber}`);
}
// Validate SKR type
if (this.skrType !== 'SKR03' && this.skrType !== 'SKR04') {
throw new Error(`Invalid SKR type: ${this.skrType}`);
}
}
};
__decorate([
unI(),
__metadata("design:type", String)
], Account.prototype, "id", void 0);
__decorate([
svDb(),
index(),
__metadata("design:type", String)
], Account.prototype, "accountNumber", void 0);
__decorate([
svDb(),
searchable(),
__metadata("design:type", String)
], Account.prototype, "accountName", void 0);
__decorate([
svDb(),
index(),
__metadata("design:type", Number)
], Account.prototype, "accountClass", void 0);
__decorate([
svDb(),
__metadata("design:type", Number)
], Account.prototype, "accountGroup", void 0);
__decorate([
svDb(),
__metadata("design:type", Number)
], Account.prototype, "accountSubgroup", void 0);
__decorate([
svDb(),
__metadata("design:type", String)
], Account.prototype, "accountType", void 0);
__decorate([
svDb(),
index(),
__metadata("design:type", String)
], Account.prototype, "skrType", void 0);
__decorate([
svDb(),
searchable(),
__metadata("design:type", String)
], Account.prototype, "description", void 0);
__decorate([
svDb(),
__metadata("design:type", Number)
], Account.prototype, "vatRate", void 0);
__decorate([
svDb(),
__metadata("design:type", Number)
], Account.prototype, "balance", void 0);
__decorate([
svDb(),
__metadata("design:type", Number)
], Account.prototype, "debitTotal", void 0);
__decorate([
svDb(),
__metadata("design:type", Number)
], Account.prototype, "creditTotal", void 0);
__decorate([
svDb(),
__metadata("design:type", Boolean)
], Account.prototype, "isActive", void 0);
__decorate([
svDb(),
__metadata("design:type", Boolean)
], Account.prototype, "isSystemAccount", void 0);
__decorate([
svDb(),
__metadata("design:type", Date)
], Account.prototype, "createdAt", void 0);
__decorate([
svDb(),
__metadata("design:type", Date)
], Account.prototype, "updatedAt", void 0);
Account = Account_1 = __decorate([
plugins.smartdata.Collection(() => getDbSync()),
__metadata("design:paramtypes", [Object])
], Account);
export { Account };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2tyLmNsYXNzZXMuYWNjb3VudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3Nrci5jbGFzc2VzLmFjY291bnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFHckQsTUFBTSxFQUFFLGNBQWMsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDO0FBR3BFLElBQU0sT0FBTyxlQUFiLE1BQU0sT0FBUSxTQUFRLGNBQWdDO0lBeUQzRCxZQUFZLElBQTRCO1FBQ3RDLEtBQUssRUFBRSxDQUFDO1FBRVIsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUNULElBQUksQ0FBQyxFQUFFLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUN4QyxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxhQUFhLElBQUksRUFBRSxDQUFDO1lBQzlDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsSUFBSSxFQUFFLENBQUM7WUFDMUMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxJQUFJLENBQUMsQ0FBQztZQUMzQyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLElBQUksT0FBTyxDQUFDO1lBQy9DLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sSUFBSSxPQUFPLENBQUM7WUFDdkMsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxJQUFJLEVBQUUsQ0FBQztZQUMxQyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDO1lBQ2pDLElBQUksQ0FBQyxRQUFRLEdBQUcs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