parent
b888359b45
commit
c4dce99f4b
7
attributions.md
Normal file
7
attributions.md
Normal file
@ -0,0 +1,7 @@
|
||||
## ERPNext includes these public works
|
||||
|
||||
For Frappe Framework, please see attributions.md at https://github.com/frappe/frappe/
|
||||
|
||||
#### Images
|
||||
|
||||
POS Icon: https://thenounproject.com/icon/41958 by hunotika
|
@ -41,7 +41,3 @@ def get_items(price_list, sales_or_purchase, item=None):
|
||||
item_det.item_code=i.name
|
||||
where
|
||||
%s""" % ('%(price_list)s', condition), args, as_dict=1)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_mode_of_payment():
|
||||
return sorted([d.name for d in frappe.get_list("Mode of Payment")])
|
||||
|
@ -9,6 +9,7 @@ cur_frm.pformat.print_heading = 'Invoice';
|
||||
frappe.provide("erpnext.accounts");
|
||||
erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.extend({
|
||||
onload: function() {
|
||||
var me = this;
|
||||
this._super();
|
||||
|
||||
if(!this.frm.doc.__islocal && !this.frm.doc.customer && this.frm.doc.debit_to) {
|
||||
@ -22,7 +23,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
this.frm.set_value("is_pos", 1);
|
||||
this.is_pos(function() {
|
||||
if (cint(frappe.defaults.get_user_defaults("fs_pos_view"))===1)
|
||||
cur_frm.cscript.toggle_pos(true);
|
||||
erpnext.pos.toggle(me.frm);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -103,16 +103,6 @@
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "is_pos",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is POS",
|
||||
"oldfieldname": "is_pos",
|
||||
"oldfieldtype": "Check",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
@ -168,6 +158,16 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "is_pos",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is POS",
|
||||
"oldfieldname": "is_pos",
|
||||
"oldfieldtype": "Check",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "shipping_address_name",
|
||||
"fieldtype": "Link",
|
||||
@ -1244,7 +1244,7 @@
|
||||
"icon": "icon-file-text",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2015-03-04 16:08:58.641155",
|
||||
"modified": "2015-03-05 01:42:46.778216",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice",
|
||||
|
@ -1,18 +1,11 @@
|
||||
frappe.pages['pos'].on_page_load = function(wrapper) {
|
||||
var page = frappe.ui.make_app_page({
|
||||
parent: wrapper,
|
||||
title: __('Start POS'),
|
||||
title: __('Start Point-of-Sale (POS)'),
|
||||
single_column: true
|
||||
});
|
||||
|
||||
page.main.html('<div class="text-center" style="padding: 40px">\
|
||||
<p>' + __("Select type of transaction") + '</p>\
|
||||
<p class="select-type" style="margin: auto; max-width: 300px; margin-bottom: 15px;"></p>\
|
||||
<p class="pos-setting-message hide">'
|
||||
+ '<br><a class="btn btn-default btn-sm" onclick="newdoc(\'POS Setting\')">'
|
||||
+ __("Make new POS Setting") + '</a><br><br></p>\
|
||||
<p><button class="btn btn-primary btn-sm">' + __("Start") + '</button></p>\
|
||||
</div>');
|
||||
page.main.html(frappe.render_template("pos_page", {}));
|
||||
|
||||
var pos_type = frappe.ui.form.make_control({
|
||||
parent: page.main.find(".select-type"),
|
||||
@ -34,6 +27,8 @@ frappe.pages['pos'].on_page_load = function(wrapper) {
|
||||
|
||||
pos_type.refresh();
|
||||
|
||||
pos_type.set_input("Sales Invoice");
|
||||
|
||||
page.main.find(".btn-primary").on("click", function() {
|
||||
erpnext.open_as_pos = true;
|
||||
new_doc(pos_type.get_value());
|
||||
|
15
erpnext/accounts/page/pos/pos_page.html
Normal file
15
erpnext/accounts/page/pos/pos_page.html
Normal file
@ -0,0 +1,15 @@
|
||||
<div class="text-center" style="padding: 40px;">
|
||||
<img src="/assets/erpnext/images/pos.svg"
|
||||
style="width: 100px; height: 100px; margin-bottom: 30px; opacity: 0.2" class="text-muted">
|
||||
<p>{%= __("Select type of transaction") %}</p>
|
||||
<p class="select-type" style="margin: auto; max-width: 300px; margin-bottom: 30px;">
|
||||
|
||||
</p>
|
||||
<p style="margin-bottom: 30px;">
|
||||
<button class="btn btn-primary btn-lg">{%= __("Start") %}</button>
|
||||
</p>
|
||||
<p class="pos-setting-message hide">
|
||||
<a class="btn btn-default btn-sm" href="#Form/POS Setting/New POS Setting">
|
||||
{%= __("Make new POS Setting") %}</a>
|
||||
</p>
|
||||
</div>
|
4
erpnext/public/images/pos.svg
Normal file
4
erpnext/public/images/pos.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" width="100px" height="100px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve">
|
||||
<rect fill="none" width="100" height="100"/>
|
||||
<path d="M73.617,42.921H53.671c-0.788,0-1.423,0.636-1.423,1.423v7.238c0,0.788,0.635,1.424,1.423,1.424h19.946 c0.788,0,1.429-0.636,1.429-1.424v-7.238C75.046,43.557,74.405,42.921,73.617,42.921z M72.194,50.16H55.099v-4.392h17.096V50.16z M58.494,57.78c0,0.788-0.635,1.423-1.423,1.423h-3.4c-0.788,0-1.423-0.635-1.423-1.423s0.635-1.429,1.423-1.429h3.4 C57.859,56.352,58.494,56.992,58.494,57.78z M66.771,57.78c0,0.788-0.636,1.423-1.424,1.423h-3.4c-0.788,0-1.429-0.635-1.429-1.423 s0.641-1.429,1.429-1.429h3.4C66.135,56.352,66.771,56.992,66.771,57.78z M75.046,57.78c0,0.788-0.641,1.423-1.429,1.423h-3.396 c-0.788,0-1.423-0.635-1.423-1.423s0.635-1.429,1.423-1.429h3.396C74.405,56.352,75.046,56.992,75.046,57.78z M58.494,64.058 c0,0.788-0.635,1.429-1.423,1.429h-3.4c-0.788,0-1.423-0.641-1.423-1.429s0.635-1.423,1.423-1.423h3.4 C57.859,62.635,58.494,63.27,58.494,64.058z M66.771,64.058c0,0.788-0.636,1.429-1.424,1.429h-3.4c-0.788,0-1.429-0.641-1.429-1.429 s0.641-1.423,1.429-1.423h3.4C66.135,62.635,66.771,63.27,66.771,64.058z M75.046,64.058c0,0.788-0.641,1.429-1.429,1.429h-3.396 c-0.788,0-1.423-0.641-1.423-1.429s0.635-1.423,1.423-1.423h3.396C74.405,62.635,75.046,63.27,75.046,64.058z M87.271,72.227 c-0.239-13.364-2.135-26.347-5.562-37.713c-0.366-1.2-1.474-2.028-2.729-2.028H66.496V22.334h11.636c1.57,0,2.847-1.276,2.847-2.852 V7.847C80.979,6.276,79.702,5,78.132,5H49.163c-1.576,0-2.852,1.276-2.852,2.847v11.636c0,1.576,1.276,2.852,2.852,2.852h11.634 v10.151H44.255c0.902-1.006,1.896-1.789,2.977-2.257c0.623-0.264,0.971-0.93,0.833-1.591c-0.137-0.666-0.722-1.139-1.398-1.139 H33.028c-0.193,0-0.386,0.041-0.564,0.117c-2.104,0.91-3.896,2.587-5.315,4.87h-6.133c-1.253,0-2.364,0.829-2.725,2.028 c-3.431,11.366-5.327,24.349-5.566,37.713c-1.515,0.066-2.732,1.297-2.732,2.826v17.096c0,1.575,1.276,2.852,2.849,2.852h74.312 c1.576,0,2.852-1.276,2.852-2.852V75.053C90.006,73.523,88.791,72.293,87.271,72.227z M52.012,10.698h23.268v5.938H52.012V10.698z M33.338,30.351h8.998c-2.229,2.389-3.922,5.901-4.85,10.182c-1.281,5.922-0.854,11.94,0.976,15.819H29 c-2.336-3.151-3.134-10.07-1.807-16.201C28.248,35.276,30.482,31.723,33.338,30.351z M23.157,38.189h1.604 c-0.122,0.447-0.251,0.884-0.353,1.357c-1.332,6.161-0.732,12.663,1.332,16.805h-1.271c-0.788,0-1.426,0.641-1.426,1.429 s0.638,1.423,1.426,1.423h3.858H41.06h3.116c0.788,0,1.423-0.635,1.423-1.423s-0.636-1.429-1.423-1.429h-2.389 c-2.14-2.897-2.809-9.241-1.515-15.214c0.227-1.052,0.516-2.018,0.834-2.948H76.84c2.903,10.339,4.529,22.005,4.753,34.012H18.404 C18.627,60.194,20.257,48.528,23.157,38.189z M84.308,89.302H15.694V77.899h68.613V89.302z M45.45,83.598 c0-1.57,1.276-2.846,2.849-2.846h3.4c1.575,0,2.851,1.275,2.851,2.846c0,1.576-1.275,2.853-2.851,2.853h-3.4 C46.726,86.45,45.45,85.174,45.45,83.598z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.0 KiB |
@ -335,19 +335,15 @@ erpnext.pos.PointOfSale = Class.extend({
|
||||
if (!this.frm.doc.is_pos) {
|
||||
this.frm.set_value("is_pos", 1);
|
||||
}
|
||||
this.frm.page.clear_actions();
|
||||
this.frm.page.set_primary_action(__("Pay"), function() {
|
||||
me.make_payment();
|
||||
});
|
||||
this.frm.toolbar.current_status = null;
|
||||
} else if (this.frm.doc.docstatus===1) {
|
||||
this.frm.page.clear_actions();
|
||||
this.frm.page.set_primary_action(__("New"), function() {
|
||||
me.frm.pos_active = false;
|
||||
erpnext.open_as_pos = true;
|
||||
new_doc(me.frm.doctype);
|
||||
});
|
||||
this.frm.toolbar.current_status = null;
|
||||
}
|
||||
},
|
||||
refresh_delete_btn: function() {
|
||||
@ -382,6 +378,18 @@ erpnext.pos.PointOfSale = Class.extend({
|
||||
this.frm.script_manager.trigger("calculate_taxes_and_totals");
|
||||
this.refresh();
|
||||
},
|
||||
with_modes_of_payment: function(callback) {
|
||||
var me = this;
|
||||
if(me.modes_of_payment) {
|
||||
callback();
|
||||
} else {
|
||||
me.modes_of_payment = [];
|
||||
$.ajax("/api/resource/Mode of Payment").success(function(data) {
|
||||
$.each(data.data, function(i, d) { me.modes_of_payment.push(d.name); });
|
||||
callback();
|
||||
});
|
||||
}
|
||||
},
|
||||
make_payment: function() {
|
||||
var me = this;
|
||||
var no_of_items = this.frm.doc.items.length;
|
||||
@ -389,95 +397,92 @@ erpnext.pos.PointOfSale = Class.extend({
|
||||
if (no_of_items == 0)
|
||||
msgprint(__("Payment cannot be made for empty cart"));
|
||||
else {
|
||||
frappe.call({
|
||||
method: 'erpnext.accounts.doctype.sales_invoice.pos.get_mode_of_payment',
|
||||
callback: function(r) {
|
||||
if(!r.message) {
|
||||
msgprint(__("Please add to Modes of Payment from Setup."))
|
||||
return;
|
||||
|
||||
this.with_modes_of_payment(function() {
|
||||
// prefer cash payment!
|
||||
var default_mode = me.modes_of_payment.indexOf(__("Cash"))!==-1 ? __("Cash") : undefined;
|
||||
|
||||
// show payment wizard
|
||||
var dialog = new frappe.ui.Dialog({
|
||||
width: 400,
|
||||
title: 'Payment',
|
||||
fields: [
|
||||
{fieldtype:'Currency',
|
||||
fieldname:'total_amount', label: __('Total Amount'), read_only:1,
|
||||
"default": me.frm.doc.grand_total, read_only: 1},
|
||||
{fieldtype:'Select', fieldname:'mode_of_payment',
|
||||
label: __('Mode of Payment'),
|
||||
options: me.modes_of_payment.join('\n'), reqd: 1,
|
||||
"default": default_mode},
|
||||
{fieldtype:'Currency', fieldname:'paid_amount', label:__('Amount Paid'),
|
||||
reqd:1, "default": me.frm.doc.grand_total, hidden: 1, change: function() {
|
||||
var values = dialog.get_values();
|
||||
dialog.set_value("change", Math.round(values.paid_amount - values.total_amount));
|
||||
dialog.get_input("change").trigger("change");
|
||||
|
||||
}},
|
||||
{fieldtype:'Currency', fieldname:'change', label: __('Change'),
|
||||
"default": 0.0, hidden: 1, change: function() {
|
||||
var values = dialog.get_values();
|
||||
var write_off_amount = (flt(values.paid_amount) - flt(values.change)) - values.total_amount;
|
||||
dialog.get_field("write_off_amount").toggle(write_off_amount);
|
||||
dialog.set_value("write_off_amount", write_off_amount);
|
||||
}
|
||||
},
|
||||
{fieldtype:'Currency', fieldname:'write_off_amount',
|
||||
label: __('Write Off'), default: 0.0, hidden: 1},
|
||||
]
|
||||
});
|
||||
me.dialog = dialog;
|
||||
dialog.show();
|
||||
|
||||
// make read only
|
||||
dialog.get_input("total_amount").prop("disabled", true);
|
||||
dialog.get_input("write_off_amount").prop("disabled", true);
|
||||
|
||||
// toggle amount paid and change
|
||||
dialog.get_input("mode_of_payment").on("change", function() {
|
||||
var is_cash = dialog.get_value("mode_of_payment") === __("Cash");
|
||||
dialog.get_field("paid_amount").toggle(is_cash);
|
||||
dialog.get_field("change").toggle(is_cash);
|
||||
|
||||
if (is_cash && !dialog.get_value("change")) {
|
||||
// set to nearest 5
|
||||
var paid_amount = 5 * Math.ceil(dialog.get_value("total_amount") / 5);
|
||||
dialog.set_value("paid_amount", paid_amount);
|
||||
dialog.get_input("paid_amount").trigger("change");
|
||||
}
|
||||
}).trigger("change");
|
||||
|
||||
var modes_of_payment = r.message;
|
||||
|
||||
// prefer cash payment!
|
||||
var default_mode = modes_of_payment.indexOf(__("Cash"))!==-1 ? __("Cash") : undefined;
|
||||
|
||||
// show payment wizard
|
||||
var dialog = new frappe.ui.Dialog({
|
||||
width: 400,
|
||||
title: 'Payment',
|
||||
fields: [
|
||||
{fieldtype:'Currency', fieldname:'total_amount', label: __('Total Amount'), read_only:1,
|
||||
options:"currency", default:me.frm.doc.grand_total, read_only: 1},
|
||||
{fieldtype:'Select', fieldname:'mode_of_payment', label: __('Mode of Payment'),
|
||||
options:modes_of_payment.join('\n'), reqd: 1, default: default_mode},
|
||||
{fieldtype:'Currency', fieldname:'paid_amount', label:__('Amount Paid'), reqd:1,
|
||||
options: "currency",
|
||||
default:me.frm.doc.grand_total, hidden: 1},
|
||||
{fieldtype:'Currency', fieldname:'change', label: __('Change'), options: "currency",
|
||||
default: 0.0, hidden: 1},
|
||||
{fieldtype:'Currency', fieldname:'write_off_amount', label: __('Write Off'), options: "currency",
|
||||
default: 0.0, hidden: 1},
|
||||
{fieldtype:'Button', fieldname:'pay', label:'Pay'}
|
||||
]
|
||||
});
|
||||
dialog.show();
|
||||
|
||||
// make read only
|
||||
dialog.get_input("total_amount").prop("disabled", true);
|
||||
dialog.get_input("write_off_amount").prop("disabled", true);
|
||||
|
||||
dialog.get_input("paid_amount").on("change", function() {
|
||||
var values = dialog.get_values();
|
||||
dialog.set_value("change", Math.round(values.paid_amount - values.total_amount));
|
||||
dialog.get_input("change").trigger("change");
|
||||
});
|
||||
|
||||
dialog.get_input("change").on("change", function() {
|
||||
var values = dialog.get_values();
|
||||
var write_off_amount = (flt(values.paid_amount) - flt(values.change)) - values.total_amount;
|
||||
dialog.set_value("write_off_amount", write_off_amount);
|
||||
dialog.fields_dict.write_off_amount.$wrapper.toggleClass("hide", !!!write_off_amount);
|
||||
});
|
||||
|
||||
// toggle amount paid and change
|
||||
dialog.get_input("mode_of_payment").on("change", function() {
|
||||
var is_cash = dialog.get_value("mode_of_payment") === __("Cash");
|
||||
dialog.fields_dict.paid_amount.$wrapper.toggleClass("hide", !is_cash);
|
||||
dialog.fields_dict.change.$wrapper.toggleClass("hide", !is_cash);
|
||||
|
||||
if (is_cash && !dialog.get_value("change")) {
|
||||
// set to nearest 5
|
||||
var paid_amount = 5 * Math.ceil(dialog.get_value("total_amount") / 5);
|
||||
dialog.set_value("paid_amount", paid_amount);
|
||||
dialog.get_input("paid_amount").trigger("change");
|
||||
}
|
||||
}).trigger("change");
|
||||
|
||||
dialog.fields_dict.pay.input.onclick = function() {
|
||||
var values = dialog.get_values();
|
||||
var is_cash = values.mode_of_payment === __("Cash");
|
||||
if (!is_cash) {
|
||||
values.write_off_amount = values.change = 0.0;
|
||||
values.paid_amount = values.total_amount;
|
||||
}
|
||||
me.frm.set_value("mode_of_payment", values.mode_of_payment);
|
||||
|
||||
var paid_amount = flt((flt(values.paid_amount) - flt(values.change)) / me.frm.doc.conversion_rate, precision("paid_amount"));
|
||||
me.frm.set_value("paid_amount", paid_amount);
|
||||
|
||||
// specifying writeoff amount here itself, so as to avoid recursion issue
|
||||
me.frm.set_value("write_off_amount", me.frm.doc.base_grand_total - paid_amount);
|
||||
me.frm.set_value("outstanding_amount", 0);
|
||||
|
||||
me.frm.savesubmit(this);
|
||||
dialog.hide();
|
||||
me.refresh();
|
||||
};
|
||||
}
|
||||
me.set_pay_button(dialog);
|
||||
});
|
||||
}
|
||||
},
|
||||
set_pay_button: function(dialog) {
|
||||
var me = this;
|
||||
dialog.set_primary_action(__("Pay"), function() {
|
||||
var values = dialog.get_values();
|
||||
console.log(values);
|
||||
var is_cash = values.mode_of_payment === __("Cash");
|
||||
if (!is_cash) {
|
||||
values.write_off_amount = values.change = 0.0;
|
||||
values.paid_amount = values.total_amount;
|
||||
}
|
||||
me.frm.set_value("mode_of_payment", values.mode_of_payment);
|
||||
|
||||
var paid_amount = flt((flt(values.paid_amount) - flt(values.change)) / me.frm.doc.conversion_rate, precision("paid_amount"));
|
||||
me.frm.set_value("paid_amount", paid_amount);
|
||||
|
||||
// specifying writeoff amount here itself, so as to avoid recursion issue
|
||||
me.frm.set_value("write_off_amount", me.frm.doc.base_grand_total - paid_amount);
|
||||
me.frm.set_value("outstanding_amount", 0);
|
||||
|
||||
me.frm.savesubmit(this);
|
||||
dialog.hide();
|
||||
me.refresh();
|
||||
})
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
erpnext.pos.make_pos_btn = function(frm) {
|
||||
@ -486,28 +491,13 @@ erpnext.pos.make_pos_btn = function(frm) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(frm.doc.docstatus <= 1) {
|
||||
if(!frm.pos_active) {
|
||||
var btn_label = __("POS View"),
|
||||
icon = "icon-th";
|
||||
} else {
|
||||
var btn_label = __("Form View"),
|
||||
icon = "icon-file-text";
|
||||
}
|
||||
if(!frm.pos_btn) {
|
||||
frm.pos_btn = frm.page.add_action_icon("icon-th", function() {
|
||||
erpnext.pos.toggle(frm) });
|
||||
}
|
||||
|
||||
if(erpnext.open_as_pos) {
|
||||
erpnext.pos.toggle(frm, true);
|
||||
erpnext.open_as_pos = false;
|
||||
}
|
||||
|
||||
frm.$pos_btn && frm.$pos_btn.remove();
|
||||
|
||||
frm.$pos_btn = frm.page.add_menu_item(btn_label, function() {
|
||||
erpnext.pos.toggle(frm);
|
||||
});
|
||||
} else {
|
||||
// hack: will avoid calling refresh from refresh
|
||||
setTimeout(function() { erpnext.pos.toggle(frm, false); }, 100);
|
||||
if(erpnext.open_as_pos && !frm.pos_active) {
|
||||
erpnext.pos.toggle(frm);
|
||||
}
|
||||
}
|
||||
|
||||
@ -534,6 +524,7 @@ erpnext.pos.toggle = function(frm, show) {
|
||||
frm.page.set_view(frm.pos_active ? "main" : "pos");
|
||||
frm.pos_active = !frm.pos_active;
|
||||
|
||||
frm.toolbar.current_status = null;
|
||||
frm.refresh();
|
||||
|
||||
// refresh
|
||||
|
Loading…
Reference in New Issue
Block a user