86 lines
3.2 KiB
TypeScript
86 lines
3.2 KiB
TypeScript
/**
|
|
* Copyright since 2025 Mifos Initiative
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
/**
|
|
* One Share Collection receipt the counter can choose, in a single shape whatever it came from.
|
|
*
|
|
* {@code GET /shareadvancecollection/unattributed} answers with two differently-shaped lists — the
|
|
* member's own receipts under {@code own}, and every other receipt still going spare under
|
|
* {@code rows} — and normalising both to this on arrival is what lets a screen show one plain list
|
|
* of vouchers instead of two tables whose difference a counter has to understand before they can
|
|
* pick anything.
|
|
*
|
|
* Shared by the two screens that settle a share purchase (the first application's Apply Collection
|
|
* dialog and the Apply Additional Shares dialog) so a receipt reads identically on both.
|
|
*/
|
|
export interface ReceiptOption {
|
|
/** Stable identity for tracking and comparison; unique across both source lists. */
|
|
key: string;
|
|
/**
|
|
* The {@code m_share_advance_collection} row behind this receipt, or null while it is still only
|
|
* a voucher number. A null one is attached to the member on first pick.
|
|
*/
|
|
collectionId: number | null;
|
|
voucherNo: string;
|
|
glAccountNo: string;
|
|
glAccountName: string;
|
|
date: string;
|
|
amount: number;
|
|
description: string;
|
|
cashierName: string;
|
|
}
|
|
|
|
/**
|
|
* A receipt that already has an {@code m_share_advance_collection} row — ready to settle as-is.
|
|
*
|
|
* Also the shape {@code GET /shareadvancecollection/by-voucher} answers with, so a receipt found by
|
|
* number arrives here too, already attached.
|
|
*/
|
|
export function receiptFromOwn(row: any): ReceiptOption {
|
|
return {
|
|
key: `c${row.id}`,
|
|
collectionId: Number(row.id),
|
|
voucherNo: row.voucher_no || row.receipt_no || '',
|
|
glAccountNo: row.gl_code || '',
|
|
glAccountName: '',
|
|
date: String(row.collection_date || '').slice(0, 10),
|
|
amount: Number(row.amount || 0),
|
|
description: row.note || '',
|
|
cashierName: row.collected_by_name || ''
|
|
};
|
|
}
|
|
|
|
/** A receipt that is still only a voucher, attached to the member when it is picked. */
|
|
export function receiptFromUnattached(row: any): ReceiptOption {
|
|
return {
|
|
key: `v${row.id}`,
|
|
collectionId: null,
|
|
voucherNo: row.voucherNo || '',
|
|
glAccountNo: row.glAccountNo || '',
|
|
glAccountName: row.glAccountName || '',
|
|
date: String(row.txnDate || '').slice(0, 10),
|
|
amount: Number(row.amount || 0),
|
|
description: row.description || '',
|
|
cashierName: row.cashierName || ''
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The GL account a receipt sits in, named where the name is known and coded where it is not.
|
|
*
|
|
* An attached receipt carries only its {@code gl_code}, so the name is looked up in whatever GL
|
|
* account list the screen already loaded for its voucher search rather than fetched again.
|
|
*/
|
|
export function receiptGlLabel(option: ReceiptOption, glAccounts: any[]): string {
|
|
const name = option.glAccountName || glAccounts.find((gl) => gl.gl_code === option.glAccountNo)?.name || '';
|
|
if (!option.glAccountNo) {
|
|
return name || '—';
|
|
}
|
|
return name ? `${option.glAccountNo} — ${name}` : option.glAccountNo;
|
|
}
|