Merge pull request #5776 from saurabh6790/warehouse_accounting_fix
[fix] for setting warehouse in account head
diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
index aca83da..a02e591 100644
--- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
+++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
@@ -9,6 +9,7 @@
"docstatus": 0,
"doctype": "DocType",
"document_type": "Other",
+ "editable_grid": 1,
"fields": [
{
"allow_on_submit": 0,
@@ -115,31 +116,6 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "fieldname": "allow_payment_entry_via_journal_entry",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Allow Payment Entry via Journal Entry",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
"description": "Role that is allowed to submit transactions that exceed credit limits set.",
"fieldname": "credit_controller",
"fieldtype": "Link",
@@ -199,7 +175,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-06-27 15:18:28.566087",
+ "modified": "2016-07-14 14:32:06.056888",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",
diff --git a/erpnext/accounts/doctype/asset/asset.py b/erpnext/accounts/doctype/asset/asset.py
index 4d8a6b4..1118766 100644
--- a/erpnext/accounts/doctype/asset/asset.py
+++ b/erpnext/accounts/doctype/asset/asset.py
@@ -229,6 +229,9 @@
def get_item_details(item_code):
asset_category = frappe.db.get_value("Item", item_code, "asset_category")
+ if not asset_category:
+ frappe.throw(_("Please enter Asset Category in Item {0}").format(item_code))
+
ret = frappe.db.get_value("Asset Category", asset_category,
["depreciation_method", "total_number_of_depreciations", "frequency_of_depreciation"], as_dict=1)
diff --git a/erpnext/accounts/doctype/asset_category/asset_category.js b/erpnext/accounts/doctype/asset_category/asset_category.js
index cbbdd48..d5f4864 100644
--- a/erpnext/accounts/doctype/asset_category/asset_category.js
+++ b/erpnext/accounts/doctype/asset_category/asset_category.js
@@ -4,13 +4,13 @@
frappe.ui.form.on('Asset Category', {
setup: function(frm) {
frm.get_field('accounts').grid.editable_fields = [
- {fieldname: 'company_name', columns: 2},
+ {fieldname: 'company_name', columns: 3},
{fieldname: 'fixed_asset_account', columns: 3},
- {fieldname: 'accumulated_depreciation_account', columns: 3},
- {fieldname: 'depreciation_expense_account', columns: 3}
+ {fieldname: 'accumulated_depreciation_account', columns: 2},
+ {fieldname: 'depreciation_expense_account', columns: 2}
];
},
-
+
onload: function(frm) {
frm.add_fetch('company_name', 'accumulated_depreciation_account', 'accumulated_depreciation_account');
frm.add_fetch('company_name', 'depreciation_expense_account', 'accumulated_depreciation_account');
diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.js b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.js
index 4b33fd3..fcd280f 100644
--- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.js
+++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.js
@@ -5,20 +5,20 @@
setup: function(frm) {
frm.get_docfield("payment_entries").allow_bulk_edit = 1;
frm.add_fetch("bank_account", "account_currency", "account_currency");
-
+
frm.get_field('payment_entries').grid.editable_fields = [
{fieldname: 'against_account', columns: 3},
{fieldname: 'amount', columns: 2},
{fieldname: 'cheque_number', columns: 3},
- {fieldname: 'clearance_date', columns: 3}
+ {fieldname: 'clearance_date', columns: 2}
];
},
onload: function(frm) {
var default_bank_account = locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"];
-
+
frm.set_value("bank_account", default_bank_account);
-
+
frm.set_query("bank_account", function() {
return {
"filters": {
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js
index cb6c36c..2b06e60 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.js
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js
@@ -9,7 +9,7 @@
setup: function(frm) {
frm.get_field('accounts').grid.editable_fields = [
{fieldname: 'account', columns: 3},
- {fieldname: 'party', columns: 4},
+ {fieldname: 'party', columns: 3},
{fieldname: 'debit_in_account_currency', columns: 2},
{fieldname: 'credit_in_account_currency', columns: 2}
];
@@ -283,7 +283,7 @@
type: "GET",
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_default_bank_cash_account",
args: {
- "account_type": (doc.voucher_type=="Bank Entry" ?
+ "account_type": (doc.voucher_type=="Bank Entry" ?
"Bank" : (doc.voucher_type=="Cash" ? "Cash" : null)),
"company": doc.company
},
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index ba76bdc..a5fbfba 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -12,7 +12,7 @@
setup: function(frm) {
frm.get_field('references').grid.editable_fields = [
{fieldname: 'reference_doctype', columns: 2},
- {fieldname: 'reference_name', columns: 3},
+ {fieldname: 'reference_name', columns: 2},
{fieldname: 'outstanding_amount', columns: 3},
{fieldname: 'allocated_amount', columns: 3}
];
@@ -278,7 +278,11 @@
frm.events.set_account_currency_and_balance(frm, frm.doc.paid_from,
"paid_from_account_currency", "paid_from_account_balance", function(frm) {
- if(frm.doc.payment_type == "Receive") frm.events.get_outstanding_documents(frm);
+ if (frm.doc.payment_type == "Receive") {
+ frm.events.get_outstanding_documents(frm);
+ } else if (frm.doc.payment_type == "Pay") {
+ frm.events.paid_amount(frm);
+ }
}
);
},
@@ -288,7 +292,11 @@
frm.events.set_account_currency_and_balance(frm, frm.doc.paid_to,
"paid_to_account_currency", "paid_to_account_balance", function(frm) {
- if(frm.doc.payment_type == "Pay") frm.events.get_outstanding_documents(frm);
+ if(frm.doc.payment_type == "Pay") {
+ frm.events.get_outstanding_documents(frm);
+ } else if (frm.doc.payment_type == "Receive") {
+ frm.events.received_amount(frm);
+ }
}
);
},
@@ -376,29 +384,38 @@
source_exchange_rate: function(frm) {
if (frm.doc.paid_amount) {
frm.set_value("base_paid_amount", flt(frm.doc.paid_amount) * flt(frm.doc.source_exchange_rate));
+ if(!frm.set_paid_amount_based_on_received_amount &&
+ (frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency)) {
+ frm.set_value("target_exchange_rate", frm.doc.source_exchange_rate);
+ frm.set_value("base_received_amount", frm.doc.base_paid_amount);
+ }
+
+ frm.events.set_difference_amount(frm);
}
},
target_exchange_rate: function(frm) {
+ frm.set_paid_amount_based_on_received_amount = true;
+
if (frm.doc.received_amount) {
frm.set_value("base_received_amount",
flt(frm.doc.received_amount) * flt(frm.doc.target_exchange_rate));
+
+ if(!frm.doc.source_exchange_rate &&
+ (frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency)) {
+ frm.set_value("source_exchange_rate", frm.doc.target_exchange_rate);
+ frm.set_value("base_paid_amount", frm.doc.base_received_amount);
+ }
+
+ frm.events.set_difference_amount(frm);
}
+ frm.set_paid_amount_based_on_received_amount = false;
},
paid_amount: function(frm) {
frm.set_value("base_paid_amount", flt(frm.doc.paid_amount) * flt(frm.doc.source_exchange_rate));
- if(!frm.set_paid_amount_based_on_received_amount &&
- (frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency)) {
- frm.set_value("received_amount", frm.doc.paid_amount);
- frm.set_value("target_exchange_rate", frm.doc.source_exchange_rate);
- frm.set_value("base_received_amount", frm.doc.base_paid_amount);
- }
- if(frm.doc.payment_type == "Receive")
- frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.paid_amount);
- else
- frm.events.set_difference_amount(frm);
+ frm.trigger("reset_received_amount");
frm.set_paid_amount_based_on_received_amount = false;
},
@@ -420,6 +437,26 @@
else
frm.events.set_difference_amount(frm);
},
+
+ reset_received_amount: function(frm) {
+ if(!frm.set_paid_amount_based_on_received_amount &&
+ (frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency)) {
+
+ // var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
+ // function(d) { return d.amount}));
+ //
+ // var received_amount = frm.doc.paid_amount +
+ // flt(total_deductions) / flt(frm.doc.source_exchange_rate);
+ //
+ frm.set_value("received_amount", frm.doc.paid_amount);
+ frm.set_value("target_exchange_rate", frm.doc.source_exchange_rate);
+ frm.set_value("base_received_amount", frm.doc.base_paid_amount);
+ }
+ if(frm.doc.payment_type == "Receive")
+ frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.paid_amount);
+ else
+ frm.events.set_difference_amount(frm);
+ },
get_outstanding_documents: function(frm) {
frm.clear_table("references");
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index f7d2272..5ed14d5 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -36,6 +36,7 @@
def validate(self):
self.setup_party_account_field()
self.set_missing_values()
+ self.validate_payment_type()
self.validate_party_details()
self.validate_bank_accounts()
self.set_exchange_rate()
@@ -108,6 +109,10 @@
for field, value in ref_details.items():
if not d.get(field):
d.set(field, value)
+
+ def validate_payment_type(self):
+ if self.payment_type not in ("Receive", "Pay", "Internal Transfer"):
+ frappe.throw(_("Payment Type must be one of Receive, Pay and Internal Transfer"))
def validate_party_details(self):
if self.party:
diff --git a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json
index 082ab04..6441748 100644
--- a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json
+++ b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json
@@ -116,7 +116,7 @@
"bold": 0,
"collapsible": 0,
"fieldname": "total_amount",
- "fieldtype": "Currency",
+ "fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -141,7 +141,7 @@
"bold": 0,
"collapsible": 0,
"fieldname": "outstanding_amount",
- "fieldtype": "Currency",
+ "fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -166,7 +166,7 @@
"bold": 0,
"collapsible": 0,
"fieldname": "allocated_amount",
- "fieldtype": "Currency",
+ "fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -222,7 +222,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-07-11 07:55:04.131655",
+ "modified": "2016-07-14 14:48:13.356944",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry Reference",
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
index a50ff19..027fa63 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
@@ -7,12 +7,12 @@
setup: function() {
this.frm.get_field('payments').grid.editable_fields = [
{fieldname: 'reference_name', columns: 3},
- {fieldname: 'amount', columns: 2},
{fieldname: 'invoice_number', columns: 3},
- {fieldname: 'allocated_amount', columns: 3}
+ {fieldname: 'amount', columns: 2},
+ {fieldname: 'allocated_amount', columns: 2}
];
- },
-
+ },
+
onload: function() {
var me = this
this.frm.set_query('party_type', function() {
@@ -113,7 +113,7 @@
if (row.invoice_number && !inList(invoices, row.invoice_number))
invoices.push(row.invoice_type + " | " + row.invoice_number);
});
-
+
if (invoices) {
frappe.meta.get_docfield("Payment Reconciliation Payment", "invoice_number",
me.frm.doc.name).options = "\n" + invoices.join("\n");
@@ -122,7 +122,7 @@
if(!inList(invoices, cstr(p.invoice_number))) p.invoice_number = null;
});
}
-
+
refresh_field("payments");
},
diff --git a/erpnext/accounts/doctype/payment_tool/payment_tool.js b/erpnext/accounts/doctype/payment_tool/payment_tool.js
deleted file mode 100644
index 8d8e0ce..0000000
--- a/erpnext/accounts/doctype/payment_tool/payment_tool.js
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-// For license information, please see license.txt
-
-frappe.provide("erpnext.payment_tool");
-
-// Help content
-frappe.ui.form.on("Payment Tool", "onload", function(frm) {
- frm.set_value("make_jv_help",
- + __("Note: If payment is not made against any reference, make Journal Entry manually."));
-
- frm.set_query("party_type", function() {
- return {
- filters: {"name": ["in", ["Customer", "Supplier"]]}
- };
- });
-
- frm.set_query("payment_account", function() {
- return {
- filters: {
- "account_type": ["in", ["Bank", "Cash"]],
- "is_group": 0,
- "company": frm.doc.company
- }
- }
- });
-
- frm.set_query("against_voucher_type", "vouchers", function() {
- if (frm.doc.party_type=="Customer") {
- var doctypes = ["Sales Order", "Sales Invoice", "Journal Entry"];
- } else {
- var doctypes = ["Purchase Order", "Purchase Invoice", "Journal Entry"];
- }
-
- return {
- filters: { "name": ["in", doctypes] }
- };
- });
-});
-
-frappe.ui.form.on("Payment Tool", "refresh", function(frm) {
- frm.disable_save();
- frappe.ui.form.trigger("Payment Tool", "party_type");
-});
-
-frappe.ui.form.on("Payment Tool", "party_type", function(frm) {
- frm.set_value("received_or_paid", frm.doc.party_type=="Customer" ? "Received" : "Paid");
-});
-
-frappe.ui.form.on("Payment Tool", "party", function(frm) {
- if(frm.doc.party_type && frm.doc.party) {
- return frappe.call({
- method: "erpnext.accounts.party.get_party_account",
- args: {
- company: frm.doc.company,
- party_type: frm.doc.party_type,
- party: frm.doc.party
- },
- callback: function(r) {
- if(!r.exc && r.message) {
- frm.set_value("party_account", r.message);
- erpnext.payment_tool.check_mandatory_to_set_button(frm);
- }
- }
- });
- }
-})
-
-frappe.ui.form.on("Payment Tool", "party_account", function(frm) {
- if(frm.doc.party_account) {
- frm.call({
- method: "frappe.client.get_value",
- args: {
- doctype: "Account",
- fieldname: "account_currency",
- filters: { name: frm.doc.party_account },
- },
- callback: function(r, rt) {
- if(r.message) {
- frm.set_value("party_account_currency", r.message.account_currency);
- erpnext.payment_tool.check_mandatory_to_set_button(frm);
- }
- }
- });
- }
-})
-
-frappe.ui.form.on("Payment Tool", "company", function(frm) {
- erpnext.payment_tool.check_mandatory_to_set_button(frm);
-});
-
-frappe.ui.form.on("Payment Tool", "received_or_paid", function(frm) {
- erpnext.payment_tool.check_mandatory_to_set_button(frm);
-});
-
-// Fetch bank/cash account based on payment mode
-frappe.ui.form.on("Payment Tool", "payment_mode", function(frm) {
- return frappe.call({
- method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.get_bank_cash_account",
- args: {
- "mode_of_payment": frm.doc.payment_mode,
- "company": frm.doc.company
- },
- callback: function(r, rt) {
- if(r.message) {
- cur_frm.set_value("payment_account", r.message['account']);
- }
- }
- });
-});
-
-
-erpnext.payment_tool.check_mandatory_to_set_button = function(frm) {
- if (frm.doc.company && frm.doc.party_type && frm.doc.party && frm.doc.received_or_paid && frm.doc.party_account) {
- frm.fields_dict.get_outstanding_vouchers.$input.addClass("btn-primary");
- }
-}
-
-// Get outstanding vouchers
-frappe.ui.form.on("Payment Tool", "get_outstanding_vouchers", function(frm) {
- erpnext.payment_tool.check_mandatory_to_fetch(frm.doc);
-
- frm.set_value("vouchers", []);
-
- return frappe.call({
- method: 'erpnext.accounts.doctype.payment_tool.payment_tool.get_outstanding_vouchers',
- args: {
- args: {
- "company": frm.doc.company,
- "party_type": frm.doc.party_type,
- "received_or_paid": frm.doc.received_or_paid,
- "party": frm.doc.party,
- "party_account": frm.doc.party_account
- }
- },
- callback: function(r, rt) {
- if(r.message) {
- frm.fields_dict.get_outstanding_vouchers.$input.removeClass("btn-primary");
- frm.fields_dict.make_journal_entry.$input.addClass("btn-primary");
-
- frm.clear_table("vouchers");
-
- $.each(r.message, function(i, d) {
- var c = frm.add_child("vouchers");
- c.against_voucher_type = d.voucher_type;
- c.against_voucher_no = d.voucher_no;
- c.total_amount = d.invoice_amount;
- c.outstanding_amount = d.outstanding_amount;
-
- if (in_list(['Sales Invoice', 'Purchase Invoice'], d.voucher_type)){
- c.due_date = d.due_date
- }
-
- if (frm.doc.set_payment_amount) {
- c.payment_amount = d.outstanding_amount;
- }
- });
- }
- refresh_field("vouchers");
- frm.layout.refresh_sections();
- erpnext.payment_tool.set_total_payment_amount(frm);
- }
- });
-});
-
-// validate against_voucher_type
-frappe.ui.form.on("Payment Tool Detail", "against_voucher_type", function(frm, cdt, cdn) {
- var row = frappe.model.get_doc(cdt, cdn);
- erpnext.payment_tool.validate_against_voucher(frm, row);
-});
-
-erpnext.payment_tool.validate_against_voucher = function(frm, row) {
- var _validate = function(i, row) {
- if (!row.against_voucher_type) {
- return;
- }
-
- if(frm.doc.party_type=="Customer"
- && !in_list(["Sales Order", "Sales Invoice", "Journal Entry"], row.against_voucher_type)) {
- frappe.model.set_value(row.doctype, row.name, "against_voucher_type", "");
- frappe.msgprint(__("Against Voucher Type must be one of Sales Order, Sales Invoice or Journal Entry"));
- return false;
- }
-
- if(frm.doc.party_type=="Supplier"
- && !in_list(["Purchase Order", "Purchase Invoice", "Journal Entry"], row.against_voucher_type)) {
- frappe.model.set_value(row.doctype, row.name, "against_voucher_type", "");
- frappe.msgprint(__("Against Voucher Type must be one of Purchase Order, Purchase Invoice or Journal Entry"));
- return false;
- }
-
- }
-
- if (row) {
- _validate(0, row);
- } else {
- $.each(frm.doc.vouchers || [], _validate);
- }
-
-}
-
-// validate against_voucher_type
-frappe.ui.form.on("Payment Tool Detail", "against_voucher_no", function(frm, cdt, cdn) {
- var row = locals[cdt][cdn];
- if (!row.against_voucher_no) {
- return;
- }
-
- frappe.call({
- method: 'erpnext.accounts.doctype.payment_tool.payment_tool.get_against_voucher_details',
- args: {
- "against_voucher_type": row.against_voucher_type,
- "against_voucher_no": row.against_voucher_no,
- "party_account": frm.doc.party_account,
- "company": frm.doc.company
- },
- callback: function(r) {
- if(!r.exc) {
- $.each(r.message, function(k, v) {
- frappe.model.set_value(cdt, cdn, k, v);
- });
-
- frappe.model.set_value(cdt, cdn, "payment_amount", r.message.outstanding_amount);
- }
- }
- });
-});
-
-// Set total payment amount
-frappe.ui.form.on("Payment Tool Detail", "payment_amount", function(frm) {
- erpnext.payment_tool.set_total_payment_amount(frm);
-});
-
-frappe.ui.form.on("Payment Tool Detail", "vouchers_remove", function(frm) {
- erpnext.payment_tool.set_total_payment_amount(frm);
-});
-
-erpnext.payment_tool.set_total_payment_amount = function(frm) {
- var total_amount = 0.00;
- $.each(frm.doc.vouchers || [], function(i, row) {
- if (row.payment_amount && (row.payment_amount <= row.outstanding_amount)) {
- total_amount = total_amount + row.payment_amount;
- } else {
- if(row.payment_amount < 0)
- msgprint(__("Row {0}: Payment amount can not be negative", [row.idx]));
- else if(row.payment_amount > row.outstanding_amount)
- msgprint(__("Row {0}: Payment Amount cannot be greater than Outstanding Amount", [__(row.idx)]));
-
- frappe.model.set_value(row.doctype, row.name, "payment_amount", 0.0);
- }
- });
- frm.set_value("total_payment_amount", total_amount);
-}
-
-
-// Make Journal Entry
-frappe.ui.form.on("Payment Tool", "make_journal_entry", function(frm) {
- erpnext.payment_tool.check_mandatory_to_fetch(frm.doc);
-
- return frappe.call({
- method: 'make_journal_entry',
- doc: frm.doc,
- callback: function(r) {
- frm.fields_dict.make_journal_entry.$input.addClass("btn-primary");
- var doclist = frappe.model.sync(r.message);
- frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
- }
- });
-});
-
-erpnext.payment_tool.check_mandatory_to_fetch = function(doc) {
- $.each(["Company", "Party Type", "Party", "Received or Paid"], function(i, field) {
- if(!doc[frappe.model.scrub(field)]) frappe.throw(__("Please select {0} first", [field]));
- });
-}
diff --git a/erpnext/accounts/doctype/payment_tool/payment_tool.json b/erpnext/accounts/doctype/payment_tool/payment_tool.json
deleted file mode 100644
index a99054f..0000000
--- a/erpnext/accounts/doctype/payment_tool/payment_tool.json
+++ /dev/null
@@ -1,551 +0,0 @@
-{
- "allow_copy": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "creation": "2014-07-23 15:12:27.746665",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "fields": [
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "sec_break1",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Find Invoices to Match",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "company",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Company",
- "no_copy": 0,
- "options": "Company",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "default": "Customer",
- "fieldname": "party_type",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Party Type",
- "no_copy": 0,
- "options": "DocType",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "received_or_paid",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Received Or Paid",
- "no_copy": 0,
- "options": "Received\nPaid",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "col_break1",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "depends_on": "",
- "fieldname": "party",
- "fieldtype": "Dynamic Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Party",
- "no_copy": 0,
- "options": "party_type",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "party_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Party Account",
- "no_copy": 1,
- "options": "Account",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "party_account_currency",
- "fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Party Account Currency",
- "no_copy": 1,
- "options": "Currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "set_payment_amount",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Set Payment Amount = Outstanding Amount",
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "get_outstanding_vouchers",
- "fieldtype": "Button",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Get Outstanding Vouchers",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "depends_on": "eval:(doc.company && doc.party_type && doc.received_or_paid && doc.party_account)",
- "fieldname": "sec_break3",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Set Matching Amounts",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "vouchers",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Against Vouchers",
- "no_copy": 0,
- "options": "Payment Tool Detail",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "depends_on": "eval:(doc.company && doc.party_type && doc.received_or_paid && doc.party_account)",
- "fieldname": "section_break_19",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Make Payment Entry",
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "payment_mode",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Payment Mode",
- "no_copy": 0,
- "options": "Mode of Payment",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "payment_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Payment Account",
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "total_payment_amount",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Total Payment Amount",
- "no_copy": 0,
- "options": "party_account_currency",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "data_22",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "reference_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Reference Date",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "reference_no",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Reference No",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "make_journal_entry",
- "fieldtype": "Button",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Make Journal Entry",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "depends_on": "eval:(doc.company && doc.party_type && doc.received_or_paid && doc.party_account)",
- "fieldname": "section_break_21",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "make_jv_help",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- }
- ],
- "hide_heading": 0,
- "hide_toolbar": 1,
- "icon": "icon-magic",
- "in_create": 0,
- "in_dialog": 0,
- "is_submittable": 0,
- "issingle": 1,
- "istable": 0,
- "modified": "2015-10-01 09:43:24.199025",
- "modified_by": "Administrator",
- "module": "Accounts",
- "name": "Payment Tool",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 0,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 0,
- "read": 1,
- "report": 0,
- "role": "Accounts Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- },
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 0,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 0,
- "read": 1,
- "report": 0,
- "role": "Accounts User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- }
- ],
- "read_only": 0,
- "read_only_onload": 0,
- "sort_field": "modified",
- "sort_order": "DESC"
-}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_tool/payment_tool.py b/erpnext/accounts/doctype/payment_tool/payment_tool.py
deleted file mode 100644
index 5c5b393..0000000
--- a/erpnext/accounts/doctype/payment_tool/payment_tool.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-import frappe
-from frappe import _, scrub
-from frappe.utils import flt
-from frappe.model.document import Document
-import json
-from erpnext.accounts.utils import get_account_currency
-from erpnext.accounts.doctype.journal_entry.journal_entry import get_exchange_rate
-
-class PaymentTool(Document):
- def make_journal_entry(self):
- from erpnext.accounts.utils import get_balance_on
- total_payment_amount = 0.00
-
- jv = frappe.new_doc('Journal Entry')
- jv.voucher_type = 'Journal Entry'
- jv.company = self.company
- jv.cheque_no = self.reference_no
- jv.cheque_date = self.reference_date
-
- party_account_currency, party_account_type = frappe.db.get_value("Account", self.party_account,
- ["account_currency", "account_type"])
-
- bank_account_currency, bank_account_type = None, None
- if self.payment_account:
- bank_account_currency, bank_account_type = frappe.db.get_value("Account", self.payment_account,
- ["account_currency", "account_type"])
-
- if not self.total_payment_amount:
- frappe.throw(_("Please enter Payment Amount in atleast one row"))
-
- for v in self.get("vouchers"):
- if not frappe.db.get_value(v.against_voucher_type, {"name": v.against_voucher_no}):
- frappe.throw(_("Row {0}: {1} is not a valid {2}").format(v.idx, v.against_voucher_no,
- v.against_voucher_type))
-
- if v.payment_amount:
- exchange_rate = get_exchange_rate(self.party_account, party_account_currency,
- self.company, v.against_voucher_type, v.against_voucher_no)
-
- d1 = jv.append("accounts")
- d1.account = self.party_account
- d1.party_type = self.party_type
- d1.party = self.party
- d1.account_currency = party_account_currency
- d1.account_type = party_account_type
- d1.balance = get_balance_on(self.party_account)
- d1.party_balance = get_balance_on(party=self.party, party_type=self.party_type)
- d1.exchange_rate = exchange_rate
- d1.set("debit_in_account_currency" if self.received_or_paid=="Paid" \
- else "credit_in_account_currency", flt(v.payment_amount))
- d1.reference_type = v.against_voucher_type
- d1.reference_name = v.against_voucher_no
- d1.is_advance = 'Yes' \
- if v.against_voucher_type in ['Sales Order', 'Purchase Order'] else 'No'
-
- amount = flt(d1.debit_in_account_currency) - flt(d1.credit_in_account_currency)
- if bank_account_currency == party_account_currency:
- total_payment_amount += amount
- else:
- total_payment_amount += amount*exchange_rate
-
- d2 = jv.append("accounts")
- if self.payment_account:
- bank_account_currency, bank_account_type = frappe.db.get_value("Account", self.payment_account,
- ["account_currency", "account_type"])
-
- d2.account = self.payment_account
- d2.account_currency = bank_account_currency
- d2.account_type = bank_account_type
- d2.exchange_rate = get_exchange_rate(self.payment_account, bank_account_currency, self.company,
- debit=(abs(total_payment_amount) if total_payment_amount < 0 else 0),
- credit=(total_payment_amount if total_payment_amount > 0 else 0))
- d2.account_balance = get_balance_on(self.payment_account)
-
- amount_field_bank = 'debit_in_account_currency' if total_payment_amount < 0 \
- else 'credit_in_account_currency'
-
- d2.set(amount_field_bank, abs(total_payment_amount))
-
- company_currency = frappe.db.get_value("Company", self.company, "default_currency")
- if party_account_currency != company_currency or \
- (bank_account_currency and bank_account_currency != company_currency):
- jv.multi_currency = 1
-
- jv.set_amounts_in_company_currency()
- jv.set_total_debit_credit()
-
- return jv.as_dict()
-
-@frappe.whitelist()
-def get_outstanding_vouchers(args):
- from erpnext.accounts.utils import get_outstanding_invoices
-
- if not frappe.has_permission("Payment Tool"):
- frappe.throw(_("No permission to use Payment Tool"), frappe.PermissionError)
-
- args = json.loads(args)
-
- party_account_currency = get_account_currency(args.get("party_account"))
- company_currency = frappe.db.get_value("Company", args.get("company"), "default_currency")
-
- if ((args.get("party_type") == "Customer" and args.get("received_or_paid") == "Paid")
- or (args.get("party_type") == "Supplier" and args.get("received_or_paid") == "Received")):
-
- frappe.throw(_("Please enter the Against Vouchers manually"))
-
- # Get all outstanding sales /purchase invoices
- outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"), args.get("party_account"))
-
- # Get all SO / PO which are not fully billed or aginst which full advance not paid
- orders_to_be_billed = get_orders_to_be_billed(args.get("party_type"), args.get("party"),
- party_account_currency, company_currency)
-
- return outstanding_invoices + orders_to_be_billed
-
-def get_orders_to_be_billed(party_type, party, party_account_currency, company_currency):
- voucher_type = 'Sales Order' if party_type == "Customer" else 'Purchase Order'
-
- ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"
-
- orders = frappe.db.sql("""
- select
- name as voucher_no,
- {ref_field} as invoice_amount,
- ({ref_field} - advance_paid) as outstanding_amount,
- transaction_date as posting_date
- from
- `tab{voucher_type}`
- where
- {party_type} = %s
- and docstatus = 1
- and ifnull(status, "") != "Closed"
- and {ref_field} > advance_paid
- and abs(100 - per_billed) > 0.01
- """.format(**{
- "ref_field": ref_field,
- "voucher_type": voucher_type,
- "party_type": scrub(party_type)
- }), party, as_dict = True)
-
- order_list = []
- for d in orders:
- d["voucher_type"] = voucher_type
- order_list.append(d)
-
- return order_list
-
-@frappe.whitelist()
-def get_against_voucher_details(against_voucher_type, against_voucher_no, party_account, company):
- party_account_currency = get_account_currency(party_account)
- company_currency = frappe.db.get_value("Company", company, "default_currency")
- ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"
-
- if against_voucher_type in ["Sales Order", "Purchase Order"]:
- select_cond = "{0} as total_amount, {0} - advance_paid as outstanding_amount"\
- .format(ref_field)
- elif against_voucher_type in ["Sales Invoice", "Purchase Invoice"]:
- select_cond = "{0} as total_amount, outstanding_amount".format(ref_field)
- elif against_voucher_type == "Journal Entry":
- ref_field = "total_debit" if party_account_currency == company_currency else "total_debit/exchange_rate"
- select_cond = "{0} as total_amount".format(ref_field)
-
- details = frappe.db.sql("""select {0} from `tab{1}` where name = %s"""
- .format(select_cond, frappe.db.escape(against_voucher_type)), against_voucher_no, as_dict=1)
-
- return details[0] if details else {}
diff --git a/erpnext/accounts/doctype/payment_tool/test_payment_tool.py b/erpnext/accounts/doctype/payment_tool/test_payment_tool.py
deleted file mode 100644
index 4f1c9e9..0000000
--- a/erpnext/accounts/doctype/payment_tool/test_payment_tool.py
+++ /dev/null
@@ -1,175 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-from __future__ import unicode_literals
-import unittest, frappe, json
-from frappe.utils import flt
-from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
-from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
-from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import test_records as si_test_records
-from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import test_records as pi_test_records
-from erpnext.accounts.doctype.journal_entry.test_journal_entry import test_records as jv_test_records
-
-test_dependencies = ["Item"]
-
-class TestPaymentTool(unittest.TestCase):
- def test_make_journal_entry(self):
- self.clear_table_entries()
- frappe.db.set_default("currency", "INR")
-
- base_customer_jv = self.create_against_jv(jv_test_records[2], { "party": "_Test Customer 3"})
- base_supplier_jv = self.create_against_jv(jv_test_records[1], { "party": "_Test Supplier 1"})
-
-
- # Create SO with partial outstanding
- so1 = make_sales_order(customer="_Test Customer 3", qty=10, rate=100)
-
- self.create_against_jv(jv_test_records[0], {
- "party": "_Test Customer 3",
- "reference_type": "Sales Order",
- "reference_name": so1.name,
- "is_advance": "Yes"
- })
-
-
- #Create SO with no outstanding
- so2 = make_sales_order(customer="_Test Customer 3")
-
- self.create_against_jv(jv_test_records[0], {
- "party": "_Test Customer 3",
- "reference_type": "Sales Order",
- "reference_name": so2.name,
- "credit_in_account_currency": 1000,
- "is_advance": "Yes"
- })
-
- # Purchase order
- po = create_purchase_order(supplier="_Test Supplier 1")
-
- #Create SI with partial outstanding
- si1 = self.create_voucher(si_test_records[0], {
- "customer": "_Test Customer 3",
- "debit_to": "_Test Receivable - _TC"
- })
-
- self.create_against_jv(jv_test_records[0], {
- "party": "_Test Customer 3",
- "reference_type": si1.doctype,
- "reference_name": si1.name
- })
- #Create SI with no outstanding
- si2 = self.create_voucher(si_test_records[0], {
- "customer": "_Test Customer 3",
- "debit_to": "_Test Receivable - _TC"
- })
-
- self.create_against_jv(jv_test_records[0], {
- "party": "_Test Customer 3",
- "reference_type": si2.doctype,
- "reference_name": si2.name,
- "credit_in_account_currency": 561.80
- })
-
- pi = self.create_voucher(pi_test_records[0], {
- "supplier": "_Test Supplier 1",
- "credit_to": "_Test Payable - _TC"
- })
-
- #Create a dict containing properties and expected values
- expected_outstanding = {
- "Journal Entry" : [base_customer_jv.name, 400.00],
- "Sales Invoice" : [si1.name, 161.80],
- "Purchase Invoice" : [pi.name, 1512.30],
- "Sales Order" : [so1.name, 600.00],
- "Purchase Order" : [po.name, 5000.00]
- }
-
- args = {
- "company": "_Test Company",
- "party_type": "Customer",
- "received_or_paid": "Received",
- "party": "_Test Customer 3",
- "party_account": "_Test Receivable - _TC",
- "payment_mode": "Cheque",
- "payment_account": "_Test Bank - _TC",
- "reference_no": "123456",
- "reference_date": "2013-02-14"
- }
-
- self.make_voucher_for_party(args, expected_outstanding)
-
- args.update({
- "party_type": "Supplier",
- "received_or_paid": "Paid",
- "party": "_Test Supplier 1",
- "party_account": "_Test Payable - _TC"
- })
- expected_outstanding["Journal Entry"] = [base_supplier_jv.name, 400.00]
- self.make_voucher_for_party(args, expected_outstanding)
-
- def create_voucher(self, test_record, args):
- doc = frappe.copy_doc(test_record)
- doc.update(args)
- doc.insert()
- doc.submit()
- return doc
-
- def create_against_jv(self, test_record, args):
- jv = frappe.copy_doc(test_record)
- jv.get("accounts")[0].update(args)
- if args.get("debit_in_account_currency"):
- jv.get("accounts")[1].credit_in_account_currency = args["debit_in_account_currency"]
- elif args.get("credit_in_account_currency"):
- jv.get("accounts")[1].debit_in_account_currency = args["credit_in_account_currency"]
-
- jv.insert()
- jv.submit()
- return jv
-
- def make_voucher_for_party(self, args, expected_outstanding):
- #Make Journal Entry for Party
- payment_tool_doc = frappe.new_doc("Payment Tool")
-
- for k, v in args.items():
- payment_tool_doc.set(k, v)
-
- self.check_outstanding_vouchers(payment_tool_doc, args, expected_outstanding)
-
-
- def check_outstanding_vouchers(self, doc, args, expected_outstanding):
- from erpnext.accounts.doctype.payment_tool.payment_tool import get_outstanding_vouchers
- outstanding_entries = get_outstanding_vouchers(json.dumps(args))
-
- for d in outstanding_entries:
- self.assertEquals(flt(d.get("outstanding_amount"), 2),
- expected_outstanding.get(d.get("voucher_type"))[1])
-
- self.check_jv_entries(doc, outstanding_entries, expected_outstanding)
-
- def check_jv_entries(self, paytool, outstanding_entries, expected_outstanding):
- for e in outstanding_entries:
- d1 = paytool.append("vouchers")
- d1.against_voucher_type = e.get("voucher_type")
- d1.against_voucher_no = e.get("voucher_no")
- d1.total_amount = e.get("invoice_amount")
- d1.outstanding_amount = e.get("outstanding_amount")
- d1.payment_amount = 100.00
- paytool.total_payment_amount = 300
-
- new_jv = paytool.make_journal_entry()
- for jv_entry in new_jv.get("accounts"):
- if paytool.party_account == jv_entry.get("account") and paytool.party == jv_entry.get("party"):
- self.assertEquals(100.00, jv_entry.get("debit_in_account_currency"
- if paytool.party_type=="Supplier" else "credit_in_account_currency"))
- self.assertEquals(jv_entry.reference_name,
- expected_outstanding[jv_entry.reference_type][0])
-
- self.assertEquals(new_jv.get("cheque_no"), paytool.reference_no)
- self.assertEquals(new_jv.get("cheque_date"), paytool.reference_date)
-
- def clear_table_entries(self):
- frappe.db.sql("""delete from `tabGL Entry` where party in ("_Test Customer 3", "_Test Supplier 1")""")
- frappe.db.sql("""delete from `tabSales Order` where customer = "_Test Customer 3" """)
- frappe.db.sql("""delete from `tabSales Invoice` where customer = "_Test Customer 3" """)
- frappe.db.sql("""delete from `tabPurchase Order` where supplier = "_Test Supplier 1" """)
- frappe.db.sql("""delete from `tabPurchase Invoice` where supplier = "_Test Supplier 1" """)
diff --git a/erpnext/accounts/doctype/payment_tool_detail/__init__.py b/erpnext/accounts/doctype/payment_tool_detail/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/accounts/doctype/payment_tool_detail/__init__.py
+++ /dev/null
diff --git a/erpnext/accounts/doctype/payment_tool_detail/payment_tool_detail.json b/erpnext/accounts/doctype/payment_tool_detail/payment_tool_detail.json
deleted file mode 100644
index 0eb37b5..0000000
--- a/erpnext/accounts/doctype/payment_tool_detail/payment_tool_detail.json
+++ /dev/null
@@ -1,213 +0,0 @@
-{
- "allow_copy": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 0,
- "creation": "2014-08-11 14:27:54.463897",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "fields": [
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "against_voucher_type",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Against Voucher Type",
- "length": 0,
- "no_copy": 0,
- "options": "DocType",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "",
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0,
- "width": ""
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "against_voucher_no",
- "fieldtype": "Dynamic Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Against Voucher No",
- "length": 0,
- "no_copy": 0,
- "options": "against_voucher_type",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "due_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Due Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "column_break_3",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "total_amount",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Total Amount",
- "length": 0,
- "no_copy": 0,
- "options": "party_account_currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "outstanding_amount",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Outstanding Amount",
- "length": 0,
- "no_copy": 0,
- "options": "party_account_currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "payment_amount",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Payment Amount",
- "length": 0,
- "no_copy": 0,
- "options": "party_account_currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- }
- ],
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "in_dialog": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 1,
- "max_attachments": 0,
- "modified": "2016-07-11 03:28:03.793149",
- "modified_by": "Administrator",
- "module": "Accounts",
- "name": "Payment Tool Detail",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_seen": 0
-}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_tool_detail/payment_tool_detail.py b/erpnext/accounts/doctype/payment_tool_detail/payment_tool_detail.py
deleted file mode 100644
index 21fd1c6..0000000
--- a/erpnext/accounts/doctype/payment_tool_detail/payment_tool_detail.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-import frappe
-from frappe.model.document import Document
-
-class PaymentToolDetail(Document):
- pass
diff --git a/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json b/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json
index c5f8b56..d73fa99 100644
--- a/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json
+++ b/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json
@@ -70,7 +70,7 @@
"bold": 0,
"collapsible": 0,
"fieldname": "remarks",
- "fieldtype": "Read Only",
+ "fieldtype": "Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -85,7 +85,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": "150px",
- "read_only": 0,
+ "read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -214,7 +214,7 @@
"istable": 1,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2016-07-11 03:28:04.828022",
+ "modified": "2016-07-18 05:13:42.137419",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice Advance",
@@ -223,5 +223,6 @@
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
+ "sort_order": "DESC",
"track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py
index c6191da..f986eea 100644
--- a/erpnext/accounts/doctype/sales_invoice/pos.py
+++ b/erpnext/accounts/doctype/sales_invoice/pos.py
@@ -114,12 +114,28 @@
item.cost_center = pos_profile.get('cost_center') or item_doc.selling_cost_center
item.actual_qty = frappe.db.get_value('Bin', {'item_code': item.name,
'warehouse': item.default_warehouse}, 'actual_qty') or 0
- item.serial_nos = frappe.db.sql_list("""select name from `tabSerial No` where warehouse= %(warehouse)s
- and item_code = %(item_code)s""", {'warehouse': item.default_warehouse, 'item_code': item.item_code})
+ item.serial_nos = get_serial_nos(item, pos_profile)
+ item.batch_nos = frappe.db.sql_list("""select name from `tabBatch` where expiry_date > curdate()
+ and item = %(item_code)s""", {'item_code': item.item_code})
+
item_list.append(item)
return item_list
+def get_serial_nos(item, pos_profile):
+ cond = "1=1"
+ if pos_profile.get('update_stock') and pos_profile.get('warehouse'):
+ cond = "warehouse = '{0}'".format(pos_profile.get('warehouse'))
+
+ serial_nos = frappe.db.sql("""select name, warehouse from `tabSerial No` where {0}
+ and item_code = %(item_code)s""".format(cond), {'item_code': item.item_code}, as_dict=1)
+
+ serial_no_list = {}
+ for serial_no in serial_nos:
+ serial_no_list[serial_no.name] = serial_no.warehouse
+
+ return serial_no_list
+
def get_customers(pos_profile, doc):
filters = {'disabled': 0}
customer_list = []
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 64379a1..b73673f 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -263,6 +263,10 @@
});
}
}
+ },
+
+ amount: function(){
+ this.write_off_outstanding_amount_automatically()
}
});
@@ -454,13 +458,6 @@
]
}
}
-
- if(frm.doc.is_pos){
- frm.get_field('payments').grid.editable_fields = [
- {fieldname: 'mode_of_payment', columns: 2},
- {fieldname: 'amount', columns: 2}
- ];
- }
},
})
diff --git a/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json b/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json
index 43557cc..069ac3a 100644
--- a/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json
+++ b/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json
@@ -70,7 +70,7 @@
"bold": 0,
"collapsible": 0,
"fieldname": "remarks",
- "fieldtype": "Read Only",
+ "fieldtype": "Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -85,7 +85,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": "150px",
- "read_only": 0,
+ "read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -214,7 +214,7 @@
"istable": 1,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2016-07-11 03:28:07.359049",
+ "modified": "2016-07-18 05:13:21.819598",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Advance",
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
index 351cd56..28964bb 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
@@ -12,8 +12,9 @@
valdiate_taxes_and_charges_template(self)
def valdiate_taxes_and_charges_template(doc):
- if not doc.is_default and not frappe.get_all(doc.doctype, filters={"is_default": 1}):
- doc.is_default = 1
+ # default should not be disabled
+ # if not doc.is_default and not frappe.get_all(doc.doctype, filters={"is_default": 1}):
+ # doc.is_default = 1
if doc.is_default == 1:
frappe.db.sql("""update `tab{0}` set is_default = 0
diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js
index 9211657..bc07aca 100644
--- a/erpnext/accounts/page/pos/pos.js
+++ b/erpnext/accounts/page/pos/pos.js
@@ -400,7 +400,8 @@
// To search item as per the key enter
var me = this;
- this.item_serial_no = {}
+ this.item_serial_no = {};
+ this.item_batch_no = {};
if(item_code){
return $.grep(window.items, function(item){
@@ -417,11 +418,13 @@
if( (item.item_code.toLowerCase().match(key)) ||
(item.item_name.toLowerCase().match(key)) || (item.item_group.toLowerCase().match(key)) ){
return true
- }else if(item.barcode){
- return item.barcode == me.search.$input.val()
- } else if (in_list(item.serial_nos, me.search.$input.val())){
- me.item_serial_no[item.item_code] = me.search.$input.val()
+ }else if(item.barcode == me.search.$input.val()){
+ return item.barcode == me.search.$input.val();
+ } else if (in_list(Object.keys(item.serial_nos), me.search.$input.val())){
+ me.item_serial_no[item.item_code] = [me.search.$input.val(), item.serial_nos[me.search.$input.val()]]
return true
+ } else if(in_list(item.batch_nos, me.search.$input.val())){
+ return me.item_batch_no[item.item_code] = me.search.$input.val()
}
})
}else{
@@ -467,6 +470,13 @@
this.remove_item = []
$.each(this.frm.doc["items"] || [], function(i, d) {
+ if (d.item_code == item_code && d.serial_no
+ && field == 'qty' && cint(value) != value) {
+ d.qty = 0.0;
+ me.refresh();
+ frappe.throw(__("Serial no item cannot be a fraction"))
+ }
+
if (d.item_code == item_code) {
d[field] = flt(value);
d.amount = flt(d.rate) * flt(d.qty);
@@ -536,7 +546,9 @@
var caught = false;
var no_of_items = me.wrapper.find(".pos-bill-item").length;
- this.validate_serial_no()
+ this.customer_validate();
+ this.mandatory_batch_no();
+ this.validate_serial_no();
this.validate_warehouse();
if (no_of_items != 0) {
@@ -544,9 +556,14 @@
if (d.item_code == me.items[0].item_code) {
caught = true;
d.qty += 1;
- d.amount = flt(d.rate) * flt(d.qty)
- if(me.item_serial_no.length){
- d.serial_no += '\n' + me.item_serial_no[d.item_code]
+ d.amount = flt(d.rate) * flt(d.qty);
+ if(me.item_serial_no[d.item_code]){
+ d.serial_no += '\n' + me.item_serial_no[d.item_code][0]
+ d.warehouse = me.item_serial_no[d.item_code][1]
+ }
+
+ if(me.item_batch_no.length){
+ d.batch_no = me.item_batch_no[d.item_code]
}
}
});
@@ -570,12 +587,15 @@
this.child.item_group = this.items[0].item_group;
this.child.cost_center = this.items[0].cost_center;
this.child.income_account = this.items[0].income_account;
- this.child.warehouse = this.items[0].default_warehouse;
+ this.child.warehouse = (this.item_serial_no[this.child.item_code]
+ ? this.item_serial_no[this.child.item_code][1] : this.items[0].default_warehouse);
this.child.price_list_rate = flt(this.items[0].price_list_rate, 9) / flt(this.frm.doc.conversion_rate, 9);
this.child.rate = flt(this.items[0].price_list_rate, 9) / flt(this.frm.doc.conversion_rate, 9);
this.child.actual_qty = this.items[0].actual_qty;
this.child.amount = flt(this.child.qty) * flt(this.child.rate);
- this.child.serial_no = this.item_serial_no[this.child.item_code];
+ this.child.batch_no = this.item_batch_no[this.child.item_code];
+ this.child.serial_no = (this.item_serial_no[this.child.item_code]
+ ? this.item_serial_no[this.child.item_code][0] : '');
},
refresh: function() {
@@ -759,7 +779,7 @@
$(this.wrapper).find('input').attr("disabled", false);
if(this.frm.doc.docstatus == 1){
- pointer_events = 'none'
+ pointer_events = 'none';
$(this.wrapper).find('input').attr("disabled", true);
}
@@ -789,7 +809,7 @@
$.each(this.si_docs, function(index, data){
for(key in data){
if(key == me.name){
- me.si_docs[index][key] = me.frm.doc
+ me.si_docs[index][key] = me.frm.doc;
me.update_localstorage();
}
}
@@ -821,7 +841,7 @@
sync_sales_invoice: function(){
var me = this;
- this.si_docs = this.get_submitted_invoice()
+ this.si_docs = this.get_submitted_invoice();
if(this.si_docs.length){
frappe.call({
@@ -860,12 +880,12 @@
remove_doc_from_localstorage: function(){
var me = this;
this.si_docs = this.get_doc_from_localstorage();
- this.new_si_docs = []
+ this.new_si_docs = [];
if(this.removed_items){
$.each(this.si_docs, function(index, data){
for(key in data){
if(!in_list(me.removed_items, key)){
- me.new_si_docs.push(data)
+ me.new_si_docs.push(data);
}
}
})
@@ -878,7 +898,7 @@
var me = this;
this.customer_validate();
this.item_validate();
- this.validate_mode_of_payments()
+ this.validate_mode_of_payments();
},
item_validate: function(){
@@ -898,7 +918,7 @@
var item_code = serial_no = '';
for (key in this.item_serial_no){
item_code = key;
- serial_no = me.item_serial_no[key]
+ serial_no = me.item_serial_no[key][0];
}
if(item_code && serial_no){
@@ -912,6 +932,21 @@
}
})
}
+
+ if(this.items[0].has_serial_no && serial_no == ""){
+ frappe.throw(__(repl("Error: Serial no is mandatory for item %(item)s", {
+ 'item': this.items[0].item_code
+ })))
+ }
+ },
+
+ mandatory_batch_no: function(){
+ var me = this;
+ if(this.items[0].has_batch_no && !this.item_batch_no[this.items[0].item_code]){
+ frappe.throw(__(repl("Error: Batch no is mandatory for item %(item)s", {
+ 'item': this.items[0].item_code
+ })))
+ }
},
apply_pricing_rule: function(){
diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js
index c684715..1806d93 100644
--- a/erpnext/buying/doctype/purchase_common/purchase_common.js
+++ b/erpnext/buying/doctype/purchase_common/purchase_common.js
@@ -14,7 +14,7 @@
this._super();
if(!in_list(["Material Request", "Request for Quotation"], this.frm.doc.doctype)){
this.frm.get_field('items').grid.editable_fields = [
- {fieldname: 'item_code', columns: 4},
+ {fieldname: 'item_code', columns: 3},
{fieldname: 'qty', columns: 2},
{fieldname: 'rate', columns: 3},
{fieldname: 'amount', columns: 2}
diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js
index ce1c088..5eafb81 100644
--- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js
+++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js
@@ -16,7 +16,7 @@
}
frm.get_field('items').grid.editable_fields = [
- {fieldname: 'item_code', columns: 4},
+ {fieldname: 'item_code', columns: 3},
{fieldname: 'qty', columns: 2},
{fieldname: 'schedule_date', columns: 2},
{fieldname: 'warehouse', columns: 3},
diff --git a/erpnext/config/accounts.py b/erpnext/config/accounts.py
index 66b59a5..a0fcb63 100644
--- a/erpnext/config/accounts.py
+++ b/erpnext/config/accounts.py
@@ -131,11 +131,6 @@
"items": [
{
"type": "doctype",
- "name": "Payment Tool",
- "description": _("Create Payment Entries against Orders or Invoices.")
- },
- {
- "type": "doctype",
"label": _("Update Bank Transaction Dates"),
"name": "Bank Reconciliation",
"description": _("Update bank payment dates with journals.")
diff --git a/erpnext/controllers/item_variant.py b/erpnext/controllers/item_variant.py
index 8294b64..ba1d242 100644
--- a/erpnext/controllers/item_variant.py
+++ b/erpnext/controllers/item_variant.py
@@ -58,12 +58,13 @@
is_incremental = remainder==0 or remainder==increment
if not (is_in_range and is_incremental):
- frappe.throw(_("Value for Attribute {0} must be within the range of {1} to {2} in the increments of {3} for Item {2}")\
- .format(attribute, from_range, to_range, increment, item.name), InvalidItemAttributeValueError)
+ frappe.throw(_("Value for Attribute {0} must be within the range of {1} to {2} in the increments of {3} for Item {4}")\
+ .format(attribute, from_range, to_range, increment, item.name),
+ InvalidItemAttributeValueError, title=_('Invalid Attribute'))
elif value not in attribute_values.get(attribute.lower(), []):
frappe.throw(_("Value {0} for Attribute {1} does not exist in the list of valid Item Attribute Values for Item {2}").format(
- value, attribute, item.name), InvalidItemAttributeValueError)
+ value, attribute, item.name), InvalidItemAttributeValueError, title=_('Invalid Attribute'))
def get_attribute_values():
if not frappe.flags.attribute_values:
diff --git a/erpnext/demo/setup_data.py b/erpnext/demo/setup_data.py
index 5245063..0903482 100644
--- a/erpnext/demo/setup_data.py
+++ b/erpnext/demo/setup_data.py
@@ -3,7 +3,8 @@
import random, json
from erpnext.demo.domains import data
import frappe, erpnext
-from frappe.utils import cint, flt
+from frappe.utils import cint, flt, now_datetime, cstr
+from frappe import _
def setup_data():
domain = frappe.flags.domain
@@ -28,6 +29,7 @@
setup_employee()
setup_salary_structure()
setup_salary_structure_for_timesheet()
+ setup_account_to_expense_type()
setup_user_roles()
frappe.db.commit()
frappe.clear_cache()
@@ -64,11 +66,11 @@
def setup_fiscal_year():
fiscal_year = None
- for year in xrange(2014, frappe.utils.now_datetime().year + 1, 1):
+ for year in xrange(2014, now_datetime().year + 1, 1):
try:
fiscal_year = frappe.get_doc({
"doctype": "Fiscal Year",
- "year": frappe.utils.cstr(year),
+ "year": cstr(year),
"year_start_date": "{0}-01-01".format(year),
"year_end_date": "{0}-12-31".format(year)
}).insert()
@@ -80,7 +82,7 @@
def setup_holiday_list():
"""Setup Holiday List for the current year"""
- year = frappe.utils.now_datetime().year
+ year = now_datetime().year
holiday_list = frappe.get_doc({
"doctype": "Holiday List",
"holiday_list_name": str(year),
@@ -306,6 +308,21 @@
doc.parent_account = frappe.db.get_value('Account', {'account_name': doc.parent_account})
doc.insert()
+def setup_account_to_expense_type():
+ expense_types = [{'name': _('Calls'), "account": "Sales Expenses - WPL"},
+ {'name': _('Food'), "account": "Entertainment Expenses - WPL"},
+ {'name': _('Medical'), "account": "Utility Expenses - WPL"},
+ {'name': _('Others'), "account": "Miscellaneous Expenses - WPL"},
+ {'name': _('Travel'), "account": "Travel Expenses - WPL"}]
+
+ for expense_type in expense_types:
+ doc = frappe.get_doc("Expense Claim Type", expense_type["name"])
+ doc.append("accounts", {
+ "company" : erpnext.get_default_company(),
+ "default_account" : expense_type["account"]
+ })
+ doc.save(ignore_permissions=True)
+
def setup_user_roles():
if not frappe.db.get_global('demo_hr_user'):
user = frappe.get_doc('User', 'CharmaineGaudreau@example.com')
diff --git a/erpnext/demo/user/hr.py b/erpnext/demo/user/hr.py
index 86fb526..bd86507 100644
--- a/erpnext/demo/user/hr.py
+++ b/erpnext/demo/user/hr.py
@@ -5,6 +5,7 @@
from erpnext.projects.doctype.timesheet.test_timesheet import make_timesheet
from erpnext.projects.doctype.timesheet.timesheet import make_salary_slip, make_sales_invoice
from frappe.utils.make_random import how_many, get_random
+from erpnext.hr.doctype.expense_claim.expense_claim import get_expense_approver, make_bank_entry
def work():
frappe.set_user(frappe.db.get_global('demo_hr_user'))
@@ -30,6 +31,61 @@
if frappe.db.get_global('demo_hr_user'):
make_timesheet_records()
+
+ #expense claim
+ expense_claim = frappe.new_doc("Expense Claim")
+ expense_claim.extend('expenses', get_expenses())
+ expense_claim.employee = get_random("Employee")
+ expense_claim.company = frappe.flags.company
+ expense_claim.posting_date = frappe.flags.current_date
+ expense_claim.exp_approver = filter((lambda x: x[0] != 'Administrator'), get_expense_approver(None, '', None, 0, 20, None))[0][0]
+ expense_claim.insert()
+
+ rand = random.random()
+
+ if rand < 0.4:
+ expense_claim.approval_status = "Approved"
+ update_sanctioned_amount(expense_claim)
+ expense_claim.submit()
+
+ if random.randint(0, 1):
+ #make journal entry against expense claim
+ je = frappe.get_doc(make_bank_entry(expense_claim.name))
+ je.posting_date = frappe.flags.current_date
+ je.cheque_no = random_string(10)
+ je.cheque_date = frappe.flags.current_date
+ je.flags.ignore_permissions = 1
+ je.submit()
+
+ elif rand < 0.2:
+ expense_claim.approval_status = "Rejected"
+ expense_claim.submit()
+
+def get_expenses():
+ expenses = []
+ expese_types = frappe.db.sql("""select ect.name, eca.default_account from `tabExpense Claim Type` ect,
+ `tabExpense Claim Account` eca where eca.parent=ect.name
+ and eca.company=%s """, frappe.flags.company,as_dict=1)
+
+ for expense_type in expese_types[:random.randint(1,4)]:
+ claim_amount = random.randint(1,20)*10
+
+ expenses.append({
+ "expense_date": frappe.flags.current_date,
+ "expense_type": expense_type.name,
+ "default_account": expense_type.default_account or "Miscellaneous Expenses - WPL",
+ "claim_amount": claim_amount,
+ "sanctioned_amount": claim_amount
+ })
+
+ return expenses
+
+def update_sanctioned_amount(expense_claim):
+ for expense in expense_claim.expenses:
+ sanctioned_amount = random.randint(1,20)*10
+
+ if sanctioned_amount < expense.claim_amount:
+ expense.sanctioned_amount = sanctioned_amount
def get_timesheet_based_salary_slip_employee():
return frappe.get_all('Salary Structure', fields = ["distinct employee as name"],
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js
index bafa008..bcd8bc0 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.js
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.js
@@ -7,39 +7,30 @@
make_bank_entry: function() {
var me = this;
return frappe.call({
- method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_default_bank_cash_account",
+ method: "erpnext.hr.doctype.expense_claim.expense_claim.make_bank_entry",
args: {
- "company": cur_frm.doc.company,
- "account_type": "Bank"
+ "docname": cur_frm.doc.name,
},
callback: function(r) {
- var jv = frappe.model.make_new_doc_and_get_name('Journal Entry');
- jv = locals['Journal Entry'][jv];
- jv.voucher_type = 'Bank Entry';
- jv.company = cur_frm.doc.company;
- jv.remark = 'Payment against Expense Claim: ' + cur_frm.doc.name;
- var expense = cur_frm.doc.expenses || [];
- for(var i = 0; i < expense.length; i++){
- var d1 = frappe.model.add_child(jv, 'Journal Entry Account', 'accounts');
- d1.account = expense[i].default_account;
- d1.debit_in_account_currency = expense[i].sanctioned_amount;
- d1.reference_type = cur_frm.doc.doctype;
- d1.reference_name = cur_frm.doc.name;
- }
+ var doc = frappe.model.sync(r.message);
+ frappe.set_route('Form', 'Journal Entry', r.message.name);
+ }
+ });
+ },
+
+ expense_type: function(frm, cdt, cdn) {
+ var d = locals[cdt][cdn];
- // credit to bank
- var d1 = frappe.model.add_child(jv, 'Journal Entry Account', 'accounts');
- d1.credit_in_account_currency = cur_frm.doc.total_sanctioned_amount;
- d1.reference_type = cur_frm.doc.doctype;
- d1.reference_name = cur_frm.doc.name;
- if(r.message) {
- d1.account = r.message.account;
- d1.balance = r.message.balance;
- d1.account_currency = r.message.account_currency;
- d1.account_type = r.message.account_type;
+ return frappe.call({
+ method: "erpnext.hr.doctype.expense_claim.expense_claim.get_expense_claim_account",
+ args: {
+ "expense_claim_type": d.expense_type,
+ "company": frm.company
+ },
+ callback: function(r) {
+ if (r.message) {
+ d.default_account = r.message.account;
}
-
- frappe.set_route('Form', 'Journal Entry', jv.name);
}
});
}
@@ -49,7 +40,6 @@
cur_frm.add_fetch('employee', 'company', 'company');
cur_frm.add_fetch('employee','employee_name','employee_name');
-cur_frm.add_fetch('expense_type', 'default_account', 'default_account');
cur_frm.cscript.onload = function(doc,cdt,cdn) {
if(!doc.approval_status)
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py
index 2e3ad66..efdee97 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.py
@@ -20,6 +20,7 @@
self.validate_expense_approver()
self.calculate_total_amount()
set_employee_name(self)
+ self.set_expense_account()
if self.task and not self.project:
self.project = frappe.db.get_value("Task", self.task, "project")
@@ -59,7 +60,11 @@
if flt(d.sanctioned_amount) > flt(d.claim_amount):
frappe.throw(_("Sanctioned Amount cannot be greater than Claim Amount in Row {0}.").format(d.idx))
-
+ def set_expense_account(self):
+ for expense in self.expenses:
+ if not expense.default_account:
+ expense.default_account = get_expense_claim_account(expense.expense_type, self.company)["account"]
+
@frappe.whitelist()
def get_expense_approver(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql("""
@@ -68,3 +73,48 @@
where u.name = r.parent and r.role = 'Expense Approver'
and u.enabled = 1 and u.name like %s
""", ("%" + txt + "%"))
+
+@frappe.whitelist()
+def make_bank_entry(docname):
+ from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
+
+ expense_claim = frappe.get_doc("Expense Claim", docname)
+ default_bank_cash_account = get_default_bank_cash_account(expense_claim.company, "Bank")
+
+ je = frappe.new_doc("Journal Entry")
+ je.voucher_type = 'Bank Entry'
+ je.company = expense_claim.company
+ je.remark = 'Payment against Expense Claim: ' + docname;
+
+ for expense in expense_claim.expenses:
+ je.append("accounts", {
+ "account": expense.default_account,
+ "debit_in_account_currency": expense.sanctioned_amount,
+ "reference_type": "Expense Claim",
+ "reference_name": expense_claim.name
+ })
+
+ je.append("accounts", {
+ "account": default_bank_cash_account.account,
+ "credit_in_account_currency": expense_claim.total_sanctioned_amount,
+ "reference_type": "Expense Claim",
+ "reference_name": expense_claim.name,
+ "balance": default_bank_cash_account.balance,
+ "account_currency": default_bank_cash_account.account_currency,
+ "account_type": default_bank_cash_account.account_type
+ })
+
+ return je.as_dict()
+
+@frappe.whitelist()
+def get_expense_claim_account(expense_claim_type, company):
+ account = frappe.db.get_value("Expense Claim Account",
+ {"parent": expense_claim_type, "company": company}, "default_account")
+
+ if not account:
+ frappe.throw(_("Please set default account in Expense Claim Type {0}")
+ .format(expense_claim_type))
+
+ return {
+ "account": account
+ }
\ No newline at end of file
diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.py b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
index b21f2a1..59d686e 100644
--- a/erpnext/hr/doctype/expense_claim/test_expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
@@ -30,7 +30,7 @@
"project": "_Test Project 1",
"task": task_name,
"expenses":
- [{ "expense_type": "Food", "claim_amount": 300, "sanctioned_amount": 200 }]
+ [{ "expense_type": "Food", "default_account": "Entertainment Expenses - _TC", "claim_amount": 300, "sanctioned_amount": 200 }]
})
expense_claim.submit()
@@ -44,7 +44,7 @@
"project": "_Test Project 1",
"task": task_name,
"expenses":
- [{ "expense_type": "Food", "claim_amount": 600, "sanctioned_amount": 500 }]
+ [{ "expense_type": "Food", "default_account": "Entertainment Expenses - _TC", "claim_amount": 600, "sanctioned_amount": 500 }]
})
expense_claim2.submit()
diff --git a/erpnext/accounts/doctype/payment_tool/__init__.py b/erpnext/hr/doctype/expense_claim_account/__init__.py
similarity index 100%
rename from erpnext/accounts/doctype/payment_tool/__init__.py
rename to erpnext/hr/doctype/expense_claim_account/__init__.py
diff --git a/erpnext/hr/doctype/expense_claim_account/expense_claim_account.json b/erpnext/hr/doctype/expense_claim_account/expense_claim_account.json
new file mode 100644
index 0000000..a2bbe0b
--- /dev/null
+++ b/erpnext/hr/doctype/expense_claim_account/expense_claim_account.json
@@ -0,0 +1,89 @@
+{
+ "allow_copy": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2016-07-18 12:24:16.507860",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "fields": [
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Company",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "default_account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Default Account",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Account",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "in_dialog": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2016-07-18 12:39:29.709848",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Expense Claim Account",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/expense_claim_account/expense_claim_account.py b/erpnext/hr/doctype/expense_claim_account/expense_claim_account.py
new file mode 100644
index 0000000..f34633c
--- /dev/null
+++ b/erpnext/hr/doctype/expense_claim_account/expense_claim_account.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class ExpenseClaimAccount(Document):
+ pass
diff --git a/erpnext/hr/doctype/expense_claim_type/expense_claim_type.js b/erpnext/hr/doctype/expense_claim_type/expense_claim_type.js
new file mode 100644
index 0000000..fda6809
--- /dev/null
+++ b/erpnext/hr/doctype/expense_claim_type/expense_claim_type.js
@@ -0,0 +1,17 @@
+// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+// License: GNU General Public License v3. See license.txt
+
+frappe.ui.form.on("Expense Claim Type", {
+ refresh: function(frm){
+ frm.fields_dict["accounts"].grid.get_field("default_account").get_query = function(frm, cdt, cdn){
+ var d = locals[cdt][cdn];
+ return{
+ filters: {
+ "is_group": 0,
+ "root_type": "Expense",
+ 'company': d.company
+ }
+ }
+ }
+ }
+})
diff --git a/erpnext/hr/doctype/expense_claim_type/expense_claim_type.json b/erpnext/hr/doctype/expense_claim_type/expense_claim_type.json
index 460b3b8..3d2b251 100644
--- a/erpnext/hr/doctype/expense_claim_type/expense_claim_type.json
+++ b/erpnext/hr/doctype/expense_claim_type/expense_claim_type.json
@@ -3,11 +3,13 @@
"allow_import": 1,
"allow_rename": 0,
"autoname": "field:expense_type",
+ "beta": 0,
"creation": "2012-03-27 14:35:55",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
+ "editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
@@ -17,6 +19,7 @@
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Expense Claim Type",
@@ -26,6 +29,7 @@
"oldfieldtype": "Data",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
@@ -37,34 +41,11 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "fieldname": "default_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Default Account",
- "length": 0,
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
"fieldname": "description",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Description",
@@ -74,6 +55,7 @@
"oldfieldtype": "Small Text",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -81,19 +63,46 @@
"set_only_once": 0,
"unique": 0,
"width": "300px"
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "accounts",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Accounts",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Expense Claim Account",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-flag",
"idx": 1,
+ "image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2015-11-16 06:29:47.084611",
+ "modified": "2016-07-18 12:36:10.096252",
"modified_by": "Administrator",
"module": "HR",
"name": "Expense Claim Type",
@@ -140,6 +149,9 @@
"write": 0
}
],
+ "quick_entry": 0,
"read_only": 0,
- "read_only_onload": 0
+ "read_only_onload": 0,
+ "sort_order": "ASC",
+ "track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/expense_claim_type/expense_claim_type.py b/erpnext/hr/doctype/expense_claim_type/expense_claim_type.py
index 91f3bcb..5e6a7a8 100644
--- a/erpnext/hr/doctype/expense_claim_type/expense_claim_type.py
+++ b/erpnext/hr/doctype/expense_claim_type/expense_claim_type.py
@@ -3,8 +3,25 @@
from __future__ import unicode_literals
import frappe
-
+from frappe import _
from frappe.model.document import Document
class ExpenseClaimType(Document):
- pass
\ No newline at end of file
+ def validate(self):
+ self.validate_accounts()
+ self.validate_repeating_companies()
+
+ def validate_repeating_companies(self):
+ """Error when Same Company is entered multiple times in accounts"""
+ accounts_list = []
+ for entry in self.accounts:
+ accounts_list.append(entry.company)
+
+ if len(accounts_list)!= len(set(accounts_list)):
+ frappe.throw(_("Same Company is entered more than once"))
+
+ def validate_accounts(self):
+ for entry in self.accounts:
+ """Error when Company of Ledger account doesn't match with Company Selected"""
+ if frappe.db.get_value("Account", entry.default_account, "company") != entry.company:
+ frappe.throw(_("Account does not match with Company"))
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js
index 832402e..2fbdbcb 100644
--- a/erpnext/manufacturing/doctype/bom/bom.js
+++ b/erpnext/manufacturing/doctype/bom/bom.js
@@ -6,7 +6,7 @@
frappe.ui.form.on("BOM", {
setup: function(frm) {
frm.get_field('items').grid.editable_fields = [
- {fieldname: 'item_code', columns: 4},
+ {fieldname: 'item_code', columns: 3},
{fieldname: 'item_name', columns: 3},
{fieldname: 'qty', columns: 2},
{fieldname: 'rate', columns: 2}
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 45fa3f3..699a745f 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -280,6 +280,8 @@
erpnext.patches.v7_0.re_route #2016-06-27
erpnext.patches.v7_0.system_settings_setup_complete
erpnext.patches.v7_0.set_naming_series_for_timesheet
+execute:frappe.reload_doc('projects', 'doctype', 'project')
+execute:frappe.reload_doc('projects', 'doctype', 'project_user')
erpnext.patches.v7_0.convert_timelogbatch_to_timesheet
erpnext.patches.v7_0.convert_timelog_to_timesheet
erpnext.patches.v7_0.move_timelogbatch_from_salesinvoiceitem_to_salesinvoicetimesheet
@@ -294,4 +296,6 @@
erpnext.patches.v7_0.make_is_group_fieldtype_as_check
execute:frappe.reload_doc('projects', 'doctype', 'timesheet', force=True)
execute:frappe.delete_doc_if_exists("Report", "Employee Holiday Attendance")
-
+execute:frappe.delete_doc_if_exists("DocType", "Payment Tool")
+execute:frappe.delete_doc_if_exists("DocType", "Payment Tool Detail")
+erpnext.patches.v7_0.setup_account_table_for_expense_claim_type_if_exists
diff --git a/erpnext/patches/v7_0/setup_account_table_for_expense_claim_type_if_exists.py b/erpnext/patches/v7_0/setup_account_table_for_expense_claim_type_if_exists.py
new file mode 100644
index 0000000..e566ac2
--- /dev/null
+++ b/erpnext/patches/v7_0/setup_account_table_for_expense_claim_type_if_exists.py
@@ -0,0 +1,14 @@
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ frappe.reload_doc("hr", "doctype", "expense_claim_type")
+
+ for expense_claim_type in frappe.get_all("Expense Claim Type", fields=["name", "default_account"]):
+ if expense_claim_type.default_account:
+ doc = frappe.get_doc("Expense Claim Type", expense_claim_type.name)
+ doc.append("accounts", {
+ "company": frappe.db.get_value("Account", expense_claim_type.default_account, "company"),
+ "default_account": expense_claim_type.default_account,
+ })
+ doc.save(ignore_permissions=True)
\ No newline at end of file
diff --git a/erpnext/projects/doctype/project/project.js b/erpnext/projects/doctype/project/project.js
index f9b71c4..1b3b05d 100644
--- a/erpnext/projects/doctype/project/project.js
+++ b/erpnext/projects/doctype/project/project.js
@@ -4,7 +4,7 @@
frappe.ui.form.on("Project", {
setup: function(frm) {
frm.get_field('tasks').grid.editable_fields = [
- {fieldname: 'title', columns: 4},
+ {fieldname: 'title', columns: 3},
{fieldname: 'status', columns: 3},
{fieldname: 'start_date', columns: 2},
{fieldname: 'end_date', columns: 2}
diff --git a/erpnext/projects/doctype/timesheet/timesheet.js b/erpnext/projects/doctype/timesheet/timesheet.js
index 4d16295..ebdb535 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.js
+++ b/erpnext/projects/doctype/timesheet/timesheet.js
@@ -5,6 +5,7 @@
frappe.ui.form.on("Timesheet", {
setup: function(frm) {
frm.get_field('time_logs').grid.editable_fields = [
+ {fieldname: 'billable', columns: 2},
{fieldname: 'activity_type', columns: 2},
{fieldname: 'from_time', columns: 2},
{fieldname: 'hours', columns: 2},
@@ -36,8 +37,8 @@
refresh: function(frm) {
if(frm.doc.docstatus==1) {
- if(!frm.doc.sales_invoice && frm.doc.total_billing_amount > 0
- && frm.doc.employee){
+ if(!frm.doc.sales_invoice && frm.doc.total_billing_amount > 0
+ && !frm.doc.production_order){
frm.add_custom_button(__("Make Sales Invoice"), function() { frm.trigger("make_invoice") },
"icon-file-alt");
}
@@ -106,25 +107,20 @@
activity_type: function(frm, cdt, cdn) {
child = locals[cdt][cdn];
- if(frm.doc.employee || frm.doc.production_order){
- frappe.call({
- method: "erpnext.projects.doctype.timesheet.timesheet.get_activity_cost",
- args: {
- employee: frm.doc.employee,
- activity_type: child.activity_type
- },
- callback: function(r){
- if(r.message){
- frappe.model.set_value(cdt, cdn, 'billing_rate', r.message['billing_rate']);
- frappe.model.set_value(cdt, cdn, 'costing_rate', r.message['costing_rate']);
- calculate_billing_costing_amount(frm, cdt, cdn)
- }
+ frappe.call({
+ method: "erpnext.projects.doctype.timesheet.timesheet.get_activity_cost",
+ args: {
+ employee: frm.doc.employee,
+ activity_type: child.activity_type
+ },
+ callback: function(r){
+ if(r.message){
+ frappe.model.set_value(cdt, cdn, 'billing_rate', r.message['billing_rate']);
+ frappe.model.set_value(cdt, cdn, 'costing_rate', r.message['costing_rate']);
+ calculate_billing_costing_amount(frm, cdt, cdn)
}
- })
- }else {
- frappe.model.set_value(cdt, cdn, 'activity_type', null);
- frappe.show_alert(__("Select employee"))
- }
+ }
+ })
}
});
diff --git a/erpnext/projects/doctype/timesheet_detail/timesheet_detail.json b/erpnext/projects/doctype/timesheet_detail/timesheet_detail.json
index c4748fd..ce8c569 100644
--- a/erpnext/projects/doctype/timesheet_detail/timesheet_detail.json
+++ b/erpnext/projects/doctype/timesheet_detail/timesheet_detail.json
@@ -14,7 +14,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "depends_on": "eval:parent.employee",
+ "depends_on": "eval:!parent.production_order",
"fieldname": "billable",
"fieldtype": "Check",
"hidden": 0,
@@ -163,7 +163,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "depends_on": "eval:parent.employee",
+ "depends_on": "eval:!parent.production_order",
"fieldname": "section_break_11",
"fieldtype": "Section Break",
"hidden": 0,
@@ -532,7 +532,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-07-11 03:28:09.410519",
+ "modified": "2016-07-18 13:57:29.873073",
"modified_by": "Administrator",
"module": "Projects",
"name": "Timesheet Detail",
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index a0507ef..fde33e8 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -6,7 +6,7 @@
if(this.frm.get_field('taxes')) {
this.frm.get_field('taxes').grid.editable_fields = [
{fieldname: 'charge_type', columns: 2},
- {fieldname: 'account_head', columns: 3},
+ {fieldname: 'account_head', columns: 2},
{fieldname: 'rate', columns: 2},
{fieldname: 'tax_amount', columns: 2},
{fieldname: 'total', columns: 2}
@@ -549,13 +549,6 @@
if(this.frm.doc.doctype == "Sales Invoice" || this.frm.doc.doctype == "Purchase Invoice") {
frappe.model.round_floats_in(this.frm.doc, ["paid_amount"]);
- if(this.frm.doc.is_pos || this.frm.doc.is_paid) {
- if(!this.frm.doc.paid_amount || update_paid_amount===undefined || update_paid_amount) {
- this.frm.doc.paid_amount = flt(total_amount_to_pay);
- }
- } else {
- this.frm.doc.paid_amount = 0
- }
this.set_in_company_currency(this.frm.doc, ["paid_amount"]);
if(this.frm.refresh_field){
@@ -564,6 +557,7 @@
}
if(this.frm.doc.doctype == "Sales Invoice"){
+ this.set_default_payment(total_amount_to_pay, update_paid_amount)
this.calculate_paid_amount()
}
@@ -585,6 +579,19 @@
this.calculate_change_amount()
},
+ set_default_payment: function(total_amount_to_pay, update_paid_amount){
+ var me = this;
+ payment_status = true;
+ if(this.frm.doc.is_pos && (!this.frm.doc.paid_amount || update_paid_amount===undefined || update_paid_amount)){
+ $.each(this.frm.doc['payments'] || [], function(index, data){
+ if(data.type == "Cash" && payment_status) {
+ data.amount = total_amount_to_pay;
+ payment_status = false;
+ }
+ })
+ }
+ },
+
calculate_paid_amount: function(){
var me = this;
var paid_amount = base_paid_amount = 0.0;
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index c39048d..2b73cf4 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -4,16 +4,16 @@
erpnext.TransactionController = erpnext.taxes_and_totals.extend({
setup: function() {
this._super();
-
+
if(in_list(["Sales Invoice", "Purchase Invoice"], this.frm.doc.doctype)) {
this.frm.get_field('advances').grid.editable_fields = [
- {fieldname: 'reference_name', columns: 2},
+ {fieldname: 'reference_name', columns: 3},
{fieldname: 'remarks', columns: 3},
- {fieldname: 'advance_amount', columns: 3},
- {fieldname: 'allocated_amount', columns: 3}
+ {fieldname: 'advance_amount', columns: 2},
+ {fieldname: 'allocated_amount', columns: 2}
];
}
-
+
frappe.ui.form.on(this.frm.doctype + " Item", "rate", function(frm, cdt, cdn) {
var item = frappe.get_doc(cdt, cdn);
frappe.model.round_floats_in(item, ["rate", "price_list_rate"]);
@@ -432,7 +432,7 @@
var company_currency = this.get_company_currency();
// Added `ignore_pricing_rule` to determine if document is loading after mapping from another doc
- if(this.frm.doc.currency && this.frm.doc.currency !== company_currency
+ if(this.frm.doc.currency && this.frm.doc.currency !== company_currency
&& !this.frm.doc.ignore_pricing_rule) {
this.get_exchange_rate(this.frm.doc.currency, company_currency,
function(exchange_rate) {
@@ -973,7 +973,7 @@
this.item_selector = new erpnext.ItemSelector({frm: this.frm});
}
},
-
+
get_advances: function() {
if(!this.frm.is_return) {
return this.frm.call({
@@ -985,7 +985,7 @@
})
}
},
-
+
make_payment_entry: function() {
return frappe.call({
method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry",
diff --git a/erpnext/public/js/payment/payments.js b/erpnext/public/js/payment/payments.js
index dc0b026..9464f50 100644
--- a/erpnext/public/js/payment/payments.js
+++ b/erpnext/public/js/payment/payments.js
@@ -74,7 +74,7 @@
this.highlight_selected_row()
this.payment_val = 0.0
if(this.frm.doc.outstanding_amount > 0 && flt(this.selected_mode.val()) == 0.0){
- //When user first tithis click on row
+ //When user first time click on row
this.payment_val = flt(this.frm.doc.outstanding_amount)
this.selected_mode.val(format_number(this.payment_val, 2));
this.update_paid_amount()
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index d02fed2..d58adce 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -15,7 +15,7 @@
this.frm.get_field('items').grid.editable_fields = [
{fieldname: 'item_code', columns: 4},
{fieldname: 'qty', columns: 2},
- {fieldname: 'rate', columns: 3},
+ {fieldname: 'rate', columns: 2},
{fieldname: 'amount', columns: 2}
];
},
diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js
index ff12f68..f22e63e 100644
--- a/erpnext/setup/doctype/company/company.js
+++ b/erpnext/setup/doctype/company/company.js
@@ -138,8 +138,9 @@
["round_off_account", {"root_type": "Expense"}],
["write_off_account", {"root_type": "Expense"}],
["exchange_gain_loss_account", {"root_type": "Expense"}],
- ["accumulated_depreciation_account", {"root_type": "Asset"}],
- ["depreciation_expense_account", {"root_type": "Expense"}],
+ ["accumulated_depreciation_account",
+ {"root_type": "Asset", "account_type": "Accumulated Depreciation"}],
+ ["depreciation_expense_account", {"root_type": "Expense", "account_type": "Depreciation"}],
["disposal_account", {"report_type": "Profit and Loss"}],
["cost_center", {}],
["round_off_cost_center", {}],
@@ -150,9 +151,12 @@
if (sys_defaults.auto_accounting_for_stock) {
$.each([
- ["stock_adjustment_account", {"root_type": "Expense"}],
- ["expenses_included_in_valuation", {"root_type": "Expense"}],
- ["stock_received_but_not_billed", {"report_type": "Balance Sheet"}]
+ ["stock_adjustment_account",
+ {"root_type": "Expense", "account_type": "Stock Adjustment"}],
+ ["expenses_included_in_valuation",
+ {"root_type": "Expense", "account_type": "Expenses Included in Valuation"}],
+ ["stock_received_but_not_billed",
+ {"root_type": "Liability", "account_type": "Stock Received But Not Billed"}]
], function(i, v) {
erpnext.company.set_custom_query(frm, v);
});
diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js
index 713789b..17e379c 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -77,8 +77,8 @@
erpnext.item.toggle_attributes(frm);
- frm.toggle_enable("is_fixed_asset", !frm.doc.is_stock_item &&
- ((frm.doc.__onload && frm.doc.__onload.asset_exists) ? false : true));
+ frm.toggle_enable("is_fixed_asset", (frm.doc.__islocal || (!frm.doc.is_stock_item &&
+ ((frm.doc.__onload && frm.doc.__onload.asset_exists) ? false : true))));
},
validate: function(frm){
@@ -95,10 +95,6 @@
}
},
- is_stock_item: function(frm) {
- frm.toggle_enable("is_fixed_asset", !frm.doc.is_stock_item);
- },
-
page_name: frappe.utils.warn_page_name_change,
item_code: function(frm) {
diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js
index bbd312d..62ae091 100644
--- a/erpnext/stock/doctype/material_request/material_request.js
+++ b/erpnext/stock/doctype/material_request/material_request.js
@@ -6,7 +6,7 @@
frappe.ui.form.on('Material Request', {
setup: function(frm) {
frm.get_field('items').grid.editable_fields = [
- {fieldname: 'item_code', columns: 4},
+ {fieldname: 'item_code', columns: 3},
{fieldname: 'qty', columns: 2},
{fieldname: 'warehouse', columns: 3},
{fieldname: 'schedule_date', columns: 2},
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 69d9a76..6c2a14b 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -52,9 +52,9 @@
this.frm.get_field('items').grid.editable_fields = [
{fieldname: 'item_code', columns: 3},
- {fieldname: 'qty', columns: 2},
- {fieldname: 's_warehouse', columns: 3},
- {fieldname: 't_warehouse', columns: 3}
+ {fieldname: 'qty', columns: 3},
+ {fieldname: 's_warehouse', columns: 2},
+ {fieldname: 't_warehouse', columns: 2}
];
},
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
index 58b3549..e7ba1ba 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
@@ -6,7 +6,7 @@
frappe.ui.form.on("Stock Reconciliation", {
onload: function(frm) {
frm.add_fetch("item_code", "item_name", "item_name");
-
+
// end of life
frm.set_query("item_code", "items", function(doc, cdt, cdn) {
return {
@@ -17,7 +17,7 @@
}
}
});
-
+
if (frm.doc.company) {
erpnext.queries.setup_queries(frm, "Warehouse", function() {
return erpnext.queries.warehouse(frm.doc);
@@ -140,12 +140,12 @@
}
}
}
-
+
this.frm.get_field('items').grid.editable_fields = [
{fieldname: 'item_code', columns: 3},
{fieldname: 'warehouse', columns: 3},
{fieldname: 'qty', columns: 2},
- {fieldname: 'valuation_rate', columns: 3}
+ {fieldname: 'valuation_rate', columns: 2}
];
},
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index c5992c2..82b7e11 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -246,6 +246,18 @@
for item in get_items(warehouse, self.posting_date, self.posting_time):
self.append("items", item)
+ def submit(self):
+ if len(self.items) > 100:
+ self.queue_action('submit')
+ else:
+ self._submit()
+
+ def cancel(self):
+ if len(self.items) > 100:
+ self.queue_action('cancel')
+ else:
+ self._cancel()
+
@frappe.whitelist()
def get_items(warehouse, posting_date, posting_time):
items = frappe.get_list("Bin", fields=["item_code"], filters={"warehouse": warehouse}, as_list=1)