mirror of
https://github.com/frappe/erpnext.git
synced 2026-09-17 18:45:20 +00:00
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:
committed by
Nabin Hait
parent
5d134e0465
commit
da486eeebd
@@ -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) {
|
||||
@@ -1619,15 +1731,15 @@ class Payment {
|
||||
|
||||
update_payment_value(fieldname, value) {
|
||||
var me = this;
|
||||
$.each(this.frm.doc.payments, function(i, data) {
|
||||
if (__(data.mode_of_payment) == __(fieldname)) {
|
||||
frappe.model.set_value('Sales Invoice Payment', data.name, 'amount', value)
|
||||
.then(() => {
|
||||
me.update_change_amount();
|
||||
me.update_write_off_amount();
|
||||
});
|
||||
}
|
||||
});
|
||||
$.each(this.frm.doc.payments, function(i, data) {
|
||||
if (__(data.mode_of_payment) == __(fieldname)) {
|
||||
frappe.model.set_value('Sales Invoice Payment', data.name, 'amount', value)
|
||||
.then(() => {
|
||||
me.update_change_amount();
|
||||
me.update_write_off_amount();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
update_change_amount() {
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user