Merge branch 'develop' into lms-refactor
diff --git a/erpnext/public/js/education/lms/call.js b/erpnext/public/js/education/lms/call.js
index e35acbd..4edcaaa 100644
--- a/erpnext/public/js/education/lms/call.js
+++ b/erpnext/public/js/education/lms/call.js
@@ -2,7 +2,7 @@
frappe.provide('lms');
lms.call = (method, args) => {
- const method_path = 'erpnext.www.lms.' + method;
+ const method_path = 'erpnext.www.lms_legacy.' + method;
return new Promise((resolve, reject) => {
return frappe.call({
method: method_path,
diff --git a/erpnext/www/lms/__init__.py b/erpnext/www/lms/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/www/lms/__init__.py
diff --git a/erpnext/www/lms/all-programs.html b/erpnext/www/lms/all-programs.html
new file mode 100644
index 0000000..1003e5e
--- /dev/null
+++ b/erpnext/www/lms/all-programs.html
@@ -0,0 +1,76 @@
+{% extends "templates/base.html" %}
+{% block title %}All Programs{% endblock %}
+
+{% block head_include %}
+ <style>
+ div.card-hero-img {
+ height: 220px;
+ background-size: cover;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-color: rgb(250, 251, 252);
+ }
+
+ .card-image-wrapper {
+ display: flex;
+ overflow: hidden;
+ height: 220px;
+ background-color: rgb(250, 251, 252);
+ justify-content: center;
+ }
+
+ .image-body {
+ align-self: center;
+ color: #d1d8dd;
+ font-size: 24px;
+ font-weight: 600;
+ line-height: 1;
+ padding: 20px;
+ }
+ </style>
+{% endblock %}
+
+
+{% macro card(program, is_enrolled) %}
+<div class="col-sm mb-4 text-left">
+ <div class="card">
+ <a href="/lms/program?name={{ program.name }}" class="no-decoration no-underline">
+ {% if program.hero_image %}
+ <div class="card-hero-img" style="background-image: url({{ program.hero_image }})"></div>
+ {% else %}
+ <div class="card-image-wrapper text-center">
+ <div class="image-body">{{ program.program_name }}</div>
+ </div>
+ {% endif %}
+ <div class='card-body'>
+ <h5 class='card-title'>{{ program.program_name }}</h5>
+ <div>{{ program.description }}</div>
+ </div>
+ <div class='card-footer'>
+ <a href='#' class='small'>Watch Intro</a>
+ </div>
+ </a>
+ </div>
+</div>
+{% endmacro %}
+
+{% block content %}
+<section class="top-section ">
+ <div class='container pb-5'>
+ <h1>All Programs</h1>
+ <p class="mt-4">
+ <a class="btn btn-primary btn-lg" style="width: 170px;" href="/pricing">Start Learning</a>
+ </p>
+ </div>
+ <div class='container'>
+ <div class="row mt-5">
+ {% for program in all_programs %}
+ {{ card(program.program, program.is_enrolled) }}
+ {% endfor %}
+ </div>
+ <p class='mt-4'>
+ <a href='/lms/all-programs' class='text-muted'>View All Programs</a>
+ </p>
+ </div>
+</section>
+{% endblock %}
\ No newline at end of file
diff --git a/erpnext/www/lms/all_programs.py b/erpnext/www/lms/all_programs.py
new file mode 100644
index 0000000..aa10e2b
--- /dev/null
+++ b/erpnext/www/lms/all_programs.py
@@ -0,0 +1,15 @@
+from __future__ import unicode_literals
+import erpnext.education.utils as utils
+import frappe
+
+no_cache = 1
+
+def get_context(context):
+ context.education_settings = frappe.get_single("Education Settings")
+ context.all_programs = get_all_programs()
+
+def get_all_programs():
+ program_names = frappe.get_all("Program", filters={"is_published": True})
+ if program_names:
+ program_list = [utils.get_program_and_enrollment_status(program['name']) for program in program_names]
+ return program_list
diff --git a/erpnext/www/lms/course.html b/erpnext/www/lms/course.html
new file mode 100644
index 0000000..2e414a0
--- /dev/null
+++ b/erpnext/www/lms/course.html
@@ -0,0 +1,77 @@
+{% extends "templates/base.html" %}
+{% block title %}{{ course.course_name }}{% endblock %}
+
+{% block head_include %}
+ <style>
+ div.card-hero-img {
+ height: 220px;
+ background-size: cover;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-color: rgb(250, 251, 252);
+ }
+
+ .card-image-wrapper {
+ display: flex;
+ overflow: hidden;
+ height: 220px;
+ background-color: rgb(250, 251, 252);
+ justify-content: center;
+ }
+
+ .image-body {
+ align-self: center;
+ color: #d1d8dd;
+ font-size: 24px;
+ font-weight: 600;
+ line-height: 1;
+ padding: 20px;
+ }
+ </style>
+{% endblock %}
+
+
+{% macro card(topic, index, length) %}
+<div class="col-sm-{{ 12 if length%3 == 1 and index == 1 else 6 if length%3 == 2 and index in [1,2] else 4}} mb-4 text-left">
+ <div class="card h-100">
+ <a href="/lms/content?topic={{ topic.name }}&type=Content" class="no-decoration no-underline">
+ {% if topic.hero_image %}
+ <div class="card-hero-img" style="background-image: url({{ topic.hero_image }})"></div>
+ {% else %}
+ <div class="card-image-wrapper text-center">
+ <div class="image-body">{{ topic.topic_name }}</div>
+ </div>
+ {% endif %}
+ <div class='card-body'>
+ <h5 class='card-title'>{{ topic.topic_name }}</h5>
+ <div>
+ <ol class="list-unstyled">
+ {% for content in topic.topic_content %}
+ <li><a class="text-muted" href="/lms/content?topic={{ topic.name }}&type={{ content.content_type }}&content={{ content.content }}">{{ content.content }}</li></a>
+ {% endfor %}
+ </ol>
+ </div>
+ </div>
+ </a>
+ </div>
+</div>
+{% endmacro %}
+
+{% block content %}
+<section class="top-section ">
+ <div class='container pb-5'>
+ <h1>{{ course.course_name }}</h1>
+ <p class='lead'>{{ course.course_intro }}</p>
+ <p class="mt-4">
+ <a class="btn btn-primary btn-lg" style="width: 170px;" href="/login#signup">Sign Up</a>
+ </p>
+ </div>
+ <div class='container'>
+ <div class="row mt-5">
+ {% for topic in topics %}
+ {{ card(topic.as_dict(), loop.index, topics|length) }}
+ {% endfor %}
+ </div>
+ </div>
+</section>
+{% endblock %}
\ No newline at end of file
diff --git a/erpnext/www/lms/course.py b/erpnext/www/lms/course.py
new file mode 100644
index 0000000..d8670e6
--- /dev/null
+++ b/erpnext/www/lms/course.py
@@ -0,0 +1,11 @@
+from __future__ import unicode_literals
+import erpnext.education.utils as utils
+import frappe
+
+no_cache = 1
+
+def get_context(context):
+ context.education_settings = frappe.get_single("Education Settings")
+ course = frappe.get_doc('Course', frappe.form_dict['name'])
+ context.course = course
+ context.topics = course.get_topics()
\ No newline at end of file
diff --git a/erpnext/www/lms/index.html b/erpnext/www/lms/index.html
new file mode 100644
index 0000000..f475699
--- /dev/null
+++ b/erpnext/www/lms/index.html
@@ -0,0 +1,118 @@
+{% extends "templates/base.html" %}
+{% block title %}{{ education_settings.portal_title }}{% endblock %}
+
+{% block head_include %}
+ <meta name="description" content="{{ education_settings.description }}" />
+ <meta name="keywords" content="ERP Software, Cloud ERP, Open Source ERP, Accounting Software, Online ERP, Online Accounting, ERP for small business" />
+ <style>
+ div.card-hero-img {
+ height: 220px;
+ background-size: cover;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-color: rgb(250, 251, 252);
+ }
+
+ .card-image-wrapper {
+ display: flex;
+ overflow: hidden;
+ height: 220px;
+ background-color: rgb(250, 251, 252);
+ justify-content: center;
+ }
+
+ .image-body {
+ align-self: center;
+ color: #d1d8dd;
+ font-size: 24px;
+ font-weight: 600;
+ line-height: 1;
+ padding: 20px;
+ }
+ </style>
+{% endblock %}
+
+
+{% macro card(program, is_enrolled) %}
+<div class="col-sm mb-4 text-left">
+ <div class="card">
+ <a href="/lms/program?name={{ program.name }}" class="no-decoration no-underline">
+ {% if program.hero_image %}
+ <div class="card-hero-img" style="background-image: url({{ program.hero_image }})"></div>
+ {% else %}
+ <div class="card-image-wrapper text-center">
+ <div class="image-body">{{ program.program_name }}</div>
+ </div>
+ {% endif %}
+ <div class='card-body'>
+ <h5 class='card-title'>{{ program.program_name }}</h5>
+ <div>{{ program.description }}</div>
+ </div>
+ <div class='card-footer'>
+ <a class='small'>Watch Intro</a>
+ </div>
+ </a>
+ </div>
+</div>
+{% endmacro %}
+
+{% block content %}
+<section class="top-section ">
+ <div class='container pb-5'>
+ <h1>{{ education_settings.portal_title }}</h1>
+ <p class='lead'>{{ education_settings.description }}</p>
+ <p class="mt-4">
+ <a class="btn btn-primary btn-lg" style="width: 170px;" href="/pricing">Start Learning</a>
+ </p>
+ <a href="https://erpnext.com" target="blank" class="mt-0 small text-muted">Go to erpnext.com</a>
+ </div>
+ <div class='container'>
+ <div class="row mt-5">
+ {% for program in featured_programs %}
+ {{ card(program.program, program.is_enrolled) }}
+ {% endfor %}
+ </div>
+ <p class='mt-4'>
+ <a href='/lms/all-programs' class='text-muted'>View All Programs</a>
+ </p>
+ </div>
+</section>
+<section class="section-padding section-bg">
+ <div class='container'>
+ <div class='card-deck'>
+ <div class="card">
+ <!-- <img class='mt-3' src="/assets/erpnext_com/img/balloon.svg" style='height: 150px'> -->
+ <div class='card-body'>
+ <h5 class='card-title'>Curated Courses</h5>
+ <div>Start with a 14 day trial to get instant access to your own ERPNext Instance. Get expert support and world class hosting too.</div>
+ </div>
+ </div>
+
+ <div class="card">
+ <!-- <img class='mt-3' src="/assets/erpnext_com/img/umbrella.svg" style='height: 150px'> -->
+ <div class='card-body'>
+ <h5 class='card-title'>Built by Experts</h5>
+ <div>For self hosted users, ERPNext Support provides you the priority support and bug fix guarantee, so you can stop worrying.</div>
+ </div>
+ </div>
+
+ <div class="card">
+ <!-- <img class='mt-3' src="/assets/erpnext_com/img/sun.svg" style='height: 150px'> -->
+ <div class='card-body'>
+ <h5 class='card-title'>Learn from the OEMs</h5>
+ <div>ERPNext is open source and infinitely extensible. Customize it, build upon it, add your own apps built with <a href="https://frappe.io/frappe" class="underline">Frappe Framework</a>.</div>
+ </div>
+ </div>
+ </div>
+ </div>
+</section>
+<section class='section-padding'>
+ <div class='container text-center'>
+ <h3 class='text-center'>About ERPNext</h3>
+ <p class='lead'>ERPNext is the world's best 100% open source ERP used by over 5000 companies worldwide.</p>
+ <div class='mt-4 '>
+ <a class="btn btn-primary btn-lg" href="/pricing">Start Learning</a>
+ </div>
+ </div>
+</section>
+{% endblock %}
\ No newline at end of file
diff --git a/erpnext/www/lms/index.py b/erpnext/www/lms/index.py
new file mode 100644
index 0000000..99dcb65
--- /dev/null
+++ b/erpnext/www/lms/index.py
@@ -0,0 +1,24 @@
+from __future__ import unicode_literals
+import erpnext.education.utils as utils
+import frappe
+
+no_cache = 1
+
+def get_context(context):
+ context.education_settings = frappe.get_single("Education Settings")
+ context.featured_programs = get_featured_programs()
+
+
+def get_featured_programs():
+ featured_program_names = frappe.get_all("Program", filters={"is_published": True, "is_featured": True})
+ if featured_program_names:
+ featured_list = [utils.get_program_and_enrollment_status(program['name']) for program in featured_program_names]
+ return featured_list
+ else:
+ return get_all_programs()[:2]
+
+def get_all_programs():
+ program_names = frappe.get_all("Program", filters={"is_published": True})
+ if program_names:
+ program_list = [utils.get_program_and_enrollment_status(program['name']) for program in program_names]
+ return program_list
diff --git a/erpnext/www/lms/program.html b/erpnext/www/lms/program.html
new file mode 100644
index 0000000..35f7f8a
--- /dev/null
+++ b/erpnext/www/lms/program.html
@@ -0,0 +1,71 @@
+{% extends "templates/base.html" %}
+{% block title %}{{ program.program_name }}{% endblock %}
+
+{% block head_include %}
+ <style>
+ div.card-hero-img {
+ height: 220px;
+ background-size: cover;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-color: rgb(250, 251, 252);
+ }
+
+ .card-image-wrapper {
+ display: flex;
+ overflow: hidden;
+ height: 220px;
+ background-color: rgb(250, 251, 252);
+ justify-content: center;
+ }
+
+ .image-body {
+ align-self: center;
+ color: #d1d8dd;
+ font-size: 24px;
+ font-weight: 600;
+ line-height: 1;
+ padding: 20px;
+ }
+ </style>
+{% endblock %}
+
+
+{% macro card(course, index, length) %}
+<div class="col-sm-{{ 12 if length%3 == 1 and index == 1 else 6 if length%3 == 2 and index in [1,2] else 4}} mb-4 text-left">
+ <div class="card h-100">
+ <a href="/lms/course?name={{ course.name }}" class="no-decoration no-underline">
+ {% if course.hero_image %}
+ <div class="card-hero-img" style="background-image: url({{ course.hero_image }})"></div>
+ {% else %}
+ <div class="card-image-wrapper text-center">
+ <div class="image-body">{{ course.course_name }}</div>
+ </div>
+ {% endif %}
+ <div class='card-body'>
+ <h5 class='card-title'>{{ course.course_name }}</h5>
+ <div>{{ course.course_intro }}</div>
+ </div>
+ </a>
+ </div>
+</div>
+{% endmacro %}
+
+{% block content %}
+<section class="top-section ">
+ <div class='container pb-5'>
+ <h1>{{ program.program_name }}</h1>
+ <p class='lead'>{{ program.description }}</p>
+ <p class="mt-4">
+ <a class="btn btn-primary btn-lg" style="width: 170px;" href="/login#signup">Sign Up</a>
+ </p>
+ </div>
+ <div class='container'>
+ <div class="row mt-5">
+ {% for course in program.courses %}
+ {{ card(frappe.get_doc("Course", course.course), loop.index, program.courses|length) }}
+ {% endfor %}
+ </div>
+ </div>
+</section>
+{% endblock %}
\ No newline at end of file
diff --git a/erpnext/www/lms/program.py b/erpnext/www/lms/program.py
new file mode 100644
index 0000000..f38e652
--- /dev/null
+++ b/erpnext/www/lms/program.py
@@ -0,0 +1,15 @@
+from __future__ import unicode_literals
+import erpnext.education.utils as utils
+import frappe
+
+no_cache = 1
+
+def get_context(context):
+ context.education_settings = frappe.get_single("Education Settings")
+ context.program = get_program(frappe.form_dict['name'])
+
+def get_program(program_name):
+ try:
+ return frappe.get_doc('Program', program_name)
+ except frappe.DoesNotExistError:
+ frappe.throw(_("Program {0} does not exist.".format(program_name)))
\ No newline at end of file
diff --git a/erpnext/www/lms.py b/erpnext/www/lms_legacy.py
similarity index 100%
rename from erpnext/www/lms.py
rename to erpnext/www/lms_legacy.py
diff --git a/erpnext/www/lms.html b/erpnext/www/lms_old.html
similarity index 100%
rename from erpnext/www/lms.html
rename to erpnext/www/lms_old.html