2
0
mirror of https://github.com/frappe/books.git synced 2025-02-03 04:28:32 +00:00

Merge pull request #1071 from frappe/payment-methods

feat: payment methods
This commit is contained in:
Akshay 2024-12-27 17:01:59 +05:30 committed by GitHub
commit a37bee8086
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 289 additions and 150 deletions

View File

@ -402,10 +402,7 @@ export class BespokeQueries {
const sinvNamesQuery = db.knex!(ModelNameEnum.SalesInvoice)
.select('name')
.where('isPOS', true)
.andWhereBetween('date', [
DateTime.fromJSDate(fromDate).toSQLDate(),
DateTime.fromJSDate(toDate).toSQLDate(),
]);
.andWhereBetween('date', [fromDate.toISOString(), toDate.toISOString()]);
if (lastShiftClosingDate) {
sinvNamesQuery.andWhere(

View File

@ -0,0 +1,57 @@
import { ModelNameEnum } from 'models/types';
import { DatabaseManager } from '../database/manager';
import { AccountTypeEnum } from 'models/baseModels/Account/types';
import { getDefaultMetaFieldValueMap } from 'backend/helpers';
type AccountTypeMap = Record<AccountTypeEnum, string[] | undefined>;
async function execute(dm: DatabaseManager) {
const accounts = (await dm.db?.getAll(ModelNameEnum.Account, {
fields: ['name', 'accountType'],
filters: {
accountType: [
'in',
[
AccountTypeEnum.Bank,
AccountTypeEnum.Cash,
AccountTypeEnum.Payable,
AccountTypeEnum.Receivable,
],
],
},
})) as { name: string; accountType: AccountTypeEnum }[];
const accountsMap = accounts.reduce((acc, ac) => {
acc[ac.accountType] ??= [];
acc[ac.accountType]!.push(ac.name);
return acc;
}, {} as AccountTypeMap);
const defaults = getDefaultMetaFieldValueMap();
const paymentMethods = [
{
name: 'Cash',
type: 'Cash',
account: accountsMap[AccountTypeEnum.Cash]?.[0],
...defaults,
},
{
name: 'Bank',
type: 'Bank',
account: accountsMap[AccountTypeEnum.Bank]?.[0],
...defaults,
},
{
name: 'Transfer',
type: 'Bank',
account: accountsMap[AccountTypeEnum.Bank]?.[0],
...defaults,
},
];
for (const paymentMethod of paymentMethods) {
await dm.db?.insert(ModelNameEnum.PaymentMethod, paymentMethod);
}
}
export default { execute };

View File

@ -7,6 +7,7 @@ import updateSchemas from './updateSchemas';
import setPaymentReferenceType from './setPaymentReferenceType';
import fixLedgerDateTime from './v0_21_0/fixLedgerDateTime';
import fixItemHSNField from './fixItemHSNField';
import createPaymentMethods from './createPaymentMethods';
export default [
{ name: 'testPatch', version: '0.5.0-beta.0', patch: testPatch },
@ -42,4 +43,9 @@ export default [
patch: fixLedgerDateTime,
},
{ name: 'fixItemHSNField', version: '0.24.0', patch: fixItemHSNField },
{
name: 'createPaymentMethods',
version: '0.25.1',
patch: createPaymentMethods,
},
] as Patch[];

View File

@ -9,7 +9,6 @@ import {
FormulaMap,
HiddenMap,
ListViewSettings,
RequiredMap,
ValidationMap,
} from 'fyo/model/types';
import { NotFoundError, ValidationError } from 'fyo/utils/errors';
@ -27,8 +26,9 @@ import { AccountTypeEnum } from '../Account/types';
import { Invoice } from '../Invoice/Invoice';
import { Party } from '../Party/Party';
import { PaymentFor } from '../PaymentFor/PaymentFor';
import { PaymentMethod, PaymentType } from './types';
import { PaymentType } from './types';
import { TaxSummary } from '../TaxSummary/TaxSummary';
import { PaymentMethod } from '../PaymentMethod/PaymentMethod';
type AccountTypeMap = Record<AccountTypeEnum, string[] | undefined>;
@ -38,10 +38,15 @@ export class Payment extends Transactional {
amount?: Money;
writeoff?: Money;
paymentType?: PaymentType;
paymentMethod?: string;
referenceType?: ModelNameEnum.SalesInvoice | ModelNameEnum.PurchaseInvoice;
for?: PaymentFor[];
_accountsMap?: AccountTypeMap;
async paymentMethodDoc() {
return (await this.loadAndGetLink('paymentMethod')) as PaymentMethod;
}
async change({ changed }: ChangeArg) {
if (changed === 'for') {
this.updateAmountOnReferenceUpdate();
@ -110,6 +115,7 @@ export class Payment extends Transactional {
this.validateAccounts();
this.validateTotalReferenceAmount();
await this.validateReferences();
await this.validateReferencesAreSet();
}
async validateFor() {
@ -223,6 +229,22 @@ export class Payment extends Transactional {
);
}
async validateReferencesAreSet() {
const type = (await this.paymentMethodDoc()).type;
if (type !== 'Bank') {
return;
}
if (!this.clearanceDate) {
throw new ValidationError(t`Clearance Date not set.`);
}
if (!this.referenceId) {
throw new ValidationError(t`Reference Id not set.`);
}
}
async getTaxSummary() {
const taxes: Record<
string,
@ -559,15 +581,13 @@ export class Payment extends Transactional {
);
}
if (this.paymentMethod === 'Cash') {
const paymentMethodDoc = await this.paymentMethodDoc();
if (paymentMethodDoc.type === 'Cash') {
return accountsMap[AccountTypeEnum.Cash]?.[0] ?? null;
}
if (this.paymentMethod !== 'Cash') {
return accountsMap[AccountTypeEnum.Bank]?.[0] ?? null;
}
return null;
return accountsMap[AccountTypeEnum.Bank]?.[0] ?? null;
},
dependsOn: ['paymentMethod', 'paymentType', 'party'],
},
@ -582,15 +602,17 @@ export class Payment extends Transactional {
);
}
if (this.paymentMethod === 'Cash') {
const paymentMethodDoc = await this.paymentMethodDoc();
if (paymentMethodDoc.account) {
return paymentMethodDoc.get('account');
}
if (paymentMethodDoc.type === 'Cash') {
return accountsMap[AccountTypeEnum.Cash]?.[0] ?? null;
}
if (this.paymentMethod !== 'Cash') {
return accountsMap[AccountTypeEnum.Bank]?.[0] ?? null;
}
return null;
return accountsMap[AccountTypeEnum.Bank]?.[0] ?? null;
},
dependsOn: ['paymentMethod', 'paymentType', 'party'],
},
@ -673,14 +695,7 @@ export class Payment extends Transactional {
},
};
required: RequiredMap = {
referenceId: () => this.paymentMethod !== 'Cash',
clearanceDate: () => this.paymentMethod !== 'Cash',
};
hidden: HiddenMap = {
referenceId: () => this.paymentMethod === 'Cash',
clearanceDate: () => this.paymentMethod === 'Cash',
amountPaid: () => this.writeoff?.isZero() ?? true,
attachment: () =>
!(this.attachment || !(this.isSubmitted || this.isCancelled)),
@ -712,7 +727,7 @@ export class Payment extends Transactional {
return { accountType: 'Receivable', isGroup: false };
}
if (paymentMethod === 'Cash') {
if (paymentMethod.name === 'Cash') {
return { accountType: 'Cash', isGroup: false };
} else {
return { accountType: ['in', ['Bank', 'Cash']], isGroup: false };
@ -726,7 +741,7 @@ export class Payment extends Transactional {
return { accountType: 'Payable', isGroup: false };
}
if (paymentMethod === 'Cash') {
if (paymentMethod.name === 'Cash') {
return { accountType: 'Cash', isGroup: false };
} else {
return { accountType: ['in', ['Bank', 'Cash']], isGroup: false };

View File

@ -0,0 +1,16 @@
import { Doc } from 'fyo/model/doc';
import { Account } from '../Account/Account';
import { ListViewSettings } from 'fyo/model/types';
import { PaymentMethodType } from 'models/types';
export class PaymentMethod extends Doc {
name?: string;
account?: Account;
type?: PaymentMethodType;
static getListViewSettings(): ListViewSettings {
return {
columns: ['name', 'type'],
};
}
}

View File

@ -16,6 +16,7 @@ import { Lead } from './baseModels/Lead/Lead';
import { AppliedCouponCodes } from './baseModels/AppliedCouponCodes/AppliedCouponCodes';
import { CouponCode } from './baseModels/CouponCode/CouponCode';
import { Payment } from './baseModels/Payment/Payment';
import { PaymentMethod } from './baseModels/PaymentMethod/PaymentMethod';
import { PaymentFor } from './baseModels/PaymentFor/PaymentFor';
import { PriceList } from './baseModels/PriceList/PriceList';
import { PriceListItem } from './baseModels/PriceList/PriceListItem';
@ -69,6 +70,7 @@ export const models = {
CollectionRulesItems,
CouponCode,
Payment,
PaymentMethod,
PaymentFor,
PrintSettings,
PriceList,

View File

@ -26,6 +26,7 @@ export enum ModelNameEnum {
AppliedCouponCodes = 'AppliedCouponCodes',
Payment = 'Payment',
PaymentMethod = 'PaymentMethod',
PaymentFor = 'PaymentFor',
PriceList = 'PriceList',
PricingRule = 'PricingRule',
@ -68,3 +69,5 @@ export enum ModelNameEnum {
}
export type ModelName = keyof typeof ModelNameEnum;
export type PaymentMethodType= 'Cash' | 'Bank'

View File

@ -81,23 +81,11 @@
"fieldname": "paymentMethod",
"label": "Payment Method",
"placeholder": "Payment Method",
"fieldtype": "Select",
"options": [
{
"value": "Cash",
"label": "Cash"
},
{
"value": "Cheque",
"label": "Cheque"
},
{
"value": "Transfer",
"label": "Transfer"
}
],
"fieldtype": "Link",
"target": "PaymentMethod",
"default": "Cash",
"required": true,
"create": true,
"section": "Details"
},
{

View File

@ -0,0 +1,35 @@
{
"name": "PaymentMethod",
"label": "Payment Method",
"naming": "manual",
"fields": [
{
"fieldname": "name",
"label": "Name",
"fieldtype": "Data"
},
{
"fieldname": "type",
"label": "Type",
"fieldtype": "Select",
"required": true,
"options": [
{
"value": "Cash",
"label": "Cash"
},
{
"value": "Bank",
"label": "Bank"
}
]
},
{
"fieldname": "account",
"label": "Account",
"fieldtype": "Link",
"target": "Account"
}
],
"quickEditFields": ["name", "type", "account"]
}

View File

@ -22,6 +22,7 @@ import CollectionRulesItems from './app/CollectionRulesItems.json';
import CouponCode from './app/CouponCode.json';
import AppliedCouponCodes from './app/AppliedCouponCodes.json';
import Payment from './app/Payment.json';
import PaymentMethod from './app/PaymentMethod.json';
import PaymentFor from './app/PaymentFor.json';
import PriceList from './app/PriceList.json';
import PriceListItem from './app/PriceListItem.json';
@ -117,6 +118,7 @@ export const appSchemas: Schema[] | SchemaStub[] = [
CollectionRulesItems as Schema,
Payment as Schema,
PaymentMethod as Schema,
PaymentFor as Schema,
JournalEntry as Schema,

View File

@ -25,7 +25,8 @@ export type PosEmits =
| 'addItem'
| 'toggleView'
| 'toggleModal'
| 'setCashAmount'
| 'setPaidAmount'
| 'setPaymentMethod'
| 'setCouponsCount'
| 'routeToSinvList'
| 'applyPricingRule'

View File

@ -43,9 +43,11 @@
<PaymentModal
:open-modal="openPaymentModal"
@toggle-modal="emitEvent('toggleModal', 'Payment')"
@set-cash-amount="(amount) => emitEvent('setCashAmount', amount)"
@set-paid-amount="(amount: Money) => emitEvent('setPaidAmount', amount)"
@set-payment-method="
(paymentMethod) => emitEvent('setPaymentMethod', paymentMethod)
"
@set-transfer-ref-no="(ref) => emitEvent('setTransferRefNo', ref)"
@set-transfer-amount="(amount) => emitEvent('setTransferAmount', amount)"
@set-transfer-clearance-date="
(date) => emitEvent('setTransferClearanceDate', date)
"
@ -338,7 +340,7 @@ export default defineComponent({
FloatingLabelCurrencyInput,
},
props: {
cashAmount: Money,
paidAmount: Money,
tableView: Boolean,
itemDiscounts: Money,
openAlertModal: Boolean,
@ -390,9 +392,10 @@ export default defineComponent({
'toggleModal',
'setCustomer',
'clearValues',
'setCashAmount',
'setPaidAmount',
'setCouponsCount',
'routeToSinvList',
'setPaymentMethod',
'setTransferRefNo',
'setLoyaltyPoints',
'applyPricingRule',
@ -409,7 +412,10 @@ export default defineComponent({
};
},
methods: {
emitEvent(eventName: PosEmits, ...args: (string | boolean | Item)[]) {
emitEvent(
eventName: PosEmits,
...args: (string | boolean | Item | Money)[]
) {
this.$emit(eventName, ...args);
},
getItem,

View File

@ -121,14 +121,16 @@ export default defineComponent({
},
methods: {
async setTransactedAmount() {
if (!fyo.singles.POSShift?.openingDate) {
this.posOpeningShiftDoc = await getPOSOpeningShiftDoc(fyo);
const fromDate = this.posOpeningShiftDoc?.openingDate as Date;
if (!fromDate) {
return;
}
const fromDate = this.posOpeningShiftDoc?.openingDate as Date;
this.transactedAmount = await fyo.db.getPOSTransactedAmount(
fromDate,
new Date(),
fyo.singles.POSShift.closingDate as Date
new Date()
);
},
seedClosingCash() {
@ -160,19 +162,7 @@ export default defineComponent({
return;
}
let expectedAmount = fyo.pesa(0);
if (row.paymentMethod === 'Cash') {
expectedAmount = expectedAmount.add(
this.posOpeningShiftDoc?.openingCashAmount as Money
);
}
if (row.paymentMethod === 'Transfer') {
expectedAmount = expectedAmount.add(
this.posOpeningShiftDoc?.openingTransferAmount as Money
);
}
let expectedAmount = row.amount ?? fyo.pesa(0);
if (this.transactedAmount) {
expectedAmount = expectedAmount.add(

View File

@ -43,9 +43,11 @@
<PaymentModal
:open-modal="openPaymentModal"
@toggle-modal="emitEvent('toggleModal', 'Payment')"
@set-cash-amount="(amount) => emitEvent('setCashAmount', amount)"
@set-paid-amount="(amount) => emitEvent('setPaidAmount', amount)"
@set-payment-method="
(paymentMethod) => emitEvent('setPaymentMethod', paymentMethod)
"
@set-transfer-ref-no="(ref) => emitEvent('setTransferRefNo', ref)"
@set-transfer-amount="(amount) => emitEvent('setTransferAmount', amount)"
@set-transfer-clearance-date="
(date) => emitEvent('setTransferClearanceDate', date)
"
@ -349,7 +351,7 @@ export default defineComponent({
ModernPOSSelectedItemTable,
},
props: {
cashAmount: Money,
paidAmount: Money,
tableView: Boolean,
itemDiscounts: Money,
openAlertModal: Boolean,
@ -402,10 +404,11 @@ export default defineComponent({
'toggleModal',
'setCustomer',
'clearValues',
'setCashAmount',
'setPaidAmount',
'setCouponsCount',
'routeToSinvList',
'setLoyaltyPoints',
'setPaymentMethod',
'setTransferRefNo',
'applyPricingRule',
'saveInvoiceAction',
@ -425,7 +428,10 @@ export default defineComponent({
};
},
methods: {
emitEvent(eventName: PosEmits, ...args: (string | boolean | Item)[]) {
emitEvent(
eventName: PosEmits,
...args: (string | boolean | Item | Money)[]
) {
this.$emit(eventName, ...args);
},
selectedRow(row: SalesInvoiceItem, field: string) {

View File

@ -141,16 +141,13 @@ export default defineComponent({
this.posShiftDoc.openingAmounts = [];
await this.posShiftDoc.set('openingAmounts', [
{
paymentMethod: 'Cash',
amount: fyo.pesa(0),
},
{
paymentMethod: 'Transfer',
amount: fyo.pesa(0),
},
]);
const paymentMethods = (
(await this.fyo.db.getAll(ModelNameEnum.PaymentMethod, {
fields: ['name'],
})) as { name: string }[]
).map((doc) => ({ paymentMethod: doc.name, amount: fyo.pesa(0) }));
await this.posShiftDoc.set('openingAmounts', paymentMethods);
},
async seedDefaults() {
if (!!this.posShiftDoc?.isShiftOpen) {

View File

@ -20,7 +20,6 @@
:default-customer="defaultCustomer"
:is-pos-shift-open="isPosShiftOpen"
:items="(items as [] as POSItem[])"
:cash-amount="(cashAmount as Money)"
:sinv-doc="(sinvDoc as SalesInvoice)"
:disable-pay-button="disablePayButton"
:open-payment-modal="openPaymentModal"
@ -39,7 +38,8 @@
@clear-values="clearValues"
@set-customer="setCustomer"
@toggle-modal="toggleModal"
@set-cash-amount="setCashAmount"
@set-paid-amount="setPaidAmount"
@set-payment-method="setPaymentMethod"
@set-coupons-count="setCouponsCount"
@route-to-sinv-list="routeToSinvList"
@set-loyalty-points="setLoyaltyPoints"
@ -61,7 +61,6 @@
:default-customer="defaultCustomer"
:is-pos-shift-open="isPosShiftOpen"
:items="(items as [] as POSItem[])"
:cash-amount="(cashAmount as Money)"
:sinv-doc="(sinvDoc as SalesInvoice)"
:disable-pay-button="disablePayButton"
:open-payment-modal="openPaymentModal"
@ -81,7 +80,8 @@
@clear-values="clearValues"
@set-customer="setCustomer"
@toggle-modal="toggleModal"
@set-cash-amount="setCashAmount"
@set-paid-amount="setPaidAmount"
@set-payment-method="setPaymentMethod"
@set-coupons-count="setCouponsCount"
@route-to-sinv-list="routeToSinvList"
@apply-pricing-rule="applyPricingRule"
@ -155,7 +155,8 @@ export default defineComponent({
sinvDoc: computed(() => this.sinvDoc),
coupons: computed(() => this.coupons),
itemQtyMap: computed(() => this.itemQtyMap),
cashAmount: computed(() => this.cashAmount),
paidAmount: computed(() => this.paidAmount),
paymentMethod: computed(() => this.paymentMethod),
transferRefNo: computed(() => this.transferRefNo),
itemDiscounts: computed(() => this.itemDiscounts),
transferAmount: computed(() => this.transferAmount),
@ -188,7 +189,7 @@ export default defineComponent({
openAppliedCouponsModal: false,
totalQuantity: 0,
cashAmount: fyo.pesa(0),
paidAmount: fyo.pesa(0),
itemDiscounts: fyo.pesa(0),
transferAmount: fyo.pesa(0),
totalTaxedAmount: fyo.pesa(0),
@ -202,6 +203,7 @@ export default defineComponent({
appliedCoupons: [] as AppliedCouponCodes[],
itemSearchTerm: '',
paymentMethod: undefined as string | undefined,
transferRefNo: undefined as string | undefined,
defaultCustomer: undefined as string | undefined,
transferClearanceDate: undefined as Date | undefined,
@ -396,8 +398,11 @@ export default defineComponent({
toggleView() {
this.tableView = !this.tableView;
},
setCashAmount(amount: Money) {
this.cashAmount = amount;
setPaidAmount(amount: Money) {
this.paidAmount = amount;
},
setPaymentMethod(method: string) {
this.paymentMethod = method;
},
setDefaultCustomer() {
this.defaultCustomer = this.fyo.singles.Defaults?.posCustomer ?? '';
@ -579,22 +584,26 @@ export default defineComponent({
},
async makePayment() {
this.paymentDoc = this.sinvDoc.getPayment() as Payment;
const paymentMethod = this.cashAmount.isZero() ? 'Transfer' : 'Cash';
const paymentMethod = this.paymentMethod;
await this.paymentDoc.set('paymentMethod', paymentMethod);
if (paymentMethod === 'Transfer') {
const paymentMethodDoc = await this.paymentDoc.loadAndGetLink(
'paymentMethod'
);
if (paymentMethodDoc?.type !== 'Cash') {
await this.paymentDoc.setMultiple({
amount: this.transferAmount as Money,
amount: this.paidAmount as Money,
referenceId: this.transferRefNo,
clearanceDate: this.transferClearanceDate,
});
}
if (paymentMethod === 'Cash') {
if (paymentMethodDoc?.type === 'Cash') {
await this.paymentDoc.setMultiple({
paymentAccount: this.defaultPOSCashAccount,
amount: this.cashAmount as Money,
amount: this.paidAmount as Money,
});
}
@ -688,7 +697,7 @@ export default defineComponent({
this.setSinvDoc();
this.itemSerialNumbers = {};
this.cashAmount = fyo.pesa(0);
this.paidAmount = fyo.pesa(0);
this.transferAmount = fyo.pesa(0);
await this.setItems();

View File

@ -1,43 +1,24 @@
<template>
<Modal class="w-2/6 ml-auto mr-3.5" :set-close-listener="false">
<div v-if="sinvDoc.fieldMap" class="px-4 py-6 grid" style="height: 95vh">
<Currency
:df="fyo.fieldMap.PaymentFor.amount"
:read-only="!transferAmount.isZero()"
:border="true"
:text-right="true"
:value="paidAmount"
@change="(amount:Money)=> $emit('setPaidAmount', amount)"
/>
<div class="grid grid-cols-2 gap-6">
<Currency
:df="fyo.fieldMap.PaymentFor.amount"
:read-only="!transferAmount.isZero()"
:border="true"
:text-right="true"
:value="cashAmount"
@change="(amount:Money)=> $emit('setCashAmount', amount)"
/>
<Button
v-for="method in paymentMethods"
:key="method"
class="w-full py-5 bg-teal-500"
@click="setCashOrTransferAmount"
@click="setPaymentMethodAndAmount(method, paidAmount)"
>
<slot>
<p class="uppercase text-lg text-white font-semibold">
{{ t`Cash` }}
</p>
</slot>
</Button>
<Currency
:df="fyo.fieldMap.PaymentFor.amount"
:read-only="!cashAmount.isZero()"
:border="true"
:text-right="true"
:value="transferAmount"
@change="(value:Money)=> $emit('setTransferAmount', value)"
/>
<Button
class="w-full py-5 bg-teal-500"
@click="setCashOrTransferAmount('Transfer')"
>
<slot>
<p class="uppercase text-lg text-white font-semibold">
{{ t`Transfer` }}
{{ t`${method}` }}
</p>
</slot>
</Button>
@ -45,7 +26,7 @@
<div class="mt-8 grid grid-cols-2 gap-6">
<Data
v-show="!transferAmount.isZero()"
v-show="!isPaymentMethodIsCash"
:df="fyo.fieldMap.Payment.referenceId"
:show-label="true"
:border="true"
@ -55,7 +36,7 @@
/>
<Date
v-show="!transferAmount.isZero()"
v-show="!isPaymentMethodIsCash"
:df="fyo.fieldMap.Payment.clearanceDate"
:show-label="true"
:border="true"
@ -149,7 +130,7 @@
/>
</div>
<div class="row-start-6 grid grid-cols-2 gap-4 mt-auto">
<div class="grid grid-cols-2 gap-4 fixed bottom-8" style="width: 25rem">
<div class="col-span-2">
<Button
class="w-full bg-red-500 dark:bg-red-700"
@ -207,6 +188,8 @@ import { Money } from 'pesa';
import { SalesInvoice } from 'models/baseModels/SalesInvoice/SalesInvoice';
import { defineComponent, inject } from 'vue';
import { fyo } from 'src/initFyo';
import { isPesa } from 'fyo/utils';
import { ModelNameEnum } from 'models/types';
export default defineComponent({
name: 'PaymentModal',
@ -219,15 +202,16 @@ export default defineComponent({
},
emits: [
'createTransaction',
'setCashAmount',
'setTransferAmount',
'setPaidAmount',
'setPaymentMethod',
'setTransferClearanceDate',
'setTransferRefNo',
'toggleModal',
],
setup() {
return {
cashAmount: inject('cashAmount') as Money,
paidAmount: inject('paidAmount') as Money,
paymentMethod: inject('paymentMethod') as string,
isDiscountingEnabled: inject('isDiscountingEnabled') as boolean,
itemDiscounts: inject('itemDiscounts') as Money,
transferAmount: inject('transferAmount') as Money,
@ -237,34 +221,46 @@ export default defineComponent({
totalTaxedAmount: inject('totalTaxedAmount') as Money,
};
},
data() {
return {
paymentMethods: [] as string[],
};
},
computed: {
isPaymentMethodIsCash(): boolean {
return this.paymentMethod === 'Cash';
},
balanceAmount(): Money {
const grandTotal = this.sinvDoc?.grandTotal ?? fyo.pesa(0);
if (this.cashAmount.isZero()) {
if (isPesa(this.paidAmount) && this.paidAmount.isZero()) {
return grandTotal.sub(this.transferAmount);
}
return grandTotal.sub(this.cashAmount);
return grandTotal.sub(this.paidAmount);
},
paidChange(): Money {
const grandTotal = this.sinvDoc?.grandTotal ?? fyo.pesa(0);
if (this.cashAmount.isZero()) {
if (this.fyo.pesa(this.paidAmount.float).isZero()) {
return this.transferAmount.sub(grandTotal);
}
return this.cashAmount.sub(grandTotal);
return this.fyo.pesa(this.paidAmount.float).sub(grandTotal);
},
showBalanceAmount(): boolean {
if (
this.cashAmount.eq(fyo.pesa(0)) &&
this.fyo.pesa(this.paidAmount.float).eq(fyo.pesa(0)) &&
this.transferAmount.eq(fyo.pesa(0))
) {
return false;
}
if (this.cashAmount.gte(this.sinvDoc?.grandTotal ?? fyo.pesa(0))) {
if (
this.fyo
.pesa(this.paidAmount.float)
.gte(this.sinvDoc?.grandTotal ?? fyo.pesa(0))
) {
return false;
}
@ -276,13 +272,17 @@ export default defineComponent({
},
showPaidChange(): boolean {
if (
this.cashAmount.eq(fyo.pesa(0)) &&
this.fyo.pesa(this.paidAmount.float).eq(fyo.pesa(0)) &&
this.transferAmount.eq(fyo.pesa(0))
) {
return false;
}
if (this.cashAmount.gt(this.sinvDoc?.grandTotal ?? fyo.pesa(0))) {
if (
this.fyo
.pesa(this.paidAmount.float)
.gt(this.sinvDoc?.grandTotal ?? fyo.pesa(0))
) {
return true;
}
@ -294,15 +294,14 @@ export default defineComponent({
},
disableSubmitButton(): boolean {
if (
!this.sinvDoc.grandTotal?.isZero() &&
this.transferAmount.isZero() &&
this.cashAmount.isZero()
(this.sinvDoc.grandTotal?.float as number) < 1 &&
this.fyo.pesa(this.paidAmount.float).isZero()
) {
return true;
}
if (
this.cashAmount.isZero() &&
this.paymentMethod !== 'Cash' &&
(!this.transferRefNo || !this.transferClearanceDate)
) {
return true;
@ -310,15 +309,25 @@ export default defineComponent({
return false;
},
},
async activated() {
await this.setPaymentMethods();
},
methods: {
setCashOrTransferAmount(paymentMethod = 'Cash') {
if (paymentMethod === 'Transfer') {
this.$emit('setCashAmount', fyo.pesa(0));
this.$emit('setTransferAmount', this.sinvDoc?.grandTotal);
return;
setPaymentMethodAndAmount(paymentMethod?: string, amount?: Money) {
if (paymentMethod) {
this.$emit('setPaymentMethod', paymentMethod);
}
this.$emit('setTransferAmount', fyo.pesa(0));
this.$emit('setCashAmount', this.sinvDoc?.grandTotal);
if (amount) {
this.$emit('setPaidAmount', this.sinvDoc.grandTotal?.float);
}
},
async setPaymentMethods() {
this.paymentMethods = (
(await this.fyo.db.getAll(ModelNameEnum.PaymentMethod, {
fields: ['name'],
})) as { name: string }[]
).map((d) => d.name);
},
submitTransaction() {
this.$emit('createTransaction');