Renamed "journal entry" to "voucher line item", and "entry type" to "side".
This commit is contained in:
@ -117,29 +117,29 @@
|
||||
}
|
||||
|
||||
/* Links between objects */
|
||||
.accounting-original-entry {
|
||||
.accounting-original-line-item {
|
||||
border-top: thin solid darkslategray;
|
||||
padding: 0.2rem 0.5rem;
|
||||
}
|
||||
.accounting-original-entry a {
|
||||
.accounting-original-line-item a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
.accounting-original-entry a:hover {
|
||||
.accounting-original-line-item a:hover {
|
||||
color: inherit;
|
||||
}
|
||||
.accounting-offset-entries {
|
||||
.accounting-offset-line-items {
|
||||
border-top: thin solid darkslategray;
|
||||
padding: 0.2rem 0.5rem;
|
||||
}
|
||||
.accounting-offset-entries ul li {
|
||||
.accounting-offset-line-items ul li {
|
||||
list-style: none;
|
||||
}
|
||||
.accounting-offset-entries ul li a {
|
||||
.accounting-offset-line-items ul li a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
.accounting-offset-entries ul li a:hover {
|
||||
.accounting-offset-line-items ul li a:hover {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
@ -156,31 +156,28 @@
|
||||
.accounting-currency-content {
|
||||
width: calc(100% - 3rem);
|
||||
}
|
||||
.accounting-entry-content {
|
||||
.accounting-line-item-content {
|
||||
width: calc(100% - 3rem);
|
||||
background-color: transparent;
|
||||
}
|
||||
.accounting-entry-control {
|
||||
border-color: transparent;
|
||||
}
|
||||
.accounting-list-group-stripped .list-group-item:nth-child(2n+1) {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
.accounting-list-group-hover .list-group-item:hover {
|
||||
background-color: #ececec;
|
||||
}
|
||||
.accounting-voucher-entry {
|
||||
.accounting-voucher-line-item {
|
||||
border: none;
|
||||
}
|
||||
.accounting-voucher-entry-header {
|
||||
.accounting-voucher-line-item-header {
|
||||
font-weight: bolder;
|
||||
border-bottom: thick double slategray;
|
||||
}
|
||||
.list-group-item.accounting-voucher-entry-total {
|
||||
.list-group-item.accounting-voucher-line-item-total {
|
||||
font-weight: bolder;
|
||||
border-top: thick double slategray;
|
||||
}
|
||||
.accounting-entry-editor-original-entry-content {
|
||||
.accounting-line-item-editor-original-line-item-content {
|
||||
width: calc(100% - 3rem);
|
||||
}
|
||||
|
||||
|
@ -29,16 +29,16 @@
|
||||
class AccountSelector {
|
||||
|
||||
/**
|
||||
* The journal entry editor
|
||||
* @type {JournalEntryEditor}
|
||||
* The line item editor
|
||||
* @type {VoucherLineItemEditor}
|
||||
*/
|
||||
#entryEditor;
|
||||
#lineItemEditor;
|
||||
|
||||
/**
|
||||
* The entry type
|
||||
* The side, either "debit" or "credit"
|
||||
* @type {string}
|
||||
*/
|
||||
#entryType;
|
||||
#side;
|
||||
|
||||
/**
|
||||
* The prefix of the HTML ID and class
|
||||
@ -85,13 +85,13 @@ class AccountSelector {
|
||||
/**
|
||||
* Constructs an account selector.
|
||||
*
|
||||
* @param entryEditor {JournalEntryEditor} the journal entry editor
|
||||
* @param entryType {string} the entry type, either "debit" or "credit"
|
||||
* @param lineItemEditor {VoucherLineItemEditor} the line item editor
|
||||
* @param side {string} the side, either "debit" or "credit"
|
||||
*/
|
||||
constructor(entryEditor, entryType) {
|
||||
this.#entryEditor = entryEditor
|
||||
this.#entryType = entryType;
|
||||
this.#prefix = "accounting-account-selector-" + entryType;
|
||||
constructor(lineItemEditor, side) {
|
||||
this.#lineItemEditor = lineItemEditor
|
||||
this.#side = side;
|
||||
this.#prefix = "accounting-account-selector-" + side;
|
||||
this.#query = document.getElementById(this.#prefix + "-query");
|
||||
this.#queryNoResult = document.getElementById(this.#prefix + "-option-no-result");
|
||||
this.#optionList = document.getElementById(this.#prefix + "-option-list");
|
||||
@ -103,9 +103,9 @@ class AccountSelector {
|
||||
this.#more.classList.add("d-none");
|
||||
this.#filterOptions();
|
||||
};
|
||||
this.#clearButton.onclick = () => this.#entryEditor.clearAccount();
|
||||
this.#clearButton.onclick = () => this.#lineItemEditor.clearAccount();
|
||||
for (const option of this.#options) {
|
||||
option.onclick = () => this.#entryEditor.saveAccount(option.dataset.code, option.dataset.content, option.classList.contains("accounting-account-is-need-offset"));
|
||||
option.onclick = () => this.#lineItemEditor.saveAccount(option.dataset.code, option.dataset.content, option.classList.contains("accounting-account-is-need-offset"));
|
||||
}
|
||||
this.#query.addEventListener("input", () => {
|
||||
this.#filterOptions();
|
||||
@ -143,9 +143,9 @@ class AccountSelector {
|
||||
* @return {string[]} the account codes that are used in the form
|
||||
*/
|
||||
#getCodesUsedInForm() {
|
||||
const inUse = this.#entryEditor.form.getAccountCodesUsed(this.#entryType);
|
||||
if (this.#entryEditor.accountCode !== null) {
|
||||
inUse.push(this.#entryEditor.accountCode);
|
||||
const inUse = this.#lineItemEditor.form.getAccountCodesUsed(this.#side);
|
||||
if (this.#lineItemEditor.accountCode !== null) {
|
||||
inUse.push(this.#lineItemEditor.accountCode);
|
||||
}
|
||||
return inUse
|
||||
}
|
||||
@ -190,13 +190,13 @@ class AccountSelector {
|
||||
this.#more.classList.remove("d-none");
|
||||
this.#filterOptions();
|
||||
for (const option of this.#options) {
|
||||
if (option.dataset.code === this.#entryEditor.accountCode) {
|
||||
if (option.dataset.code === this.#lineItemEditor.accountCode) {
|
||||
option.classList.add("active");
|
||||
} else {
|
||||
option.classList.remove("active");
|
||||
}
|
||||
}
|
||||
if (this.#entryEditor.accountCode === null) {
|
||||
if (this.#lineItemEditor.accountCode === null) {
|
||||
this.#clearButton.classList.add("btn-secondary");
|
||||
this.#clearButton.classList.remove("btn-danger");
|
||||
this.#clearButton.disabled = true;
|
||||
@ -210,14 +210,14 @@ class AccountSelector {
|
||||
/**
|
||||
* Returns the account selector instances.
|
||||
*
|
||||
* @param entryEditor {JournalEntryEditor} the journal entry editor
|
||||
* @param lineItemEditor {VoucherLineItemEditor} the line item editor
|
||||
* @return {{debit: AccountSelector, credit: AccountSelector}}
|
||||
*/
|
||||
static getInstances(entryEditor) {
|
||||
static getInstances(lineItemEditor) {
|
||||
const selectors = {}
|
||||
const modals = Array.from(document.getElementsByClassName("accounting-account-selector"));
|
||||
for (const modal of modals) {
|
||||
selectors[modal.dataset.entryType] = new AccountSelector(entryEditor, modal.dataset.entryType);
|
||||
selectors[modal.dataset.side] = new AccountSelector(lineItemEditor, modal.dataset.side);
|
||||
}
|
||||
return selectors;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* The Mia! Accounting Flask Project
|
||||
* original-entry-selector.js: The JavaScript for the original entry selector
|
||||
* original-line-item-selector.js: The JavaScript for the original line item selector
|
||||
*/
|
||||
|
||||
/* Copyright (c) 2023 imacat.
|
||||
@ -23,22 +23,22 @@
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* The original entry selector.
|
||||
* The original line item selector.
|
||||
*
|
||||
*/
|
||||
class OriginalEntrySelector {
|
||||
class OriginalLineItemSelector {
|
||||
|
||||
/**
|
||||
* The journal entry editor
|
||||
* @type {JournalEntryEditor}
|
||||
* The line item editor
|
||||
* @type {VoucherLineItemEditor}
|
||||
*/
|
||||
entryEditor;
|
||||
lineItemEditor;
|
||||
|
||||
/**
|
||||
* The prefix of the HTML ID and class
|
||||
* @type {string}
|
||||
*/
|
||||
#prefix = "accounting-original-entry-selector";
|
||||
#prefix = "accounting-original-line-item-selector";
|
||||
|
||||
/**
|
||||
* The query input
|
||||
@ -60,13 +60,13 @@ class OriginalEntrySelector {
|
||||
|
||||
/**
|
||||
* The options
|
||||
* @type {OriginalEntry[]}
|
||||
* @type {OriginalLineItem[]}
|
||||
*/
|
||||
#options;
|
||||
|
||||
/**
|
||||
* The options by their ID
|
||||
* @type {Object.<string, OriginalEntry>}
|
||||
* @type {Object.<string, OriginalLineItem>}
|
||||
*/
|
||||
#optionById;
|
||||
|
||||
@ -77,21 +77,21 @@ class OriginalEntrySelector {
|
||||
#currencyCode;
|
||||
|
||||
/**
|
||||
* The entry
|
||||
* The side, either "credit" or "debit"
|
||||
*/
|
||||
#entryType;
|
||||
#side;
|
||||
|
||||
/**
|
||||
* Constructs an original entry selector.
|
||||
* Constructs an original line item selector.
|
||||
*
|
||||
* @param entryEditor {JournalEntryEditor} the journal entry editor
|
||||
* @param lineItemEditor {VoucherLineItemEditor} the line item editor
|
||||
*/
|
||||
constructor(entryEditor) {
|
||||
this.entryEditor = entryEditor;
|
||||
constructor(lineItemEditor) {
|
||||
this.lineItemEditor = lineItemEditor;
|
||||
this.#query = document.getElementById(this.#prefix + "-query");
|
||||
this.#queryNoResult = document.getElementById(this.#prefix + "-option-no-result");
|
||||
this.#optionList = document.getElementById(this.#prefix + "-option-list");
|
||||
this.#options = Array.from(document.getElementsByClassName(this.#prefix + "-option")).map((element) => new OriginalEntry(this, element));
|
||||
this.#options = Array.from(document.getElementsByClassName(this.#prefix + "-option")).map((element) => new OriginalLineItem(this, element));
|
||||
this.#optionById = {};
|
||||
for (const option of this.#options) {
|
||||
this.#optionById[option.id] = option;
|
||||
@ -102,44 +102,44 @@ class OriginalEntrySelector {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the net balance for an original entry.
|
||||
* Returns the net balance for an original line item.
|
||||
*
|
||||
* @param currentEntry {JournalEntrySubForm} the journal entry sub-form that is currently editing
|
||||
* @param currentLineItem {LineItemSubForm} the line item sub-form that is currently editing
|
||||
* @param form {VoucherForm} the voucher form
|
||||
* @param originalEntryId {string} the ID of the original entry
|
||||
* @return {Decimal} the net balance of the original entry
|
||||
* @param originalLineItemId {string} the ID of the original line item
|
||||
* @return {Decimal} the net balance of the original line item
|
||||
*/
|
||||
getNetBalance(currentEntry, form, originalEntryId) {
|
||||
const otherEntries = form.getEntries().filter((entry) => entry !== currentEntry);
|
||||
getNetBalance(currentLineItem, form, originalLineItemId) {
|
||||
const otherLineItems = form.getLineItems().filter((lineItem) => lineItem !== currentLineItem);
|
||||
let otherOffset = new Decimal(0);
|
||||
for (const otherEntry of otherEntries) {
|
||||
if (otherEntry.getOriginalEntryId() === originalEntryId) {
|
||||
const amount = otherEntry.getAmount();
|
||||
for (const otherLineItem of otherLineItems) {
|
||||
if (otherLineItem.getOriginalLineItemId() === originalLineItemId) {
|
||||
const amount = otherLineItem.getAmount();
|
||||
if (amount !== null) {
|
||||
otherOffset = otherOffset.plus(amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.#optionById[originalEntryId].bareNetBalance.minus(otherOffset);
|
||||
return this.#optionById[originalLineItemId].bareNetBalance.minus(otherOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the net balances, subtracting the offset amounts on the form but the currently editing journal entry
|
||||
* Updates the net balances, subtracting the offset amounts on the form but the currently editing line item
|
||||
*
|
||||
*/
|
||||
#updateNetBalances() {
|
||||
const otherEntries = this.entryEditor.form.getEntries().filter((entry) => entry !== this.entryEditor.entry);
|
||||
const otherLineItems = this.lineItemEditor.form.getLineItems().filter((lineItem) => lineItem !== this.lineItemEditor.lineItem);
|
||||
const otherOffsets = {}
|
||||
for (const otherEntry of otherEntries) {
|
||||
const otherOriginalEntryId = otherEntry.getOriginalEntryId();
|
||||
const amount = otherEntry.getAmount();
|
||||
if (otherOriginalEntryId === null || amount === null) {
|
||||
for (const otherLineItem of otherLineItems) {
|
||||
const otherOriginalLineItemId = otherLineItem.getOriginalLineItemId();
|
||||
const amount = otherLineItem.getAmount();
|
||||
if (otherOriginalLineItemId === null || amount === null) {
|
||||
continue;
|
||||
}
|
||||
if (!(otherOriginalEntryId in otherOffsets)) {
|
||||
otherOffsets[otherOriginalEntryId] = new Decimal("0");
|
||||
if (!(otherOriginalLineItemId in otherOffsets)) {
|
||||
otherOffsets[otherOriginalLineItemId] = new Decimal("0");
|
||||
}
|
||||
otherOffsets[otherOriginalEntryId] = otherOffsets[otherOriginalEntryId].plus(amount);
|
||||
otherOffsets[otherOriginalLineItemId] = otherOffsets[otherOriginalLineItemId].plus(amount);
|
||||
}
|
||||
for (const option of this.#options) {
|
||||
if (option.id in otherOffsets) {
|
||||
@ -157,7 +157,7 @@ class OriginalEntrySelector {
|
||||
#filterOptions() {
|
||||
let hasAnyMatched = false;
|
||||
for (const option of this.#options) {
|
||||
if (option.isMatched(this.#entryType, this.#currencyCode, this.#query.value)) {
|
||||
if (option.isMatched(this.#side, this.#currencyCode, this.#query.value)) {
|
||||
option.setShown(true);
|
||||
hasAnyMatched = true;
|
||||
} else {
|
||||
@ -174,14 +174,14 @@ class OriginalEntrySelector {
|
||||
}
|
||||
|
||||
/**
|
||||
* The callback when the original entry selector is shown.
|
||||
* The callback when the original line item selector is shown.
|
||||
*
|
||||
*/
|
||||
onOpen() {
|
||||
this.#currencyCode = this.entryEditor.getCurrencyCode();
|
||||
this.#entryType = this.entryEditor.entryType;
|
||||
this.#currencyCode = this.lineItemEditor.getCurrencyCode();
|
||||
this.#side = this.lineItemEditor.side;
|
||||
for (const option of this.#options) {
|
||||
option.setActive(option.id === this.entryEditor.originalEntryId);
|
||||
option.setActive(option.id === this.lineItemEditor.originalLineItemId);
|
||||
}
|
||||
this.#query.value = "";
|
||||
this.#updateNetBalances();
|
||||
@ -190,14 +190,14 @@ class OriginalEntrySelector {
|
||||
}
|
||||
|
||||
/**
|
||||
* An original entry.
|
||||
* An original line item.
|
||||
*
|
||||
*/
|
||||
class OriginalEntry {
|
||||
class OriginalLineItem {
|
||||
|
||||
/**
|
||||
* The original entry selector
|
||||
* @type {OriginalEntrySelector}
|
||||
* The original line item selector
|
||||
* @type {OriginalLineItemSelector}
|
||||
*/
|
||||
#selector;
|
||||
|
||||
@ -220,10 +220,10 @@ class OriginalEntry {
|
||||
date;
|
||||
|
||||
/**
|
||||
* The entry type, either "debit" or "credit"
|
||||
* The side, either "debit" or "credit"
|
||||
* @type {string}
|
||||
*/
|
||||
#entryType;
|
||||
#side;
|
||||
|
||||
/**
|
||||
* The currency code
|
||||
@ -268,7 +268,7 @@ class OriginalEntry {
|
||||
netBalanceText;
|
||||
|
||||
/**
|
||||
* The text representation of the original entry
|
||||
* The text representation of the original line item
|
||||
* @type {string}
|
||||
*/
|
||||
text;
|
||||
@ -280,9 +280,9 @@ class OriginalEntry {
|
||||
#queryValues;
|
||||
|
||||
/**
|
||||
* Constructs an original entry.
|
||||
* Constructs an original line item.
|
||||
*
|
||||
* @param selector {OriginalEntrySelector} the original entry selector
|
||||
* @param selector {OriginalLineItemSelector} the original line item selector
|
||||
* @param element {HTMLLIElement} the element
|
||||
*/
|
||||
constructor(selector, element) {
|
||||
@ -290,17 +290,17 @@ class OriginalEntry {
|
||||
this.#element = element;
|
||||
this.id = element.dataset.id;
|
||||
this.date = element.dataset.date;
|
||||
this.#entryType = element.dataset.entryType;
|
||||
this.#side = element.dataset.side;
|
||||
this.#currencyCode = element.dataset.currencyCode;
|
||||
this.accountCode = element.dataset.accountCode;
|
||||
this.accountText = element.dataset.accountText;
|
||||
this.summary = element.dataset.summary;
|
||||
this.bareNetBalance = new Decimal(element.dataset.netBalance);
|
||||
this.netBalance = this.bareNetBalance;
|
||||
this.netBalanceText = document.getElementById("accounting-original-entry-selector-option-" + this.id + "-net-balance");
|
||||
this.netBalanceText = document.getElementById("accounting-original-line-item-selector-option-" + this.id + "-net-balance");
|
||||
this.text = element.dataset.text;
|
||||
this.#queryValues = JSON.parse(element.dataset.queryValues);
|
||||
this.#element.onclick = () => this.#selector.entryEditor.saveOriginalEntry(this);
|
||||
this.#element.onclick = () => this.#selector.lineItemEditor.saveOriginalLineItem(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -335,31 +335,31 @@ class OriginalEntry {
|
||||
/**
|
||||
* Returns whether the original matches.
|
||||
*
|
||||
* @param entryType {string} the entry type, either "debit" or "credit"
|
||||
* @param side {string} the side, either "debit" or "credit"
|
||||
* @param currencyCode {string} the currency code
|
||||
* @param query {string|null} the query term
|
||||
*/
|
||||
isMatched(entryType, currencyCode, query = null) {
|
||||
isMatched(side, currencyCode, query = null) {
|
||||
return this.netBalance.greaterThan(0)
|
||||
&& this.date <= this.#selector.entryEditor.form.getDate()
|
||||
&& this.#isEntryTypeMatches(entryType)
|
||||
&& this.date <= this.#selector.lineItemEditor.form.getDate()
|
||||
&& this.#isSideMatches(side)
|
||||
&& this.#currencyCode === currencyCode
|
||||
&& this.#isQueryMatches(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the original entry matches the entry type.
|
||||
* Returns whether the original line item matches the debit or credit side.
|
||||
*
|
||||
* @param entryType {string} the entry type, either "debit" or credit
|
||||
* @param side {string} the side, either "debit" or credit
|
||||
* @return {boolean} true if the option matches, or false otherwise
|
||||
*/
|
||||
#isEntryTypeMatches(entryType) {
|
||||
return (entryType === "debit" && this.#entryType === "credit")
|
||||
|| (entryType === "credit" && this.#entryType === "debit");
|
||||
#isSideMatches(side) {
|
||||
return (side === "debit" && this.#side === "credit")
|
||||
|| (side === "credit" && this.#side === "debit");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the original entry matches the query.
|
||||
* Returns whether the original line item matches the query.
|
||||
*
|
||||
* @param query {string|null} the query term
|
||||
* @return {boolean} true if the option matches, or false otherwise
|
@ -29,10 +29,10 @@
|
||||
class SummaryEditor {
|
||||
|
||||
/**
|
||||
* The journal entry editor
|
||||
* @type {JournalEntryEditor}
|
||||
* The line item editor
|
||||
* @type {VoucherLineItemEditor}
|
||||
*/
|
||||
#entryEditor;
|
||||
#lineItemEditor;
|
||||
|
||||
/**
|
||||
* The summary editor form
|
||||
@ -53,10 +53,10 @@ class SummaryEditor {
|
||||
#modal;
|
||||
|
||||
/**
|
||||
* The entry type, either "debit" or "credit"
|
||||
* The side, either "debit" or "credit"
|
||||
* @type {string}
|
||||
*/
|
||||
entryType;
|
||||
side;
|
||||
|
||||
/**
|
||||
* The current tab
|
||||
@ -71,7 +71,7 @@ class SummaryEditor {
|
||||
summary;
|
||||
|
||||
/**
|
||||
* The button to the original entry selector
|
||||
* The button to the original line item selector
|
||||
* @type {HTMLButtonElement}
|
||||
*/
|
||||
#offsetButton;
|
||||
@ -109,13 +109,13 @@ class SummaryEditor {
|
||||
/**
|
||||
* Constructs a summary editor.
|
||||
*
|
||||
* @param entryEditor {JournalEntryEditor} the journal entry editor
|
||||
* @param entryType {string} the entry type, either "debit" or "credit"
|
||||
* @param lineItemEditor {VoucherLineItemEditor} the line item editor
|
||||
* @param side {string} the side, either "debit" or "credit"
|
||||
*/
|
||||
constructor(entryEditor, entryType) {
|
||||
this.#entryEditor = entryEditor;
|
||||
this.entryType = entryType;
|
||||
this.prefix = "accounting-summary-editor-" + entryType;
|
||||
constructor(lineItemEditor, side) {
|
||||
this.#lineItemEditor = lineItemEditor;
|
||||
this.side = side;
|
||||
this.prefix = "accounting-summary-editor-" + side;
|
||||
this.#form = document.getElementById(this.prefix);
|
||||
this.#modal = document.getElementById(this.prefix + "-modal");
|
||||
this.summary = document.getElementById(this.prefix + "-summary");
|
||||
@ -132,7 +132,7 @@ class SummaryEditor {
|
||||
this.currentTab = this.tabPlanes.general;
|
||||
this.#initializeSuggestedAccounts();
|
||||
this.summary.onchange = () => this.#onSummaryChange();
|
||||
this.#offsetButton.onclick = () => this.#entryEditor.originalEntrySelector.onOpen();
|
||||
this.#offsetButton.onclick = () => this.#lineItemEditor.originalLineItemSelector.onOpen();
|
||||
this.#form.onsubmit = () => {
|
||||
if (this.currentTab.validate()) {
|
||||
this.#submit();
|
||||
@ -215,9 +215,9 @@ class SummaryEditor {
|
||||
#submit() {
|
||||
bootstrap.Modal.getOrCreateInstance(this.#modal).hide();
|
||||
if (this.#selectedAccount !== null) {
|
||||
this.#entryEditor.saveSummaryWithAccount(this.summary.value, this.#selectedAccount.dataset.code, this.#selectedAccount.dataset.text, this.#selectedAccount.classList.contains("accounting-account-is-need-offset"));
|
||||
this.#lineItemEditor.saveSummaryWithAccount(this.summary.value, this.#selectedAccount.dataset.code, this.#selectedAccount.dataset.text, this.#selectedAccount.classList.contains("accounting-account-is-need-offset"));
|
||||
} else {
|
||||
this.#entryEditor.saveSummary(this.summary.value);
|
||||
this.#lineItemEditor.saveSummary(this.summary.value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -227,7 +227,7 @@ class SummaryEditor {
|
||||
*/
|
||||
onOpen() {
|
||||
this.#reset();
|
||||
this.summary.value = this.#entryEditor.summary === null? "": this.#entryEditor.summary;
|
||||
this.summary.value = this.#lineItemEditor.summary === null? "": this.#lineItemEditor.summary;
|
||||
this.#onSummaryChange();
|
||||
}
|
||||
|
||||
@ -246,14 +246,14 @@ class SummaryEditor {
|
||||
/**
|
||||
* Returns the summary editor instances.
|
||||
*
|
||||
* @param entryEditor {JournalEntryEditor} the journal entry editor
|
||||
* @param lineItemEditor {VoucherLineItemEditor} the line item editor
|
||||
* @return {{debit: SummaryEditor, credit: SummaryEditor}}
|
||||
*/
|
||||
static getInstances(entryEditor) {
|
||||
static getInstances(lineItemEditor) {
|
||||
const editors = {}
|
||||
const forms = Array.from(document.getElementsByClassName("accounting-summary-editor"));
|
||||
for (const form of forms) {
|
||||
editors[form.dataset.entryType] = new SummaryEditor(entryEditor, form.dataset.entryType);
|
||||
editors[form.dataset.side] = new SummaryEditor(lineItemEditor, form.dataset.side);
|
||||
}
|
||||
return editors;
|
||||
}
|
||||
|
@ -39,10 +39,10 @@ class VoucherForm {
|
||||
#element;
|
||||
|
||||
/**
|
||||
* The template to add a new journal entry
|
||||
* The template to add a new line item
|
||||
* @type {string}
|
||||
*/
|
||||
entryTemplate;
|
||||
lineItemTemplate;
|
||||
|
||||
/**
|
||||
* The date
|
||||
@ -99,10 +99,10 @@ class VoucherForm {
|
||||
#noteError;
|
||||
|
||||
/**
|
||||
* The journal entry editor
|
||||
* @type {JournalEntryEditor}
|
||||
* The line item editor
|
||||
* @type {VoucherLineItemEditor}
|
||||
*/
|
||||
entryEditor;
|
||||
lineItemEditor;
|
||||
|
||||
/**
|
||||
* Constructs the voucher form.
|
||||
@ -110,7 +110,7 @@ class VoucherForm {
|
||||
*/
|
||||
constructor() {
|
||||
this.#element = document.getElementById("accounting-form");
|
||||
this.entryTemplate = this.#element.dataset.entryTemplate;
|
||||
this.lineItemTemplate = this.#element.dataset.lineItemTemplate;
|
||||
this.#date = document.getElementById("accounting-date");
|
||||
this.#dateError = document.getElementById("accounting-date-error");
|
||||
this.#currencyControl = document.getElementById("accounting-currencies");
|
||||
@ -121,7 +121,7 @@ class VoucherForm {
|
||||
this.#addCurrencyButton = document.getElementById("accounting-add-currency");
|
||||
this.#note = document.getElementById("accounting-note");
|
||||
this.#noteError = document.getElementById("accounting-note-error");
|
||||
this.entryEditor = new JournalEntryEditor(this);
|
||||
this.lineItemEditor = new VoucherLineItemEditor(this);
|
||||
|
||||
this.#addCurrencyButton.onclick = () => {
|
||||
const newIndex = 1 + (this.#currencies.length === 0? 0: Math.max(...this.#currencies.map((currency) => currency.index)));
|
||||
@ -162,14 +162,14 @@ class VoucherForm {
|
||||
this.#currencies[0].deleteButton.classList.add("d-none");
|
||||
} else {
|
||||
for (const currency of this.#currencies) {
|
||||
let isAnyEntryMatched = false;
|
||||
for (const entry of currency.getEntries()) {
|
||||
if (entry.isMatched) {
|
||||
isAnyEntryMatched = true;
|
||||
let isAnyLineItemMatched = false;
|
||||
for (const lineItem of currency.getLineItems()) {
|
||||
if (lineItem.isMatched) {
|
||||
isAnyLineItemMatched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isAnyEntryMatched) {
|
||||
if (isAnyLineItemMatched) {
|
||||
currency.deleteButton.classList.add("d-none");
|
||||
} else {
|
||||
currency.deleteButton.classList.remove("d-none");
|
||||
@ -193,27 +193,27 @@ class VoucherForm {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the journal entries in the form.
|
||||
* Returns all the line items in the form.
|
||||
*
|
||||
* @param entryType {string|null} the entry type, either "debit" or "credit", or null for both
|
||||
* @return {JournalEntrySubForm[]} all the journal entry sub-forms
|
||||
* @param side {string|null} the side, either "debit" or "credit", or null for both
|
||||
* @return {LineItemSubForm[]} all the line item sub-forms
|
||||
*/
|
||||
getEntries(entryType = null) {
|
||||
const entries = [];
|
||||
getLineItems(side = null) {
|
||||
const lineItems = [];
|
||||
for (const currency of this.#currencies) {
|
||||
entries.push(...currency.getEntries(entryType));
|
||||
lineItems.push(...currency.getLineItems(side));
|
||||
}
|
||||
return entries;
|
||||
return lineItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the account codes used in the form.
|
||||
*
|
||||
* @param entryType {string} the entry type, either "debit" or "credit"
|
||||
* @param side {string} the side, either "debit" or "credit"
|
||||
* @return {string[]} the account codes used in the form
|
||||
*/
|
||||
getAccountCodesUsed(entryType) {
|
||||
return this.getEntries(entryType).map((entry) => entry.getAccountCode())
|
||||
getAccountCodesUsed(side) {
|
||||
return this.getLineItems(side).map((lineItem) => lineItem.getAccountCode())
|
||||
.filter((code) => code !== null);
|
||||
}
|
||||
|
||||
@ -231,16 +231,16 @@ class VoucherForm {
|
||||
*
|
||||
*/
|
||||
updateMinDate() {
|
||||
let lastOriginalEntryDate = null;
|
||||
for (const entry of this.getEntries()) {
|
||||
const date = entry.getOriginalEntryDate();
|
||||
let lastOriginalLineItemDate = null;
|
||||
for (const lineItem of this.getLineItems()) {
|
||||
const date = lineItem.getOriginalLineItemDate();
|
||||
if (date !== null) {
|
||||
if (lastOriginalEntryDate === null || lastOriginalEntryDate < date) {
|
||||
lastOriginalEntryDate = date;
|
||||
if (lastOriginalLineItemDate === null || lastOriginalLineItemDate < date) {
|
||||
lastOriginalLineItemDate = date;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.#date.min = lastOriginalEntryDate === null? "": lastOriginalEntryDate;
|
||||
this.#date.min = lastOriginalLineItemDate === null? "": lastOriginalLineItemDate;
|
||||
this.#validateDate();
|
||||
}
|
||||
|
||||
@ -272,7 +272,7 @@ class VoucherForm {
|
||||
}
|
||||
if (this.#date.value < this.#date.min) {
|
||||
this.#date.classList.add("is-invalid");
|
||||
this.#dateError.innerText = A_("The date cannot be earlier than the original entries.");
|
||||
this.#dateError.innerText = A_("The date cannot be earlier than the original line items.");
|
||||
return false;
|
||||
}
|
||||
this.#date.classList.remove("is-invalid");
|
||||
@ -407,13 +407,13 @@ class CurrencySubForm {
|
||||
|
||||
/**
|
||||
* The debit side
|
||||
* @type {DebitCreditSideSubForm|null}
|
||||
* @type {SideSubForm|null}
|
||||
*/
|
||||
#debit;
|
||||
|
||||
/**
|
||||
* The credit side
|
||||
* @type {DebitCreditSideSubForm|null}
|
||||
* @type {SideSubForm|null}
|
||||
*/
|
||||
#credit;
|
||||
|
||||
@ -435,9 +435,9 @@ class CurrencySubForm {
|
||||
this.#codeSelect = document.getElementById(this.#prefix + "-code-select");
|
||||
this.deleteButton = document.getElementById(this.#prefix + "-delete");
|
||||
const debitElement = document.getElementById(this.#prefix + "-debit");
|
||||
this.#debit = debitElement === null? null: new DebitCreditSideSubForm(this, debitElement, "debit");
|
||||
this.#debit = debitElement === null? null: new SideSubForm(this, debitElement, "debit");
|
||||
const creditElement = document.getElementById(this.#prefix + "-credit");
|
||||
this.#credit = creditElement == null? null: new DebitCreditSideSubForm(this, creditElement, "credit");
|
||||
this.#credit = creditElement == null? null: new SideSubForm(this, creditElement, "credit");
|
||||
this.#codeSelect.onchange = () => this.#code.value = this.#codeSelect.value;
|
||||
this.deleteButton.onclick = () => {
|
||||
this.element.parentElement.removeChild(this.element);
|
||||
@ -455,21 +455,21 @@ class CurrencySubForm {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the journal entries in the form.
|
||||
* Returns all the line items in the form.
|
||||
*
|
||||
* @param entryType {string|null} the entry type, either "debit" or "credit", or null for both
|
||||
* @return {JournalEntrySubForm[]} all the journal entry sub-forms
|
||||
* @param side {string|null} the side, either "debit" or "credit", or null for both
|
||||
* @return {LineItemSubForm[]} all the line item sub-forms
|
||||
*/
|
||||
getEntries(entryType = null) {
|
||||
const entries = []
|
||||
for (const side of [this.#debit, this.#credit]) {
|
||||
if (side !== null ) {
|
||||
if (entryType === null || side.entryType === entryType) {
|
||||
entries.push(...side.entries);
|
||||
getLineItems(side = null) {
|
||||
const lineItems = []
|
||||
for (const sideSubForm of [this.#debit, this.#credit]) {
|
||||
if (sideSubForm !== null ) {
|
||||
if (side === null || sideSubForm.side === side) {
|
||||
lineItems.push(...sideSubForm.lineItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
return lineItems;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -478,8 +478,8 @@ class CurrencySubForm {
|
||||
*/
|
||||
updateCodeSelectorStatus() {
|
||||
let isEnabled = true;
|
||||
for (const entry of this.getEntries()) {
|
||||
if (entry.getOriginalEntryId() !== null) {
|
||||
for (const lineItem of this.getLineItems()) {
|
||||
if (lineItem.getOriginalLineItemId() !== null) {
|
||||
isEnabled = false;
|
||||
break;
|
||||
}
|
||||
@ -527,7 +527,7 @@ class CurrencySubForm {
|
||||
* The debit or credit side sub-form
|
||||
*
|
||||
*/
|
||||
class DebitCreditSideSubForm {
|
||||
class SideSubForm {
|
||||
|
||||
/**
|
||||
* The currency sub-form
|
||||
@ -548,10 +548,10 @@ class DebitCreditSideSubForm {
|
||||
#currencyIndex;
|
||||
|
||||
/**
|
||||
* The entry type, either "debit" or "credit"
|
||||
* The side, either "debit" or "credit"
|
||||
* @type {string}
|
||||
*/
|
||||
entryType;
|
||||
side;
|
||||
|
||||
/**
|
||||
* The prefix of the HTML ID and class
|
||||
@ -566,16 +566,16 @@ class DebitCreditSideSubForm {
|
||||
#error;
|
||||
|
||||
/**
|
||||
* The journal entry list
|
||||
* The line item list
|
||||
* @type {HTMLUListElement}
|
||||
*/
|
||||
#entryList;
|
||||
#lineItemList;
|
||||
|
||||
/**
|
||||
* The journal entry sub-forms
|
||||
* @type {JournalEntrySubForm[]}
|
||||
* The line item sub-forms
|
||||
* @type {LineItemSubForm[]}
|
||||
*/
|
||||
entries;
|
||||
lineItems;
|
||||
|
||||
/**
|
||||
* The total
|
||||
@ -584,82 +584,82 @@ class DebitCreditSideSubForm {
|
||||
#total;
|
||||
|
||||
/**
|
||||
* The button to add a new entry
|
||||
* The button to add a new line item
|
||||
* @type {HTMLButtonElement}
|
||||
*/
|
||||
#addEntryButton;
|
||||
#addLineItemButton;
|
||||
|
||||
/**
|
||||
* Constructs a debit or credit side sub-form
|
||||
*
|
||||
* @param currency {CurrencySubForm} the currency sub-form
|
||||
* @param element {HTMLDivElement} the element
|
||||
* @param entryType {string} the entry type, either "debit" or "credit"
|
||||
* @param side {string} the side, either "debit" or "credit"
|
||||
*/
|
||||
constructor(currency, element, entryType) {
|
||||
constructor(currency, element, side) {
|
||||
this.currency = currency;
|
||||
this.#element = element;
|
||||
this.#currencyIndex = currency.index;
|
||||
this.entryType = entryType;
|
||||
this.#prefix = "accounting-currency-" + String(this.#currencyIndex) + "-" + entryType;
|
||||
this.side = side;
|
||||
this.#prefix = "accounting-currency-" + String(this.#currencyIndex) + "-" + side;
|
||||
this.#error = document.getElementById(this.#prefix + "-error");
|
||||
this.#entryList = document.getElementById(this.#prefix + "-list");
|
||||
this.#lineItemList = document.getElementById(this.#prefix + "-list");
|
||||
// noinspection JSValidateTypes
|
||||
this.entries = Array.from(document.getElementsByClassName(this.#prefix)).map((element) => new JournalEntrySubForm(this, element));
|
||||
this.lineItems = Array.from(document.getElementsByClassName(this.#prefix)).map((element) => new LineItemSubForm(this, element));
|
||||
this.#total = document.getElementById(this.#prefix + "-total");
|
||||
this.#addEntryButton = document.getElementById(this.#prefix + "-add-entry");
|
||||
this.#addEntryButton.onclick = () => this.currency.form.entryEditor.onAddNew(this);
|
||||
this.#resetDeleteJournalEntryButtons();
|
||||
this.#addLineItemButton = document.getElementById(this.#prefix + "-add-line-item");
|
||||
this.#addLineItemButton.onclick = () => this.currency.form.lineItemEditor.onAddNew(this);
|
||||
this.#resetDeleteLineItemButtons();
|
||||
this.#initializeDragAndDropReordering();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new journal entry sub-form
|
||||
* Adds a new line item sub-form
|
||||
*
|
||||
* @returns {JournalEntrySubForm} the newly-added journal entry sub-form
|
||||
* @returns {LineItemSubForm} the newly-added line item sub-form
|
||||
*/
|
||||
addJournalEntry() {
|
||||
const newIndex = 1 + (this.entries.length === 0? 0: Math.max(...this.entries.map((entry) => entry.entryIndex)));
|
||||
const html = this.currency.form.entryTemplate
|
||||
addLineItem() {
|
||||
const newIndex = 1 + (this.lineItems.length === 0? 0: Math.max(...this.lineItems.map((lineItem) => lineItem.lineItemIndex)));
|
||||
const html = this.currency.form.lineItemTemplate
|
||||
.replaceAll("CURRENCY_INDEX", escapeHtml(String(this.#currencyIndex)))
|
||||
.replaceAll("ENTRY_TYPE", escapeHtml(this.entryType))
|
||||
.replaceAll("ENTRY_INDEX", escapeHtml(String(newIndex)));
|
||||
this.#entryList.insertAdjacentHTML("beforeend", html);
|
||||
const entry = new JournalEntrySubForm(this, document.getElementById(this.#prefix + "-" + String(newIndex)));
|
||||
this.entries.push(entry);
|
||||
this.#resetDeleteJournalEntryButtons();
|
||||
.replaceAll("SIDE", escapeHtml(this.side))
|
||||
.replaceAll("LINE_ITEM_INDEX", escapeHtml(String(newIndex)));
|
||||
this.#lineItemList.insertAdjacentHTML("beforeend", html);
|
||||
const lineItem = new LineItemSubForm(this, document.getElementById(this.#prefix + "-" + String(newIndex)));
|
||||
this.lineItems.push(lineItem);
|
||||
this.#resetDeleteLineItemButtons();
|
||||
this.#initializeDragAndDropReordering();
|
||||
this.validate();
|
||||
return entry;
|
||||
return lineItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a journal entry sub-form
|
||||
* Deletes a line item sub-form
|
||||
*
|
||||
* @param entry {JournalEntrySubForm}
|
||||
* @param lineItem {LineItemSubForm}
|
||||
*/
|
||||
deleteJournalEntry(entry) {
|
||||
const index = this.entries.indexOf(entry);
|
||||
this.entries.splice(index, 1);
|
||||
deleteLineItem(lineItem) {
|
||||
const index = this.lineItems.indexOf(lineItem);
|
||||
this.lineItems.splice(index, 1);
|
||||
this.updateTotal();
|
||||
this.currency.updateCodeSelectorStatus();
|
||||
this.currency.form.updateMinDate();
|
||||
this.#resetDeleteJournalEntryButtons();
|
||||
this.#resetDeleteLineItemButtons();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the buttons to delete the journal entry sub-forms
|
||||
* Resets the buttons to delete the line item sub-forms
|
||||
*
|
||||
*/
|
||||
#resetDeleteJournalEntryButtons() {
|
||||
if (this.entries.length === 1) {
|
||||
this.entries[0].deleteButton.classList.add("d-none");
|
||||
#resetDeleteLineItemButtons() {
|
||||
if (this.lineItems.length === 1) {
|
||||
this.lineItems[0].deleteButton.classList.add("d-none");
|
||||
} else {
|
||||
for (const entry of this.entries) {
|
||||
if (entry.isMatched) {
|
||||
entry.deleteButton.classList.add("d-none");
|
||||
for (const lineItem of this.lineItems) {
|
||||
if (lineItem.isMatched) {
|
||||
lineItem.deleteButton.classList.add("d-none");
|
||||
} else {
|
||||
entry.deleteButton.classList.remove("d-none");
|
||||
lineItem.deleteButton.classList.remove("d-none");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -672,8 +672,8 @@ class DebitCreditSideSubForm {
|
||||
*/
|
||||
getTotal() {
|
||||
let total = new Decimal("0");
|
||||
for (const entry of this.entries) {
|
||||
const amount = entry.getAmount();
|
||||
for (const lineItem of this.lineItems) {
|
||||
const amount = lineItem.getAmount();
|
||||
if (amount !== null) {
|
||||
total = total.plus(amount);
|
||||
}
|
||||
@ -695,11 +695,11 @@ class DebitCreditSideSubForm {
|
||||
*
|
||||
*/
|
||||
#initializeDragAndDropReordering() {
|
||||
initializeDragAndDropReordering(this.#entryList, () => {
|
||||
const entryId = Array.from(this.#entryList.children).map((entry) => entry.id);
|
||||
this.entries.sort((a, b) => entryId.indexOf(a.element.id) - entryId.indexOf(b.element.id));
|
||||
for (let i = 0; i < this.entries.length; i++) {
|
||||
this.entries[i].no.value = String(i + 1);
|
||||
initializeDragAndDropReordering(this.#lineItemList, () => {
|
||||
const lineItemId = Array.from(this.#lineItemList.children).map((lineItem) => lineItem.id);
|
||||
this.lineItems.sort((a, b) => lineItemId.indexOf(a.element.id) - lineItemId.indexOf(b.element.id));
|
||||
for (let i = 0; i < this.lineItems.length; i++) {
|
||||
this.lineItems[i].no.value = String(i + 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -712,8 +712,8 @@ class DebitCreditSideSubForm {
|
||||
validate() {
|
||||
let isValid = true;
|
||||
isValid = this.#validateReal() && isValid;
|
||||
for (const entry of this.entries) {
|
||||
isValid = entry.validate() && isValid;
|
||||
for (const lineItem of this.lineItems) {
|
||||
isValid = lineItem.validate() && isValid;
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
@ -724,9 +724,9 @@ class DebitCreditSideSubForm {
|
||||
* @returns {boolean} true if valid, or false otherwise
|
||||
*/
|
||||
#validateReal() {
|
||||
if (this.entries.length === 0) {
|
||||
if (this.lineItems.length === 0) {
|
||||
this.#element.classList.add("is-invalid");
|
||||
this.#error.innerText = A_("Please add some journal entries.");
|
||||
this.#error.innerText = A_("Please add some line items.");
|
||||
return false;
|
||||
}
|
||||
this.#element.classList.remove("is-invalid");
|
||||
@ -736,16 +736,16 @@ class DebitCreditSideSubForm {
|
||||
}
|
||||
|
||||
/**
|
||||
* The journal entry sub-form.
|
||||
* The line item sub-form.
|
||||
*
|
||||
*/
|
||||
class JournalEntrySubForm {
|
||||
class LineItemSubForm {
|
||||
|
||||
/**
|
||||
* The debit or credit entry side sub-form
|
||||
* @type {DebitCreditSideSubForm}
|
||||
* The debit or credit side sub-form
|
||||
* @type {SideSubForm}
|
||||
*/
|
||||
side;
|
||||
sideSubForm;
|
||||
|
||||
/**
|
||||
* The element
|
||||
@ -754,19 +754,19 @@ class JournalEntrySubForm {
|
||||
element;
|
||||
|
||||
/**
|
||||
* The entry type, either "debit" or "credit"
|
||||
* The side, either "debit" or "credit"
|
||||
* @type {string}
|
||||
*/
|
||||
entryType;
|
||||
side;
|
||||
|
||||
/**
|
||||
* The entry index
|
||||
* The line item index
|
||||
* @type {number}
|
||||
*/
|
||||
entryIndex;
|
||||
lineItemIndex;
|
||||
|
||||
/**
|
||||
* Whether this is an original entry with offsets
|
||||
* Whether this is an original line item with offsets
|
||||
* @type {boolean}
|
||||
*/
|
||||
isMatched;
|
||||
@ -820,19 +820,19 @@ class JournalEntrySubForm {
|
||||
#summaryText;
|
||||
|
||||
/**
|
||||
* The ID of the original entry
|
||||
* The ID of the original line item
|
||||
* @type {HTMLInputElement}
|
||||
*/
|
||||
#originalEntryId;
|
||||
#originalLineItemId;
|
||||
|
||||
/**
|
||||
* The text of the original entry
|
||||
* The text of the original line item
|
||||
* @type {HTMLDivElement}
|
||||
*/
|
||||
#originalEntryText;
|
||||
#originalLineItemText;
|
||||
|
||||
/**
|
||||
* The offset entries
|
||||
* The offset items
|
||||
* @type {HTMLInputElement}
|
||||
*/
|
||||
#offsets;
|
||||
@ -850,24 +850,24 @@ class JournalEntrySubForm {
|
||||
#amountText;
|
||||
|
||||
/**
|
||||
* The button to delete journal entry
|
||||
* The button to delete line item
|
||||
* @type {HTMLButtonElement}
|
||||
*/
|
||||
deleteButton;
|
||||
|
||||
/**
|
||||
* Constructs the journal entry sub-form.
|
||||
* Constructs the line item sub-form.
|
||||
*
|
||||
* @param side {DebitCreditSideSubForm} the debit or credit entry side sub-form
|
||||
* @param side {SideSubForm} the debit or credit side sub-form
|
||||
* @param element {HTMLLIElement} the element
|
||||
*/
|
||||
constructor(side, element) {
|
||||
this.side = side;
|
||||
this.sideSubForm = side;
|
||||
this.element = element;
|
||||
this.entryType = element.dataset.entryType;
|
||||
this.entryIndex = parseInt(element.dataset.entryIndex);
|
||||
this.isMatched = element.classList.contains("accounting-matched-entry");
|
||||
this.#prefix = "accounting-currency-" + element.dataset.currencyIndex + "-" + this.entryType + "-" + this.entryIndex;
|
||||
this.side = element.dataset.side;
|
||||
this.lineItemIndex = parseInt(element.dataset.lineItemIndex);
|
||||
this.isMatched = element.classList.contains("accounting-matched-line-item");
|
||||
this.#prefix = "accounting-currency-" + element.dataset.currencyIndex + "-" + this.side + "-" + this.lineItemIndex;
|
||||
this.#control = document.getElementById(this.#prefix + "-control");
|
||||
this.#error = document.getElementById(this.#prefix + "-error");
|
||||
this.no = document.getElementById(this.#prefix + "-no");
|
||||
@ -875,53 +875,53 @@ class JournalEntrySubForm {
|
||||
this.#accountText = document.getElementById(this.#prefix + "-account-text");
|
||||
this.#summary = document.getElementById(this.#prefix + "-summary");
|
||||
this.#summaryText = document.getElementById(this.#prefix + "-summary-text");
|
||||
this.#originalEntryId = document.getElementById(this.#prefix + "-original-entry-id");
|
||||
this.#originalEntryText = document.getElementById(this.#prefix + "-original-entry-text");
|
||||
this.#originalLineItemId = document.getElementById(this.#prefix + "-original-line-item-id");
|
||||
this.#originalLineItemText = document.getElementById(this.#prefix + "-original-line-item-text");
|
||||
this.#offsets = document.getElementById(this.#prefix + "-offsets");
|
||||
this.#amount = document.getElementById(this.#prefix + "-amount");
|
||||
this.#amountText = document.getElementById(this.#prefix + "-amount-text");
|
||||
this.deleteButton = document.getElementById(this.#prefix + "-delete");
|
||||
this.#control.onclick = () => this.side.currency.form.entryEditor.onEdit(this);
|
||||
this.#control.onclick = () => this.sideSubForm.currency.form.lineItemEditor.onEdit(this);
|
||||
this.deleteButton.onclick = () => {
|
||||
this.element.parentElement.removeChild(this.element);
|
||||
this.side.deleteJournalEntry(this);
|
||||
this.sideSubForm.deleteLineItem(this);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the entry is an original entry.
|
||||
* Returns whether the line item needs offset.
|
||||
*
|
||||
* @return {boolean} true if the entry is an original entry, or false otherwise
|
||||
* @return {boolean} true if the line item needs offset, or false otherwise
|
||||
*/
|
||||
isNeedOffset() {
|
||||
return "isNeedOffset" in this.element.dataset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of the original entry.
|
||||
* Returns the ID of the original line item.
|
||||
*
|
||||
* @return {string|null} the ID of the original entry
|
||||
* @return {string|null} the ID of the original line item
|
||||
*/
|
||||
getOriginalEntryId() {
|
||||
return this.#originalEntryId.value === ""? null: this.#originalEntryId.value;
|
||||
getOriginalLineItemId() {
|
||||
return this.#originalLineItemId.value === ""? null: this.#originalLineItemId.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date of the original entry.
|
||||
* Returns the date of the original line item.
|
||||
*
|
||||
* @return {string|null} the date of the original entry
|
||||
* @return {string|null} the date of the original line item
|
||||
*/
|
||||
getOriginalEntryDate() {
|
||||
return this.#originalEntryId.dataset.date === ""? null: this.#originalEntryId.dataset.date;
|
||||
getOriginalLineItemDate() {
|
||||
return this.#originalLineItemId.dataset.date === ""? null: this.#originalLineItemId.dataset.date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text of the original entry.
|
||||
* Returns the text of the original line item.
|
||||
*
|
||||
* @return {string|null} the text of the original entry
|
||||
* @return {string|null} the text of the original line item
|
||||
*/
|
||||
getOriginalEntryText() {
|
||||
return this.#originalEntryId.dataset.text === ""? null: this.#originalEntryId.dataset.text;
|
||||
getOriginalLineItemText() {
|
||||
return this.#originalLineItemId.dataset.text === ""? null: this.#originalLineItemId.dataset.text;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -991,9 +991,9 @@ class JournalEntrySubForm {
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the data into the journal entry sub-form.
|
||||
* Stores the data into the line item sub-form.
|
||||
*
|
||||
* @param editor {JournalEntryEditor} the journal entry editor
|
||||
* @param editor {VoucherLineItemEditor} the line item editor
|
||||
*/
|
||||
save(editor) {
|
||||
if (editor.isNeedOffset) {
|
||||
@ -1001,15 +1001,15 @@ class JournalEntrySubForm {
|
||||
} else {
|
||||
this.#offsets.classList.add("d-none");
|
||||
}
|
||||
this.#originalEntryId.value = editor.originalEntryId === null? "": editor.originalEntryId;
|
||||
this.#originalEntryId.dataset.date = editor.originalEntryDate === null? "": editor.originalEntryDate;
|
||||
this.#originalEntryId.dataset.text = editor.originalEntryText === null? "": editor.originalEntryText;
|
||||
if (editor.originalEntryText === null) {
|
||||
this.#originalEntryText.classList.add("d-none");
|
||||
this.#originalEntryText.innerText = "";
|
||||
this.#originalLineItemId.value = editor.originalLineItemId === null? "": editor.originalLineItemId;
|
||||
this.#originalLineItemId.dataset.date = editor.originalLineItemDate === null? "": editor.originalLineItemDate;
|
||||
this.#originalLineItemId.dataset.text = editor.originalLineItemText === null? "": editor.originalLineItemText;
|
||||
if (editor.originalLineItemText === null) {
|
||||
this.#originalLineItemText.classList.add("d-none");
|
||||
this.#originalLineItemText.innerText = "";
|
||||
} else {
|
||||
this.#originalEntryText.classList.remove("d-none");
|
||||
this.#originalEntryText.innerText = A_("Offset %(entry)s", {entry: editor.originalEntryText});
|
||||
this.#originalLineItemText.classList.remove("d-none");
|
||||
this.#originalLineItemText.innerText = A_("Offset %(item)s", {item: editor.originalLineItemText});
|
||||
}
|
||||
this.#accountCode.value = editor.accountCode === null? "": editor.accountCode;
|
||||
this.#accountCode.dataset.text = editor.accountText === null? "": editor.accountText;
|
||||
@ -1019,9 +1019,9 @@ class JournalEntrySubForm {
|
||||
this.#amount.value = editor.amount;
|
||||
this.#amountText.innerText = formatDecimal(new Decimal(editor.amount));
|
||||
this.validate();
|
||||
this.side.updateTotal();
|
||||
this.side.currency.updateCodeSelectorStatus();
|
||||
this.side.currency.form.updateMinDate();
|
||||
this.sideSubForm.updateTotal();
|
||||
this.sideSubForm.currency.updateCodeSelectorStatus();
|
||||
this.sideSubForm.currency.form.updateMinDate();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* The Mia! Accounting Flask Project
|
||||
* journal-entry-editor.js: The JavaScript for the journal entry editor
|
||||
* voucher-line-item-editor.js: The JavaScript for the voucher line item editor
|
||||
*/
|
||||
|
||||
/* Copyright (c) 2023 imacat.
|
||||
@ -23,10 +23,10 @@
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* The journal entry editor.
|
||||
* The voucher line item editor.
|
||||
*
|
||||
*/
|
||||
class JournalEntryEditor {
|
||||
class VoucherLineItemEditor {
|
||||
|
||||
/**
|
||||
* The voucher form
|
||||
@ -35,7 +35,7 @@ class JournalEntryEditor {
|
||||
form;
|
||||
|
||||
/**
|
||||
* The journal entry editor
|
||||
* The voucher line item editor
|
||||
* @type {HTMLFormElement}
|
||||
*/
|
||||
#element;
|
||||
@ -47,46 +47,46 @@ class JournalEntryEditor {
|
||||
#modal;
|
||||
|
||||
/**
|
||||
* The entry type, either "debit" or "credit"
|
||||
* The side, either "debit" or "credit"
|
||||
* @type {string}
|
||||
*/
|
||||
entryType;
|
||||
side;
|
||||
|
||||
/**
|
||||
* The prefix of the HTML ID and class
|
||||
* @type {string}
|
||||
*/
|
||||
#prefix = "accounting-entry-editor"
|
||||
#prefix = "accounting-line-item-editor"
|
||||
|
||||
/**
|
||||
* The container of the original entry
|
||||
* The container of the original line item
|
||||
* @type {HTMLDivElement}
|
||||
*/
|
||||
#originalEntryContainer;
|
||||
#originalLineItemContainer;
|
||||
|
||||
/**
|
||||
* The control of the original entry
|
||||
* The control of the original line item
|
||||
* @type {HTMLDivElement}
|
||||
*/
|
||||
#originalEntryControl;
|
||||
#originalLineItemControl;
|
||||
|
||||
/**
|
||||
* The original entry
|
||||
* The original line item
|
||||
* @type {HTMLDivElement}
|
||||
*/
|
||||
#originalEntryText;
|
||||
#originalLineItemText;
|
||||
|
||||
/**
|
||||
* The error message of the original entry
|
||||
* The error message of the original line item
|
||||
* @type {HTMLDivElement}
|
||||
*/
|
||||
#originalEntryError;
|
||||
#originalLineItemError;
|
||||
|
||||
/**
|
||||
* The delete button of the original entry
|
||||
* The delete button of the original line item
|
||||
* @type {HTMLButtonElement}
|
||||
*/
|
||||
#originalEntryDelete;
|
||||
#originalLineItemDelete;
|
||||
|
||||
/**
|
||||
* The control of the summary
|
||||
@ -137,40 +137,40 @@ class JournalEntryEditor {
|
||||
#amountError;
|
||||
|
||||
/**
|
||||
* The journal entry to edit
|
||||
* @type {JournalEntrySubForm|null}
|
||||
* The voucher line item to edit
|
||||
* @type {LineItemSubForm|null}
|
||||
*/
|
||||
entry;
|
||||
lineItem;
|
||||
|
||||
/**
|
||||
* The debit or credit entry side sub-form
|
||||
* @type {DebitCreditSideSubForm}
|
||||
* The debit or credit side sub-form
|
||||
* @type {SideSubForm}
|
||||
*/
|
||||
#side;
|
||||
#sideSubForm;
|
||||
|
||||
/**
|
||||
* Whether the journal entry needs offset
|
||||
* Whether the voucher line item needs offset
|
||||
* @type {boolean}
|
||||
*/
|
||||
isNeedOffset = false;
|
||||
|
||||
/**
|
||||
* The ID of the original entry
|
||||
* The ID of the original line item
|
||||
* @type {string|null}
|
||||
*/
|
||||
originalEntryId = null;
|
||||
originalLineItemId = null;
|
||||
|
||||
/**
|
||||
* The date of the original entry
|
||||
* The date of the original line item
|
||||
* @type {string|null}
|
||||
*/
|
||||
originalEntryDate = null;
|
||||
originalLineItemDate = null;
|
||||
|
||||
/**
|
||||
* The text of the original entry
|
||||
* The text of the original line item
|
||||
* @type {string|null}
|
||||
*/
|
||||
originalEntryText = null;
|
||||
originalLineItemText = null;
|
||||
|
||||
/**
|
||||
* The account code
|
||||
@ -209,13 +209,13 @@ class JournalEntryEditor {
|
||||
#accountSelectors;
|
||||
|
||||
/**
|
||||
* The original entry selector
|
||||
* @type {OriginalEntrySelector}
|
||||
* The original line item selector
|
||||
* @type {OriginalLineItemSelector}
|
||||
*/
|
||||
originalEntrySelector;
|
||||
originalLineItemSelector;
|
||||
|
||||
/**
|
||||
* Constructs a new journal entry editor.
|
||||
* Constructs a new voucher line item editor.
|
||||
*
|
||||
* @param form {VoucherForm} the voucher form
|
||||
*/
|
||||
@ -223,11 +223,11 @@ class JournalEntryEditor {
|
||||
this.form = form;
|
||||
this.#element = document.getElementById(this.#prefix);
|
||||
this.#modal = document.getElementById(this.#prefix + "-modal");
|
||||
this.#originalEntryContainer = document.getElementById(this.#prefix + "-original-entry-container");
|
||||
this.#originalEntryControl = document.getElementById(this.#prefix + "-original-entry-control");
|
||||
this.#originalEntryText = document.getElementById(this.#prefix + "-original-entry");
|
||||
this.#originalEntryError = document.getElementById(this.#prefix + "-original-entry-error");
|
||||
this.#originalEntryDelete = document.getElementById(this.#prefix + "-original-entry-delete");
|
||||
this.#originalLineItemContainer = document.getElementById(this.#prefix + "-original-line-item-container");
|
||||
this.#originalLineItemControl = document.getElementById(this.#prefix + "-original-line-item-control");
|
||||
this.#originalLineItemText = document.getElementById(this.#prefix + "-original-line-item");
|
||||
this.#originalLineItemError = document.getElementById(this.#prefix + "-original-line-item-error");
|
||||
this.#originalLineItemDelete = document.getElementById(this.#prefix + "-original-line-item-delete");
|
||||
this.#summaryControl = document.getElementById(this.#prefix + "-summary-control");
|
||||
this.#summaryText = document.getElementById(this.#prefix + "-summary");
|
||||
this.#summaryError = document.getElementById(this.#prefix + "-summary-error");
|
||||
@ -238,19 +238,19 @@ class JournalEntryEditor {
|
||||
this.#amountError = document.getElementById(this.#prefix + "-amount-error");
|
||||
this.#summaryEditors = SummaryEditor.getInstances(this);
|
||||
this.#accountSelectors = AccountSelector.getInstances(this);
|
||||
this.originalEntrySelector = new OriginalEntrySelector(this);
|
||||
this.#originalEntryControl.onclick = () => this.originalEntrySelector.onOpen()
|
||||
this.#originalEntryDelete.onclick = () => this.clearOriginalEntry();
|
||||
this.#summaryControl.onclick = () => this.#summaryEditors[this.entryType].onOpen();
|
||||
this.#accountControl.onclick = () => this.#accountSelectors[this.entryType].onOpen();
|
||||
this.originalLineItemSelector = new OriginalLineItemSelector(this);
|
||||
this.#originalLineItemControl.onclick = () => this.originalLineItemSelector.onOpen()
|
||||
this.#originalLineItemDelete.onclick = () => this.clearOriginalLineItem();
|
||||
this.#summaryControl.onclick = () => this.#summaryEditors[this.side].onOpen();
|
||||
this.#accountControl.onclick = () => this.#accountSelectors[this.side].onOpen();
|
||||
this.#amountInput.onchange = () => this.#validateAmount();
|
||||
this.#element.onsubmit = () => {
|
||||
if (this.#validate()) {
|
||||
if (this.entry === null) {
|
||||
this.entry = this.#side.addJournalEntry();
|
||||
if (this.lineItem === null) {
|
||||
this.lineItem = this.#sideSubForm.addLineItem();
|
||||
}
|
||||
this.amount = this.#amountInput.value;
|
||||
this.entry.save(this);
|
||||
this.lineItem.save(this);
|
||||
bootstrap.Modal.getInstance(this.#modal).hide();
|
||||
}
|
||||
return false;
|
||||
@ -258,48 +258,48 @@ class JournalEntryEditor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the original entry from the original entry selector.
|
||||
* Saves the original line item from the original line item selector.
|
||||
*
|
||||
* @param originalEntry {OriginalEntry} the original entry
|
||||
* @param originalLineItem {OriginalLineItem} the original line item
|
||||
*/
|
||||
saveOriginalEntry(originalEntry) {
|
||||
saveOriginalLineItem(originalLineItem) {
|
||||
this.isNeedOffset = false;
|
||||
this.#originalEntryContainer.classList.remove("d-none");
|
||||
this.#originalEntryControl.classList.add("accounting-not-empty");
|
||||
this.originalEntryId = originalEntry.id;
|
||||
this.originalEntryDate = originalEntry.date;
|
||||
this.originalEntryText = originalEntry.text;
|
||||
this.#originalEntryText.innerText = originalEntry.text;
|
||||
this.#originalLineItemContainer.classList.remove("d-none");
|
||||
this.#originalLineItemControl.classList.add("accounting-not-empty");
|
||||
this.originalLineItemId = originalLineItem.id;
|
||||
this.originalLineItemDate = originalLineItem.date;
|
||||
this.originalLineItemText = originalLineItem.text;
|
||||
this.#originalLineItemText.innerText = originalLineItem.text;
|
||||
this.#setEnableSummaryAccount(false);
|
||||
if (originalEntry.summary === "") {
|
||||
if (originalLineItem.summary === "") {
|
||||
this.#summaryControl.classList.remove("accounting-not-empty");
|
||||
} else {
|
||||
this.#summaryControl.classList.add("accounting-not-empty");
|
||||
}
|
||||
this.summary = originalEntry.summary === ""? null: originalEntry.summary;
|
||||
this.#summaryText.innerText = originalEntry.summary;
|
||||
this.summary = originalLineItem.summary === ""? null: originalLineItem.summary;
|
||||
this.#summaryText.innerText = originalLineItem.summary;
|
||||
this.#accountControl.classList.add("accounting-not-empty");
|
||||
this.accountCode = originalEntry.accountCode;
|
||||
this.accountText = originalEntry.accountText;
|
||||
this.#accountText.innerText = originalEntry.accountText;
|
||||
this.#amountInput.value = String(originalEntry.netBalance);
|
||||
this.#amountInput.max = String(originalEntry.netBalance);
|
||||
this.accountCode = originalLineItem.accountCode;
|
||||
this.accountText = originalLineItem.accountText;
|
||||
this.#accountText.innerText = originalLineItem.accountText;
|
||||
this.#amountInput.value = String(originalLineItem.netBalance);
|
||||
this.#amountInput.max = String(originalLineItem.netBalance);
|
||||
this.#amountInput.min = "0";
|
||||
this.#validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the original entry.
|
||||
* Clears the original line item.
|
||||
*
|
||||
*/
|
||||
clearOriginalEntry() {
|
||||
clearOriginalLineItem() {
|
||||
this.isNeedOffset = false;
|
||||
this.#originalEntryContainer.classList.add("d-none");
|
||||
this.#originalEntryControl.classList.remove("accounting-not-empty");
|
||||
this.originalEntryId = null;
|
||||
this.originalEntryDate = null;
|
||||
this.originalEntryText = null;
|
||||
this.#originalEntryText.innerText = "";
|
||||
this.#originalLineItemContainer.classList.add("d-none");
|
||||
this.#originalLineItemControl.classList.remove("accounting-not-empty");
|
||||
this.originalLineItemId = null;
|
||||
this.originalLineItemDate = null;
|
||||
this.originalLineItemText = null;
|
||||
this.#originalLineItemText.innerText = "";
|
||||
this.#setEnableSummaryAccount(true);
|
||||
this.#accountControl.classList.remove("accounting-not-empty");
|
||||
this.accountCode = null;
|
||||
@ -314,7 +314,7 @@ class JournalEntryEditor {
|
||||
* @return {string} the currency code
|
||||
*/
|
||||
getCurrencyCode() {
|
||||
return this.#side.currency.getCurrencyCode();
|
||||
return this.#sideSubForm.currency.getCurrencyCode();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -340,7 +340,7 @@ class JournalEntryEditor {
|
||||
* @param summary {string} the summary
|
||||
* @param accountCode {string} the account code
|
||||
* @param accountText {string} the account text
|
||||
* @param isAccountNeedOffset {boolean} true if the journal entries in the account need offset, or false otherwise
|
||||
* @param isAccountNeedOffset {boolean} true if the line items in the account need offset, or false otherwise
|
||||
*/
|
||||
saveSummaryWithAccount(summary, accountCode, accountText, isAccountNeedOffset) {
|
||||
this.isNeedOffset = isAccountNeedOffset;
|
||||
@ -370,7 +370,7 @@ class JournalEntryEditor {
|
||||
*
|
||||
* @param code {string} the account code
|
||||
* @param text {string} the account text
|
||||
* @param isNeedOffset {boolean} true if the journal entries in the account need offset or false otherwise
|
||||
* @param isNeedOffset {boolean} true if the line items in the account need offset or false otherwise
|
||||
*/
|
||||
saveAccount(code, text, isNeedOffset) {
|
||||
this.isNeedOffset = isNeedOffset;
|
||||
@ -388,7 +388,7 @@ class JournalEntryEditor {
|
||||
*/
|
||||
#validate() {
|
||||
let isValid = true;
|
||||
isValid = this.#validateOriginalEntry() && isValid;
|
||||
isValid = this.#validateOriginalLineItem() && isValid;
|
||||
isValid = this.#validateSummary() && isValid;
|
||||
isValid = this.#validateAccount() && isValid;
|
||||
isValid = this.#validateAmount() && isValid
|
||||
@ -396,14 +396,14 @@ class JournalEntryEditor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the original entry.
|
||||
* Validates the original line item.
|
||||
*
|
||||
* @return {boolean} true if valid, or false otherwise
|
||||
* @private
|
||||
*/
|
||||
#validateOriginalEntry() {
|
||||
this.#originalEntryControl.classList.remove("is-invalid");
|
||||
this.#originalEntryError.innerText = "";
|
||||
#validateOriginalLineItem() {
|
||||
this.#originalLineItemControl.classList.remove("is-invalid");
|
||||
this.#originalLineItemError.innerText = "";
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -458,7 +458,7 @@ class JournalEntryEditor {
|
||||
if (this.#amountInput.max !== "") {
|
||||
if (amount.greaterThan(new Decimal(this.#amountInput.max))) {
|
||||
this.#amountInput.classList.add("is-invalid");
|
||||
this.#amountError.innerText = A_("The amount must not exceed the net balance %(balance)s of the original entry.", {balance: new Decimal(this.#amountInput.max)});
|
||||
this.#amountError.innerText = A_("The amount must not exceed the net balance %(balance)s of the original line item.", {balance: new Decimal(this.#amountInput.max)});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -476,22 +476,22 @@ class JournalEntryEditor {
|
||||
}
|
||||
|
||||
/**
|
||||
* The callback when adding a new journal entry.
|
||||
* The callback when adding a new voucher line item.
|
||||
*
|
||||
* @param side {DebitCreditSideSubForm} the debit or credit side sub-form
|
||||
* @param side {SideSubForm} the debit or credit side sub-form
|
||||
*/
|
||||
onAddNew(side) {
|
||||
this.entry = null;
|
||||
this.#side = side;
|
||||
this.entryType = this.#side.entryType;
|
||||
this.lineItem = null;
|
||||
this.#sideSubForm = side;
|
||||
this.side = this.#sideSubForm.side;
|
||||
this.isNeedOffset = false;
|
||||
this.#originalEntryContainer.classList.add("d-none");
|
||||
this.#originalEntryControl.classList.remove("accounting-not-empty");
|
||||
this.#originalEntryControl.classList.remove("is-invalid");
|
||||
this.originalEntryId = null;
|
||||
this.originalEntryDate = null;
|
||||
this.originalEntryText = null;
|
||||
this.#originalEntryText.innerText = "";
|
||||
this.#originalLineItemContainer.classList.add("d-none");
|
||||
this.#originalLineItemControl.classList.remove("accounting-not-empty");
|
||||
this.#originalLineItemControl.classList.remove("is-invalid");
|
||||
this.originalLineItemId = null;
|
||||
this.originalLineItemDate = null;
|
||||
this.originalLineItemText = null;
|
||||
this.#originalLineItemText.innerText = "";
|
||||
this.#setEnableSummaryAccount(true);
|
||||
this.#summaryControl.classList.remove("accounting-not-empty");
|
||||
this.#summaryControl.classList.remove("is-invalid");
|
||||
@ -512,46 +512,46 @@ class JournalEntryEditor {
|
||||
}
|
||||
|
||||
/**
|
||||
* The callback when editing a journal entry.
|
||||
* The callback when editing a voucher line item.
|
||||
*
|
||||
* @param entry {JournalEntrySubForm} the journal entry sub-form
|
||||
* @param lineItem {LineItemSubForm} the voucher line item sub-form
|
||||
*/
|
||||
onEdit(entry) {
|
||||
this.entry = entry;
|
||||
this.#side = entry.side;
|
||||
this.entryType = this.#side.entryType;
|
||||
this.isNeedOffset = entry.isNeedOffset();
|
||||
this.originalEntryId = entry.getOriginalEntryId();
|
||||
this.originalEntryDate = entry.getOriginalEntryDate();
|
||||
this.originalEntryText = entry.getOriginalEntryText();
|
||||
this.#originalEntryText.innerText = this.originalEntryText;
|
||||
if (this.originalEntryId === null) {
|
||||
this.#originalEntryContainer.classList.add("d-none");
|
||||
this.#originalEntryControl.classList.remove("accounting-not-empty");
|
||||
onEdit(lineItem) {
|
||||
this.lineItem = lineItem;
|
||||
this.#sideSubForm = lineItem.sideSubForm;
|
||||
this.side = this.#sideSubForm.side;
|
||||
this.isNeedOffset = lineItem.isNeedOffset();
|
||||
this.originalLineItemId = lineItem.getOriginalLineItemId();
|
||||
this.originalLineItemDate = lineItem.getOriginalLineItemDate();
|
||||
this.originalLineItemText = lineItem.getOriginalLineItemText();
|
||||
this.#originalLineItemText.innerText = this.originalLineItemText;
|
||||
if (this.originalLineItemId === null) {
|
||||
this.#originalLineItemContainer.classList.add("d-none");
|
||||
this.#originalLineItemControl.classList.remove("accounting-not-empty");
|
||||
} else {
|
||||
this.#originalEntryContainer.classList.remove("d-none");
|
||||
this.#originalEntryControl.classList.add("accounting-not-empty");
|
||||
this.#originalLineItemContainer.classList.remove("d-none");
|
||||
this.#originalLineItemControl.classList.add("accounting-not-empty");
|
||||
}
|
||||
this.#setEnableSummaryAccount(!entry.isMatched && this.originalEntryId === null);
|
||||
this.summary = entry.getSummary();
|
||||
this.#setEnableSummaryAccount(!lineItem.isMatched && this.originalLineItemId === null);
|
||||
this.summary = lineItem.getSummary();
|
||||
if (this.summary === null) {
|
||||
this.#summaryControl.classList.remove("accounting-not-empty");
|
||||
} else {
|
||||
this.#summaryControl.classList.add("accounting-not-empty");
|
||||
}
|
||||
this.#summaryText.innerText = this.summary === null? "": this.summary;
|
||||
if (entry.getAccountCode() === null) {
|
||||
if (lineItem.getAccountCode() === null) {
|
||||
this.#accountControl.classList.remove("accounting-not-empty");
|
||||
} else {
|
||||
this.#accountControl.classList.add("accounting-not-empty");
|
||||
}
|
||||
this.accountCode = entry.getAccountCode();
|
||||
this.accountText = entry.getAccountText();
|
||||
this.accountCode = lineItem.getAccountCode();
|
||||
this.accountText = lineItem.getAccountText();
|
||||
this.#accountText.innerText = this.accountText;
|
||||
this.#amountInput.value = entry.getAmount() === null? "": String(entry.getAmount());
|
||||
this.#amountInput.value = lineItem.getAmount() === null? "": String(lineItem.getAmount());
|
||||
const maxAmount = this.#getMaxAmount();
|
||||
this.#amountInput.max = maxAmount === null? "": maxAmount;
|
||||
this.#amountInput.min = entry.getAmountMin() === null? "": String(entry.getAmountMin());
|
||||
this.#amountInput.min = lineItem.getAmountMin() === null? "": String(lineItem.getAmountMin());
|
||||
this.#validate();
|
||||
}
|
||||
|
||||
@ -561,10 +561,10 @@ class JournalEntryEditor {
|
||||
* @return {Decimal|null} the max amount
|
||||
*/
|
||||
#getMaxAmount() {
|
||||
if (this.originalEntryId === null) {
|
||||
if (this.originalLineItemId === null) {
|
||||
return null;
|
||||
}
|
||||
return this.originalEntrySelector.getNetBalance(this.entry, this.form, this.originalEntryId);
|
||||
return this.originalLineItemSelector.getNetBalance(this.lineItem, this.form, this.originalLineItemId);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -575,11 +575,11 @@ class JournalEntryEditor {
|
||||
#setEnableSummaryAccount(isEnabled) {
|
||||
if (isEnabled) {
|
||||
this.#summaryControl.dataset.bsToggle = "modal";
|
||||
this.#summaryControl.dataset.bsTarget = "#accounting-summary-editor-" + this.#side.entryType + "-modal";
|
||||
this.#summaryControl.dataset.bsTarget = "#accounting-summary-editor-" + this.#sideSubForm.side + "-modal";
|
||||
this.#summaryControl.classList.remove("accounting-disabled");
|
||||
this.#summaryControl.classList.add("accounting-clickable");
|
||||
this.#accountControl.dataset.bsToggle = "modal";
|
||||
this.#accountControl.dataset.bsTarget = "#accounting-account-selector-" + this.#side.entryType + "-modal";
|
||||
this.#accountControl.dataset.bsTarget = "#accounting-account-selector-" + this.#sideSubForm.side + "-modal";
|
||||
this.#accountControl.classList.remove("accounting-disabled");
|
||||
this.#accountControl.classList.add("accounting-clickable");
|
||||
} else {
|
Reference in New Issue
Block a user