2
0
mirror of https://github.com/frappe/books.git synced 2025-02-08 15:08:29 +00:00

Merge pull request #1110 from AbleKSaju/feat-print-payment-entries

feat: print template for payment entries
This commit is contained in:
Akshay 2025-01-31 15:23:11 +05:30 committed by GitHub
commit ee03ab2097
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 175 additions and 14 deletions

View File

@ -502,6 +502,14 @@ export class Payment extends Transactional {
date: () => new Date(),
};
async getTotalTax() {
const taxArr = await this.getTaxSummary();
return taxArr
.map(({ amount }) => amount)
.reduce((a, b) => a.add(b), this.fyo.pesa(0));
}
async _getAccountsMap(): Promise<AccountTypeMap> {
if (this._accountsMap) {
return this._accountsMap;

View File

@ -14,6 +14,7 @@ import {
} from './ui';
import { Money } from 'pesa';
import { SalesInvoice } from 'models/baseModels/SalesInvoice/SalesInvoice';
import { Payment } from 'models/baseModels/Payment/Payment';
export type PrintTemplateHint = {
[key: string]: string | PrintTemplateHint | PrintTemplateHint[];
@ -44,28 +45,54 @@ export async function getPrintTemplatePropValues(
doc: Doc
): Promise<PrintValues> {
const fyo = doc.fyo;
let paymentId;
let sinvDoc;
const values: PrintValues = { doc: {}, print: {} };
values.doc = await getPrintTemplateDocValues(doc);
const totalTax = await (doc as Invoice)?.getTotalTax();
const paymentId = await (doc as SalesInvoice).getPaymentIds();
if (values.doc.entryType !== ModelNameEnum.Payment) {
paymentId = await (doc as SalesInvoice).getPaymentIds();
if (paymentId.length) {
const paymentDoc = await fyo.doc.getDoc(
ModelNameEnum.Payment,
paymentId[0]
if (paymentId && paymentId.length) {
const paymentDoc = await fyo.doc.getDoc(
ModelNameEnum.Payment,
paymentId[0]
);
(values.doc as PrintTemplateData).paymentMethod =
paymentDoc.paymentMethod;
(values.doc as PrintTemplateData).paidAmount = doc.fyo.format(
paymentDoc.amount as Money,
ModelNameEnum.Currency
);
}
}
if (doc.referenceType == ModelNameEnum.SalesInvoice) {
sinvDoc = await fyo.doc.getDoc(
ModelNameEnum.SalesInvoice,
(doc as Payment)?.for![0].referenceName
);
(values.doc as PrintTemplateData).paymentMethod = paymentDoc.paymentMethod;
if (sinvDoc.taxes) {
(values.doc as PrintTemplateData).taxes = sinvDoc.taxes;
}
}
(values.doc as PrintTemplateData).paidAmount = doc.fyo.format(
paymentDoc.amount as Money,
ModelNameEnum.Currency
const totalTax = await (
(sinvDoc as Invoice) ?? (doc as Payment)
)?.getTotalTax();
if (doc.schema.name == ModelNameEnum.Payment) {
(values.doc as PrintTemplateData).amountPaidInWords = getGrandTotalInWords(
(doc.amountPaid as Money)?.float
);
}
(values.doc as PrintTemplateData).subTotal = doc.fyo.format(
(doc.grandTotal as Money).sub(totalTax),
((doc.grandTotal as Money) ?? (doc.amount as Money)).sub(totalTax),
ModelNameEnum.Currency
);
@ -95,7 +122,7 @@ export async function getPrintTemplatePropValues(
}
(values.doc as PrintTemplateData).grandTotalInWords = getGrandTotalInWords(
(doc.grandTotal as Money).float
((doc.grandTotal as Money) ?? (doc.amount as Money)).float
);
(values.doc as PrintTemplateData).date = getDate(doc.date as string);

View File

@ -0,0 +1,126 @@
<main class="bg-white h-full" :style="{ 'font-family': print.font }">
<!-- Invoice Header -->
<header class="bg-gray-100 px-12 py-10">
<!-- Company Details -->
<section class="flex items-center">
<img
v-if="print.displayLogo"
class="h-12 max-w-32 object-contain mr-4"
:src="print.logo"
/>
<div>
<p class="font-semibold text-xl" :style="{ color: print.color }">
{{ print.companyName }}
</p>
<p class="text-sm text-gray-800" v-if="print.address">
{{ print.links.address.addressDisplay }}
</p>
<p class="text-sm text-gray-800" v-if="print.gstin">
GSTIN: {{ print.gstin }}
</p>
</div>
</section>
<!-- Sub Heading Section -->
<div class="mt-8 text-lg">
<!-- Doc Details -->
<section class="flex">
<h3 class="w-1/3 font-semibold">{{t`Bill`}}</h3>
<div class="w-2/3 text-gray-800">
<p class="font-semibold">{{ doc.name }}</p>
<div class="flex gap-2">
<p>{{ doc.date }}</p>
<p>{{doc?.time }}</p>
</div>
</div>
</section>
<!-- Party Details -->
<section class="mt-4 flex">
<h3 class="w-1/3 font-semibold">{{t`party`}}</h3>
<div class="w-2/3 text-gray-800" v-if="doc.party">
<p class="font-semibold">{{ doc.party }}</p>
<p v-if="doc.links.party.address">
{{ doc.links.party.links.address.addressDisplay }}
</p>
<p v-if="doc.links.party.gstin">GSTIN: {{ doc.links.party.gstin }}</p>
</div>
</section>
</div>
</header>
<!-- Payment Details -->
<section class="px-12 py-12 text-lg">
<div class="w-3/4 grid grid-cols-7 grid-rows-2 p-2 gap-3">
<div class="col-span-2 font-bold"><p>{{t`Payment Type`}}</p></div>
<div class="col-start-3">:</div>
<div class="col-span-4 col-start-4">{{ doc.paymentType }}</div>
<div class="col-span-2 row-start-2 font-bold">{{t`Payment Method`}}</div>
<div class="col-start-3 row-start-2">:</div>
<div class="col-span-4 col-start-4 row-start-2">
{{ doc.paymentMethod }}
</div>
</div>
</section>
<section class="w-1/2 px-12 pb-6 text-lg" v-if="doc.taxes.length">
<p class="flex justify-center font-semibold text-lg mt-2">
{{t`Tax Summary`}}
</p>
<div
class="flex justify-between pl-5 text-base"
v-for="tax in doc?.taxes"
:key="tax.name"
>
<p>{{ tax.account }}</p>
<p>{{ tax.amount }}</p>
</div>
<div class="flex justify-between pl-5 text-base">
<p>{{t`Total Ex.Tax`}}</p>
<p>{{doc.subTotal}}</p>
</div>
</section>
<!-- Invoice Footer -->
<footer class="px-12 text-lg">
<section class="pt-5 text-lg">
<div class="w-full grid grid-cols-7 grid-rows-5 p-2 gap-3">
<div class="col-span-2 font-bold">
<p>{{t`Grand Total`}}</p>
</div>
<div class="col-start-3">:</div>
<div class="col-span-4 col-start-4 font-bold">
<p>{{ doc.amount }}</p>
<p class="font-normal">{{ doc.grandTotalInWords }}</p>
</div>
<div class="col-span-2 row-start-2 font-bold">{{t`Amount Paid`}}</div>
<div class="col-start-3 row-start-2">:</div>
<div class="col-span-4 col-start-4 row-start-2 font-bold">
<p>{{ doc.amountPaid }}</p>
<p class="font-normal">{{ doc.amountPaidInWords }}</p>
</div>
</div>
</section>
<!-- Invoice Terms -->
<section class="mt-12" v-if="doc.terms">
<h3 class="text-lg font-semibold">{{t`Notes`}}</h3>
<p class="mt-4 text-lg whitespace-pre-line">{{ doc.terms }}</p>
</section>
</footer>
</main>

View File

@ -127,11 +127,11 @@
<!-- Invoice Terms -->
<section class="mt-12" v-if="doc.terms">
<h3 class="text-lg font-semibold">Notes</h3>
<h3 class="text-lg font-semibold">{{t`Notes`}}</h3>
<p class="mt-4 text-lg whitespace-pre-line">{{ doc.terms }}</p>
</section>
<div v-if="print.amountInWords" class="flex justify-end mt-10">
<h3 class="text-lg font-semibold mr-2">Grand Total In Words:</h3>
<h3 class="text-lg font-semibold mr-2">{{t`Grand Total In Words`}}:</h3>
<p>{{doc.grandTotalInWords}}</p>
</div>
</footer>