Loyalty Program (#12631)
* First Cut for the Loyalty Program * finished the collection part * redmeption for the loyalty point update the loyalty point entry in the FIFO style make the accounting entry knocking the debtors account against the expense account selected in the loyalty program update the outstanding balance in the client side * completed for the desk viewe * wrap up for the desk and shopping cart * pos * fix and test the travis
This commit is contained in:
parent
5d134e0465
commit
da486eeebd
@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Loyalty Point Entry', {
|
||||
refresh: function(frm) {
|
||||
|
||||
}
|
||||
});
|
@ -0,0 +1,419 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "LPE.####",
|
||||
"beta": 0,
|
||||
"creation": "2018-01-23 05:40:18.117583",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "loyalty_program",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Loyalty Program",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Loyalty Program",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "loyalty_program_tier",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Loyalty Program Tier",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "customer",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Customer",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Customer",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "sales_invoice",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Sales Invoice",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Sales Invoice",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "redeem_against",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Redeem Against",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Loyalty Point Entry",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "loyalty_points",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Loyalty Points",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "purchase_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Purchase Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "expiry_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Expiry Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "posting_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Posting Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Company",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-03-26 08:52:09.468010",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Loyalty Point Entry",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Auditor",
|
||||
"set_user_permissions": 0,
|
||||
"share": 0,
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 0,
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 0,
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "customer",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import today
|
||||
|
||||
exclude_from_linked_with = True
|
||||
|
||||
class LoyaltyPointEntry(Document):
|
||||
pass
|
||||
|
||||
|
||||
def get_loyalty_point_entries(customer, loyalty_program, expiry_date=None, company=None):
|
||||
if not expiry_date:
|
||||
date = today()
|
||||
args_list = [customer, loyalty_program, expiry_date]
|
||||
condition = ''
|
||||
if company:
|
||||
condition = " and company=%s "
|
||||
args_list.append(company)
|
||||
loyalty_point_details = frappe.db.sql('''select name, loyalty_points, expiry_date, loyalty_program_tier
|
||||
from `tabLoyalty Point Entry` where customer=%s and loyalty_program=%s and expiry_date>=%s and loyalty_points>0
|
||||
{condition} order by expiry_date'''.format(condition=condition), tuple(args_list), as_dict=1)
|
||||
return loyalty_point_details
|
@ -0,0 +1,23 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Loyalty Point Entry", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Loyalty Point Entry
|
||||
() => frappe.tests.make('Loyalty Point Entry', [
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
|
||||
class TestLoyaltyPointEntry(unittest.TestCase):
|
||||
pass
|
@ -0,0 +1,134 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2018-03-26 01:32:10.108450",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "sales_invoice",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Sales Invoice",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "redemption_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Redemption Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "redeemed_points",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Redeemed Points",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-03-26 03:12:59.173071",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Loyalty Point Entry Redemption",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class LoyaltyPointEntryRedemption(Document):
|
||||
pass
|
65
erpnext/accounts/doctype/loyalty_program/loyalty_program.js
Normal file
65
erpnext/accounts/doctype/loyalty_program/loyalty_program.js
Normal file
@ -0,0 +1,65 @@
|
||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Loyalty Program', {
|
||||
setup: function(frm) {
|
||||
var help_content =
|
||||
`<table class="table table-bordered" style="background-color: #f9f9f9;">
|
||||
<tr><td>
|
||||
<h4>
|
||||
<i class="fa fa-hand-right"></i>
|
||||
${__('Notes')}
|
||||
</h4>
|
||||
<ul>
|
||||
<li>
|
||||
${__("Loyalty Points will be calculated from the spent done (via the Sales Invoice), based on collection factor mentioned.")}
|
||||
</li>
|
||||
<li>
|
||||
${__("There can be multiple tiered collection factor based on the total spent. But the conversion factor for redemption will always be same for all the tier.")}
|
||||
</li>
|
||||
<li>
|
||||
${__("In the case of multi-tier program, Customers will be auto assigned to the concerned tier as per their spent")}
|
||||
</li>
|
||||
<li>
|
||||
${__("If unlimited expiry for the Loyalty Points, keep the Expiry Duration empty or 0.")}
|
||||
</li>
|
||||
<li>
|
||||
${__("If Auto Opt In is checked, then the customers will be automatically linked with the concerned Loyalty Program (on save)")}
|
||||
</li>
|
||||
<li>
|
||||
${__("One customer can be part of only single Loyalty Program.")}
|
||||
</li>
|
||||
</ul>
|
||||
</td></tr>
|
||||
</table>`;
|
||||
set_field_options("loyalty_program_help", help_content);
|
||||
},
|
||||
|
||||
onload: function(frm) {
|
||||
frm.set_query("expense_account", function(doc) {
|
||||
return {
|
||||
filters: {
|
||||
"root_type": "Expense",
|
||||
'is_group': 0,
|
||||
'company': doc.company
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("cost_center", function() {
|
||||
return {
|
||||
filters: {
|
||||
company: frm.doc.company
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_value("company", frappe.defaults.get_user_default("Company"));
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
if (frm.doc.loyalty_program_type === "Single Tier Program" && frm.doc.collection_rules.length > 1) {
|
||||
frappe.throw(__("Please select the Multiple Tier Program type for more than one collection rules."));
|
||||
}
|
||||
}
|
||||
});
|
687
erpnext/accounts/doctype/loyalty_program/loyalty_program.json
Normal file
687
erpnext/accounts/doctype/loyalty_program/loyalty_program.json
Normal file
@ -0,0 +1,687 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "field:loyalty_program_name",
|
||||
"beta": 0,
|
||||
"creation": "2018-01-23 06:23:05.731431",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "disabled",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Disabled",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_2",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "auto_opt_in",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Auto Opt In (For all customers)",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_2",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "loyalty_program_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Loyalty Program Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "loyalty_program_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Loyalty Program Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Single Tier Program\nMultiple Tier Program",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_7",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "customer_group",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Customer Group",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Customer Group",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "customer_territory",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Customer Territory",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Territory",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "rules",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Collection Tier",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "collection_rules",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Collection Rules",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Loyalty Program Collection",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "redemption",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Redemption",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "1 Loyalty Points = How much base currency?",
|
||||
"fieldname": "conversion_factor",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Conversion Factor",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "expiry_duration",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Expiry Duration (in days)",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_10",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "expense_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Expense Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Cost Center",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Cost Center",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Company",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "help_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Help Section",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "loyalty_program_help",
|
||||
"fieldtype": "HTML",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Loyalty Program Help",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-03-21 10:20:25.468206",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Loyalty Program",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
125
erpnext/accounts/doctype/loyalty_program/loyalty_program.py
Normal file
125
erpnext/accounts/doctype/loyalty_program/loyalty_program.py
Normal file
@ -0,0 +1,125 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import today, flt
|
||||
|
||||
class LoyaltyProgram(Document):
|
||||
pass
|
||||
|
||||
|
||||
def get_loyalty_details(customer, loyalty_program, expiry_date=None, company=None):
|
||||
if not expiry_date:
|
||||
expiry_date = today()
|
||||
args_list = [customer, loyalty_program, expiry_date]
|
||||
condition = ''
|
||||
if company:
|
||||
condition = " and company=%s "
|
||||
args_list.append(company)
|
||||
loyalty_point_details = frappe.db.sql('''select sum(loyalty_points) as loyalty_points,
|
||||
sum(purchase_amount) as total_spent from `tabLoyalty Point Entry`
|
||||
where customer=%s and loyalty_program=%s and (expiry_date>=%s) {condition}
|
||||
group by customer'''.format(condition=condition), tuple(args_list), as_dict=1)
|
||||
if loyalty_point_details:
|
||||
return loyalty_point_details[0]
|
||||
else:
|
||||
return {"loyalty_points": 0, "total_spent": 0}
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_loyalty_program_details(customer, loyalty_program=None, expiry_date=None, company=None, silent=False):
|
||||
lp_details = frappe._dict()
|
||||
customer_loyalty_program = frappe.db.get_value("Customer", customer, "loyalty_program")
|
||||
|
||||
if not (customer_loyalty_program or silent):
|
||||
frappe.throw(_("Customer isn't enrolled in any Loyalty Program"))
|
||||
elif silent and not customer_loyalty_program:
|
||||
return frappe._dict({"loyalty_program": None})
|
||||
|
||||
if loyalty_program and loyalty_program != customer_loyalty_program:
|
||||
frappe.throw(_("Customer isn't enrolled in this Loyalty Program"))
|
||||
|
||||
if not loyalty_program:
|
||||
loyalty_program = customer_loyalty_program
|
||||
if not company:
|
||||
company = frappe.db.get_default("company") or frappe.get_all("Company")[0].name
|
||||
|
||||
lp_details.update(get_loyalty_details(customer, loyalty_program, expiry_date, company))
|
||||
|
||||
lp_details.update({"loyalty_program": loyalty_program})
|
||||
loyalty_program = frappe.get_doc("Loyalty Program", lp_details.loyalty_program)
|
||||
|
||||
lp_details.expiry_duration = loyalty_program.expiry_duration
|
||||
lp_details.conversion_factor = loyalty_program.conversion_factor
|
||||
lp_details.expense_account = loyalty_program.expense_account
|
||||
lp_details.cost_center = loyalty_program.cost_center
|
||||
lp_details.company = loyalty_program.company
|
||||
|
||||
tier_spent_level = sorted([d.as_dict() for d in loyalty_program.collection_rules], key=lambda rule:rule.min_spent, reverse=True)
|
||||
for i, d in enumerate(tier_spent_level):
|
||||
if i==0 or lp_details.total_spent < d.min_spent:
|
||||
lp_details.tier_name = d.tier_name
|
||||
lp_details.collection_factor = d.collection_factor
|
||||
else:
|
||||
break
|
||||
return lp_details
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_redeemption_factor(loyalty_program=None, customer=None):
|
||||
customer_loyalty_program = None
|
||||
if not loyalty_program:
|
||||
customer_loyalty_program = frappe.db.get_value("Customer", customer, "loyalty_program")
|
||||
loyalty_program = customer_loyalty_program
|
||||
if loyalty_program:
|
||||
return frappe.db.get_value("Loyalty Program", loyalty_program, "conversion_factor")
|
||||
else:
|
||||
frappe.throw(_("Customer isn't enrolled in any Loyalty Program"))
|
||||
|
||||
|
||||
def validate_loyalty_points(ref_doc, points_to_redeem):
|
||||
loyalty_program = None
|
||||
posting_date = None
|
||||
|
||||
if ref_doc.doctype == "Sales Invoice":
|
||||
posting_date = ref_doc.posting_date
|
||||
else:
|
||||
posting_date = today()
|
||||
|
||||
if hasattr(ref_doc, "loyalty_program") and ref_doc.loyalty_program:
|
||||
loyalty_program = ref_doc.loyalty_program
|
||||
else:
|
||||
loyalty_program = frappe.db.get_value("Customer", ref_doc.customer, ["loyalty_program"])
|
||||
|
||||
if loyalty_program and frappe.db.get_value("Loyalty Program", loyalty_program, ["company"]) !=\
|
||||
ref_doc.company:
|
||||
frappe.throw(_("The Loyalty Program isn't valid for the selected company"))
|
||||
|
||||
if loyalty_program and points_to_redeem:
|
||||
loyalty_program_details = get_loyalty_program_details(ref_doc.customer, loyalty_program,
|
||||
posting_date, ref_doc.company)
|
||||
|
||||
if points_to_redeem > loyalty_program_details.loyalty_points:
|
||||
frappe.throw(_("You don't have enought Loyalty Points to redeem"))
|
||||
|
||||
loyalty_amount = flt(points_to_redeem * loyalty_program_details.conversion_factor)
|
||||
|
||||
if loyalty_amount > ref_doc.grand_total:
|
||||
frappe.throw(_("You can't redeem Loyalty Points having more value than the Grand Total."))
|
||||
|
||||
if not ref_doc.loyalty_amount and ref_doc.loyalty_amount != loyalty_amount:
|
||||
ref_doc.loyalty_amount = loyalty_amount
|
||||
|
||||
if ref_doc.doctype == "Sales Invoice":
|
||||
ref_doc.loyalty_program = loyalty_program
|
||||
if not ref_doc.loyalty_redemption_account:
|
||||
ref_doc.loyalty_redemption_account = loyalty_program_details.expense_account
|
||||
|
||||
if not ref_doc.loyalty_redemption_cost_center:
|
||||
ref_doc.loyalty_redemption_cost_center = loyalty_program_details.cost_center
|
||||
|
||||
elif ref_doc.doctype == "Sales Order":
|
||||
return loyalty_amount
|
@ -0,0 +1,23 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Loyalty Program", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Loyalty Program
|
||||
() => frappe.tests.make('Loyalty Program', [
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
|
||||
class TestLoyaltyProgram(unittest.TestCase):
|
||||
pass
|
@ -0,0 +1,161 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2018-01-23 06:56:37.163859",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 0,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "tier_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Tier Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "min_spent",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Minimum Total Spent",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "For how much spent = 1 Loyalty Point",
|
||||
"fieldname": "collection_factor",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Collection Factor (=1 LP)",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-01-23 07:19:10.316392",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Loyalty Program Collection",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class LoyaltyProgramCollection(Document):
|
||||
pass
|
@ -240,14 +240,23 @@ def make_payment_request(**args):
|
||||
"""Make payment request"""
|
||||
|
||||
args = frappe._dict(args)
|
||||
|
||||
ref_doc = frappe.get_doc(args.dt, args.dn)
|
||||
grand_total = get_amount(ref_doc, args.dt)
|
||||
if args.loyalty_points and args.dt == "Sales Order":
|
||||
from erpnext.accounts.doctype.loyalty_program.loyalty_program import validate_loyalty_points
|
||||
loyalty_amount = validate_loyalty_points(ref_doc, int(args.loyalty_points))
|
||||
frappe.db.set_value("Sales Order", args.dn, "loyalty_points", int(args.loyalty_points), update_modified=False)
|
||||
frappe.db.set_value("Sales Order", args.dn, "loyalty_amount", loyalty_amount, update_modified=False)
|
||||
grand_total = grand_total - loyalty_amount
|
||||
|
||||
gateway_account = get_gateway_details(args) or frappe._dict()
|
||||
|
||||
existing_payment_request = frappe.db.get_value("Payment Request",
|
||||
{"reference_doctype": args.dt, "reference_name": args.dn, "docstatus": ["!=", 2]})
|
||||
|
||||
if existing_payment_request:
|
||||
frappe.db.set_value("Payment Request", existing_payment_request, "grand_total", grand_total, update_modified=False)
|
||||
pr = frappe.get_doc("Payment Request", existing_payment_request)
|
||||
|
||||
else:
|
||||
|
@ -17,6 +17,8 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
onload: function() {
|
||||
var me = this;
|
||||
this._super();
|
||||
console.log("class erpnext.accounts.SalesInvoiceController, onload this->", this);
|
||||
|
||||
|
||||
if(!this.frm.doc.__islocal && !this.frm.doc.customer && this.frm.doc.debit_to) {
|
||||
// show debit_to in print format
|
||||
@ -36,6 +38,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
},
|
||||
|
||||
refresh: function(doc, dt, dn) {
|
||||
console.log("triggered the SalesInvoiceController");
|
||||
this._super();
|
||||
if(cur_frm.msgbox && cur_frm.msgbox.$wrapper.is(":visible")) {
|
||||
// hide new msgbox
|
||||
@ -228,7 +231,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
price_list: this.frm.doc.selling_price_list,
|
||||
}, function() {
|
||||
me.apply_pricing_rule();
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
make_inter_company_invoice: function() {
|
||||
@ -355,7 +358,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
});
|
||||
}
|
||||
}
|
||||
else this.frm.trigger("refresh")
|
||||
else this.frm.trigger("refresh");
|
||||
},
|
||||
|
||||
amount: function(){
|
||||
@ -364,13 +367,21 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
|
||||
change_amount: function(){
|
||||
if(this.frm.doc.paid_amount > this.frm.doc.grand_total){
|
||||
this.calculate_write_off_amount()
|
||||
this.calculate_write_off_amount();
|
||||
}else {
|
||||
this.frm.set_value("change_amount", 0.0)
|
||||
this.frm.set_value("base_change_amount", 0.0)
|
||||
this.frm.set_value("change_amount", 0.0);
|
||||
this.frm.set_value("base_change_amount", 0.0);
|
||||
}
|
||||
|
||||
this.frm.refresh_fields();
|
||||
},
|
||||
|
||||
loyalty_amount: function(){
|
||||
console.log("triggered the loyalty amount");
|
||||
this.calculate_outstanding_amount();
|
||||
this.frm.refresh_field("outstanding_amount");
|
||||
this.frm.refresh_field("paid_amount");
|
||||
this.frm.refresh_field("base_paid_amount");
|
||||
}
|
||||
});
|
||||
|
||||
@ -521,7 +532,12 @@ cur_frm.set_query("asset", "items", function(doc, cdt, cdn) {
|
||||
});
|
||||
|
||||
frappe.ui.form.on('Sales Invoice', {
|
||||
refresh: function(frm) {
|
||||
frm.add_fetch('customer', 'loyalty_program', 'loyalty_program');
|
||||
},
|
||||
|
||||
setup: function(frm){
|
||||
|
||||
frm.custom_make_buttons = {
|
||||
'Delivery Note': 'Delivery',
|
||||
'Sales Invoice': 'Sales Return',
|
||||
@ -612,7 +628,71 @@ frappe.ui.form.on('Sales Invoice', {
|
||||
refresh_field(['timesheets'])
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
onload: function(frm) {
|
||||
frm.redemption_conversion_factor = null;
|
||||
},
|
||||
|
||||
redeem_loyalty_points: function(frm) {
|
||||
frm.events.get_loyalty_details(frm);
|
||||
},
|
||||
|
||||
loyalty_points: function(frm) {
|
||||
if (frm.redemption_conversion_factor) {
|
||||
frm.events.set_loyalty_points(frm);
|
||||
} else {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.loyalty_program.loyalty_program.get_redeemption_factor",
|
||||
args: {
|
||||
"loyalty_program": frm.doc.loyalty_program
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r) {
|
||||
frm.redemption_conversion_factor = r.message;
|
||||
frm.events.set_loyalty_points(frm);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
get_loyalty_details: function(frm) {
|
||||
if (frm.doc.customer && frm.doc.redeem_loyalty_points) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.loyalty_program.loyalty_program.get_loyalty_program_details",
|
||||
args: {
|
||||
"customer": frm.doc.customer,
|
||||
"till_date": frm.doc.posting_date,
|
||||
"company": frm.doc.company
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r) {
|
||||
frm.set_value("loyalty_program", r.message.loyalty_program);
|
||||
frm.set_value("loyalty_redemption_account", r.message.expense_account);
|
||||
frm.set_value("loyalty_redemption_cost_center", r.message.cost_center);
|
||||
frm.redemption_conversion_factor = r.message.conversion_factor;
|
||||
// let max_loyalty_points = parseInt((frm.doc.grand_total-frm.doc.total_advance)/r.message.conversion_factor);
|
||||
// let redeemable_points = max_loyalty_points > r.message.loyalty_points ? r.message.loyalty_points : max_loyalty_points;
|
||||
// frm.set_value("loyalty_points", redeemable_points);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
set_loyalty_points: function(frm) {
|
||||
if (frm.redemption_conversion_factor) {
|
||||
let loyalty_amount = flt(frm.redemption_conversion_factor*flt(frm.doc.loyalty_points), precision("loyalty_amount"));
|
||||
var remaining_amount = flt(frm.doc.grand_total - frm.doc.total_advance)
|
||||
if (frm.doc.grand_total && (remaining_amount < loyalty_amount)) {
|
||||
let redeemable_amount = parseInt(remaining_amount/frm.redemption_conversion_factor);
|
||||
frappe.throw(__("You can only redeem max {0} points in this order.",[redeemable_amount]));
|
||||
}
|
||||
frm.set_value("loyalty_amount", loyalty_amount);
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
frappe.ui.form.on('Sales Invoice Timesheet', {
|
||||
|
@ -381,6 +381,38 @@
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "redeem_loyalty_points",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Redeem Loyalty Points",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
@ -2423,6 +2455,234 @@
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": "",
|
||||
"columns": 0,
|
||||
"depends_on": "redeem_loyalty_points",
|
||||
"fieldname": "loyalty_points_redemption",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Loyalty Points Redemption",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "loyalty_points",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Loyalty Points",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "loyalty_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Loyalty Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_77",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "loyalty_program",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Loyalty Program",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Loyalty Program",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "loyalty_redemption_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Redemption Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "loyalty_redemption_cost_center",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Redemption Cost Center",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Cost Center",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
@ -3426,7 +3686,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "is_pos",
|
||||
"depends_on": "eval: doc.is_pos || doc.redeem_loyalty_points",
|
||||
"fieldname": "paid_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
|
@ -4,7 +4,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe, erpnext
|
||||
import frappe.defaults
|
||||
from frappe.utils import cint, flt, add_months, today, date_diff, getdate, add_days
|
||||
from frappe.utils import cint, flt, add_months, today, date_diff, getdate, add_days, cstr
|
||||
from frappe import _, msgprint, throw
|
||||
from erpnext.accounts.party import get_party_account, get_due_date
|
||||
from erpnext.controllers.stock_controller import update_gl_entries_after
|
||||
@ -21,6 +21,8 @@ from erpnext.stock.doctype.batch.batch import set_batch_nos
|
||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos, get_delivery_note_serial_no
|
||||
from erpnext.setup.doctype.company.company import update_company_current_month_sales
|
||||
from erpnext.accounts.general_ledger import get_round_off_account_and_cost_center
|
||||
from erpnext.accounts.doctype.loyalty_program.loyalty_program import \
|
||||
get_loyalty_program_details, get_loyalty_details, validate_loyalty_points
|
||||
|
||||
from six import iteritems
|
||||
|
||||
@ -106,6 +108,9 @@ class SalesInvoice(SellingController):
|
||||
self.set_status()
|
||||
if self.is_pos and not self.is_return:
|
||||
self.verify_payment_amount_is_positive()
|
||||
if self.redeem_loyalty_points and self.loyalty_program and self.loyalty_points:
|
||||
validate_loyalty_points(self, self.loyalty_points)
|
||||
|
||||
|
||||
def before_save(self):
|
||||
set_account_for_mode_of_payment(self)
|
||||
@ -152,6 +157,15 @@ class SalesInvoice(SellingController):
|
||||
self.update_project()
|
||||
update_linked_invoice(self.doctype, self.name, self.inter_company_invoice_reference)
|
||||
|
||||
# create the loyalty point ledger entry if the customer is enrolled in any loyalty program
|
||||
if not self.is_return and self.loyalty_program:
|
||||
self.make_loyalty_point_entry()
|
||||
elif self.is_return and self.return_against and self.loyalty_program:
|
||||
against_si_doc = frappe.get_doc("Sales Invoice", self.return_against)
|
||||
against_si_doc.delete_loyalty_point_entry()
|
||||
if self.redeem_loyalty_points and self.loyalty_points:
|
||||
self.apply_loyalty_points()
|
||||
|
||||
def validate_pos_paid_amount(self):
|
||||
if len(self.payments) == 0 and self.is_pos:
|
||||
frappe.throw(_("At least one mode of payment is required for POS invoice."))
|
||||
@ -191,6 +205,11 @@ class SalesInvoice(SellingController):
|
||||
if frappe.db.get_single_value('Selling Settings', 'sales_update_frequency') == "Each Transaction":
|
||||
update_company_current_month_sales(self.company)
|
||||
self.update_project()
|
||||
if not self.is_return and self.loyalty_program:
|
||||
self.delete_loyalty_point_entry()
|
||||
elif self.is_return and self.return_against and self.loyalty_program:
|
||||
against_si_doc = frappe.get_doc("Sales Invoice", self.return_against)
|
||||
against_si_doc.make_loyalty_point_entry()
|
||||
|
||||
unlink_inter_company_invoice(self.doctype, self.name, self.inter_company_invoice_reference)
|
||||
|
||||
@ -607,7 +626,8 @@ class SalesInvoice(SellingController):
|
||||
from erpnext.accounts.general_ledger import make_gl_entries
|
||||
|
||||
# if POS and amount is written off, updating outstanding amt after posting all gl entries
|
||||
update_outstanding = "No" if (cint(self.is_pos) or self.write_off_account) else "Yes"
|
||||
update_outstanding = "No" if (cint(self.is_pos) or self.write_off_account or
|
||||
cint(self.redeem_loyalty_points)) else "Yes"
|
||||
|
||||
make_gl_entries(gl_entries, cancel=(self.docstatus == 2),
|
||||
update_outstanding=update_outstanding, merge_entries=False)
|
||||
@ -640,6 +660,7 @@ class SalesInvoice(SellingController):
|
||||
# merge gl entries before adding pos entries
|
||||
gl_entries = merge_similar_entries(gl_entries)
|
||||
|
||||
self.make_loyalty_point_redemption_gle(gl_entries)
|
||||
self.make_pos_gl_entries(gl_entries)
|
||||
self.make_gle_for_change_amount(gl_entries)
|
||||
|
||||
@ -716,6 +737,29 @@ class SalesInvoice(SellingController):
|
||||
erpnext.is_perpetual_inventory_enabled(self.company):
|
||||
gl_entries += super(SalesInvoice, self).get_gl_entries()
|
||||
|
||||
def make_loyalty_point_redemption_gle(self, gl_entries):
|
||||
if cint(self.redeem_loyalty_points):
|
||||
gl_entries.append(
|
||||
self.get_gl_dict({
|
||||
"account": self.debit_to,
|
||||
"party_type": "Customer",
|
||||
"party": self.customer,
|
||||
"against": "Expense account - " + cstr(self.loyalty_redemption_account) + " for the Loyalty Program",
|
||||
"credit": self.loyalty_amount,
|
||||
"against_voucher": self.return_against if cint(self.is_return) else self.name,
|
||||
"against_voucher_type": self.doctype
|
||||
})
|
||||
)
|
||||
gl_entries.append(
|
||||
self.get_gl_dict({
|
||||
"account": self.loyalty_redemption_account,
|
||||
"cost_center": self.loyalty_redemption_cost_center,
|
||||
"against": self.customer,
|
||||
"debit": self.loyalty_amount,
|
||||
"remark": "Loyalty Points redeemed by the customer"
|
||||
})
|
||||
)
|
||||
|
||||
def make_pos_gl_entries(self, gl_entries):
|
||||
if cint(self.is_pos):
|
||||
for payment_mode in self.payments:
|
||||
@ -920,6 +964,71 @@ class SalesInvoice(SellingController):
|
||||
if entry.amount < 0:
|
||||
frappe.throw(_("Row #{0} (Payment Table): Amount must be positive").format(entry.idx))
|
||||
|
||||
# collection of the loyalty points, create the ledger entry for that.
|
||||
def make_loyalty_point_entry(self):
|
||||
loyalty_program_details = get_loyalty_program_details(self.customer, company=self.company)
|
||||
if loyalty_program_details:
|
||||
points_earned = int(self.grand_total/loyalty_program_details.collection_factor)
|
||||
doc = frappe.get_doc({
|
||||
"doctype": "Loyalty Point Entry",
|
||||
"company": self.company,
|
||||
"loyalty_program": loyalty_program_details.loyalty_program,
|
||||
"loyalty_program_tier": loyalty_program_details.tier_name,
|
||||
"customer": self.customer,
|
||||
"sales_invoice": self.name,
|
||||
"loyalty_points": points_earned,
|
||||
"purchase_amount": self.grand_total,
|
||||
"expiry_date": add_days(self.posting_date, loyalty_program_details.expiry_duration),
|
||||
"posting_date": self.posting_date
|
||||
})
|
||||
doc.flags.ignore_permissions = 1
|
||||
doc.save()
|
||||
# frappe.db.set_value("Customer", self.customer, "loyalty_program_tier", loyalty_program_details.tier_name)
|
||||
|
||||
# valdite the redemption and then delete the loyalty points earned on cancel of the invoice
|
||||
def delete_loyalty_point_entry(self):
|
||||
lp_entry = frappe.db.sql("select name from `tabLoyalty Point Entry` where sales_invoice=%s",
|
||||
(self.name), as_dict=1)[0]
|
||||
against_lp_entry = frappe.db.sql('''select name, sales_invoice from `tabLoyalty Point Entry`
|
||||
where redeem_against=%s''', (lp_entry.name), as_dict=1)
|
||||
if against_lp_entry:
|
||||
invoice_list = ", ".join([d.sales_invoice for d in against_lp_entry])
|
||||
frappe.throw(_('''Sales Invoice can't be cancelled since the Loyalty Points earned has been redeemed.
|
||||
First cancel the Sales Invoice No {0}''').format(invoice_list))
|
||||
else:
|
||||
frappe.db.sql('''delete from `tabLoyalty Point Entry` where sales_invoice=%s''', (self.name))
|
||||
|
||||
# redeem the loyalty points.
|
||||
def apply_loyalty_points(self):
|
||||
from erpnext.accounts.doctype.loyalty_point_entry.loyalty_point_entry \
|
||||
import get_loyalty_point_entries
|
||||
loyalty_point_entries = get_loyalty_point_entries(self.customer, self.loyalty_program, self.posting_date, self.company)
|
||||
|
||||
points_to_redeem = self.loyalty_amount
|
||||
for lp_entry in loyalty_point_entries:
|
||||
if lp_entry.loyalty_points > points_to_redeem:
|
||||
redeemed_points = points_to_redeem
|
||||
else:
|
||||
redeemed_points = lp_entry.loyalty_points
|
||||
doc = frappe.get_doc({
|
||||
"doctype": "Loyalty Point Entry",
|
||||
"company": self.company,
|
||||
"loyalty_program": self.loyalty_program,
|
||||
"loyalty_program_tier": lp_entry.loyalty_program_tier,
|
||||
"customer": self.customer,
|
||||
"sales_invoice": self.name,
|
||||
"redeem_against": lp_entry.name,
|
||||
"loyalty_points": -(redeemed_points),
|
||||
"purchase_amount": self.grand_total,
|
||||
"expiry_date": lp_entry.expiry_date,
|
||||
"posting_date": self.posting_date
|
||||
})
|
||||
doc.flags.ignore_permissions = 1
|
||||
doc.save()
|
||||
points_to_redeem -= redeemed_points
|
||||
if points_to_redeem < 1: # since points_to_redeem is integer
|
||||
break
|
||||
|
||||
def book_income_for_deferred_revenue(self):
|
||||
# book the income on the last day, but it will be trigger on the 1st of month at 12:00 AM
|
||||
# start_date: 1st of the last month or the start date
|
||||
|
@ -481,11 +481,11 @@ class calculate_taxes_and_totals(object):
|
||||
paid_amount = self.doc.paid_amount \
|
||||
if self.doc.party_account_currency == self.doc.currency else self.doc.base_paid_amount
|
||||
|
||||
|
||||
self.doc.outstanding_amount = flt(total_amount_to_pay - flt(paid_amount) + flt(change_amount),
|
||||
self.doc.precision("outstanding_amount"))
|
||||
|
||||
def calculate_paid_amount(self):
|
||||
|
||||
paid_amount = base_paid_amount = 0.0
|
||||
|
||||
if self.doc.is_pos:
|
||||
@ -497,6 +497,10 @@ class calculate_taxes_and_totals(object):
|
||||
elif not self.doc.is_return:
|
||||
self.doc.set('payments', [])
|
||||
|
||||
if self.doc.redeem_loyalty_points and self.doc.loyalty_amount:
|
||||
base_paid_amount += self.doc.loyalty_amount
|
||||
paid_amount += (self.doc.loyalty_amount / flt(self.doc.conversion_rate))
|
||||
|
||||
self.doc.paid_amount = flt(paid_amount, self.doc.precision("paid_amount"))
|
||||
self.doc.base_paid_amount = flt(base_paid_amount, self.doc.precision("base_paid_amount"))
|
||||
|
||||
|
@ -568,9 +568,8 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
|
||||
|
||||
calculate_outstanding_amount: function(update_paid_amount) {
|
||||
// NOTE:
|
||||
// paid_amount and write_off_amount is only for POS Invoice
|
||||
// paid_amount and write_off_amount is only for POS/Loyalty Point Redemption Invoice
|
||||
// total_advance is only for non POS Invoice
|
||||
|
||||
if(this.frm.doc.doctype == "Sales Invoice" && this.frm.doc.is_return){
|
||||
this.calculate_paid_amount();
|
||||
}
|
||||
@ -602,16 +601,19 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
|
||||
}
|
||||
|
||||
if(this.frm.doc.doctype == "Sales Invoice") {
|
||||
this.set_default_payment(total_amount_to_pay, update_paid_amount);
|
||||
let total_amount_for_payment = (this.frm.doc.redeem_loyalty_points && this.frm.doc.loyalty_amount)
|
||||
? flt(total_amount_to_pay - this.frm.doc.loyalty_amount, precision("base_grand_total"))
|
||||
: total_amount_to_pay;
|
||||
this.set_default_payment(total_amount_for_payment, update_paid_amount);
|
||||
this.calculate_paid_amount();
|
||||
}
|
||||
this.calculate_change_amount();
|
||||
|
||||
var paid_amount = (this.frm.doc.party_account_currency == this.frm.doc.currency) ?
|
||||
this.frm.doc.paid_amount : this.frm.doc.base_paid_amount;
|
||||
|
||||
this.frm.doc.outstanding_amount = flt(total_amount_to_pay - flt(paid_amount) +
|
||||
flt(this.frm.doc.change_amount * this.frm.doc.conversion_rate), precision("outstanding_amount"));
|
||||
console.log("set the outstanding amount");
|
||||
}
|
||||
},
|
||||
|
||||
@ -644,9 +646,14 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
|
||||
} else if(!this.frm.doc.is_return){
|
||||
this.frm.doc.payments = [];
|
||||
}
|
||||
if (this.frm.doc.redeem_loyalty_points && this.frm.doc.loyalty_amount) {
|
||||
base_paid_amount += this.frm.doc.loyalty_amount;
|
||||
paid_amount += flt(this.frm.doc.loyalty_amount / me.frm.doc.conversion_rate, precision("paid_amount"));
|
||||
}
|
||||
|
||||
this.frm.doc.paid_amount = flt(paid_amount, precision("paid_amount"));
|
||||
this.frm.doc.base_paid_amount = flt(base_paid_amount, precision("base_paid_amount"));
|
||||
console.log("paid amount set as -> ", paid_amount, base_paid_amount);
|
||||
},
|
||||
|
||||
calculate_change_amount: function(){
|
||||
|
@ -103,6 +103,11 @@ frappe.ui.form.on("Customer", {
|
||||
// indicator
|
||||
erpnext.utils.set_party_dashboard_indicators(frm);
|
||||
|
||||
//
|
||||
if (frm.doc.__onload.dashboard_info.loyalty_point) {
|
||||
frm.dashboard.add_indicator(__('Loyalty Point: {0}', [frm.doc.__onload.dashboard_info.loyalty_point]), 'blue');
|
||||
}
|
||||
|
||||
} else {
|
||||
frappe.contacts.clear_address_and_contact(frm);
|
||||
}
|
||||
|
@ -1470,6 +1470,97 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_38",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Loyalty Points",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "loyalty_program",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Loyalty Program",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Loyalty Program",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "loyalty_program_tier",
|
||||
"fieldtype": "Read Only",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Loyalty Program Tier",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"collapsible_depends_on": "default_sales_partner",
|
||||
"columns": 0,
|
||||
"fieldname": "sales_team_section_break",
|
||||
@ -1677,7 +1768,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-06-26 13:12:30.677834",
|
||||
"modified": "2018-06-27 12:12:30.677834",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Customer",
|
||||
|
@ -24,6 +24,9 @@ class Customer(TransactionBase):
|
||||
|
||||
def load_dashboard_info(self):
|
||||
info = get_dashboard_info(self.doctype, self.name)
|
||||
loyalty_point_details = self.get_loyalty_points()
|
||||
if loyalty_point_details and loyalty_point_details.get("loyalty_points"):
|
||||
info["loyalty_point"] = loyalty_point_details.loyalty_points
|
||||
self.set_onload('dashboard_info', info)
|
||||
|
||||
def autoname(self):
|
||||
@ -33,6 +36,11 @@ class Customer(TransactionBase):
|
||||
else:
|
||||
set_name_by_naming_series(self)
|
||||
|
||||
def get_loyalty_points(self):
|
||||
if self.loyalty_program:
|
||||
from erpnext.accounts.doctype.loyalty_program.loyalty_program import get_loyalty_details
|
||||
return get_loyalty_details(self.name, self.loyalty_program)
|
||||
|
||||
def get_customer_name(self):
|
||||
if frappe.db.get_value("Customer", self.customer_name):
|
||||
count = frappe.db.sql("""select ifnull(MAX(CAST(SUBSTRING_INDEX(name, ' ', -1) AS UNSIGNED)), 0) from tabCustomer
|
||||
@ -51,6 +59,7 @@ class Customer(TransactionBase):
|
||||
self.flags.old_lead = self.lead_name
|
||||
validate_party_accounts(self)
|
||||
self.validate_credit_limit_on_change()
|
||||
self.set_loyalty_program()
|
||||
self.check_customer_group_change()
|
||||
|
||||
def check_customer_group_change(self):
|
||||
@ -178,6 +187,17 @@ class Customer(TransactionBase):
|
||||
if frappe.defaults.get_global_default('cust_master_name') == 'Customer Name':
|
||||
frappe.db.set(self, "customer_name", newdn)
|
||||
|
||||
def set_loyalty_program(self):
|
||||
if not self.loyalty_program:
|
||||
loyalty_programs = frappe.get_all("Loyalty Program", fields=["name", "customer_group",
|
||||
"customer_territory"], filters={"auto_opt_in": 1, "disabled": 0})
|
||||
from frappe.desk.treeview import get_children
|
||||
for loyalty_program in loyalty_programs:
|
||||
customer_groups = get_children("Customer Group", loyalty_program.customer_group, )
|
||||
if self.customer_group in customer_groups and\
|
||||
self.territory in get_children("Territory", loyalty_program.customer_territory):
|
||||
self.loyalty_program = loyalty_program.name
|
||||
|
||||
|
||||
def get_customer_list(doctype, txt, searchfield, start, page_len, filters=None):
|
||||
if frappe.db.get_default("cust_master_name") == "Customer Name":
|
||||
|
@ -1910,6 +1910,99 @@
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "loyalty_points_redemption",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Loyalty Points Redemption",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "loyalty_points",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Loyalty Points",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "loyalty_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Loyalty Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
|
@ -558,6 +558,10 @@ def make_sales_invoice(source_name, target_doc=None, ignore_permissions=False):
|
||||
if target.company_address:
|
||||
target.update(get_fetch_values("Sales Invoice", 'company_address', target.company_address))
|
||||
|
||||
# set the redeem loyalty points if provided via shopping cart
|
||||
if source.loyalty_points and source.order_type == "Shopping Cart":
|
||||
target.redeem_loyalty_points = 1
|
||||
|
||||
def update_item(source, target, source_parent):
|
||||
target.amount = flt(source.amount) - flt(source.billed_amt)
|
||||
target.base_amount = target.amount * flt(source_parent.conversion_rate)
|
||||
|
@ -95,7 +95,9 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
frm: this.frm,
|
||||
wrapper: this.wrapper.find('.cart-container'),
|
||||
events: {
|
||||
on_customer_change: (customer) => this.frm.set_value('customer', customer),
|
||||
on_customer_change: (customer) => {
|
||||
this.frm.set_value('customer', customer);
|
||||
},
|
||||
on_field_change: (item_code, field, value, batch_no) => {
|
||||
this.update_item_in_cart(item_code, field, value, batch_no);
|
||||
},
|
||||
@ -119,6 +121,46 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
},
|
||||
get_item_details: (item_code) => {
|
||||
return this.items.get(item_code);
|
||||
},
|
||||
get_loyalty_details: () => {
|
||||
var me = this;
|
||||
if (this.frm.doc.customer) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.loyalty_program.loyalty_program.get_loyalty_program_details",
|
||||
args: {
|
||||
"customer": me.frm.doc.customer,
|
||||
"till_date": me.frm.doc.posting_date,
|
||||
"company": me.frm.doc.company,
|
||||
"silent": true
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r.message.loyalty_program && r.message.loyalty_points) {
|
||||
me.cart.events.set_loyalty_details(r.message, true);
|
||||
}
|
||||
if (!r.message.loyalty_program) {
|
||||
var loyalty_details = {
|
||||
loyalty_points: 0,
|
||||
loyalty_program: '',
|
||||
expense_account: '',
|
||||
cost_center: ''
|
||||
}
|
||||
me.cart.events.set_loyalty_details(loyalty_details, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
set_loyalty_details: (details, view_status) => {
|
||||
if (view_status) {
|
||||
this.cart.available_loyalty_points.$wrapper.removeClass("hide");
|
||||
} else {
|
||||
this.cart.available_loyalty_points.$wrapper.addClass("hide");
|
||||
}
|
||||
this.cart.available_loyalty_points.set_value(details.loyalty_points);
|
||||
this.cart.available_loyalty_points.refresh_input();
|
||||
this.frm.set_value("loyalty_program", details.loyalty_program);
|
||||
this.frm.set_value("loyalty_redemption_account", details.expense_account);
|
||||
this.frm.set_value("loyalty_redemption_cost_center", details.cost_center);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -563,6 +605,7 @@ class POSCart {
|
||||
make() {
|
||||
this.make_dom();
|
||||
this.make_customer_field();
|
||||
this.make_loyalty_points();
|
||||
this.make_numpad();
|
||||
}
|
||||
|
||||
@ -598,16 +641,27 @@ class POSCart {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="number-pad-container">
|
||||
<div class="row">
|
||||
<div class="number-pad-container col-sm-6"></div>
|
||||
<div class="col-sm-6 loyalty-program-section">
|
||||
<div class="loyalty-program-field"> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
|
||||
|
||||
this.$cart_items = this.wrapper.find('.cart-items');
|
||||
this.$empty_state = this.wrapper.find('.cart-items .empty-state');
|
||||
this.$taxes_and_totals = this.wrapper.find('.taxes-and-totals');
|
||||
this.$discount_amount = this.wrapper.find('.discount-amount');
|
||||
this.$grand_total = this.wrapper.find('.grand-total');
|
||||
this.$qty_total = this.wrapper.find('.quantity-total');
|
||||
// this.$loyalty_button = this.wrapper.find('.loyalty-button');
|
||||
|
||||
// this.$loyalty_button.on('click', () => {
|
||||
// this.loyalty_button.show();
|
||||
// })
|
||||
|
||||
this.toggle_taxes_and_totals(false);
|
||||
this.$grand_total.on('click', () => {
|
||||
@ -765,6 +819,7 @@ class POSCart {
|
||||
},
|
||||
onchange: () => {
|
||||
this.events.on_customer_change(this.customer_field.get_value());
|
||||
this.events.get_loyalty_details();
|
||||
}
|
||||
},
|
||||
parent: this.wrapper.find('.customer-field'),
|
||||
@ -774,6 +829,21 @@ class POSCart {
|
||||
this.customer_field.set_value(this.frm.doc.customer);
|
||||
}
|
||||
|
||||
|
||||
make_loyalty_points() {
|
||||
this.available_loyalty_points = frappe.ui.form.make_control({
|
||||
df: {
|
||||
fieldtype: 'Int',
|
||||
label: 'Available Loyalty Points',
|
||||
read_only: 1,
|
||||
fieldname: 'available_loyalty_points'
|
||||
},
|
||||
parent: this.wrapper.find('.loyalty-program-field')
|
||||
});
|
||||
this.available_loyalty_points.set_value(this.frm.doc.loyalty_points);
|
||||
}
|
||||
|
||||
|
||||
disable_numpad_control() {
|
||||
let disabled_btns = [];
|
||||
if(!this.frm.allow_edit_rate) {
|
||||
@ -1458,7 +1528,8 @@ class Payment {
|
||||
this.set_flag();
|
||||
this.dialog = new frappe.ui.Dialog({
|
||||
fields: this.get_fields(),
|
||||
width: 800
|
||||
width: 800,
|
||||
invoice_frm: this.frm
|
||||
});
|
||||
|
||||
this.set_title();
|
||||
@ -1541,6 +1612,44 @@ class Payment {
|
||||
fieldtype: 'HTML',
|
||||
fieldname: 'numpad'
|
||||
},
|
||||
{
|
||||
fieldtype: 'Section Break',
|
||||
depends_on: 'eval: this.invoice_frm.doc.loyalty_program'
|
||||
},
|
||||
{
|
||||
fieldtype: 'Check',
|
||||
label: 'Redeem Loyalty Points',
|
||||
fieldname: 'redeem_loyalty_points',
|
||||
onchange: () => {
|
||||
me.update_cur_frm_value("redeem_loyalty_points", () => {
|
||||
frappe.flags.redeem_loyalty_points = false;
|
||||
me.update_loyalty_points();
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
fieldtype: 'Column Break',
|
||||
},
|
||||
{
|
||||
fieldtype: 'Int',
|
||||
fieldname: "loyalty_points",
|
||||
label: __("Loyalty Points"),
|
||||
depends_on: "redeem_loyalty_points",
|
||||
onchange: () => {
|
||||
me.update_cur_frm_value("loyalty_points", () => {
|
||||
frappe.flags.loyalty_points = false;
|
||||
me.update_loyalty_points();
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
fieldtype: 'Currency',
|
||||
label: __("Loyalty Amount"),
|
||||
fieldname: "loyalty_amount",
|
||||
options: me.frm.doc.currency,
|
||||
read_only: 1,
|
||||
depends_on: "redeem_loyalty_points"
|
||||
},
|
||||
{
|
||||
fieldtype: 'Section Break',
|
||||
},
|
||||
@ -1603,6 +1712,9 @@ class Payment {
|
||||
set_flag() {
|
||||
frappe.flags.write_off_amount = true;
|
||||
frappe.flags.change_amount = true;
|
||||
frappe.flags.loyalty_points = true;
|
||||
frappe.flags.redeem_loyalty_points = true;
|
||||
frappe.flags.payment_method = true;
|
||||
}
|
||||
|
||||
update_cur_frm_value(fieldname, callback) {
|
||||
@ -1643,4 +1755,22 @@ class Payment {
|
||||
this.dialog.set_value("paid_amount", this.frm.doc.paid_amount);
|
||||
this.dialog.set_value("outstanding_amount", this.frm.doc.outstanding_amount);
|
||||
}
|
||||
|
||||
update_payment_amount() {
|
||||
var me = this;
|
||||
$.each(this.frm.doc.payments, function(i, data) {
|
||||
console.log("setting the ", data.mode_of_payment, " for the value", data.amount);
|
||||
me.dialog.set_value(data.mode_of_payment, data.amount);
|
||||
});
|
||||
}
|
||||
|
||||
update_loyalty_points() {
|
||||
if (this.dialog.get_value("redeem_loyalty_points")) {
|
||||
this.dialog.set_value("loyalty_points", this.frm.doc.loyalty_points);
|
||||
this.dialog.set_value("loyalty_amount", this.frm.doc.loyalty_amount);
|
||||
this.update_payment_amount();
|
||||
this.show_paid_amount();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -570,6 +570,7 @@ class TestDeliveryNote(unittest.TestCase):
|
||||
self.assertEqual(dn.name, dt.delivery_stops[0].delivery_note)
|
||||
|
||||
def create_delivery_note(**args):
|
||||
print (frappe.session.user)
|
||||
dn = frappe.new_doc("Delivery Note")
|
||||
args = frappe._dict(args)
|
||||
dn.posting_date = args.posting_date or nowdate()
|
||||
|
@ -94,22 +94,52 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cart-taxes row small">
|
||||
<div class="col-sm-6"><!-- empty --></div>
|
||||
<div class="col-sm-6">
|
||||
{% if enabled_checkout %}
|
||||
{% if (doc.doctype=="Sales Order" and doc.per_billed <= 0)
|
||||
or (doc.doctype=="Sales Invoice" and doc.outstanding_amount > 0) %}
|
||||
{% if enabled_checkout and ((doc.doctype=="Sales Order" and doc.per_billed <= 0)
|
||||
or (doc.doctype=="Sales Invoice" and doc.outstanding_amount > 0)) %}
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<div class="row">
|
||||
<div class="form-column col-sm-6 address-title">
|
||||
<strong>Payment</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-collapse">
|
||||
<div class="panel-body text-muted small">
|
||||
<div class="row">
|
||||
<div class="form-column col-sm-6">
|
||||
{% if available_loyalty_points %}
|
||||
<div class="form-group">
|
||||
<div class="h6">Enter Loyalty Points</div>
|
||||
<div class="control-input-wrapper">
|
||||
<div class="control-input">
|
||||
<input class="form-control" type="number" min="0" max="{{ available_loyalty_points }}" id="loyalty-point-to-redeem">
|
||||
</div>
|
||||
<p class="help-box small text-muted hidden-xs"> Available Points: {{ available_loyalty_points }} </p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="form-column col-sm-6">
|
||||
<div id="loyalty-points-status" style="text-align: right"></div>
|
||||
<div class="page-header-actions-block" data-html-block="header-actions">
|
||||
<p>
|
||||
<a href="/api/method/erpnext.accounts.doctype.payment_request.payment_request.make_payment_request?dn={{ doc.name }}&dt={{ doc.doctype }}&submit_doc=1&order_type=Shopping Cart"
|
||||
class="btn btn-primary btn-sm">{{ _("Pay") }} {{ doc.get_formatted("grand_total") }} </a>
|
||||
class="btn btn-primary btn-sm" id="pay-for-order">{{ _("Pay") }} {{ doc.get_formatted("grand_total") }} </a>
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if attachments %}
|
||||
<div class="order-item-table">
|
||||
<div class="row order-items order-item-header text-muted">
|
||||
@ -135,3 +165,16 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block script %}
|
||||
<script> {% include "templates/pages/order.js" %} </script>
|
||||
<script>
|
||||
window.doc_info = {
|
||||
customer: '{{doc.customer}}',
|
||||
doctype: '{{ doc.doctype }}',
|
||||
doctype_name: '{{ doc.name }}',
|
||||
grand_total: '{{ doc.grand_total }}',
|
||||
currency: '{{ doc.currency }}'
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
40
erpnext/templates/pages/order.js
Normal file
40
erpnext/templates/pages/order.js
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ready(function(){
|
||||
|
||||
var loyalty_points_input = document.getElementById("loyalty-point-to-redeem");
|
||||
var loyalty_points_status = document.getElementById("loyalty-points-status");
|
||||
loyalty_points_input.onblur = apply_loyalty_points;
|
||||
|
||||
function apply_loyalty_points() {
|
||||
var loyalty_points = parseInt(loyalty_points_input.value);
|
||||
if (loyalty_points) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.loyalty_program.loyalty_program.get_redeemption_factor",
|
||||
args: {
|
||||
"customer": doc_info.customer
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r) {
|
||||
var message = ""
|
||||
let loyalty_amount = flt(r.message*loyalty_points);
|
||||
if (doc_info.grand_total && doc_info.grand_total < loyalty_amount) {
|
||||
let redeemable_amount = parseInt(doc_info.grand_total/r.message);
|
||||
message = "You can only redeem max " + redeemable_amount + " points in this order.";
|
||||
frappe.msgprint(__(message));
|
||||
} else {
|
||||
message = loyalty_points + " Loyalty Points of amount "+ loyalty_amount + " is applied."
|
||||
frappe.msgprint(__(message));
|
||||
var remaining_amount = flt(doc_info.grand_total) - flt(loyalty_amount);
|
||||
var payment_button = document.getElementById("pay-for-order");
|
||||
payment_button.innerHTML = __("Pay Remaining");
|
||||
payment_button.href = "/api/method/erpnext.accounts.doctype.payment_request.payment_request.make_payment_request?dn="+doc_info.doctype_name+"&dt="+doc_info.doctype+"&loyalty_points="+loyalty_points+"&submit_doc=1&order_type=Shopping Cart";
|
||||
}
|
||||
loyalty_points_status.innerHTML = message;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
@ -33,6 +33,13 @@ def get_context(context):
|
||||
if not frappe.has_website_permission(context.doc):
|
||||
frappe.throw(_("Not Permitted"), frappe.PermissionError)
|
||||
|
||||
# check for the loyalty program of the customer
|
||||
customer_loyalty_program = frappe.db.get_value("Customer", context.doc.customer, "loyalty_program")
|
||||
if customer_loyalty_program:
|
||||
from erpnext.accounts.doctype.loyalty_program.loyalty_program import get_loyalty_program_details
|
||||
loyalty_program_details = get_loyalty_program_details(context.doc.customer, customer_loyalty_program)
|
||||
context.available_loyalty_points = int(loyalty_program_details.get("loyalty_points"))
|
||||
|
||||
def get_attachments(dt, dn):
|
||||
return frappe.get_all("File",
|
||||
fields=["name", "file_name", "file_url", "is_private"],
|
||||
|
Loading…
x
Reference in New Issue
Block a user