Merge branch 'master' of github.com:webnotes/erpnext into wsgi
Conflicts: accounts/doctype/purchase_invoice/purchase_invoice.py accounts/doctype/sales_invoice/sales_invoice.txt selling/doctype/lead/lead.txt selling/doctype/opportunity/opportunity.txt stock/doctype/warehouse/warehouse.py
This commit is contained in:
commit
fa228e9c9b
@ -8,6 +8,7 @@ cur_frm.cscript.other_fname = "purchase_tax_details";
|
|||||||
wn.provide("erpnext.accounts");
|
wn.provide("erpnext.accounts");
|
||||||
wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js');
|
wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js');
|
||||||
wn.require('app/buying/doctype/purchase_common/purchase_common.js');
|
wn.require('app/buying/doctype/purchase_common/purchase_common.js');
|
||||||
|
wn.require('app/accounts/doctype/sales_invoice/pos.js');
|
||||||
|
|
||||||
erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
||||||
onload: function() {
|
onload: function() {
|
||||||
|
@ -61,19 +61,23 @@ class DocType(BuyingController):
|
|||||||
"purchase_receipt_details")
|
"purchase_receipt_details")
|
||||||
|
|
||||||
def get_credit_to(self):
|
def get_credit_to(self):
|
||||||
acc_head = webnotes.conn.sql("""select name, credit_days from `tabAccount`
|
|
||||||
where (name = %s or (master_name = %s and master_type = 'supplier'))
|
|
||||||
and docstatus != 2 and company = %s""",
|
|
||||||
(cstr(self.doc.supplier) + " - " + self.company_abbr,
|
|
||||||
self.doc.supplier, self.doc.company))
|
|
||||||
|
|
||||||
ret = {}
|
ret = {}
|
||||||
if acc_head and acc_head[0][0]:
|
if self.doc.supplier:
|
||||||
ret['credit_to'] = acc_head[0][0]
|
acc_head = webnotes.conn.sql("""select name, credit_days from `tabAccount`
|
||||||
if not self.doc.due_date:
|
where (name = %s or (master_name = %s and master_type = 'supplier'))
|
||||||
ret['due_date'] = add_days(cstr(self.doc.posting_date), acc_head and cint(acc_head[0][1]) or 0)
|
and docstatus != 2 and company = %s""",
|
||||||
elif not acc_head:
|
(cstr(self.doc.supplier) + " - " + self.company_abbr,
|
||||||
msgprint("%s does not have an Account Head in %s. You must first create it from the Supplier Master" % (self.doc.supplier, self.doc.company))
|
self.doc.supplier, self.doc.company))
|
||||||
|
|
||||||
|
if acc_head and acc_head[0][0]:
|
||||||
|
ret['credit_to'] = acc_head[0][0]
|
||||||
|
if not self.doc.due_date:
|
||||||
|
ret['due_date'] = add_days(cstr(self.doc.posting_date),
|
||||||
|
acc_head and cint(acc_head[0][1]) or 0)
|
||||||
|
elif not acc_head:
|
||||||
|
msgprint("%s does not have an Account Head in %s. \
|
||||||
|
You must first create it from the Supplier Master" % \
|
||||||
|
(self.doc.supplier, self.doc.company))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def set_supplier_defaults(self):
|
def set_supplier_defaults(self):
|
||||||
|
@ -7,7 +7,7 @@ erpnext.POS = Class.extend({
|
|||||||
this.frm = frm;
|
this.frm = frm;
|
||||||
this.wrapper.html('<div class="container">\
|
this.wrapper.html('<div class="container">\
|
||||||
<div class="row">\
|
<div class="row">\
|
||||||
<div class="customer-area col-sm-3 col-xs-6"></div>\
|
<div class="party-area col-sm-3 col-xs-6"></div>\
|
||||||
<div class="barcode-area col-sm-3 col-xs-6"></div>\
|
<div class="barcode-area col-sm-3 col-xs-6"></div>\
|
||||||
<div class="search-area col-sm-3 col-xs-6"></div>\
|
<div class="search-area col-sm-3 col-xs-6"></div>\
|
||||||
<div class="item-group-area col-sm-3 col-xs-6"></div>\
|
<div class="item-group-area col-sm-3 col-xs-6"></div>\
|
||||||
@ -71,7 +71,18 @@ erpnext.POS = Class.extend({
|
|||||||
</div>\
|
</div>\
|
||||||
</div>\
|
</div>\
|
||||||
</div></div>');
|
</div></div>');
|
||||||
|
|
||||||
|
if (wn.meta.has_field(cur_frm.doc.doctype, "customer")) {
|
||||||
|
this.party = "Customer";
|
||||||
|
this.price_list = this.frm.doc.selling_price_list;
|
||||||
|
this.sales_or_purchase = "Sales";
|
||||||
|
}
|
||||||
|
else if (wn.meta.has_field(cur_frm.doc.doctype, "supplier")) {
|
||||||
|
this.party = "Supplier";
|
||||||
|
this.price_list = this.frm.doc.buying_price_list;
|
||||||
|
this.sales_or_purchase = "Purchase";
|
||||||
|
}
|
||||||
|
|
||||||
this.make();
|
this.make();
|
||||||
|
|
||||||
var me = this;
|
var me = this;
|
||||||
@ -88,28 +99,29 @@ erpnext.POS = Class.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
make: function() {
|
make: function() {
|
||||||
this.make_customer();
|
this.make_party();
|
||||||
this.make_item_group();
|
this.make_item_group();
|
||||||
this.make_search();
|
this.make_search();
|
||||||
this.make_barcode();
|
this.make_barcode();
|
||||||
this.make_item_list();
|
this.make_item_list();
|
||||||
},
|
},
|
||||||
make_customer: function() {
|
make_party: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
this.customer = wn.ui.form.make_control({
|
this.party_field = wn.ui.form.make_control({
|
||||||
df: {
|
df: {
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Customer",
|
"options": this.party,
|
||||||
"label": "Customer",
|
"label": this.party,
|
||||||
"fieldname": "pos_customer",
|
"fieldname": "pos_party",
|
||||||
"placeholder": "Customer"
|
"placeholder": this.party
|
||||||
},
|
},
|
||||||
parent: this.wrapper.find(".customer-area")
|
parent: this.wrapper.find(".party-area")
|
||||||
});
|
});
|
||||||
this.customer.make_input();
|
this.party_field.make_input();
|
||||||
this.customer.$input.on("change", function() {
|
this.party_field.$input.on("change", function() {
|
||||||
if(!me.customer.autocomplete_open)
|
if(!me.party_field.autocomplete_open)
|
||||||
wn.model.set_value("Sales Invoice", me.frm.docname, "customer", this.value);
|
wn.model.set_value(me.frm.doctype, me.frm.docname,
|
||||||
|
me.party.toLowerCase(), this.value);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
make_item_group: function() {
|
make_item_group: function() {
|
||||||
@ -120,7 +132,7 @@ erpnext.POS = Class.extend({
|
|||||||
"options": "Item Group",
|
"options": "Item Group",
|
||||||
"label": "Item Group",
|
"label": "Item Group",
|
||||||
"fieldname": "pos_item_group",
|
"fieldname": "pos_item_group",
|
||||||
"placeholder": "Filter by Item Group"
|
"placeholder": "Item Group"
|
||||||
},
|
},
|
||||||
parent: this.wrapper.find(".item-group-area")
|
parent: this.wrapper.find(".item-group-area")
|
||||||
});
|
});
|
||||||
@ -138,7 +150,7 @@ erpnext.POS = Class.extend({
|
|||||||
"options": "Item",
|
"options": "Item",
|
||||||
"label": "Item",
|
"label": "Item",
|
||||||
"fieldname": "pos_item",
|
"fieldname": "pos_item",
|
||||||
"placeholder": "Select Item"
|
"placeholder": "Item"
|
||||||
},
|
},
|
||||||
parent: this.wrapper.find(".search-area")
|
parent: this.wrapper.find(".search-area")
|
||||||
});
|
});
|
||||||
@ -155,7 +167,7 @@ erpnext.POS = Class.extend({
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Barcode",
|
"label": "Barcode",
|
||||||
"fieldname": "pos_barcode",
|
"fieldname": "pos_barcode",
|
||||||
"placeholder": "Select Barcode"
|
"placeholder": "Barcode"
|
||||||
},
|
},
|
||||||
parent: this.wrapper.find(".barcode-area")
|
parent: this.wrapper.find(".barcode-area")
|
||||||
});
|
});
|
||||||
@ -171,7 +183,8 @@ erpnext.POS = Class.extend({
|
|||||||
wn.call({
|
wn.call({
|
||||||
method: 'accounts.doctype.sales_invoice.pos.get_items',
|
method: 'accounts.doctype.sales_invoice.pos.get_items',
|
||||||
args: {
|
args: {
|
||||||
price_list: cur_frm.doc.selling_price_list,
|
sales_or_purchase: this.sales_or_purchase,
|
||||||
|
price_list: this.price_list,
|
||||||
item_group: this.item_group.$input.val(),
|
item_group: this.item_group.$input.val(),
|
||||||
item: this.search.$input.val()
|
item: this.search.$input.val()
|
||||||
},
|
},
|
||||||
@ -200,15 +213,18 @@ erpnext.POS = Class.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// if form is local then allow this function
|
// if form is local then allow this function
|
||||||
if (cur_frm.doc.docstatus===0) {
|
$(me.wrapper).find("div.pos-item").on("click", function() {
|
||||||
$("div.pos-item").on("click", function() {
|
if(me.frm.doc.docstatus==0) {
|
||||||
if(!cur_frm.doc.customer) {
|
if(!me.frm.doc[me.party.toLowerCase()] && ((me.frm.doctype == "Quotation" &&
|
||||||
msgprint("Please select customer first.");
|
me.frm.doc.quotation_to == "Customer")
|
||||||
|
|| me.frm.doctype != "Quotation")) {
|
||||||
|
msgprint("Please select " + me.party + " first.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
me.add_to_cart($(this).attr("data-item_code"));
|
else
|
||||||
});
|
me.add_to_cart($(this).attr("data-item_code"));
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -217,12 +233,12 @@ erpnext.POS = Class.extend({
|
|||||||
var caught = false;
|
var caught = false;
|
||||||
|
|
||||||
// get no_of_items
|
// get no_of_items
|
||||||
no_of_items = me.wrapper.find("#cart tbody").length;
|
var no_of_items = me.wrapper.find("#cart tbody tr").length;
|
||||||
|
|
||||||
// check whether the item is already added
|
// check whether the item is already added
|
||||||
if (no_of_items != 0) {
|
if (no_of_items != 0) {
|
||||||
$.each(wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries",
|
$.each(wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
|
||||||
"Sales Invoice"), function(i, d) {
|
this.frm.cscript.fname, this.frm.doctype), function(i, d) {
|
||||||
if (d.item_code == item_code)
|
if (d.item_code == item_code)
|
||||||
caught = true;
|
caught = true;
|
||||||
});
|
});
|
||||||
@ -233,15 +249,16 @@ erpnext.POS = Class.extend({
|
|||||||
me.update_qty(item_code, 1);
|
me.update_qty(item_code, 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var child = wn.model.add_child(me.frm.doc, "Sales Invoice Item", "entries");
|
var child = wn.model.add_child(me.frm.doc, this.frm.doctype + " Item",
|
||||||
|
this.frm.cscript.fname);
|
||||||
child.item_code = item_code;
|
child.item_code = item_code;
|
||||||
me.frm.cscript.item_code(me.frm.doc, child.doctype, child.name);
|
me.frm.cscript.item_code(me.frm.doc, child.doctype, child.name);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
update_qty: function(item_code, qty, textbox_qty) {
|
update_qty: function(item_code, qty, textbox_qty) {
|
||||||
var me = this;
|
var me = this;
|
||||||
$.each(wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries",
|
$.each(wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
|
||||||
"Sales Invoice"), function(i, d) {
|
this.frm.cscript.fname, this.frm.doctype), function(i, d) {
|
||||||
if (d.item_code == item_code) {
|
if (d.item_code == item_code) {
|
||||||
if (textbox_qty) {
|
if (textbox_qty) {
|
||||||
if (qty == 0 && d.item_code == item_code)
|
if (qty == 0 && d.item_code == item_code)
|
||||||
@ -259,14 +276,24 @@ erpnext.POS = Class.extend({
|
|||||||
},
|
},
|
||||||
refresh: function() {
|
refresh: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
this.customer.set_input(this.frm.doc.customer);
|
this.party_field.set_input(this.frm.doc[this.party.toLowerCase()]);
|
||||||
this.barcode.set_input("");
|
this.barcode.set_input("");
|
||||||
|
|
||||||
// add items
|
// add items
|
||||||
var $items = me.wrapper.find("#cart tbody").empty();
|
var $items = me.wrapper.find("#cart tbody").empty();
|
||||||
|
|
||||||
$.each(wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries",
|
$.each(wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
|
||||||
"Sales Invoice"), function(i, d) {
|
this.frm.cscript.fname, this.frm.doctype), function(i, d) {
|
||||||
|
|
||||||
|
if (me.sales_or_purchase == "Sales") {
|
||||||
|
item_amount = d.export_amount;
|
||||||
|
rate = d.export_rate;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
item_amount = d.import_amount;
|
||||||
|
rate = d.import_rate;
|
||||||
|
}
|
||||||
|
|
||||||
$(repl('<tr id="%(item_code)s" data-selected="false">\
|
$(repl('<tr id="%(item_code)s" data-selected="false">\
|
||||||
<td>%(item_code)s%(item_name)s</td>\
|
<td>%(item_code)s%(item_name)s</td>\
|
||||||
<td><input type="text" value="%(qty)s" \
|
<td><input type="text" value="%(qty)s" \
|
||||||
@ -277,16 +304,16 @@ erpnext.POS = Class.extend({
|
|||||||
item_code: d.item_code,
|
item_code: d.item_code,
|
||||||
item_name: d.item_name===d.item_code ? "" : ("<br>" + d.item_name),
|
item_name: d.item_name===d.item_code ? "" : ("<br>" + d.item_name),
|
||||||
qty: d.qty,
|
qty: d.qty,
|
||||||
rate: format_currency(d.ref_rate, cur_frm.doc.price_list_currency),
|
rate: format_currency(rate, me.frm.doc.currency),
|
||||||
amount: format_currency(d.export_amount, cur_frm.doc.price_list_currency)
|
amount: format_currency(item_amount, me.frm.doc.currency)
|
||||||
}
|
}
|
||||||
)).appendTo($items);
|
)).appendTo($items);
|
||||||
});
|
});
|
||||||
|
|
||||||
// taxes
|
// taxes
|
||||||
var taxes = wn.model.get_children("Sales Taxes and Charges", this.frm.doc.name, "other_charges",
|
var taxes = wn.model.get_children(this.sales_or_purchase + " Taxes and Charges",
|
||||||
"Sales Invoice");
|
this.frm.doc.name, this.frm.cscript.other_fname, this.frm.doctype);
|
||||||
$(".tax-table")
|
$(this.wrapper).find(".tax-table")
|
||||||
.toggle((taxes && taxes.length) ? true : false)
|
.toggle((taxes && taxes.length) ? true : false)
|
||||||
.find("tbody").empty();
|
.find("tbody").empty();
|
||||||
|
|
||||||
@ -297,30 +324,39 @@ erpnext.POS = Class.extend({
|
|||||||
<tr>', {
|
<tr>', {
|
||||||
description: d.description,
|
description: d.description,
|
||||||
rate: d.rate,
|
rate: d.rate,
|
||||||
tax_amount: format_currency(d.tax_amount, me.frm.doc.price_list_currency)
|
tax_amount: format_currency(flt(d.tax_amount)/flt(me.frm.doc.conversion_rate),
|
||||||
|
me.frm.doc.currency)
|
||||||
})).appendTo(".tax-table tbody");
|
})).appendTo(".tax-table tbody");
|
||||||
});
|
});
|
||||||
|
|
||||||
// set totals
|
// set totals
|
||||||
this.wrapper.find(".net-total").text(format_currency(this.frm.doc.net_total_export,
|
if (this.sales_or_purchase == "Sales") {
|
||||||
cur_frm.doc.price_list_currency));
|
this.wrapper.find(".net-total").text(format_currency(this.frm.doc.net_total_export,
|
||||||
this.wrapper.find(".grand-total").text(format_currency(this.frm.doc.grand_total_export,
|
me.frm.doc.currency));
|
||||||
cur_frm.doc.price_list_currency));
|
this.wrapper.find(".grand-total").text(format_currency(this.frm.doc.grand_total_export,
|
||||||
|
me.frm.doc.currency));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.wrapper.find(".net-total").text(format_currency(this.frm.doc.net_total_import,
|
||||||
|
me.frm.doc.currency));
|
||||||
|
this.wrapper.find(".grand-total").text(format_currency(this.frm.doc.grand_total_import,
|
||||||
|
me.frm.doc.currency));
|
||||||
|
}
|
||||||
|
|
||||||
// if form is local then only run all these functions
|
// if form is local then only run all these functions
|
||||||
if (cur_frm.doc.docstatus===0) {
|
if (this.frm.doc.docstatus===0) {
|
||||||
$("input.qty").on("focus", function() {
|
$(this.wrapper).find("input.qty").on("focus", function() {
|
||||||
$(this).select();
|
$(this).select();
|
||||||
});
|
});
|
||||||
|
|
||||||
// append quantity to the respective item after change from input box
|
// append quantity to the respective item after change from input box
|
||||||
$("input.qty").on("change", function() {
|
$(this.wrapper).find("input.qty").on("change", function() {
|
||||||
var item_code = $(this).closest("tr")[0].id;
|
var item_code = $(this).closest("tr")[0].id;
|
||||||
me.update_qty(item_code, $(this).val(), true);
|
me.update_qty(item_code, $(this).val(), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
// on td click toggle the highlighting of row
|
// on td click toggle the highlighting of row
|
||||||
$("#cart tbody tr td").on("click", function() {
|
$(this.wrapper).find("#cart tbody tr td").on("click", function() {
|
||||||
var row = $(this).closest("tr");
|
var row = $(this).closest("tr");
|
||||||
if (row.attr("data-selected") == "false") {
|
if (row.attr("data-selected") == "false") {
|
||||||
row.attr("class", "warning");
|
row.attr("class", "warning");
|
||||||
@ -335,20 +371,37 @@ erpnext.POS = Class.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
me.refresh_delete_btn();
|
me.refresh_delete_btn();
|
||||||
cur_frm.pos.barcode.$input.focus();
|
this.barcode.$input.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if form is submitted & cancelled then disable all input box & buttons
|
// if form is submitted & cancelled then disable all input box & buttons
|
||||||
if (cur_frm.doc.docstatus>=1 && cint(cur_frm.doc.is_pos)) {
|
if (this.frm.doc.docstatus>=1) {
|
||||||
me.wrapper.find('input, button').each(function () {
|
$(this.wrapper).find('input, button').each(function () {
|
||||||
$(this).prop('disabled', true);
|
$(this).prop('disabled', true);
|
||||||
});
|
});
|
||||||
$(".delete-items").hide();
|
$(this.wrapper).find(".delete-items").hide();
|
||||||
$(".make-payment").hide();
|
$(this.wrapper).find(".make-payment").hide();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$(this.wrapper).find('input, button').each(function () {
|
||||||
|
$(this).prop('disabled', false);
|
||||||
|
});
|
||||||
|
$(this.wrapper).find(".make-payment").show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show Make Payment button only in Sales Invoice
|
||||||
|
if (this.frm.doctype != "Sales Invoice")
|
||||||
|
$(this.wrapper).find(".make-payment").hide();
|
||||||
|
|
||||||
|
// If quotation to is not Customer then remove party
|
||||||
|
if (this.frm.doctype == "Quotation") {
|
||||||
|
this.party_field.$wrapper.remove();
|
||||||
|
if (this.frm.doc.quotation_to == "Customer")
|
||||||
|
this.make_party();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
refresh_delete_btn: function() {
|
refresh_delete_btn: function() {
|
||||||
$(".delete-items").toggle($(".item-cart .warning").length ? true : false);
|
$(this.wrapper).find(".delete-items").toggle($(".item-cart .warning").length ? true : false);
|
||||||
},
|
},
|
||||||
add_item_thru_barcode: function() {
|
add_item_thru_barcode: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
@ -370,32 +423,32 @@ erpnext.POS = Class.extend({
|
|||||||
remove_selected_item: function() {
|
remove_selected_item: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
var selected_items = [];
|
var selected_items = [];
|
||||||
var no_of_items = $("#cart tbody tr").length;
|
var no_of_items = $(this.wrapper).find("#cart tbody tr").length;
|
||||||
for(var x=0; x<=no_of_items - 1; x++) {
|
for(var x=0; x<=no_of_items - 1; x++) {
|
||||||
var row = $("#cart tbody tr:eq(" + x + ")");
|
var row = $(this.wrapper).find("#cart tbody tr:eq(" + x + ")");
|
||||||
if(row.attr("data-selected") == "true") {
|
if(row.attr("data-selected") == "true") {
|
||||||
selected_items.push(row.attr("id"));
|
selected_items.push(row.attr("id"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var child = wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries",
|
var child = wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
|
||||||
"Sales Invoice");
|
this.frm.cscript.fname, this.frm.doctype);
|
||||||
|
|
||||||
$.each(child, function(i, d) {
|
$.each(child, function(i, d) {
|
||||||
for (var i in selected_items) {
|
for (var i in selected_items) {
|
||||||
if (d.item_code == selected_items[i]) {
|
if (d.item_code == selected_items[i]) {
|
||||||
// cur_frm.fields_dict["entries"].grid.grid_rows[d.idx].remove();
|
|
||||||
wn.model.clear_doc(d.doctype, d.name);
|
wn.model.clear_doc(d.doctype, d.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
cur_frm.fields_dict["entries"].grid.refresh();
|
this.frm.fields_dict[this.frm.cscript.fname].grid.refresh();
|
||||||
cur_frm.script_manager.trigger("calculate_taxes_and_totals");
|
this.frm.script_manager.trigger("calculate_taxes_and_totals");
|
||||||
me.frm.dirty();
|
me.frm.dirty();
|
||||||
me.refresh();
|
me.refresh();
|
||||||
},
|
},
|
||||||
make_payment: function() {
|
make_payment: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
var no_of_items = $("#cart tbody tr").length;
|
var no_of_items = $(this.wrapper).find("#cart tbody tr").length;
|
||||||
var mode_of_payment = [];
|
var mode_of_payment = [];
|
||||||
|
|
||||||
if (no_of_items == 0)
|
if (no_of_items == 0)
|
||||||
@ -423,15 +476,15 @@ erpnext.POS = Class.extend({
|
|||||||
"total_amount": $(".grand-total").text()
|
"total_amount": $(".grand-total").text()
|
||||||
});
|
});
|
||||||
dialog.show();
|
dialog.show();
|
||||||
cur_frm.pos.barcode.$input.focus();
|
me.barcode.$input.focus();
|
||||||
|
|
||||||
dialog.get_input("total_amount").prop("disabled", true);
|
dialog.get_input("total_amount").prop("disabled", true);
|
||||||
|
|
||||||
dialog.fields_dict.pay.input.onclick = function() {
|
dialog.fields_dict.pay.input.onclick = function() {
|
||||||
cur_frm.set_value("mode_of_payment", dialog.get_values().mode_of_payment);
|
me.frm.set_value("mode_of_payment", dialog.get_values().mode_of_payment);
|
||||||
cur_frm.set_value("paid_amount", dialog.get_values().total_amount);
|
me.frm.set_value("paid_amount", dialog.get_values().total_amount);
|
||||||
cur_frm.cscript.mode_of_payment(cur_frm.doc);
|
me.frm.cscript.mode_of_payment(me.frm.doc);
|
||||||
cur_frm.save();
|
me.frm.save();
|
||||||
dialog.hide();
|
dialog.hide();
|
||||||
me.refresh();
|
me.refresh();
|
||||||
};
|
};
|
||||||
|
@ -3,17 +3,21 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import webnotes
|
import webnotes
|
||||||
from webnotes import msgprint
|
|
||||||
|
|
||||||
@webnotes.whitelist()
|
@webnotes.whitelist()
|
||||||
def get_items(price_list, item=None, item_group=None):
|
def get_items(price_list, sales_or_purchase, item=None, item_group=None):
|
||||||
condition = ""
|
condition = ""
|
||||||
|
|
||||||
|
if sales_or_purchase == "Sales":
|
||||||
|
condition = "i.is_sales_item='Yes'"
|
||||||
|
else:
|
||||||
|
condition = "i.is_purchase_item='Yes'"
|
||||||
|
|
||||||
if item_group and item_group != "All Item Groups":
|
if item_group and item_group != "All Item Groups":
|
||||||
condition = "and i.item_group='%s'" % item_group
|
condition += " and i.item_group='%s'" % item_group
|
||||||
|
|
||||||
if item:
|
if item:
|
||||||
condition = "and i.name='%s'" % item
|
condition += " and i.name='%s'" % item
|
||||||
|
|
||||||
return webnotes.conn.sql("""select i.name, i.item_name, i.image,
|
return webnotes.conn.sql("""select i.name, i.item_name, i.image,
|
||||||
pl_items.ref_rate, pl_items.currency
|
pl_items.ref_rate, pl_items.currency
|
||||||
@ -24,13 +28,18 @@ def get_items(price_list, item=None, item_group=None):
|
|||||||
ON
|
ON
|
||||||
pl_items.item_code=i.name
|
pl_items.item_code=i.name
|
||||||
where
|
where
|
||||||
i.is_sales_item='Yes'%s""" % ('%s', condition), (price_list), as_dict=1)
|
%s""" % ('%s', condition), (price_list), as_dict=1)
|
||||||
|
|
||||||
@webnotes.whitelist()
|
@webnotes.whitelist()
|
||||||
def get_item_from_barcode(barcode):
|
def get_item_from_barcode(barcode):
|
||||||
return webnotes.conn.sql("""select name from `tabItem` where barcode=%s""",
|
return webnotes.conn.sql("""select name from `tabItem` where barcode=%s""",
|
||||||
(barcode), as_dict=1)
|
(barcode), as_dict=1)
|
||||||
|
|
||||||
|
@webnotes.whitelist()
|
||||||
|
def get_item_from_serial_no(serial_no):
|
||||||
|
return webnotes.conn.sql("""select name, item_code from `tabSerial No` where
|
||||||
|
name=%s""", (serial_no), as_dict=1)
|
||||||
|
|
||||||
@webnotes.whitelist()
|
@webnotes.whitelist()
|
||||||
def get_mode_of_payment():
|
def get_mode_of_payment():
|
||||||
return webnotes.conn.sql("""select name from `tabMode of Payment`""", as_dict=1)
|
return webnotes.conn.sql("""select name from `tabMode of Payment`""", as_dict=1)
|
@ -1,15 +0,0 @@
|
|||||||
.pos-item {
|
|
||||||
height: 200px;
|
|
||||||
overflow: hidden;
|
|
||||||
cursor: pointer;
|
|
||||||
padding-left: 5px !important;
|
|
||||||
padding-right: 5px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pos-bill {
|
|
||||||
padding: 20px 5px;
|
|
||||||
font-family: Monospace;
|
|
||||||
border: 1px solid #eee;
|
|
||||||
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
|
|
||||||
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
|
|
||||||
}
|
|
@ -29,9 +29,10 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
|||||||
// toggle to pos view if is_pos is 1 in user_defaults
|
// toggle to pos view if is_pos is 1 in user_defaults
|
||||||
if ((cint(wn.defaults.get_user_defaults("is_pos"))===1 || cur_frm.doc.is_pos) &&
|
if ((cint(wn.defaults.get_user_defaults("is_pos"))===1 || cur_frm.doc.is_pos) &&
|
||||||
cint(wn.defaults.get_user_defaults("fs_pos_view"))===1) {
|
cint(wn.defaults.get_user_defaults("fs_pos_view"))===1) {
|
||||||
this.frm.set_value("is_pos", 1);
|
if(this.frm.doc.__islocal && !this.frm.doc.amended_from) {
|
||||||
this.is_pos();
|
this.frm.set_value("is_pos", 1);
|
||||||
cur_frm.cscript.toggle_pos(true);
|
this.is_pos(function() {cur_frm.cscript.toggle_pos(true);});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if document is POS then change default print format to "POS Invoice"
|
// if document is POS then change default print format to "POS Invoice"
|
||||||
@ -78,14 +79,11 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
|||||||
cur_frm.add_custom_button('Make Payment Entry', cur_frm.cscript.make_bank_voucher);
|
cur_frm.add_custom_button('Make Payment Entry', cur_frm.cscript.make_bank_voucher);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doc.docstatus===0) {
|
// Show buttons only when pos view is active
|
||||||
|
if (doc.docstatus===0 && !this.pos_active) {
|
||||||
cur_frm.cscript.sales_order_btn();
|
cur_frm.cscript.sales_order_btn();
|
||||||
cur_frm.cscript.delivery_note_btn();
|
cur_frm.cscript.delivery_note_btn();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show POS button only if it enabled from features setup
|
|
||||||
if(cint(sys_defaults.fs_pos_view)===1)
|
|
||||||
cur_frm.cscript.pos_btn();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
sales_order_btn: function() {
|
sales_order_btn: function() {
|
||||||
@ -124,62 +122,13 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
pos_btn: function() {
|
|
||||||
if(cur_frm.$pos_btn)
|
|
||||||
cur_frm.$pos_btn.remove();
|
|
||||||
|
|
||||||
if(!cur_frm.pos_active) {
|
|
||||||
var btn_label = wn._("POS View"),
|
|
||||||
icon = "icon-desktop";
|
|
||||||
|
|
||||||
cur_frm.cscript.sales_order_btn();
|
|
||||||
cur_frm.cscript.delivery_note_btn();
|
|
||||||
} else {
|
|
||||||
var btn_label = wn._("Invoice View"),
|
|
||||||
icon = "icon-file-text";
|
|
||||||
|
|
||||||
if (cur_frm.doc.docstatus===0) {
|
|
||||||
this.$delivery_note_btn.remove();
|
|
||||||
this.$sales_order_btn.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_frm.$pos_btn = cur_frm.add_custom_button(btn_label, function() {
|
|
||||||
cur_frm.cscript.toggle_pos();
|
|
||||||
cur_frm.cscript.pos_btn();
|
|
||||||
}, icon);
|
|
||||||
},
|
|
||||||
|
|
||||||
toggle_pos: function(show) {
|
|
||||||
if (!this.frm.doc.selling_price_list)
|
|
||||||
msgprint(wn._("Please select Price List"))
|
|
||||||
else {
|
|
||||||
if((show===true && cur_frm.pos_active) || (show===false && !cur_frm.pos_active)) return;
|
|
||||||
|
|
||||||
// make pos
|
|
||||||
if(!cur_frm.pos) {
|
|
||||||
cur_frm.layout.add_view("pos");
|
|
||||||
cur_frm.pos = new erpnext.POS(cur_frm.layout.views.pos, cur_frm);
|
|
||||||
}
|
|
||||||
|
|
||||||
// toggle view
|
|
||||||
cur_frm.layout.set_view(cur_frm.pos_active ? "" : "pos");
|
|
||||||
cur_frm.pos_active = !cur_frm.pos_active;
|
|
||||||
|
|
||||||
// refresh
|
|
||||||
if(cur_frm.pos_active)
|
|
||||||
cur_frm.pos.refresh();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
tc_name: function() {
|
tc_name: function() {
|
||||||
this.get_terms();
|
this.get_terms();
|
||||||
},
|
},
|
||||||
|
|
||||||
is_pos: function() {
|
is_pos: function(callback_fn) {
|
||||||
cur_frm.cscript.hide_fields(this.frm.doc);
|
cur_frm.cscript.hide_fields(this.frm.doc);
|
||||||
|
|
||||||
if(cint(this.frm.doc.is_pos)) {
|
if(cint(this.frm.doc.is_pos)) {
|
||||||
if(!this.frm.doc.company) {
|
if(!this.frm.doc.company) {
|
||||||
this.frm.set_value("is_pos", 0);
|
this.frm.set_value("is_pos", 0);
|
||||||
@ -192,11 +141,13 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
|||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if(!r.exc) {
|
if(!r.exc) {
|
||||||
me.frm.script_manager.trigger("update_stock");
|
me.frm.script_manager.trigger("update_stock");
|
||||||
|
if(callback_fn) callback_fn()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
debit_to: function() {
|
debit_to: function() {
|
||||||
|
@ -195,7 +195,7 @@ class DocType(SellingController):
|
|||||||
pos = get_pos_settings(self.doc.company)
|
pos = get_pos_settings(self.doc.company)
|
||||||
|
|
||||||
if pos:
|
if pos:
|
||||||
if not for_validate:
|
if not for_validate and not self.doc.customer:
|
||||||
self.doc.customer = pos.customer
|
self.doc.customer = pos.customer
|
||||||
self.set_customer_defaults()
|
self.set_customer_defaults()
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-05-24 19:29:05",
|
"creation": "2013-05-24 19:29:05",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-10-02 14:24:52",
|
"modified": "2013-10-02 14:24:50",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -181,6 +181,7 @@
|
|||||||
"search_index": 1
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"default": "Today",
|
||||||
"description": "Enter the date by which payments from customer is expected against this invoice.",
|
"description": "Enter the date by which payments from customer is expected against this invoice.",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "due_date",
|
"fieldname": "due_date",
|
||||||
@ -412,7 +413,7 @@
|
|||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "other_charges",
|
"fieldname": "other_charges",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"label": "Taxes and Charges1",
|
"label": "Sales Taxes and Charges",
|
||||||
"oldfieldname": "other_charges",
|
"oldfieldname": "other_charges",
|
||||||
"oldfieldtype": "Table",
|
"oldfieldtype": "Table",
|
||||||
"options": "Sales Taxes and Charges",
|
"options": "Sales Taxes and Charges",
|
||||||
|
@ -55,7 +55,7 @@ def get_stock_ledger_entries(filters):
|
|||||||
from `tabStock Ledger Entry`"""
|
from `tabStock Ledger Entry`"""
|
||||||
|
|
||||||
if filters.get("company"):
|
if filters.get("company"):
|
||||||
query += """ and company=%(company)s"""
|
query += """ where company=%(company)s"""
|
||||||
|
|
||||||
query += " order by item_code desc, warehouse desc, posting_date desc, posting_time desc, name desc"
|
query += " order by item_code desc, warehouse desc, posting_date desc, posting_time desc, name desc"
|
||||||
|
|
||||||
|
@ -108,8 +108,7 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
|
|||||||
var item = wn.model.get_doc(cdt, cdn);
|
var item = wn.model.get_doc(cdt, cdn);
|
||||||
if(item.item_code) {
|
if(item.item_code) {
|
||||||
if(!this.validate_company_and_party("supplier")) {
|
if(!this.validate_company_and_party("supplier")) {
|
||||||
item.item_code = null;
|
cur_frm.fields_dict[me.frm.cscript.fname].grid.grid_rows[item.idx - 1].remove();
|
||||||
refresh_field("item_code", item.name, item.parentfield);
|
|
||||||
} else {
|
} else {
|
||||||
return this.frm.call({
|
return this.frm.call({
|
||||||
method: "buying.utils.get_item_details",
|
method: "buying.utils.get_item_details",
|
||||||
|
@ -10,6 +10,7 @@ cur_frm.cscript.other_fname = "purchase_tax_details";
|
|||||||
wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js');
|
wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js');
|
||||||
wn.require('app/utilities/doctype/sms_control/sms_control.js');
|
wn.require('app/utilities/doctype/sms_control/sms_control.js');
|
||||||
wn.require('app/buying/doctype/purchase_common/purchase_common.js');
|
wn.require('app/buying/doctype/purchase_common/purchase_common.js');
|
||||||
|
wn.require('app/accounts/doctype/sales_invoice/pos.js');
|
||||||
|
|
||||||
erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend({
|
erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend({
|
||||||
refresh: function(doc, cdt, cdn) {
|
refresh: function(doc, cdt, cdn) {
|
||||||
|
@ -6,9 +6,10 @@ from __future__ import unicode_literals
|
|||||||
import unittest
|
import unittest
|
||||||
import webnotes
|
import webnotes
|
||||||
import webnotes.defaults
|
import webnotes.defaults
|
||||||
|
from webnotes.utils import flt
|
||||||
|
|
||||||
class TestPurchaseOrder(unittest.TestCase):
|
class TestPurchaseOrder(unittest.TestCase):
|
||||||
def test_make_purchase_receipt(self):
|
def test_make_purchase_receipt(self):
|
||||||
from buying.doctype.purchase_order.purchase_order import make_purchase_receipt
|
from buying.doctype.purchase_order.purchase_order import make_purchase_receipt
|
||||||
|
|
||||||
po = webnotes.bean(copy=test_records[0]).insert()
|
po = webnotes.bean(copy=test_records[0]).insert()
|
||||||
@ -18,6 +19,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
|
|
||||||
po = webnotes.bean("Purchase Order", po.doc.name)
|
po = webnotes.bean("Purchase Order", po.doc.name)
|
||||||
po.submit()
|
po.submit()
|
||||||
|
|
||||||
pr = make_purchase_receipt(po.doc.name)
|
pr = make_purchase_receipt(po.doc.name)
|
||||||
pr[0]["supplier_warehouse"] = "_Test Warehouse 1 - _TC"
|
pr[0]["supplier_warehouse"] = "_Test Warehouse 1 - _TC"
|
||||||
|
|
||||||
@ -25,7 +27,52 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
self.assertEquals(len(pr), len(test_records[0]))
|
self.assertEquals(len(pr), len(test_records[0]))
|
||||||
|
|
||||||
pr[0].naming_series = "_T-Purchase Receipt-"
|
pr[0].naming_series = "_T-Purchase Receipt-"
|
||||||
webnotes.bean(pr).insert()
|
pr_bean = webnotes.bean(pr)
|
||||||
|
pr_bean.insert()
|
||||||
|
|
||||||
|
def test_ordered_qty(self):
|
||||||
|
webnotes.conn.sql("delete from tabBin")
|
||||||
|
|
||||||
|
from buying.doctype.purchase_order.purchase_order import make_purchase_receipt
|
||||||
|
|
||||||
|
po = webnotes.bean(copy=test_records[0]).insert()
|
||||||
|
|
||||||
|
self.assertRaises(webnotes.ValidationError, make_purchase_receipt,
|
||||||
|
po.doc.name)
|
||||||
|
|
||||||
|
po = webnotes.bean("Purchase Order", po.doc.name)
|
||||||
|
po.doc.is_subcontracted = "No"
|
||||||
|
po.doclist[1].item_code = "_Test Item"
|
||||||
|
po.submit()
|
||||||
|
|
||||||
|
self.assertEquals(webnotes.conn.get_value("Bin", {"item_code": "_Test Item",
|
||||||
|
"warehouse": "_Test Warehouse - _TC"}, "ordered_qty"), 10)
|
||||||
|
|
||||||
|
pr = make_purchase_receipt(po.doc.name)
|
||||||
|
|
||||||
|
self.assertEquals(pr[0]["doctype"], "Purchase Receipt")
|
||||||
|
self.assertEquals(len(pr), len(test_records[0]))
|
||||||
|
|
||||||
|
pr[0].naming_series = "_T-Purchase Receipt-"
|
||||||
|
pr[1].qty = 4.0
|
||||||
|
pr_bean = webnotes.bean(pr)
|
||||||
|
pr_bean.insert()
|
||||||
|
pr_bean.submit()
|
||||||
|
|
||||||
|
self.assertEquals(flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item",
|
||||||
|
"warehouse": "_Test Warehouse - _TC"}, "ordered_qty")), 6.0)
|
||||||
|
|
||||||
|
webnotes.conn.set_value('Item', '_Test Item', 'tolerance', 50)
|
||||||
|
|
||||||
|
pr1 = make_purchase_receipt(po.doc.name)
|
||||||
|
pr1[0].naming_series = "_T-Purchase Receipt-"
|
||||||
|
pr1[1].qty = 8
|
||||||
|
pr1_bean = webnotes.bean(pr1)
|
||||||
|
pr1_bean.insert()
|
||||||
|
pr1_bean.submit()
|
||||||
|
|
||||||
|
self.assertEquals(flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item",
|
||||||
|
"warehouse": "_Test Warehouse - _TC"}, "ordered_qty")), 0.0)
|
||||||
|
|
||||||
def test_make_purchase_invocie(self):
|
def test_make_purchase_invocie(self):
|
||||||
from buying.doctype.purchase_order.purchase_order import make_purchase_invoice
|
from buying.doctype.purchase_order.purchase_order import make_purchase_invoice
|
||||||
|
@ -9,6 +9,7 @@ cur_frm.cscript.other_fname = "purchase_tax_details";
|
|||||||
// attach required files
|
// attach required files
|
||||||
wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js');
|
wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js');
|
||||||
wn.require('app/buying/doctype/purchase_common/purchase_common.js');
|
wn.require('app/buying/doctype/purchase_common/purchase_common.js');
|
||||||
|
wn.require('app/accounts/doctype/sales_invoice/pos.js');
|
||||||
|
|
||||||
erpnext.buying.SupplierQuotationController = erpnext.buying.BuyingController.extend({
|
erpnext.buying.SupplierQuotationController = erpnext.buying.BuyingController.extend({
|
||||||
refresh: function() {
|
refresh: function() {
|
||||||
|
@ -65,7 +65,7 @@ def _get_basic_details(args, item_bean):
|
|||||||
|
|
||||||
out = webnotes._dict({
|
out = webnotes._dict({
|
||||||
"description": item.description_html or item.description,
|
"description": item.description_html or item.description,
|
||||||
"qty": 0.0,
|
"qty": 1.0,
|
||||||
"uom": item.stock_uom,
|
"uom": item.stock_uom,
|
||||||
"conversion_factor": 1.0,
|
"conversion_factor": 1.0,
|
||||||
"warehouse": args.warehouse or item.default_warehouse,
|
"warehouse": args.warehouse or item.default_warehouse,
|
||||||
|
@ -17,5 +17,28 @@ To make a Stock Reconciliation, go to:
|
|||||||
|
|
||||||
and follow the steps mentioned on the page.
|
and follow the steps mentioned on the page.
|
||||||
|
|
||||||
![Stock Reconciliation](img/stock-reconciliation1.png)
|
#### Step 1: Download Template
|
||||||
|
|
||||||
|
|
||||||
|
![Stock Reconciliation](img/stock-reconciliation-1.png)
|
||||||
|
|
||||||
|
#### Step 2: Enter Data in csv file.
|
||||||
|
|
||||||
|
|
||||||
|
![Stock Reconciliation](img/stock-reconciliation-csv-1.png)
|
||||||
|
|
||||||
|
The csv format is case-sensitive. Thus special care should be taken to avoid spelling errors or wrong names. Even if you do not list some quantities or valuation rates, the file will still process the data.
|
||||||
|
|
||||||
|
#### Step 3: Upload the csv file with data
|
||||||
|
|
||||||
|
![Stock Reconciliation](img/stock-reconciliation-2.png)
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
#### Step 4: Attach the uploaded file.
|
||||||
|
|
||||||
|
![Stock Reconciliation](img/stock-reconciliation-3.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
After reviewing saved Reconciliation Data, submit the Stock Reconciliation. On successful submission, the data will be updated in the system. To check the uploaded data go to Stock and view Stock Level Report.
|
@ -20,7 +20,15 @@ You can create a new Supplier via:
|
|||||||
|
|
||||||
> Tip: When you select a Supplier in any transaction, one Contact and Address gets pre-selected. This is the “Default Contact or Address”. So make sure you set your defaults correctly!
|
> Tip: When you select a Supplier in any transaction, one Contact and Address gets pre-selected. This is the “Default Contact or Address”. So make sure you set your defaults correctly!
|
||||||
|
|
||||||
|
### Integration with Accounts
|
||||||
|
|
||||||
|
In ERPNext, there is a separate Account record for each Supplier, of Each company.
|
||||||
|
|
||||||
|
When you create a new Supplier, ERPNext will automatically create an Account Ledger for the Supplier under “Accounts Receivable” in the Company set in the Supplier record.
|
||||||
|
|
||||||
|
> Advanced Tip: If you want to change the Account Group under which the Supplier Account is created, you can set it in the Company master.
|
||||||
|
|
||||||
|
If you want to create an Account in another Company, just change the Company value and “Save” the Supplier again.
|
||||||
|
|
||||||
|
|
||||||
> Buying > Contact > New Contact
|
> Buying > Contact > New Contact
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
"_label": "Supplier Type"
|
"_label": "Supplier Type"
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
A supplier may be distinguished from a contractor or subcontractor, who commonly adds specialized input to deliverables. A supplier is also known as a vendor. There are different types of suppliers based on their goods and products.
|
||||||
|
|
||||||
Based on what the suppliers supply, they are classified into different categories called Supplier Type.
|
ERPNext allows you to create your own categories of suppliers. These categories are known as Supplier Type. For Example, if your suppliers are mainly pharmaceutical companies and FMCG distributors, You can create a new Type for them and name them accordingly.
|
||||||
There can be different types of suppliers. You can create your own category of Supplier Type.
|
|
||||||
|
Based on what the suppliers supply, they are classified into different categories called Supplier Type. There can be different types of suppliers. You can create your own category of Supplier Type.
|
||||||
|
|
||||||
> Buying > Supplier Type > New Supplier Type
|
> Buying > Supplier Type > New Supplier Type
|
||||||
|
|
||||||
|
@ -85,6 +85,7 @@ Contents
|
|||||||
1. [Purchase Receipt](docs.user.stock.purchase_receipt.html)
|
1. [Purchase Receipt](docs.user.stock.purchase_receipt.html)
|
||||||
1. [Delivery Note](docs.user.stock.delivery_note.html)
|
1. [Delivery Note](docs.user.stock.delivery_note.html)
|
||||||
1. [Stock Entry / Material Transfer](docs.user.stock.stock_entry.html)
|
1. [Stock Entry / Material Transfer](docs.user.stock.stock_entry.html)
|
||||||
|
1. [Opening Stock](docs.user.accounts.opening_stock.html)
|
||||||
1. [Material Issue](docs.user.stock.material_issue.html)
|
1. [Material Issue](docs.user.stock.material_issue.html)
|
||||||
1. [Sales Return](docs.user.stock.sales_return.html)
|
1. [Sales Return](docs.user.stock.sales_return.html)
|
||||||
1. [Purchase Return](docs.user.stock.purchase_return.html)
|
1. [Purchase Return](docs.user.stock.purchase_return.html)
|
||||||
@ -100,7 +101,6 @@ Contents
|
|||||||
1. [Payment Entry](docs.user.accounts.payments.html)
|
1. [Payment Entry](docs.user.accounts.payments.html)
|
||||||
1. [Journal Voucher](docs.user.accounts.journal_voucher.html)
|
1. [Journal Voucher](docs.user.accounts.journal_voucher.html)
|
||||||
1. [Opening Entry](docs.user.accounts.opening_entry.html)
|
1. [Opening Entry](docs.user.accounts.opening_entry.html)
|
||||||
1. [Opening Stock](docs.user.accounts.opening_stock.html)
|
|
||||||
1. [Period Closing](docs.user.accounts.closing.html)
|
1. [Period Closing](docs.user.accounts.closing.html)
|
||||||
1. [Accounting Reports](docs.user.accounts.reports.html)
|
1. [Accounting Reports](docs.user.accounts.reports.html)
|
||||||
1. [Point of Sale (POS) Invoice](docs.user.accounts.pos.html)
|
1. [Point of Sale (POS) Invoice](docs.user.accounts.pos.html)
|
||||||
@ -151,3 +151,7 @@ Contents
|
|||||||
1. [Fiscal Year](docs.user.knowledge.fiscal_year.html)
|
1. [Fiscal Year](docs.user.knowledge.fiscal_year.html)
|
||||||
1. [Accounting Knowledge](docs.user.knowledge.accounting.html)
|
1. [Accounting Knowledge](docs.user.knowledge.accounting.html)
|
||||||
1. [Accounting Entries](docs.user.knowledge.accounting_entries.html)
|
1. [Accounting Entries](docs.user.knowledge.accounting_entries.html)
|
||||||
|
1. [DocType Definitions](docs.user.knowledge.doctype.html)
|
||||||
|
1. [Attachment and CSV Files](docs.user.knowledge.attachment_csv.html)
|
||||||
|
1. [Format using Markdown](docs.user.knowledge.markdown.html)
|
||||||
|
|
||||||
|
@ -22,34 +22,34 @@ Accounting Entries
|
|||||||
|
|
||||||
The balance of account can be increased / decreased, depending on account type and transaction type.
|
The balance of account can be increased / decreased, depending on account type and transaction type.
|
||||||
|
|
||||||
<table class="table table-bordered">
|
<table class="table table-bordered text-center">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="active">
|
<tr class="active">
|
||||||
<td style="text-align: center;">Account Type</td>
|
<td>Account Type</td>
|
||||||
<td style="text-align: center;">Transaction Type</td>
|
<td>Transaction Type</td>
|
||||||
<td style="text-align: center;">Effect on account balance</td>
|
<td>Effect on account balance</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="text-align: center;">Debit</td>
|
<td>Debit</td>
|
||||||
<td style="text-align: center;">Debit</td>
|
<td>Debit</td>
|
||||||
<td style="text-align: center;">Increases</td>
|
<td>Increases</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="text-align: center;">Debit</td>
|
<td>Debit</td>
|
||||||
<td style="text-align: center;">Credit</td>
|
<td>Credit</td>
|
||||||
<td style="text-align: center;">Decreases</td>
|
<td>Decreases</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="text-align: center;">Credit</td>
|
<td>Credit</td>
|
||||||
<td style="text-align: center;">Credit</td>
|
<td>Credit</td>
|
||||||
<td style="text-align: center;">Increases</td>
|
<td>Increases</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="text-align: center;">Credit</td>
|
<td>Credit</td>
|
||||||
<td style="text-align: center;">Debit</td>
|
<td>Debit</td>
|
||||||
<td style="text-align: center;">Decreases</td>
|
<td>Decreases</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@ -62,48 +62,48 @@ This means that every accounting entry has two parts, one debit and one credit a
|
|||||||
|
|
||||||
As the company will receive a payment from customer, the customer is considered as an asset account. For booking income, company maintains an account called "Sales of Laptop". So, entries will be done in the following manner:
|
As the company will receive a payment from customer, the customer is considered as an asset account. For booking income, company maintains an account called "Sales of Laptop". So, entries will be done in the following manner:
|
||||||
|
|
||||||
<table class="table table-bordered">
|
<table class="table table-bordered text-center">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="active">
|
<tr class="active">
|
||||||
<td style="text-align: center;">Account</td>
|
<td>Account</td>
|
||||||
<td style="text-align: center;">Debit</td>
|
<td>Debit</td>
|
||||||
<td style="text-align: center;">Credit</td>
|
<td>Credit</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="text-align: center;">Customer A</td>
|
<td>Customer A</td>
|
||||||
<td style="text-align: center;">50000</td>
|
<td>50000</td>
|
||||||
<td style="text-align: center;"></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="text-align: center;">Sales of Laptop</td>
|
<td>Sales of Laptop</td>
|
||||||
<td style="text-align: center;"></td>
|
<td></td>
|
||||||
<td style="text-align: center;">50000</td>
|
<td>50000</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
Customer A has made the payment, so customer balance should decreased based on the paid amount, which will increase "Cash" balance.
|
Customer A has made the payment, so customer balance should decreased based on the paid amount, which will increase "Cash" balance.
|
||||||
|
|
||||||
<table class="table table-bordered">
|
<table class="table table-bordered text-center">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="active">
|
<tr class="active">
|
||||||
<td style="text-align: center;">Account</td>
|
<td>Account</td>
|
||||||
<td style="text-align: center;">Debit</td>
|
<td>Debit</td>
|
||||||
<td style="text-align: center;">Credit</td>
|
<td>Credit</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="text-align: center;">Customer A</td>
|
<td>Customer A</td>
|
||||||
<td style="text-align: center;"></td>
|
<td></td>
|
||||||
<td style="text-align: center;">50000</td>
|
<td>50000</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="text-align: center;">Cash</td>
|
<td>Cash</td>
|
||||||
<td style="text-align: center;">50000</td>
|
<td>50000</td>
|
||||||
<td style="text-align: center;"></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
16
docs/user/knowledge/docs.user.knowledge.attachment_csv.md
Normal file
16
docs/user/knowledge/docs.user.knowledge.attachment_csv.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
{
|
||||||
|
"_label": "Attachement and CSV files"
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
#### How to Attach files?
|
||||||
|
|
||||||
|
When you open a form, on the right sidebar, you will see a section to attach files. Click on “Add” and select the file you want to attach. Click on “Upload” and you are set.
|
||||||
|
|
||||||
|
#### What is a CSV file?
|
||||||
|
|
||||||
|
A CSV (Comma Separated Value) file is a data file that you can upload into ERPNext to update various data. Any spreadsheet file from popular spreadsheet applications like MS Excel or Open Office Spreadsheet can be saved as a CSV file.
|
||||||
|
|
||||||
|
If you are using Microsoft Excel and using non-English characters, make sure to save your file encoded as UTF-8. For older versions of Excel, there is no clear way of saving as UTF-8. So save your file as a CSV, then open it in Notepad, and save as “UTF-8”. (Sorry blame Microsoft for this!)
|
||||||
|
|
267
docs/user/knowledge/docs.user.knowledge.doctype.md
Normal file
267
docs/user/knowledge/docs.user.knowledge.doctype.md
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
---
|
||||||
|
{
|
||||||
|
"_label": "DocType"
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ERPNext is a based on a “metadata” (data about data) framework that helps define all the different types of documents in the system. The basic building block of ERPNext is a DocType.
|
||||||
|
|
||||||
|
A DocType represents both a table in the database and a form from which a user can enter data.
|
||||||
|
|
||||||
|
Many DocTypes are single tables, but some work in groups. For example, Quotation has a “Quotation” DocType and a “Quotation Item” doctype for the Items table, among others. DocTypes contain a collection of fields called DocFields that form the basis of the columns in the database and the layout of the form.
|
||||||
|
|
||||||
|
<table class="table table-bordered text-left">
|
||||||
|
<thead>
|
||||||
|
<tr class="active">
|
||||||
|
<td width="30%">Column</td>
|
||||||
|
<td>Description</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Name</td>
|
||||||
|
<td>Name of the record</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Owner</td>
|
||||||
|
<td>Creator and Owner of the record</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Created on</td>
|
||||||
|
<td>Date and Time of Creation</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Modified On </td>
|
||||||
|
<td>Date and Time of Modification</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Docstatus</td>
|
||||||
|
<td>Status of the record<br>
|
||||||
|
0 = Saved/Draft<br>
|
||||||
|
1 = Submitted<br>
|
||||||
|
2 = Cancelled/Deleted
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Parent</td>
|
||||||
|
<td>Name of the Parent</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Parent Type</td>
|
||||||
|
<td>Type of Parent</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Parent Field</td>
|
||||||
|
<td>Specifying the relationship with the parent (there can be multiple child relationships with the same DocType).</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Index(idx)</td>
|
||||||
|
<td>Index (sequence) of the record in the child table.</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
#### Single DocType
|
||||||
|
|
||||||
|
There are a certain type of DocTypes that are “Single”, i.e. they have no table associated and have only one record of its fields. DocTypes such as Global Defaults, Production Planning Tool are “Single” DocTypes.
|
||||||
|
|
||||||
|
#### Field Columns
|
||||||
|
|
||||||
|
In the fields table, there are many columns, here is an explanation of the columns of the field table.
|
||||||
|
|
||||||
|
<table class="table table-bordered text-left">
|
||||||
|
<thead>
|
||||||
|
<tr class="active">
|
||||||
|
<td width="30%">Column</td>
|
||||||
|
<td>Description</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Label</td>
|
||||||
|
<td>Field Label (that appears in the form).</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Type</td>
|
||||||
|
<td>Field Type</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Name</td>
|
||||||
|
<td>Column name in the database, must be code friendly with no white spaces, special characters and capital letters.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>options</td>
|
||||||
|
<td>Field settings:<br>
|
||||||
|
For Select: List of options (each on a new line).<br>
|
||||||
|
For Link: DocType that is “linked”.<br>
|
||||||
|
For HTML: HTML Content
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Perm Level</td>
|
||||||
|
<td>Permission level (number) of the field. You can group fields by numbers, called levels, and apply rules on the levels.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Width</td>
|
||||||
|
<td>Width of the field (in pixels) - useful for “Table” types.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Reqd</td>
|
||||||
|
<td>Checked if field is mandatory (required).</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>In Filter</td>
|
||||||
|
<td>Checked if field appears as a standard filter in old style reports.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Hidden</td>
|
||||||
|
<td>Checked if field is hidden.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Print Hide</td>
|
||||||
|
<td>Checked if field is hidden in Print Formats.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Report Hide</td>
|
||||||
|
<td>Checked if field is hidden in old style reports.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Allow on Submit</td>
|
||||||
|
<td>Checked if this field can be edited after the document is “Submitted”.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Depends On</td>
|
||||||
|
<td>The fieldname of the field that will decide whether this field will be shown or hidden. It is useful to hide un-necessary fields.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Description</td>
|
||||||
|
<td>Description of the field</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Default</td>
|
||||||
|
<td>Default value when a new record is created.<br>
|
||||||
|
Note: “user” will set the current user as default and “today” will set today’s date (if the field is a Date field).</td>
|
||||||
|
</tr>
|
||||||
|
<tbody>
|
||||||
|
<table>
|
||||||
|
|
||||||
|
#### Field Types and Options
|
||||||
|
|
||||||
|
Here is a list of the different types of fields used to make / customize forms in ERPNext.
|
||||||
|
|
||||||
|
<table class="table table-bordered text-left">
|
||||||
|
<thead>
|
||||||
|
<tr class="active">
|
||||||
|
<td width="30%">Type</td>
|
||||||
|
<td>Description</td>
|
||||||
|
<td>Options/Setting</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Data</td>
|
||||||
|
<td>Single line text field with 180 characters</td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Select</td>
|
||||||
|
<td>Select from a pre-determined items in a drop-down.</td>
|
||||||
|
<td>The “Options” contains the drop-down items, each on a new row</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Link</td>
|
||||||
|
<td>Link an existing document / record</td>
|
||||||
|
<td>Options contains the name of the type of document (DocType)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Currency</td>
|
||||||
|
<td>Number with 2 decimal places, that will be shown separated by commas for thousands etc. in Print.</td>
|
||||||
|
<td>e.g. 1,000,000.00</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Float</td>
|
||||||
|
<td>Number with 6 decimal places.</td>
|
||||||
|
<td>e.g. 3.141593</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Int</td>
|
||||||
|
<td>Integer (no decimals)</td>
|
||||||
|
<td>e.g. 100</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Date</td>
|
||||||
|
<td>Date</td>
|
||||||
|
<td>Format can be selected in Global Defaults</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Time</td>
|
||||||
|
<td>Time</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="3" class="active">Text</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Text</td>
|
||||||
|
<td>Multi-line text box without formatting features</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Text editor</td>
|
||||||
|
<td>Multi-line text box with formatting toolbar etc</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Code</td>
|
||||||
|
<td>Code Editor</td>
|
||||||
|
<td>Options can include the type of language for syntax formatting.
|
||||||
|
Eg JS / Python / HTML</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="3" class="active">Table (Grid)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Table</td>
|
||||||
|
<td>Table of child items linked to the record.</td>
|
||||||
|
<td>Options contains the name of the DocType of the child table. For example “Sales Invoice Item” for “Sales Invoice”</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="3" class="active">Layout</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Section Break</td>
|
||||||
|
<td>Break into a new horizontal section.</td>
|
||||||
|
<td>The layout in ERPNext is evaluated from top to bottom.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Column Break</td>
|
||||||
|
<td>Break into a new vertical column.</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>HTML</td>
|
||||||
|
<td>Add a static text / help / link etc in HTML</td>
|
||||||
|
<td>Options contains the HTML.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="3" class="active">Action</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Button</td>
|
||||||
|
<td>Button</td>
|
||||||
|
<td>[for developers only]</td>
|
||||||
|
</tr>
|
||||||
|
<tbody>
|
||||||
|
<table>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
84
docs/user/knowledge/docs.user.knowledge.markdown.md
Normal file
84
docs/user/knowledge/docs.user.knowledge.markdown.md
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
---
|
||||||
|
{
|
||||||
|
"_label": "Format Using Markdown"
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
Markdown is a simple way of writing text to format your content. Markdown allows you easy ways to format.
|
||||||
|
|
||||||
|
1. Headings (h1 (largest), h2, h3, h4 and so on)
|
||||||
|
1. Paragraphs
|
||||||
|
1. Lists (numbered or bulleted)
|
||||||
|
1. Hyper links (links to other pages)
|
||||||
|
1. Images
|
||||||
|
1. Code
|
||||||
|
1. Embed HTML (HTML tags within your text)
|
||||||
|
|
||||||
|
#### Headings
|
||||||
|
|
||||||
|
Headings are specified by adding a `#` (hash) at the beginning of the line. The more the number of hashes, the smaller the heading:
|
||||||
|
|
||||||
|
# This is a large heading.
|
||||||
|
|
||||||
|
### This is a smaller heading.
|
||||||
|
|
||||||
|
#### Paragraphs
|
||||||
|
|
||||||
|
To start a new paragraph, just make sure that there is an empty line at the beginning and end of the paragraph.
|
||||||
|
|
||||||
|
To format text as **bold** or with _italics_ format as follows:
|
||||||
|
|
||||||
|
**This text** is **bold** and _this one_ is with _italics_
|
||||||
|
|
||||||
|
#### Lists
|
||||||
|
|
||||||
|
To define numbered lists, start your link with a number and a dot (.) and ensure there is a blank line before and after the list. The numbers are automatically generated so it does not matter what number you put:
|
||||||
|
|
||||||
|
1. list 1st item
|
||||||
|
1. second item
|
||||||
|
1. and so on
|
||||||
|
1. and so forth
|
||||||
|
|
||||||
|
To define bulleted lists, start your items with a hyphen (-)
|
||||||
|
|
||||||
|
- item 1
|
||||||
|
- item 2
|
||||||
|
- item 3
|
||||||
|
|
||||||
|
To nest lists within one another, put four spaces to indent your inner list as follows:
|
||||||
|
|
||||||
|
1. item 1
|
||||||
|
1. item 2
|
||||||
|
- sub item 1
|
||||||
|
- sub item 2
|
||||||
|
1. item 3
|
||||||
|
|
||||||
|
#### Links (to other pages)
|
||||||
|
|
||||||
|
Links to other pages can be defined by adding your text in box brackets [] followed by the link in round brackets ()
|
||||||
|
|
||||||
|
[This is an external link](http://example.com)
|
||||||
|
[A link within the site](my-page.html)
|
||||||
|
|
||||||
|
#### Images
|
||||||
|
|
||||||
|
Images can be added by adding an exclamation ! before the link.
|
||||||
|
|
||||||
|
![A flower](files/flower.gif)
|
||||||
|
|
||||||
|
|
||||||
|
#### Code
|
||||||
|
|
||||||
|
To add a code block, just leave a blank line before and after the block and make sure all code line are indented by four spaces:
|
||||||
|
|
||||||
|
This is normal text
|
||||||
|
|
||||||
|
This is a code block
|
||||||
|
|
||||||
|
#### HTML
|
||||||
|
|
||||||
|
You can embed any kind of HTML tags within your code. Any content written within HTML tags will not be formatted.
|
||||||
|
|
||||||
|
[Detailed description of the markdown format](http://daringfireball.net/projects/markdown/syntax)
|
||||||
|
|
||||||
|
|
@ -4,8 +4,12 @@
|
|||||||
"_toc": [
|
"_toc": [
|
||||||
"docs.user.knowledge.fiscal_year",
|
"docs.user.knowledge.fiscal_year",
|
||||||
"docs.user.knowledge.accounting",
|
"docs.user.knowledge.accounting",
|
||||||
"docs.user.knowledge.accounting_entries"
|
"docs.user.knowledge.accounting_entries",
|
||||||
|
"docs.user.knowledge.doctype",
|
||||||
|
"docs.user.knowledge.attachment_csv",
|
||||||
|
"docs.user.knowledge.markdown"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
Knowledge Library contains definitions and explanations of various management concepts. This page is created for users who wish to elaborate their conceptual knowledge.
|
Knowledge Library contains definitions and explanations of various management concepts. This page is created for users who wish to elaborate their conceptual knowledge.
|
||||||
|
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
"_title_image": "img/customers.png"
|
"_title_image": "img/customers.png"
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
You can either directly create your Customers via
|
A customer, who is sometimes known as a client, buyer, or purchaser is the one who receives goods, services, products, or ideas, from a seller for a monetary consideration. A customer can also receive goods or services from a vendor or a supplier for other valuable considerations.
|
||||||
|
|
||||||
|
You can either directly create your Customers via
|
||||||
|
|
||||||
> Selling > Customer
|
> Selling > Customer
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"_label": "Data Import Tool"
|
"_label": "Data Import Tool"
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
The Data Import Tool is a great way to upload (or edit) bulk data, specially master data, into the system. To start the tool go to:
|
The Data Import Tool is a great way to upload (or edit) bulk data, specially master data, into the system.
|
||||||
|
|
||||||
To Open the data import tool, you either go to Setup or go to the Transaction you want to Import. If Data Import is allowed, you will see an Import Button:
|
To Open the data import tool, you either go to Setup or go to the Transaction you want to Import. If Data Import is allowed, you will see an Import Button:
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ The tool has two sections, one to download a template and the second to upload t
|
|||||||
|
|
||||||
### 1. Downloading The Template
|
### 1. Downloading The Template
|
||||||
|
|
||||||
Data in ERPNext is stored in tables, much like a spreadsheet with columns and rows of data. Each entity in ERPNext can have multiple child tables associated with it too. The child tables are linked to the parent tables and are implemented where are multiple values for any property. For example an Item can have multiple prices, An Invoice has multiple Items and so on.
|
Data in ERPNext is stored in tables, much like a spreadsheet with columns and rows of data. Each entity in ERPNext can have multiple child tables associated with it too. The child tables are linked to the parent tables and are implemented where there are multiple values for any property. For example an Item can have multiple prices, An Invoice has multiple Items and so on.
|
||||||
|
|
||||||
You can import each table separately, or all at a time. In the child table, you must mention the parent of the row in the “parent” column so that ERPNext knows which Item’s price or tax you are trying to set if you are importing separately.
|
You can import each table separately, or all at a time. In the child table, you must mention the parent of the row in the “parent” column so that ERPNext knows which Item’s price or tax you are trying to set if you are importing separately.
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ Then export your template or save it as a **Comma Separated Values** (CSV) file.
|
|||||||
|
|
||||||
### 3. Upload the .csv File
|
### 3. Upload the .csv File
|
||||||
|
|
||||||
Finally attach the .csv file in the section section click on the "Upload and Import" button.
|
Finally attach the .csv file in the section. Click on the "Upload and Import" button.
|
||||||
|
|
||||||
![Attach and Upload](img/import-5.png)
|
![Attach and Upload](img/import-5.png)
|
||||||
|
|
||||||
|
@ -27,11 +27,7 @@ To upload an image for your icon that will appear in all transactions, save the
|
|||||||
|
|
||||||
![Item Properties](img/item-add-image.png)
|
![Item Properties](img/item-add-image.png)
|
||||||
|
|
||||||
### Item Pricing
|
### Inventory : Warehouse and Stock Setting
|
||||||
|
|
||||||
Item Price and Price Lists: ERPNext lets you maintain multiple selling prices for an Item using Price Lists. A Price List is a place where different rate plans can be stored. It’s a name you can give to a set of Item prices. In case you have different zones (based on the shipping costs), for different currencies etc, you can maintain different Price Lists. A Price List is formed when you create different Item Prices. To import Item Price see [Importing Data](docs.user.data_import.md).
|
|
||||||
|
|
||||||
## Inventory : Warehouse and Stock Setting
|
|
||||||
|
|
||||||
In ERPNext, you can select different type of Warehouses to stock your different Items. This can be selected based on Item types. It could be Fixed Asset Item, Stock Item or even Manufacturing Item.
|
In ERPNext, you can select different type of Warehouses to stock your different Items. This can be selected based on Item types. It could be Fixed Asset Item, Stock Item or even Manufacturing Item.
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
"docs.user.stock.purchase_receipt",
|
"docs.user.stock.purchase_receipt",
|
||||||
"docs.user.stock.delivery_note",
|
"docs.user.stock.delivery_note",
|
||||||
"docs.user.stock.stock_entry",
|
"docs.user.stock.stock_entry",
|
||||||
|
"docs.user.stock.opening_stock",
|
||||||
"docs.user.stock.material_issue",
|
"docs.user.stock.material_issue",
|
||||||
"docs.user.stock.sales_return",
|
"docs.user.stock.sales_return",
|
||||||
"docs.user.stock.purchase_return",
|
"docs.user.stock.purchase_return",
|
||||||
|
@ -14,6 +14,7 @@ erpnext.hr.EmployeeController = wn.ui.form.Controller.extend({
|
|||||||
onload: function() {
|
onload: function() {
|
||||||
this.frm.toggle_display(["esic_card_no", "gratuity_lic_id", "pan_number", "pf_number"],
|
this.frm.toggle_display(["esic_card_no", "gratuity_lic_id", "pan_number", "pf_number"],
|
||||||
wn.control_panel.country==="India");
|
wn.control_panel.country==="India");
|
||||||
|
if(this.frm.doc.__islocal) this.frm.set_value("employee_name", "");
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function() {
|
refresh: function() {
|
||||||
|
@ -58,11 +58,12 @@ cur_frm.cscript.onload = function(doc,cdt,cdn) {
|
|||||||
query:"controllers.queries.employee_query"
|
query:"controllers.queries.employee_query"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var exp_approver = doc.exp_approver;
|
||||||
return cur_frm.call({
|
return cur_frm.call({
|
||||||
method:"hr.utils.get_expense_approver_list",
|
method:"hr.utils.get_expense_approver_list",
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
cur_frm.set_df_property("exp_approver", "options", r.message);
|
cur_frm.set_df_property("exp_approver", "options", r.message);
|
||||||
|
if(exp_approver) cur_frm.set_value("exp_approver", exp_approver);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -79,26 +80,39 @@ cur_frm.cscript.clear_sanctioned = function(doc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript.refresh = function(doc,cdt,cdn){
|
cur_frm.cscript.refresh = function(doc,cdt,cdn){
|
||||||
|
cur_frm.cscript.set_help(doc);
|
||||||
|
|
||||||
|
if(!doc.__islocal) {
|
||||||
|
cur_frm.toggle_enable("exp_approver", (doc.owner==user && doc.approval_status=="Draft"));
|
||||||
|
cur_frm.toggle_enable("approval_status", (doc.exp_approver==user && doc.docstatus==0));
|
||||||
|
|
||||||
|
if(!doc.__islocal && user!=doc.exp_approver && cur_frm.frm_head.appframe.buttons.Submit)
|
||||||
|
cur_frm.frm_head.appframe.buttons.Submit.toggle(false);
|
||||||
|
|
||||||
|
if(doc.docstatus==0 && doc.exp_approver==user && doc.approval_status=="Approved")
|
||||||
|
cur_frm.savesubmit();
|
||||||
|
|
||||||
|
if(doc.docstatus==1 && wn.model.can_create("Journal Voucher"))
|
||||||
|
cur_frm.add_custom_button("Make Bank Voucher", cur_frm.cscript.make_bank_voucher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_frm.cscript.set_help = function(doc) {
|
||||||
cur_frm.set_intro("");
|
cur_frm.set_intro("");
|
||||||
if(doc.__islocal && !in_list(user_roles, "HR User")) {
|
if(doc.__islocal && !in_list(user_roles, "HR User")) {
|
||||||
cur_frm.set_intro("Fill the form and save it")
|
cur_frm.set_intro("Fill the form and save it")
|
||||||
} else {
|
} else {
|
||||||
if(doc.docstatus==0 && doc.approval_status=="Draft") {
|
if(doc.docstatus==0 && doc.approval_status=="Draft") {
|
||||||
if(user==doc.exp_approver) {
|
if(user==doc.exp_approver) {
|
||||||
cur_frm.set_intro("You are the Expense Approver for this record. Please Update the 'Status' and Save");
|
cur_frm.set_intro("You are the Expense Approver for this record. \
|
||||||
cur_frm.toggle_enable("approval_status", true);
|
Please Update the 'Status' and Save");
|
||||||
} else {
|
} else {
|
||||||
cur_frm.set_intro("Expense Claim is pending approval. Only the Expense Approver can update status.");
|
cur_frm.set_intro("Expense Claim is pending approval. \
|
||||||
cur_frm.toggle_enable("approval_status", false);
|
Only the Expense Approver can update status.");
|
||||||
if(!doc.__islocal && cur_frm.frm_head.appframe.buttons.Submit)
|
|
||||||
cur_frm.frm_head.appframe.buttons.Submit.toggle(false);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(doc.approval_status=="Approved") {
|
if(doc.approval_status=="Approved") {
|
||||||
cur_frm.set_intro("Expense Claim has been approved.");
|
cur_frm.set_intro("Expense Claim has been approved.");
|
||||||
if(doc.docstatus==0) cur_frm.savesubmit();
|
|
||||||
if(doc.docstatus==1) cur_frm.add_custom_button("Make Bank Voucher",
|
|
||||||
cur_frm.cscript.make_bank_voucher);
|
|
||||||
} else if(doc.approval_status=="Rejected") {
|
} else if(doc.approval_status=="Rejected") {
|
||||||
cur_frm.set_intro("Expense Claim has been rejected.");
|
cur_frm.set_intro("Expense Claim has been rejected.");
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ cur_frm.cscript.onload = function(doc, dt, dn) {
|
|||||||
cur_frm.set_value("status", "Open");
|
cur_frm.set_value("status", "Open");
|
||||||
cur_frm.cscript.calculate_total_days(doc, dt, dn);
|
cur_frm.cscript.calculate_total_days(doc, dt, dn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var leave_approver = doc.leave_approver;
|
||||||
return cur_frm.call({
|
return cur_frm.call({
|
||||||
method:"hr.utils.get_leave_approver_list",
|
method:"hr.utils.get_leave_approver_list",
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
@ -17,6 +19,7 @@ cur_frm.cscript.onload = function(doc, dt, dn) {
|
|||||||
function(profile) {
|
function(profile) {
|
||||||
return {value: profile, label: wn.user_info(profile).fullname};
|
return {value: profile, label: wn.user_info(profile).fullname};
|
||||||
}));
|
}));
|
||||||
|
if(leave_approver) cur_frm.set_value("leave_approver", leave_approver);
|
||||||
cur_frm.cscript.get_leave_balance(cur_frm.doc);
|
cur_frm.cscript.get_leave_balance(cur_frm.doc);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -6,6 +6,7 @@ import webnotes
|
|||||||
|
|
||||||
def execute():
|
def execute():
|
||||||
webnotes.reload_doc("selling", "doctype", "shopping_cart_price_list")
|
webnotes.reload_doc("selling", "doctype", "shopping_cart_price_list")
|
||||||
|
webnotes.reload_doc("setup", "doctype", "item_price")
|
||||||
|
|
||||||
for t in [
|
for t in [
|
||||||
("Supplier Quotation", "price_list_name", "buying_price_list"),
|
("Supplier Quotation", "price_list_name", "buying_price_list"),
|
||||||
|
0
patches/october_2013/__init__.py
Normal file
0
patches/october_2013/__init__.py
Normal file
13
patches/october_2013/fix_is_cancelled_in_sle.py
Normal file
13
patches/october_2013/fix_is_cancelled_in_sle.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import webnotes
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
webnotes.conn.sql("""update `tabStock Ledger Entry` set is_cancelled = 'No'
|
||||||
|
where ifnull(is_cancelled, '') = ''""")
|
||||||
|
|
||||||
|
webnotes.conn.sql("""update tabBin b set b.stock_uom =
|
||||||
|
(select i.stock_uom from tabItem i where i.name = b.item_code)
|
||||||
|
where b.creation>='2013-09-01'""")
|
@ -218,4 +218,6 @@ patch_list = [
|
|||||||
"execute:webnotes.bean('Style Settings').save() #2013-09-19",
|
"execute:webnotes.bean('Style Settings').save() #2013-09-19",
|
||||||
"execute:webnotes.conn.set_value('Accounts Settings', None, 'frozen_accounts_modifier', 'Accounts Manager') # 2013-09-24",
|
"execute:webnotes.conn.set_value('Accounts Settings', None, 'frozen_accounts_modifier', 'Accounts Manager') # 2013-09-24",
|
||||||
"patches.september_2013.p04_unsubmit_serial_nos",
|
"patches.september_2013.p04_unsubmit_serial_nos",
|
||||||
|
"patches.september_2013.p05_fix_customer_in_pos",
|
||||||
|
"patches.october_2013.fix_is_cancelled_in_sle",
|
||||||
]
|
]
|
22
patches/september_2013/p05_fix_customer_in_pos.py
Normal file
22
patches/september_2013/p05_fix_customer_in_pos.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import webnotes
|
||||||
|
def execute():
|
||||||
|
si_list = webnotes.conn.sql("""select name, debit_to from `tabSales Invoice`
|
||||||
|
where ifnull(is_pos, 1)=1 and docstatus=1 and modified > '2013-09-03'""", as_dict=1)
|
||||||
|
|
||||||
|
for si in si_list:
|
||||||
|
if not webnotes.conn.get_value("GL Entry", {"voucher_type": "Sales Invoice",
|
||||||
|
"voucher_no": si.name, "account": si.debit_to}):
|
||||||
|
debit_to = webnotes.conn.sql("""select account from `tabGL Entry` gle
|
||||||
|
where voucher_type='Sales Invoice' and voucher_no=%s
|
||||||
|
and (select master_type from tabAccount where name=gle.account)='Customer'
|
||||||
|
""", si.name)
|
||||||
|
if debit_to:
|
||||||
|
si_bean = webnotes.bean("Sales Invoice", si.name)
|
||||||
|
si_bean.doc.debit_to = debit_to[0][0]
|
||||||
|
si_bean.doc.customer = None
|
||||||
|
si_bean.run_method("set_customer_defaults")
|
||||||
|
si_bean.update_after_submit()
|
@ -9,7 +9,6 @@ $(document).ready(function() {
|
|||||||
type: "POST",
|
type: "POST",
|
||||||
method: "selling.utils.cart.get_cart_quotation",
|
method: "selling.utils.cart.get_cart_quotation",
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
console.log(r);
|
|
||||||
$("#cart-container").removeClass("hide");
|
$("#cart-container").removeClass("hide");
|
||||||
$(".progress").remove();
|
$(".progress").remove();
|
||||||
if(r.exc) {
|
if(r.exc) {
|
||||||
@ -126,8 +125,8 @@ $.extend(erpnext.cart, {
|
|||||||
},
|
},
|
||||||
|
|
||||||
render_item_row: function($cart_items, doc) {
|
render_item_row: function($cart_items, doc) {
|
||||||
doc.image_html = doc.image ?
|
doc.image_html = doc.website_image ?
|
||||||
'<div style="height: 120px; overflow: hidden;"><img src="' + doc.image + '" /></div>' :
|
'<div style="height: 120px; overflow: hidden;"><img src="' + doc.website_image + '" /></div>' :
|
||||||
'{% include "app/stock/doctype/item/templates/includes/product_missing_image.html" %}';
|
'{% include "app/stock/doctype/item/templates/includes/product_missing_image.html" %}';
|
||||||
|
|
||||||
if(doc.description === doc.item_name) doc.description = "";
|
if(doc.description === doc.item_name) doc.description = "";
|
||||||
|
@ -9,4 +9,6 @@ erpnext.projects.TimeLog = wn.ui.form.Controller.extend({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
cur_frm.cscript = new erpnext.projects.TimeLog({frm: cur_frm});
|
cur_frm.cscript = new erpnext.projects.TimeLog({frm: cur_frm});
|
||||||
|
|
||||||
|
cur_frm.add_fetch('task','project','project');
|
@ -29,4 +29,21 @@ span, div, td, input, textarea, button, select {
|
|||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
margin: -10px auto;
|
margin: -10px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pos */
|
||||||
|
.pos-item {
|
||||||
|
height: 200px;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
padding-left: 5px !important;
|
||||||
|
padding-right: 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pos-bill {
|
||||||
|
padding: 20px 5px;
|
||||||
|
font-family: Monospace;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
|
||||||
|
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
|
||||||
}
|
}
|
@ -29,6 +29,8 @@ erpnext.StockGridReport = wn.views.TreeGridReport.extend({
|
|||||||
|
|
||||||
if(add_qty)
|
if(add_qty)
|
||||||
wh.fifo_stack.push([add_qty, sl.incoming_rate, sl.posting_date]);
|
wh.fifo_stack.push([add_qty, sl.incoming_rate, sl.posting_date]);
|
||||||
|
|
||||||
|
if(sl.serial_no) value_diff = this.get_serialized_value_diff(sl);
|
||||||
} else {
|
} else {
|
||||||
// outgoing
|
// outgoing
|
||||||
if(sl.serial_no) {
|
if(sl.serial_no) {
|
||||||
@ -98,7 +100,7 @@ erpnext.StockGridReport = wn.views.TreeGridReport.extend({
|
|||||||
|
|
||||||
$.each(sl.serial_no.trim().split("\n"), function(i, sr) {
|
$.each(sl.serial_no.trim().split("\n"), function(i, sr) {
|
||||||
if(sr) {
|
if(sr) {
|
||||||
value_diff += flt(me.serialized_buying_rates[sr.trim()]);
|
value_diff += flt(me.serialized_buying_rates[sr.trim().toLowerCase()]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -112,7 +114,7 @@ erpnext.StockGridReport = wn.views.TreeGridReport.extend({
|
|||||||
if(sle.qty > 0 && sle.serial_no) {
|
if(sle.qty > 0 && sle.serial_no) {
|
||||||
$.each(sle.serial_no.trim().split("\n"), function(i, sr) {
|
$.each(sle.serial_no.trim().split("\n"), function(i, sr) {
|
||||||
if(sr && sle.incoming_rate !== undefined) {
|
if(sr && sle.incoming_rate !== undefined) {
|
||||||
serialized_buying_rates[sr.trim()] = flt(sle.incoming_rate);
|
serialized_buying_rates[sr.trim().toLowerCase()] = flt(sle.incoming_rate);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,56 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
|||||||
erpnext.hide_company();
|
erpnext.hide_company();
|
||||||
this.show_item_wise_taxes();
|
this.show_item_wise_taxes();
|
||||||
this.set_dynamic_labels();
|
this.set_dynamic_labels();
|
||||||
|
|
||||||
|
// Show POS button only if it is enabled from features setup
|
||||||
|
if(cint(sys_defaults.fs_pos_view)===1 && this.frm.doctype!="Material Request")
|
||||||
|
this.pos_btn();
|
||||||
|
},
|
||||||
|
|
||||||
|
pos_btn: function() {
|
||||||
|
if(this.$pos_btn)
|
||||||
|
this.$pos_btn.remove();
|
||||||
|
|
||||||
|
if(!this.pos_active) {
|
||||||
|
var btn_label = wn._("POS View"),
|
||||||
|
icon = "icon-desktop";
|
||||||
|
} else {
|
||||||
|
var btn_label = wn._(this.frm.doctype) + wn._(" View"),
|
||||||
|
icon = "icon-file-text";
|
||||||
|
}
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
this.$pos_btn = this.frm.add_custom_button(btn_label, function() {
|
||||||
|
me.toggle_pos();
|
||||||
|
me.pos_btn();
|
||||||
|
}, icon);
|
||||||
|
},
|
||||||
|
|
||||||
|
toggle_pos: function(show) {
|
||||||
|
// Check whether it is Selling or Buying cycle
|
||||||
|
var price_list = wn.meta.has_field(cur_frm.doc.doctype, "selling_price_list") ?
|
||||||
|
this.frm.doc.selling_price_list : this.frm.doc.buying_price_list;
|
||||||
|
|
||||||
|
if (!price_list)
|
||||||
|
msgprint(wn._("Please select Price List"))
|
||||||
|
else {
|
||||||
|
if((show===true && this.pos_active) || (show===false && !this.pos_active)) return;
|
||||||
|
|
||||||
|
// make pos
|
||||||
|
if(!this.frm.pos) {
|
||||||
|
this.frm.layout.add_view("pos");
|
||||||
|
this.frm.pos = new erpnext.POS(this.frm.layout.views.pos, this.frm);
|
||||||
|
}
|
||||||
|
|
||||||
|
// toggle view
|
||||||
|
this.frm.layout.set_view(this.pos_active ? "" : "pos");
|
||||||
|
this.pos_active = !this.pos_active;
|
||||||
|
|
||||||
|
// refresh
|
||||||
|
if(this.pos_active)
|
||||||
|
this.frm.pos.refresh();
|
||||||
|
this.frm.refresh();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
validate: function() {
|
validate: function() {
|
||||||
@ -182,6 +232,29 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
|||||||
tax_rate: function(doc, cdt, cdn) {
|
tax_rate: function(doc, cdt, cdn) {
|
||||||
this.calculate_taxes_and_totals();
|
this.calculate_taxes_and_totals();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// serial_no: function(doc, cdt, cdn) {
|
||||||
|
// var me = this;
|
||||||
|
// var item = wn.model.get_doc(cdt, cdn);
|
||||||
|
// if (!item.item_code) {
|
||||||
|
// wn.call({
|
||||||
|
// method: 'accounts.doctype.sales_invoice.pos.get_item_from_serial_no',
|
||||||
|
// args: {serial_no: this.serial_no.$input.val()},
|
||||||
|
// callback: function(r) {
|
||||||
|
// if (r.message) {
|
||||||
|
// var item_code = r.message[0].item_code;
|
||||||
|
// var child = wn.model.add_child(me.frm.doc, this.frm.doctype + " Item",
|
||||||
|
// this.frm.cscript.fname);
|
||||||
|
// child.item_code = item_code;
|
||||||
|
// me.frm.cscript.item_code(me.frm.doc, child.doctype, child.name);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// msgprint(wn._("Invalid Serial No."));
|
||||||
|
// me.refresh();
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
|
||||||
row_id: function(doc, cdt, cdn) {
|
row_id: function(doc, cdt, cdn) {
|
||||||
var tax = wn.model.get_doc(cdt, cdn);
|
var tax = wn.model.get_doc(cdt, cdn);
|
||||||
@ -418,10 +491,10 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
|||||||
(this.frm.doc.currency != company_currency && this.frm.doc.conversion_rate != 1.0)) :
|
(this.frm.doc.currency != company_currency && this.frm.doc.conversion_rate != 1.0)) :
|
||||||
false;
|
false;
|
||||||
|
|
||||||
// if(!valid_conversion_rate) {
|
if(!valid_conversion_rate) {
|
||||||
// wn.throw(wn._("Please enter valid") + " " + wn._(conversion_rate_label) +
|
wn.throw(wn._("Please enter valid") + " " + wn._(conversion_rate_label) +
|
||||||
// " 1 " + this.frm.doc.currency + " = [?] " + company_currency);
|
" 1 " + this.frm.doc.currency + " = [?] " + company_currency);
|
||||||
// }
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
calculate_taxes_and_totals: function() {
|
calculate_taxes_and_totals: function() {
|
||||||
|
@ -45,7 +45,7 @@ cur_frm.cscript.setup_dashboard = function(doc) {
|
|||||||
cur_frm.dashboard.reset(doc);
|
cur_frm.dashboard.reset(doc);
|
||||||
if(doc.__islocal)
|
if(doc.__islocal)
|
||||||
return;
|
return;
|
||||||
cur_frm.dashboard.set_headline('<span class="text-muted">Loading...</span>')
|
cur_frm.dashboard.set_headline('<span class="text-muted">'+ wn._('Loading...')+ '</span>')
|
||||||
|
|
||||||
cur_frm.dashboard.add_doctype_badge("Opportunity", "customer");
|
cur_frm.dashboard.add_doctype_badge("Opportunity", "customer");
|
||||||
cur_frm.dashboard.add_doctype_badge("Quotation", "customer");
|
cur_frm.dashboard.add_doctype_badge("Quotation", "customer");
|
||||||
@ -99,7 +99,7 @@ cur_frm.cscript.make_contact = function() {
|
|||||||
return "select name, first_name, last_name, email_id, phone, mobile_no, department, designation, is_primary_contact from tabContact where customer='"+cur_frm.docname+"' and docstatus != 2 order by is_primary_contact desc"
|
return "select name, first_name, last_name, email_id, phone, mobile_no, department, designation, is_primary_contact from tabContact where customer='"+cur_frm.docname+"' and docstatus != 2 order by is_primary_contact desc"
|
||||||
},
|
},
|
||||||
as_dict: 1,
|
as_dict: 1,
|
||||||
no_results_message: 'No contacts created',
|
no_results_message: wn._('No contacts created'),
|
||||||
render_row: cur_frm.cscript.render_contact_row,
|
render_row: cur_frm.cscript.render_contact_row,
|
||||||
});
|
});
|
||||||
// note: render_contact_row is defined in contact_control.js
|
// note: render_contact_row is defined in contact_control.js
|
||||||
@ -119,4 +119,4 @@ cur_frm.fields_dict.lead_name.get_query = function(doc,cdt,cdn) {
|
|||||||
return{
|
return{
|
||||||
query:"controllers.queries.lead_query"
|
query:"controllers.queries.lead_query"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,16 +33,7 @@ erpnext.LeadController = wn.ui.form.Controller.extend({
|
|||||||
var doc = this.frm.doc;
|
var doc = this.frm.doc;
|
||||||
erpnext.hide_naming_series();
|
erpnext.hide_naming_series();
|
||||||
this.frm.clear_custom_buttons();
|
this.frm.clear_custom_buttons();
|
||||||
|
|
||||||
this.frm.dashboard.reset(doc);
|
|
||||||
if(!doc.__islocal) {
|
|
||||||
if(doc.status=="Converted") {
|
|
||||||
this.frm.dashboard.set_headline_alert(wn._("Converted"), "alert-success", "icon-ok-sign");
|
|
||||||
} else {
|
|
||||||
this.frm.dashboard.set_headline_alert(wn._(doc.status), "alert-info", "icon-exclamation-sign");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.frm.__is_customer = this.frm.__is_customer || this.frm.doc.__is_customer;
|
this.frm.__is_customer = this.frm.__is_customer || this.frm.doc.__is_customer;
|
||||||
if(!this.frm.doc.__islocal && !this.frm.__is_customer) {
|
if(!this.frm.doc.__islocal && !this.frm.__is_customer) {
|
||||||
this.frm.add_custom_button("Create Customer", this.create_customer);
|
this.frm.add_custom_button("Create Customer", this.create_customer);
|
||||||
|
@ -125,6 +125,10 @@ def make_opportunity(source_name, target_doclist=None):
|
|||||||
"campaign_name": "campaign",
|
"campaign_name": "campaign",
|
||||||
"doctype": "enquiry_from",
|
"doctype": "enquiry_from",
|
||||||
"name": "lead",
|
"name": "lead",
|
||||||
|
"lead_name": "contact_display",
|
||||||
|
"company_name": "customer_name",
|
||||||
|
"email_id": "contact_email",
|
||||||
|
"mobile_no": "contact_mobile"
|
||||||
}
|
}
|
||||||
}}, target_doclist)
|
}}, target_doclist)
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-04-10 11:45:37",
|
"creation": "2013-04-10 11:45:37",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-10-02 14:24:34",
|
"modified": "2013-10-02 14:24:30",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -112,7 +112,7 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldname": "status",
|
"oldfieldname": "status",
|
||||||
"oldfieldtype": "Select",
|
"oldfieldtype": "Select",
|
||||||
"options": "\nOpen\nReplied\nAttempted to Contact\nContact in Future\nContacted\nInterested\nNot interested\nLead Lost\nConverted\nPassive",
|
"options": "\nOpen\nReplied\nAttempted to Contact\nContact in Future\nContacted\nOpportunity Made\nInterested\nNot interested\nLead Lost\nConverted\nPassive",
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 1
|
"search_index": 1
|
||||||
},
|
},
|
||||||
|
@ -53,6 +53,11 @@ erpnext.selling.Opportunity = wn.ui.form.Controller.extend({
|
|||||||
this.frm.set_query("contact_by", erpnext.queries.profile);
|
this.frm.set_query("contact_by", erpnext.queries.profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.frm.set_query("customer_address", function() {
|
||||||
|
if(me.frm.doc.lead) return {filters: { lead: me.frm.doc.lead } };
|
||||||
|
else if(me.frm.doc.customer) return {filters: { customer: me.frm.doc.customer } };
|
||||||
|
});
|
||||||
|
|
||||||
this.frm.set_query("item_code", "enquiry_details", function() {
|
this.frm.set_query("item_code", "enquiry_details", function() {
|
||||||
return {
|
return {
|
||||||
query: "controllers.queries.item_query",
|
query: "controllers.queries.item_query",
|
||||||
@ -63,7 +68,6 @@ erpnext.selling.Opportunity = wn.ui.form.Controller.extend({
|
|||||||
|
|
||||||
$.each([["lead", "lead"],
|
$.each([["lead", "lead"],
|
||||||
["customer", "customer"],
|
["customer", "customer"],
|
||||||
["customer_address", "customer_filter"],
|
|
||||||
["contact_person", "customer_filter"],
|
["contact_person", "customer_filter"],
|
||||||
["territory", "not_a_group_filter"]], function(i, opts) {
|
["territory", "not_a_group_filter"]], function(i, opts) {
|
||||||
me.frm.set_query(opts[0], erpnext.queries[opts[1]]);
|
me.frm.set_query(opts[0], erpnext.queries[opts[1]]);
|
||||||
@ -151,8 +155,14 @@ cur_frm.cscript.lead_cust_show = function(doc,cdt,cdn){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc,dt,dn) {
|
cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc, dt, dn) {
|
||||||
if(doc.customer) return get_server_fields('get_customer_address', JSON.stringify({customer: doc.customer, address: doc.customer_address, contact: doc.contact_person}),'', doc, dt, dn, 1);
|
args = {
|
||||||
|
address: doc.customer_address,
|
||||||
|
contact: doc.contact_person
|
||||||
|
}
|
||||||
|
if(doc.customer) args.update({customer: doc.customer});
|
||||||
|
|
||||||
|
return get_server_fields('get_customer_address', JSON.stringify(args),'', doc, dt, dn, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript.lead = function(doc, cdt, cdn) {
|
cur_frm.cscript.lead = function(doc, cdt, cdn) {
|
||||||
@ -163,7 +173,7 @@ cur_frm.cscript.lead = function(doc, cdt, cdn) {
|
|||||||
source_name: cur_frm.doc.lead
|
source_name: cur_frm.doc.lead
|
||||||
})
|
})
|
||||||
|
|
||||||
unhide_field(['customer_name', 'address_display','contact_mobile',
|
unhide_field(['customer_name', 'address_display','contact_mobile', 'customer_address',
|
||||||
'contact_email', 'territory']);
|
'contact_email', 'territory']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,12 +127,12 @@ class DocType(TransactionBase):
|
|||||||
|
|
||||||
from accounts.utils import validate_fiscal_year
|
from accounts.utils import validate_fiscal_year
|
||||||
validate_fiscal_year(self.doc.transaction_date, self.doc.fiscal_year, "Opportunity Date")
|
validate_fiscal_year(self.doc.transaction_date, self.doc.fiscal_year, "Opportunity Date")
|
||||||
|
self.doc.status = "Draft"
|
||||||
if not self.doc.status:
|
|
||||||
self.doc.status = "Draft"
|
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
webnotes.conn.set(self.doc, 'status', 'Submitted')
|
webnotes.conn.set(self.doc, 'status', 'Submitted')
|
||||||
|
if self.doc.lead and webnotes.conn.get_value("Lead", self.doc.lead, "status")!="Converted":
|
||||||
|
webnotes.conn.set_value("Lead", self.doc.lead, "status", "Opportunity Made")
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
chk = webnotes.conn.sql("select t1.name from `tabQuotation` t1, `tabQuotation Item` t2 where t2.parent = t1.name and t1.docstatus=1 and (t1.status!='Order Lost' and t1.status!='Cancelled') and t2.prevdoc_docname = %s",self.doc.name)
|
chk = webnotes.conn.sql("select t1.name from `tabQuotation` t1, `tabQuotation Item` t2 where t2.parent = t1.name and t1.docstatus=1 and (t1.status!='Order Lost' and t1.status!='Cancelled') and t2.prevdoc_docname = %s",self.doc.name)
|
||||||
@ -141,6 +141,14 @@ class DocType(TransactionBase):
|
|||||||
raise Exception
|
raise Exception
|
||||||
else:
|
else:
|
||||||
webnotes.conn.set(self.doc, 'status', 'Cancelled')
|
webnotes.conn.set(self.doc, 'status', 'Cancelled')
|
||||||
|
if self.doc.lead and webnotes.conn.get_value("Lead", self.doc.lead,
|
||||||
|
"status")!="Converted":
|
||||||
|
if webnotes.conn.get_value("Communication", {"parent": self.doc.lead}):
|
||||||
|
status = "Contacted"
|
||||||
|
else:
|
||||||
|
status = "Open"
|
||||||
|
|
||||||
|
webnotes.conn.set_value("Lead", self.doc.lead, "status", status)
|
||||||
|
|
||||||
def declare_enquiry_lost(self,arg):
|
def declare_enquiry_lost(self,arg):
|
||||||
chk = webnotes.conn.sql("select t1.name from `tabQuotation` t1, `tabQuotation Item` t2 where t2.parent = t1.name and t1.docstatus=1 and (t1.status!='Order Lost' and t1.status!='Cancelled') and t2.prevdoc_docname = %s",self.doc.name)
|
chk = webnotes.conn.sql("select t1.name from `tabQuotation` t1, `tabQuotation Item` t2 where t2.parent = t1.name and t1.docstatus=1 and (t1.status!='Order Lost' and t1.status!='Cancelled') and t2.prevdoc_docname = %s",self.doc.name)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-03-07 18:50:30",
|
"creation": "2013-03-07 18:50:30",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-10-02 14:24:35",
|
"modified": "2013-10-02 14:24:30",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -189,34 +189,16 @@
|
|||||||
"options": "icon-bullhorn",
|
"options": "icon-bullhorn",
|
||||||
"read_only": 0
|
"read_only": 0
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"doctype": "DocField",
|
|
||||||
"fieldname": "contact_person",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"in_filter": 1,
|
|
||||||
"label": "Contact Person",
|
|
||||||
"options": "Contact",
|
|
||||||
"print_hide": 1,
|
|
||||||
"read_only": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "customer_address",
|
"fieldname": "customer_address",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_filter": 1,
|
"in_filter": 1,
|
||||||
"label": "Customer Address",
|
"label": "Customer / Lead Address",
|
||||||
"options": "Address",
|
"options": "Address",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 0
|
"read_only": 0
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"doctype": "DocField",
|
|
||||||
"fieldname": "customer_name",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"label": "Customer Name",
|
|
||||||
"print_hide": 0,
|
|
||||||
"read_only": 1
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "address_display",
|
"fieldname": "address_display",
|
||||||
@ -227,12 +209,60 @@
|
|||||||
"oldfieldtype": "Small Text",
|
"oldfieldtype": "Small Text",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"description": "<a href=\"#Sales Browser/Territory\">To manage Territory, click here</a>",
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "territory",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_filter": 1,
|
||||||
|
"label": "Territory",
|
||||||
|
"options": "Territory",
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:doc.enquiry_from==\"Customer\"",
|
||||||
|
"description": "<a href=\"#Sales Browser/Customer Group\">To manage Territory, click here</a>",
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "customer_group",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"in_filter": 1,
|
||||||
|
"label": "Customer Group",
|
||||||
|
"oldfieldname": "customer_group",
|
||||||
|
"oldfieldtype": "Link",
|
||||||
|
"options": "Customer Group",
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 1
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "column_break3",
|
"fieldname": "column_break3",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"read_only": 0
|
"read_only": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "customer_name",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Customer Name",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "contact_person",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_filter": 1,
|
||||||
|
"label": "Contact Person",
|
||||||
|
"options": "Contact",
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "contact_display",
|
"fieldname": "contact_display",
|
||||||
@ -254,36 +284,6 @@
|
|||||||
"label": "Contact Mobile No",
|
"label": "Contact Mobile No",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"depends_on": "eval:doc.enquiry_from==\"Customer\"",
|
|
||||||
"description": "<a href=\"#Sales Browser/Customer Group\">To manage Territory, click here</a>",
|
|
||||||
"doctype": "DocField",
|
|
||||||
"fieldname": "customer_group",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"in_filter": 1,
|
|
||||||
"label": "Customer Group",
|
|
||||||
"oldfieldname": "customer_group",
|
|
||||||
"oldfieldtype": "Link",
|
|
||||||
"options": "Customer Group",
|
|
||||||
"print_hide": 1,
|
|
||||||
"read_only": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "<a href=\"#Sales Browser/Territory\">To manage Territory, click here</a>",
|
|
||||||
"doctype": "DocField",
|
|
||||||
"fieldname": "territory",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"in_filter": 1,
|
|
||||||
"label": "Territory",
|
|
||||||
"options": "Territory",
|
|
||||||
"print_hide": 1,
|
|
||||||
"read_only": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 1
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"description": "Filing in Additional Information about the Opportunity will help you analyze your data better.",
|
"description": "Filing in Additional Information about the Opportunity will help you analyze your data better.",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
|
@ -11,6 +11,7 @@ cur_frm.cscript.sales_team_fname = "sales_team";
|
|||||||
wn.require('app/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js');
|
wn.require('app/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js');
|
||||||
wn.require('app/utilities/doctype/sms_control/sms_control.js');
|
wn.require('app/utilities/doctype/sms_control/sms_control.js');
|
||||||
wn.require('app/selling/doctype/sales_common/sales_common.js');
|
wn.require('app/selling/doctype/sales_common/sales_common.js');
|
||||||
|
wn.require('app/accounts/doctype/sales_invoice/pos.js');
|
||||||
|
|
||||||
erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
|
erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
|
||||||
onload: function(doc, dt, dn) {
|
onload: function(doc, dt, dn) {
|
||||||
@ -82,12 +83,12 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
validate_company_and_party: function(party_field) {
|
validate_company_and_party: function(party_field) {
|
||||||
if(this.frm.doc.quotation_to == "Lead") {
|
if(!this.frm.doc.quotation_to) {
|
||||||
return true;
|
|
||||||
} else if(!this.frm.doc.quotation_to) {
|
|
||||||
msgprint(wn._("Please select a value for" + " " + wn.meta.get_label(this.frm.doc.doctype,
|
msgprint(wn._("Please select a value for" + " " + wn.meta.get_label(this.frm.doc.doctype,
|
||||||
"quotation_to", this.frm.doc.name)));
|
"quotation_to", this.frm.doc.name)));
|
||||||
return false;
|
return false;
|
||||||
|
} else if (this.frm.doc.quotation_to == "Lead") {
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return this._super(party_field);
|
return this._super(party_field);
|
||||||
}
|
}
|
||||||
|
@ -162,8 +162,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
|||||||
var item = wn.model.get_doc(cdt, cdn);
|
var item = wn.model.get_doc(cdt, cdn);
|
||||||
if(item.item_code || item.barcode) {
|
if(item.item_code || item.barcode) {
|
||||||
if(!this.validate_company_and_party("customer")) {
|
if(!this.validate_company_and_party("customer")) {
|
||||||
item.item_code = null;
|
cur_frm.fields_dict[me.frm.cscript.fname].grid.grid_rows[item.idx - 1].remove();
|
||||||
refresh_field("item_code", item.name, item.parentfield);
|
|
||||||
} else {
|
} else {
|
||||||
return this.frm.call({
|
return this.frm.call({
|
||||||
method: "selling.utils.get_item_details",
|
method: "selling.utils.get_item_details",
|
||||||
|
@ -12,6 +12,7 @@ cur_frm.cscript.sales_team_fname = "sales_team";
|
|||||||
wn.require('app/selling/doctype/sales_common/sales_common.js');
|
wn.require('app/selling/doctype/sales_common/sales_common.js');
|
||||||
wn.require('app/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js');
|
wn.require('app/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js');
|
||||||
wn.require('app/utilities/doctype/sms_control/sms_control.js');
|
wn.require('app/utilities/doctype/sms_control/sms_control.js');
|
||||||
|
wn.require('app/accounts/doctype/sales_invoice/pos.js');
|
||||||
|
|
||||||
erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend({
|
erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend({
|
||||||
refresh: function(doc, dt, dn) {
|
refresh: function(doc, dt, dn) {
|
||||||
@ -26,34 +27,34 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
|
|||||||
cur_frm.dashboard.add_progress(cint(doc.per_billed) + wn._("% Billed"),
|
cur_frm.dashboard.add_progress(cint(doc.per_billed) + wn._("% Billed"),
|
||||||
doc.per_billed);
|
doc.per_billed);
|
||||||
|
|
||||||
cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms);
|
cur_frm.add_custom_button(wn._('Send SMS'), cur_frm.cscript.send_sms);
|
||||||
// delivery note
|
// delivery note
|
||||||
if(flt(doc.per_delivered, 2) < 100 && doc.order_type=='Sales')
|
if(flt(doc.per_delivered, 2) < 100 && doc.order_type=='Sales')
|
||||||
cur_frm.add_custom_button('Make Delivery', this.make_delivery_note);
|
cur_frm.add_custom_button(wn._('Make Delivery'), this.make_delivery_note);
|
||||||
|
|
||||||
// maintenance
|
// maintenance
|
||||||
if(flt(doc.per_delivered, 2) < 100 && (doc.order_type !='Sales')) {
|
if(flt(doc.per_delivered, 2) < 100 && (doc.order_type !='Sales')) {
|
||||||
cur_frm.add_custom_button('Make Maint. Visit', this.make_maintenance_visit);
|
cur_frm.add_custom_button(wn._('Make Maint. Visit'), this.make_maintenance_visit);
|
||||||
cur_frm.add_custom_button('Make Maint. Schedule',
|
cur_frm.add_custom_button(wn._('Make Maint. Schedule'),
|
||||||
this.make_maintenance_schedule);
|
this.make_maintenance_schedule);
|
||||||
}
|
}
|
||||||
|
|
||||||
// indent
|
// indent
|
||||||
if(!doc.order_type || (doc.order_type == 'Sales'))
|
if(!doc.order_type || (doc.order_type == 'Sales'))
|
||||||
cur_frm.add_custom_button('Make ' + wn._('Material Request'),
|
cur_frm.add_custom_button(wn._('Make ') + wn._('Material Request'),
|
||||||
this.make_material_request);
|
this.make_material_request);
|
||||||
|
|
||||||
// sales invoice
|
// sales invoice
|
||||||
if(flt(doc.per_billed, 2) < 100)
|
if(flt(doc.per_billed, 2) < 100)
|
||||||
cur_frm.add_custom_button('Make Invoice', this.make_sales_invoice);
|
cur_frm.add_custom_button(wn._('Make Invoice'), this.make_sales_invoice);
|
||||||
|
|
||||||
// stop
|
// stop
|
||||||
if(flt(doc.per_delivered, 2) < 100 || doc.per_billed < 100)
|
if(flt(doc.per_delivered, 2) < 100 || doc.per_billed < 100)
|
||||||
cur_frm.add_custom_button('Stop!', cur_frm.cscript['Stop Sales Order']);
|
cur_frm.add_custom_button(wn._('Stop!'), cur_frm.cscript['Stop Sales Order']);
|
||||||
} else {
|
} else {
|
||||||
// un-stop
|
// un-stop
|
||||||
cur_frm.dashboard.set_headline_alert("Stopped", "alert-danger", "icon-stop");
|
cur_frm.dashboard.set_headline_alert(wn._("Stopped"), "alert-danger", "icon-stop");
|
||||||
cur_frm.add_custom_button('Unstop', cur_frm.cscript['Unstop Sales Order']);
|
cur_frm.add_custom_button(wn._('Unstop'), cur_frm.cscript['Unstop Sales Order']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +158,7 @@ cur_frm.fields_dict['project_name'].get_query = function(doc, cdt, cdn) {
|
|||||||
cur_frm.cscript['Stop Sales Order'] = function() {
|
cur_frm.cscript['Stop Sales Order'] = function() {
|
||||||
var doc = cur_frm.doc;
|
var doc = cur_frm.doc;
|
||||||
|
|
||||||
var check = confirm("Are you sure you want to STOP " + doc.name);
|
var check = confirm(wn._("Are you sure you want to STOP ") + doc.name);
|
||||||
|
|
||||||
if (check) {
|
if (check) {
|
||||||
return $c('runserverobj', {
|
return $c('runserverobj', {
|
||||||
@ -172,7 +173,7 @@ cur_frm.cscript['Stop Sales Order'] = function() {
|
|||||||
cur_frm.cscript['Unstop Sales Order'] = function() {
|
cur_frm.cscript['Unstop Sales Order'] = function() {
|
||||||
var doc = cur_frm.doc;
|
var doc = cur_frm.doc;
|
||||||
|
|
||||||
var check = confirm("Are you sure you want to UNSTOP " + doc.name);
|
var check = confirm(wn._("Are you sure you want to UNSTOP ") + doc.name);
|
||||||
|
|
||||||
if (check) {
|
if (check) {
|
||||||
return $c('runserverobj', {
|
return $c('runserverobj', {
|
||||||
@ -188,4 +189,4 @@ cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
|
|||||||
if(cint(wn.boot.notification_settings.sales_order)) {
|
if(cint(wn.boot.notification_settings.sales_order)) {
|
||||||
cur_frm.email_doc(wn.boot.notification_settings.sales_order_message);
|
cur_frm.email_doc(wn.boot.notification_settings.sales_order_message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -34,6 +34,7 @@ def get_item_details(args):
|
|||||||
"plc_conversion_rate": 1.0
|
"plc_conversion_rate": 1.0
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if isinstance(args, basestring):
|
if isinstance(args, basestring):
|
||||||
args = json.loads(args)
|
args = json.loads(args)
|
||||||
args = webnotes._dict(args)
|
args = webnotes._dict(args)
|
||||||
|
@ -286,7 +286,7 @@ def apply_cart_settings(party=None, quotation=None):
|
|||||||
cart_settings = webnotes.get_obj("Shopping Cart Settings")
|
cart_settings = webnotes.get_obj("Shopping Cart Settings")
|
||||||
|
|
||||||
billing_territory = get_address_territory(quotation.doc.customer_address) or \
|
billing_territory = get_address_territory(quotation.doc.customer_address) or \
|
||||||
party.territory
|
party.territory or "All Territories"
|
||||||
|
|
||||||
set_price_list_and_rate(quotation, cart_settings, billing_territory)
|
set_price_list_and_rate(quotation, cart_settings, billing_territory)
|
||||||
|
|
||||||
|
@ -96,6 +96,7 @@ def backup_to_dropbox():
|
|||||||
error_log = []
|
error_log = []
|
||||||
path = os.path.join(get_base_path(), "public", "files")
|
path = os.path.join(get_base_path(), "public", "files")
|
||||||
for filename in os.listdir(path):
|
for filename in os.listdir(path):
|
||||||
|
filename = cstr(filename)
|
||||||
if filename in ignore_list:
|
if filename in ignore_list:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -85,6 +85,7 @@ def backup_to_gdrive():
|
|||||||
webnotes.conn.close()
|
webnotes.conn.close()
|
||||||
path = os.path.join(get_base_path(), "public", "files")
|
path = os.path.join(get_base_path(), "public", "files")
|
||||||
for filename in os.listdir(path):
|
for filename in os.listdir(path):
|
||||||
|
filename = cstr(filename)
|
||||||
found = False
|
found = False
|
||||||
filepath = os.path.join(path, filename)
|
filepath = os.path.join(path, filename)
|
||||||
ext = filename.split('.')[-1]
|
ext = filename.split('.')[-1]
|
||||||
|
@ -9,6 +9,7 @@ from __future__ import unicode_literals
|
|||||||
import os, json
|
import os, json
|
||||||
from xml.etree import ElementTree as ET
|
from xml.etree import ElementTree as ET
|
||||||
from webnotes.utils.datautils import read_csv_content
|
from webnotes.utils.datautils import read_csv_content
|
||||||
|
from webnotes.utils import cstr
|
||||||
|
|
||||||
path = "/Users/rmehta/Downloads/openerp/openerp/addons"
|
path = "/Users/rmehta/Downloads/openerp/openerp/addons"
|
||||||
chart_roots = []
|
chart_roots = []
|
||||||
@ -108,6 +109,7 @@ def find_charts():
|
|||||||
basename = os.path.basename(basepath)
|
basename = os.path.basename(basepath)
|
||||||
if basename.startswith("l10n"):
|
if basename.startswith("l10n"):
|
||||||
for fname in files:
|
for fname in files:
|
||||||
|
fname = cstr(fname)
|
||||||
filepath = os.path.join(basepath, fname)
|
filepath = os.path.join(basepath, fname)
|
||||||
if fname.endswith(".xml"):
|
if fname.endswith(".xml"):
|
||||||
tree = ET.parse(filepath)
|
tree = ET.parse(filepath)
|
||||||
|
7
setup/doctype/price_list/price_list.css
Normal file
7
setup/doctype/price_list/price_list.css
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
.table-grid tbody tr {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-grid thead tr {
|
||||||
|
height: 50px;
|
||||||
|
}
|
@ -5,4 +5,253 @@ $.extend(cur_frm.cscript, {
|
|||||||
onload: function() {
|
onload: function() {
|
||||||
erpnext.add_for_territory();
|
erpnext.add_for_territory();
|
||||||
},
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||||
|
cur_frm.cscript.show_item_prices();
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_frm.cscript.show_item_prices = function() {
|
||||||
|
var item_price = wn.model.get("Item Price", {parent: cur_frm.doc.name});
|
||||||
|
|
||||||
|
$(cur_frm.fields_dict.item_prices_html.wrapper).empty();
|
||||||
|
|
||||||
|
new wn.ui.form.TableGrid({
|
||||||
|
parent: cur_frm.fields_dict.item_prices_html.wrapper,
|
||||||
|
frm: cur_frm,
|
||||||
|
table_field: wn.meta.get_docfield("Price List", "item_prices", cur_frm.doc.name)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
wn.ui.form.TableGrid = Class.extend({
|
||||||
|
init: function(opts) {
|
||||||
|
$.extend(this, opts);
|
||||||
|
this.fields = wn.meta.get_docfields("Item Price", cur_frm.doc.name);
|
||||||
|
this.make_table();
|
||||||
|
},
|
||||||
|
make_table: function() {
|
||||||
|
var me = this;
|
||||||
|
// Creating table & assigning attributes
|
||||||
|
var grid_table = document.createElement("table");
|
||||||
|
grid_table.className = "table table-hover table-bordered table-grid";
|
||||||
|
|
||||||
|
// Appending header & rows to table
|
||||||
|
grid_table.appendChild(this.make_table_headers());
|
||||||
|
grid_table.appendChild(this.make_table_rows());
|
||||||
|
|
||||||
|
// Creating button to add new row
|
||||||
|
var btn_div = document.createElement("div");
|
||||||
|
var new_row_btn = document.createElement("button");
|
||||||
|
new_row_btn.className = "btn btn-success table-new-row";
|
||||||
|
new_row_btn.title = "Add new row";
|
||||||
|
|
||||||
|
var btn_icon = document.createElement("i");
|
||||||
|
btn_icon.className = "icon-plus";
|
||||||
|
new_row_btn.appendChild(btn_icon);
|
||||||
|
new_row_btn.innerHTML += " Add new row";
|
||||||
|
btn_div.appendChild(new_row_btn);
|
||||||
|
|
||||||
|
// Appending table & button to parent
|
||||||
|
var $grid_table = $(grid_table).appendTo($(this.parent));
|
||||||
|
var $btn_div = $(btn_div).appendTo($(this.parent));
|
||||||
|
|
||||||
|
$btn_div.on("click", ".table-new-row", function() {
|
||||||
|
me.make_dialog();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$grid_table.on("click", ".table-row", function() {
|
||||||
|
me.make_dialog(this);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
make_table_headers: function() {
|
||||||
|
var me = this;
|
||||||
|
var header = document.createElement("thead");
|
||||||
|
|
||||||
|
// Creating header row
|
||||||
|
var row = document.createElement("tr");
|
||||||
|
row.className = "active";
|
||||||
|
|
||||||
|
// Creating head first cell
|
||||||
|
var th = document.createElement("th");
|
||||||
|
th.width = "8%";
|
||||||
|
th.className = "text-center";
|
||||||
|
th.innerHTML = "#";
|
||||||
|
row.appendChild(th);
|
||||||
|
|
||||||
|
// Make other headers with label as heading
|
||||||
|
for(var i=0, l=this.fields.length; i<l; i++) {
|
||||||
|
var df = this.fields[i];
|
||||||
|
|
||||||
|
if(!!!df.hidden && df.in_list_view === 1) {
|
||||||
|
var th = document.createElement("th");
|
||||||
|
|
||||||
|
// If currency then move header to right
|
||||||
|
if(["Int", "Currency", "Float"].indexOf(df.fieldtype) !== -1) th.className = "text-right";
|
||||||
|
|
||||||
|
th.innerHTML = wn._(df.label);
|
||||||
|
row.appendChild(th);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
header.appendChild(row);
|
||||||
|
|
||||||
|
return header;
|
||||||
|
},
|
||||||
|
make_table_rows: function() {
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
// Creating table body
|
||||||
|
var table_body = document.createElement("tbody");
|
||||||
|
|
||||||
|
var item_prices = wn.model.get_children(this.table_field.options, this.frm.doc.name,
|
||||||
|
this.table_field.fieldname, this.frm.doctype);
|
||||||
|
|
||||||
|
for(var i=0, l=item_prices.length; i<l; i++) {
|
||||||
|
var d = item_prices[i];
|
||||||
|
|
||||||
|
// Creating table row
|
||||||
|
var tr = this.add_new_row(d);
|
||||||
|
|
||||||
|
// append row to table body
|
||||||
|
table_body.appendChild(tr);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.table_body = table_body;
|
||||||
|
|
||||||
|
return table_body;
|
||||||
|
},
|
||||||
|
make_dialog: function(row) {
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
this.dialog = new wn.ui.Dialog({
|
||||||
|
title: this.table_field.options,
|
||||||
|
fields: this.fields
|
||||||
|
});
|
||||||
|
|
||||||
|
if (row)
|
||||||
|
this.dialog.set_values(this.make_dialog_values(row));
|
||||||
|
|
||||||
|
$a(this.dialog.body, 'div', '', '', this.make_dialog_buttons(row));
|
||||||
|
this.dialog.show();
|
||||||
|
|
||||||
|
this.dialog.$wrapper.find('button.update').on('click', function() {
|
||||||
|
me.update_row(row);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.dialog.$wrapper.find('button.delete').on('click', function() {
|
||||||
|
me.delete_row(row);
|
||||||
|
});
|
||||||
|
return row;
|
||||||
|
},
|
||||||
|
make_dialog_values: function(row) {
|
||||||
|
var me = this;
|
||||||
|
var dialog_values = {};
|
||||||
|
|
||||||
|
$.each(this.fields, function(i, item) {
|
||||||
|
dialog_values[item.fieldname] = $(row).find('td[data-fieldname="'+ item.fieldname +'"]').attr('data-fieldvalue');
|
||||||
|
});
|
||||||
|
|
||||||
|
return dialog_values;
|
||||||
|
},
|
||||||
|
make_dialog_buttons: function(row) {
|
||||||
|
var me = this;
|
||||||
|
var buttons = '<button class="btn btn-primary update">Update</button>';
|
||||||
|
|
||||||
|
// if user can delete then only add the delete button in dialog
|
||||||
|
if (wn.model.can_delete(me.frm.doc.doctype) && row)
|
||||||
|
buttons += ' <button class="btn btn-default delete">Delete</button>';
|
||||||
|
|
||||||
|
return buttons;
|
||||||
|
},
|
||||||
|
update_row: function(row) {
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
if (!row) {
|
||||||
|
var d = wn.model.add_child(this.frm.doc, this.table_field.options,
|
||||||
|
this.table_field.fieldname);
|
||||||
|
refresh_field(this.table_field.fieldname);
|
||||||
|
this.update_item_price(d.name);
|
||||||
|
var tr = this.add_new_row(d);
|
||||||
|
this.table_body.appendChild(tr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.update_item_price(null, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dialog.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
update_item_price: function(docname, row) {
|
||||||
|
var me = this;
|
||||||
|
if(!docname && row) docname = $(row).attr("data-docname");
|
||||||
|
$.each(me.fields, function(i, df) {
|
||||||
|
var val = me.dialog.get_values()[df.fieldname];
|
||||||
|
|
||||||
|
if(["Currency", "Float"].indexOf(df.fieldtype)!==-1) {
|
||||||
|
val = flt(val);
|
||||||
|
} else if(["Int", "Check"].indexOf(df.fieldtype)!==-1) {
|
||||||
|
val = cint(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
wn.model.set_value(me.table_field.options, docname,
|
||||||
|
df.fieldname, val);
|
||||||
|
|
||||||
|
if(row) {
|
||||||
|
var $td = $(row).find('td[data-fieldname="'+ df.fieldname +'"]');
|
||||||
|
$td.attr('data-fieldvalue', val);
|
||||||
|
// If field type is currency the update with format currency
|
||||||
|
$td.html(wn.format(val, df));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
delete_row: function(row) {
|
||||||
|
var me = this;
|
||||||
|
var docname = $(row).find('td:last').attr('data-docname');
|
||||||
|
wn.model.clear_doc(me.table_field.options, docname);
|
||||||
|
$(row).remove();
|
||||||
|
|
||||||
|
// Re-assign idx
|
||||||
|
$.each($(this.parent).find("tbody tr"), function(idx, data) {
|
||||||
|
var $td = $(data).find('td:first');
|
||||||
|
$td.html(idx + 1);
|
||||||
|
});
|
||||||
|
this.dialog.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
add_new_row: function(d) {
|
||||||
|
var tr = document.createElement("tr");
|
||||||
|
tr.className = "table-row";
|
||||||
|
tr.setAttribute("data-docname", d.name);
|
||||||
|
|
||||||
|
// Creating table data & appending to row
|
||||||
|
var td = document.createElement("td");
|
||||||
|
td.className = "text-center";
|
||||||
|
td.innerHTML = d.idx;
|
||||||
|
tr.appendChild(td);
|
||||||
|
|
||||||
|
for(var f=0, lf=this.fields.length; f<lf; f++) {
|
||||||
|
var df = this.fields[f];
|
||||||
|
if(!!!df.hidden && df.in_list_view===1) {
|
||||||
|
var td = document.createElement("td");
|
||||||
|
td.setAttribute("data-fieldname", df.fieldname);
|
||||||
|
td.setAttribute("data-fieldvalue", d[df.fieldname]);
|
||||||
|
td.setAttribute("data-docname", d.name);
|
||||||
|
|
||||||
|
// If currency then move header to right
|
||||||
|
if(["Int", "Currency", "Float"].indexOf(df.fieldtype) !== -1) {
|
||||||
|
td.className = "text-right";
|
||||||
|
}
|
||||||
|
|
||||||
|
// format and set display
|
||||||
|
td.innerHTML = wn.format(d[df.fieldname], df);
|
||||||
|
|
||||||
|
// append column to tabel row
|
||||||
|
tr.appendChild(td);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tr;
|
||||||
|
}
|
||||||
});
|
});
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-01-25 11:35:09",
|
"creation": "2013-01-25 11:35:09",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-09-06 15:03:38",
|
"modified": "2013-10-02 11:36:09",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -85,16 +85,23 @@
|
|||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"description": "To change row values, click on the respective row",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "item_prices_section",
|
"fieldname": "item_prices_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"label": "Item Prices"
|
"label": "Item Prices"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "item_prices_html",
|
||||||
|
"fieldtype": "HTML"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "item_prices",
|
"fieldname": "item_prices",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
|
"hidden": 1,
|
||||||
"label": "Item Prices",
|
"label": "Item Prices",
|
||||||
"options": "Item Price"
|
"options": "Item Price"
|
||||||
},
|
},
|
||||||
|
@ -15,7 +15,7 @@ class DocType:
|
|||||||
self.doclist = doclist
|
self.doclist = doclist
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
if not self.doc.stock_uom:
|
if self.doc.fields.get("__islocal") or not self.doc.stock_uom:
|
||||||
self.doc.stock_uom = webnotes.conn.get_value('Item', self.doc.item_code, 'stock_uom')
|
self.doc.stock_uom = webnotes.conn.get_value('Item', self.doc.item_code, 'stock_uom')
|
||||||
|
|
||||||
self.validate_mandatory()
|
self.validate_mandatory()
|
||||||
|
@ -10,6 +10,7 @@ cur_frm.cscript.sales_team_fname = "sales_team";
|
|||||||
wn.require('app/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js');
|
wn.require('app/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js');
|
||||||
wn.require('app/utilities/doctype/sms_control/sms_control.js');
|
wn.require('app/utilities/doctype/sms_control/sms_control.js');
|
||||||
wn.require('app/selling/doctype/sales_common/sales_common.js');
|
wn.require('app/selling/doctype/sales_common/sales_common.js');
|
||||||
|
wn.require('app/accounts/doctype/sales_invoice/pos.js');
|
||||||
|
|
||||||
wn.provide("erpnext.stock");
|
wn.provide("erpnext.stock");
|
||||||
erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend({
|
erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend({
|
||||||
|
@ -347,9 +347,16 @@ def make_supplier_quotation(source_name, target_doclist=None):
|
|||||||
@webnotes.whitelist()
|
@webnotes.whitelist()
|
||||||
def make_stock_entry(source_name, target_doclist=None):
|
def make_stock_entry(source_name, target_doclist=None):
|
||||||
from webnotes.model.mapper import get_mapped_doclist
|
from webnotes.model.mapper import get_mapped_doclist
|
||||||
|
|
||||||
def set_purpose(source, target):
|
def update_item(obj, target, source_parent):
|
||||||
|
target.conversion_factor = 1
|
||||||
|
target.qty = flt(obj.qty) - flt(obj.ordered_qty)
|
||||||
|
target.transfer_qty = flt(obj.qty) - flt(obj.ordered_qty)
|
||||||
|
|
||||||
|
def set_missing_values(source, target):
|
||||||
target[0].purpose = "Material Transfer"
|
target[0].purpose = "Material Transfer"
|
||||||
|
se = webnotes.bean(target)
|
||||||
|
se.run_method("get_stock_and_rate")
|
||||||
|
|
||||||
doclist = get_mapped_doclist("Material Request", source_name, {
|
doclist = get_mapped_doclist("Material Request", source_name, {
|
||||||
"Material Request": {
|
"Material Request": {
|
||||||
@ -369,6 +376,6 @@ def make_stock_entry(source_name, target_doclist=None):
|
|||||||
},
|
},
|
||||||
"postprocess": update_item
|
"postprocess": update_item
|
||||||
}
|
}
|
||||||
}, target_doclist, set_purpose)
|
}, target_doclist, set_missing_values)
|
||||||
|
|
||||||
return [d.fields for d in doclist]
|
return [d.fields for d in doclist]
|
@ -8,6 +8,7 @@ cur_frm.cscript.other_fname = "purchase_tax_details";
|
|||||||
wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js');
|
wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js');
|
||||||
wn.require('app/utilities/doctype/sms_control/sms_control.js');
|
wn.require('app/utilities/doctype/sms_control/sms_control.js');
|
||||||
wn.require('app/buying/doctype/purchase_common/purchase_common.js');
|
wn.require('app/buying/doctype/purchase_common/purchase_common.js');
|
||||||
|
wn.require('app/accounts/doctype/sales_invoice/pos.js');
|
||||||
|
|
||||||
wn.provide("erpnext.stock");
|
wn.provide("erpnext.stock");
|
||||||
erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend({
|
erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend({
|
||||||
|
@ -117,8 +117,7 @@ class DocType(BuyingController):
|
|||||||
},
|
},
|
||||||
"Purchase Order Item": {
|
"Purchase Order Item": {
|
||||||
"ref_dn_field": "prevdoc_detail_docname",
|
"ref_dn_field": "prevdoc_detail_docname",
|
||||||
"compare_fields": [["project_name", "="], ["warehouse", "="],
|
"compare_fields": [["project_name", "="], ["uom", "="], ["item_code", "="]],
|
||||||
["uom", "="], ["item_code", "="]],
|
|
||||||
"is_child_table": True
|
"is_child_table": True
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -165,34 +164,43 @@ class DocType(BuyingController):
|
|||||||
|
|
||||||
self.bk_flush_supp_wh(sl_entries)
|
self.bk_flush_supp_wh(sl_entries)
|
||||||
self.make_sl_entries(sl_entries)
|
self.make_sl_entries(sl_entries)
|
||||||
|
|
||||||
def update_ordered_qty(self, is_cancelled="No"):
|
def update_ordered_qty(self):
|
||||||
pc_obj = get_obj('Purchase Common')
|
|
||||||
stock_items = self.get_stock_items()
|
stock_items = self.get_stock_items()
|
||||||
for d in getlist(self.doclist, 'purchase_receipt_details'):
|
for d in self.doclist.get({"parentfield": "purchase_receipt_details"}):
|
||||||
if d.item_code in stock_items and d.warehouse \
|
if d.item_code in stock_items and d.warehouse \
|
||||||
and cstr(d.prevdoc_doctype) == 'Purchase Order':
|
and cstr(d.prevdoc_doctype) == 'Purchase Order':
|
||||||
pr_qty = flt(d.qty) * flt(d.conversion_factor)
|
|
||||||
|
already_received_qty = self.get_already_received_qty(d.prevdoc_docname,
|
||||||
# get qty and pending_qty of prevdoc
|
d.prevdoc_detail_docname)
|
||||||
curr_ref_qty = pc_obj.get_qty(d.doctype, 'prevdoc_detail_docname',
|
po_qty, ordered_warehouse = self.get_po_qty_and_warehouse(d.prevdoc_detail_docname)
|
||||||
d.prevdoc_detail_docname, 'Purchase Order Item',
|
|
||||||
'Purchase Order - Purchase Receipt', self.doc.name)
|
if not ordered_warehouse:
|
||||||
max_qty, qty, curr_qty = flt(curr_ref_qty.split('~~~')[1]), \
|
webnotes.throw(_("Warehouse is missing in Purchase Order"))
|
||||||
flt(curr_ref_qty.split('~~~')[0]), 0
|
|
||||||
|
if already_received_qty + d.qty > po_qty:
|
||||||
if flt(qty) + flt(pr_qty) > flt(max_qty):
|
ordered_qty = - (po_qty - already_received_qty) * flt(d.conversion_factor)
|
||||||
curr_qty = (flt(max_qty) - flt(qty)) * flt(d.conversion_factor)
|
|
||||||
else:
|
else:
|
||||||
curr_qty = flt(pr_qty)
|
ordered_qty = - flt(d.qty) * flt(d.conversion_factor)
|
||||||
|
|
||||||
args = {
|
update_bin({
|
||||||
"item_code": d.item_code,
|
"item_code": d.item_code,
|
||||||
"warehouse": d.warehouse,
|
"warehouse": ordered_warehouse,
|
||||||
"posting_date": self.doc.posting_date,
|
"posting_date": self.doc.posting_date,
|
||||||
"ordered_qty": (is_cancelled=="Yes" and -1 or 1)*flt(curr_qty)
|
"ordered_qty": flt(ordered_qty) if self.doc.docstatus==1 else -flt(ordered_qty)
|
||||||
}
|
})
|
||||||
update_bin(args)
|
|
||||||
|
def get_already_received_qty(self, po, po_detail):
|
||||||
|
qty = webnotes.conn.sql("""select sum(qty) from `tabPurchase Receipt Item`
|
||||||
|
where prevdoc_detail_docname = %s and docstatus = 1
|
||||||
|
and prevdoc_doctype='Purchase Order' and prevdoc_docname=%s
|
||||||
|
and parent != %s""", (po_detail, po, self.doc.name))
|
||||||
|
return qty and flt(qty[0][0]) or 0.0
|
||||||
|
|
||||||
|
def get_po_qty_and_warehouse(self, po_detail):
|
||||||
|
po_qty, po_warehouse = webnotes.conn.get_value("Purchase Order Item", po_detail,
|
||||||
|
["qty", "warehouse"])
|
||||||
|
return po_qty, po_warehouse
|
||||||
|
|
||||||
def bk_flush_supp_wh(self, sl_entries):
|
def bk_flush_supp_wh(self, sl_entries):
|
||||||
for d in getlist(self.doclist, 'pr_raw_material_details'):
|
for d in getlist(self.doclist, 'pr_raw_material_details'):
|
||||||
@ -201,7 +209,7 @@ class DocType(BuyingController):
|
|||||||
sl_entries.append(self.get_sl_entries(d, {
|
sl_entries.append(self.get_sl_entries(d, {
|
||||||
"item_code": d.rm_item_code,
|
"item_code": d.rm_item_code,
|
||||||
"warehouse": self.doc.supplier_warehouse,
|
"warehouse": self.doc.supplier_warehouse,
|
||||||
"actual_qty": -1*flt(consumed_qty),
|
"actual_qty": -1*flt(d.consumed_qty),
|
||||||
"incoming_rate": 0
|
"incoming_rate": 0
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@ -281,7 +289,7 @@ class DocType(BuyingController):
|
|||||||
|
|
||||||
webnotes.conn.set(self.doc,'status','Cancelled')
|
webnotes.conn.set(self.doc,'status','Cancelled')
|
||||||
|
|
||||||
self.update_ordered_qty(is_cancelled="Yes")
|
self.update_ordered_qty()
|
||||||
|
|
||||||
self.update_stock()
|
self.update_stock()
|
||||||
self.update_serial_nos(cancel=True)
|
self.update_serial_nos(cancel=True)
|
||||||
|
@ -246,6 +246,7 @@ class DocType(StockController):
|
|||||||
"stock_uom": webnotes.conn.get_value("Item", row.item_code, "stock_uom"),
|
"stock_uom": webnotes.conn.get_value("Item", row.item_code, "stock_uom"),
|
||||||
"voucher_detail_no": row.voucher_detail_no,
|
"voucher_detail_no": row.voucher_detail_no,
|
||||||
"fiscal_year": self.doc.fiscal_year,
|
"fiscal_year": self.doc.fiscal_year,
|
||||||
|
"is_cancelled": "No"
|
||||||
})
|
})
|
||||||
args.update(opts)
|
args.update(opts)
|
||||||
self.make_sl_entries([args])
|
self.make_sl_entries([args])
|
||||||
|
@ -209,5 +209,4 @@ class DocType:
|
|||||||
msgprint("""Warehosue can not be deleted as stock ledger entry
|
msgprint("""Warehosue can not be deleted as stock ledger entry
|
||||||
exists for this warehouse.""", raise_exception=1)
|
exists for this warehouse.""", raise_exception=1)
|
||||||
else:
|
else:
|
||||||
webnotes.conn.sql("delete from `tabStock Ledger Entry` where warehouse = %s", self.doc.name)
|
webnotes.conn.sql("delete from `tabStock Ledger Entry` where warehouse = %s", self.doc.name)
|
||||||
|
|
@ -126,10 +126,11 @@ erpnext.StockBalance = erpnext.StockAnalytics.extend({
|
|||||||
} else {
|
} else {
|
||||||
item.inflow_value += value_diff;
|
item.inflow_value += value_diff;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
item.closing_qty += qty_diff;
|
item.closing_qty += qty_diff;
|
||||||
item.closing_value += value_diff;
|
item.closing_value += value_diff;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -14,29 +14,31 @@ _exceptions = webnotes.local('stockledger_exceptions')
|
|||||||
# _exceptions = []
|
# _exceptions = []
|
||||||
|
|
||||||
def make_sl_entries(sl_entries, is_amended=None):
|
def make_sl_entries(sl_entries, is_amended=None):
|
||||||
from stock.utils import update_bin
|
if sl_entries:
|
||||||
|
from stock.utils import update_bin
|
||||||
|
|
||||||
cancel = True if sl_entries[0].get("is_cancelled") == "Yes" else False
|
cancel = True if sl_entries[0].get("is_cancelled") == "Yes" else False
|
||||||
if cancel:
|
if cancel:
|
||||||
set_as_cancel(sl_entries[0].get('voucher_no'), sl_entries[0].get('voucher_type'))
|
set_as_cancel(sl_entries[0].get('voucher_no'), sl_entries[0].get('voucher_type'))
|
||||||
|
|
||||||
for sle in sl_entries:
|
for sle in sl_entries:
|
||||||
sle_id = None
|
sle_id = None
|
||||||
if sle.get('is_cancelled') == 'Yes':
|
if sle.get('is_cancelled') == 'Yes':
|
||||||
sle['actual_qty'] = -flt(sle['actual_qty'])
|
sle['actual_qty'] = -flt(sle['actual_qty'])
|
||||||
|
|
||||||
if sle.get("actual_qty"):
|
if sle.get("actual_qty"):
|
||||||
sle_id = make_entry(sle)
|
sle_id = make_entry(sle)
|
||||||
|
|
||||||
args = sle.copy()
|
args = sle.copy()
|
||||||
args.update({
|
args.update({
|
||||||
"sle_id": sle_id,
|
"sle_id": sle_id,
|
||||||
"is_amended": is_amended
|
"is_amended": is_amended
|
||||||
})
|
})
|
||||||
update_bin(args)
|
update_bin(args)
|
||||||
|
|
||||||
if cancel:
|
if cancel:
|
||||||
delete_cancelled_entry(sl_entries[0].get('voucher_type'), sl_entries[0].get('voucher_no'))
|
delete_cancelled_entry(sl_entries[0].get('voucher_type'),
|
||||||
|
sl_entries[0].get('voucher_no'))
|
||||||
|
|
||||||
def set_as_cancel(voucher_type, voucher_no):
|
def set_as_cancel(voucher_type, voucher_no):
|
||||||
webnotes.conn.sql("""update `tabStock Ledger Entry` set is_cancelled='Yes',
|
webnotes.conn.sql("""update `tabStock Ledger Entry` set is_cancelled='Yes',
|
||||||
|
@ -143,7 +143,8 @@ class TransactionBase(StatusUpdater):
|
|||||||
self.doc.fields.update(self.get_lead_defaults())
|
self.doc.fields.update(self.get_lead_defaults())
|
||||||
|
|
||||||
def get_customer_address(self, args):
|
def get_customer_address(self, args):
|
||||||
args = load_json(args)
|
args = load_json(args)
|
||||||
|
webnotes.errprint(args)
|
||||||
ret = {
|
ret = {
|
||||||
'customer_address' : args["address"],
|
'customer_address' : args["address"],
|
||||||
'address_display' : get_address_display(args["address"]),
|
'address_display' : get_address_display(args["address"]),
|
||||||
@ -425,6 +426,7 @@ def get_address_territory(address_doc):
|
|||||||
|
|
||||||
def validate_conversion_rate(currency, conversion_rate, conversion_rate_label, company):
|
def validate_conversion_rate(currency, conversion_rate, conversion_rate_label, company):
|
||||||
"""common validation for currency and price list currency"""
|
"""common validation for currency and price list currency"""
|
||||||
|
|
||||||
if conversion_rate == 0:
|
if conversion_rate == 0:
|
||||||
msgprint(conversion_rate_label + _(' cannot be 0'), raise_exception=True)
|
msgprint(conversion_rate_label + _(' cannot be 0'), raise_exception=True)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user