fix: replace hardcoded meta fields with validation from backend

This commit is contained in:
raizasafeel
2026-03-05 02:05:00 +05:30
parent 5683fd5d7a
commit a893c405d1
3 changed files with 95 additions and 49 deletions
@@ -55,17 +55,18 @@
:label="__('Member')" :label="__('Member')"
doctype="User" doctype="User"
v-model="transactionData.member" v-model="transactionData.member"
:required="true" :required="!!fieldMeta.member?.reqd"
/> />
<FormControl <FormControl
:label="__('Billing Name')" :label="__('Billing Name')"
v-model="transactionData.billing_name" v-model="transactionData.billing_name"
:required="true" :required="!!fieldMeta.billing_name?.reqd"
/> />
<Link <Link
:label="__('Source')" :label="__('Source')"
v-model="transactionData.source" v-model="transactionData.source"
doctype="LMS Source" doctype="LMS Source"
:required="!!fieldMeta.source?.reqd"
/> />
<FormControl <FormControl
type="select" type="select"
@@ -73,12 +74,14 @@
:label="__('Payment For Document Type')" :label="__('Payment For Document Type')"
v-model="transactionData.payment_for_document_type" v-model="transactionData.payment_for_document_type"
doctype="DocType" doctype="DocType"
:required="!!fieldMeta.payment_for_document_type?.reqd"
/> />
<Link <Link
v-if="transactionData.payment_for_document_type" v-if="transactionData.payment_for_document_type"
:label="__('Payment For Document')" :label="__('Payment For Document')"
v-model="transactionData.payment_for_document" v-model="transactionData.payment_for_document"
:doctype="transactionData.payment_for_document_type" :doctype="transactionData.payment_for_document_type"
:required="!!fieldMeta.payment_for_document?.reqd"
/> />
</div> </div>
@@ -90,17 +93,18 @@
:label="__('Currency')" :label="__('Currency')"
v-model="transactionData.currency" v-model="transactionData.currency"
doctype="Currency" doctype="Currency"
:required="true" :required="!!fieldMeta.currency?.reqd"
/> />
<FormControl <FormControl
:label="__('Amount')" :label="__('Amount')"
v-model="transactionData.amount" v-model="transactionData.amount"
:required="true" :required="!!fieldMeta.amount?.reqd"
/> />
<FormControl <FormControl
v-if="transactionData.amount_with_gst" v-if="transactionData.amount_with_gst"
:label="__('Amount with GST')" :label="__('Amount with GST')"
v-model="transactionData.amount_with_gst" v-model="transactionData.amount_with_gst"
:required="!!fieldMeta.amount_with_gst?.reqd"
/> />
</div> </div>
@@ -113,21 +117,25 @@
v-if="transactionData.coupon" v-if="transactionData.coupon"
:label="__('Coupon Code')" :label="__('Coupon Code')"
v-model="transactionData.coupon" v-model="transactionData.coupon"
:required="!!fieldMeta.coupon?.reqd"
/> />
<FormControl <FormControl
v-if="transactionData.coupon" v-if="transactionData.coupon"
:label="__('Coupon Code')" :label="__('Coupon Code')"
v-model="transactionData.coupon_code" v-model="transactionData.coupon_code"
:required="!!fieldMeta.coupon_code?.reqd"
/> />
<FormControl <FormControl
v-if="transactionData.coupon" v-if="transactionData.coupon"
:label="__('Discount Amount')" :label="__('Discount Amount')"
v-model="transactionData.discount_amount" v-model="transactionData.discount_amount"
:required="!!fieldMeta.discount_amount?.reqd"
/> />
<FormControl <FormControl
v-if="transactionData.coupon" v-if="transactionData.coupon"
:label="__('Original Amount')" :label="__('Original Amount')"
v-model="transactionData.original_amount" v-model="transactionData.original_amount"
:required="!!fieldMeta.original_amount?.reqd"
/> />
</div> </div>
</div> </div>
@@ -140,17 +148,27 @@
:label="__('Address')" :label="__('Address')"
v-model="transactionData.address" v-model="transactionData.address"
doctype="Address" doctype="Address"
:required="true" :required="!!fieldMeta.address?.reqd"
/>
<FormControl
:label="__('GSTIN')"
v-model="transactionData.gstin"
:required="!!fieldMeta.gstin?.reqd"
/>
<FormControl
:label="__('PAN')"
v-model="transactionData.pan"
:required="!!fieldMeta.pan?.reqd"
/> />
<FormControl :label="__('GSTIN')" v-model="transactionData.gstin" />
<FormControl :label="__('PAN')" v-model="transactionData.pan" />
<FormControl <FormControl
:label="__('Payment ID')" :label="__('Payment ID')"
v-model="transactionData.payment_id" v-model="transactionData.payment_id"
:required="!!fieldMeta.payment_id?.reqd"
/> />
<FormControl <FormControl
:label="__('Order ID')" :label="__('Order ID')"
v-model="transactionData.order_id" v-model="transactionData.order_id"
:required="!!fieldMeta.order_id?.reqd"
/> />
</div> </div>
</div> </div>
@@ -171,6 +189,10 @@ const show = defineModel('show')
const props = defineProps<{ const props = defineProps<{
transactions: any transactions: any
data: any data: any
fieldMeta: Record<
string,
{ reqd?: number; default?: string; description?: string }
>
}>() }>()
const saveTransaction = () => { const saveTransaction = () => {
@@ -226,33 +248,36 @@ const openDetails = () => {
} }
} }
const emptyTransactionData = { const getDefault = (fieldname: string) =>
props.fieldMeta[fieldname]?.default || null
const getEmptyTransactionData = () => ({
payment_received: false, payment_received: false,
payment_for_certificate: false, payment_for_certificate: false,
member: null, member: getDefault('member'),
billing_name: null, billing_name: getDefault('billing_name'),
source: null, source: getDefault('source'),
payment_for_document_type: null, payment_for_document_type: getDefault('payment_for_document_type'),
payment_for_document: null, payment_for_document: getDefault('payment_for_document'),
member_consent: false, member_consent: false,
currency: null, currency: getDefault('currency'),
amount: null, amount: getDefault('amount'),
amount_with_gst: null, amount_with_gst: getDefault('amount_with_gst'),
coupon: null, coupon: getDefault('coupon'),
coupon_code: null, coupon_code: getDefault('coupon_code'),
discount_amount: null, discount_amount: getDefault('discount_amount'),
original_amount: null, original_amount: getDefault('original_amount'),
order_id: null, order_id: getDefault('order_id'),
payment_id: null, payment_id: getDefault('payment_id'),
gstin: null, gstin: getDefault('gstin'),
pan: null, pan: getDefault('pan'),
address: null, address: getDefault('address'),
} })
watch( watch(
() => props.data, () => props.data,
(newVal) => { (newVal) => {
transactionData.value = newVal ? { ...newVal } : emptyTransactionData transactionData.value = newVal ? { ...newVal } : getEmptyTransactionData()
}, },
{ immediate: true } { immediate: true }
) )
@@ -3,6 +3,7 @@
v-if="step == 'new'" v-if="step == 'new'"
:transactions="transactions" :transactions="transactions"
:data="data" :data="data"
:fieldMeta="fieldMeta.data || {}"
v-model:show="show" v-model:show="show"
@updateStep="updateStep" @updateStep="updateStep"
/> />
@@ -17,13 +18,14 @@
v-else-if="step == 'details'" v-else-if="step == 'details'"
:transactions="transactions" :transactions="transactions"
:data="data" :data="data"
:fieldMeta="fieldMeta.data || {}"
v-model:show="show" v-model:show="show"
@updateStep="updateStep" @updateStep="updateStep"
/> />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref } from 'vue'
import { createListResource } from 'frappe-ui' import { createListResource, createResource } from 'frappe-ui'
import TransactionList from '@/components/Settings/Transactions/TransactionList.vue' import TransactionList from '@/components/Settings/Transactions/TransactionList.vue'
import TransactionDetails from '@/components/Settings/Transactions/TransactionDetails.vue' import TransactionDetails from '@/components/Settings/Transactions/TransactionDetails.vue'
@@ -45,6 +47,11 @@ const updateStep = (newStep: 'list' | 'new' | 'edit', newData: any) => {
} }
} }
const fieldMeta = createResource({
url: 'lms.lms.api.get_payment_field_meta',
auto: true,
})
const transactions = createListResource({ const transactions = createListResource({
doctype: 'LMS Payment', doctype: 'LMS Payment',
fields: [ fields: [
+35 -21
View File
@@ -114,25 +114,27 @@
<FormControl <FormControl
:label="__('Billing Name')" :label="__('Billing Name')"
v-model="billingDetails.billing_name" v-model="billingDetails.billing_name"
:required="true" :required="!!fieldMeta.billing_name?.reqd"
/> />
<FormControl <FormControl
:label="__('Address Line 1')" :label="__('Address Line 1')"
v-model="billingDetails.address_line1" v-model="billingDetails.address_line1"
:required="true" :required="!!fieldMeta.address_line1?.reqd"
/> />
<FormControl <FormControl
:label="__('Address Line 2')" :label="__('Address Line 2')"
v-model="billingDetails.address_line2" v-model="billingDetails.address_line2"
:required="!!fieldMeta.address_line2?.reqd"
/> />
<FormControl <FormControl
:label="__('City')" :label="__('City')"
v-model="billingDetails.city" v-model="billingDetails.city"
:required="true" :required="!!fieldMeta.city?.reqd"
/> />
<FormControl <FormControl
:label="__('State/Province')" :label="__('State/Province')"
v-model="billingDetails.state" v-model="billingDetails.state"
:required="!!fieldMeta.state?.reqd"
/> />
</div> </div>
<div class="space-y-4"> <div class="space-y-4">
@@ -141,34 +143,36 @@
:value="billingDetails.country" :value="billingDetails.country"
@change="(option) => changeCurrency(option)" @change="(option) => changeCurrency(option)"
:label="__('Country')" :label="__('Country')"
:required="true" :required="!!fieldMeta.country?.reqd"
/> />
<FormControl <FormControl
:label="__('Postal Code')" :label="__('Postal Code')"
v-model="billingDetails.pincode" v-model="billingDetails.pincode"
:required="true" :required="!!fieldMeta.pincode?.reqd"
/> />
<FormControl <FormControl
:label="__('Phone Number')" :label="__('Phone Number')"
v-model="billingDetails.phone" v-model="billingDetails.phone"
:required="true" :required="!!fieldMeta.phone?.reqd"
/> />
<Link <Link
doctype="LMS Source" doctype="LMS Source"
:value="billingDetails.source" :value="billingDetails.source"
@change="(option) => (billingDetails.source = option)" @change="(option) => (billingDetails.source = option)"
:label="__('Where did you hear about us?')" :label="__('Where did you hear about us?')"
:required="true" :required="!!fieldMeta.source?.reqd"
/> />
<FormControl <FormControl
v-if="billingDetails.country == 'India'" v-if="billingDetails.country == 'India'"
:label="__('GST Number')" :label="__('GST Number')"
v-model="billingDetails.gstin" v-model="billingDetails.gstin"
:required="!!fieldMeta.gstin?.reqd"
/> />
<FormControl <FormControl
v-if="billingDetails.country == 'India'" v-if="billingDetails.country == 'India'"
:label="__('PAN Number')" :label="__('PAN Number')"
v-model="billingDetails.pan" v-model="billingDetails.pan"
:required="!!fieldMeta.pan?.reqd"
/> />
</div> </div>
</div> </div>
@@ -273,6 +277,7 @@ const access = createResource({
name: props.name, name: props.name,
}, },
onSuccess(data) { onSuccess(data) {
Object.assign(fieldMeta, data.billing_field_meta || {})
setBillingDetails(data.address) setBillingDetails(data.address)
orderSummary.submit() orderSummary.submit()
}, },
@@ -295,19 +300,24 @@ const orderSummary = createResource({
const appliedCoupon = ref(null) const appliedCoupon = ref(null)
const billingDetails = reactive({}) const billingDetails = reactive({})
const fieldMeta = reactive({})
const getDefault = (fieldname) => fieldMeta[fieldname]?.default || ''
const setBillingDetails = (data) => { const setBillingDetails = (data) => {
billingDetails.billing_name = data?.billing_name || '' billingDetails.billing_name = data?.billing_name || getDefault('billing_name')
billingDetails.address_line1 = data?.address_line1 || '' billingDetails.address_line1 =
billingDetails.address_line2 = data?.address_line2 || '' data?.address_line1 || getDefault('address_line1')
billingDetails.city = data?.city || '' billingDetails.address_line2 =
billingDetails.state = data?.state || '' data?.address_line2 || getDefault('address_line2')
billingDetails.country = data?.country || '' billingDetails.city = data?.city || getDefault('city')
billingDetails.pincode = data?.pincode || '' billingDetails.state = data?.state || getDefault('state')
billingDetails.phone = data?.phone || '' billingDetails.country = data?.country || getDefault('country')
billingDetails.source = data?.source || '' billingDetails.pincode = data?.pincode || getDefault('pincode')
billingDetails.gstin = data?.gstin || '' billingDetails.phone = data?.phone || getDefault('phone')
billingDetails.pan = data?.pan || '' billingDetails.source = data?.source || getDefault('source')
billingDetails.gstin = data?.gstin || getDefault('gstin')
billingDetails.pan = data?.pan || getDefault('pan')
} }
const paymentLink = createResource({ const paymentLink = createResource({
@@ -336,7 +346,7 @@ const generatePaymentLink = () => {
{}, {},
{ {
validate() { validate() {
if (!billingDetails.source) { if (!billingDetails.source && fieldMeta.source?.reqd) {
return __('Please let us know where you heard about us from.') return __('Please let us know where you heard about us from.')
} }
if (!billingDetails.member_consent) { if (!billingDetails.member_consent) {
@@ -370,15 +380,19 @@ function removeCoupon() {
} }
const validateAddress = () => { const validateAddress = () => {
let mandatoryFields = [ let billingFields = [
'billing_name', 'billing_name',
'address_line1', 'address_line1',
'address_line2',
'city', 'city',
'state',
'pincode', 'pincode',
'country', 'country',
'phone', 'phone',
'source', 'gstin',
'pan',
] ]
let mandatoryFields = billingFields.filter((f) => fieldMeta[f]?.reqd)
for (let field of mandatoryFields) { for (let field of mandatoryFields) {
if (!billingDetails[field]) if (!billingDetails[field])
return ( return (