diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js
index 370d529908..3183b08c29 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.js
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js
@@ -50,6 +50,7 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
},
load_defaults: function() {
+ this.frm.show_print_first = true;
if(this.frm.doc.__islocal && this.frm.doc.company) {
frappe.model.set_default_values(this.frm.doc);
$.each(this.frm.doc.accounts || [], function(i, jvd) {
@@ -360,7 +361,7 @@ frappe.ui.form.on("Journal Entry Account", {
credit: function(frm, dt, dn) {
cur_frm.cscript.update_totals(frm.doc);
},
-
+
exchange_rate: function(frm, cdt, cdn) {
var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
var row = locals[cdt][cdn];
@@ -368,7 +369,7 @@ frappe.ui.form.on("Journal Entry Account", {
if(row.account_currency == company_currency || !frm.doc.multi_currency) {
frappe.model.set_value(cdt, cdn, "exchange_rate", 1);
}
-
+
erpnext.journal_entry.set_debit_credit_in_company_currency(frm, cdt, cdn);
}
})
@@ -404,7 +405,7 @@ $.extend(erpnext.journal_entry, {
frappe.model.set_value(cdt, cdn, "credit",
flt(flt(row.credit_in_account_currency)*row.exchange_rate), precision("credit", row));
-
+
cur_frm.cscript.update_totals(frm.doc);
},
diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py
index b94b3ebd87..b40e6f4811 100644
--- a/erpnext/controllers/queries.py
+++ b/erpnext/controllers/queries.py
@@ -160,10 +160,10 @@ def tax_account_query(doctype, txt, searchfield, start, page_len, filters):
return tax_accounts
-def item_query(doctype, txt, searchfield, start, page_len, filters):
+def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=False):
conditions = []
- return frappe.db.sql("""select tabItem.name,tabItem.item_group,
+ return frappe.db.sql("""select tabItem.name, tabItem.item_group, tabItem.image,
if(length(tabItem.item_name) > 40,
concat(substr(tabItem.item_name, 1, 40), "..."), item_name) as item_name,
if(length(tabItem.description) > 40, \
@@ -192,7 +192,7 @@ def item_query(doctype, txt, searchfield, start, page_len, filters):
"_txt": txt.replace("%", ""),
"start": start,
"page_len": page_len
- })
+ }, as_dict=as_dict)
def bom(doctype, txt, searchfield, start, page_len, filters):
conditions = []
@@ -209,11 +209,11 @@ def bom(doctype, txt, searchfield, start, page_len, filters):
limit %(start)s, %(page_len)s """.format(
fcond=get_filters_cond(doctype, filters, conditions),
mcond=get_match_cond(doctype),
- key=frappe.db.escape(searchfield)),
+ key=frappe.db.escape(searchfield)),
{
'txt': "%%%s%%" % frappe.db.escape(txt),
'_txt': txt.replace("%", ""),
- 'start': start,
+ 'start': start,
'page_len': page_len
})
@@ -346,13 +346,13 @@ def get_income_account(doctype, txt, searchfield, start, page_len, filters):
@frappe.whitelist()
def get_expense_account(doctype, txt, searchfield, start, page_len, filters):
from erpnext.controllers.queries import get_match_cond
-
+
if not filters: filters = {}
condition = ""
if filters.get("company"):
condition += "and tabAccount.company = %(company)s"
-
+
return frappe.db.sql("""select tabAccount.name from `tabAccount`
where (tabAccount.report_type = "Profit and Loss"
or tabAccount.account_type in ("Expense Account", "Fixed Asset", "Temporary"))
@@ -360,7 +360,7 @@ def get_expense_account(doctype, txt, searchfield, start, page_len, filters):
and tabAccount.docstatus!=2
and tabAccount.{key} LIKE %(txt)s
{condition} {match_condition}"""
- .format(condition=condition, key=frappe.db.escape(searchfield),
+ .format(condition=condition, key=frappe.db.escape(searchfield),
match_condition=get_match_cond(doctype)), {
'company': filters.get("company", ""),
'txt': "%%%s%%" % frappe.db.escape(txt)
diff --git a/erpnext/public/build.json b/erpnext/public/build.json
index ff8bf94269..b3da719691 100644
--- a/erpnext/public/build.json
+++ b/erpnext/public/build.json
@@ -18,6 +18,8 @@
"public/js/pos/pos_bill_item.html",
"public/js/pos/pos_item.html",
"public/js/pos/pos_tax_row.html",
- "public/js/pos/pos.js"
+ "public/js/pos/pos.js",
+ "public/js/utils/item_selector.js",
+ "public/js/templates/item_selector.html"
]
}
diff --git a/erpnext/public/css/erpnext.css b/erpnext/public/css/erpnext.css
index 621efb55d7..d1d26bc4a8 100644
--- a/erpnext/public/css/erpnext.css
+++ b/erpnext/public/css/erpnext.css
@@ -13,17 +13,20 @@
margin: -10px auto;
}
/* pos */
+.pos-item-area {
+ padding: 0px 10px;
+}
+.pos-item-wrapper {
+ padding: 5px;
+}
.pos-item {
- display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
cursor: pointer;
padding: 5px;
- height: 0px;
- padding-bottom: 38%;
- width: 30%;
- margin: 1.6%;
+ padding-bottom: 15px;
border: 1px solid #d1d8dd;
+ margin-bottom: 5px;
}
.pos-item-text {
padding: 0px 5px;
@@ -36,7 +39,13 @@
border: 1px dashed #d1d8dd;
}
.pos-item-image {
- padding-bottom: 100%;
+ width: 100%;
+ height: 0px;
+ padding: 50% 0;
+ text-align: center;
+ line-height: 0;
+ color: #fff;
+ font-size: 30px;
background-size: cover;
border: 1px solid transparent;
background-position: top center;
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index dc6d4cdc81..9e2bd22caa 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -8,6 +8,7 @@ frappe.require("assets/erpnext/js/utils.js");
erpnext.TransactionController = erpnext.taxes_and_totals.extend({
onload: function() {
var me = this;
+ this.frm.show_print_first = true;
if(this.frm.doc.__islocal) {
var today = get_today(),
currency = frappe.defaults.get_user_default("currency");
@@ -81,7 +82,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
me.calculate_taxes_and_totals();
}
if(frappe.meta.get_docfield(this.frm.doc.doctype + " Item", "item_code")) {
- cur_frm.get_field("items").grid.set_multiple_add("item_code", "qty");
+ this.setup_item_selector();
}
},
@@ -890,7 +891,16 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
rate = flt(item.rate) * flt(this.frm.doc.conversion_rate || 1);
item.gross_profit = flt(((rate - item.valuation_rate) * item.qty), precision("amount", item));
}
+ },
+
+ setup_item_selector: function() {
+ if(!this.item_selector) {
+ this.item_selector = new erpnext.ItemSelector({frm: this.frm});
+ }
}
+
+
+
});
frappe.ui.form.on(cur_frm.doctype + " Item", "rate", function(frm, cdt, cdn) {
diff --git a/erpnext/public/js/pos/pos.html b/erpnext/public/js/pos/pos.html
index d12b9b28bb..36ef7c958c 100644
--- a/erpnext/public/js/pos/pos.html
+++ b/erpnext/public/js/pos/pos.html
@@ -47,7 +47,10 @@
-
+
+
+
+
diff --git a/erpnext/public/js/pos/pos.js b/erpnext/public/js/pos/pos.js
index a239bbc09f..60801e628a 100644
--- a/erpnext/public/js/pos/pos.js
+++ b/erpnext/public/js/pos/pos.js
@@ -131,7 +131,9 @@ erpnext.pos.PointOfSale = Class.extend({
item_code: obj.name,
item_price: format_currency(obj.price_list_rate, obj.currency),
item_name: obj.name===obj.item_name ? "" : obj.item_name,
- item_image: obj.image ? "url('" + obj.image + "')" : null
+ item_image: obj.image ? "url('" + obj.image + "')" : null,
+ color: frappe.get_palette(obj.item_name),
+ abbr: frappe.get_abbr(obj.item_name)
})).tooltip().appendTo($wrap);
});
}
diff --git a/erpnext/public/js/pos/pos_item.html b/erpnext/public/js/pos/pos_item.html
index 1235db9b84..aec36a7f80 100644
--- a/erpnext/public/js/pos/pos_item.html
+++ b/erpnext/public/js/pos/pos_item.html
@@ -1,9 +1,13 @@
-
-
+
+
+
+ {% if (!item_image) { %}{{ abbr }}{% } %}
+
+
+
{%= item_name ? (item_name + " (" + item_code + ")") : item_code %}
+
{%= item_price %}
+
-
-
{%= item_name ? (item_name + " (" + item_code + ")") : item_code %}
-
{%= item_price %}
-
-
+
\ No newline at end of file
diff --git a/erpnext/public/js/templates/item_selector.html b/erpnext/public/js/templates/item_selector.html
new file mode 100644
index 0000000000..47da67c8ee
--- /dev/null
+++ b/erpnext/public/js/templates/item_selector.html
@@ -0,0 +1,16 @@
+
+{% for (var i=0; i < data.length; i++) { var item = data[i]; %}
+
+
+
+ {% if(!item.image) { %}{{ item.abbr }}{% } %}
+
+
+
{{ item.name }}
+
+
+
+{% } %}
+
\ No newline at end of file
diff --git a/erpnext/public/js/utils/item_selector.js b/erpnext/public/js/utils/item_selector.js
new file mode 100644
index 0000000000..7d0bd15954
--- /dev/null
+++ b/erpnext/public/js/utils/item_selector.js
@@ -0,0 +1,94 @@
+erpnext.ItemSelector = Class.extend({
+ init: function(opts) {
+ $.extend(this, opts);
+
+ this.grid = this.frm.get_field("items").grid;
+ this.setup();
+ },
+
+ setup: function() {
+ var me = this;
+ if(!this.grid.add_items_button) {
+ this.grid.add_items_button = this.grid.add_custom_button(__('Add Items'), function() {
+ if(!me.dialog) {
+ me.make_dialog();
+ }
+ me.dialog.show();
+ me.render_items();
+ });
+ }
+ },
+
+ make_dialog: function() {
+ this.dialog = new frappe.ui.Dialog({
+ title: __('Add Items')
+ });
+ var body = $(this.dialog.body);
+ body.html('
');
+
+ this.dialog.input = body.find('.form-control');
+ this.dialog.results = body.find('.results');
+
+ var me = this;
+ this.dialog.results.on('click', '.pos-item', function() {
+ me.add_item($(this).attr('data-name'))
+ });
+
+ this.dialog.input.on('keyup', function() {
+ if(me.timeout_id) {
+ clearTimeout(me.timeout_id);
+ }
+ me.timeout_id = setTimeout(function() {
+ me.render_items();
+ me.timeout_id = undefined;
+ }, 500);
+ });
+ },
+
+ add_item: function(item_code) {
+ // add row or update qty
+ var added = false;
+
+ // find row with item if exists
+ $.each(this.frm.doc.items || [], function(i, d) {
+ if(d.item_code===item_code) {
+ frappe.model.set_value(d.doctype, d.name, 'qty', d.qty + 1);
+ show_alert(__("Added {0} ({1})", [item_code, d.qty]));
+ added = true;
+ return false;
+ }
+ });
+
+ if(!added) {
+ var d = this.grid.add_new_row();
+ frappe.model.set_value(d.doctype, d.name, 'item_code', item_code);
+
+ // after item fetch
+ frappe.after_ajax(function() {
+ setTimeout(function() {
+ frappe.model.set_value(d.doctype, d.name, 'qty', 1);
+ show_alert(__("Added {0} ({1})", [item_code, 1]));
+ }, 100);
+ });
+ }
+
+ },
+
+ render_items: function() {
+ var args = erpnext.queries.item();
+ args.txt = this.dialog.input.val();
+ args.as_dict = 1;
+
+ var me = this;
+ frappe.link_search("Item", args, function(r) {
+ $.each(r.values, function(i, d) {
+ if(!d.image) {
+ d.abbr = frappe.get_abbr(d.item_name);
+ d.color = frappe.get_palette(d.item_name);
+ }
+ });
+ me.dialog.results.html(frappe.render_template('item_selector', {'data':r.values}));
+ });
+ }
+})
\ No newline at end of file
diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less
index 813a5677cc..29d1533f48 100644
--- a/erpnext/public/less/erpnext.less
+++ b/erpnext/public/less/erpnext.less
@@ -16,20 +16,23 @@
}
/* pos */
-.pos {
+
+.pos-item-area {
+ padding: 0px 10px;
+}
+
+.pos-item-wrapper {
+ padding: 5px;
}
.pos-item {
- display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
cursor: pointer;
padding: 5px;
- height: 0px;
- padding-bottom: 38%;
- width: 30%;
- margin: 1.6%;
+ padding-bottom: 15px;
border: 1px solid #d1d8dd;
+ margin-bottom: 5px;
}
.pos-item-text {
@@ -46,7 +49,13 @@
}
.pos-item-image {
- padding-bottom: 100%;
+ width: 100%;
+ height: 0px;
+ padding: 50% 0;
+ text-align: center;
+ line-height: 0;
+ color: #fff;
+ font-size: 30px;
background-size: cover;
border: 1px solid transparent;
background-position: top center;
@@ -130,7 +139,7 @@
.discount-field-col {
padding-left: 0px;
}
-
+
.input-group {
margin-top: 2px;
}
diff --git a/erpnext/selling/doctype/customer/customer.json b/erpnext/selling/doctype/customer/customer.json
index 09f29cd3a8..6974eb5234 100644
--- a/erpnext/selling/doctype/customer/customer.json
+++ b/erpnext/selling/doctype/customer/customer.json
@@ -300,7 +300,7 @@
{
"allow_on_submit": 0,
"bold": 0,
- "collapsible": 0,
+ "collapsible": 1,
"fieldname": "currency_and_price_list",
"fieldtype": "Section Break",
"hidden": 0,
@@ -308,7 +308,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "label": "",
+ "label": "Currency and Price List",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -525,7 +525,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
- "collapsible_depends_on": "accounts",
+ "collapsible_depends_on": "",
"fieldname": "default_receivable_accounts",
"fieldtype": "Section Break",
"hidden": 0,
@@ -533,7 +533,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "label": "Default Receivable Accounts",
+ "label": "Accounting",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -927,7 +927,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-04-06 03:15:14.488537",
+ "modified": "2016-04-07 01:25:25.676480",
"modified_by": "Administrator",
"module": "Selling",
"name": "Customer",
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 1cd085235f..46f8c70d21 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -55,12 +55,15 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
onload_post_render: function() {
var me = this;
- cur_frm.get_field("items").grid.set_multiple_add("item_code", "qty");
this.set_default_account(function() {
if(me.frm.doc.__islocal && me.frm.doc.company && !me.frm.doc.amended_from) {
cur_frm.script_manager.trigger("company");
}
});
+
+ if(!this.item_selector) {
+ this.item_selector = new erpnext.ItemSelector({frm: this.frm});
+ }
},
refresh: function() {