chore: refactor payment settings
This commit is contained in:
@@ -52,7 +52,6 @@ const props = defineProps({
|
||||
const saveSettings = createResource({
|
||||
url: 'frappe.client.set_value',
|
||||
makeParams(values) {
|
||||
console.log(values)
|
||||
return {
|
||||
doctype: 'Website Settings',
|
||||
name: 'Website Settings',
|
||||
@@ -77,7 +76,6 @@ const update = () => {
|
||||
}
|
||||
|
||||
watch(props.data, (newData) => {
|
||||
console.log(newData)
|
||||
if (newData && !isDirty.value) {
|
||||
isDirty.value = true
|
||||
}
|
||||
|
||||
@@ -45,6 +45,13 @@
|
||||
:label="activeTab.label"
|
||||
:description="activeTab.description"
|
||||
/>
|
||||
<PaymentSettings
|
||||
v-else-if="activeTab.label === 'Payment Gateway'"
|
||||
:label="activeTab.label"
|
||||
:description="activeTab.description"
|
||||
:data="data"
|
||||
:fields="activeTab.fields"
|
||||
/>
|
||||
<BrandSettings
|
||||
v-else-if="activeTab.label === 'Branding'"
|
||||
:label="activeTab.label"
|
||||
@@ -73,6 +80,7 @@ import SidebarLink from '@/components/SidebarLink.vue'
|
||||
import Members from '@/components/Members.vue'
|
||||
import Categories from '@/components/Categories.vue'
|
||||
import BrandSettings from '@/components/BrandSettings.vue'
|
||||
import PaymentSettings from '@/components/PaymentSettings.vue'
|
||||
|
||||
const show = defineModel()
|
||||
const doctype = ref('LMS Settings')
|
||||
@@ -133,25 +141,12 @@ const tabsStructure = computed(() => {
|
||||
type: 'Link',
|
||||
doctype: 'Payment Gateway',
|
||||
},
|
||||
{
|
||||
label: 'Razorpay Key',
|
||||
name: 'razorpay_key',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
label: 'Razorpay Secret',
|
||||
name: 'razorpay_secret',
|
||||
type: 'password',
|
||||
},
|
||||
{
|
||||
label: 'Default Currency',
|
||||
name: 'default_currency',
|
||||
type: 'Link',
|
||||
doctype: 'Currency',
|
||||
},
|
||||
{
|
||||
type: 'Column Break',
|
||||
},
|
||||
{
|
||||
label: 'Apply GST for India',
|
||||
name: 'apply_gst',
|
||||
@@ -319,24 +314,6 @@ const tabs = computed(() => {
|
||||
})
|
||||
})
|
||||
|
||||
const paymentGateways = computed(() => {
|
||||
const gateways = [
|
||||
'Razorpay',
|
||||
'Stripe',
|
||||
'Mpesa',
|
||||
'Patym',
|
||||
'Paypal',
|
||||
'Braintree',
|
||||
'GoCardless',
|
||||
]
|
||||
return gateways.map((gateway) => {
|
||||
return {
|
||||
label: gateway,
|
||||
value: gateway,
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
watch(show, async () => {
|
||||
if (show.value) {
|
||||
const currentTab = await tabs.value
|
||||
|
||||
109
frontend/src/components/PaymentSettings.vue
Normal file
109
frontend/src/components/PaymentSettings.vue
Normal file
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<div class="flex flex-col min-h-0">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="text-xl font-semibold mb-1">
|
||||
{{ label }}
|
||||
</div>
|
||||
<!-- <Badge
|
||||
v-if="isDirty"
|
||||
:label="__('Not Saved')"
|
||||
variant="subtle"
|
||||
theme="orange"
|
||||
/> -->
|
||||
</div>
|
||||
<div class="overflow-y-scroll">
|
||||
<div class="flex space-x-4">
|
||||
<SettingFields :fields="fields" :data="data.doc" class="w-1/2" />
|
||||
<SettingFields
|
||||
v-if="paymentGateway.data"
|
||||
:fields="paymentGateway.data.fields"
|
||||
:data="paymentGateway.data.data"
|
||||
class="w-1/2"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-row-reverse mt-auto">
|
||||
<Button variant="solid" @click="update">
|
||||
{{ __('Update') }}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import SettingFields from '@/components/SettingFields.vue'
|
||||
import { createResource, Badge, Button } from 'frappe-ui'
|
||||
import { watch, ref } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
label: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
fields: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const paymentGateway = createResource({
|
||||
url: 'lms.lms.api.get_payment_gateway_details',
|
||||
makeParams(values) {
|
||||
return {
|
||||
payment_gateway: props.data.doc.payment_gateway,
|
||||
}
|
||||
},
|
||||
auto: true,
|
||||
})
|
||||
|
||||
const saveSettings = createResource({
|
||||
url: 'frappe.client.set_value',
|
||||
makeParams(values) {
|
||||
let fields = {}
|
||||
Object.keys(paymentGateway.data.data).forEach((key) => {
|
||||
if (
|
||||
paymentGateway.data.data[key] &&
|
||||
typeof paymentGateway.data.data[key] === 'object'
|
||||
) {
|
||||
fields[key] = paymentGateway.data.data[key].file_url
|
||||
} else {
|
||||
fields[key] = paymentGateway.data.data[key]
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
doctype: paymentGateway.data.doctype,
|
||||
name: paymentGateway.data.docname,
|
||||
fieldname: fields,
|
||||
}
|
||||
},
|
||||
auto: false,
|
||||
onSuccess(data) {
|
||||
paymentGateway.reload()
|
||||
},
|
||||
})
|
||||
|
||||
const update = () => {
|
||||
props.fields.forEach((f) => {
|
||||
if (f.type != 'Column Break') {
|
||||
props.data.doc[f.name] = f.value
|
||||
}
|
||||
})
|
||||
props.data.save.submit()
|
||||
saveSettings.submit()
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.data.doc.payment_gateway,
|
||||
() => {
|
||||
paymentGateway.reload()
|
||||
}
|
||||
)
|
||||
</script>
|
||||
@@ -90,7 +90,7 @@
|
||||
<script setup>
|
||||
import { FormControl, FileUploader, Button } from 'frappe-ui'
|
||||
import { computed } from 'vue'
|
||||
import { getFileSize } from '@/utils'
|
||||
import { getFileSize, validateFile } from '@/utils'
|
||||
import { X, FileText } from 'lucide-vue-next'
|
||||
import Link from '@/components/Controls/Link.vue'
|
||||
import Codemirror from 'codemirror-editor-vue3'
|
||||
|
||||
@@ -12,21 +12,20 @@
|
||||
v-if="access.data?.access && orderSummary.data"
|
||||
class="pt-5 pb-10 mx-5"
|
||||
>
|
||||
<div class="mb-5">
|
||||
<!-- <div class="mb-5">
|
||||
<div class="text-lg font-semibold">
|
||||
{{ __('Address') }}
|
||||
</div>
|
||||
<!-- <div class="text-sm text-gray-600 mt-1">
|
||||
{{ __('Specify your billing address correctly.') }}
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="grid grid-cols-[65%,30%] gap-10">
|
||||
<div class="h-fit bg-gray-100 rounded-md p-5 space-y-4 order-last">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="text-gray-700">
|
||||
</div> -->
|
||||
<div class="flex flex-col lg:flex-row justify-between">
|
||||
<div
|
||||
class="h-fit bg-gray-100 rounded-md p-5 space-y-4 lg:order-last mb-10 lg:mt-10 text-sm font-medium lg:w-1/4"
|
||||
>
|
||||
<div class="flex items-center justify-between space-x-2">
|
||||
<div class="text-gray-600">
|
||||
{{ __('Ordered Item') }}
|
||||
</div>
|
||||
<div class="font-medium">
|
||||
<div class="">
|
||||
{{ orderSummary.data.title }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -34,10 +33,10 @@
|
||||
v-if="orderSummary.data.gst_applied"
|
||||
class="flex items-center justify-between"
|
||||
>
|
||||
<div class="text-gray-700">
|
||||
<div class="text-gray-600">
|
||||
{{ __('Original Amount') }}
|
||||
</div>
|
||||
<div>
|
||||
<div class="">
|
||||
{{ orderSummary.data.original_amount_formatted }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -45,7 +44,7 @@
|
||||
v-if="orderSummary.data.gst_applied"
|
||||
class="flex items-center justify-between mt-2"
|
||||
>
|
||||
<div class="text-sm text-gray-600 font-medium">
|
||||
<div class="text-gray-600">
|
||||
{{ __('GST Amount') }}
|
||||
</div>
|
||||
<div>
|
||||
@@ -53,9 +52,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center justify-between font-semibold border-t border-gray-400 pt-4 mt-2"
|
||||
class="flex items-center justify-between border-t border-gray-400 pt-4 mt-2"
|
||||
>
|
||||
<div>
|
||||
<div class="text-lg font-semibold">
|
||||
{{ __('Total') }}
|
||||
</div>
|
||||
<div class="text-lg font-semibold">
|
||||
@@ -64,15 +63,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<!-- <div class="mb-5">
|
||||
<div class="flex-1 lg:mr-10">
|
||||
<div class="mb-5">
|
||||
<div class="text-lg font-semibold">
|
||||
{{ __('Address') }}
|
||||
</div>
|
||||
<div class="text-sm text-gray-600 mt-1">
|
||||
{{ __('Specify your billing address correctly.') }}
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-5">
|
||||
<div class="space-y-4">
|
||||
<FormControl
|
||||
@@ -92,14 +88,14 @@
|
||||
:label="__('State')"
|
||||
v-model="billingDetails.state"
|
||||
/>
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
<Link
|
||||
doctype="Country"
|
||||
:value="billingDetails.country"
|
||||
@change="(option) => changeCurrency(option)"
|
||||
:label="__('Country')"
|
||||
/>
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
<FormControl
|
||||
:label="__('Postal Code')"
|
||||
v-model="billingDetails.pincode"
|
||||
@@ -200,7 +196,6 @@ const access = createResource({
|
||||
const orderSummary = createResource({
|
||||
url: 'lms.lms.utils.get_order_summary',
|
||||
makeParams(values) {
|
||||
console.log(billingDetails.country)
|
||||
return {
|
||||
doctype: props.type == 'course' ? 'LMS Course' : 'LMS Batch',
|
||||
docname: props.name,
|
||||
@@ -234,6 +229,7 @@ const paymentLink = createResource({
|
||||
return {
|
||||
doctype: props.type == 'course' ? 'LMS Course' : 'LMS Batch',
|
||||
docname: props.name,
|
||||
title: orderSummary.data.title,
|
||||
amount: orderSummary.data.original_amount,
|
||||
total_amount: orderSummary.data.amount,
|
||||
currency: orderSummary.data.currency,
|
||||
@@ -247,6 +243,9 @@ const generatePaymentLink = () => {
|
||||
{},
|
||||
{
|
||||
validate() {
|
||||
if (!billingDetails.source) {
|
||||
return __('Please let us know where you heard about us from.')
|
||||
}
|
||||
return validateAddress()
|
||||
},
|
||||
onSuccess(data) {
|
||||
|
||||
@@ -244,7 +244,10 @@ const lesson = createResource({
|
||||
onSuccess(data) {
|
||||
lessonProgress.value = data.membership?.progress
|
||||
if (data.content) editor.value = renderEditor('editor', data.content)
|
||||
if (JSON.parse(data.instructor_content)?.blocks?.length > 1)
|
||||
if (
|
||||
data.instructor_content &&
|
||||
JSON.parse(data.instructor_content)?.blocks?.length > 1
|
||||
)
|
||||
instructorEditor.value = renderEditor(
|
||||
'instructor-content',
|
||||
data.instructor_content
|
||||
|
||||
@@ -708,3 +708,49 @@ def delete_documents(doctype, documents):
|
||||
frappe.only_for("Moderator")
|
||||
for doc in documents:
|
||||
frappe.delete_doc(doctype, doc)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_payment_gateway_details(payment_gateway):
|
||||
fields = []
|
||||
gateway = frappe.get_doc("Payment Gateway", payment_gateway)
|
||||
|
||||
if gateway.gateway_controller is None:
|
||||
try:
|
||||
data = frappe.get_doc(f"{payment_gateway} Settings").as_dict()
|
||||
meta = frappe.get_meta(f"{payment_gateway} Settings").fields
|
||||
doctype = f"{payment_gateway} Settings"
|
||||
docname = f"{payment_gateway} Settings"
|
||||
except Exception:
|
||||
frappe.throw(_("{0} Settings not found").format(payment_gateway))
|
||||
else:
|
||||
try:
|
||||
data = frappe.get_doc(gateway.gateway_settings, gateway.gateway_controller).as_dict()
|
||||
meta = frappe.get_meta(gateway.gateway_settings).fields
|
||||
doctype = gateway.gateway_settings
|
||||
docname = gateway.gateway_controller
|
||||
except Exception:
|
||||
frappe.throw(_("{0} Settings not found").format(payment_gateway))
|
||||
|
||||
for row in meta:
|
||||
if row.fieldtype not in ["Column Break", "Section Break"]:
|
||||
if row.fieldtype in ["Attach", "Attach Image"]:
|
||||
fieldtype = "Upload"
|
||||
data[row.fieldname] = get_file_info(data.get(row.fieldname))
|
||||
else:
|
||||
fieldtype = row.fieldtype
|
||||
|
||||
fields.append(
|
||||
{
|
||||
"label": row.label,
|
||||
"name": row.fieldname,
|
||||
"type": fieldtype,
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
"fields": fields,
|
||||
"data": data,
|
||||
"doctype": doctype,
|
||||
"docname": docname,
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ from lms.lms.utils import (
|
||||
get_lesson_url,
|
||||
get_quiz_details,
|
||||
get_assignment_details,
|
||||
update_payment_record,
|
||||
)
|
||||
from frappe.email.doctype.email_template.email_template import get_email_template
|
||||
|
||||
@@ -26,6 +27,7 @@ class LMSBatch(Document):
|
||||
self.validate_batch_end_date()
|
||||
self.validate_duplicate_courses()
|
||||
self.validate_duplicate_students()
|
||||
self.validate_payments_app()
|
||||
self.validate_duplicate_assessments()
|
||||
self.validate_membership()
|
||||
self.validate_timetable()
|
||||
@@ -55,6 +57,12 @@ class LMSBatch(Document):
|
||||
_("Course {0} has already been added to this batch.").format(frappe.bold(title))
|
||||
)
|
||||
|
||||
def validate_payments_app(self):
|
||||
if self.paid_batch:
|
||||
installed_apps = frappe.get_installed_apps()
|
||||
if "payments" not in installed_apps:
|
||||
frappe.throw(_("Please install the Payments app to create a paid batches."))
|
||||
|
||||
def validate_duplicate_assessments(self):
|
||||
assessments = [row.assessment_name for row in self.assessment]
|
||||
for assessment in self.assessment:
|
||||
@@ -165,64 +173,8 @@ class LMSBatch(Document):
|
||||
)
|
||||
|
||||
def on_payment_authorized(self, payment_status):
|
||||
if payment_status == "Authorized":
|
||||
self.update_payment_record()
|
||||
|
||||
def update_payment_record(self):
|
||||
request = frappe.get_all(
|
||||
"Integration Request",
|
||||
{
|
||||
"reference_doctype": self.doctype,
|
||||
"reference_docname": self.name,
|
||||
"owner": frappe.session.user,
|
||||
},
|
||||
order_by="creation desc",
|
||||
limit=1,
|
||||
)
|
||||
|
||||
if len(request):
|
||||
data = frappe.db.get_value("Integration Request", request[0].name, "data")
|
||||
data = frappe._dict(json.loads(data))
|
||||
|
||||
payment_gateway = data.get("payment_gateway")
|
||||
frappe.db.set_value(
|
||||
"LMS Payment",
|
||||
data.payment,
|
||||
{
|
||||
"payment_received": 1,
|
||||
"payment_id": data[f"{payment_gateway.lower()}_payment_id"],
|
||||
"order_id": data["order_id"],
|
||||
},
|
||||
)
|
||||
|
||||
try:
|
||||
enroll_in_batch(data.payment, self)
|
||||
except Exception as e:
|
||||
frappe.log_error(frappe.get_traceback(), _("Enrollment Failed"))
|
||||
|
||||
|
||||
def enroll_in_batch(payment_name, batch):
|
||||
if not frappe.db.exists(
|
||||
"Batch Student", {"parent": batch.name, "student": frappe.session.user}
|
||||
):
|
||||
student = frappe.new_doc("Batch Student")
|
||||
current_count = frappe.db.count("Batch Student", {"parent": batch.name})
|
||||
payment = frappe.db.get_value(
|
||||
"LMS Payment", payment_name, ["name", "source"], as_dict=True
|
||||
)
|
||||
|
||||
student.update(
|
||||
{
|
||||
"student": frappe.session.user,
|
||||
"payment": payment.name,
|
||||
"source": payment.source,
|
||||
"parent": batch.name,
|
||||
"parenttype": "LMS Batch",
|
||||
"parentfield": "students",
|
||||
"idx": current_count + 1,
|
||||
}
|
||||
)
|
||||
student.save(ignore_permissions=True)
|
||||
if payment_status in ["Authorized", "Completed"]:
|
||||
update_payment_record("LMS Batch", self.name)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
|
||||
@@ -8,7 +8,7 @@ from frappe.model.document import Document
|
||||
from frappe.utils import cint, today
|
||||
from frappe.utils.telemetry import capture
|
||||
from lms.lms.utils import get_chapters, can_create_courses
|
||||
from ...utils import generate_slug, validate_image
|
||||
from ...utils import generate_slug, validate_image, update_payment_record
|
||||
from frappe import _
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ class LMSCourse(Document):
|
||||
self.validate_instructors()
|
||||
self.validate_video_link()
|
||||
self.validate_status()
|
||||
self.validate_payments_app()
|
||||
self.image = validate_image(self.image)
|
||||
|
||||
def validate_published(self):
|
||||
@@ -44,10 +45,20 @@ class LMSCourse(Document):
|
||||
if self.published:
|
||||
self.status = "Approved"
|
||||
|
||||
def validate_payments_app(self):
|
||||
if self.paid_course:
|
||||
installed_apps = frappe.get_installed_apps()
|
||||
if "payments" not in installed_apps:
|
||||
frappe.throw(_("Please install the Payments app to create a paid courses."))
|
||||
|
||||
def on_update(self):
|
||||
if not self.upcoming and self.has_value_changed("upcoming"):
|
||||
self.send_email_to_interested_users()
|
||||
|
||||
def on_payment_authorized(self, payment_status):
|
||||
if payment_status in ["Authorized", "Completed"]:
|
||||
update_payment_record("LMS Course", self.name)
|
||||
|
||||
def send_email_to_interested_users(self):
|
||||
interested_users = frappe.get_all(
|
||||
"LMS Course Interest", {"course": self.name}, ["name", "user"]
|
||||
|
||||
@@ -43,14 +43,12 @@
|
||||
"payment_settings_tab",
|
||||
"payment_section",
|
||||
"payment_gateway",
|
||||
"razorpay_key",
|
||||
"razorpay_secret",
|
||||
"apply_gst",
|
||||
"column_break_cfcv",
|
||||
"default_currency",
|
||||
"exception_country",
|
||||
"column_break_cfcv",
|
||||
"apply_gst",
|
||||
"show_usd_equivalent",
|
||||
"apply_rounding",
|
||||
"exception_country",
|
||||
"email_templates_tab",
|
||||
"certification_template",
|
||||
"batch_confirmation_template",
|
||||
@@ -148,16 +146,6 @@
|
||||
"fieldname": "column_break_cfcv",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "razorpay_key",
|
||||
"fieldtype": "Data",
|
||||
"label": "Razorpay Key"
|
||||
},
|
||||
{
|
||||
"fieldname": "razorpay_secret",
|
||||
"fieldtype": "Password",
|
||||
"label": "Razorpay Secret"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "apply_gst",
|
||||
@@ -174,7 +162,7 @@
|
||||
"depends_on": "show_usd_equivalent",
|
||||
"fieldname": "exception_country",
|
||||
"fieldtype": "Table MultiSelect",
|
||||
"label": "Maintain Original Currency",
|
||||
"label": "Primary Countries",
|
||||
"options": "Payment Country"
|
||||
},
|
||||
{
|
||||
@@ -343,7 +331,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2024-09-24 19:55:47.914930",
|
||||
"modified": "2024-09-30 18:30:28.689084",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Settings",
|
||||
|
||||
@@ -16,7 +16,7 @@ def validate_currency(payment_gateway, currency):
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_payment_link(doctype, docname, amount, total_amount, currency, address):
|
||||
def get_payment_link(doctype, docname, title, amount, total_amount, currency, address):
|
||||
payment_gateway = get_payment_gateway()
|
||||
address = frappe._dict(address)
|
||||
amount_with_gst = total_amount if total_amount != amount else 0
|
||||
@@ -24,26 +24,24 @@ def get_payment_link(doctype, docname, amount, total_amount, currency, address):
|
||||
payment = record_payment(address, doctype, docname, amount, currency, amount_with_gst)
|
||||
controller = get_controller(payment_gateway)
|
||||
|
||||
if controller.doctype == "Stripe Settings":
|
||||
print(controller.as_dict())
|
||||
doctype = "Stripe Settings"
|
||||
docname = controller.name
|
||||
if doctype == "LMS Course":
|
||||
redirect_to = f"/lms/courses/{docname}/learn/1-1"
|
||||
elif doctype == "LMS Batch":
|
||||
redirect_to = f"/lms/batches/{docname}"
|
||||
|
||||
payment_details = {
|
||||
"amount": total_amount,
|
||||
"title": f"Payment for {doctype} {docname}",
|
||||
"description": f"{address.billing_name}'s payment for {doctype} {docname}",
|
||||
"title": f"Payment for {doctype} {title} {docname}",
|
||||
"description": f"{address.billing_name}'s payment for {title}",
|
||||
"reference_doctype": doctype,
|
||||
"reference_docname": docname,
|
||||
"payer_email": frappe.session.user,
|
||||
"payer_name": address.billing_name,
|
||||
"order_id": docname,
|
||||
"currency": currency,
|
||||
"payment_gateway": payment_gateway,
|
||||
"redirect_to": f"/lms/batches/{docname}",
|
||||
"redirect_to": redirect_to,
|
||||
"payment": payment.name,
|
||||
}
|
||||
print(controller)
|
||||
url = controller.get_payment_url(**payment_details)
|
||||
|
||||
return url
|
||||
|
||||
@@ -1682,12 +1682,10 @@ def get_order_summary(doctype, docname, country=None):
|
||||
)
|
||||
details.original_amount = details.amount
|
||||
details.original_amount_formatted = fmt_money(details.amount, 0, details.currency)
|
||||
print(details.currency)
|
||||
|
||||
if details.currency == "INR":
|
||||
print("inside")
|
||||
details.amount, details.gst_applied = apply_gst(details.amount)
|
||||
details.amount, details.gst_applied = apply_gst(details.amount, country)
|
||||
details.gst_amount_formatted = fmt_money(details.gst_applied, 0, details.currency)
|
||||
print(details.amount, details.gst_applied, details.gst_amount_formatted)
|
||||
|
||||
details.total_amount_formatted = fmt_money(details.amount, 0, details.currency)
|
||||
return details
|
||||
@@ -1744,3 +1742,89 @@ def publish_notifications(doc, method):
|
||||
frappe.publish_realtime(
|
||||
"publish_lms_notifications", user=doc.for_user, after_commit=True
|
||||
)
|
||||
|
||||
|
||||
def update_payment_record(doctype, docname):
|
||||
request = frappe.get_all(
|
||||
"Integration Request",
|
||||
{
|
||||
"reference_doctype": doctype,
|
||||
"reference_docname": docname,
|
||||
"owner": frappe.session.user,
|
||||
},
|
||||
order_by="creation desc",
|
||||
limit=1,
|
||||
)
|
||||
|
||||
if len(request):
|
||||
data = frappe.db.get_value("Integration Request", request[0].name, "data")
|
||||
data = frappe._dict(json.loads(data))
|
||||
|
||||
payment_gateway = data.get("payment_gateway")
|
||||
if payment_gateway == "Razorpay":
|
||||
payment_id = "razorpay_payment_id"
|
||||
elif "Stripe" in payment_gateway:
|
||||
payment_id = "stripe_token_id"
|
||||
else:
|
||||
payment_id = "order_id"
|
||||
|
||||
frappe.db.set_value(
|
||||
"LMS Payment",
|
||||
data.payment,
|
||||
{
|
||||
"payment_received": 1,
|
||||
"payment_id": data.get(payment_id),
|
||||
"order_id": data.get("order_id"),
|
||||
},
|
||||
)
|
||||
|
||||
try:
|
||||
if doctype == "LMS Course":
|
||||
enroll_in_course(data.payment, docname)
|
||||
else:
|
||||
enroll_in_batch(data.payment, docname)
|
||||
except Exception as e:
|
||||
frappe.log_error(frappe.get_traceback(), _("Enrollment Failed"))
|
||||
|
||||
|
||||
def enroll_in_course(payment_name, course):
|
||||
if not frappe.db.exists(
|
||||
"LMS Enrollment", {"member": frappe.session.user, "course": course}
|
||||
):
|
||||
enrollment = frappe.new_doc("LMS Enrollment")
|
||||
payment = frappe.db.get_value(
|
||||
"LMS Payment", payment_name, ["name", "source"], as_dict=True
|
||||
)
|
||||
|
||||
enrollment.update(
|
||||
{
|
||||
"member": frappe.session.user,
|
||||
"course": course,
|
||||
"payment": payment.name,
|
||||
}
|
||||
)
|
||||
enrollment.save(ignore_permissions=True)
|
||||
|
||||
|
||||
def enroll_in_batch(payment_name, batch):
|
||||
if not frappe.db.exists(
|
||||
"Batch Student", {"parent": batch, "student": frappe.session.user}
|
||||
):
|
||||
student = frappe.new_doc("Batch Student")
|
||||
current_count = frappe.db.count("Batch Student", {"parent": batch})
|
||||
payment = frappe.db.get_value(
|
||||
"LMS Payment", payment_name, ["name", "source"], as_dict=True
|
||||
)
|
||||
|
||||
student.update(
|
||||
{
|
||||
"student": frappe.session.user,
|
||||
"payment": payment.name,
|
||||
"source": payment.source,
|
||||
"parent": batch,
|
||||
"parenttype": "LMS Batch",
|
||||
"parentfield": "students",
|
||||
"idx": current_count + 1,
|
||||
}
|
||||
)
|
||||
student.save(ignore_permissions=True)
|
||||
|
||||
Reference in New Issue
Block a user