mirror of
https://github.com/frappe/lms.git
synced 2026-05-02 13:39:31 +03:00
fix: replace hardcoded meta fields with validation from backend
This commit is contained in:
@@ -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: [
|
||||||
|
|||||||
@@ -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 (
|
||||||
|
|||||||
Reference in New Issue
Block a user