Fixed merge conflict
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index ced1e85..cedaf60 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -171,7 +171,7 @@
old_warehouse = cstr(frappe.db.get_value("Account", self.name, "warehouse"))
if old_warehouse != cstr(self.warehouse):
- if old_warehouse:
+ if old_warehouse and frappe.db.exists("Warehouse", old_warehouse):
self.validate_warehouse(old_warehouse)
if self.warehouse:
self.validate_warehouse(self.warehouse)
diff --git a/erpnext/accounts/doctype/account/account_tree.js b/erpnext/accounts/doctype/account/account_tree.js
index bd0b8f2..8aee1ba 100644
--- a/erpnext/accounts/doctype/account/account_tree.js
+++ b/erpnext/accounts/doctype/account/account_tree.js
@@ -49,4 +49,23 @@
+ '</span>').insertBefore(node.$ul);
}
},
+ toolbar: [
+ {
+ condition: function(node) {
+ return !node.root && frappe.boot.user.can_read.indexOf("GL Entry") !== -1
+ },
+ label: __("View Ledger"),
+ click: function(node, btn) {
+ frappe.route_options = {
+ "account": node.label,
+ "from_date": sys_defaults.year_start_date,
+ "to_date": sys_defaults.year_end_date,
+ "company": frappe.defaults.get_default('company') ? frappe.defaults.get_default('company'): ""
+ };
+ frappe.set_route("query-report", "General Ledger");
+ },
+ btnClass: "hidden-xs"
+ }
+ ],
+ extend_toolbar: true
}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
index a02e591..c5b3e5b 100644
--- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
+++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
@@ -15,6 +15,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "1",
"description": "If enabled, the system will post accounting entries for inventory automatically.",
"fieldname": "auto_accounting_for_stock",
@@ -41,6 +42,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Accounting entry frozen up to this date, nobody can do / modify entry except role specified below.",
"fieldname": "acc_frozen_upto",
"fieldtype": "Date",
@@ -66,6 +68,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Users with this role are allowed to set frozen accounts and create / modify accounting entries against frozen accounts",
"fieldname": "frozen_accounts_modifier",
"fieldtype": "Link",
@@ -92,6 +95,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_4",
"fieldtype": "Column Break",
"hidden": 0,
@@ -116,6 +120,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Role that is allowed to submit transactions that exceed credit limits set.",
"fieldname": "credit_controller",
"fieldtype": "Link",
@@ -142,6 +147,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "check_supplier_invoice_uniqueness",
"fieldtype": "Check",
"hidden": 0,
@@ -162,6 +168,32 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "make_payment_via_journal_entry",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Make Payment 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
}
],
"hide_heading": 0,
@@ -175,8 +207,8 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-07-14 14:32:06.056888",
- "modified_by": "Administrator",
+ "modified": "2016-10-05 16:13:10.978208",
+ "modified_by": "rohitw1991@gmail.com",
"module": "Accounts",
"name": "Accounts Settings",
"owner": "Administrator",
@@ -191,6 +223,7 @@
"export": 0,
"if_owner": 0,
"import": 0,
+ "is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
diff --git a/erpnext/accounts/doctype/budget/budget.py b/erpnext/accounts/doctype/budget/budget.py
index 529401c..2488dd6 100644
--- a/erpnext/accounts/doctype/budget/budget.py
+++ b/erpnext/accounts/doctype/budget/budget.py
@@ -51,6 +51,9 @@
def validate_expense_against_budget(args):
args = frappe._dict(args)
+ if not args.cost_center:
+ return
+
if frappe.db.get_value("Account", {"name": args.account, "root_type": "Expense"}):
cc_lft, cc_rgt = frappe.db.get_value("Cost Center", args.cost_center, ["lft", "rgt"])
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.json b/erpnext/accounts/doctype/journal_entry/journal_entry.json
index 9d4ad48..969af5a 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.json
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.json
@@ -3,16 +3,19 @@
"allow_import": 1,
"allow_rename": 0,
"autoname": "naming_series:",
+ "beta": 0,
"creation": "2013-03-25 10:53:52",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Document",
+ "editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "entry_type_and_date",
"fieldtype": "Section Break",
"hidden": 0,
@@ -38,6 +41,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "",
"fieldname": "title",
"fieldtype": "Data",
@@ -64,6 +68,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "Journal Entry",
"fieldname": "voucher_type",
"fieldtype": "Select",
@@ -92,6 +97,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
@@ -119,6 +125,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -144,6 +151,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "posting_date",
"fieldtype": "Date",
"hidden": 0,
@@ -170,6 +178,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -197,6 +206,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "2_add_edit_gl_entries",
"fieldtype": "Section Break",
"hidden": 0,
@@ -223,6 +233,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "accounts",
"fieldtype": "Table",
"hidden": 0,
@@ -250,6 +261,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "section_break99",
"fieldtype": "Section Break",
"hidden": 0,
@@ -273,6 +285,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "",
"fieldname": "cheque_no",
"fieldtype": "Data",
@@ -300,6 +313,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "cheque_date",
"fieldtype": "Date",
"hidden": 0,
@@ -326,6 +340,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "user_remark",
"fieldtype": "Small Text",
"hidden": 0,
@@ -352,6 +367,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break99",
"fieldtype": "Column Break",
"hidden": 0,
@@ -375,6 +391,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "total_debit",
"fieldtype": "Currency",
"hidden": 0,
@@ -402,6 +419,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "total_credit",
"fieldtype": "Currency",
"hidden": 0,
@@ -429,6 +447,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "difference",
"fieldname": "difference",
"fieldtype": "Currency",
@@ -457,6 +476,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "difference",
"fieldname": "get_balance",
"fieldtype": "Button",
@@ -483,6 +503,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "multi_currency",
"fieldtype": "Check",
"hidden": 0,
@@ -506,8 +527,36 @@
},
{
"allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "total_amount_currency",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Total Amount Currency",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "report_hide": 1,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
+ "columns": 0,
"fieldname": "total_amount",
"fieldtype": "Currency",
"hidden": 1,
@@ -518,7 +567,7 @@
"label": "Total Amount",
"length": 0,
"no_copy": 1,
- "options": "Company:company:default_currency",
+ "options": "total_amount_currency",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@@ -533,6 +582,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "total_amount_in_words",
"fieldtype": "Data",
"hidden": 1,
@@ -557,6 +607,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
+ "columns": 0,
"fieldname": "reference",
"fieldtype": "Section Break",
"hidden": 0,
@@ -582,6 +633,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "clearance_date",
"fieldtype": "Date",
"hidden": 0,
@@ -608,6 +660,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "",
"fieldname": "remark",
"fieldtype": "Small Text",
@@ -635,6 +688,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break98",
"fieldtype": "Column Break",
"hidden": 0,
@@ -658,6 +712,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "bill_no",
"fieldtype": "Data",
"hidden": 0,
@@ -684,6 +739,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "bill_date",
"fieldtype": "Date",
"hidden": 0,
@@ -710,6 +766,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "due_date",
"fieldtype": "Date",
"hidden": 0,
@@ -736,6 +793,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
+ "columns": 0,
"depends_on": "eval:doc.voucher_type == 'Write Off Entry'",
"fieldname": "write_off",
"fieldtype": "Section Break",
@@ -762,6 +820,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "Accounts Receivable",
"depends_on": "eval:doc.voucher_type == 'Write Off Entry'",
"fieldname": "write_off_based_on",
@@ -789,6 +848,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.voucher_type == 'Write Off Entry'",
"fieldname": "get_outstanding_invoices",
"fieldtype": "Button",
@@ -815,6 +875,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_30",
"fieldtype": "Column Break",
"hidden": 0,
@@ -839,6 +900,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.voucher_type == 'Write Off Entry'",
"fieldname": "write_off_amount",
"fieldtype": "Currency",
@@ -865,6 +927,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
+ "columns": 0,
"fieldname": "printing_settings",
"fieldtype": "Section Break",
"hidden": 0,
@@ -890,6 +953,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "pay_to_recd_from",
"fieldtype": "Data",
"hidden": 0,
@@ -914,6 +978,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_35",
"fieldtype": "Column Break",
"hidden": 0,
@@ -938,6 +1003,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "letter_head",
"fieldtype": "Link",
"hidden": 0,
@@ -963,6 +1029,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "select_print_heading",
"fieldtype": "Link",
"hidden": 0,
@@ -990,6 +1057,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
+ "columns": 0,
"fieldname": "addtional_info",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1016,6 +1084,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break3",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1041,6 +1110,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "No",
"description": "",
"fieldname": "is_opening",
@@ -1070,6 +1140,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:inList([\"Credit Note\", \"Debit Note\"], doc.voucher_type)",
"fieldname": "stock_entry",
"fieldtype": "Link",
@@ -1097,6 +1168,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@@ -1125,6 +1197,7 @@
"hide_toolbar": 0,
"icon": "icon-file-text",
"idx": 176,
+ "image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 1,
@@ -1132,7 +1205,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2016-04-06 05:33:21.851581",
+ "modified": "2016-10-03 10:13:49.458343",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Journal Entry",
@@ -1148,6 +1221,7 @@
"export": 0,
"if_owner": 0,
"import": 0,
+ "is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@@ -1168,6 +1242,7 @@
"export": 0,
"if_owner": 0,
"import": 0,
+ "is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@@ -1188,6 +1263,7 @@
"export": 0,
"if_owner": 0,
"import": 0,
+ "is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@@ -1199,6 +1275,7 @@
"write": 0
}
],
+ "quick_entry": 0,
"read_only": 0,
"read_only_onload": 1,
"search_fields": "voucher_type,posting_date, due_date, cheque_no",
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index 4e00c32..083ba6f 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -62,11 +62,13 @@
def on_cancel(self):
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
+ from erpnext.hr.doctype.salary_slip.salary_slip import unlink_ref_doc_from_salary_slip
unlink_ref_doc_from_payment_entries(self.doctype, self.name)
-
+ unlink_ref_doc_from_salary_slip(self.name)
self.make_gl_entries(1)
self.update_advance_paid()
self.update_expense_claim()
+
def validate_party(self):
for d in self.get("accounts"):
@@ -381,6 +383,7 @@
def set_total_amount(self, amt, currency):
self.total_amount = amt
+ self.total_amount_currency = currency
from frappe.utils import money_in_words
self.total_amount_in_words = money_in_words(amt, currency)
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index 5e6fc53..6ecd8fa 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -504,6 +504,18 @@
});
},
+ allocate_payment_amount: function(frm) {
+ if(frm.doc.payment_type == 'Internal Transfer'){
+ return
+ }
+
+ if(frm.doc.references.length == 0){
+ frm.events.get_outstanding_documents(frm);
+ }
+
+ frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount);
+ },
+
allocate_party_amount_against_ref_docs: function(frm, paid_amount) {
var total_positive_outstanding_including_order = 0;
var total_negative_outstanding = 0;
@@ -545,22 +557,24 @@
}
$.each(frm.doc.references || [], function(i, row) {
- row.allocated_amount = 0
+ row.allocated_amount = 0 //If allocate payment amount checkbox is unchecked, set zero to allocate amount
+ if(frm.doc.allocate_payment_amount){
+ if(row.outstanding_amount > 0 && allocated_positive_outstanding > 0) {
+ if(row.outstanding_amount >= allocated_positive_outstanding)
+ row.allocated_amount = allocated_positive_outstanding;
+ else row.allocated_amount = row.outstanding_amount;
- if(row.outstanding_amount > 0 && allocated_positive_outstanding > 0) {
- if(row.outstanding_amount >= allocated_positive_outstanding)
- row.allocated_amount = allocated_positive_outstanding;
- else row.allocated_amount = row.outstanding_amount;
+ allocated_positive_outstanding -= flt(row.allocated_amount);
+ } else if (row.outstanding_amount < 0 && allocated_negative_outstanding) {
+ if(Math.abs(row.outstanding_amount) >= allocated_negative_outstanding)
+ row.allocated_amount = -1*allocated_negative_outstanding;
+ else row.allocated_amount = row.outstanding_amount;
- allocated_positive_outstanding -= flt(row.allocated_amount);
- } else if (row.outstanding_amount < 0 && allocated_negative_outstanding) {
- if(Math.abs(row.outstanding_amount) >= allocated_negative_outstanding)
- row.allocated_amount = -1*allocated_negative_outstanding;
- else row.allocated_amount = row.outstanding_amount;
-
- allocated_negative_outstanding -= Math.abs(flt(row.allocated_amount));
+ allocated_negative_outstanding -= Math.abs(flt(row.allocated_amount));
+ }
}
})
+
frm.refresh_fields()
frm.events.set_total_allocated_amount(frm);
},
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json
index 2057d07..6018571 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.json
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json
@@ -777,6 +777,34 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "default": "1",
+ "depends_on": "eval:in_list(['Pay', 'Receive'], doc.payment_type)",
+ "fieldname": "allocate_payment_amount",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Allocate Payment Amount",
+ "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,
+ "columns": 0,
"depends_on": "",
"fieldname": "references",
"fieldtype": "Table",
@@ -1426,7 +1454,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-09-05 11:06:18.183458",
+ "modified": "2016-09-28 18:20:47.625383",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry",
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 179a321..7b9bf16 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -669,6 +669,7 @@
pe.paid_to_account_currency = party_account_currency if payment_type=="Pay" else bank.account_currency
pe.paid_amount = paid_amount
pe.received_amount = received_amount
+ pe.allocate_payment_amount = 1
pe.append("references", {
"reference_doctype": dt,
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py
index 84a8e82..26663fd 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.py
+++ b/erpnext/accounts/doctype/payment_request/payment_request.py
@@ -65,7 +65,7 @@
data = frappe.db.get_value(self.reference_doctype, self.reference_name,
["company", "customer_name"], as_dict=1)
- controller = get_integration_controller(self.payment_gateway, setup=False)
+ controller = get_integration_controller(self.payment_gateway)
controller.validate_transaction_currency(self.currency)
return controller.get_payment_url(**{
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index 836a2e0..bad511e 100755
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -15,6 +15,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "{supplier_name}",
"fieldname": "title",
"fieldtype": "Data",
@@ -41,6 +42,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
@@ -68,6 +70,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "supplier",
"fieldtype": "Link",
"hidden": 0,
@@ -95,6 +98,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
+ "columns": 0,
"depends_on": "supplier",
"fieldname": "supplier_name",
"fieldtype": "Data",
@@ -122,6 +126,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "",
"fieldname": "bill_no",
"fieldtype": "Data",
@@ -149,6 +154,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "is_paid",
"fieldtype": "Check",
"hidden": 0,
@@ -174,6 +180,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "0",
"fieldname": "is_return",
"fieldtype": "Check",
@@ -184,7 +191,7 @@
"in_list_view": 0,
"label": "Is Return",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
@@ -200,6 +207,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -225,6 +233,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "Today",
"fieldname": "posting_date",
"fieldtype": "Date",
@@ -252,6 +261,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "due_date",
"fieldtype": "Date",
"hidden": 0,
@@ -278,6 +288,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "bill_date",
"fieldtype": "Date",
"hidden": 0,
@@ -304,6 +315,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@@ -331,6 +343,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -356,6 +369,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "is_return",
"fieldname": "return_against",
"fieldtype": "Link",
@@ -366,7 +380,7 @@
"in_list_view": 0,
"label": "Return Against Purchase Invoice",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"options": "Purchase Invoice",
"permlevel": 0,
"precision": "",
@@ -383,6 +397,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
+ "columns": 0,
"fieldname": "section_addresses",
"fieldtype": "Section Break",
"hidden": 0,
@@ -408,6 +423,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "supplier_address",
"fieldtype": "Link",
"hidden": 0,
@@ -433,6 +449,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "contact_person",
"fieldtype": "Link",
"hidden": 0,
@@ -458,6 +475,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "address_display",
"fieldtype": "Small Text",
@@ -483,6 +501,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "contact_display",
"fieldtype": "Small Text",
"hidden": 0,
@@ -507,6 +526,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "contact_mobile",
"fieldtype": "Small Text",
"hidden": 0,
@@ -531,6 +551,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "contact_email",
"fieldtype": "Small Text",
"hidden": 0,
@@ -555,6 +576,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "col_break_address",
"fieldtype": "Column Break",
"hidden": 0,
@@ -579,6 +601,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "shipping_address",
"fieldtype": "Link",
@@ -606,6 +629,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "shipping_address_display",
"fieldtype": "Small Text",
"hidden": 0,
@@ -631,6 +655,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
+ "columns": 0,
"fieldname": "currency_and_price_list",
"fieldtype": "Section Break",
"hidden": 0,
@@ -656,6 +681,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "currency",
"fieldtype": "Link",
"hidden": 0,
@@ -683,6 +709,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "",
"fieldname": "conversion_rate",
"fieldtype": "Float",
@@ -711,6 +738,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break2",
"fieldtype": "Column Break",
"hidden": 0,
@@ -734,6 +762,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "buying_price_list",
"fieldtype": "Link",
"hidden": 0,
@@ -759,6 +788,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "price_list_currency",
"fieldtype": "Link",
"hidden": 0,
@@ -784,6 +814,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "plc_conversion_rate",
"fieldtype": "Float",
"hidden": 0,
@@ -809,6 +840,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "ignore_pricing_rule",
"fieldtype": "Check",
"hidden": 0,
@@ -833,6 +865,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "items_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -859,6 +892,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "0",
"fieldname": "update_stock",
"fieldtype": "Check",
@@ -885,6 +919,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "items",
"fieldtype": "Table",
"hidden": 0,
@@ -912,6 +947,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "section_break_26",
"fieldtype": "Section Break",
"hidden": 0,
@@ -935,6 +971,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "base_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -961,6 +998,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "",
"fieldname": "base_net_total",
"fieldtype": "Currency",
@@ -989,6 +1027,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_28",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1012,6 +1051,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1038,6 +1078,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "net_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1065,6 +1106,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "taxes_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1091,6 +1133,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "taxes_and_charges",
"fieldtype": "Link",
"hidden": 0,
@@ -1118,6 +1161,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "taxes",
"fieldtype": "Table",
"hidden": 0,
@@ -1145,6 +1189,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "other_charges_calculation",
"fieldtype": "HTML",
"hidden": 0,
@@ -1170,6 +1215,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "totals",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1196,6 +1242,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "base_taxes_and_charges_added",
"fieldtype": "Currency",
"hidden": 0,
@@ -1223,6 +1270,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "base_taxes_and_charges_deducted",
"fieldtype": "Currency",
"hidden": 0,
@@ -1250,6 +1298,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "base_total_taxes_and_charges",
"fieldtype": "Currency",
"hidden": 0,
@@ -1277,6 +1326,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_40",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1301,6 +1351,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "taxes_and_charges_added",
"fieldtype": "Currency",
"hidden": 0,
@@ -1328,6 +1379,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "taxes_and_charges_deducted",
"fieldtype": "Currency",
"hidden": 0,
@@ -1355,6 +1407,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "total_taxes_and_charges",
"fieldtype": "Currency",
"hidden": 0,
@@ -1382,6 +1435,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "discount_amount",
+ "columns": 0,
"fieldname": "section_break_44",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1407,6 +1461,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "Grand Total",
"fieldname": "apply_discount_on",
"fieldtype": "Select",
@@ -1434,6 +1489,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "base_discount_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1460,6 +1516,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_46",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1484,6 +1541,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "additional_discount_percentage",
"fieldtype": "Float",
"hidden": 0,
@@ -1509,6 +1567,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "discount_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1535,6 +1594,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "section_break_49",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1559,6 +1619,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "base_grand_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1586,6 +1647,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "",
"fieldname": "base_in_words",
"fieldtype": "Data",
@@ -1613,6 +1675,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break8",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1638,6 +1701,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "grand_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1665,6 +1729,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "in_words",
"fieldtype": "Data",
"hidden": 0,
@@ -1691,6 +1756,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "total_advance",
"fieldtype": "Currency",
"hidden": 0,
@@ -1718,6 +1784,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "outstanding_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1746,6 +1813,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "paid_amount",
+ "columns": 0,
"depends_on": "eval:doc.is_paid===1||(doc.advances && doc.advances.length>0)",
"fieldname": "payments_section",
"fieldtype": "Section Break",
@@ -1772,6 +1840,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "mode_of_payment",
"fieldtype": "Link",
"hidden": 0,
@@ -1798,6 +1867,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "cash_bank_account",
"fieldtype": "Link",
"hidden": 0,
@@ -1824,6 +1894,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "col_br_payments",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1848,6 +1919,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "is_paid",
"fieldname": "paid_amount",
"fieldtype": "Currency",
@@ -1875,6 +1947,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "base_paid_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1902,6 +1975,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "write_off_amount",
+ "columns": 0,
"depends_on": "grand_total",
"fieldname": "write_off",
"fieldtype": "Section Break",
@@ -1928,6 +2002,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "write_off_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1953,6 +2028,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "base_write_off_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1979,6 +2055,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_61",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2003,6 +2080,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:flt(doc.write_off_amount)!=0",
"fieldname": "write_off_account",
"fieldtype": "Link",
@@ -2029,6 +2107,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:flt(doc.write_off_amount)!=0",
"fieldname": "write_off_cost_center",
"fieldtype": "Link",
@@ -2056,6 +2135,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "advances",
+ "columns": 0,
"fieldname": "advances_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2082,6 +2162,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "get_advances",
"fieldtype": "Button",
"hidden": 0,
@@ -2108,6 +2189,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "advances",
"fieldtype": "Table",
"hidden": 0,
@@ -2136,6 +2218,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "terms",
+ "columns": 0,
"fieldname": "terms_section_break",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2161,6 +2244,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "tc_name",
"fieldtype": "Link",
"hidden": 0,
@@ -2186,6 +2270,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "terms",
"fieldtype": "Text Editor",
"hidden": 0,
@@ -2210,6 +2295,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "raw_materials_supplied",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2235,6 +2321,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "No",
"fieldname": "is_subcontracted",
"fieldtype": "Select",
@@ -2262,6 +2349,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "supplier_warehouse",
"fieldtype": "Link",
"hidden": 0,
@@ -2290,6 +2378,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "supplied_items",
"fieldtype": "Table",
"hidden": 0,
@@ -2316,6 +2405,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
+ "columns": 0,
"fieldname": "printing_settings",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2341,6 +2431,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "letter_head",
"fieldtype": "Link",
"hidden": 0,
@@ -2367,6 +2458,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "select_print_heading",
"fieldtype": "Link",
"hidden": 0,
@@ -2394,6 +2486,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "language",
"fieldtype": "Data",
"hidden": 0,
@@ -2419,6 +2512,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
+ "columns": 0,
"fieldname": "more_info",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2445,6 +2539,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "",
"fieldname": "credit_to",
"fieldtype": "Link",
@@ -2473,6 +2568,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "party_account_currency",
"fieldtype": "Link",
"hidden": 1,
@@ -2499,6 +2595,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "No",
"description": "",
"fieldname": "is_opening",
@@ -2528,6 +2625,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "against_expense_account",
"fieldtype": "Small Text",
"hidden": 1,
@@ -2554,6 +2652,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_63",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2577,6 +2676,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "posting_time",
"fieldtype": "Time",
"hidden": 0,
@@ -2604,6 +2704,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "remarks",
"fieldtype": "Small Text",
"hidden": 0,
@@ -2630,6 +2731,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Warehouse where you are maintaining stock of rejected items",
"fieldname": "rejected_warehouse",
"fieldtype": "Link",
@@ -2658,6 +2760,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "is_recurring",
+ "columns": 0,
"depends_on": "eval:doc.docstatus<2",
"fieldname": "recurring_invoice",
"fieldtype": "Section Break",
@@ -2684,6 +2787,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.docstatus<2",
"description": "",
"fieldname": "is_recurring",
@@ -2710,6 +2814,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.is_recurring==1",
"description": "Select the period when the invoice will be generated automatically",
"fieldname": "recurring_type",
@@ -2737,6 +2842,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.is_recurring==1",
"description": "Start date of current invoice's period",
"fieldname": "from_date",
@@ -2763,6 +2869,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.is_recurring==1",
"description": "End date of current invoice's period",
"fieldname": "to_date",
@@ -2789,6 +2896,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name",
"fieldname": "submit_on_creation",
"fieldtype": "Check",
@@ -2815,6 +2923,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name",
"description": "",
"fieldname": "notify_by_email",
@@ -2842,6 +2951,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.is_recurring==1",
"description": "The day of the month on which auto invoice will be generated e.g. 05, 28 etc",
"fieldname": "repeat_on_day_of_month",
@@ -2868,6 +2978,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.is_recurring==1",
"description": "The date on which recurring invoice will be stop",
"fieldname": "end_date",
@@ -2894,6 +3005,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_82",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2918,6 +3030,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.is_recurring==1",
"description": "The date on which next invoice will be generated. It is generated on submit.",
"fieldname": "next_date",
@@ -2944,6 +3057,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.is_recurring==1",
"description": "The unique id for tracking all recurring invoices. It is generated on submit.",
"fieldname": "recurring_id",
@@ -2970,6 +3084,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.is_recurring==1",
"description": "Enter email id separated by commas, invoice will be mailed automatically on particular date",
"fieldname": "notification_email_address",
@@ -2996,6 +3111,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.is_recurring==1",
"fieldname": "recurring_print_format",
"fieldtype": "Link",
@@ -3032,7 +3148,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2016-08-24 12:50:15.777689",
+ "modified": "2016-09-23 18:02:45.349273",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice",
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index adc30e2..d741a60 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -58,7 +58,7 @@
self.check_for_closed_status()
self.validate_with_previous_doc()
self.validate_uom_is_integer("uom", "qty")
- self.set_expense_account()
+ self.set_expense_account(for_validate=True)
self.set_against_expense_account()
self.validate_write_off_account()
self.validate_multiple_billing("Purchase Receipt", "pr_detail", "amount", "items")
@@ -155,7 +155,7 @@
super(PurchaseInvoice, self).validate_warehouse()
- def set_expense_account(self):
+ def set_expense_account(self, for_validate=False):
auto_accounting_for_stock = cint(frappe.defaults.get_global_default("auto_accounting_for_stock"))
if auto_accounting_for_stock:
@@ -181,7 +181,7 @@
else:
item.expense_account = stock_not_billed_account
- elif not item.expense_account:
+ elif not item.expense_account and for_validate:
throw(_("Expense account is mandatory for item {0}").format(item.item_code or item.item_name))
def set_against_expense_account(self):
@@ -372,7 +372,7 @@
if flt(item.base_net_amount):
account_currency = get_account_currency(item.expense_account)
- if self.update_stock and self.auto_accounting_for_stock:
+ if self.update_stock and self.auto_accounting_for_stock and item.item_code in stock_items:
val_rate_db_precision = 6 if cint(item.precision("valuation_rate")) <= 6 else 9
# warehouse account
diff --git a/erpnext/accounts/doctype/salary_component_account/salary_component_account.json b/erpnext/accounts/doctype/salary_component_account/salary_component_account.json
index 6bbde22..6ba820e 100644
--- a/erpnext/accounts/doctype/salary_component_account/salary_component_account.json
+++ b/erpnext/accounts/doctype/salary_component_account/salary_component_account.json
@@ -14,6 +14,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -40,7 +41,8 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "description": "Default Bank / Cash account will be automatically updated in POS Invoice when this mode is selected.",
+ "columns": 0,
+ "description": "Default Bank / Cash account will be automatically updated in Salary Journal Entry when this mode is selected.",
"fieldname": "default_account",
"fieldtype": "Link",
"hidden": 0,
@@ -74,7 +76,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-07-27 17:24:24.956896",
+ "modified": "2016-09-02 07:49:06.567389",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Salary Component Account",
diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py
index 5ed25b4..1d1a122 100644
--- a/erpnext/accounts/doctype/sales_invoice/pos.py
+++ b/erpnext/accounts/doctype/sales_invoice/pos.py
@@ -15,6 +15,7 @@
doc = frappe.new_doc('Sales Invoice')
doc.is_pos = 1;
pos_profile = get_pos_profile(doc.company) or {}
+ if not doc.company: doc.company = pos_profile.get('company')
doc.update_stock = pos_profile.get('update_stock')
if pos_profile.get('name'):
@@ -63,7 +64,7 @@
doc.naming_series = pos_profile.get('naming_series') or 'SINV-'
doc.letter_head = pos_profile.get('letter_head') or company_data.default_letter_head
doc.ignore_pricing_rule = pos_profile.get('ignore_pricing_rule') or 0
- doc.apply_discount_on = pos_profile.get('apply_discount_on') or ''
+ doc.apply_discount_on = pos_profile.get('apply_discount_on') if pos_profile.get('apply_discount') else ''
doc.customer_group = pos_profile.get('customer_group') or get_root('Customer Group')
doc.territory = pos_profile.get('territory') or get_root('Territory')
@@ -235,10 +236,4 @@
si_doc.docstatus = 0
si_doc.flags.ignore_mandatory = True
si_doc.insert()
- make_scheduler_log(e, si_doc.name)
-
-def make_scheduler_log(e, sales_invoice):
- scheduler_log = frappe.new_doc('Scheduler Log')
- scheduler_log.error = e
- scheduler_log.sales_invoice = sales_invoice
- scheduler_log.save(ignore_permissions=True)
\ No newline at end of file
+ frappe.log_error(frappe.get_traceback())
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index 8e65061..15a7112 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -191,7 +191,7 @@
"in_list_view": 0,
"label": "Is Return",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
@@ -342,6 +342,34 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "project",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_list_view": 0,
+ "label": "Project",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "project_name",
+ "oldfieldtype": "Link",
+ "options": "Project",
+ "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,
+ "columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@@ -380,7 +408,7 @@
"in_list_view": 0,
"label": "Return Against Sales Invoice",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"options": "Sales Invoice",
"permlevel": 0,
"precision": "",
@@ -2878,21 +2906,22 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "project",
+ "depends_on": "",
+ "fieldname": "campaign",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
- "in_filter": 1,
+ "in_filter": 0,
"in_list_view": 0,
- "label": "Project",
+ "label": "Campaign",
"length": 0,
"no_copy": 0,
- "oldfieldname": "project_name",
+ "oldfieldname": "campaign",
"oldfieldtype": "Link",
- "options": "Project",
+ "options": "Campaign",
"permlevel": 0,
- "print_hide": 0,
+ "print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
@@ -2931,35 +2960,6 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "depends_on": "",
- "fieldname": "campaign",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Campaign",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "campaign",
- "oldfieldtype": "Link",
- "options": "Campaign",
- "permlevel": 0,
- "print_hide": 1,
- "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,
- "columns": 0,
"fieldname": "source",
"fieldtype": "Link",
"hidden": 0,
@@ -3867,7 +3867,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2016-09-16 06:09:01.246951",
+ "modified": "2016-09-24 15:54:33.104276",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 2a0077a..3c46a16 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -401,7 +401,7 @@
super(SalesInvoice, self).validate_warehouse()
for d in self.get('items'):
- if not d.warehouse:
+ if not d.warehouse and frappe.db.get_value("Item", d.item_code, "is_stock_item"):
frappe.throw(_("Warehouse required at Row No {0}").format(d.idx))
def validate_delivery_note(self):
diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py
index 4af197e..392902c 100644
--- a/erpnext/accounts/general_ledger.py
+++ b/erpnext/accounts/general_ledger.py
@@ -168,8 +168,8 @@
if not gl_entries:
gl_entries = frappe.db.sql("""
- select account, posting_date, party_type, party, cost_center, fiscal_year,
- voucher_type, voucher_no, against_voucher_type, against_voucher, cost_center
+ select account, posting_date, party_type, party, cost_center, fiscal_year,voucher_type,
+ voucher_no, against_voucher_type, against_voucher, cost_center, company
from `tabGL Entry`
where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no), as_dict=True)
diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js
index 8da1332..b47d6f2 100644
--- a/erpnext/accounts/page/pos/pos.js
+++ b/erpnext/accounts/page/pos/pos.js
@@ -15,13 +15,11 @@
window.onbeforeunload = function () {
return wrapper.pos.beforeunload()
}
- wrapper.pos.on_refresh_page()
}
erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
init: function(wrapper){
- this.load = true;
this.page = wrapper.page;
this.wrapper = $(wrapper).find('.page-content');
this.set_indicator();
@@ -31,17 +29,6 @@
this.si_docs = this.get_doc_from_localstorage();
},
- on_refresh_page: function() {
- var me = this;
- if(this.load){
- this.load = false;
- }else if(this.connection_status){
- this.onload();
- }else{
- this.create_new();
- }
- },
-
beforeunload: function(e){
if(this.connection_status == false && frappe.get_route()[0] == "pos"){
e = e || window.event;
@@ -106,11 +93,15 @@
me.get_data_from_server(function(){
me.load_data(false);
me.make_customer();
- me.make_item_list();
+ me.make_item_list(true);
me.set_missing_values();
})
});
+ this.page.add_menu_item(__("Sync Offline Invoices"), function(){
+ me.sync_sales_invoice()
+ });
+
this.page.add_menu_item(__("POS Profile"), function() {
frappe.set_route('List', 'POS Profile');
});
@@ -278,7 +269,7 @@
make: function() {
this.make_search();
this.make_customer();
- this.make_item_list();
+ this.make_item_list(true);
this.make_discount_field()
},
@@ -299,7 +290,7 @@
this.search.$input.on("keyup", function() {
setTimeout(function() {
me.items = me.get_items();
- me.make_item_list();
+ me.make_item_list(false);
}, 1000);
});
@@ -367,11 +358,14 @@
get_customers: function(key){
var me = this;
key = key.toLowerCase().trim()
+ var re = new RegExp('%', 'g');
+ var reg = new RegExp(key.replace(re, '\\w*\\s*[a-zA-Z0-9]*'))
+
if(key){
return $.grep(this.customers, function(data) {
- if(data.name.toLowerCase().match(key)
- || data.customer_name.toLowerCase().match(key)
- || (data.customer_group && data.customer_group.toLowerCase().match(key))){
+ if(reg.test(data.name.toLowerCase())
+ || reg.test(data.customer_name.toLowerCase())
+ || (data.customer_group && reg.test(data.customer_group.toLowerCase()))){
return data
}
})
@@ -381,7 +375,7 @@
}
},
- make_item_list: function() {
+ make_item_list: function(index_search) {
var me = this;
if(!this.price_list) {
msgprint(__("Price List not found or disabled"));
@@ -395,7 +389,7 @@
if (this.items) {
$.each(this.items, function(index, obj) {
- if(index < 16){
+ if(!index_search || index < 16){
$(frappe.render_template("pos_item", {
item_code: obj.name,
item_price: format_currency(obj.price_list_rate, obj.currency),
@@ -439,7 +433,9 @@
})
}
- key = this.search.$input.val().toLowerCase();
+ key = this.search.$input.val().toLowerCase();
+ var re = new RegExp('%', 'g');
+ var reg = new RegExp(key.replace(re, '\\w*\\s*[a-zA-Z0-9]*'))
search_status = true
if(key){
@@ -455,8 +451,8 @@
} else if(item.barcode == me.search.$input.val()) {
search_status = false;
return item.barcode == me.search.$input.val();
- } else if((item.item_code.toLowerCase().match(key)) ||
- (item.item_name.toLowerCase().match(key)) || (item.item_group.toLowerCase().match(key))) {
+ } else if(reg.test(item.item_code.toLowerCase()) || reg.test(item.description.toLowerCase()) ||
+ reg.test(item.item_name.toLowerCase()) || reg.test(item.item_group.toLowerCase()) ){
return true
}
}
@@ -667,7 +663,6 @@
show_items_in_item_cart: function() {
var me = this;
var $items = this.wrapper.find(".items").empty();
- me.frm.doc.net_total = 0.0
$.each(this.frm.doc.items|| [], function(i, d) {
$(frappe.render_template("pos_bill_item", {
item_code: d.item_code,
diff --git a/erpnext/accounts/party_status.py b/erpnext/accounts/party_status.py
index 68b4818..6d9efb1 100644
--- a/erpnext/accounts/party_status.py
+++ b/erpnext/accounts/party_status.py
@@ -55,7 +55,6 @@
if party.status == 'Open':
# may be open elsewhere, check
# default status
- party.status = status
update_status(party)
party.update_modified()
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index e1f4f80..f6e1629 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -93,9 +93,10 @@
data = []
for gle in self.get_entries_till(self.filters.report_date, args.get("party_type")):
if self.is_receivable_or_payable(gle, dr_or_cr, future_vouchers):
- outstanding_amount = self.get_outstanding_amount(gle, self.filters.report_date, dr_or_cr)
+ outstanding_amount = flt(self.get_outstanding_amount(gle,
+ self.filters.report_date, dr_or_cr), currency_precision)
+
if abs(outstanding_amount) > 0.1/10**currency_precision:
-
row = [gle.posting_date, gle.party]
# customer / supplier name
@@ -124,6 +125,10 @@
row += get_ageing_data(cint(self.filters.range1), cint(self.filters.range2),
cint(self.filters.range3), self.age_as_on, entry_date, outstanding_amount)
+ # issue 6371-Ageing buckets should not have amounts if due date is not reached
+ if self.filters.ageing_based_on == "Due Date" and getdate(due_date) > getdate(self.filters.report_date):
+ row[-1]=row[-2]=row[-3]=row[-4]=0
+
if self.filters.get(scrub(args.get("party_type"))):
row.append(gle.account_currency)
else:
@@ -214,14 +219,16 @@
conditions, values = self.prepare_conditions(party_type)
if self.filters.get(scrub(party_type)):
- select_fields = "debit_in_account_currency as debit, credit_in_account_currency as credit"
+ select_fields = "sum(debit_in_account_currency) as debit, sum(credit_in_account_currency) as credit"
else:
- select_fields = "debit, credit"
+ select_fields = "sum(debit) as debit, sum(credit) as credit"
- self.gl_entries = frappe.db.sql("""select name, posting_date, account, party_type, party,
- voucher_type, voucher_no, against_voucher_type, against_voucher, account_currency, remarks, {0}
+ self.gl_entries = frappe.db.sql("""select name, posting_date, account, party_type, party,
+ voucher_type, voucher_no, against_voucher_type, against_voucher,
+ account_currency, remarks, {0}
from `tabGL Entry`
where docstatus < 2 and party_type=%s and (party is not null and party != '') {1}
+ group by voucher_type, voucher_no, against_voucher_type, against_voucher, party
order by posting_date, party"""
.format(select_fields, conditions), values, as_dict=True)
diff --git a/erpnext/accounts/report/balance_sheet/balance_sheet.py b/erpnext/accounts/report/balance_sheet/balance_sheet.py
index d2626cd..5547b49 100644
--- a/erpnext/accounts/report/balance_sheet/balance_sheet.py
+++ b/erpnext/accounts/report/balance_sheet/balance_sheet.py
@@ -14,17 +14,31 @@
liability = get_data(filters.company, "Liability", "Credit", period_list, only_current_fiscal_year=False)
equity = get_data(filters.company, "Equity", "Credit", period_list, only_current_fiscal_year=False)
- provisional_profit_loss = get_provisional_profit_loss(asset, liability, equity,
+ provisional_profit_loss,total_credit = get_provisional_profit_loss(asset, liability, equity,
period_list, filters.company)
- message = check_opening_balance(asset, liability, equity)
+ message,opening_balance = check_opening_balance(asset, liability, equity)
data = []
data.extend(asset or [])
data.extend(liability or [])
data.extend(equity or [])
+ if opening_balance and round(opening_balance,2) !=0:
+ unclosed ={
+ "account_name": "'" + _("Unclosed Fiscal Years Profit / Loss (Credit)") + "'",
+ "account": None,
+ "warn_if_negative": True,
+ "currency": frappe.db.get_value("Company", filters.company, "default_currency")
+ }
+ for period in period_list:
+ unclosed[period.key] = opening_balance
+ provisional_profit_loss[period.key] = provisional_profit_loss[period.key] - opening_balance
+ unclosed["total"]=opening_balance
+ data.append(unclosed)
+
if provisional_profit_loss:
data.append(provisional_profit_loss)
+ data.append(total_credit)
columns = get_columns(filters.periodicity, period_list, company=filters.company)
@@ -34,14 +48,20 @@
def get_provisional_profit_loss(asset, liability, equity, period_list, company):
if asset and (liability or equity):
- total=0
+ total = total_row_total=0
+ currency = frappe.db.get_value("Company", company, "default_currency")
provisional_profit_loss = {
"account_name": "'" + _("Provisional Profit / Loss (Credit)") + "'",
"account": None,
"warn_if_negative": True,
- "currency": frappe.db.get_value("Company", company, "default_currency")
+ "currency": currency
}
-
+ total_row = {
+ "account_name": "'" + _("Total (Credit)") + "'",
+ "account": None,
+ "warn_if_negative": True,
+ "currency": currency
+ }
has_value = False
for period in period_list:
@@ -52,15 +72,20 @@
effective_liability += flt(equity[-2].get(period.key))
provisional_profit_loss[period.key] = flt(asset[-2].get(period.key)) - effective_liability
+ total_row[period.key] = effective_liability + provisional_profit_loss[period.key]
if provisional_profit_loss[period.key]:
has_value = True
total += flt(provisional_profit_loss[period.key])
provisional_profit_loss["total"] = total
+
+ total_row_total += flt(total_row[period.key])
+ total_row["total"] = total_row_total
if has_value:
- return provisional_profit_loss
+ return provisional_profit_loss, total_row
+ return None,total_row
def check_opening_balance(asset, liability, equity):
# Check if previous year balance sheet closed
@@ -73,7 +98,8 @@
opening_balance -= flt(equity[0].get("opening_balance", 0))
if opening_balance:
- return _("Previous Financial Year is not closed")
+ return _("Previous Financial Year is not closed"),opening_balance
+ return None,None
def get_chart_data(columns, asset, liability, equity):
x_intervals = ['x'] + [d.get("label") for d in columns[2:]]
diff --git a/erpnext/accounts/report/cash_flow/cash_flow.py b/erpnext/accounts/report/cash_flow/cash_flow.py
index 24c5cd2..182878a 100644
--- a/erpnext/accounts/report/cash_flow/cash_flow.py
+++ b/erpnext/accounts/report/cash_flow/cash_flow.py
@@ -60,7 +60,6 @@
company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
for cash_flow_account in cash_flow_accounts:
-
section_data = []
data.append({
"account_name": cash_flow_account['section_header'],
@@ -83,7 +82,8 @@
account_data = get_account_type_based_data(filters.company,
account['account_type'], period_list, filters.accumulated_values)
account_data.update({
- "account_name": account['label'],
+ "account_name": account['label'],
+ "account": account['label'],
"indent": 1,
"parent_account": cash_flow_account['section_header'],
"currency": company_currency
@@ -136,7 +136,7 @@
def add_total_row_account(out, data, label, period_list, currency):
total_row = {
"account_name": "'" + _("{0}").format(label) + "'",
- "account": None,
+ "account": "'" + _("{0}").format(label) + "'",
"currency": currency
}
for row in data:
diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
index 39e38d7..1322649 100644
--- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
+++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
@@ -5,6 +5,7 @@
import frappe
from frappe import _
from frappe.utils import flt
+from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments
def execute(filters=None):
if not filters: filters = {}
@@ -21,6 +22,7 @@
"width": 80
})
company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
+ mode_of_payments = get_mode_of_payments(set([d.parent for d in item_list]))
data = []
for d in item_list:
@@ -34,7 +36,8 @@
delivery_note = d.parent
row = [d.item_code, d.item_name, d.item_group, d.parent, d.posting_date, d.customer, d.customer_name,
- d.customer_group, d.debit_to, d.mode_of_payment, d.territory, d.project, d.company, d.sales_order,
+ d.customer_group, d.debit_to, ", ".join(mode_of_payments.get(d.parent, [])),
+ d.territory, d.project, d.company, d.sales_order,
delivery_note, d.income_account, d.cost_center, d.qty, d.base_net_rate, d.base_net_amount]
for tax in tax_accounts:
@@ -54,7 +57,7 @@
_("Posting Date") + ":Date:80", _("Customer") + ":Link/Customer:120",
_("Customer Name") + "::120", _("Customer Group") + ":Link/Customer Group:120",
_("Receivable Account") + ":Link/Account:120",
- _("Mode of Payment") + ":Link/Mode of Payment:80", _("Territory") + ":Link/Territory:80",
+ _("Mode of Payment") + "::120", _("Territory") + ":Link/Territory:80",
_("Project") + ":Link/Project:80", _("Company") + ":Link/Company:100",
_("Sales Order") + ":Link/Sales Order:100", _("Delivery Note") + ":Link/Delivery Note:100",
_("Income Account") + ":Link/Account:140", _("Cost Center") + ":Link/Cost Center:140",
@@ -70,10 +73,14 @@
("customer", " and si.customer = %(customer)s"),
("item_code", " and si_item.item_code = %(item_code)s"),
("from_date", " and si.posting_date>=%(from_date)s"),
- ("to_date", " and si.posting_date<=%(to_date)s"),
- ("mode_of_payment", " and ifnull(mode_of_payment, '') = %(mode_of_payment)s")):
+ ("to_date", " and si.posting_date<=%(to_date)s")):
if filters.get(opts[0]):
conditions += opts[1]
+
+ if filters.get("mode_of_payment"):
+ conditions += """ and exists(select name from `tabSales Invoice Payment`
+ where parent=si.name
+ and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
return conditions
@@ -86,7 +93,7 @@
si_item.item_code, si_item.item_name, si_item.item_group, si_item.sales_order,
si_item.delivery_note, si_item.income_account, si_item.cost_center, si_item.qty,
si_item.base_net_rate, si_item.base_net_amount, si.customer_name,
- si.customer_group, si_item.so_detail, si.update_stock, si.mode_of_payment
+ si.customer_group, si_item.so_detail, si.update_stock
from `tabSales Invoice` si, `tabSales Invoice Item` si_item
where si.name = si_item.parent and si.docstatus = 1 %s
order by si.posting_date desc, si_item.item_code desc""" % conditions, filters, as_dict=1)
diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py
index 6b7f490..747eb43 100644
--- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py
+++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py
@@ -34,7 +34,7 @@
total = 0
net_profit_loss = {
"account_name": "'" + _("Net Profit / Loss") + "'",
- "account": None,
+ "account": "'" + _("Net Profit / Loss") + "'",
"warn_if_negative": True,
"currency": frappe.db.get_value("Company", company, "default_currency")
}
diff --git a/erpnext/accounts/report/profitability_analysis/profitability_analysis.js b/erpnext/accounts/report/profitability_analysis/profitability_analysis.js
index 4b9a1af..a25fa56 100644
--- a/erpnext/accounts/report/profitability_analysis/profitability_analysis.js
+++ b/erpnext/accounts/report/profitability_analysis/profitability_analysis.js
@@ -14,7 +14,7 @@
},
{
"fieldname": "based_on",
- "label": __("Baed On"),
+ "label": __("Based On"),
"fieldtype": "Select",
"options": "Cost Center\nProject",
"default": "Cost Center",
diff --git a/erpnext/accounts/report/sales_register/sales_register.py b/erpnext/accounts/report/sales_register/sales_register.py
index 663c5c9..5b1742a 100644
--- a/erpnext/accounts/report/sales_register/sales_register.py
+++ b/erpnext/accounts/report/sales_register/sales_register.py
@@ -23,6 +23,7 @@
invoice_so_dn_map = get_invoice_so_dn_map(invoice_list)
customer_map = get_customer_deatils(invoice_list)
company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
+ mode_of_payments = get_mode_of_payments([inv.name for inv in invoice_list])
data = []
for inv in invoice_list:
@@ -33,7 +34,7 @@
row = [inv.name, inv.posting_date, inv.customer, inv.customer_name,
customer_map.get(inv.customer, {}).get("customer_group"),
customer_map.get(inv.customer, {}).get("territory"),
- inv.debit_to, inv.mode_of_payment, inv.project, inv.remarks,
+ inv.debit_to, ", ".join(mode_of_payments.get(inv.name, [])), inv.project, inv.remarks,
", ".join(sales_order), ", ".join(delivery_note), company_currency]
# map income values
@@ -68,7 +69,7 @@
_("Invoice") + ":Link/Sales Invoice:120", _("Posting Date") + ":Date:80",
_("Customer Id") + "::120", _("Customer Name") + "::120",
_("Customer Group") + ":Link/Customer Group:120", _("Territory") + ":Link/Territory:80",
- _("Receivable Account") + ":Link/Account:120", _("Mode of Payment") + ":Link/Mode of Payment:80",
+ _("Receivable Account") + ":Link/Account:120", _("Mode of Payment") + "::120",
_("Project") +":Link/Project:80", _("Remarks") + "::150",
_("Sales Order") + ":Link/Sales Order:100", _("Delivery Note") + ":Link/Delivery Note:100",
{
@@ -113,14 +114,17 @@
if filters.get("from_date"): conditions += " and posting_date >= %(from_date)s"
if filters.get("to_date"): conditions += " and posting_date <= %(to_date)s"
- if filters.get("mode_of_payment"): conditions += " and ifnull(mode_of_payment, '') = %(mode_of_payment)s"
-
+ if filters.get("mode_of_payment"):
+ conditions += """ and exists(select name from `tabSales Invoice Payment`
+ where parent=`tabSales Invoice`.name
+ and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
+
return conditions
def get_invoices(filters):
conditions = get_conditions(filters)
return frappe.db.sql("""select name, posting_date, debit_to, project, customer, customer_name, remarks,
- base_net_total, base_grand_total, base_rounded_total, outstanding_amount, mode_of_payment
+ base_net_total, base_grand_total, base_rounded_total, outstanding_amount
from `tabSales Invoice`
where docstatus = 1 %s order by posting_date desc, name desc""" %
conditions, filters, as_dict=1)
@@ -188,3 +192,16 @@
customer_map.setdefault(cust.name, cust)
return customer_map
+
+
+def get_mode_of_payments(invoice_list):
+ mode_of_payments = {}
+ if invoice_list:
+ inv_mop = frappe.db.sql("""select parent, mode_of_payment
+ from `tabSales Invoice Payment` where parent in (%s) group by parent, mode_of_payment""" %
+ ', '.join(['%s']*len(invoice_list)), tuple(invoice_list), as_dict=1)
+
+ for d in inv_mop:
+ mode_of_payments.setdefault(d.parent, []).append(d.mode_of_payment)
+
+ return mode_of_payments
\ No newline at end of file
diff --git a/erpnext/accounts/report/trial_balance/trial_balance.js b/erpnext/accounts/report/trial_balance/trial_balance.js
index 9943e5d..ff198e9 100644
--- a/erpnext/accounts/report/trial_balance/trial_balance.js
+++ b/erpnext/accounts/report/trial_balance/trial_balance.js
@@ -55,6 +55,11 @@
"label": __("Show zero values"),
"fieldtype": "Check"
},
+ {
+ "fieldname": "show_unclosed_fy_pl_balances",
+ "label": __("Show unclosed fiscal year's P&L balances"),
+ "fieldtype": "Check"
+ }
],
"formatter": erpnext.financial_statements.formatter,
"tree": true,
diff --git a/erpnext/accounts/report/trial_balance/trial_balance.py b/erpnext/accounts/report/trial_balance/trial_balance.py
index 5401902..7609d1d 100644
--- a/erpnext/accounts/report/trial_balance/trial_balance.py
+++ b/erpnext/accounts/report/trial_balance/trial_balance.py
@@ -87,8 +87,10 @@
def get_rootwise_opening_balances(filters, report_type):
- additional_conditions = " and posting_date >= %(year_start_date)s" \
- if report_type == "Profit and Loss" else ""
+ additional_conditions = ""
+ if not filters.show_unclosed_fy_pl_balances:
+ additional_conditions = " and posting_date >= %(year_start_date)s" \
+ if report_type == "Profit and Loss" else ""
if not flt(filters.with_period_closing_entry):
additional_conditions += " and ifnull(voucher_type, '')!='Period Closing Voucher'"
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index eefdc1d..f3dc7ba 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -701,4 +701,4 @@
except frappe.DuplicateEntryError:
# already exists, due to a reinstall?
- pass
+ pass
\ No newline at end of file
diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
index de76c82..466300c 100755
--- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
+++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
@@ -605,7 +605,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
- "label": "Rate ",
+ "label": "Rate",
"length": 0,
"no_copy": 0,
"oldfieldname": "import_rate",
@@ -1465,7 +1465,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-08-26 04:41:17.371535",
+ "modified": "2016-09-22 05:46:00.860706",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order Item",
diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.json b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.json
index e48e1dc..7525e44 100644
--- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.json
+++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.json
@@ -15,6 +15,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
@@ -43,6 +44,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "",
"fieldname": "company",
"fieldtype": "Link",
@@ -72,6 +74,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "For individual supplier",
"fieldname": "vendor",
"fieldtype": "Link",
@@ -99,6 +102,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -126,6 +130,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "transaction_date",
"fieldtype": "Date",
"hidden": 0,
@@ -153,6 +158,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "suppliers_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -178,6 +184,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "suppliers",
"fieldtype": "Table",
"hidden": 0,
@@ -204,6 +211,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "items_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -231,6 +239,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "items",
"fieldtype": "Table",
"hidden": 0,
@@ -259,6 +268,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "supplier_response_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -284,6 +294,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "standard_reply",
"fieldtype": "Link",
"hidden": 0,
@@ -310,6 +321,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "message_for_supplier",
"fieldtype": "Text Editor",
"hidden": 0,
@@ -336,6 +348,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "terms",
+ "columns": 0,
"fieldname": "terms_section_break",
"fieldtype": "Section Break",
"hidden": 0,
@@ -363,6 +376,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "tc_name",
"fieldtype": "Link",
"hidden": 0,
@@ -391,6 +405,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "terms",
"fieldtype": "Text Editor",
"hidden": 0,
@@ -418,6 +433,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
+ "columns": 0,
"fieldname": "printing_settings",
"fieldtype": "Section Break",
"hidden": 0,
@@ -443,6 +459,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "select_print_heading",
"fieldtype": "Link",
"hidden": 0,
@@ -471,6 +488,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "letter_head",
"fieldtype": "Link",
"hidden": 0,
@@ -499,6 +517,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
+ "columns": 0,
"fieldname": "more_info",
"fieldtype": "Section Break",
"hidden": 0,
@@ -526,6 +545,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "status",
"fieldtype": "Select",
"hidden": 0,
@@ -554,6 +574,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "fiscal_year",
"fieldtype": "Link",
"hidden": 0,
@@ -582,6 +603,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break3",
"fieldtype": "Column Break",
"hidden": 0,
@@ -606,6 +628,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@@ -639,8 +662,8 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-08-01 08:45:39.777405",
- "modified_by": "Administrator",
+ "modified": "2016-09-29 11:56:57.123429",
+ "modified_by": "neil@frappe.io",
"module": "Buying",
"name": "Request for Quotation",
"name_case": "",
@@ -732,26 +755,6 @@
"cancel": 0,
"create": 0,
"delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Supplier",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
- "write": 0
- },
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
"email": 0,
"export": 0,
"if_owner": 0,
diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
index b01d3e8..78af1ef 100644
--- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
+++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
@@ -192,8 +192,6 @@
if isinstance(doc, basestring):
doc = json.loads(doc)
- validate_duplicate_supplier_quotation(doc)
-
try:
sq_doc = frappe.get_doc({
"doctype": "Supplier Quotation",
@@ -210,7 +208,7 @@
frappe.msgprint(_("Supplier Quotation {0} created").format(sq_doc.name))
return sq_doc.name
except Exception:
- return
+ return None
def add_items(sq_doc, supplier, items):
for data in items:
@@ -245,13 +243,3 @@
args = doc.get('suppliers')[cint(supplier_idx) - 1]
doc.update_supplier_part_no(args)
return doc
-
-@frappe.whitelist()
-def validate_duplicate_supplier_quotation(args):
- data = frappe.db.sql("""select sq.name as name from `tabSupplier Quotation` sq,
- `tabSupplier Quotation Item` sqi where sqi.parent = sq.name and sq.supplier = %(supplier)s
- and sqi.request_for_quotation = %(rfq)s and sq.docstatus < 2""",
- {'supplier': args.get('supplier'), 'rfq': args.get('name')}, as_dict=True)
-
- if data and data[0] and data[0].name:
- frappe.throw(_("Already supplier quotation has created"))
diff --git a/erpnext/buying/doctype/supplier/supplier.json b/erpnext/buying/doctype/supplier/supplier.json
index a9c8f1a..ac7656c 100644
--- a/erpnext/buying/doctype/supplier/supplier.json
+++ b/erpnext/buying/doctype/supplier/supplier.json
@@ -16,6 +16,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "basic_info",
"fieldtype": "Section Break",
"hidden": 0,
@@ -42,6 +43,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
@@ -69,6 +71,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
+ "columns": 0,
"fieldname": "supplier_name",
"fieldtype": "Data",
"hidden": 0,
@@ -95,6 +98,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "country",
"fieldtype": "Link",
"hidden": 0,
@@ -121,6 +125,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "image",
"fieldtype": "Attach Image",
"hidden": 1,
@@ -130,7 +135,7 @@
"in_list_view": 0,
"label": "Image",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
@@ -146,6 +151,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "status",
"fieldtype": "Select",
"hidden": 1,
@@ -172,6 +178,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
@@ -196,6 +203,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "supplier_type",
"fieldtype": "Link",
"hidden": 0,
@@ -223,6 +231,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "language",
"fieldtype": "Link",
"hidden": 0,
@@ -249,6 +258,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
+ "columns": 0,
"default": "0",
"fieldname": "disabled",
"fieldtype": "Check",
@@ -275,6 +285,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
+ "columns": 0,
"fieldname": "section_break_7",
"fieldtype": "Section Break",
"hidden": 0,
@@ -300,6 +311,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "default_currency",
"fieldtype": "Link",
"hidden": 0,
@@ -325,6 +337,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_10",
"fieldtype": "Column Break",
"hidden": 0,
@@ -349,6 +362,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "default_price_list",
"fieldtype": "Link",
"hidden": 0,
@@ -374,6 +388,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
+ "columns": 0,
"fieldname": "section_credit_limit",
"fieldtype": "Section Break",
"hidden": 0,
@@ -399,6 +414,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "credit_days_based_on",
"fieldtype": "Select",
"hidden": 0,
@@ -425,6 +441,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.credit_days_based_on == 'Fixed Days'",
"fieldname": "credit_days",
"fieldtype": "Int",
@@ -450,6 +467,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:!doc.__islocal",
"fieldname": "address_contacts",
"fieldtype": "Section Break",
@@ -477,6 +495,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "address_html",
"fieldtype": "HTML",
"hidden": 0,
@@ -501,6 +520,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -525,6 +545,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "contact_html",
"fieldtype": "HTML",
"hidden": 0,
@@ -550,6 +571,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "accounts",
+ "columns": 0,
"fieldname": "default_payable_accounts",
"fieldtype": "Section Break",
"hidden": 0,
@@ -574,6 +596,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"description": "Mention if non-standard receivable account",
"fieldname": "accounts",
@@ -602,6 +625,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "supplier_details",
+ "columns": 0,
"fieldname": "column_break2",
"fieldtype": "Section Break",
"hidden": 0,
@@ -627,6 +651,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "website",
"fieldtype": "Data",
"hidden": 0,
@@ -653,6 +678,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Statutory info and other general information about your Supplier",
"fieldname": "supplier_details",
"fieldtype": "Text",
@@ -680,6 +706,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "is_frozen",
"fieldtype": "Check",
"hidden": 0,
@@ -714,7 +741,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-08-23 05:43:20.950021",
+ "modified": "2016-09-21 18:11:03.873221",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier",
diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
index 206dfa3..144e982 100644
--- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
+++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
@@ -3,6 +3,7 @@
from __future__ import unicode_literals
import frappe
+from frappe import _
from frappe.utils import flt
from frappe.model.mapper import get_mapped_doc
@@ -54,6 +55,18 @@
pc = frappe.get_doc('Purchase Common')
pc.validate_for_items(self)
+def get_list_context(context=None):
+ from erpnext.controllers.website_list_for_contact import get_list_context
+ list_context = get_list_context(context)
+ list_context.update({
+ 'show_sidebar': True,
+ 'show_search': True,
+ 'no_breadcrumbs': True,
+ 'title': _('Supplier Quotation'),
+ })
+
+ return list_context
+
@frappe.whitelist()
def make_purchase_order(source_name, target_doc=None):
def set_missing_values(source, target):
diff --git a/erpnext/config/projects.py b/erpnext/config/projects.py
index e6c9578..87174a4 100644
--- a/erpnext/config/projects.py
+++ b/erpnext/config/projects.py
@@ -19,7 +19,7 @@
},
{
"type": "report",
- "route": "Gantt/Task",
+ "route": "List/Task/Gantt",
"doctype": "Task",
"name": "Gantt Chart",
"description": _("Gantt chart of all tasks.")
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 8927da7..3d2f16b 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -26,6 +26,9 @@
return self.__company_currency
+ def onload(self):
+ self.get("__onload").make_payment_via_journal_entry = frappe.db.get_single_value('Accounts Settings', 'make_payment_via_journal_entry')
+
def validate(self):
if self.get("_action") and self._action != "update_after_submit":
self.set_missing_values(for_validate=True)
@@ -144,7 +147,7 @@
self.conversion_rate = get_exchange_rate(self.currency,
self.company_currency)
- def set_missing_item_details(self):
+ def set_missing_item_details(self, for_validate=False):
"""set missing item values"""
from erpnext.stock.get_item_details import get_item_details
@@ -196,7 +199,7 @@
(1.0 - (flt(item.discount_percentage) / 100.0)), item.precision("rate"))
if self.doctype == "Purchase Invoice":
- self.set_expense_account()
+ self.set_expense_account(for_validate)
def set_taxes(self):
if not self.meta.get_field("taxes"):
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index f7181d7..865514b 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -62,7 +62,7 @@
if getattr(self, "supplier", None):
self.update_if_missing(get_party_details(self.supplier, party_type="Supplier", ignore_permissions=self.flags.ignore_permissions))
- self.set_missing_item_details()
+ self.set_missing_item_details(for_validate)
def set_supplier_from_item_default(self):
if self.meta.get_field("supplier") and not self.supplier:
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index b9b94f5..3f4d12d 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -23,6 +23,7 @@
self.grand_total)
def onload(self):
+ super(SellingController, self).onload()
if self.doctype in ("Sales Order", "Delivery Note", "Sales Invoice"):
for item in self.get("items"):
item.update(get_bin_details(item.item_code,
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index 7be6acd..157c385 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -301,12 +301,7 @@
ref_doc = frappe.get_doc(ref_dt, ref_dn)
ref_doc.db_set("per_billed", per_billed)
-
- if frappe.get_meta(ref_dt).get_field("billing_status"):
- if per_billed < 0.001: billing_status = "Not Billed"
- elif per_billed >= 99.99: billing_status = "Fully Billed"
- else: billing_status = "Partly Billed"
- ref_doc.db_set('billing_status', billing_status)
+ ref_doc.set_status(update=True)
def get_tolerance_for(item_code, item_tolerance={}, global_tolerance=None):
"""
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index 3f25e02..aa84929 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -276,12 +276,18 @@
def compare_existing_and_expected_gle(existing_gle, expected_gle):
matched = True
for entry in expected_gle:
+ account_existed = False
for e in existing_gle:
- if entry.account==e.account and entry.against_account==e.against_account \
- and (not entry.cost_center or not e.cost_center or entry.cost_center==e.cost_center) \
- and (entry.debit != e.debit or entry.credit != e.credit):
- matched = False
- break
+ if entry.account == e.account:
+ account_existed = True
+ if entry.account == e.account and entry.against_account == e.against_account \
+ and (not entry.cost_center or not e.cost_center or entry.cost_center == e.cost_center) \
+ and (entry.debit != e.debit or entry.credit != e.credit):
+ matched = False
+ break
+ if not account_existed:
+ matched = False
+ break
return matched
def get_future_stock_vouchers(posting_date, posting_time, for_warehouses=None, for_items=None):
diff --git a/erpnext/controllers/trends.py b/erpnext/controllers/trends.py
index 080d749..d991c15 100644
--- a/erpnext/controllers/trends.py
+++ b/erpnext/controllers/trends.py
@@ -49,10 +49,10 @@
posting_date = 't1.posting_date'
if conditions["based_on_select"] in ["t1.project,", "t2.project,"]:
- cond = 'and '+ conditions["based_on_select"][:-1] +' IS Not NULL'
+ cond = ' and '+ conditions["based_on_select"][:-1] +' IS Not NULL'
if conditions.get('trans') in ['Sales Order', 'Purchase Order']:
- cond += "and t1.status != 'Closed'"
+ cond += " and t1.status != 'Closed'"
year_start_date, year_end_date = frappe.db.get_value("Fiscal Year",
filters.get('fiscal_year'), ["year_start_date", "year_end_date"])
diff --git a/erpnext/controllers/website_list_for_contact.py b/erpnext/controllers/website_list_for_contact.py
index 75c6e08..1abb7e7 100644
--- a/erpnext/controllers/website_list_for_contact.py
+++ b/erpnext/controllers/website_list_for_contact.py
@@ -25,7 +25,10 @@
if not filters: filters = []
- filters.append((doctype, "docstatus", "=", 1))
+ if doctype == 'Supplier Quotation':
+ filters.append((doctype, "docstatus", "<", 2))
+ else:
+ filters.append((doctype, "docstatus", "=", 1))
if user != "Guest" and is_website_user():
parties_doctype = 'Request for Quotation Supplier' if doctype == 'Request for Quotation' else doctype
@@ -112,7 +115,8 @@
return frappe.get_all(doctype, filters=[(doctype, "customer", "in", customers),
(doctype, "name", "=", doc.name)]) and True or False
elif suppliers:
- return frappe.get_all(doctype, filters=[(doctype, "suppliers", "in", suppliers),
+ fieldname = 'suppliers' if doctype == 'Request for Quotation' else 'supplier'
+ return frappe.get_all(doctype, filters=[(doctype, fieldname, "in", suppliers),
(doctype, "name", "=", doc.name)]) and True or False
else:
return False
diff --git a/erpnext/docs/assets/img/accounts/account-settings.png b/erpnext/docs/assets/img/accounts/account-settings.png
index 943aa3d..dfe2abe 100644
--- a/erpnext/docs/assets/img/accounts/account-settings.png
+++ b/erpnext/docs/assets/img/accounts/account-settings.png
Binary files differ
diff --git a/erpnext/docs/assets/img/accounts/journal-entry.png b/erpnext/docs/assets/img/accounts/journal-entry.png
index d4a4e21..c6a2a64 100644
--- a/erpnext/docs/assets/img/accounts/journal-entry.png
+++ b/erpnext/docs/assets/img/accounts/journal-entry.png
Binary files differ
diff --git a/erpnext/docs/assets/img/accounts/pos-sales-invoice.png b/erpnext/docs/assets/img/accounts/pos-sales-invoice.png
new file mode 100644
index 0000000..3a115ed
--- /dev/null
+++ b/erpnext/docs/assets/img/accounts/pos-sales-invoice.png
Binary files differ
diff --git a/erpnext/docs/assets/img/fleet-management/__init__.py b/erpnext/docs/assets/img/fleet-management/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/docs/assets/img/fleet-management/__init__.py
diff --git a/erpnext/docs/assets/img/fleet-management/expense-claim-3.1.png b/erpnext/docs/assets/img/fleet-management/expense-claim-3.1.png
new file mode 100644
index 0000000..6aa4d69
--- /dev/null
+++ b/erpnext/docs/assets/img/fleet-management/expense-claim-3.1.png
Binary files differ
diff --git a/erpnext/docs/assets/img/fleet-management/expense-claim-3.2.png b/erpnext/docs/assets/img/fleet-management/expense-claim-3.2.png
new file mode 100644
index 0000000..9376988
--- /dev/null
+++ b/erpnext/docs/assets/img/fleet-management/expense-claim-3.2.png
Binary files differ
diff --git a/erpnext/docs/assets/img/fleet-management/vehicle-1.1.png b/erpnext/docs/assets/img/fleet-management/vehicle-1.1.png
new file mode 100644
index 0000000..b40912d
--- /dev/null
+++ b/erpnext/docs/assets/img/fleet-management/vehicle-1.1.png
Binary files differ
diff --git a/erpnext/docs/assets/img/fleet-management/vehicle-1.2.png b/erpnext/docs/assets/img/fleet-management/vehicle-1.2.png
new file mode 100644
index 0000000..8a8695e
--- /dev/null
+++ b/erpnext/docs/assets/img/fleet-management/vehicle-1.2.png
Binary files differ
diff --git a/erpnext/docs/assets/img/fleet-management/vehicle-1.3.png b/erpnext/docs/assets/img/fleet-management/vehicle-1.3.png
new file mode 100644
index 0000000..8110454
--- /dev/null
+++ b/erpnext/docs/assets/img/fleet-management/vehicle-1.3.png
Binary files differ
diff --git a/erpnext/docs/assets/img/fleet-management/vehicle-expenses.png b/erpnext/docs/assets/img/fleet-management/vehicle-expenses.png
new file mode 100644
index 0000000..166717c
--- /dev/null
+++ b/erpnext/docs/assets/img/fleet-management/vehicle-expenses.png
Binary files differ
diff --git a/erpnext/docs/assets/img/fleet-management/vehicle-log-2.1.png b/erpnext/docs/assets/img/fleet-management/vehicle-log-2.1.png
new file mode 100644
index 0000000..f859b42
--- /dev/null
+++ b/erpnext/docs/assets/img/fleet-management/vehicle-log-2.1.png
Binary files differ
diff --git a/erpnext/docs/assets/img/fleet-management/vehicle-log-2.2.png b/erpnext/docs/assets/img/fleet-management/vehicle-log-2.2.png
new file mode 100644
index 0000000..12d3187
--- /dev/null
+++ b/erpnext/docs/assets/img/fleet-management/vehicle-log-2.2.png
Binary files differ
diff --git a/erpnext/docs/assets/img/human-resources/bank-entry.png b/erpnext/docs/assets/img/human-resources/bank-entry.png
new file mode 100644
index 0000000..b870bc5
--- /dev/null
+++ b/erpnext/docs/assets/img/human-resources/bank-entry.png
Binary files differ
diff --git a/erpnext/docs/assets/img/human-resources/process-payroll.png b/erpnext/docs/assets/img/human-resources/process-payroll.png
index ebbd9ae..2e2fbed 100644
--- a/erpnext/docs/assets/img/human-resources/process-payroll.png
+++ b/erpnext/docs/assets/img/human-resources/process-payroll.png
Binary files differ
diff --git a/erpnext/docs/assets/img/human-resources/salary-structure-account.png b/erpnext/docs/assets/img/human-resources/salary-structure-account.png
new file mode 100644
index 0000000..bd37ee0
--- /dev/null
+++ b/erpnext/docs/assets/img/human-resources/salary-structure-account.png
Binary files differ
diff --git a/erpnext/docs/assets/img/human-resources/salary-structure.png b/erpnext/docs/assets/img/human-resources/salary-structure.png
index a135092..71f6013 100644
--- a/erpnext/docs/assets/img/human-resources/salary-structure.png
+++ b/erpnext/docs/assets/img/human-resources/salary-structure.png
Binary files differ
diff --git a/erpnext/docs/user/manual/en/accounts/index.txt b/erpnext/docs/user/manual/en/accounts/index.txt
index d7c405a..6ba9337 100644
--- a/erpnext/docs/user/manual/en/accounts/index.txt
+++ b/erpnext/docs/user/manual/en/accounts/index.txt
@@ -3,6 +3,7 @@
sales-invoice
point-of-sale-pos-invoice
purchase-invoice
+payments
journal-entry
payment-entry
multi-currency-accounting
diff --git a/erpnext/docs/user/manual/en/accounts/managing-fixed-assets.md b/erpnext/docs/user/manual/en/accounts/managing-fixed-assets.md
index f8dbe1d..8eefe7f 100644
--- a/erpnext/docs/user/manual/en/accounts/managing-fixed-assets.md
+++ b/erpnext/docs/user/manual/en/accounts/managing-fixed-assets.md
@@ -62,7 +62,7 @@
On submission of the invoice, the "Fixed Asset Account" will be debited and payable account will be credited. It also updates purchase date, supplier and Purchase Invoice no. in the Asset master.
-## Sale an Asset
+## Sell an Asset
To sale an asset, open the asset record and create a Sales Invoice by clicking on "Sale Asset". On submission of the Sales Invoice, following entries will take place:
diff --git a/erpnext/docs/user/manual/en/accounts/payments.md b/erpnext/docs/user/manual/en/accounts/payments.md
new file mode 100644
index 0000000..7e5aab3
--- /dev/null
+++ b/erpnext/docs/user/manual/en/accounts/payments.md
@@ -0,0 +1,48 @@
+Payment can be made against following transactions.
+
+ 1. Sales Invoice.
+ 2. Purchase Invoice.
+ 3. Sales Order (Advance Payment)
+ 4. Purchase Order (Advance Payment)
+
+In ERPNext, there is two options through which user can capture the payment
+
+ 1. Payment Entry(Default).
+ 2. Journal Entry.
+
+## Payment Entry
+
+####Step 1: Make Payment
+
+On submitting a document against which Payment Entry can be made, you will find Make Payment button.
+
+<img class="screenshot" alt="Making Payment" src="{{docs_base_url}}/assets/img/accounts/payment-entry-1.png">
+
+####Step 2: Payment Entry
+
+<img class="screenshot" alt="Making Payment" src="{{docs_base_url}}/assets/img/accounts/payment-entry-9.png">
+
+For more details about payment entry [check here.](https://frappe.github.io/erpnext/user/manual/en/accounts/payment-entry)
+
+## Journal Entry
+
+To make paymant using journal entry, check below steps
+
+####Step 1: Activate Payment via Journal Entry
+
+Goto Accounts Settings > checked Make Payment via Journal Entry
+
+<img class="screenshot" alt="Making Payment" src="{{docs_base_url}}/assets/img/accounts/account-settings.png">
+
+####Step 2: Make Payment
+
+On submitting a document against which Journal Entry can be made, you will find Make Payment button.
+
+<img class="screenshot" alt="Making Payment" src="{{docs_base_url}}/assets/img/accounts/payment-entry-1.png">
+
+####Step 3: Journal Entry
+
+Save and submit the journal entry to record the payament against the invoice
+<img class="screenshot" alt="Making Payment" src="{{docs_base_url}}/assets/img/accounts/journal-entry.png">
+
+For more details about journal entry [check here.](https://frappe.github.io/erpnext/user/manual/en/accounts/journal-entry)
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/accounts/sales-invoice.md b/erpnext/docs/user/manual/en/accounts/sales-invoice.md
index f9a453e..fb132e7 100644
--- a/erpnext/docs/user/manual/en/accounts/sales-invoice.md
+++ b/erpnext/docs/user/manual/en/accounts/sales-invoice.md
@@ -2,9 +2,9 @@
You can create a Sales Invoice directly from
-> Accounting > Documents > Sales Invoice > New Sales Invoice
+> Accounts > Billing > Sales Invoice > New Sales Invoice
-or Click on Make Invoice at the right hand corner of the Delivery Note.
+or you can Make a new Sales Invoice after you submit the Delivery Note.
<img class="screenshot" alt="Sales Invoice" src="{{docs_base_url}}/assets/img/accounts/sales-invoice.png">
@@ -54,6 +54,16 @@
ERPNext will automatically create new Invoices and mail it to the email ids
you set.
+#### POS Invoices
+
+Consider a scenario where retail transaction is carried out. For e.g: A retail shop.
+If you check the **Is POS** checkbox, then all your **POS Profile** data is fetched
+into the Sales Invoice and you can easily make payments.
+Also, if you check the **Update Stock** the stock will also update automatically,
+without the need of a Delivery Note.
+
+<img class="screenshot" alt="POS Invoice" src="{{docs_base_url}}/assets/img/accounts/pos-sales-invoice.png">
+
* * *
#### "Pro Forma" Invoice
diff --git a/erpnext/docs/user/manual/en/buying/supplier.md b/erpnext/docs/user/manual/en/buying/supplier.md
index 45ec6b1..89107db 100644
--- a/erpnext/docs/user/manual/en/buying/supplier.md
+++ b/erpnext/docs/user/manual/en/buying/supplier.md
@@ -2,7 +2,7 @@
You can create a new Supplier from:
-`Buying > Documents > Supplier > New Supplier`
+`Explore > Supplier > New Supplier`
<img class="screenshot" alt="Supplier Master" src="{{docs_base_url}}/assets/img/buying/supplier-master.png">
diff --git a/erpnext/docs/user/manual/en/fleet_management/__init__.py b/erpnext/docs/user/manual/en/fleet_management/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/docs/user/manual/en/fleet_management/__init__.py
diff --git a/erpnext/docs/user/manual/en/fleet_management/index.md b/erpnext/docs/user/manual/en/fleet_management/index.md
new file mode 100644
index 0000000..8ae3b7c
--- /dev/null
+++ b/erpnext/docs/user/manual/en/fleet_management/index.md
@@ -0,0 +1,64 @@
+Fleet Management module helps your Organization manage their fleet of vehicles and track their expenses.
+
+To use Fleet Management in ERPNext,
+
+ 1. Set Up a Vehicle.
+ 2. Enter Vehicle Logs regularly.
+ 3. Make Expense Claims for Vehicle Expenses.
+ 4. View Reports for Vehicle Expenses.
+
+### Vehicle Set Up
+
+The Vehicle Set Up allows you to define the different types of Vehicles in your Organization.It acts as the Vehicle Master for Fleet Management.
+
+To create a new Vehicle go to:
+
+ERPNext > Vehicle
+
+* Enter License Plate,Make,Model,Odometer Value,Fuel Type and Fuel UOM for a quick entry.
+
+ <img class="screenshot" alt="Vehicle" src="{{docs_base_url}}/assets/img/fleet-management/vehicle-1.1.png">
+
+* Enter details like Insurance,Chassis,Vehicle Value,Location and Employee.
+
+ <img class="screenshot" alt="Vehicle" src="{{docs_base_url}}/assets/img/fleet-management/vehicle-1.2.png">
+
+* Enter Vehicle attributes like color,wheels,doors and last carbon check
+
+ <img class="screenshot" alt="Vehicle" src="{{docs_base_url}}/assets/img/fleet-management/vehicle-1.3.png">
+
+### Vehicle Log
+
+Vehicle Log is used to enter Odometer readings,Fuel Expenses and Service Expense details.
+
+To create a new Vehicle Log go to:
+
+ERPNext > Vehicle Log
+
+* Enter License Plate,Employee,Date,Odometer reading for a quick entry.
+
+ <img class="screenshot" alt="Vehicle Log" src="{{docs_base_url}}/assets/img/fleet-management/vehicle-log-2.1.png">
+
+* Enter Refuelling details,Service details if applicable.
+
+ <img class="screenshot" alt="Vehicle Log" src="{{docs_base_url}}/assets/img/fleet-management/vehicle-log-2.2.png">
+
+### Make Expense Claim
+
+* Click on Make Expense Claim button .This button appears only in case of Submitted Vehicle Logs.
+
+ <img class="screenshot" alt="Vehicle Log" src="{{docs_base_url}}/assets/img/fleet-management/expense-claim-3.1.png">
+
+When you click on 'Make Expense Claim',
+
+ 1. The date,employee,expense total are copied over to the created Expense Claim.
+ 2. The sum of Fuel Expenses and Service Expenses is copied over to Expense Claim Amount.
+ 3. Employee can submit the Expense Claim for further processing.
+
+ <img class="screenshot" alt="Vehicle Log" src="{{docs_base_url}}/assets/img/fleet-management/expense-claim-3.2.png">
+
+### Vehicle Expenses Report
+
+* To track and monitor Vehicle Expenses you can use the Vehicle Expenses report.This report gives a one stop view of all your vehicle expenses month wise.
+
+ <img class="screenshot" alt="Vehicle Log" src="{{docs_base_url}}/assets/img/fleet-management/vehicle-expenses.png">
diff --git a/erpnext/docs/user/manual/en/fleet_management/index.txt b/erpnext/docs/user/manual/en/fleet_management/index.txt
new file mode 100644
index 0000000..2da8e7b
--- /dev/null
+++ b/erpnext/docs/user/manual/en/fleet_management/index.txt
@@ -0,0 +1,3 @@
+Vehicle
+Vehicle Log
+Vehicle Expenses
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/human-resources/salary-and-payroll.md b/erpnext/docs/user/manual/en/human-resources/salary-and-payroll.md
index 62933df..286df14 100644
--- a/erpnext/docs/user/manual/en/human-resources/salary-and-payroll.md
+++ b/erpnext/docs/user/manual/en/human-resources/salary-and-payroll.md
@@ -81,6 +81,12 @@
* Only Formula
* Only Amount
+#### Figure 1.5:Account Details
+
+<img class="screenshot" alt="Salary Structure" src="{{docs_base_url}}/assets/img/human-resources/salary-structure-account.png">
+
+ * Select Mode of Payment and Payment Account for the Salary Slips which will be generated using this Salary Structure
+
Save the Salary Structure.
In conditions and formulas,
@@ -128,8 +134,10 @@
In Process Payroll,
1. Select the Company for which you want to create the Salary Slips.
- 2. Select the Month and the Year for which you want to create the Salary Slips.
- 3. Click on “Create Salary Slips”. This will create Salary Slip records for each active Employee for the month selected. If the Salary Slips are created, the system will not create any more Salary Slips. All updates will be shown in the “Activity Log” section.
+ 2. Check "Salary Slip based on Timesheet" if you want to process timesheet based Salary Slips.
+ 3. Select the From Date and To Date or Fiscal year and month for which you want to create the Salary Slips.
+ 3. Select the Payment Account.
+ 3. Click on “Create Salary Slips”. This will create Salary Slip records for each active Employee for the time period selected. If the Salary Slips are created, the system will not create any more Salary Slips. All updates will be shown in the “Activity Log” section.
4. Once all Salary Slips are created, you can check if they are created correctly or edit it if you want to deduct Leave Without Pay (LWP).
5. After checking, you can “Submit” them all together by clicking on “Submit Salary Slips”. 1. If you want them to be automatically emailed to the Employee, make sure to check the “Send Email” box.
@@ -144,12 +152,19 @@
with access to the company’s accounts will not have access to the individual
salaries.
-The salary payment entry is a Journal Entry entry that debits the total
-salary of all Employees to the Salary Account and credits the company’s bank
-Account.
+The salary payment entry is a Journal Entry that debits the total of the
+earning type salary component and credits the total of deduction type salary
+component of all Employees to the default account set at Salary Component level
+for each component.
To generate your salary payment voucher from Process Payroll, click on
-“Make Bank Voucher” and a new Journal Entry with the total salaries will be
+“Make Bank Entry”. It will ask to enter the Bank Transaction Reference Number and date.
+Click on "Make" and a new Journal Entry with the total salary components will be
created.
+#### Figure 3.1: Make Bank Entry
+
+<img class="screenshot" alt="Process Payroll" src="{{docs_base_url}}/assets/img/human-resources/bank-entry.png">
+
+
{next}
diff --git a/erpnext/docs/user/manual/en/selling/setup/product-bundle.md b/erpnext/docs/user/manual/en/selling/setup/product-bundle.md
index fa7f948..123eeaf 100644
--- a/erpnext/docs/user/manual/en/selling/setup/product-bundle.md
+++ b/erpnext/docs/user/manual/en/selling/setup/product-bundle.md
@@ -1,9 +1,7 @@
#Product Bundle
-Product Bundle stands for Sales Bill-of-Material. It's a master where you can list item which are bundled together and
-sold as one item. For instance, when laptop is delivered, you need to ensure that charger, mouse and laptop bag are
-delivered and stock level of these items gets affected. To address this scenario, you can set create Product Bundle for
-the main item, i.e. laptop, and list deliverable items i.e. laptop + charger + other accessories as child items.
+Product Bundle can be seen as something like a "Bill-of-Material" on the Sales side. It's a master where you can list existing items which are bundled together and sold as a set (or bundle). For instance, when you sell a laptop, you need to ensure that charger, mouse and laptop bag are delivered with it and stock levels of these items get affected.
+To address this scenario, you can set create a Product Bundle for the main item, i.e. laptop, and list deliverable items i.e. laptop + charger + mouse + laptop bag as so-called "Child Items".
Following are the steps on how to setup Product Bundle master, and how is it used in the sales transactions.
@@ -17,25 +15,27 @@
###Select Parent Item
-In Product Bundle master, there are two sections. Product Bundle Item and Package Item.
+In Product Bundle master, there are two sections. The "Parent Item" and a List of items to be shipped (Child Items).
-In Product Bundle item, you will select a Parent Item. The parent item must be a <b>non-stock item</b>.
-This is non-stock item because there is no stock maintained for it but only the Package Items.
+The "Parent Item" must be a so called <b>non-stock item</b>. The "Parent Item" is to be seen more like a vessel or virtual item and not a physical product.
+To create a <b>non-stock item</b> you have to unmark "Maintain Stock" in the Item Form.
+This is non-stock item because there is no stock maintained for it but only for the "Child Items".
If you want to maintain stock for the Parent Item, then you must create a regular Bill of Material (BOM)
and package them using a Stock Entry Transactions.
###Select Child Items
In Package Item section, you will list all the child items for which we maintain stock and is delivered to customer.
+Remember: The "Parent Item" is just virtual, so your main product (a laptop in our example here) also has to be listed on the List of Child (or Package) Items
###Product Bundle in the Sales Transactions
-When making Sales transactions like Sales Invoice, Sales Order and Delivery Note,
-Parent Item will be selected in the main item table.
+When making Sales transactions (Sales Invoice, Sales Order, Delivery Note)
+the Parent Item will be selected in the main item table.
<img class="screenshot" alt="Product Bundle" src="{{docs_base_url}}/assets/img/selling/product-bundle.gif">
-On selection on Parent Item in the main item table, its child items will be fetched in Packing List
+On selection of a Parent Item in the main item table, its child items will be fetched in Packing List
table of the transaction. If child item is the serialized item, you will be able to specify its Serial Mo.
in packing List table itself. On submission of transaction, system will reduce the stock level of child items from
warehouse specified in Packing List table.
diff --git a/erpnext/docs/user/videos/learn/data-import-tool.md b/erpnext/docs/user/videos/learn/data-import-tool.md
index 10cd00f..a3272e9 100644
--- a/erpnext/docs/user/videos/learn/data-import-tool.md
+++ b/erpnext/docs/user/videos/learn/data-import-tool.md
@@ -1,8 +1,7 @@
# Data Import Tool
-<iframe width="660" height="371" src="https://www.youtube.com/embed/6wiriRKPhmg" frameborder="0" allowfullscreen></iframe>
+<iframe width="660" height="371" src="https://www.youtube.com/embed/Ta2Xx3QoK3E" frameborder="0" allowfullscreen></iframe>
-**Duration: 3:24**
+**Duration: 6:32**
-This video walks you through on importing data in ERPNext from spreadsheet files. This tools allows you in faster migration of masters and transactions from legacy system into ERPNext. You can also use this tool to export data from ERPNext, and keep it as a backup
-of specific document type.
+This video walks you through on importing data in ERPNext from spreadsheet files. This tools allows you in faster migration of masters and transactions from legacy system into ERPNext. You can also use this tool to export data from ERPNext, and keep it as a backup of specific document type.
diff --git a/erpnext/fleet_management/__init__.py b/erpnext/fleet_management/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/fleet_management/__init__.py
diff --git a/erpnext/fleet_management/doctype/__init__.py b/erpnext/fleet_management/doctype/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/fleet_management/doctype/__init__.py
diff --git a/erpnext/fleet_management/doctype/vehicle/__init__.py b/erpnext/fleet_management/doctype/vehicle/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/fleet_management/doctype/vehicle/__init__.py
diff --git a/erpnext/fleet_management/doctype/vehicle/test_vehicle.py b/erpnext/fleet_management/doctype/vehicle/test_vehicle.py
new file mode 100644
index 0000000..6431977
--- /dev/null
+++ b/erpnext/fleet_management/doctype/vehicle/test_vehicle.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+from frappe.utils import nowdate,flt, cstr,random_string
+# test_records = frappe.get_test_records('Vehicle')
+
+class TestVehicle(unittest.TestCase):
+ def test_make_vehicle(self):
+ vehicle = frappe.get_doc({
+ "doctype": "Vehicle",
+ "license_plate": random_string(10).upper(),
+ "make": "Maruti",
+ "model": "PCM",
+ "last_odometer":5000,
+ "acquisition_date":frappe.utils.nowdate(),
+ "location": "Mumbai",
+ "chassis_no": "1234ABCD",
+ "vehicle_value":frappe.utils.flt(500000)
+ })
+ vehicle.insert()
diff --git a/erpnext/fleet_management/doctype/vehicle/vehicle.js b/erpnext/fleet_management/doctype/vehicle/vehicle.js
new file mode 100644
index 0000000..f12c434
--- /dev/null
+++ b/erpnext/fleet_management/doctype/vehicle/vehicle.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Vehicle', {
+ refresh: function(frm) {
+
+ }
+});
diff --git a/erpnext/fleet_management/doctype/vehicle/vehicle.json b/erpnext/fleet_management/doctype/vehicle/vehicle.json
new file mode 100644
index 0000000..5dec1e3
--- /dev/null
+++ b/erpnext/fleet_management/doctype/vehicle/vehicle.json
@@ -0,0 +1,764 @@
+{
+ "allow_copy": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:license_plate",
+ "beta": 0,
+ "creation": "2016-09-03 03:33:27.680331",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Document",
+ "editable_grid": 1,
+ "fields": [
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "license_plate",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_list_view": 0,
+ "label": "License Plate",
+ "length": 0,
+ "no_copy": 1,
+ "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": 1
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "make",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Make",
+ "length": 0,
+ "no_copy": 0,
+ "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
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 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,
+ "columns": 0,
+ "fieldname": "model",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_list_view": 1,
+ "label": "Model",
+ "length": 0,
+ "no_copy": 0,
+ "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
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "vehicle_details",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Details",
+ "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,
+ "columns": 0,
+ "fieldname": "last_odometer",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_list_view": 1,
+ "label": "Odometer Value (Last)",
+ "length": 0,
+ "no_copy": 1,
+ "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": 1,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "acquisition_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_list_view": 0,
+ "label": "Acquisition Date",
+ "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,
+ "columns": 0,
+ "fieldname": "location",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Location",
+ "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,
+ "columns": 0,
+ "fieldname": "column_break_8",
+ "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,
+ "columns": 0,
+ "fieldname": "chassis_no",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Chassis No",
+ "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,
+ "columns": 0,
+ "fieldname": "vehicle_value",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Vehicle Value",
+ "length": 0,
+ "no_copy": 0,
+ "options": "",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 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,
+ "columns": 0,
+ "fieldname": "employee",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Employee",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Employee",
+ "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,
+ "columns": 0,
+ "fieldname": "insurance_details",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Insurance Details",
+ "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,
+ "columns": 0,
+ "fieldname": "insurance_company",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_list_view": 0,
+ "label": "Insurance Company",
+ "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,
+ "columns": 0,
+ "fieldname": "policy_no",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_list_view": 0,
+ "label": "Policy No",
+ "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,
+ "columns": 0,
+ "fieldname": "column_break_15",
+ "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,
+ "columns": 0,
+ "fieldname": "start_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Start Date",
+ "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,
+ "columns": 0,
+ "fieldname": "end_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "End Date",
+ "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,
+ "columns": 0,
+ "fieldname": "additional_details",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Additional Details",
+ "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,
+ "columns": 0,
+ "fieldname": "fuel_type",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Fuel Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Petrol\nDiesel\nNatural Gas\nElectric",
+ "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
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "Litre",
+ "fieldname": "uom",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Fuel UOM",
+ "length": 0,
+ "no_copy": 0,
+ "options": "UOM",
+ "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
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "carbon_check_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Last Carbon Check",
+ "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,
+ "columns": 0,
+ "fieldname": "column_break_21",
+ "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,
+ "columns": 0,
+ "fieldname": "color",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Color",
+ "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,
+ "columns": 0,
+ "fieldname": "wheels",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Wheels",
+ "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,
+ "columns": 0,
+ "fieldname": "doors",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Doors",
+ "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,
+ "columns": 0,
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Amended From",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Vehicle",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
+ "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": 0,
+ "max_attachments": 0,
+ "modified": "2016-09-20 11:39:45.446271",
+ "modified_by": "Administrator",
+ "module": "Fleet Management",
+ "name": "Vehicle",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Fleet Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "search_fields": "license_plate,location,model",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "",
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/fleet_management/doctype/vehicle/vehicle.py b/erpnext/fleet_management/doctype/vehicle/vehicle.py
new file mode 100644
index 0000000..ef5bfe5
--- /dev/null
+++ b/erpnext/fleet_management/doctype/vehicle/vehicle.py
@@ -0,0 +1,14 @@
+# -*- 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 import _
+from frappe.utils import getdate
+from frappe.model.document import Document
+
+class Vehicle(Document):
+ def validate(self):
+ if getdate(self.start_date) > getdate(self.end_date):
+ frappe.throw(_("Insurance Start date should be less than Insurance End date"))
\ No newline at end of file
diff --git a/erpnext/fleet_management/doctype/vehicle/vehicle_dashboard.py b/erpnext/fleet_management/doctype/vehicle/vehicle_dashboard.py
new file mode 100644
index 0000000..2c1c4c3
--- /dev/null
+++ b/erpnext/fleet_management/doctype/vehicle/vehicle_dashboard.py
@@ -0,0 +1,13 @@
+from frappe import _
+
+data = {
+ 'heatmap': True,
+ 'heatmap_message': _('This is based on logs against this Vehicle. See timeline below for details'),
+ 'fieldname': 'license_plate',
+ 'transactions': [
+ {
+ 'label': _('Logs'),
+ 'items': ['Vehicle Log']
+ }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/fleet_management/doctype/vehicle_log/__init__.py b/erpnext/fleet_management/doctype/vehicle_log/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/fleet_management/doctype/vehicle_log/__init__.py
diff --git a/erpnext/fleet_management/doctype/vehicle_log/test_vehicle_log.py b/erpnext/fleet_management/doctype/vehicle_log/test_vehicle_log.py
new file mode 100644
index 0000000..71c1d91
--- /dev/null
+++ b/erpnext/fleet_management/doctype/vehicle_log/test_vehicle_log.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+from frappe.utils import nowdate,flt, cstr,random_string
+# test_records = frappe.get_test_records('Vehicle Log')
+class TestVehicleLog(unittest.TestCase):
+ def test_make_vehicle_log(self):
+ license_plate=random_string(10).upper()
+ employee_id=frappe.db.sql("""select name from `tabEmployee` order by modified desc limit 1""")[0][0]
+ vehicle = frappe.get_doc({
+ "doctype": "Vehicle",
+ "license_plate": cstr(license_plate),
+ "make": "Maruti",
+ "model": "PCM",
+ "last_odometer":5000,
+ "acquisition_date":frappe.utils.nowdate(),
+ "location": "Mumbai",
+ "chassis_no": "1234ABCD",
+ "vehicle_value":frappe.utils.flt(500000)
+ })
+ try:
+ vehicle.insert()
+ except frappe.DuplicateEntryError:
+ pass
+ vehicle_log = frappe.get_doc({
+ "doctype": "Vehicle Log",
+ "license_plate": cstr(license_plate),
+ "employee":employee_id,
+ "date":frappe.utils.nowdate(),
+ "odometer":5010,
+ "fuel_qty":frappe.utils.flt(50),
+ "price": frappe.utils.flt(500)
+ })
+ vehicle_log.insert()
+ vehicle_log.submit()
\ No newline at end of file
diff --git a/erpnext/fleet_management/doctype/vehicle_log/vehicle_log.js b/erpnext/fleet_management/doctype/vehicle_log/vehicle_log.js
new file mode 100644
index 0000000..1ccf347
--- /dev/null
+++ b/erpnext/fleet_management/doctype/vehicle_log/vehicle_log.js
@@ -0,0 +1,33 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on("Vehicle Log", {
+ refresh: function(frm,cdt,cdn) {
+ vehicle_log=frappe.model.get_doc(cdt,cdn);
+ if (vehicle_log.license_plate) {
+ frappe.call({
+ method: "erpnext.fleet_management.doctype.vehicle_log.vehicle_log.get_make_model",
+ args: {
+ license_plate: vehicle_log.license_plate
+ },
+ callback: function(r) {
+ frappe.model.set_value(cdt, cdn, ("model"), r.message[0]);
+ frappe.model.set_value(cdt, cdn, ("make"), r.message[1]);
+ }
+ })
+ }
+ },
+ expense_claim: function(frm){
+ frappe.call({
+ method: "erpnext.fleet_management.doctype.vehicle_log.vehicle_log.make_expense_claim",
+ args:{
+ docname: frm.doc.name
+ },
+ callback: function(r){
+ var doc = frappe.model.sync(r.message);
+ frappe.set_route('Form', 'Expense Claim', r.message.name);
+ }
+ })
+ }
+});
+
diff --git a/erpnext/fleet_management/doctype/vehicle_log/vehicle_log.json b/erpnext/fleet_management/doctype/vehicle_log/vehicle_log.json
new file mode 100644
index 0000000..9381852
--- /dev/null
+++ b/erpnext/fleet_management/doctype/vehicle_log/vehicle_log.json
@@ -0,0 +1,634 @@
+{
+ "allow_copy": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "naming_series:",
+ "beta": 0,
+ "creation": "2016-09-03 14:14:51.788550",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Document",
+ "editable_grid": 1,
+ "fields": [
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "vehicle_section",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "length": 0,
+ "no_copy": 0,
+ "options": "icon-user",
+ "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,
+ "columns": 0,
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Series",
+ "length": 0,
+ "no_copy": 1,
+ "options": "VLOG.",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 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,
+ "columns": 0,
+ "fieldname": "license_plate",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_list_view": 1,
+ "label": "License Plate",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Vehicle",
+ "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
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "employee",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Employee",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Employee",
+ "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
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_4",
+ "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,
+ "columns": 0,
+ "fieldname": "column_break_7",
+ "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,
+ "columns": 0,
+ "fieldname": "model",
+ "fieldtype": "Read Only",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Model",
+ "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,
+ "columns": 0,
+ "fieldname": "make",
+ "fieldtype": "Read Only",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Make",
+ "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,
+ "columns": 0,
+ "fieldname": "odometer_reading",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Odometer Reading",
+ "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,
+ "columns": 0,
+ "fieldname": "date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Date",
+ "length": 0,
+ "no_copy": 0,
+ "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
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "odometer",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Odometer",
+ "length": 0,
+ "no_copy": 0,
+ "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
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 1,
+ "columns": 0,
+ "fieldname": "refuelling_details",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Refuelling Details",
+ "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,
+ "columns": 0,
+ "fieldname": "fuel_qty",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Fuel Qty",
+ "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,
+ "columns": 0,
+ "fieldname": "price",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Fuel Price",
+ "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,
+ "columns": 0,
+ "fieldname": "column_break_15",
+ "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,
+ "columns": 0,
+ "fieldname": "supplier",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Supplier",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Supplier",
+ "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,
+ "columns": 0,
+ "fieldname": "invoice",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Invoice Ref",
+ "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": 1,
+ "columns": 0,
+ "fieldname": "service_details",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Service_Details",
+ "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,
+ "columns": 0,
+ "fieldname": "service_detail",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Service Detail",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Vehicle Service",
+ "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,
+ "columns": 0,
+ "fieldname": "section_break_20",
+ "fieldtype": "Section 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": 1,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.docstatus==1",
+ "fieldname": "expense_claim",
+ "fieldtype": "Button",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Make Expense Claim",
+ "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,
+ "columns": 0,
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Amended From",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Vehicle Log",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
+ "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": 1,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2016-09-17 15:44:02.397851",
+ "modified_by": "Administrator",
+ "module": "Fleet Management",
+ "name": "Vehicle Log",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Fleet Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 1,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "",
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/fleet_management/doctype/vehicle_log/vehicle_log.py b/erpnext/fleet_management/doctype/vehicle_log/vehicle_log.py
new file mode 100644
index 0000000..ceea493
--- /dev/null
+++ b/erpnext/fleet_management/doctype/vehicle_log/vehicle_log.py
@@ -0,0 +1,57 @@
+# -*- 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 import _
+from frappe.utils import flt, cstr
+from frappe.model.mapper import get_mapped_doc
+from frappe.model.document import Document
+
+class VehicleLog(Document):
+ def validate(self):
+ last_odometer=frappe.db.get_value("Vehicle", self.license_plate, "last_odometer")
+ if flt(self.odometer) < flt(last_odometer):
+ frappe.throw(_("Current Odometer reading entered should be greater than initial Vehicle Odometer {0}").format(last_odometer))
+ for service_detail in self.service_detail:
+ if (service_detail.service_item or service_detail.type or service_detail.frequency or service_detail.expense_amount):
+ if not (service_detail.service_item and service_detail.type and service_detail.frequency and service_detail.expense_amount):
+ frappe.throw(_("Service Item,Type,frequency and expense amount are required"))
+
+ def on_submit(self):
+ frappe.db.sql("update `tabVehicle` set last_odometer=%s where license_plate=%s",
+ (self.odometer, self.license_plate))
+
+@frappe.whitelist()
+def get_make_model(license_plate):
+ vehicle=frappe.get_doc("Vehicle",license_plate)
+ return (vehicle.make,vehicle.model)
+
+@frappe.whitelist()
+def make_expense_claim(docname):
+ def check_exp_claim_exists():
+ exp_claim = frappe.db.sql("""select name from `tabExpense Claim` where vehicle_log=%s""",vehicle_log.name)
+ return exp_claim[0][0] if exp_claim else ""
+ def calc_service_exp():
+ total_exp_amt=0
+ exp_claim = check_exp_claim_exists()
+ if exp_claim:
+ frappe.throw(_("Expense Claim {0} already exists for the Vehicle Log").format(exp_claim))
+ for serdetail in vehicle_log.service_detail:
+ total_exp_amt = total_exp_amt + serdetail.expense_amount
+ return total_exp_amt
+
+ vehicle_log = frappe.get_doc("Vehicle Log", docname)
+ exp_claim = frappe.new_doc("Expense Claim")
+ exp_claim.employee=vehicle_log.employee
+ exp_claim.vehicle_log=vehicle_log.name
+ exp_claim.remark=_("Expense Claim for Vehicle Log {0}").format(vehicle_log.name)
+ fuel_price=vehicle_log.price
+ total_claim_amt=calc_service_exp() + fuel_price
+ exp_claim.append("expenses",{
+ "expense_date":vehicle_log.date,
+ "description":_("Vehicle Expenses"),
+ "claim_amount":total_claim_amt
+ })
+ return exp_claim.as_dict()
diff --git a/erpnext/fleet_management/doctype/vehicle_service/__init__.py b/erpnext/fleet_management/doctype/vehicle_service/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/fleet_management/doctype/vehicle_service/__init__.py
diff --git a/erpnext/fleet_management/doctype/vehicle_service/vehicle_service.json b/erpnext/fleet_management/doctype/vehicle_service/vehicle_service.json
new file mode 100644
index 0000000..6b80efc
--- /dev/null
+++ b/erpnext/fleet_management/doctype/vehicle_service/vehicle_service.json
@@ -0,0 +1,144 @@
+{
+ "allow_copy": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2016-09-03 19:20:14.561962",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Document",
+ "editable_grid": 1,
+ "fields": [
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "service_item",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Service Item",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nBrake Oil\nBrake Pad\nClutch Plate\nEngine Oil\nOil Change\nWheels",
+ "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,
+ "columns": 0,
+ "fieldname": "type",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nInspection\nService\nChange",
+ "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,
+ "columns": 0,
+ "fieldname": "frequency",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Frequency",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nMileage\nMonthly\nQuarterly\nHalf Yearly\nYearly",
+ "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,
+ "columns": 0,
+ "fieldname": "expense_amount",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Expense",
+ "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
+ }
+ ],
+ "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-09-20 07:29:50.852748",
+ "modified_by": "Administrator",
+ "module": "Fleet Management",
+ "name": "Vehicle Service",
+ "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/fleet_management/doctype/vehicle_service/vehicle_service.py b/erpnext/fleet_management/doctype/vehicle_service/vehicle_service.py
new file mode 100644
index 0000000..18ed782
--- /dev/null
+++ b/erpnext/fleet_management/doctype/vehicle_service/vehicle_service.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 VehicleService(Document):
+ pass
diff --git a/erpnext/fleet_management/report/__init__.py b/erpnext/fleet_management/report/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/fleet_management/report/__init__.py
diff --git a/erpnext/fleet_management/report/vehicle_expenses/__init__.py b/erpnext/fleet_management/report/vehicle_expenses/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/fleet_management/report/vehicle_expenses/__init__.py
diff --git a/erpnext/fleet_management/report/vehicle_expenses/vehicle_expenses.js b/erpnext/fleet_management/report/vehicle_expenses/vehicle_expenses.js
new file mode 100644
index 0000000..8a05c81
--- /dev/null
+++ b/erpnext/fleet_management/report/vehicle_expenses/vehicle_expenses.js
@@ -0,0 +1,41 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+frappe.require("assets/erpnext/js/financial_statements.js", function() {
+ frappe.query_reports["Vehicle Expenses"] = {
+ "filters": [
+ {
+ "fieldname": "fiscal_year",
+ "label": __("Fiscal Year"),
+ "fieldtype": "Link",
+ "options": "Fiscal Year",
+ "default": frappe.defaults.get_user_default("fiscal_year"),
+ "reqd": 1,
+ "on_change": function(query_report) {
+ var fiscal_year = query_report.get_values().fiscal_year;
+ if (!fiscal_year) {
+ return;
+ }
+ frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
+ var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
+ frappe.query_report_filters_by_name.from_date.set_input(fy.year_start_date);
+ frappe.query_report_filters_by_name.to_date.set_input(fy.year_end_date);
+ query_report.trigger_refresh();
+ });
+ }
+ },
+ {
+ "fieldname": "from_date",
+ "label": __("From Date"),
+ "fieldtype": "Date",
+ "default": frappe.defaults.get_user_default("year_start_date"),
+ },
+ {
+ "fieldname": "to_date",
+ "label": __("To Date"),
+ "fieldtype": "Date",
+ "default": frappe.defaults.get_user_default("year_end_date"),
+ }
+ ]
+ }
+});
+
diff --git a/erpnext/fleet_management/report/vehicle_expenses/vehicle_expenses.json b/erpnext/fleet_management/report/vehicle_expenses/vehicle_expenses.json
new file mode 100644
index 0000000..380c873
--- /dev/null
+++ b/erpnext/fleet_management/report/vehicle_expenses/vehicle_expenses.json
@@ -0,0 +1,18 @@
+{
+ "add_total_row": 0,
+ "apply_user_permissions": 1,
+ "creation": "2016-09-09 03:33:40.605734",
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2016-09-18 08:54:12.080753",
+ "modified_by": "Administrator",
+ "module": "Fleet Management",
+ "name": "Vehicle Expenses",
+ "owner": "Administrator",
+ "ref_doctype": "Vehicle",
+ "report_name": "Vehicle Expenses",
+ "report_type": "Script Report"
+}
\ No newline at end of file
diff --git a/erpnext/fleet_management/report/vehicle_expenses/vehicle_expenses.py b/erpnext/fleet_management/report/vehicle_expenses/vehicle_expenses.py
new file mode 100644
index 0000000..717a94f
--- /dev/null
+++ b/erpnext/fleet_management/report/vehicle_expenses/vehicle_expenses.py
@@ -0,0 +1,81 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from frappe.utils import flt,cstr
+from erpnext.accounts.report.financial_statements import get_period_list
+
+def execute(filters=None):
+ period_list = get_period_list(2016, 2016,"Monthly")
+ for period in period_list:
+ pass
+ columns, data = [], []
+ columns=get_columns()
+ data=get_log_data(filters)
+ chart=get_chart_data(data,period_list)
+ return columns,data,None,chart
+
+def get_columns():
+ columns = [_("License") + ":Link/Vehicle:100", _("Make") + ":data:50",
+ _("Model") + ":data:50", _("Location") + ":data:100",
+ _("Log") + ":Link/Vehicle Log:100", _("Odometer") + ":Int:80",
+ _("Date") + ":Date:100", _("Fuel Qty") + ":Float:80",
+ _("Fuel Price") + ":Float:100",_("Service Expense") + ":Float:100"
+ ]
+ return columns
+
+def get_log_data(filters):
+ conditions=""
+ if filters.from_date:
+ conditions += " and date >= %(from_date)s"
+ if filters.to_date:
+ conditions += " and date <= %(to_date)s"
+ data = frappe.db.sql("""select vhcl.license_plate as "License",vhcl.make as "Make",vhcl.model as "Model",
+ vhcl.location as "Location",log.name as "Log",log.odometer as "Odometer",log.date as "Date",
+ log.fuel_qty as "Fuel Qty",log.price as "Fuel Price"
+ from `tabVehicle` vhcl,`tabVehicle Log` log
+ where vhcl.license_plate = log.license_plate and log.docstatus = 1 %s
+ order by date""" % (conditions,),filters, as_dict=1)
+ dl=list(data)
+ for row in dl:
+ row["Service Expense"]= get_service_expense(row["Log"])
+ return dl
+
+def get_service_expense(logname):
+ expense_amount = frappe.db.sql("""select sum(expense_amount)
+ from `tabVehicle Log` log,`tabVehicle Service` ser
+ where ser.parent=log.name and log.name=%s""",logname)
+ return flt(expense_amount[0][0]) if expense_amount else 0
+
+def get_chart_data(data,period_list):
+ fuel_exp_data,service_exp_data,fueldata,servicedata = [],[],[],[]
+ service_exp_data = []
+ fueldata = []
+ for period in period_list:
+ total_fuel_exp=0
+ total_ser_exp=0
+ for row in data:
+ if row["Date"] <= period.to_date and row["Date"] >= period.from_date:
+ total_fuel_exp+=flt(row["Fuel Price"])
+ total_ser_exp+=flt(row["Service Expense"])
+ fueldata.append([period.key,total_fuel_exp])
+ servicedata.append([period.key,total_ser_exp])
+
+ x_intervals = ['x'] + [period.key for period in period_list]
+ fuel_exp_data= [row[1] for row in fueldata]
+ service_exp_data= [row[1] for row in servicedata]
+ columns = [x_intervals]
+ if fuel_exp_data:
+ columns.append(["Fuel Expenses"]+ fuel_exp_data)
+ if service_exp_data:
+ columns.append(["Service Expenses"]+ service_exp_data)
+ chart = {
+ "data": {
+ 'x': 'x',
+ 'columns': columns
+ }
+ }
+ chart["chart_type"] = "line"
+ return chart
\ No newline at end of file
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 19e915e..8b8d3c9 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -67,6 +67,13 @@
"parents": [{"title": _("Invoices"), "name": "invoices"}]
}
},
+ {"from_route": "/quotations", "to_route": "Supplier Quotation"},
+ {"from_route": "/quotations/<path:name>", "to_route": "order",
+ "defaults": {
+ "doctype": "Supplier Quotation",
+ "parents": [{"title": _("Supplier Quotation"), "name": "quotations"}]
+ }
+ },
{"from_route": "/shipments", "to_route": "Delivery Note"},
{"from_route": "/shipments/<path:name>", "to_route": "order",
"defaults": {
@@ -94,21 +101,31 @@
portal_menu_items = [
{"title": _("Projects"), "route": "/project", "reference_doctype": "Project"},
- {"title": _("Request for Quotations"), "route": "/rfq", "reference_doctype": "Request for Quotation"},
- {"title": _("Orders"), "route": "/orders", "reference_doctype": "Sales Order"},
- {"title": _("Invoices"), "route": "/invoices", "reference_doctype": "Sales Invoice"},
- {"title": _("Shipments"), "route": "/shipments", "reference_doctype": "Delivery Note"},
- {"title": _("Issues"), "route": "/issues", "reference_doctype": "Issue", "show_always": True},
+ {"title": _("Request for Quotations"), "route": "/rfq", "reference_doctype": "Request for Quotation", "role": "Supplier"},
+ {"title": _("Supplier Quotation"), "route": "/quotations", "reference_doctype": "Supplier Quotation", "role": "Supplier"},
+ {"title": _("Orders"), "route": "/orders", "reference_doctype": "Sales Order", "role":"Customer"},
+ {"title": _("Invoices"), "route": "/invoices", "reference_doctype": "Sales Invoice", "role":"Customer"},
+ {"title": _("Shipments"), "route": "/shipments", "reference_doctype": "Delivery Note", "role":"Customer"},
+ {"title": _("Issues"), "route": "/issues", "reference_doctype": "Issue", "role":"Customer"},
{"title": _("Addresses"), "route": "/addresses", "reference_doctype": "Address"},
{"title": _("Announcements"), "route": "/announcement", "reference_doctype": "Announcement"},
- {"title": _("Courses"), "route": "/course", "reference_doctype": "Course"},
- {"title": _("Assessment Schedule"), "route": "/assessment", "reference_doctype": "Assessment"},
- {"title": _("Fees"), "route": "/fees", "reference_doctype": "Fees"}
+ {"title": _("Courses"), "route": "/course", "reference_doctype": "Course", "role":"Student"},
+ {"title": _("Assessment Schedule"), "route": "/assessment", "reference_doctype": "Assessment", "role":"Student"},
+ {"title": _("Fees"), "route": "/fees", "reference_doctype": "Fees", "role":"Student"}
+]
+
+default_roles = [
+ {'role': 'Customer', 'doctype':'Contact', 'email_field': 'email_id',
+ 'filters': {'ifnull(customer, "")': ('!=', '')}},
+ {'role': 'Supplier', 'doctype':'Contact', 'email_field': 'email_id',
+ 'filters': {'ifnull(supplier, "")': ('!=', '')}},
+ {'role': 'Student', 'doctype':'Student', 'email_field': 'student_email_id'}
]
has_website_permission = {
"Sales Order": "erpnext.controllers.website_list_for_contact.has_website_permission",
"Sales Invoice": "erpnext.controllers.website_list_for_contact.has_website_permission",
+ "Supplier Quotation": "erpnext.controllers.website_list_for_contact.has_website_permission",
"Delivery Note": "erpnext.controllers.website_list_for_contact.has_website_permission",
"Issue": "erpnext.support.doctype.issue.issue.has_website_permission",
"Address": "erpnext.utilities.doctype.address.address.has_website_permission",
diff --git a/erpnext/hr/doctype/employee/employee.json b/erpnext/hr/doctype/employee/employee.json
index 0e71e9b..0ae69b9 100644
--- a/erpnext/hr/doctype/employee/employee.json
+++ b/erpnext/hr/doctype/employee/employee.json
@@ -9,12 +9,13 @@
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
- "editable_grid": 0,
+ "editable_grid": 1,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "basic_information",
"fieldtype": "Section Break",
"hidden": 0,
@@ -40,6 +41,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "employee",
"fieldtype": "Data",
"hidden": 1,
@@ -64,6 +66,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
@@ -91,6 +94,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "salutation",
"fieldtype": "Select",
"hidden": 0,
@@ -118,6 +122,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "employee_name",
"fieldtype": "Data",
"hidden": 0,
@@ -144,6 +149,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -169,6 +175,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "System User (login) ID. If set, it will become default for all HR forms.",
"fieldname": "user_id",
"fieldtype": "Link",
@@ -195,6 +202,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "image",
"fieldtype": "Attach Image",
"hidden": 1,
@@ -204,7 +212,7 @@
"in_list_view": 0,
"label": "Image",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"options": "",
"permlevel": 0,
"print_hide": 0,
@@ -220,6 +228,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -244,6 +253,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "employee_number",
"fieldtype": "Data",
"hidden": 0,
@@ -270,6 +280,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "date_of_joining",
"fieldtype": "Date",
"hidden": 0,
@@ -296,6 +307,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "You can enter any date manually",
"fieldname": "date_of_birth",
"fieldtype": "Date",
@@ -323,6 +335,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "gender",
"fieldtype": "Select",
"hidden": 0,
@@ -350,6 +363,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "employment_details",
"fieldtype": "Section Break",
"hidden": 0,
@@ -374,6 +388,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "Active",
"fieldname": "status",
"fieldtype": "Select",
@@ -402,6 +417,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "employment_type",
"fieldtype": "Link",
"hidden": 0,
@@ -429,6 +445,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Applicable Holiday List",
"fieldname": "holiday_list",
"fieldtype": "Link",
@@ -457,6 +474,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "col_break_22",
"fieldtype": "Column Break",
"hidden": 0,
@@ -480,6 +498,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "scheduled_confirmation_date",
"fieldtype": "Date",
"hidden": 0,
@@ -506,6 +525,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "final_confirmation_date",
"fieldtype": "Date",
"hidden": 0,
@@ -532,6 +552,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "contract_end_date",
"fieldtype": "Date",
"hidden": 0,
@@ -558,6 +579,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "date_of_retirement",
"fieldtype": "Date",
"hidden": 0,
@@ -584,6 +606,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "job_profile",
"fieldtype": "Section Break",
"hidden": 0,
@@ -608,6 +631,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "branch",
"fieldtype": "Link",
"hidden": 0,
@@ -635,6 +659,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "department",
"fieldtype": "Link",
"hidden": 0,
@@ -662,6 +687,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "designation",
"fieldtype": "Link",
"hidden": 0,
@@ -689,6 +715,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Provide email id registered in company",
"fieldname": "company_email",
"fieldtype": "Data",
@@ -717,6 +744,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "notice_number_of_days",
"fieldtype": "Int",
"hidden": 0,
@@ -743,6 +771,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "salary_information",
"fieldtype": "Column Break",
"hidden": 0,
@@ -769,6 +798,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "salary_mode",
"fieldtype": "Select",
"hidden": 0,
@@ -796,6 +826,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.salary_mode == 'Bank'",
"fieldname": "bank_name",
"fieldtype": "Data",
@@ -823,6 +854,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.salary_mode == 'Bank'",
"fieldname": "bank_ac_no",
"fieldtype": "Data",
@@ -850,6 +882,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "organization_profile",
"fieldtype": "Section Break",
"hidden": 0,
@@ -874,6 +907,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "reports_to",
"fieldtype": "Link",
"hidden": 0,
@@ -901,6 +935,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "The first Leave Approver in the list will be set as the default Leave Approver",
"fieldname": "leave_approvers",
"fieldtype": "Table",
@@ -927,6 +962,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "contact_details",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1028,6 +1064,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "personal_email",
"fieldtype": "Data",
"hidden": 0,
@@ -1053,6 +1090,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "unsubscribed",
"fieldtype": "Check",
"hidden": 0,
@@ -1077,6 +1115,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
+ "columns": 0,
"fieldname": "person_to_be_contacted",
"fieldtype": "Data",
"hidden": 0,
@@ -1101,6 +1140,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "relation",
"fieldtype": "Data",
"hidden": 0,
@@ -1125,6 +1165,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
+ "columns": 0,
"fieldname": "emergency_phone_number",
"fieldtype": "Data",
"hidden": 0,
@@ -1149,6 +1190,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break4",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1173,6 +1215,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "permanent_accommodation_type",
"fieldtype": "Select",
"hidden": 0,
@@ -1198,6 +1241,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "permanent_address",
"fieldtype": "Small Text",
"hidden": 0,
@@ -1222,6 +1266,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "current_accommodation_type",
"fieldtype": "Select",
"hidden": 0,
@@ -1247,6 +1292,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "current_address",
"fieldtype": "Small Text",
"hidden": 0,
@@ -1271,6 +1317,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "sb53",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1295,6 +1342,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Short biography for website and other publications.",
"fieldname": "bio",
"fieldtype": "Text Editor",
@@ -1320,6 +1368,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "personal_details",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1344,6 +1393,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "passport_number",
"fieldtype": "Data",
"hidden": 0,
@@ -1368,6 +1418,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "date_of_issue",
"fieldtype": "Date",
"hidden": 0,
@@ -1392,6 +1443,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "valid_upto",
"fieldtype": "Date",
"hidden": 0,
@@ -1416,6 +1468,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "place_of_issue",
"fieldtype": "Data",
"hidden": 0,
@@ -1440,6 +1493,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break6",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1464,6 +1518,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "marital_status",
"fieldtype": "Select",
"hidden": 0,
@@ -1489,6 +1544,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "blood_group",
"fieldtype": "Select",
"hidden": 0,
@@ -1514,6 +1570,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Here you can maintain family details like name and occupation of parent, spouse and children",
"fieldname": "family_background",
"fieldtype": "Small Text",
@@ -1539,6 +1596,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Here you can maintain height, weight, allergies, medical concerns etc",
"fieldname": "health_details",
"fieldtype": "Small Text",
@@ -1564,6 +1622,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "educational_qualification",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1588,6 +1647,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "education",
"fieldtype": "Table",
"hidden": 0,
@@ -1613,6 +1673,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "previous_work_experience",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1638,6 +1699,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "external_work_history",
"fieldtype": "Table",
"hidden": 0,
@@ -1663,6 +1725,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "history_in_company",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1688,6 +1751,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "internal_work_history",
"fieldtype": "Table",
"hidden": 0,
@@ -1713,6 +1777,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "exit",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1738,6 +1803,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "resignation_letter_date",
"fieldtype": "Date",
"hidden": 0,
@@ -1764,6 +1830,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "relieving_date",
"fieldtype": "Date",
"hidden": 0,
@@ -1790,6 +1857,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "reason_for_leaving",
"fieldtype": "Data",
"hidden": 0,
@@ -1816,6 +1884,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "leave_encashed",
"fieldtype": "Select",
"hidden": 0,
@@ -1843,6 +1912,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "encashment_date",
"fieldtype": "Date",
"hidden": 0,
@@ -1869,6 +1939,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "exit_interview_details",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1896,6 +1967,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "held_on",
"fieldtype": "Date",
"hidden": 0,
@@ -1922,6 +1994,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "reason_for_resignation",
"fieldtype": "Select",
"hidden": 0,
@@ -1949,6 +2022,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "new_workplace",
"fieldtype": "Data",
"hidden": 0,
@@ -1975,6 +2049,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "feedback",
"fieldtype": "Small Text",
"hidden": 0,
@@ -2003,13 +2078,14 @@
"icon": "icon-user",
"idx": 24,
"image_field": "image",
+ "image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-09-19 16:46:48.432197",
+ "modified": "2016-09-21 18:12:12.474098",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee",
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js
index bcd8bc0..8b3c451 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.js
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.js
@@ -129,9 +129,6 @@
doc.total_sanctioned_amount = 0;
$.each((doc.expenses || []), function(i, d) {
doc.total_claimed_amount += d.claim_amount;
- if(d.sanctioned_amount==null) {
- d.sanctioned_amount = d.claim_amount;
- }
doc.total_sanctioned_amount += d.sanctioned_amount;
});
@@ -144,17 +141,6 @@
cur_frm.cscript.calculate_total(doc,cdt,cdn);
}
-cur_frm.cscript.claim_amount = function(doc,cdt,cdn){
- cur_frm.cscript.calculate_total(doc,cdt,cdn);
-
- var child = locals[cdt][cdn];
- refresh_field("sanctioned_amount", child.name, child.parentfield);
-}
-
-cur_frm.cscript.sanctioned_amount = function(doc,cdt,cdn){
- cur_frm.cscript.calculate_total(doc,cdt,cdn);
-}
-
cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
if(cint(frappe.boot.notification_settings && frappe.boot.notification_settings.expense_claim)) {
cur_frm.email_doc(frappe.boot.notification_settings.expense_claim_message);
@@ -172,6 +158,25 @@
}
}
+frappe.ui.form.on("Expense Claim Detail", {
+ claim_amount: function(frm, cdt, cdn) {
+ var child = locals[cdt][cdn];
+ var doc = frm.doc;
+
+ if(!child.sanctioned_amount){
+ frappe.model.set_value(cdt, cdn, 'sanctioned_amount', child.claim_amount)
+ }
+
+ cur_frm.cscript.calculate_total(doc,cdt,cdn);
+ },
+
+ sanctioned_amount: function(frm, cdt, cdn) {
+ var doc = frm.doc;
+ cur_frm.cscript.calculate_total(doc,cdt,cdn);
+ }
+})
+
+
frappe.ui.form.on("Expense Claim", "employee_name", function(frm) {
erpnext.expense_claim.set_title(frm);
});
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json
index 035f7de..f2a14c5 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.json
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.json
@@ -3,16 +3,19 @@
"allow_import": 1,
"allow_rename": 0,
"autoname": "naming_series:",
+ "beta": 0,
"creation": "2013-01-10 16:34:14",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
+ "editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "EXP",
"fieldname": "naming_series",
"fieldtype": "Select",
@@ -40,6 +43,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "Draft",
"depends_on": "eval:!doc.__islocal",
"fieldname": "approval_status",
@@ -69,6 +73,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "A user with \"Expense Approver\" role",
"fieldname": "exp_approver",
"fieldtype": "Link",
@@ -98,6 +103,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
@@ -123,6 +129,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "total_claimed_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -151,6 +158,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "total_sanctioned_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -179,6 +187,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "expense_details",
"fieldtype": "Section Break",
"hidden": 0,
@@ -204,6 +213,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "expenses",
"fieldtype": "Table",
"hidden": 0,
@@ -231,6 +241,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "sb1",
"fieldtype": "Section Break",
"hidden": 0,
@@ -255,6 +266,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "Today",
"fieldname": "posting_date",
"fieldtype": "Date",
@@ -282,6 +294,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "employee",
"fieldtype": "Link",
"hidden": 0,
@@ -309,6 +322,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "employee_name",
"fieldtype": "Data",
"hidden": 0,
@@ -336,6 +350,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -363,6 +378,34 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
+ "fieldname": "vehicle_log",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Vehicle Log",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Vehicle Log",
+ "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,
+ "columns": 0,
"fieldname": "cb1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -386,6 +429,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "total_amount_reimbursed",
"fieldtype": "Currency",
"hidden": 0,
@@ -412,6 +456,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "remark",
"fieldtype": "Small Text",
"hidden": 0,
@@ -438,6 +483,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "project",
"fieldtype": "Link",
"hidden": 0,
@@ -464,6 +510,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "task",
"fieldtype": "Link",
"hidden": 0,
@@ -490,6 +537,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "{employee_name}",
"fieldname": "title",
"fieldtype": "Data",
@@ -516,6 +564,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "email_id",
"fieldtype": "Data",
"hidden": 1,
@@ -542,6 +591,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@@ -571,6 +621,7 @@
"hide_toolbar": 0,
"icon": "icon-money",
"idx": 1,
+ "image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 1,
@@ -578,7 +629,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2016-03-03 04:00:28.190351",
+ "modified": "2016-09-22 05:17:31.428020",
"modified_by": "Administrator",
"module": "HR",
"name": "Expense Claim",
@@ -668,11 +719,13 @@
"write": 1
}
],
+ "quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"search_fields": "approval_status,employee,employee_name",
"sort_field": "modified",
"sort_order": "DESC",
"timeline_field": "employee",
- "title_field": "title"
+ "title_field": "title",
+ "track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/holiday_list/holiday_list_calendar.js b/erpnext/hr/doctype/holiday_list/holiday_list_calendar.js
index 3cc8dd5..507d070 100644
--- a/erpnext/hr/doctype/holiday_list/holiday_list_calendar.js
+++ b/erpnext/hr/doctype/holiday_list/holiday_list_calendar.js
@@ -3,8 +3,8 @@
frappe.views.calendar["Holiday List"] = {
field_map: {
- "start": "holiday_date",
- "end": "holiday_date",
+ "start": "from_date",
+ "end": "to_date",
"id": "name",
"title": "description",
"allDay": "allDay"
diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation.js b/erpnext/hr/doctype/leave_allocation/leave_allocation.js
index d01f1ba..b7e1f45 100755
--- a/erpnext/hr/doctype/leave_allocation/leave_allocation.js
+++ b/erpnext/hr/doctype/leave_allocation/leave_allocation.js
@@ -11,6 +11,13 @@
return {
query: "erpnext.controllers.queries.employee_query"
}
+ });
+ frm.set_query("leave_type", function() {
+ return {
+ filters: {
+ is_lwp: 0
+ }
+ }
})
},
diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation.py b/erpnext/hr/doctype/leave_allocation/leave_allocation.py
index 86ed187..3473fd8 100755
--- a/erpnext/hr/doctype/leave_allocation/leave_allocation.py
+++ b/erpnext/hr/doctype/leave_allocation/leave_allocation.py
@@ -23,6 +23,7 @@
self.validate_back_dated_allocation()
self.set_total_leaves_allocated()
self.validate_total_leaves_allocated()
+ self.validate_lwp()
set_employee_name(self)
def on_update_after_submit(self):
@@ -37,6 +38,10 @@
def validate_period(self):
if date_diff(self.to_date, self.from_date) <= 0:
frappe.throw(_("To date cannot be before from date"))
+
+ def validate_lwp(self):
+ if frappe.db.get_value("Leave Type", self.leave_type, "is_lwp"):
+ frappe.throw(_("Leave Type {0} cannot be allocated since it is leave without pay").format(self.leave_type))
def validate_new_leaves_allocated_value(self):
"""validate that leave allocation is in multiples of 0.5"""
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index 0aabd27..c1a9a06 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -97,12 +97,19 @@
.format(formatdate(future_allocation[0].from_date), future_allocation[0].name))
def validate_salary_processed_days(self):
- last_processed_pay_slip = frappe.db.sql("""select start_date, end_date from `tabSalary Slip`
- where docstatus != 2 and employee = %s and ((%s between start_date and end_date) or (%s between start_date and end_date)) order by modified desc limit 1""",(self.employee, self.to_date, self.from_date))
+ if not frappe.db.get_value("Leave Type", self.leave_type, "is_lwp"):
+ return
+
+ last_processed_pay_slip = frappe.db.sql("""
+ select start_date, end_date from `tabSalary Slip`
+ where docstatus != 2 and employee = %s
+ and ((%s between start_date and end_date) or (%s between start_date and end_date))
+ order by modified desc limit 1
+ """,(self.employee, self.to_date, self.from_date))
if last_processed_pay_slip:
- frappe.throw(_("Salary already processed for period between {0} and {1}, Leave application period cannot be between this date range.").
- format(formatdate(last_processed_pay_slip[0][0]), formatdate(last_processed_pay_slip[0][1])))
+ frappe.throw(_("Salary already processed for period between {0} and {1}, Leave application period cannot be between this date range.").format(formatdate(last_processed_pay_slip[0][0]),
+ formatdate(last_processed_pay_slip[0][1])))
def show_block_day_warning(self):
diff --git a/erpnext/hr/doctype/leave_application/leave_application_list.js b/erpnext/hr/doctype/leave_application/leave_application_list.js
index f82dfb2..966d1aa 100644
--- a/erpnext/hr/doctype/leave_application/leave_application_list.js
+++ b/erpnext/hr/doctype/leave_application/leave_application_list.js
@@ -1,5 +1,5 @@
frappe.listview_settings['Leave Application'] = {
- add_fields: ["status", "leave_type", "employee", "employee_name", "total_leave_days", "from_date"],
+ add_fields: ["status", "leave_type", "employee", "employee_name", "total_leave_days", "from_date", "to_date"],
filters:[["status","!=", "Rejected"]],
get_indicator: function(doc) {
return [__(doc.status), frappe.utils.guess_colour(doc.status),
diff --git a/erpnext/hr/doctype/process_payroll/process_payroll.js b/erpnext/hr/doctype/process_payroll/process_payroll.js
index 1c60a5f..6c057e1 100644
--- a/erpnext/hr/doctype/process_payroll/process_payroll.js
+++ b/erpnext/hr/doctype/process_payroll/process_payroll.js
@@ -1,6 +1,62 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
+frappe.ui.form.on("Process Payroll", {
+ refresh: function(frm) {
+ frm.disable_save();
+ frm.trigger("toggle_fields");
+ frm.trigger("set_month_dates");
+ },
+
+ month: function(frm) {
+ frm.trigger("set_month_dates");
+ },
+
+ fiscal_year: function(frm) {
+ frm.trigger("set_month_dates");
+ },
+
+ salary_slip_based_on_timesheet: function(frm) {
+ frm.trigger("toggle_fields")
+ },
+
+ toggle_fields: function(frm) {
+ frm.toggle_display(['from_date','to_date'],
+ cint(frm.doc.salary_slip_based_on_timesheet)==1);
+ frm.toggle_display(['fiscal_year', 'month'],
+ cint(frm.doc.salary_slip_based_on_timesheet)==0);
+ },
+
+ set_month_dates: function(frm) {
+ if (!frm.doc.salary_slip_based_on_timesheet){
+ frappe.call({
+ method:'erpnext.hr.doctype.process_payroll.process_payroll.get_month_details',
+ args:{
+ year: frm.doc.fiscal_year,
+ month: frm.doc.month
+ },
+ callback: function(r){
+ if (r.message){
+ frm.set_value('from_date', r.message.month_start_date);
+ frm.set_value('to_date', r.message.month_end_date);
+ }
+ }
+ })
+ }
+ }
+})
+
+cur_frm.cscript.onload = function(doc,cdt,cdn){
+ if(!doc.month) {
+ var today=new Date();
+ month = (today.getMonth()+01).toString();
+ if(month.length>1) doc.month = month;
+ else doc.month = '0'+month;
+ }
+ if(!doc.fiscal_year) doc.fiscal_year = sys_defaults['fiscal_year'];
+ refresh_many(['month', 'fiscal_year']);
+}
+
cur_frm.cscript.display_activity_log = function(msg) {
if(!cur_frm.ss_html)
cur_frm.ss_html = $a(cur_frm.fields_dict['activity_log'].wrapper,'div');
@@ -26,7 +82,7 @@
cur_frm.cscript.submit_salary_slip = function(doc, cdt, cdn) {
cur_frm.cscript.display_activity_log("");
- frappe.confirm(__("Do you really want to Submit all Salary Slip for month {0} and year {1}", [doc.month, doc.fiscal_year]), function() {
+ frappe.confirm(__("Do you really want to Submit all Salary Slip for Account {0} from {1} to {2}", [doc.payment_account, doc.from_date, doc.to_date]), function() {
// clear all in locals
if(locals["Salary Slip"]) {
$.each(locals["Salary Slip"], function(name, d) {
@@ -44,22 +100,45 @@
}
cur_frm.cscript.make_bank_entry = function(doc,cdt,cdn){
- if(doc.company && doc.month && doc.fiscal_year){
- cur_frm.cscript.make_jv(doc, cdt, cdn);
+ if(doc.company && doc.from_date && doc.to_date){
+ return cur_frm.cscript.reference_entry(doc,cdt,cdn);
} else {
- msgprint(__("Company, Month and Fiscal Year is mandatory"));
+ msgprint(__("Company, From Date and To Date is mandatory"));
}
}
-cur_frm.cscript.make_jv = function(doc, dt, dn) {
- return $c_obj(doc, 'make_journal_entry', '', function(r) {
- var doc = frappe.model.sync(r.message)[0];
- frappe.set_route("Form", doc.doctype, doc.name);
+cur_frm.cscript.reference_entry = function(doc,cdt,cdn){
+ var dialog = new frappe.ui.Dialog({
+ title: __("Bank Transaction Reference"),
+ fields: [
+ {
+ "label": __("Reference Number"),
+ "fieldname": "reference_number",
+ "fieldtype": "Data",
+ "reqd": 1
+ },
+ {
+ "label": __("Reference Date"),
+ "fieldname": "reference_date",
+ "fieldtype": "Date",
+ "reqd": 1,
+ "default": get_today()
+ }
+ ]
});
-}
-
-frappe.ui.form.on("Process Payroll", {
- refresh: function(frm) {
- frm.disable_save();
- }
-})
+ dialog.set_primary_action(__("Make"), function() {
+ args = dialog.get_values();
+ if(!args) return;
+ dialog.hide();
+ return frappe.call({
+ doc: cur_frm.doc,
+ method: "make_journal_entry",
+ args: {"reference_number": args.reference_number, "reference_date":args.reference_date},
+ callback: function(r) {
+ if (r.message)
+ cur_frm.cscript.display_activity_log(r.message);
+ }
+ });
+ });
+ dialog.show();
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/process_payroll/process_payroll.json b/erpnext/hr/doctype/process_payroll/process_payroll.json
index 8d8124b..13d3191 100644
--- a/erpnext/hr/doctype/process_payroll/process_payroll.json
+++ b/erpnext/hr/doctype/process_payroll/process_payroll.json
@@ -8,11 +8,13 @@
"docstatus": 0,
"doctype": "DocType",
"document_type": "Other",
+ "editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "section_break0",
"fieldtype": "Section Break",
"hidden": 0,
@@ -37,6 +39,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
@@ -61,6 +64,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -86,6 +90,59 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
+ "default": "Today",
+ "fieldname": "posting_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Posting Date",
+ "length": 0,
+ "no_copy": 0,
+ "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
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break1",
+ "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,
+ "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,
+ "width": "50%"
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
"fieldname": "branch",
"fieldtype": "Link",
"hidden": 0,
@@ -111,30 +168,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "fieldname": "column_break1",
- "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,
- "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,
- "width": "50%"
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
+ "columns": 0,
"fieldname": "department",
"fieldtype": "Link",
"hidden": 0,
@@ -160,6 +194,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "designation",
"fieldtype": "Link",
"hidden": 0,
@@ -185,6 +220,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "section_break_8",
"fieldtype": "Section Break",
"hidden": 0,
@@ -209,9 +245,10 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "salary_slip_based_on_timesheet",
"fieldtype": "Check",
- "hidden": 1,
+ "hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
@@ -234,14 +271,15 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "fieldname": "select_payroll_year_and_month",
+ "columns": 0,
+ "fieldname": "select_payroll_period",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "label": "Select Payroll Year and Month",
+ "label": "Select Payroll Period",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -259,6 +297,33 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
+ "fieldname": "from_date",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "From",
+ "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,
+ "columns": 0,
"fieldname": "fiscal_year",
"fieldtype": "Link",
"hidden": 0,
@@ -284,6 +349,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_11",
"fieldtype": "Column Break",
"hidden": 0,
@@ -308,6 +374,33 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
+ "fieldname": "to_date",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "To",
+ "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,
+ "columns": 0,
"fieldname": "month",
"fieldtype": "Select",
"hidden": 0,
@@ -333,32 +426,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "default": "Today",
- "fieldname": "posting_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Posting Date",
- "length": 0,
- "no_copy": 0,
- "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
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
+ "columns": 0,
"fieldname": "process_payroll",
"fieldtype": "Section Break",
"hidden": 0,
@@ -384,6 +452,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break2",
"fieldtype": "Column Break",
"hidden": 0,
@@ -408,6 +477,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Creates salary slip for above mentioned criteria.",
"fieldname": "create_salary_slip",
"fieldtype": "Button",
@@ -433,6 +503,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break3",
"fieldtype": "Column Break",
"hidden": 0,
@@ -457,6 +528,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Submit all salary slips for the above selected criteria",
"fieldname": "submit_salary_slip",
"fieldtype": "Button",
@@ -482,16 +554,19 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "fieldname": "column_break4",
- "fieldtype": "Column Break",
+ "columns": 0,
+ "fieldname": "account",
+ "fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "label": "Account",
"length": 0,
"no_copy": 0,
"permlevel": 0,
+ "precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
@@ -499,13 +574,42 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "unique": 0,
- "width": "25%"
+ "unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
+ "description": "Select Payment Account to make Bank Entry",
+ "fieldname": "payment_account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Payment 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": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "payment_account",
"description": "Create Bank Entry for the total salary paid for the above selected criteria",
"fieldname": "make_bank_entry",
"fieldtype": "Button",
@@ -531,6 +635,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "section_break2",
"fieldtype": "Section Break",
"hidden": 0,
@@ -554,6 +659,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "activity_log",
"fieldtype": "HTML",
"hidden": 0,
@@ -586,7 +692,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-09-19 15:12:54.090381",
+ "modified": "2016-09-28 05:43:26.472928",
"modified_by": "Administrator",
"module": "HR",
"name": "Process Payroll",
diff --git a/erpnext/hr/doctype/process_payroll/process_payroll.py b/erpnext/hr/doctype/process_payroll/process_payroll.py
index 3e6e3e0..f31ddfb 100644
--- a/erpnext/hr/doctype/process_payroll/process_payroll.py
+++ b/erpnext/hr/doctype/process_payroll/process_payroll.py
@@ -5,12 +5,13 @@
import frappe
from frappe.utils import cint, flt, nowdate
from frappe import _
+import collections
+from collections import defaultdict
from frappe.model.document import Document
class ProcessPayroll(Document):
-
def get_emp_list(self):
"""
Returns list of active employees based on selected criteria
@@ -21,19 +22,20 @@
sal_struct = frappe.db.sql("""
select name from `tabSalary Structure`
- where docstatus != 2 and
- ifnull(salary_slip_based_on_timesheet,0) = 0""")
-
+ where docstatus != 2 and payment_account = '%(payment_account)s' and
+ ifnull(salary_slip_based_on_timesheet,0) = %(salary_slip_based_on_timesheet)s"""%
+ {"payment_account": self.payment_account, "salary_slip_based_on_timesheet":self.salary_slip_based_on_timesheet})
+
if sal_struct:
cond += "and t2.parent IN %(sal_struct)s "
- emp_list = frappe.db.sql("""
- select t1.name
- from `tabEmployee` t1, `tabSalary Structure Employee` t2
- where t1.docstatus!=2 and t1.name = t2.employee
- %s """% cond, {"sal_struct": sal_struct})
+ emp_list = frappe.db.sql("""
+ select t1.name
+ from `tabEmployee` t1, `tabSalary Structure Employee` t2
+ where t1.docstatus!=2 and t1.name = t2.employee
+ %s """% cond, {"sal_struct": sal_struct})
- return emp_list
+ return emp_list
def get_filter_condition(self):
@@ -48,16 +50,15 @@
def get_joining_releiving_condition(self):
- m = get_month_details(self.fiscal_year, self.month)
cond = """
- and ifnull(t1.date_of_joining, '0000-00-00') <= '%(month_end_date)s'
- and ifnull(t1.relieving_date, '2199-12-31') >= '%(month_start_date)s'
- """ % m
+ and ifnull(t1.date_of_joining, '0000-00-00') <= '%(from_date)s'
+ and ifnull(t1.relieving_date, '2199-12-31') >= '%(to_date)s'
+ """ % {"from_date": self.from_date, "to_date": self.to_date}
return cond
def check_mandatory(self):
- for f in ['company', 'month', 'fiscal_year']:
+ for f in ['company', 'from_date', 'to_date']:
if not self.get(f):
frappe.throw(_("Please set {0}").format(f))
@@ -65,27 +66,37 @@
"""
Creates salary slip for selected employees if already not created
"""
-
self.check_permission('write')
emp_list = self.get_emp_list()
ss_list = []
- for emp in emp_list:
- if not frappe.db.sql("""select name from `tabSalary Slip`
- where docstatus!= 2 and employee = %s and month = %s and fiscal_year = %s and company = %s
- """, (emp[0], self.month, self.fiscal_year, self.company)):
- ss = frappe.get_doc({
- "doctype": "Salary Slip",
- "salary_slip_based_on_timesheet": 0,
- "fiscal_year": self.fiscal_year,
- "employee": emp[0],
- "month": self.month,
- "company": self.company,
- "posting_date": self.posting_date,
- })
- ss.insert()
- ss_list.append(ss.name)
-
+ if emp_list:
+ for emp in emp_list:
+ if not frappe.db.sql("""select name from `tabSalary Slip`
+ where docstatus!= 2 and employee = %s and start_date >= %s and end_date <= %s and company = %s
+ """, (emp[0], self.from_date, self.to_date, self.company)):
+ if self.salary_slip_based_on_timesheet:
+ ss = frappe.get_doc({
+ "doctype": "Salary Slip",
+ "salary_slip_based_on_timesheet": self.salary_slip_based_on_timesheet,
+ "start_date": self.from_date,
+ "end_date": self.to_date,
+ "employee": emp[0],
+ "company": self.company,
+ "posting_date": self.posting_date
+ })
+ else:
+ ss = frappe.get_doc({
+ "doctype": "Salary Slip",
+ "salary_slip_based_on_timesheet": self.salary_slip_based_on_timesheet,
+ "fiscal_year": self.fiscal_year,
+ "month": self.month,
+ "employee": emp[0],
+ "company": self.company,
+ "posting_date": self.posting_date
+ })
+ ss.insert()
+ ss_list.append(ss.name)
return self.create_log(ss_list)
@@ -97,16 +108,17 @@
return log
- def get_sal_slip_list(self):
+ def get_sal_slip_list(self, ss_status, as_dict=False):
"""
Returns list of salary slips based on selected criteria
- which are not submitted
"""
cond = self.get_filter_condition()
+
ss_list = frappe.db.sql("""
- select t1.name from `tabSalary Slip` t1
- where t1.docstatus = 0 and month = %s and fiscal_year = %s %s
- """ % ('%s', '%s', cond), (self.month, self.fiscal_year))
+ select t1.name, t1.salary_structure from `tabSalary Slip` t1
+ where t1.docstatus = %s and t1.start_date >= %s and t1.end_date <= %s
+ and (t1.journal_entry is null or t1.journal_entry = "") and ifnull(salary_slip_based_on_timesheet,0) = %s %s
+ """ % ('%s', '%s', '%s','%s', cond), (ss_status, self.from_date, self.to_date, self.salary_slip_based_on_timesheet), as_dict=as_dict)
return ss_list
@@ -116,16 +128,17 @@
"""
self.check_permission('write')
- ss_list = self.get_sal_slip_list()
+ ss_list = self.get_sal_slip_list(ss_status=0)
not_submitted_ss = []
for ss in ss_list:
ss_obj = frappe.get_doc("Salary Slip",ss[0])
- try:
- ss_obj.submit()
- except Exception,e:
+ if ss_obj.net_pay<0:
not_submitted_ss.append(ss[0])
- frappe.msgprint(e)
- continue
+ else:
+ try:
+ ss_obj.submit()
+ except Exception,e:
+ not_submitted_ss.append(ss[0])
return self.create_submit_log(ss_list, not_submitted_ss)
@@ -148,6 +161,7 @@
<b>Not Submitted Salary Slips: </b>\
<br><br> %s <br><br> \
Reason: <br>\
+ May be net pay is less than 0 <br>
May be company email id specified in employee master is not valid. <br> \
Please mention correct email id in employee master or if you don't want to \
send mail, uncheck 'Send Email' checkbox. <br>\
@@ -166,38 +180,105 @@
cond = self.get_filter_condition()
tot = frappe.db.sql("""
select sum(rounded_total) from `tabSalary Slip` t1
- where t1.docstatus = 1 and month = %s and fiscal_year = %s %s
- """ % ('%s', '%s', cond), (self.month, self.fiscal_year))
+ where t1.docstatus = 1 and start_date >= %s and end_date <= %s %s
+ """ % ('%s', '%s', cond), (self.from_date, self.to_date))
return flt(tot[0][0])
-
-
- def make_journal_entry(self, salary_account = None):
+
+ def get_salary_component_account(self, salary_component):
+ account = frappe.db.get_value("Salary Component Account",
+ {"parent": salary_component, "company": self.company}, "default_account")
+
+ if not account:
+ frappe.throw(_("Please set default account in Salary Component {0}")
+ .format(salary_component))
+
+ return account
+
+ def get_salary_components(self, component_type):
+ salary_slips = self.get_sal_slip_list(ss_status = 1, as_dict = True)
+ if salary_slips:
+ salary_components = frappe.db.sql("""select salary_component, amount, parentfield
+ from `tabSalary Detail` where parentfield = '%s' and parent in (%s)""" %
+ (component_type, ', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]), as_dict=True)
+ return salary_components
+
+ def get_salary_component_total(self, component_type = None):
+ salary_components = self.get_salary_components(component_type)
+ if salary_components:
+ component_dict = {}
+ for item in salary_components:
+ component_dict[item['salary_component']] = component_dict.get(item['salary_component'], 0) + item['amount']
+ account_details = self.get_account(component_dict = component_dict)
+ return account_details
+
+ def get_account(self, component_dict = None):
+ account_dict = {}
+ for s, a in component_dict.items():
+ account = self.get_salary_component_account(s)
+ account_dict[account] = account_dict.get(account, 0) + a
+ return account_dict
+
+
+ def make_journal_entry(self, reference_number = None, reference_date = None):
self.check_permission('write')
+ earnings = self.get_salary_component_total(component_type = "earnings")
+ deductions = self.get_salary_component_total(component_type = "deductions")
+ jv_name = ""
- amount = self.get_total_salary()
- default_bank_account = frappe.db.get_value("Company", self.company,
- "default_bank_account")
+ if earnings or deductions:
+ journal_entry = frappe.new_doc('Journal Entry')
+ journal_entry.voucher_type = 'Bank Entry'
+ journal_entry.user_remark = _('Payment of salary from {0} to {1}').format(self.from_date,
+ self.to_date)
+ journal_entry.company = self.company
+ journal_entry.posting_date = nowdate()
+
+ account_amt_list = []
+ adjustment_amt = 0
+ for acc, amt in earnings.items():
+ adjustment_amt = adjustment_amt+amt
+ account_amt_list.append({
+ "account": acc,
+ "debit_in_account_currency": amt
+ })
+ for acc, amt in deductions.items():
+ adjustment_amt = adjustment_amt-amt
+ account_amt_list.append({
+ "account": acc,
+ "credit_in_account_currency": amt
+ })
+ account_amt_list.append({
+ "account": self.payment_account,
+ "credit_in_account_currency": adjustment_amt
+ })
+ journal_entry.set("accounts", account_amt_list)
+ journal_entry.cheque_no = reference_number
+ journal_entry.cheque_date = reference_date
+ journal_entry.save()
+ try:
+ journal_entry.submit()
+ jv_name = journal_entry.name
+ self.update_salary_slip_status(jv_name = jv_name)
+ except Exception, e:
+ frappe.msgprint(e)
+ return self.create_jv_log(jv_name)
+
- journal_entry = frappe.new_doc('Journal Entry')
- journal_entry.voucher_type = 'Bank Entry'
- journal_entry.user_remark = _('Payment of salary for the month {0} and year {1}').format(self.month,
- self.fiscal_year)
- journal_entry.fiscal_year = self.fiscal_year
- journal_entry.company = self.company
- journal_entry.posting_date = nowdate()
- journal_entry.set("accounts", [
- {
- "account": salary_account,
- "debit_in_account_currency": amount
- },
- {
- "account": default_bank_account,
- "credit_in_account_currency": amount
- },
- ])
+ def create_jv_log(self, jv_name):
+ log = "<p>" + _("No submitted Salary Slip found") + "</p>"
+ if jv_name:
+ log = "<b>" + _("Journal Entry Submitted") + "</b>\
+ %s" % '<br>''<a href="#Form/Journal Entry/{0}">{0}</a>'.format(jv_name)
+ return log
+
+ def update_salary_slip_status(self, jv_name = None):
+ ss_list = self.get_sal_slip_list(ss_status=1)
+ for ss in ss_list:
+ ss_obj = frappe.get_doc("Salary Slip",ss[0])
+ frappe.db.set_value("Salary Slip", ss_obj.name, "status", "Paid")
+ frappe.db.set_value("Salary Slip", ss_obj.name, "journal_entry", jv_name)
- return journal_entry.as_dict()
@frappe.whitelist()
def get_month_details(year, month):
diff --git a/erpnext/hr/doctype/process_payroll/test_process_payroll.py b/erpnext/hr/doctype/process_payroll/test_process_payroll.py
new file mode 100644
index 0000000..4e3a588
--- /dev/null
+++ b/erpnext/hr/doctype/process_payroll/test_process_payroll.py
@@ -0,0 +1,27 @@
+# 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
+import frappe
+import erpnext
+from frappe.utils import flt, add_months, cint, nowdate, getdate, add_days, random_string
+from frappe.utils.make_random import get_random
+
+class TestProcessPayroll(unittest.TestCase):
+ def test_process_payroll(self):
+ month = "11"
+ fiscal_year = "_Test Fiscal Year 2016"
+ payment_account = frappe.get_all("Account")[0].name
+ if not frappe.db.get_value("Salary Slip", {"fiscal_year": fiscal_year, "month": month}):
+ process_payroll = frappe.get_doc("Process Payroll", "Process Payroll")
+ process_payroll.company = erpnext.get_default_company()
+ process_payroll.month = month
+ process_payroll.fiscal_year = fiscal_year
+ process_payroll.from_date = "2016-11-01"
+ process_payroll.to_date = "2016-11-30"
+ process_payroll.payment_account = payment_account
+ process_payroll.create_sal_slip()
+ process_payroll.submit_salary_slip()
+ if process_payroll.get_sal_slip_list(ss_status = 1):
+ r = process_payroll.make_journal_entry(reference_number=random_string(10),reference_date=nowdate())
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_component/salary_component.json b/erpnext/hr/doctype/salary_component/salary_component.json
index ca7378b..33fb793 100644
--- a/erpnext/hr/doctype/salary_component/salary_component.json
+++ b/erpnext/hr/doctype/salary_component/salary_component.json
@@ -70,6 +70,33 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "type",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Earning\nDeduction",
+ "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
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
"fieldname": "description",
"fieldtype": "Small Text",
"hidden": 0,
@@ -96,6 +123,31 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "section_break_5",
+ "fieldtype": "Section 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,
+ "columns": 0,
"fieldname": "accounts",
"fieldtype": "Table",
"hidden": 0,
@@ -117,33 +169,6 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "type",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Type",
- "length": 0,
- "no_copy": 0,
- "options": "Earning\nDeduction",
- "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,
@@ -157,7 +182,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-08-29 05:33:22.495594",
+ "modified": "2016-08-31 08:08:47.359578",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Component",
diff --git a/erpnext/hr/doctype/salary_detail/salary_detail.json b/erpnext/hr/doctype/salary_detail/salary_detail.json
index 3bb621b..99c705a 100644
--- a/erpnext/hr/doctype/salary_detail/salary_detail.json
+++ b/erpnext/hr/doctype/salary_detail/salary_detail.json
@@ -300,7 +300,7 @@
"label": "Condition and Formula Help",
"length": 0,
"no_copy": 0,
- "options": "<h3>Condition and Formula Help</h3>\n\n<p>Notes:</p>\n\n<ol>\n<li>Use field <code>base</code> for using base salary of the Employee</li>\n<li>Use Salary Component abbreviations in conditions and formulas. <code>BS = Basic Salary</code></li>\n<li>Use field name for employee details in conditions and formulas. <code>Employment Type = employment_type</code><code>Branch = branch</code></li>\n<li>Direct Amount can also be entered based on Condtion. See example 3</li></ol>\n\n<h4>Examples</h4>\n<ol>\n<li>Calculating Basic Salary based on <code>base</code>\n<pre><code>Condition: base < 10000</code></pre>\n<pre><code>Formula: base * .2</code></pre></li>\n<li>Calculating HRA based on Basic Salary<code>BS</code> \n<pre><code>Condition: BS > 2000</code></pre>\n<pre><code>Formula: BS * .1</code></pre></li>\n<li>Calculating TDS based on Employment Type<code>employment_type</code> \n<pre><code>Condition: employment_type==\"Intern\"</code></pre>\n<pre><code>Amount: 1000</code></pre></li>\n</ol>",
+ "options": "<h3>Condition and Formula Help</h3>\n\n<p>Notes:</p>\n\n<ol>\n<li>Use field <code>base</code> for using base salary of the Employee</li>\n<li>Use Salary Component abbreviations in conditions and formulas. <code>BS = Basic Salary</code></li>\n<li>Use field name for employee details in conditions and formulas. <code>Employment Type = employment_type</code><code>Branch = branch</code></li>\n<li>Use field name from Salary Slip in conditions and formulas. <code>Payment Days = payment_days</code><code>Leave without pay = leave_without_pay</code></li>\n<li>Direct Amount can also be entered based on Condtion. See example 3</li></ol>\n\n<h4>Examples</h4>\n<ol>\n<li>Calculating Basic Salary based on <code>base</code>\n<pre><code>Condition: base < 10000</code></pre>\n<pre><code>Formula: base * .2</code></pre></li>\n<li>Calculating HRA based on Basic Salary<code>BS</code> \n<pre><code>Condition: BS > 2000</code></pre>\n<pre><code>Formula: BS * .1</code></pre></li>\n<li>Calculating TDS based on Employment Type<code>employment_type</code> \n<pre><code>Condition: employment_type==\"Intern\"</code></pre>\n<pre><code>Amount: 1000</code></pre></li>\n</ol>",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -323,7 +323,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-08-23 15:26:07.754570",
+ "modified": "2016-09-20 05:29:26.373992",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Detail",
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.js b/erpnext/hr/doctype/salary_slip/salary_slip.js
index 4c60fba..bb27a42 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.js
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.js
@@ -13,6 +13,20 @@
}
}
}
+ frm.set_query("salary_component", "earnings", function() {
+ return {
+ filters: {
+ type: "earning"
+ }
+ }
+ })
+ frm.set_query("salary_component", "deductions", function() {
+ return {
+ filters: {
+ type: "deduction"
+ }
+ }
+ })
},
company: function(frm) {
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.json b/erpnext/hr/doctype/salary_slip/salary_slip.json
index c250cbd..40592c2 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.json
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.json
@@ -15,6 +15,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
@@ -40,14 +41,15 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "posting_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
- "in_filter": 0,
+ "in_filter": 0,
"in_list_view": 0,
- "label": "posting Date",
+ "label": "Posting Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -65,6 +67,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "employee",
"fieldtype": "Link",
"hidden": 0,
@@ -92,6 +95,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "employee_name",
"fieldtype": "Read Only",
"hidden": 0,
@@ -119,6 +123,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "department",
"fieldtype": "Link",
"hidden": 0,
@@ -146,6 +151,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "designation",
"fieldtype": "Link",
"hidden": 0,
@@ -173,6 +179,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "branch",
"fieldtype": "Link",
"hidden": 0,
@@ -200,6 +207,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -225,6 +233,60 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Status",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Draft\nSubmitted\nPaid\nCancelled",
+ "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,
+ "columns": 0,
+ "fieldname": "journal_entry",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Journal Entry",
+ "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,
+ "columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -250,6 +312,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "letter_head",
"fieldtype": "Link",
"hidden": 0,
@@ -275,6 +338,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "section_break_10",
"fieldtype": "Section Break",
"hidden": 0,
@@ -299,6 +363,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "salary_slip_based_on_timesheet",
"fieldtype": "Check",
@@ -326,6 +391,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "fiscal_year",
"fieldtype": "Link",
@@ -354,6 +420,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "month",
"fieldtype": "Select",
@@ -383,6 +450,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "start_date",
"fieldtype": "Date",
"hidden": 0,
@@ -408,6 +476,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "Today",
"depends_on": "",
"fieldname": "end_date",
@@ -435,6 +504,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_15",
"fieldtype": "Column Break",
"hidden": 0,
@@ -459,6 +529,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "salary_structure",
"fieldtype": "Link",
@@ -486,6 +557,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "total_days_in_month",
"fieldtype": "Float",
@@ -513,6 +585,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "leave_without_pay",
"fieldtype": "Float",
@@ -540,6 +613,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "payment_days",
"fieldtype": "Float",
@@ -567,6 +641,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "hourly_wages",
"fieldtype": "Section Break",
@@ -593,6 +668,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "timesheets",
"fieldtype": "Table",
@@ -620,6 +696,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_20",
"fieldtype": "Column Break",
"hidden": 0,
@@ -644,6 +721,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "total_working_hours",
"fieldtype": "Float",
"hidden": 0,
@@ -669,6 +747,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "hour_rate",
"fieldtype": "Currency",
"hidden": 0,
@@ -694,6 +773,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "section_break_26",
"fieldtype": "Section Break",
@@ -720,6 +800,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "bank_name",
"fieldtype": "Data",
"hidden": 0,
@@ -746,6 +827,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "bank_account_no",
"fieldtype": "Data",
"hidden": 0,
@@ -772,6 +854,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_01",
"fieldtype": "Column Break",
"hidden": 0,
@@ -796,6 +879,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@@ -823,6 +907,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "earning_deduction",
"fieldtype": "Section Break",
"hidden": 0,
@@ -848,6 +933,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "earning",
"fieldtype": "Column Break",
"hidden": 0,
@@ -874,6 +960,8 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
"fieldname": "earnings",
"fieldtype": "Table",
"hidden": 0,
@@ -901,6 +989,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "deduction",
"fieldtype": "Column Break",
"hidden": 0,
@@ -927,6 +1016,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "deductions",
"fieldtype": "Table",
"hidden": 0,
@@ -954,6 +1044,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "totals",
"fieldtype": "Section Break",
"hidden": 0,
@@ -979,6 +1070,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "arrear_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1006,6 +1098,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "leave_encashment_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1033,6 +1126,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "gross_pay",
"fieldtype": "Currency",
"hidden": 0,
@@ -1060,6 +1154,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_25",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1083,6 +1178,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "total_deduction",
"fieldtype": "Currency",
"hidden": 0,
@@ -1110,6 +1206,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Gross Pay + Arrear Amount +Encashment Amount - Total Deduction",
"fieldname": "net_pay",
"fieldtype": "Currency",
@@ -1138,6 +1235,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
+ "columns": 0,
"fieldname": "rounded_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1163,6 +1261,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Net Pay (in words) will be visible once you save the Salary Slip.",
"fieldname": "total_in_words",
"fieldtype": "Data",
@@ -1198,7 +1297,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-09-19 15:15:06.809508",
+ "modified": "2016-09-25 04:29:14.432800",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Slip",
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index 94a7202..84a20d9 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -20,6 +20,7 @@
self.name = make_autoname('Sal Slip/' +self.employee + '/.#####')
def validate(self):
+ self.status = self.get_status()
self.validate_dates()
self.check_existing()
self.set_month_dates()
@@ -31,7 +32,7 @@
self.get_leave_details(lwp = self.leave_without_pay)
# if self.salary_slip_based_on_timesheet or not self.net_pay:
- # self.calculate_net_pay()
+ self.calculate_net_pay()
company_currency = get_company_currency(self.company)
self.total_in_words = money_in_words(self.rounded_total, company_currency)
@@ -52,29 +53,40 @@
data = self.get_data_for_eval()
for key in ('earnings', 'deductions'):
- for d in self._salary_structure_doc.get(key):
- amount = self.eval_condition_and_formula(d, data)
+ for struct_row in self._salary_structure_doc.get(key):
+ amount = self.eval_condition_and_formula(struct_row, data)
if amount:
- self.append(key, {
- 'amount': amount,
- 'default_amount': amount,
- 'depends_on_lwp' : d.depends_on_lwp,
- 'salary_component' : d.salary_component
- })
+ self.update_component_row(struct_row, amount, key)
+
+
+ def update_component_row(self, struct_row, amount, key):
+ component_row = None
+ for d in self.get(key):
+ if d.salary_component == struct_row.salary_component:
+ component_row = d
+
+ if not component_row:
+ self.append(key, {
+ 'amount': amount,
+ 'default_amount': amount,
+ 'depends_on_lwp' : struct_row.depends_on_lwp,
+ 'salary_component' : struct_row.salary_component
+ })
+ else:
+ component_row.amount = amount
def eval_condition_and_formula(self, d, data):
try:
if d.condition:
if not eval(d.condition, None, data):
- return None
-
+ return None
amount = d.amount
if d.amount_based_on_formula:
if d.formula:
amount = eval(d.formula, None, data)
-
data[d.abbr] = amount
return amount
+
except NameError as err:
frappe.throw(_("Name error: {0}".format(err)))
except SyntaxError as err:
@@ -92,6 +104,7 @@
data.base, data.variable = d.base, d.variable
data.update(frappe.get_doc("Employee", self.employee).as_dict())
+ data.update(self.as_dict())
# set values for components
salary_components = frappe.get_all("Salary Component", fields=["salary_component_abbr"])
@@ -312,7 +325,8 @@
self.set(total_field, self.get(total_field) + flt(d.amount))
def calculate_net_pay(self):
- self.calculate_component_amounts()
+ if self.salary_structure:
+ self.calculate_component_amounts()
disable_rounded_total = cint(frappe.db.get_value("Global Defaults", None, "disable_rounded_total"))
@@ -327,11 +341,16 @@
self.precision("net_pay") if disable_rounded_total else 0)
def on_submit(self):
- self.update_status(self.name)
- if(frappe.db.get_single_value("HR Settings", "email_salary_slip_to_employee")):
- self.email_salary_slip()
+ if self.net_pay < 0:
+ frappe.throw(_("Net Pay cannot be less than 0"))
+ else:
+ self.set_status()
+ self.update_status(self.name)
+ if(frappe.db.get_single_value("HR Settings", "email_salary_slip_to_employee")):
+ self.email_salary_slip()
def on_cancel(self):
+ self.set_status()
self.update_status()
def email_salary_slip(self):
@@ -351,4 +370,30 @@
timesheet.salary_slip = salary_slip
timesheet.flags.ignore_validate_update_after_submit = True
timesheet.set_status()
- timesheet.save()
\ No newline at end of file
+ timesheet.save()
+
+ def set_status(self, status=None):
+ '''Get and update status'''
+ if not status:
+ status = self.get_status()
+ self.db_set("status", status)
+
+ def get_status(self):
+ if self.docstatus == 0:
+ status = "Draft"
+ elif self.docstatus == 1:
+ status = "Submitted"
+ if self.journal_entry:
+ status = "Paid"
+ elif self.docstatus == 2:
+ status = "Cancelled"
+ return status
+
+def unlink_ref_doc_from_salary_slip(ref_no):
+ linked_ss = frappe.db.sql_list("""select name from `tabSalary Slip`
+ where journal_entry=%s and docstatus < 2""", (ref_no))
+ if linked_ss:
+ for ss in linked_ss:
+ ss_doc = frappe.get_doc("Salary Slip", ss)
+ frappe.db.set_value("Salary Slip", ss_doc.name, "status", "Submitted")
+ frappe.db.set_value("Salary Slip", ss_doc.name, "journal_entry", "")
diff --git a/erpnext/hr/doctype/salary_slip/test_salary_slip.py b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
index 503996d..2287e9c 100644
--- a/erpnext/hr/doctype/salary_slip/test_salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
@@ -5,6 +5,7 @@
import unittest
import frappe
import erpnext
+from frappe.utils.make_random import get_random
from frappe.utils import today, now_datetime, getdate, cstr, add_years, nowdate
from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
from erpnext.hr.doctype.leave_application.test_leave_application import make_allocation_record
@@ -41,12 +42,12 @@
self.assertEquals(ss.total_days_in_month, 31)
self.assertEquals(ss.payment_days, 31)
- self.assertEquals(ss.earnings[0].amount, 0)
- self.assertEquals(ss.earnings[1].amount, 0)
- self.assertEquals(ss.deductions[0].amount, 0)
- self.assertEquals(ss.deductions[1].amount, 0)
- self.assertEquals(ss.gross_pay, 0)
- self.assertEquals(ss.net_pay, 0)
+ self.assertEquals(ss.earnings[0].amount, 5000)
+ self.assertEquals(ss.earnings[1].amount, 3000)
+ self.assertEquals(ss.deductions[0].amount, 5000)
+ self.assertEquals(ss.deductions[1].amount, 2500)
+ self.assertEquals(ss.gross_pay, 10500)
+ self.assertEquals(ss.net_pay, 3000)
def test_salary_slip_with_holidays_excluded(self):
frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0)
@@ -58,13 +59,13 @@
self.assertEquals(ss.total_days_in_month, 27)
self.assertEquals(ss.payment_days, 27)
- self.assertEquals(ss.earnings[0].amount, 0)
+ self.assertEquals(ss.earnings[0].amount, 5000)
self.assertEquals(ss.earnings[0].default_amount, 5000)
- self.assertEquals(ss.earnings[1].amount, 0)
- self.assertEquals(ss.deductions[0].amount, 0)
- self.assertEquals(ss.deductions[1].amount, 0)
- self.assertEquals(ss.gross_pay, 0)
- self.assertEquals(ss.net_pay, 0)
+ self.assertEquals(ss.earnings[1].amount, 3000)
+ self.assertEquals(ss.deductions[0].amount, 5000)
+ self.assertEquals(ss.deductions[1].amount, 2500)
+ self.assertEquals(ss.gross_pay, 10500)
+ self.assertEquals(ss.net_pay, 3000)
def test_payment_days(self):
# Holidays not included in working days
@@ -179,6 +180,7 @@
salary_slip.employee_name = frappe.get_value("Employee", {"name":frappe.db.get_value("Employee", {"user_id": user})}, "employee_name")
salary_slip.month = "12"
salary_slip.fiscal_year = "_Test Fiscal Year 2016"
+ salary_slip.posting_date = nowdate()
salary_slip.insert()
# salary_slip.submit()
salary_slip = salary_slip.name
@@ -202,7 +204,8 @@
"from_date": nowdate(),
"employees": get_employee_details(),
"earnings": get_earnings_component(),
- "deductions": get_deductions_component()
+ "deductions": get_deductions_component(),
+ "payment_account": get_random("Account")
}).insert()
return sal_struct
diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.js b/erpnext/hr/doctype/salary_structure/salary_structure.js
index 0dce0a4..d3f362e 100755
--- a/erpnext/hr/doctype/salary_structure/salary_structure.js
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.js
@@ -1,5 +1,6 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
+{% include "erpnext/public/js/controllers/accounts.js" %}
cur_frm.add_fetch('employee', 'company', 'company');
cur_frm.add_fetch('company', 'default_letter_head', 'letter_head');
diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.json b/erpnext/hr/doctype/salary_structure/salary_structure.json
index 5abebef..4d14fdb 100644
--- a/erpnext/hr/doctype/salary_structure/salary_structure.json
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.json
@@ -687,6 +687,111 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "account",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Account",
+ "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,
+ "columns": 0,
+ "fieldname": "mode_of_payment",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Mode of Payment",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Mode of Payment",
+ "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,
+ "columns": 0,
+ "fieldname": "column_break_28",
+ "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,
+ "columns": 0,
+ "fieldname": "payment_account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Payment 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,
@@ -700,7 +805,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-08-23 12:49:41.258649",
+ "modified": "2016-09-06 05:40:18.311581",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Structure",
diff --git a/erpnext/hr/doctype/salary_structure/test_salary_structure.py b/erpnext/hr/doctype/salary_structure/test_salary_structure.py
index ef9231a..cd7ee47 100644
--- a/erpnext/hr/doctype/salary_structure/test_salary_structure.py
+++ b/erpnext/hr/doctype/salary_structure/test_salary_structure.py
@@ -5,6 +5,7 @@
import frappe
import unittest
import erpnext
+from frappe.utils.make_random import get_random
from frappe.utils import nowdate, add_days, add_years
from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
# test_records = frappe.get_test_records('Salary Structure')
@@ -85,11 +86,11 @@
if not sal_slip:
sal_slip = make_salary_slip_from_salary_structure(employee=frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}))
self.assertEquals(sal_slip.get("salary_structure"), 'Salary Structure Sample')
- self.assertEquals(sal_slip.get("earnings")[0].amount, 0)
- self.assertEquals(sal_slip.get("deductions")[0].amount, 0)
- self.assertEquals(sal_slip.get("deductions")[1].amount, 0)
- self.assertEquals(sal_slip.get("total_deduction"), 0)
- self.assertEquals(sal_slip.get("net_pay"), 0)
+ self.assertEquals(sal_slip.get("earnings")[0].amount, 5000)
+ self.assertEquals(sal_slip.get("deductions")[0].amount, 5000)
+ self.assertEquals(sal_slip.get("deductions")[1].amount, 2500)
+ self.assertEquals(sal_slip.get("total_deduction"), 7500)
+ self.assertEquals(sal_slip.get("net_pay"), 7500)
def make_salary_slip_from_salary_structure(employee):
@@ -98,6 +99,7 @@
sal_slip.employee_name = frappe.get_value("Employee", {"name":employee}, "employee_name")
sal_slip.month = "11"
sal_slip.fiscal_year = "_Test Fiscal Year 2016"
+ sal_slip.posting_date = nowdate()
sal_slip.insert()
sal_slip.submit()
return sal_slip
@@ -111,7 +113,8 @@
"from_date": nowdate(),
"employees": get_employee_details(),
"earnings": get_earnings_component(),
- "deductions": get_deductions_component()
+ "deductions": get_deductions_component(),
+ "payment_account": frappe.get_all("Account")[0].name
}).insert()
return sal_struct
@@ -123,7 +126,7 @@
"idx": 1
},
{"employee": frappe.get_value("Employee", {"employee_name":"test_employee_2@salary.com"}, "name"),
- "base": 2100,
+ "base": 15000,
"variable": 100,
"idx": 2
}
@@ -148,7 +151,7 @@
{
"salary_component": 'HRA',
"abbr":'H',
- "amount": 3000,
+ "amount": 10000,
"idx": 3
},
{
@@ -172,6 +175,7 @@
{
"salary_component": 'TDS',
"abbr":'T',
+ "condition": 'employment_type!="Intern"',
"formula": 'base*.5',
"idx": 2
},
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index d598ee2..c94788a 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -55,7 +55,8 @@
if not self.expected_delivery_date:
self.expected_delivery_date = so[0].delivery_date
- self.project = so[0].project
+ if so[0].project:
+ self.project = so[0].project
self.validate_production_order_against_so()
else:
@@ -115,7 +116,7 @@
'''Update status of production order if unknown'''
if not status:
status = self.get_status(status)
-
+
if status != self.status:
self.db_set("status", status)
@@ -240,7 +241,7 @@
holidays[holiday_list] = holiday_list_days
return holidays[holiday_list]
-
+
def make_time_logs(self, open_new=False):
"""Capacity Planning. Plan time logs based on earliest availablity of workstation after
Planned Start Date. Time logs will be created and remain in Draft mode and must be submitted
@@ -261,7 +262,7 @@
if d.workstation and d.status != 'Completed':
last_workstation_idx[d.workstation] = i # set last row index of workstation
self.set_start_end_time_for_workstation(d, workstation_list, last_workstation_idx.get(d.workstation))
-
+
args = self.get_operations_data(d)
add_timesheet_detail(timesheet, args)
original_start_time = d.planned_start_time
@@ -366,7 +367,8 @@
if frappe.db.get_value("Item", self.production_item, "has_variants"):
frappe.throw(_("Production Order cannot be raised against a Item Template"), ItemHasVariantError)
- validate_end_of_life(self.production_item)
+ if self.production_item:
+ validate_end_of_life(self.production_item)
def validate_qty(self):
if not self.qty > 0:
@@ -520,7 +522,7 @@
timesheet.production_order = production_order
return timesheet
-@frappe.whitelist()
+@frappe.whitelist()
def add_timesheet_detail(timesheet, args):
if isinstance(timesheet, unicode):
timesheet = frappe.get_doc('Timesheet', timesheet)
diff --git a/erpnext/manufacturing/doctype/production_order/production_order_list.js b/erpnext/manufacturing/doctype/production_order/production_order_list.js
index cce56cf..762beb0 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order_list.js
+++ b/erpnext/manufacturing/doctype/production_order/production_order_list.js
@@ -1,6 +1,6 @@
frappe.listview_settings['Production Order'] = {
add_fields: ["bom_no", "status", "sales_order", "qty",
- "produced_qty", "expected_delivery_date"],
+ "produced_qty", "expected_delivery_date", "planned_start_date", "planned_end_date"],
filters: [["status", "!=", "Stopped"]],
get_indicator: function(doc) {
if(doc.status==="Submitted") {
diff --git a/erpnext/modules.txt b/erpnext/modules.txt
index 609a3fe..4daf0eb 100644
--- a/erpnext/modules.txt
+++ b/erpnext/modules.txt
@@ -1,6 +1,7 @@
Accounts
CRM
Buying
+Fleet Management
Projects
Selling
Setup
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 5ab2dbf..5b3781f 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -23,19 +23,15 @@
execute:frappe.reload_doc('buying', 'doctype', 'supplier') # 2014-01-29
execute:frappe.reload_doc('accounts', 'doctype', 'asset_category')
execute:frappe.reload_doc('accounts', 'doctype', 'pricing_rule')
-
-erpnext.patches.v5_2.change_item_selects_to_checks
-execute:frappe.reload_doctype('Item')
-
erpnext.patches.v4_0.map_charge_to_taxes_and_charges
execute:frappe.reload_doc('support', 'doctype', 'newsletter') # 2014-01-31
execute:frappe.reload_doc('hr', 'doctype', 'employee') # 2014-02-03
execute:frappe.db.sql("update tabPage set module='Core' where name='Setup'")
-
+erpnext.patches.v5_2.change_item_selects_to_checks
+execute:frappe.reload_doctype('Item')
erpnext.patches.v4_0.fields_to_be_renamed
erpnext.patches.v4_0.rename_sitemap_to_route
erpnext.patches.v7_0.re_route #2016-06-27
-
erpnext.patches.v4_0.fix_contact_address
erpnext.patches.v4_0.customer_discount_to_pricing_rule
execute:frappe.db.sql("""delete from `tabWebsite Item Group` where ifnull(item_group, '')=''""")
@@ -175,6 +171,7 @@
execute:frappe.db.sql_list("delete from `tabDocPerm` where parent='Issue' and modified_by='Administrator' and role='Guest'")
erpnext.patches.v5_0.update_item_and_description_again
erpnext.patches.v6_0.multi_currency
+erpnext.patches.v7_0.create_budget_record
erpnext.patches.v5_0.repost_gle_for_jv_with_multiple_party
erpnext.patches.v5_0.portal_fixes
erpnext.patches.v5_0.reset_values_in_tools # 02-05-2016
@@ -237,7 +234,6 @@
erpnext.patches.v6_4.set_user_in_contact
erpnext.patches.v6_4.make_image_thumbnail #2015-10-20
erpnext.patches.v6_5.show_in_website_for_template_item
-erpnext.patches.v7_0.create_budget_record
erpnext.patches.v6_4.fix_expense_included_in_valuation
execute:frappe.delete_doc_if_exists("Report", "Item-wise Last Purchase Rate")
erpnext.patches.v6_6.fix_website_image
@@ -268,7 +264,7 @@
erpnext.patches.v6_24.map_customer_address_to_shipping_address_on_po
erpnext.patches.v6_27.fix_recurring_order_status
erpnext.patches.v6_20x.update_product_bundle_description
-erpnext.patches.v7_0.update_party_status
+erpnext.patches.v7_0.update_party_status #2016-09-22
erpnext.patches.v7_0.update_item_projected
erpnext.patches.v7_0.remove_features_setup
erpnext.patches.v7_0.update_home_page
@@ -286,7 +282,7 @@
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
-erpnext.patches.v7_0.remove_doctypes_and_reports
+erpnext.patches.v7_0.remove_doctypes_and_reports #2016-10-29
erpnext.patches.v7_0.update_maintenance_module_in_doctype
erpnext.patches.v7_0.update_prevdoc_values_for_supplier_quotation_item
erpnext.patches.v7_0.rename_advance_table_fields
@@ -313,6 +309,7 @@
erpnext.patches.v7_0.set_material_request_type_in_item
erpnext.patches.v7_0.rename_examination_to_assessment
erpnext.patches.v7_0.set_portal_settings
+erpnext.patches.v7_0.update_change_amount_account
erpnext.patches.v7_0.repost_future_gle_for_purchase_invoice
erpnext.patches.v7_0.fix_duplicate_icons
erpnext.patches.v7_0.move_employee_parent_to_child_in_salary_structure
@@ -329,9 +326,15 @@
execute:frappe.db.sql("update `tabTimesheet` ts, `tabEmployee` emp set ts.employee_name = emp.employee_name where emp.name = ts.employee and ts.employee_name is null and ts.employee is not null")
erpnext.patches.v7_1.update_lead_source
erpnext.patches.v7_1.fix_link_for_customer_from_lead
+execute:frappe.db.sql("delete from `tabTimesheet Detail` where NOT EXISTS (select name from `tabTimesheet` where name = `tabTimesheet Detail`.parent)")
erpnext.patches.v7_0.update_mode_of_payment_type
execute:frappe.reload_doctype('Employee')
execute:frappe.db.sql("update `tabEmployee` set prefered_contact_email = IFNULL(prefered_contact_email,'') ")
execute:frappe.reload_doctype("Salary Slip")
execute:frappe.db.sql("update `tabSalary Slip` set posting_date=creation")
+erpnext.patches.v7_1.update_portal_roles
+erpnext.patches.v7_1.set_total_amount_currency_in_je
+finally:erpnext.patches.v7_0.update_timesheet_communications
+erpnext.patches.v7_0.update_status_of_zero_amount_sales_order
+erpnext.patches.v7_1.add_field_for_task_dependent
diff --git a/erpnext/patches/v6_3/convert_applicable_territory.py b/erpnext/patches/v6_3/convert_applicable_territory.py
index 69ec18f..b1793db 100644
--- a/erpnext/patches/v6_3/convert_applicable_territory.py
+++ b/erpnext/patches/v6_3/convert_applicable_territory.py
@@ -5,7 +5,7 @@
frappe.reload_doc("accounts", "doctype", "shipping_rule_country")
frappe.reload_doctype("Price List")
frappe.reload_doctype("Shipping Rule")
- frappe.reload_doctype("Shopping Cart Settings")
+ frappe.reload_doctype("shopping_cart", "doctype", "shopping_cart_settings")
# for price list
countries = frappe.db.sql_list("select name from tabCountry")
diff --git a/erpnext/patches/v7_0/convert_timelog_to_timesheet.py b/erpnext/patches/v7_0/convert_timelog_to_timesheet.py
index 16b2aec..2ca72b4 100644
--- a/erpnext/patches/v7_0/convert_timelog_to_timesheet.py
+++ b/erpnext/patches/v7_0/convert_timelog_to_timesheet.py
@@ -28,6 +28,7 @@
time_sheet.update_cost()
time_sheet.calculate_total_amounts()
time_sheet.flags.ignore_validate = True
+ time_sheet.flags.ignore_links = True
time_sheet.save(ignore_permissions=True)
# To ignore validate_mandatory_fields function
diff --git a/erpnext/patches/v7_0/convert_timelogbatch_to_timesheet.py b/erpnext/patches/v7_0/convert_timelogbatch_to_timesheet.py
index 0eff8d4..a7cb0d7 100644
--- a/erpnext/patches/v7_0/convert_timelogbatch_to_timesheet.py
+++ b/erpnext/patches/v7_0/convert_timelogbatch_to_timesheet.py
@@ -17,10 +17,10 @@
add_timesheet_detail(time_sheet, args)
time_sheet.docstatus = tlb.docstatus
+ time_sheet.flags.ignore_links = True
time_sheet.save(ignore_permissions=True)
def get_timesheet_data(data):
- time_log = frappe.get_all('Time Log', fields=["*"],
- filters = {'name': data.time_log})[0]
-
- return get_timelog_data(time_log)
\ No newline at end of file
+ time_log = frappe.get_all('Time Log', fields=["*"], filters = {'name': data.time_log})
+ if time_log:
+ return get_timelog_data(time_log[0])
\ No newline at end of file
diff --git a/erpnext/patches/v7_0/create_warehouse_nestedset.py b/erpnext/patches/v7_0/create_warehouse_nestedset.py
index 8190fd7..8ae86f7 100644
--- a/erpnext/patches/v7_0/create_warehouse_nestedset.py
+++ b/erpnext/patches/v7_0/create_warehouse_nestedset.py
@@ -29,10 +29,11 @@
make_warehouse_nestedset(company)
else:
sle_against_companies = frappe.db.sql_list("""select distinct company from `tabStock Ledger Entry`""")
- company = frappe.defaults.get_defaults().company
if len(sle_against_companies) == 1:
- set_company_to_warehouse(company)
+ company = frappe.db.get_value("Company", sle_against_companies[0],
+ fieldname=["name", "abbr"], as_dict=1)
+ set_company_to_warehouse(company.name)
make_warehouse_nestedset(company)
elif len(sle_against_companies) > 1:
diff --git a/erpnext/patches/v7_0/move_timelogbatch_from_salesinvoiceitem_to_salesinvoicetimesheet.py b/erpnext/patches/v7_0/move_timelogbatch_from_salesinvoiceitem_to_salesinvoicetimesheet.py
index 0332955..727a44e 100644
--- a/erpnext/patches/v7_0/move_timelogbatch_from_salesinvoiceitem_to_salesinvoicetimesheet.py
+++ b/erpnext/patches/v7_0/move_timelogbatch_from_salesinvoiceitem_to_salesinvoicetimesheet.py
@@ -5,6 +5,8 @@
frappe.reload_doc('accounts', 'doctype', 'sales_invoice_payment')
for time_sheet in frappe.db.sql(""" select sales_invoice, name, total_billable_amount from `tabTimesheet`
where sales_invoice is not null and docstatus < 2""", as_dict=True):
+ if not frappe.db.exists('Sales Invoice', time_sheet.sales_invoice):
+ continue
si_doc = frappe.get_doc('Sales Invoice', time_sheet.sales_invoice)
ts = si_doc.append('timesheets',{})
ts.time_sheet = time_sheet.name
diff --git a/erpnext/patches/v7_0/remove_doctypes_and_reports.py b/erpnext/patches/v7_0/remove_doctypes_and_reports.py
index 0a302b1..03461de 100644
--- a/erpnext/patches/v7_0/remove_doctypes_and_reports.py
+++ b/erpnext/patches/v7_0/remove_doctypes_and_reports.py
@@ -5,6 +5,22 @@
frappe.db.sql("""delete from `tabDocType`
where name in('Time Log Batch', 'Time Log Batch Detail', 'Time Log')""")
+ frappe.db.sql("""delete from `tabDocField` where parent in ('Time Log', 'Time Log Batch')""")
+ frappe.db.sql("""update `tabCustom Script` set dt = 'Timesheet' where dt = 'Time Log'""")
+
+ for data in frappe.db.sql(""" select label, fieldname from `tabCustom Field` where dt = 'Time Log'""", as_dict=1):
+ custom_field = frappe.get_doc({
+ 'doctype': 'Custom Field',
+ 'label': data.label,
+ 'dt': 'Timesheet Detail',
+ 'fieldname': data.fieldname,
+ 'fieldtype': data.fieldtype or "Data"
+ }).insert(ignore_permissions=True)
+
+ frappe.db.sql("""delete from `tabCustom Field` where dt = 'Time Log'""")
+ frappe.reload_doc('projects', 'doctype', 'timesheet')
+ frappe.reload_doc('projects', 'doctype', 'timesheet_detail')
+
report = "Daily Time Log Summary"
if frappe.db.exists("Report", report):
- frappe.delete_doc('Report', report)
\ No newline at end of file
+ frappe.delete_doc('Report', report)
diff --git a/erpnext/patches/v7_0/remove_features_setup.py b/erpnext/patches/v7_0/remove_features_setup.py
index 60d1926..596f7a9 100644
--- a/erpnext/patches/v7_0/remove_features_setup.py
+++ b/erpnext/patches/v7_0/remove_features_setup.py
@@ -7,6 +7,8 @@
frappe.reload_doctype('Stock Settings')
stock_settings = frappe.get_doc('Stock Settings', 'Stock Settings')
stock_settings.show_barcode_field = cint(frappe.db.get_value("Features Setup", None, "fs_item_barcode"))
+ if not frappe.db.exists("UOM", stock_settings.stock_uom):
+ stock_settings.stock_uom = None
stock_settings.save()
create_compact_item_print_custom_field()
diff --git a/erpnext/patches/v7_0/repost_gle_for_pos_sales_return.py b/erpnext/patches/v7_0/repost_gle_for_pos_sales_return.py
index d3dd2e9..77ecafd 100644
--- a/erpnext/patches/v7_0/repost_gle_for_pos_sales_return.py
+++ b/erpnext/patches/v7_0/repost_gle_for_pos_sales_return.py
@@ -7,6 +7,7 @@
def execute():
frappe.reload_doctype("Sales Invoice")
+ frappe.reload_doctype("Sales Invoice Item")
for si in frappe.get_all("Sales Invoice", fields = ["name"],
filters={"docstatus": 1, "is_pos": 1, "is_return": 1}):
diff --git a/erpnext/patches/v7_0/set_portal_settings.py b/erpnext/patches/v7_0/set_portal_settings.py
index 3e3b729..d9b6400 100644
--- a/erpnext/patches/v7_0/set_portal_settings.py
+++ b/erpnext/patches/v7_0/set_portal_settings.py
@@ -9,10 +9,12 @@
def execute():
for dt in ("assessment", "announcement", "course", "fees"):
frappe.reload_doc("schools", "doctype", dt)
-
+
+ frappe.reload_doc('website', 'doctype', 'portal_menu_item')
+
frappe.get_doc('Portal Settings').sync_menu()
if 'schools' in frappe.get_installed_apps():
domainify.setup_domain('Education')
else:
- domainify.setup_sidebar_items(domainify.get_domain('Manufacturing'))
\ No newline at end of file
+ domainify.setup_sidebar_items(domainify.get_domain('Manufacturing'))
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
index 9622490..c565707 100644
--- 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
@@ -16,4 +16,5 @@
"company": frappe.db.get_value("Account", expense_claim_type.default_account, "company"),
"default_account": expense_claim_type.default_account,
})
+ doc.flags.ignore_mandatory = True
doc.save(ignore_permissions=True)
\ No newline at end of file
diff --git a/erpnext/patches/v7_0/update_change_amount_account.py b/erpnext/patches/v7_0/update_change_amount_account.py
new file mode 100644
index 0000000..1741095
--- /dev/null
+++ b/erpnext/patches/v7_0/update_change_amount_account.py
@@ -0,0 +1,19 @@
+from __future__ import unicode_literals
+import frappe
+from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
+
+def execute():
+ frappe.reload_doc('accounts', 'doctype', 'sales_invoice')
+
+ for company in frappe.db.sql("""select company from `tabSales Invoice`
+ where change_amount <> 0 and account_for_change_amount is null group by company""", as_list = 1):
+ cash_account = get_default_bank_cash_account(company[0], 'Cash').get('account')
+ if not cash_account:
+ bank_account = get_default_bank_cash_account(company[0], 'Bank').get('account')
+ cash_account = bank_account
+
+ if cash_account:
+ frappe.db.sql("""update `tabSales Invoice`
+ set account_for_change_amount = %(cash_account)s where change_amount <> 0
+ and company = %(company)s and account_for_change_amount is null""",
+ {'cash_account': cash_account, 'company': company[0]})
diff --git a/erpnext/patches/v7_0/update_status_of_zero_amount_sales_order.py b/erpnext/patches/v7_0/update_status_of_zero_amount_sales_order.py
new file mode 100644
index 0000000..9b2b247
--- /dev/null
+++ b/erpnext/patches/v7_0/update_status_of_zero_amount_sales_order.py
@@ -0,0 +1,7 @@
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ for data in frappe.get_all('Sales Order', fields = ["name"], filters = [["docstatus", "=", "1"], ["grand_total", "=", "0"]]):
+ sales_order = frappe.get_doc('Sales Order', data.name)
+ sales_order.set_status(update=True, update_modified = False)
\ No newline at end of file
diff --git a/erpnext/patches/v7_0/update_timesheet_communications.py b/erpnext/patches/v7_0/update_timesheet_communications.py
new file mode 100644
index 0000000..203471e
--- /dev/null
+++ b/erpnext/patches/v7_0/update_timesheet_communications.py
@@ -0,0 +1,27 @@
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ if frappe.db.table_exists("Time Log"):
+ timesheet = frappe.db.sql("""SELECT ts.name AS name, tl.name AS timelogname,
+ tl.modified AS modified, tl.modified_by AS modified_by, tl.creation AS creation, tl.owner AS owner
+ FROM
+ `tabTimesheet` ts, `tabTimesheet Detail` tsd, `tabTime Log` tl
+ WHERE
+ tsd.parent = ts.name AND tl.from_time = tsd.from_time AND tl.to_time = tsd.to_time
+ AND tl.hours = tsd.hours AND tl.billing_rate = tsd.billing_rate AND tsd.idx=1
+ AND tl.docstatus < 2""", as_dict=1)
+
+ for data in timesheet:
+ frappe.db.sql(""" update `tabTimesheet` set creation = %(creation)s,
+ owner = %(owner)s, modified = %(modified)s, modified_by = %(modified_by)s
+ where name = %(name)s""", data)
+
+ frappe.db.sql("""
+ update
+ tabCommunication
+ set
+ reference_doctype = "Timesheet", reference_name = %(timesheet)s
+ where
+ reference_doctype = "Time Log" and reference_name = %(timelog)s
+ """, {'timesheet': data.name, 'timelog': data.timelogname}, auto_commit=1)
diff --git a/erpnext/patches/v7_1/add_field_for_task_dependent.py b/erpnext/patches/v7_1/add_field_for_task_dependent.py
new file mode 100644
index 0000000..96daa13
--- /dev/null
+++ b/erpnext/patches/v7_1/add_field_for_task_dependent.py
@@ -0,0 +1,9 @@
+import frappe
+
+def execute():
+ frappe.reload_doctype('Task')
+ for t in frappe.get_all('Task', fields=['name']):
+ task = frappe.get_doc('Task', t.name)
+ task.update_depends_on()
+ if task.depends_on_tasks:
+ task.db_set('depends_on_tasks', task.depends_on_tasks, update_modified=False)
diff --git a/erpnext/patches/v7_1/set_total_amount_currency_in_je.py b/erpnext/patches/v7_1/set_total_amount_currency_in_je.py
new file mode 100644
index 0000000..eb4a347
--- /dev/null
+++ b/erpnext/patches/v7_1/set_total_amount_currency_in_je.py
@@ -0,0 +1,23 @@
+import frappe
+from erpnext import get_default_currency
+
+def execute():
+ frappe.reload_doc("accounts", "doctype", "journal_entry")
+
+ frappe.db.sql(""" update `tabJournal Entry` set total_amount_currency = %s
+ where ifnull(multi_currency, 0) = 0
+ and (pay_to_recd_from is not null or pay_to_recd_from != "") """, get_default_currency())
+
+ for je in frappe.db.sql(""" select name from `tabJournal Entry` where multi_currency = 1
+ and (pay_to_recd_from is not null or pay_to_recd_from != "")""", as_dict=1):
+
+ doc = frappe.get_doc("Journal Entry", je.name)
+ for d in doc.get('accounts'):
+ if d.party_type and d.party:
+ total_amount_currency = d.account_currency
+
+ elif frappe.db.get_value("Account", d.account, "account_type") in ["Bank", "Cash"]:
+ total_amount_currency = d.account_currency
+
+ frappe.db.set_value("Journal Entry", je.name, "total_amount_currency",
+ total_amount_currency, update_modified=False)
diff --git a/erpnext/patches/v7_1/update_lead_source.py b/erpnext/patches/v7_1/update_lead_source.py
index c7815c1..444159d 100644
--- a/erpnext/patches/v7_1/update_lead_source.py
+++ b/erpnext/patches/v7_1/update_lead_source.py
@@ -9,7 +9,7 @@
frappe.local.lang = frappe.db.get_default("lang") or 'en'
for s in default_lead_sources:
- frappe.get_doc(dict(doctype='Lead Source', source_name=_(s))).insert()
+ insert_lead_source(_(s))
# get lead sources in existing forms (customized)
# and create a document if not created
@@ -17,9 +17,12 @@
sources = frappe.db.sql_list('select distinct source from `tab{0}`'.format(d))
for s in sources:
if s and s not in default_lead_sources:
- frappe.get_doc(dict(doctype='Lead Source', source_name=s)).insert()
+ insert_lead_source(s)
# remove customization for source
for p in frappe.get_all('Property Setter', {'doc_type':d, 'field_name':'source', 'property':'options'}):
frappe.delete_doc('Property Setter', p.name)
+def insert_lead_source(s):
+ if not frappe.db.exists('Lead Source', s):
+ frappe.get_doc(dict(doctype='Lead Source', source_name=s)).insert()
diff --git a/erpnext/patches/v7_1/update_portal_roles.py b/erpnext/patches/v7_1/update_portal_roles.py
new file mode 100644
index 0000000..695f998
--- /dev/null
+++ b/erpnext/patches/v7_1/update_portal_roles.py
@@ -0,0 +1,20 @@
+import frappe
+
+def execute():
+ frappe.reload_doctype('Role')
+ for role_name in ('Customer', 'Supplier', 'Student'):
+ if frappe.db.exists('Role', role_name):
+ frappe.db.set_value('Role', role_name, 'desk_access', 0)
+ else:
+ frappe.get_doc(dict(doctype='Role', role_name=role_name, desk_access=0)).insert()
+
+
+ # set customer, supplier roles
+ for c in frappe.get_all('Contact', fields=['user'], filters={'ifnull(user, "")': ('!=', '')}):
+ user = frappe.get_doc('User', c.user)
+ user.set_default_roles()
+ user.flags.ignore_validate = True
+ user.flags.ignore_mandatory = True
+ user.save()
+
+
diff --git a/erpnext/portal/doctype/homepage/homepage.js b/erpnext/portal/doctype/homepage/homepage.js
index 100074f..0b07814 100644
--- a/erpnext/portal/doctype/homepage/homepage.js
+++ b/erpnext/portal/doctype/homepage/homepage.js
@@ -2,6 +2,14 @@
// For license information, please see license.txt
frappe.ui.form.on('Homepage', {
+ setup: function(frm) {
+ frm.fields_dict["products"].grid.get_field("item_code").get_query = function(){
+ return {
+ filters: {'show_in_website': 1}
+ }
+ }
+ },
+
refresh: function(frm) {
},
@@ -35,5 +43,12 @@
}
});
}
+ },
+
+ view: function(frm, cdt, cdn){
+ var child= locals[cdt][cdn]
+ if(child.item_code && frm.doc.products_url){
+ window.location.href = frm.doc.products_url + '/' + encodeURIComponent(child.item_code);
+ }
}
});
diff --git a/erpnext/projects/doctype/project/project.js b/erpnext/projects/doctype/project/project.js
index ee2db46..5f48a93 100644
--- a/erpnext/projects/doctype/project/project.js
+++ b/erpnext/projects/doctype/project/project.js
@@ -43,9 +43,8 @@
if(frappe.model.can_read("Task")) {
frm.add_custom_button(__("Gantt Chart"), function() {
- frappe.route_options = {"project": frm.doc.name,
- "start": frm.doc.expected_start_date, "end": frm.doc.expected_end_date};
- frappe.set_route("Gantt", "Task");
+ frappe.route_options = {"project": frm.doc.name};
+ frappe.set_route("List", "Task", "Gantt");
});
}
diff --git a/erpnext/projects/doctype/task/task.json b/erpnext/projects/doctype/task/task.json
index 94ec8a1..46c8746 100644
--- a/erpnext/projects/doctype/task/task.json
+++ b/erpnext/projects/doctype/task/task.json
@@ -9,11 +9,13 @@
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
+ "editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "subject",
"fieldtype": "Data",
"hidden": 0,
@@ -40,6 +42,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
+ "columns": 0,
"fieldname": "project",
"fieldtype": "Link",
"hidden": 0,
@@ -67,6 +70,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
@@ -93,6 +97,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
+ "columns": 0,
"fieldname": "status",
"fieldtype": "Select",
"hidden": 0,
@@ -120,6 +125,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "priority",
"fieldtype": "Select",
"hidden": 0,
@@ -147,6 +153,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "section_break_10",
"fieldtype": "Section Break",
"hidden": 0,
@@ -171,6 +178,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "exp_start_date",
"fieldtype": "Date",
"hidden": 0,
@@ -197,6 +205,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "0",
"description": "",
"fieldname": "expected_time",
@@ -225,6 +234,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_11",
"fieldtype": "Column Break",
"hidden": 0,
@@ -249,6 +259,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
+ "columns": 0,
"fieldname": "exp_end_date",
"fieldtype": "Date",
"hidden": 0,
@@ -275,6 +286,33 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
+ "fieldname": "progress",
+ "fieldtype": "Percent",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Progress",
+ "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,
+ "columns": 0,
"fieldname": "section_break0",
"fieldtype": "Section Break",
"hidden": 0,
@@ -300,6 +338,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "description",
"fieldtype": "Text Editor",
"hidden": 0,
@@ -328,6 +367,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "section_break",
"fieldtype": "Section Break",
"hidden": 0,
@@ -353,6 +393,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "depends_on",
"fieldtype": "Table",
"hidden": 0,
@@ -379,6 +420,33 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
+ "fieldname": "depends_on_tasks",
+ "fieldtype": "Read Only",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "depends_on_tasks",
+ "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,
+ "columns": 0,
"description": "",
"fieldname": "actual",
"fieldtype": "Section Break",
@@ -407,6 +475,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "act_start_date",
"fieldtype": "Date",
"hidden": 0,
@@ -433,6 +502,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "",
"description": "",
"fieldname": "actual_time",
@@ -461,6 +531,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_15",
"fieldtype": "Column Break",
"hidden": 0,
@@ -485,6 +556,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "act_end_date",
"fieldtype": "Date",
"hidden": 0,
@@ -511,6 +583,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "section_break_17",
"fieldtype": "Section Break",
"hidden": 0,
@@ -535,6 +608,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "total_costing_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -562,6 +636,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "total_expense_claim",
"fieldtype": "Currency",
"hidden": 0,
@@ -588,6 +663,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_20",
"fieldtype": "Column Break",
"hidden": 0,
@@ -612,6 +688,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "total_billing_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -637,6 +714,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "more_details",
"fieldtype": "Section Break",
"hidden": 0,
@@ -661,6 +739,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.status == \"Closed\" || doc.status == \"Pending Review\"",
"fieldname": "review_date",
"fieldtype": "Date",
@@ -688,6 +767,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "eval:doc.status == \"Closed\"",
"fieldname": "closing_date",
"fieldtype": "Date",
@@ -715,6 +795,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_22",
"fieldtype": "Column Break",
"hidden": 0,
@@ -738,6 +819,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -772,7 +854,7 @@
"istable": 0,
"max_attachments": 5,
"menu_index": 0,
- "modified": "2016-06-20 17:31:00.798534",
+ "modified": "2016-10-03 15:12:56.078675",
"modified_by": "Administrator",
"module": "Projects",
"name": "Task",
@@ -788,6 +870,7 @@
"export": 0,
"if_owner": 0,
"import": 0,
+ "is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index b918e3a..34b9ed5 100644
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -29,6 +29,7 @@
def validate(self):
self.validate_dates()
self.validate_status()
+ self.update_depends_on()
def validate_dates(self):
if self.exp_start_date and self.exp_end_date and getdate(self.exp_start_date) > getdate(self.exp_end_date):
@@ -46,6 +47,12 @@
from frappe.desk.form.assign_to import clear
clear(self.doctype, self.name)
+ def update_depends_on(self):
+ depends_on_tasks = ""
+ for d in self.depends_on:
+ depends_on_tasks += d.task + ","
+ self.depends_on_tasks = depends_on_tasks
+
def on_update(self):
self.check_recursion()
self.reschedule_dependent_tasks()
@@ -156,5 +163,3 @@
and exp_end_date < CURDATE()
and `status` not in ('Closed', 'Cancelled')""")
-
-
diff --git a/erpnext/projects/doctype/task/task_list.js b/erpnext/projects/doctype/task/task_list.js
index d24e1ac..4bfa781 100644
--- a/erpnext/projects/doctype/task/task_list.js
+++ b/erpnext/projects/doctype/task/task_list.js
@@ -1,5 +1,6 @@
frappe.listview_settings['Task'] = {
- add_fields: ["project", "status", "priority", "exp_start_date", "exp_end_date", "subject"],
+ add_fields: ["project", "status", "priority", "exp_start_date",
+ "exp_end_date", "subject", "progress", "depends_on_tasks"],
filters: [["status", "=", "Open"]],
onload: function(listview) {
var method = "erpnext.projects.doctype.task.task.set_multiple_status";
diff --git a/erpnext/projects/doctype/timesheet/test_timesheet.py b/erpnext/projects/doctype/timesheet/test_timesheet.py
index 369be6d..98866ab 100644
--- a/erpnext/projects/doctype/timesheet/test_timesheet.py
+++ b/erpnext/projects/doctype/timesheet/test_timesheet.py
@@ -6,6 +6,7 @@
import frappe
import unittest
import datetime
+from frappe.utils.make_random import get_random
from frappe.utils import now_datetime, nowdate
from erpnext.projects.doctype.timesheet.timesheet import OverlapError
from erpnext.projects.doctype.timesheet.timesheet import make_salary_slip, make_sales_invoice
@@ -30,7 +31,7 @@
self.assertEquals(salary_slip.total_working_hours, 2)
self.assertEquals(salary_slip.hour_rate, 50)
- self.assertEquals(salary_slip.net_pay, 50)
+ self.assertEquals(salary_slip.net_pay, 150)
self.assertEquals(salary_slip.timesheets[0].time_sheet, timesheet.name)
self.assertEquals(salary_slip.timesheets[0].working_hours, 2)
@@ -78,7 +79,8 @@
salary_structure.from_date = nowdate()
salary_structure.salary_component = "Basic"
salary_structure.hour_rate = 50.0
- salary_structure.company= "_Test Company"
+ salary_structure.company = "_Test Company"
+ salary_structure.payment_account = get_random("Account")
salary_structure.set('employees', [])
salary_structure.set('earnings', [])
diff --git a/erpnext/projects/doctype/timesheet/timesheet.py b/erpnext/projects/doctype/timesheet/timesheet.py
index 3b8f939..60435bc 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.py
+++ b/erpnext/projects/doctype/timesheet/timesheet.py
@@ -163,7 +163,7 @@
def validate_dates(self):
for data in self.time_logs:
- if time_diff_in_hours(data.to_time, data.from_time) < 0:
+ if data.from_time and data.to_time and time_diff_in_hours(data.to_time, data.from_time) < 0:
frappe.throw(_("To date cannot be before from date"))
def validate_time_logs(self):
@@ -345,6 +345,7 @@
target.salary_slip_based_on_timesheet = 1
target.start_date = doc.start_date
target.end_date = doc.end_date
+ target.posting_date = doc.modified
@frappe.whitelist()
def get_activity_cost(employee=None, activity_type=None):
diff --git a/erpnext/projects/doctype/timesheet/timesheet_calendar.js b/erpnext/projects/doctype/timesheet/timesheet_calendar.js
index a41ba38..ad81de6 100644
--- a/erpnext/projects/doctype/timesheet/timesheet_calendar.js
+++ b/erpnext/projects/doctype/timesheet/timesheet_calendar.js
@@ -1,10 +1,10 @@
frappe.views.calendar["Timesheet"] = {
field_map: {
- "start": "from_time",
- "end": "to_time",
+ "start": "start_date",
+ "end": "end_date",
"name": "parent",
- "id": "parent",
- "title": "activity_type",
+ "id": "name",
+ "title": "name",
"allDay": "allDay",
"child_name": "name"
},
diff --git a/erpnext/projects/doctype/timesheet/timesheet_list.js b/erpnext/projects/doctype/timesheet/timesheet_list.js
index c538fa1..1b200f8 100644
--- a/erpnext/projects/doctype/timesheet/timesheet_list.js
+++ b/erpnext/projects/doctype/timesheet/timesheet_list.js
@@ -1,5 +1,5 @@
frappe.listview_settings['Timesheet'] = {
- add_fields: ["status", "total_hours"],
+ add_fields: ["status", "total_hours", "start_date", "end_date"],
get_indicator: function(doc) {
if (doc.status== "Billed") {
return [__("Billed"), "green", "status,=," + "Billed"]
diff --git a/erpnext/projects/report/daily_timesheet_summary/daily_timesheet_summary.py b/erpnext/projects/report/daily_timesheet_summary/daily_timesheet_summary.py
index cc854a4..682fb2e 100644
--- a/erpnext/projects/report/daily_timesheet_summary/daily_timesheet_summary.py
+++ b/erpnext/projects/report/daily_timesheet_summary/daily_timesheet_summary.py
@@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
from frappe import _
+from frappe.desk.reportview import build_match_conditions
def execute(filters=None):
if not filters:
@@ -12,25 +13,36 @@
filters["from_time"] = "00:00:00"
filters["to_time"] = "24:00:00"
- columns = [_("Timesheet") + ":Link/Timesheet:120", _("Employee") + "::150", _("Employee Name") + "::150",
- _("From Datetime") + "::140", _("To Datetime") + "::140", _("Hours") + "::70",
- _("Activity Type") + "::120", _("Task") + ":Link/Task:150",
- _("Project") + ":Link/Project:120", _("Status") + "::70"]
-
- conditions = "ts.docstatus = 1"
- if filters.get("from_date"):
- conditions += " and tsd.from_time >= timestamp(%(from_date)s, %(from_time)s)"
- if filters.get("to_date"):
- conditions += " and tsd.to_time <= timestamp(%(to_date)s, %(to_time)s)"
-
+ columns = get_column()
+ conditions = get_conditions(filters)
data = get_data(conditions, filters)
return columns, data
+def get_column():
+ return [_("Timesheet") + ":Link/Timesheet:120", _("Employee") + "::150", _("Employee Name") + "::150",
+ _("From Datetime") + "::140", _("To Datetime") + "::140", _("Hours") + "::70",
+ _("Activity Type") + "::120", _("Task") + ":Link/Task:150",
+ _("Project") + ":Link/Project:120", _("Status") + "::70"]
+
def get_data(conditions, filters):
- time_sheet = frappe.db.sql(""" select ts.name, ts.employee, ts.employee_name,
- tsd.from_time, tsd.to_time, tsd.hours,
- tsd.activity_type, tsd.task, tsd.project, ts.status from `tabTimesheet Detail` tsd,
- `tabTimesheet` ts where ts.name = tsd.parent and %s order by ts.name"""%(conditions), filters, as_list=1)
+ time_sheet = frappe.db.sql(""" select `tabTimesheet`.name, `tabTimesheet`.employee, `tabTimesheet`.employee_name,
+ `tabTimesheet Detail`.from_time, `tabTimesheet Detail`.to_time, `tabTimesheet Detail`.hours,
+ `tabTimesheet Detail`.activity_type, `tabTimesheet Detail`.task, `tabTimesheet Detail`.project,
+ `tabTimesheet`.status from `tabTimesheet Detail`, `tabTimesheet` where
+ `tabTimesheet Detail`.parent = `tabTimesheet`.name and %s order by `tabTimesheet`.name"""%(conditions), filters, as_list=1)
return time_sheet
+
+def get_conditions(filters):
+ conditions = "`tabTimesheet`.docstatus = 1"
+ if filters.get("from_date"):
+ conditions += " and `tabTimesheet Detail`.from_time >= timestamp(%(from_date)s, %(from_time)s)"
+ if filters.get("to_date"):
+ conditions += " and `tabTimesheet Detail`.to_time <= timestamp(%(to_date)s, %(to_time)s)"
+
+ match_conditions = build_match_conditions("Timesheet")
+ if match_conditions:
+ conditions += " and %s" % match_conditions
+
+ return conditions
\ No newline at end of file
diff --git a/erpnext/public/css/website.css b/erpnext/public/css/website.css
index ab3beb0..2bfcd3e 100644
--- a/erpnext/public/css/website.css
+++ b/erpnext/public/css/website.css
@@ -2,6 +2,9 @@
font-size: 18px;
line-height: 200%;
}
+.web-page-content {
+ margin-bottom: 30px;
+}
.item-stock {
margin-bottom: 10px !important;
}
diff --git a/erpnext/public/js/controllers/accounts.js b/erpnext/public/js/controllers/accounts.js
index 37ce5de..c1c3553 100644
--- a/erpnext/public/js/controllers/accounts.js
+++ b/erpnext/public/js/controllers/accounts.js
@@ -81,6 +81,14 @@
}
})
+frappe.ui.form.on('Salary Structure', {
+ mode_of_payment: function(frm) {
+ get_payment_mode_account(frm, frm.doc.mode_of_payment, function(account){
+ frm.set_value("payment_account", account);
+ })
+ }
+})
+
get_payment_mode_account = function(frm, mode_of_payment, callback){
return frappe.call({
method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.get_bank_cash_account",
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index 189b56f..f642da1 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -14,11 +14,11 @@
item.total_margin = item.price_list_rate + item.margin_rate_or_amount;
}
- item.rate = flt(item.total_margin , 2);
+ item.rate = flt(item.total_margin , precision("rate", item));
if(item.discount_percentage){
discount_value = flt(item.total_margin) * flt(item.discount_percentage) / 100;
- item.rate = flt((item.total_margin) - (discount_value), precision('rate'));
+ item.rate = flt((item.total_margin) - (discount_value), precision('rate', item));
}
},
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 34cbbae..0244cf3 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -668,6 +668,7 @@
me._set_values_for_item_list(r.message);
if(item) me.set_gross_profit(item);
if(calculate_taxes_and_totals) me.calculate_taxes_and_totals();
+ if(me.frm.doc.apply_discount_on) me.frm.trigger("apply_discount_on")
}
}
});
@@ -978,7 +979,7 @@
make_payment_entry: function() {
return frappe.call({
- method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry",
+ method: cur_frm.cscript.get_method_for_payment(),
args: {
"dt": cur_frm.doc.doctype,
"dn": cur_frm.doc.name
@@ -989,5 +990,18 @@
// cur_frm.refresh_fields()
}
});
+ },
+
+ get_method_for_payment: function(){
+ method = "erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry"
+ if(cur_frm.doc.__onload && cur_frm.doc.__onload.make_payment_via_journal_entry){
+ if(in_list(['Sales Invoice', 'Purchase Invoice'], cur_frm.doc.doctype)){
+ method = "erpnext.accounts.doctype.journal_entry.journal_entry.get_payment_entry_against_invoice"
+ }else {
+ method= "erpnext.accounts.doctype.journal_entry.journal_entry.get_payment_entry_against_order"
+ }
+ }
+
+ return method
}
});
\ No newline at end of file
diff --git a/erpnext/public/js/shopping_cart.js b/erpnext/public/js/shopping_cart.js
index f5819a8..ace7fd8 100644
--- a/erpnext/public/js/shopping_cart.js
+++ b/erpnext/public/js/shopping_cart.js
@@ -10,7 +10,7 @@
$('.navbar li[data-label="User"] a')
.html('<i class="icon-fixed-width icon-user"></i> ' + full_name);
}
-
+
// update login
shopping_cart.show_shoppingcart_dropdown();
shopping_cart.set_cart_count();
@@ -32,7 +32,7 @@
}
});
},
-
+
update_cart: function(opts) {
if(!full_name || full_name==="Guest") {
if(localStorage) {
@@ -50,10 +50,10 @@
},
btn: opts.btn,
callback: function(r) {
- shopping_cart.set_cart_count();
+ shopping_cart.set_cart_count();
if (r.message.shopping_cart_menu) {
$('.shopping-cart-menu').html(r.message.shopping_cart_menu);
- }
+ }
if(opts.callback)
opts.callback(r);
}
@@ -63,11 +63,11 @@
set_cart_count: function() {
var cart_count = getCookie("cart_count");
-
+
if(cart_count) {
- $(".shopping-cart").toggle(true);
- }
-
+ $(".shopping-cart").toggleClass('hidden', true);
+ }
+
var $cart = $('.cart-icon');
var $badge = $cart.find("#cart-count");
@@ -88,7 +88,7 @@
$badge.remove();
}
},
-
+
shopping_cart_update: function(item_code, newVal, cart_dropdown) {
frappe.freeze();
shopping_cart.update_cart({
@@ -103,20 +103,20 @@
$(".cart-tax-items").html(r.message.taxes);
if (cart_dropdown != true) {
$(".cart-icon").hide();
- }
+ }
}
},
});
},
-
-
+
+
bind_dropdown_cart_buttons: function() {
$(".cart-icon").on('click', '.number-spinner button', function () {
var btn = $(this),
input = btn.closest('.number-spinner').find('input'),
oldValue = input.val().trim(),
newVal = 0;
-
+
if (btn.attr('data-dir') == 'up') {
newVal = parseInt(oldValue) + 1;
} else {
@@ -125,11 +125,11 @@
}
}
input.val(newVal);
- var item_code = input.attr("data-item-code");
+ var item_code = input.attr("data-item-code");
shopping_cart.shopping_cart_update(item_code, newVal, true);
return false;
});
-
+
},
-
+
});
diff --git a/erpnext/public/less/website.less b/erpnext/public/less/website.less
index 37d69e0..ce36e5f 100644
--- a/erpnext/public/less/website.less
+++ b/erpnext/public/less/website.less
@@ -8,6 +8,10 @@
line-height: 200%;
}
+.web-page-content {
+ margin-bottom: 30px;
+}
+
.item-stock {
margin-bottom: 10px !important;
}
diff --git a/erpnext/schools/doctype/student_admission/student_admission.js b/erpnext/schools/doctype/student_admission/student_admission.js
index 48f4c46..d7f7454 100644
--- a/erpnext/schools/doctype/student_admission/student_admission.js
+++ b/erpnext/schools/doctype/student_admission/student_admission.js
@@ -8,7 +8,7 @@
frm.refresh_field("route");
}
},
-
+
academic_year: function(frm) {
frm.trigger("program");
}
diff --git a/erpnext/schools/doctype/student_admission/student_admission.json b/erpnext/schools/doctype/student_admission/student_admission.json
index e757ae1..77a3236 100644
--- a/erpnext/schools/doctype/student_admission/student_admission.json
+++ b/erpnext/schools/doctype/student_admission/student_admission.json
@@ -1,8 +1,8 @@
{
"allow_copy": 0,
"allow_import": 0,
- "allow_rename": 0,
- "autoname": "field:route",
+ "allow_rename": 1,
+ "autoname": "",
"beta": 0,
"creation": "2016-09-13 03:05:27.154713",
"custom": 0,
@@ -121,6 +121,32 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "naming_series_for_student_applicant",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Naming Series (for Student Applicant)",
+ "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,
+ "columns": 0,
"fieldname": "publish",
"fieldtype": "Check",
"hidden": 0,
@@ -189,7 +215,7 @@
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
- "reqd": 1,
+ "reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@@ -389,7 +415,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-09-15 07:03:55.581346",
+ "modified": "2016-10-04 02:44:28.480942",
"modified_by": "Administrator",
"module": "Schools",
"name": "Student Admission",
@@ -406,6 +432,7 @@
"export": 1,
"if_owner": 0,
"import": 0,
+ "is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
diff --git a/erpnext/schools/doctype/student_admission/student_admission.py b/erpnext/schools/doctype/student_admission/student_admission.py
index c4384e2..b0c7b55 100644
--- a/erpnext/schools/doctype/student_admission/student_admission.py
+++ b/erpnext/schools/doctype/student_admission/student_admission.py
@@ -11,15 +11,19 @@
website = frappe._dict(
template = "templates/generators/student_admission.html",
condition_field = "publish",
- page_title_field = "route"
+ page_title_field = "title"
)
+ def autoname(self):
+ if not self.title:
+ self.title = self.get_title()
+ self.name = self.title
+
def get_context(self, context):
context.parents = [{'name': 'admissions', 'title': _('All Student Admissions') }]
-
- def validate(self):
- if not self.title:
- self.title = self.program + " admissions for " + self.academic_year
+
+ def get_title(self):
+ return _("Admissions for {0}").format(self.academic_term)
def get_list_context(context):
context.title = _("Student Admissions")
diff --git a/erpnext/schools/doctype/student_applicant/student_applicant.js b/erpnext/schools/doctype/student_applicant/student_applicant.js
index 6857a66..36baa80 100644
--- a/erpnext/schools/doctype/student_applicant/student_applicant.js
+++ b/erpnext/schools/doctype/student_applicant/student_applicant.js
@@ -4,22 +4,22 @@
frm.add_custom_button(__("Approve"), function() {
frm.set_value("application_status", "Approved");
frm.save_or_update();
-
- }).addClass("btn-primary");
-
+
+ }, 'Actions');
+
frm.add_custom_button(__("Reject"), function() {
frm.set_value("application_status", "Rejected");
frm.save_or_update();
- }).addClass("btn-danger");
+ }, 'Actions');
}
-
+
if(frm.doc.application_status== "Approved" && frm.doc.docstatus== 1 ) {
frm.add_custom_button(__("Enroll"), function() {
frm.events.enroll(frm)
}).addClass("btn-primary");
}
},
-
+
enroll: function(frm) {
frappe.model.open_mapped_doc({
method: "erpnext.schools.api.enroll_student",
diff --git a/erpnext/schools/doctype/student_applicant/student_applicant.json b/erpnext/schools/doctype/student_applicant/student_applicant.json
index ae99488..e60a54e 100644
--- a/erpnext/schools/doctype/student_applicant/student_applicant.json
+++ b/erpnext/schools/doctype/student_applicant/student_applicant.json
@@ -6,10 +6,12 @@
"beta": 0,
"creation": "2015-09-11 11:50:09.740807",
"custom": 0,
+ "default_print_format": "",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Document",
"editable_grid": 0,
+ "engine": "InnoDB",
"fields": [
{
"allow_on_submit": 0,
@@ -121,6 +123,32 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "paid",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Paid",
+ "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,
+ "columns": 0,
"fieldname": "column_break_8",
"fieldtype": "Column Break",
"hidden": 0,
@@ -156,7 +184,7 @@
"label": "Naming Series",
"length": 0,
"no_copy": 0,
- "options": "AP.",
+ "options": "AP",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -256,6 +284,33 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "student_admission",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Student Admission",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Student Admission",
+ "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,
+ "columns": 0,
"fieldname": "image",
"fieldtype": "Attach Image",
"hidden": 1,
@@ -865,7 +920,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2016-09-08 06:40:54.242322",
+ "modified": "2016-10-10 06:19:19.319038",
"modified_by": "Administrator",
"module": "Schools",
"name": "Student Applicant",
@@ -882,6 +937,7 @@
"export": 1,
"if_owner": 0,
"import": 1,
+ "is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@@ -891,6 +947,27 @@
"share": 1,
"submit": 1,
"write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 1,
+ "export": 0,
+ "if_owner": 1,
+ "import": 0,
+ "is_custom": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 0,
+ "role": "Guest",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
+ "write": 0
}
],
"quick_entry": 1,
diff --git a/erpnext/schools/doctype/student_applicant/student_applicant.py b/erpnext/schools/doctype/student_applicant/student_applicant.py
index 5ef72cb..047c702 100644
--- a/erpnext/schools/doctype/student_applicant/student_applicant.py
+++ b/erpnext/schools/doctype/student_applicant/student_applicant.py
@@ -8,6 +8,18 @@
from frappe.model.document import Document
class StudentApplicant(Document):
+ def autoname(self):
+ from frappe.model.naming import set_name_by_naming_series
+ if self.student_admission:
+ naming_series = frappe.db.get_value('Student Admission', self.student_admission,
+ 'naming_series_for_student_applicant')
+ print naming_series
+
+ if naming_series:
+ self.naming_series = naming_series
+
+ set_name_by_naming_series(self)
+
def validate(self):
self.title = " ".join(filter(None, [self.first_name, self.middle_name, self.last_name]))
@@ -15,3 +27,6 @@
student = frappe.get_list("Student", filters= {"student_applicant": self.name})
if student:
frappe.throw(_("Cannot change status as student {0} is linked with student application {1}").format(student[0].name, self.name))
+
+ def on_payment_authorized(self, *args, **kwargs):
+ self.db_set('paid', 1)
diff --git a/erpnext/schools/doctype/student_applicant/student_applicant_list.js b/erpnext/schools/doctype/student_applicant/student_applicant_list.js
index 43402d8..817a728 100644
--- a/erpnext/schools/doctype/student_applicant/student_applicant_list.js
+++ b/erpnext/schools/doctype/student_applicant/student_applicant_list.js
@@ -1,7 +1,11 @@
frappe.listview_settings['Student Applicant'] = {
- add_fields: [ "application_status"],
+ add_fields: [ "application_status", 'paid'],
+ has_indicator_for_draft: 1,
get_indicator: function(doc) {
- if (doc.application_status=="Applied") {
+ if (doc.paid) {
+ return [__("Paid"), "green", "paid,=,Yes"];
+ }
+ else if (doc.application_status=="Applied") {
return [__("Applied"), "orange", "application_status,=,Applied"];
}
else if (doc.application_status=="Approved") {
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index ced3679..0435141 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -553,6 +553,9 @@
def make_purchase_order_for_drop_shipment(source_name, for_supplier, target_doc=None):
def set_missing_values(source, target):
target.supplier = for_supplier
+ target.apply_discount_on = ""
+ target.additional_discount_percentage = 0.0
+ target.discount_amount = 0.0
default_price_list = frappe.get_value("Supplier", for_supplier, "default_price_list")
if default_price_list:
diff --git a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.json b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.json
index 0612dc0..af28e20 100644
--- a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.json
+++ b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.json
@@ -1,5 +1,5 @@
{
- "add_total_row": 0,
+ "add_total_row": 1,
"apply_user_permissions": 1,
"creation": "2013-05-03 11:31:05",
"disabled": 0,
@@ -7,7 +7,7 @@
"doctype": "Report",
"idx": 1,
"is_standard": "Yes",
- "modified": "2016-01-28 04:22:49.476068",
+ "modified": "2016-10-05 12:26:15.736596",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Person-wise Transaction Summary",
diff --git a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py
index e9930f3..0c6914d 100644
--- a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py
+++ b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py
@@ -39,7 +39,7 @@
_("Customer") + ":Link/Customer:140", _("Territory") + ":Link/Territory:100", _("Posting Date") + ":Date:100",
_("Item Code") + ":Link/Item:120", _("Item Group") + ":Link/Item Group:120",
_("Brand") + ":Link/Brand:120", _("Qty") + ":Float:100", _("Amount") + ":Currency:120",
- _("Sales Person") + ":Link/Sales Person:140", _("Contribution %") + ":Float:110",
+ _("Sales Person") + ":Link/Sales Person:140", _("Contribution %") + "::110",
_("Contribution Amount") + ":Currency:140"]
def get_entries(filters):
diff --git a/erpnext/setup/doctype/company/delete_company_transactions.py b/erpnext/setup/doctype/company/delete_company_transactions.py
index 7e1681c..8f058e8 100644
--- a/erpnext/setup/doctype/company/delete_company_transactions.py
+++ b/erpnext/setup/doctype/company/delete_company_transactions.py
@@ -18,7 +18,6 @@
frappe.PermissionError)
delete_bins(company_name)
- delete_time_sheets(company_name)
delete_lead_addresses(company_name)
for doctype in frappe.db.sql_list("""select parent from
@@ -70,14 +69,6 @@
frappe.db.sql("""delete from tabBin where warehouse in
(select name from tabWarehouse where company=%s)""", company_name)
-def delete_time_sheets(company_name):
- # Delete Time Logs as it is linked to Production Order / Project / Task, which are linked to company
- frappe.db.sql("""
- delete from `tabTimesheet`
- where
- company=%(company)s
- """, {"company": company_name})
-
def delete_lead_addresses(company_name):
"""Delete addresses to which leads are linked"""
for lead in frappe.get_all("Lead", filters={"company": company_name}):
diff --git a/erpnext/setup/doctype/email_digest/email_digest.py b/erpnext/setup/doctype/email_digest/email_digest.py
index 7ec04c8..ac999ed 100644
--- a/erpnext/setup/doctype/email_digest/email_digest.py
+++ b/erpnext/setup/doctype/email_digest/email_digest.py
@@ -340,13 +340,13 @@
count = 0
for account in accounts:
balance += (get_balance_on(account, date = self.future_to_date)
- - get_balance_on(account, date = self.future_from_date))
+ - get_balance_on(account, date = self.future_from_date - timedelta(days=1)))
count += (get_count_on(account,fieldname, date = self.future_to_date )
- - get_count_on(account,fieldname, date = self.future_from_date))
+ - get_count_on(account,fieldname, date = self.future_from_date - timedelta(days=1)))
past_balance += (get_balance_on(account, date = self.past_to_date)
- - get_balance_on(account, date = self.past_from_date))
+ - get_balance_on(account, date = self.past_from_date - timedelta(days=1)))
return balance, past_balance, count
diff --git a/erpnext/setup/doctype/email_digest/templates/default.html b/erpnext/setup/doctype/email_digest/templates/default.html
index 0500dc1..78acbd9 100644
--- a/erpnext/setup/doctype/email_digest/templates/default.html
+++ b/erpnext/setup/doctype/email_digest/templates/default.html
@@ -43,7 +43,8 @@
<!-- issue list -->
{% if issue_list %}
-<h4 style="{{ section_head }}">{{ _("Open Issues ") }}<span class="badge">({{ issue_count }})</span></h4>
+<h4 style="{{ section_head }}">{{ _("Open Issues ") }}
+ <span class="badge">({{ issue_count }})</span></h4>
<div>
{% for t in issue_list %}
<div style="{{ line_item }}">
@@ -66,7 +67,8 @@
<!-- project list -->
{% if project_list %}
-<h4 style="{{ section_head }}">{{ _("Open Projects ") }}<span class="badge">({{ project_count }})</span></h4>
+<h4 style="{{ section_head }}">{{ _("Open Projects ") }}
+ <span class="badge">({{ project_count }})</span></h4>
<div>
{% for t in project_list %}
<div style="{{ line_item }}">
@@ -92,7 +94,8 @@
<!-- events -->
{% if events %}
-<h4 style="{{ section_head }}">{{ _("Upcoming Calendar Events ") }}<span class="badge">({{ event_count }})</span></h4>
+<h4 style="{{ section_head }}">{{ _("Upcoming Calendar Events ") }}
+ <span class="badge">({{ event_count }})</span></h4>
<div>
{% for e in events %}
{% if loop.index==1 or events[loop.index-1].date != e.date %}
@@ -124,7 +127,8 @@
<!-- todo list -->
{% if todo_list %}
-<h4 style="{{ section_head }}">{{ _("Open To Do ") }}<span class="badge">({{ todo_count }})</span></h4>
+<h4 style="{{ section_head }}">{{ _("Open To Do ") }}
+ <span class="badge">({{ todo_count }})</span></h4>
<div>
{% for t in todo_list %}
<div style="{{ line_item }}">
diff --git a/erpnext/setup/doctype/naming_series/naming_series.py b/erpnext/setup/doctype/naming_series/naming_series.py
index 33deea4..60a1270 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.py
+++ b/erpnext/setup/doctype/naming_series/naming_series.py
@@ -24,7 +24,8 @@
try:
options = self.get_options(d)
except frappe.DoesNotExistError:
- frappe.pass_does_not_exist_error()
+ frappe.msgprint('Unable to find DocType {0}'.format(d))
+ #frappe.pass_does_not_exist_error()
continue
if options:
diff --git a/erpnext/setup/doctype/notification_control/notification_control.js b/erpnext/setup/doctype/notification_control/notification_control.js
index c8e199b..7f58ede 100644
--- a/erpnext/setup/doctype/notification_control/notification_control.js
+++ b/erpnext/setup/doctype/notification_control/notification_control.js
@@ -9,7 +9,9 @@
frm.set_value("custom_message", frm.doc[frm.events.get_fieldname(frm)]);
},
set_message: function(frm) {
- frm.set_value(frm.events.get_fieldname(frm), frm.doc.custom_message);
+ if(frm.doc.select_transaction && frm.doc.select_transaction !== "") {
+ frm.set_value(frm.events.get_fieldname(frm), frm.doc.custom_message);
+ }
frm.save();
},
get_fieldname: function(frm) {
diff --git a/erpnext/setup/doctype/sales_partner/sales_partner.js b/erpnext/setup/doctype/sales_partner/sales_partner.js
index cb66b7f..143bf44 100644
--- a/erpnext/setup/doctype/sales_partner/sales_partner.js
+++ b/erpnext/setup/doctype/sales_partner/sales_partner.js
@@ -12,9 +12,3 @@
erpnext.utils.render_address_and_contact(cur_frm);
}
}
-
-cur_frm.fields_dict['targets'].grid.get_field("item_group").get_query = function(doc, dt, dn) {
- return{
- filters:{ 'is_group': 0 }
- }
-}
diff --git a/erpnext/setup/doctype/uom/uom.json b/erpnext/setup/doctype/uom/uom.json
index 99f97fe..cea21de 100644
--- a/erpnext/setup/doctype/uom/uom.json
+++ b/erpnext/setup/doctype/uom/uom.json
@@ -1,7 +1,7 @@
{
"allow_copy": 0,
"allow_import": 1,
- "allow_rename": 0,
+ "allow_rename": 1,
"autoname": "field:uom_name",
"beta": 0,
"creation": "2013-01-10 16:34:24",
@@ -15,6 +15,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "uom_name",
"fieldtype": "Data",
"hidden": 0,
@@ -41,6 +42,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Check this to disallow fractions. (for Nos)",
"fieldname": "must_be_whole_number",
"fieldtype": "Check",
@@ -74,7 +76,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-07-25 05:24:25.434534",
+ "modified": "2016-09-23 17:58:21.574996",
"modified_by": "Administrator",
"module": "Setup",
"name": "UOM",
@@ -144,5 +146,6 @@
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
+ "sort_order": "ASC",
"track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py
index 3337b1f..9971baa 100644
--- a/erpnext/setup/install.py
+++ b/erpnext/setup/install.py
@@ -26,7 +26,8 @@
return False
def set_single_defaults():
- for dt in frappe.db.sql_list("""select name from `tabDocType` where issingle=1"""):
+ for dt in ('Accounts Settings', 'Print Settings', 'HR Settings', 'Buying Settings',
+ 'Selling Settings', 'Stock Settings'):
default_values = frappe.db.sql("""select fieldname, `default` from `tabDocField`
where parent=%s""", dt)
if default_values:
@@ -37,6 +38,8 @@
b.save()
except frappe.MandatoryError:
pass
+ except frappe.ValidationError:
+ pass
frappe.db.set_default("date_format", "dd-mm-yyyy")
diff --git a/erpnext/setup/setup_wizard/domainify.py b/erpnext/setup/setup_wizard/domainify.py
index 67d77a8..2b87cc0 100644
--- a/erpnext/setup/setup_wizard/domainify.py
+++ b/erpnext/setup/setup_wizard/domainify.py
@@ -18,7 +18,7 @@
'set_value': [
['Stock Settings', None, 'show_barcode_field', 1]
],
- 'remove_sidebar_items': ['/announcement', '/course', '/assessment', '/fees']
+ 'default_portal_role': 'Customer'
},
'Retail': {
@@ -32,7 +32,7 @@
'set_value': [
['Stock Settings', None, 'show_barcode_field', 1]
],
- 'remove_sidebar_items': ['/announcement', '/course', '/assessment', '/fees']
+ 'default_portal_role': 'Customer'
},
'Distribution': {
@@ -45,7 +45,7 @@
'set_value': [
['Stock Settings', None, 'show_barcode_field', 1]
],
- 'remove_sidebar_items': ['/announcement', '/course', '/assessment', '/fees']
+ 'default_portal_role': 'Customer'
},
'Services': {
@@ -58,13 +58,15 @@
'set_value': [
['Stock Settings', None, 'show_barcode_field', 0]
],
- 'remove_sidebar_items': ['/announcement', '/course', '/assessment', '/fees']
+ 'default_portal_role': 'Customer'
},
'Education': {
'desktop_icons': ['Student', 'Program', 'Course', 'Student Group', 'Instructor',
'Fees', 'ToDo', 'Schools'],
- 'allow_roles': ['Academics User', 'Accounts User', 'Accounts Manager', 'Website Manager'],
- 'allow_sidebar_items': ['/announcement', '/course', '/assessment', '/fees']
+ 'allow_roles': ['Academics User', 'Accounts User', 'Accounts Manager', 'Item Manager',
+ 'Website Manager', 'HR User', 'HR Manager', 'Purchase User', 'Purchase Manager',
+ 'Student'],
+ 'default_portal_role': 'Student'
},
}
if not domain in data:
@@ -79,6 +81,8 @@
setup_properties(data)
set_values(data)
setup_sidebar_items(data)
+ if data.get('default_portal_role'):
+ frappe.db.set_value('Portal Settings', None, 'default_role', data.get('default_portal_role'))
frappe.clear_cache()
def setup_desktop_icons(data):
diff --git a/erpnext/setup/setup_wizard/install_fixtures.py b/erpnext/setup/setup_wizard/install_fixtures.py
index 1f14ddf..a80e6d9 100644
--- a/erpnext/setup/setup_wizard/install_fixtures.py
+++ b/erpnext/setup/setup_wizard/install_fixtures.py
@@ -13,7 +13,6 @@
def install(country=None):
records = [
-
# address template
{'doctype':"Address Template", "country": country},
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json
index 1ab1abe..01924a9 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.json
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.json
@@ -362,7 +362,7 @@
"in_list_view": 0,
"label": "Is Return",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
@@ -389,7 +389,7 @@
"in_list_view": 0,
"label": "Return Against Delivery Note",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"options": "Delivery Note",
"permlevel": 0,
"precision": "",
@@ -2908,7 +2908,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2016-09-16 05:55:36.487662",
+ "modified": "2016-09-23 18:01:54.003673",
"modified_by": "Administrator",
"module": "Stock",
"name": "Delivery Note",
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 454fc70..e9d4cb3 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -567,7 +567,7 @@
existing_allow_negative_stock = frappe.db.get_value("Stock Settings", None, "allow_negative_stock")
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1)
- for warehouse in frappe.db.sql("select name from `tabWarehouse`"):
+ for warehouse in frappe.db.sql("select name from `tabWarehouse` where is_group = 0"):
repost_stock(new_name, warehouse[0])
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", existing_allow_negative_stock)
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index b1f1423..06df636 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -15,9 +15,9 @@
from erpnext.manufacturing.doctype.production_order.production_order import get_item_details
-# form_grid_templates = {
-# "items": "templates/form_grid/material_request_grid.html"
-# }
+form_grid_templates = {
+ "items": "templates/form_grid/material_request_grid.html"
+}
class MaterialRequest(BuyingController):
def get_feed(self):
@@ -75,7 +75,7 @@
pc_obj = frappe.get_doc('Purchase Common')
pc_obj.validate_for_items(self)
- self.set_title()
+ # self.set_title()
# self.validate_qty_against_so()
diff --git a/erpnext/stock/doctype/material_request/test_material_request.py b/erpnext/stock/doctype/material_request/test_material_request.py
index ebdfa5a..8f43acd 100644
--- a/erpnext/stock/doctype/material_request/test_material_request.py
+++ b/erpnext/stock/doctype/material_request/test_material_request.py
@@ -66,7 +66,6 @@
"posting_date": "2013-03-01",
"posting_time": "00:00:00",
"purpose": "Material Receipt",
- "fiscal_year": "_Test Fiscal Year 2013",
"items": [
{
"conversion_factor": 1.0,
@@ -79,6 +78,7 @@
"transfer_qty": qty1,
"uom": "_Test UOM 1",
"t_warehouse": warehouse or "_Test Warehouse 1 - _TC",
+ "cost_center": "_Test Cost Center - _TC"
},
{
"conversion_factor": 1.0,
@@ -91,6 +91,7 @@
"transfer_qty": qty2,
"uom": "_Test UOM 1",
"t_warehouse": warehouse or "_Test Warehouse 1 - _TC",
+ "cost_center": "_Test Cost Center - _TC"
}
]
})
diff --git a/erpnext/stock/doctype/material_request_item/material_request_item.json b/erpnext/stock/doctype/material_request_item/material_request_item.json
index dd087c4..f7ca7d9 100644
--- a/erpnext/stock/doctype/material_request_item/material_request_item.json
+++ b/erpnext/stock/doctype/material_request_item/material_request_item.json
@@ -343,7 +343,7 @@
"bold": 1,
"collapsible": 0,
"columns": 2,
- "default": "Today",
+ "default": "",
"fieldname": "schedule_date",
"fieldtype": "Date",
"hidden": 0,
@@ -705,7 +705,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-09-18 14:38:38.517137",
+ "modified": "2016-10-17 04:58:33.317145",
"modified_by": "Administrator",
"module": "Stock",
"name": "Material Request Item",
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
index f10b634..0a6ec9f 100755
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
@@ -9,11 +9,13 @@
"docstatus": 0,
"doctype": "DocType",
"document_type": "Document",
+ "editable_grid": 1,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "supplier_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -39,6 +41,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
@@ -65,6 +68,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "{supplier_name}",
"fieldname": "title",
"fieldtype": "Data",
@@ -91,6 +95,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "",
"fieldname": "naming_series",
"fieldtype": "Select",
@@ -119,6 +124,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
+ "columns": 0,
"fieldname": "supplier",
"fieldtype": "Link",
"hidden": 0,
@@ -148,6 +154,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
+ "columns": 0,
"depends_on": "supplier",
"fieldname": "supplier_name",
"fieldtype": "Data",
@@ -173,6 +180,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -199,6 +207,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "Today",
"fieldname": "posting_date",
"fieldtype": "Date",
@@ -228,6 +237,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Time at which materials were received",
"fieldname": "posting_time",
"fieldtype": "Time",
@@ -257,6 +267,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "",
"fieldname": "company",
"fieldtype": "Link",
@@ -287,6 +298,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "is_return",
"fieldtype": "Check",
"hidden": 0,
@@ -296,7 +308,7 @@
"in_list_view": 0,
"label": "Is Return",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
@@ -312,6 +324,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "is_return",
"fieldname": "return_against",
"fieldtype": "Link",
@@ -322,7 +335,7 @@
"in_list_view": 0,
"label": "Return Against Purchase Receipt",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"options": "Purchase Receipt",
"permlevel": 0,
"precision": "",
@@ -339,6 +352,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
+ "columns": 0,
"fieldname": "section_addresses",
"fieldtype": "Section Break",
"hidden": 0,
@@ -364,6 +378,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "supplier_address",
"fieldtype": "Link",
"hidden": 0,
@@ -389,6 +404,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "contact_person",
"fieldtype": "Link",
"hidden": 0,
@@ -414,6 +430,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "address_display",
"fieldtype": "Small Text",
@@ -439,6 +456,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "contact_display",
"fieldtype": "Small Text",
"hidden": 0,
@@ -463,6 +481,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "contact_mobile",
"fieldtype": "Small Text",
"hidden": 0,
@@ -487,6 +506,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "contact_email",
"fieldtype": "Small Text",
"hidden": 0,
@@ -511,6 +531,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "col_break_address",
"fieldtype": "Column Break",
"hidden": 0,
@@ -535,6 +556,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "shipping_address",
"fieldtype": "Link",
@@ -562,6 +584,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "shipping_address_display",
"fieldtype": "Small Text",
"hidden": 0,
@@ -587,6 +610,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
+ "columns": 0,
"fieldname": "currency_and_price_list",
"fieldtype": "Section Break",
"hidden": 0,
@@ -612,6 +636,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "currency",
"fieldtype": "Link",
"hidden": 0,
@@ -639,6 +664,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Rate at which supplier's currency is converted to company's base currency",
"fieldname": "conversion_rate",
"fieldtype": "Float",
@@ -667,6 +693,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break2",
"fieldtype": "Column Break",
"hidden": 0,
@@ -693,6 +720,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "buying_price_list",
"fieldtype": "Link",
"hidden": 0,
@@ -718,6 +746,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "buying_price_list",
"fieldname": "price_list_currency",
"fieldtype": "Link",
@@ -744,6 +773,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"depends_on": "buying_price_list",
"fieldname": "plc_conversion_rate",
"fieldtype": "Float",
@@ -770,6 +800,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "ignore_pricing_rule",
"fieldtype": "Check",
"hidden": 0,
@@ -794,6 +825,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "items_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -820,6 +852,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "items",
"fieldtype": "Table",
"hidden": 0,
@@ -847,6 +880,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "get_current_stock",
"fieldtype": "Button",
"hidden": 0,
@@ -873,6 +907,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "section_break0",
"fieldtype": "Section Break",
"hidden": 0,
@@ -897,6 +932,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "base_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -923,6 +959,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "base_net_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -952,6 +989,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_27",
"fieldtype": "Column Break",
"hidden": 0,
@@ -975,6 +1013,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1001,6 +1040,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "net_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1028,6 +1068,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Add / Edit Taxes and Charges",
"fieldname": "taxes_section",
"fieldtype": "Section Break",
@@ -1055,6 +1096,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "",
"fieldname": "taxes_and_charges",
"fieldtype": "Link",
@@ -1083,6 +1125,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "taxes",
"fieldtype": "Table",
"hidden": 0,
@@ -1110,6 +1153,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "other_charges_calculation",
"fieldtype": "HTML",
"hidden": 0,
@@ -1135,6 +1179,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "",
"fieldname": "totals",
"fieldtype": "Section Break",
@@ -1162,6 +1207,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "base_taxes_and_charges_added",
"fieldtype": "Currency",
"hidden": 0,
@@ -1189,6 +1235,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "base_taxes_and_charges_deducted",
"fieldtype": "Currency",
"hidden": 0,
@@ -1216,6 +1263,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "base_total_taxes_and_charges",
"fieldtype": "Currency",
"hidden": 0,
@@ -1243,6 +1291,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break3",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1268,6 +1317,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "taxes_and_charges_added",
"fieldtype": "Currency",
"hidden": 0,
@@ -1295,6 +1345,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "taxes_and_charges_deducted",
"fieldtype": "Currency",
"hidden": 0,
@@ -1322,6 +1373,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "total_taxes_and_charges",
"fieldtype": "Currency",
"hidden": 0,
@@ -1349,6 +1401,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "discount_amount",
+ "columns": 0,
"fieldname": "section_break_42",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1374,6 +1427,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "Grand Total",
"fieldname": "apply_discount_on",
"fieldtype": "Select",
@@ -1401,6 +1455,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "base_discount_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1427,6 +1482,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_44",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1451,6 +1507,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "additional_discount_percentage",
"fieldtype": "Float",
"hidden": 0,
@@ -1476,6 +1533,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "discount_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1502,6 +1560,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "section_break_46",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1526,6 +1585,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "base_grand_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1553,6 +1613,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "",
"fieldname": "base_in_words",
"fieldtype": "Data",
@@ -1580,6 +1641,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "base_rounded_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1607,6 +1669,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_50",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1631,6 +1694,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "grand_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1658,6 +1722,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "in_words",
"fieldtype": "Data",
"hidden": 0,
@@ -1685,6 +1750,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "terms",
+ "columns": 0,
"fieldname": "terms_section_break",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1711,6 +1777,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "tc_name",
"fieldtype": "Link",
"hidden": 0,
@@ -1738,6 +1805,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "terms",
"fieldtype": "Text Editor",
"hidden": 0,
@@ -1765,6 +1833,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "supplied_items",
+ "columns": 0,
"description": "",
"fieldname": "raw_material_details",
"fieldtype": "Section Break",
@@ -1792,6 +1861,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "No",
"description": "",
"fieldname": "is_subcontracted",
@@ -1821,6 +1891,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "",
"fieldname": "supplier_warehouse",
"fieldtype": "Link",
@@ -1851,6 +1922,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "supplied_items",
"fieldtype": "Table",
"hidden": 0,
@@ -1878,6 +1950,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "bill_no",
"fieldtype": "Data",
"hidden": 1,
@@ -1904,6 +1977,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "bill_date",
"fieldtype": "Date",
"hidden": 1,
@@ -1930,6 +2004,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
+ "columns": 0,
"fieldname": "more_info",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1956,6 +2031,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"default": "Draft",
"fieldname": "status",
"fieldtype": "Select",
@@ -1986,6 +2062,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Warehouse where you are maintaining stock of rejected items",
"fieldname": "rejected_warehouse",
"fieldtype": "Link",
@@ -2014,6 +2091,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 1,
@@ -2043,6 +2121,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "range",
"fieldtype": "Data",
"hidden": 1,
@@ -2069,6 +2148,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break4",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2095,6 +2175,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "per_billed",
"fieldtype": "Percent",
"hidden": 0,
@@ -2120,6 +2201,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
+ "columns": 0,
"fieldname": "printing_settings",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2145,6 +2227,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "letter_head",
"fieldtype": "Link",
"hidden": 0,
@@ -2170,6 +2253,7 @@
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "select_print_heading",
"fieldtype": "Link",
"hidden": 0,
@@ -2197,6 +2281,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "language",
"fieldtype": "Data",
"hidden": 0,
@@ -2222,6 +2307,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "other_details",
"fieldtype": "HTML",
"hidden": 1,
@@ -2250,6 +2336,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "instructions",
"fieldtype": "Small Text",
"hidden": 0,
@@ -2276,6 +2363,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "remarks",
"fieldtype": "Small Text",
"hidden": 0,
@@ -2301,6 +2389,7 @@
"bold": 0,
"collapsible": 1,
"collapsible_depends_on": "transporter_name",
+ "columns": 0,
"fieldname": "transporter_info",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2326,6 +2415,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "transporter_name",
"fieldtype": "Data",
"hidden": 0,
@@ -2352,6 +2442,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break5",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2377,6 +2468,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "",
"fieldname": "lr_no",
"fieldtype": "Data",
@@ -2406,6 +2498,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "",
"fieldname": "lr_date",
"fieldtype": "Date",
@@ -2444,7 +2537,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2016-06-30 13:42:23.310309",
+ "modified": "2016-09-23 18:02:17.332333",
"modified_by": "Administrator",
"module": "Stock",
"name": "Purchase Receipt",
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 20630b2..6d6ae97 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -4,9 +4,9 @@
from __future__ import unicode_literals
import frappe
-from frappe.utils import flt, cint
+from frappe.utils import flt, cint, nowdate
-from frappe import _
+from frappe import throw, _
import frappe.defaults
from erpnext.controllers.buying_controller import BuyingController
@@ -58,6 +58,10 @@
pc_obj = frappe.get_doc('Purchase Common')
self.check_for_closed_status(pc_obj)
+
+ if self.posting_date > nowdate():
+ throw(_("Posting Date cannot be future date"))
+
def validate_with_previous_doc(self):
super(PurchaseReceipt, self).validate_with_previous_doc({
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 7c9e1e6..85166a6 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -348,6 +348,7 @@
}
cur_frm.cscript.purpose = function(doc, cdt, cdn) {
+ cur_frm.fields_dict.items.grid.refresh();
cur_frm.cscript.toggle_related_fields(doc);
}
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
index c70613b..2b031d1 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
@@ -75,6 +75,9 @@
frappe.model.set_value(cdt, cdn, "valuation_rate", r.message.rate);
frappe.model.set_value(cdt, cdn, "current_qty", r.message.qty);
frappe.model.set_value(cdt, cdn, "current_valuation_rate", r.message.rate);
+ frappe.model.set_value(cdt, cdn, "current_amount", r.message.rate * r.message.qty);
+ frappe.model.set_value(cdt, cdn, "amount", r.message.rate * r.message.qty);
+
}
});
}
@@ -92,7 +95,15 @@
}
});
}
- }
+ },
+ set_amount_quantity: function(doc, cdt, cdn) {
+ var d = frappe.model.get_doc(cdt, cdn);
+ if (d.qty & d.valuation_rate) {
+ frappe.model.set_value(cdt, cdn, "amount", flt(d.qty) * flt(d.valuation_rate));
+ frappe.model.set_value(cdt, cdn, "quantity_difference", flt(d.qty) - flt(d.current_qty));
+ frappe.model.set_value(cdt, cdn, "amount_difference", flt(d.amount) - flt(d.current_amount));
+ }
+ }
});
frappe.ui.form.on("Stock Reconciliation Item", {
@@ -104,7 +115,14 @@
},
item_code: function(frm, cdt, cdn) {
frm.events.set_valuation_rate_and_qty(frm, cdt, cdn);
+ },
+ qty: function(frm, cdt, cdn) {
+ frm.events.set_amount_quantity(frm, cdt, cdn);
+ },
+ valuation_rate: function(frm, cdt, cdn) {
+ frm.events.set_amount_quantity(frm, cdt, cdn);
}
+
});
erpnext.stock.StockReconciliation = erpnext.stock.StockController.extend({
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json
index 291f14d..0c1c10c 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json
@@ -389,7 +389,7 @@
"istable": 0,
"max_attachments": 1,
"menu_index": 0,
- "modified": "2016-09-02 04:09:18.909485",
+ "modified": "2016-10-05 13:03:39.887647",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock Reconciliation",
@@ -405,6 +405,7 @@
"export": 0,
"if_owner": 0,
"import": 0,
+ "is_custom": 0,
"permlevel": 0,
"print": 0,
"read": 1,
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index 0f5cb96..4ab49e5 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -27,6 +27,7 @@
self.remove_items_with_no_change()
self.validate_data()
self.validate_expense_account()
+ self.set_total_qty_and_amount()
def on_submit(self):
self.update_stock_ledger()
@@ -236,6 +237,13 @@
elif not frappe.db.sql("""select name from `tabStock Ledger Entry` limit 1"""):
if frappe.db.get_value("Account", self.expense_account, "report_type") == "Profit and Loss":
frappe.throw(_("Difference Account must be a Asset/Liability type account, since this Stock Reconciliation is an Opening Entry"), OpeningEntryAccountError)
+
+ def set_total_qty_and_amount(self):
+ for d in self.get("items"):
+ d.amount = flt(d.qty) * flt(d.valuation_rate)
+ d.current_amount = flt(d.current_qty) * flt(d.current_valuation_rate)
+ d.quantity_difference = flt(d.qty) - flt(d.current_qty)
+ d.amount_difference = flt(d.amount) - flt(d.current_amount)
def get_items_for(self, warehouse):
self.items = []
diff --git a/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json b/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
index efd0dee..5452aa1 100644
--- a/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
+++ b/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
@@ -173,7 +173,7 @@
"bold": 0,
"collapsible": 0,
"columns": 2,
- "description": "Do not include symbols (ex. $)",
+ "description": "",
"fieldname": "valuation_rate",
"fieldtype": "Currency",
"hidden": 0,
@@ -200,6 +200,32 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "amount",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Amount",
+ "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,
+ "columns": 0,
"fieldname": "section_break_3",
"fieldtype": "Section Break",
"hidden": 0,
@@ -207,6 +233,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "label": "Before reconciliation",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -225,7 +252,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "description": "Before reconciliation",
+ "description": "",
"fieldname": "current_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -277,9 +304,9 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "description": "Before reconciliation",
+ "description": "",
"fieldname": "current_valuation_rate",
- "fieldtype": "Read Only",
+ "fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -298,6 +325,135 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "",
+ "fieldname": "current_amount",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Current Amount",
+ "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,
+ "columns": 0,
+ "fieldname": "section_break_14",
+ "fieldtype": "Section 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,
+ "columns": 0,
+ "fieldname": "quantity_difference",
+ "fieldtype": "Read Only",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Quantity Difference",
+ "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,
+ "columns": 0,
+ "fieldname": "column_break_16",
+ "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,
+ "columns": 0,
+ "fieldname": "amount_difference",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Amount Difference",
+ "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
}
],
"hide_heading": 0,
@@ -311,7 +467,7 @@
"istable": 1,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2016-09-05 07:10:19.571562",
+ "modified": "2016-09-28 06:43:53.764287",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock Reconciliation Item",
diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py
index e371d70..8e7941c 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.py
+++ b/erpnext/stock/doctype/warehouse/warehouse.py
@@ -71,7 +71,7 @@
"freeze_account": "No"
})
ac_doc.flags.ignore_permissions = True
-
+ ac_doc.flags.ignore_mandatory = True
try:
ac_doc.insert()
msgprint(_("Account head {0} created").format(ac_doc.name))
@@ -150,7 +150,10 @@
return new_warehouse
def rename_account_for(self, olddn, newdn, merge):
- old_account = self.get_account(olddn)
+ if self.is_group:
+ old_account = self.get_account()
+ else:
+ old_account = self.get_account(olddn)
if old_account:
new_account = None
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 1e3bd8a..e5dd735 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -328,10 +328,11 @@
@frappe.whitelist()
def get_pos_profile(company):
+ condition = "and company = '%s'"%(company) if company else ''
pos_profile = frappe.db.sql("""select * from `tabPOS Profile` where user = %s
- and company = %s""", (frappe.session['user'], company), as_dict=1)
+ {cond}""".format(cond=condition), (frappe.session['user']), as_dict=1)
- if not pos_profile:
+ if not pos_profile and company:
pos_profile = frappe.db.sql("""select * from `tabPOS Profile`
where ifnull(user,'') = '' and company = %s""", company, as_dict=1)
diff --git a/erpnext/stock/stock_balance.py b/erpnext/stock/stock_balance.py
index 22fa12a..096f6c0 100644
--- a/erpnext/stock/stock_balance.py
+++ b/erpnext/stock/stock_balance.py
@@ -230,7 +230,7 @@
pass
def repost_all_stock_vouchers():
- warehouses_with_account = frappe.db.sql_list("""select master_name from tabAccount
+ warehouses_with_account = frappe.db.sql_list("""select warehouse from tabAccount
where ifnull(account_type, '') = 'Stock' and (warehouse is not null and warehouse != '')
and is_group=0""")
@@ -244,7 +244,7 @@
i = 0
for voucher_type, voucher_no in vouchers:
i+=1
- print i, "/", len(vouchers)
+ print i, "/", len(vouchers), voucher_type, voucher_no
try:
for dt in ["Stock Ledger Entry", "GL Entry"]:
frappe.db.sql("""delete from `tab%s` where voucher_type=%s and voucher_no=%s"""%
diff --git a/erpnext/support/doctype/warranty_claim/warranty_claim.js b/erpnext/support/doctype/warranty_claim/warranty_claim.js
index cf9d806..9fed265 100644
--- a/erpnext/support/doctype/warranty_claim/warranty_claim.js
+++ b/erpnext/support/doctype/warranty_claim/warranty_claim.js
@@ -37,7 +37,7 @@
cur_frm.cscript.onload = function(doc,cdt,cdn){
if(!doc.status)
- set_multiple(dt,dn,{status:'Open'});
+ set_multiple(cdt,cdn,{status:'Open'});
}
cur_frm.fields_dict['customer_address'].get_query = function(doc, cdt, cdn) {
diff --git a/erpnext/support/doctype/warranty_claim/warranty_claim.py b/erpnext/support/doctype/warranty_claim/warranty_claim.py
index b4427be..a3428a2 100644
--- a/erpnext/support/doctype/warranty_claim/warranty_claim.py
+++ b/erpnext/support/doctype/warranty_claim/warranty_claim.py
@@ -19,7 +19,7 @@
if session['user'] != 'Guest' and not self.customer:
frappe.throw(_("Customer is required"))
- if self.status=="Closed" and \
+ if self.status=="Closed" and not self.resolution_date and \
frappe.db.get_value("Warranty Claim", self.name, "status")!="Closed":
self.resolution_date = now_datetime()
diff --git a/erpnext/templates/emails/request_for_quotation.html b/erpnext/templates/emails/request_for_quotation.html
index aedd8e2..b4dfb88 100644
--- a/erpnext/templates/emails/request_for_quotation.html
+++ b/erpnext/templates/emails/request_for_quotation.html
@@ -4,8 +4,8 @@
<p>{{_("Please click on the following link to set your new password")}}:</p>
<p><a href="{{ update_password_link }}">{{ update_password_link }}</a></p>
{% else %}
-<p>{{_("Request for quotation can be access by clicking following link")}}:</p>
+<p>{{_("The request for quotation can be accessed by clicking on the following link")}}:</p>
<p><a href="{{ rfq_link }}">Submit your Quotation</a></p>
{% endif %}
<p>{{_("Thank you")}},<br>
-{{ user_fullname }}</p>
\ No newline at end of file
+{{ user_fullname }}</p>
diff --git a/erpnext/templates/form_grid/material_request_grid.html b/erpnext/templates/form_grid/material_request_grid.html
new file mode 100644
index 0000000..866c06e
--- /dev/null
+++ b/erpnext/templates/form_grid/material_request_grid.html
@@ -0,0 +1,49 @@
+{% var visible_columns = row.get_visible_columns(["item_code", "warehouse",
+ "item_name", "amount", "stock_uom", "uom", "qty", "schedule_date"]); %}
+
+{% if(!doc) { %}
+ <div class="row">
+ <div class="col-sm-4">{%= __("Item") %}</div>
+ <div class="col-sm-3">{%= __("Required On") %}</div>
+ <div class="col-sm-3">{%= __("Warehouse") %}</div>
+ <div class="col-sm-2 text-right">{%= __("Qty") %}</div>
+ </div>
+{% } else { %}
+ <div class="row">
+ <div class="col-sm-4">
+ <span class="indicator {%= (doc.qty<=doc.ordered_qty) ? "green" : "orange" %}">{%= doc.item_code %}</strong>
+ {% if(doc.item_name != doc.item_code) { %}
+ <br>{%= doc.item_name %}{% } %}
+ <!-- {% if(doc.item_name != doc.description) { %}
+ <p>{%= doc.description %}</p>{% } %} -->
+ {% include "templates/form_grid/includes/visible_cols.html" %}
+ </div>
+
+
+ <div class="col-sm-3">
+ {% if(doc.schedule_date) { %}
+ <span title="{%= __("Reqd By Date") %}" class="{%=
+ (frappe.datetime.get_diff(doc.schedule_date, frappe.datetime.get_today()) < 0
+ && doc.ordered_qty < doc.qty)
+ ? "text-danger" : "text-muted" %}">
+ {%= doc.get_formatted("schedule_date") %}</span>
+ {% } %}
+ </div>
+
+ <!-- warehouse -->
+ <div class="col-sm-3">
+ {% if(doc.warehouse) { %}
+ <span class="label label-default" title="{%= __("For Warehouse") %}"
+ style="margin-right: 10px;">
+ {%= doc.warehouse %}
+ </span>
+ {% } %}
+ </div>
+
+ <!-- qty -->
+ <div class="col-sm-2 text-right">
+ {%= doc.get_formatted("qty") %}
+ <span class="small">{%= doc.uom || doc.stock_uom %}</span>
+ </div>
+ </div>
+{% } %}
diff --git a/erpnext/templates/generators/student_admission.html b/erpnext/templates/generators/student_admission.html
index 7eb9226..ae70df8 100644
--- a/erpnext/templates/generators/student_admission.html
+++ b/erpnext/templates/generators/student_admission.html
@@ -16,38 +16,10 @@
<div>{{ introduction }}</div>
{% endif %}
-{%- if eligibility -%}
-<h3> Eligibility </h3>
-<div>{{ eligibility }}</div>
-{% endif %}
-
-<table class="table table-bordered" style="margin-top: 20px; width: 30%">
- <tr>
- <th> Program</th>
- <td>{{ program }} </td>
- </tr>
- <tr>
- <th> Academic Year</th>
- <td>{{ academic_year }} </td>
- </tr>
- <tr>
- <th> Admission Start Date</th>
- <td>{{ frappe.utils.formatdate(admission_start_date) }}</td>
- </tr>
- <tr>
- <th> Admission End Date</th>
- <td>{{ frappe.utils.formatdate(admission_end_date) }}</td>
- </tr>
- <tr>
- <th> Application Fee</th>
- <td>{{ frappe.utils.fmt_money(application_fee, 2, currency) }}</td>
- </tr>
-</table>
-
{%- if application_form_route -%}
<p>
<a class='btn btn-primary'
- href='/{{ doc.application_form_route }}?program={{ doc.program }}&academic_year={{ doc.academic_year }}&new=1'>
+ href='/{{ doc.application_form_route }}'>
{{ _("Apply Now") }}</a>
</p>
{% endif %}
diff --git a/erpnext/templates/includes/navbar/navbar_items.html b/erpnext/templates/includes/navbar/navbar_items.html
index c7af2fd..f0c780d 100644
--- a/erpnext/templates/includes/navbar/navbar_items.html
+++ b/erpnext/templates/includes/navbar/navbar_items.html
@@ -1,7 +1,7 @@
{% extends 'frappe/templates/includes/navbar/navbar_items.html' %}
{% block navbar_right_extension %}
- <li class="shopping-cart">
+ <li class="shopping-cart hidden">
<div class="cart-icon small">
<a class="dropdown-toggle" href="#" data-toggle="dropdown" id="navLogin">
Cart <span class="badge-wrapper" id="cart-count"></span>
diff --git a/erpnext/templates/includes/rfq.js b/erpnext/templates/includes/rfq.js
index c63226c..46357d4 100644
--- a/erpnext/templates/includes/rfq.js
+++ b/erpnext/templates/includes/rfq.js
@@ -18,6 +18,7 @@
this.change_rate();
this.terms();
this.submit_rfq();
+ this.navigate_quotations();
},
onfocus_select_all: function(){
@@ -81,10 +82,20 @@
},
btn: this,
callback: function(r){
- $('.btn-sm').hide()
frappe.unfreeze();
+ if(r.message){
+ $('.btn-sm').hide()
+ window.location.href = "/quotations/" + encodeURIComponent(r.message);
+ }
}
})
})
+ },
+
+ navigate_quotations: function() {
+ $('.quotations').click(function(){
+ name = $(this).attr('idx')
+ window.location.href = "/quotations/" + encodeURIComponent(name);
+ })
}
})
diff --git a/erpnext/templates/pages/order.py b/erpnext/templates/pages/order.py
index d390ebf..296b907 100644
--- a/erpnext/templates/pages/order.py
+++ b/erpnext/templates/pages/order.py
@@ -14,10 +14,10 @@
context.doc.set_indicator()
context.parents = frappe.form_dict.parents
- context.payment_ref = frappe.db.get_value("Payment Request",
+ context.payment_ref = frappe.db.get_value("Payment Request",
{"reference_name": frappe.form_dict.name}, "name")
-
+
context.enabled_checkout = frappe.get_doc("Shopping Cart Settings").enable_checkout
-
- if not context.doc.has_website_permission("read"):
+
+ if not frappe.has_website_permission(context.doc):
frappe.throw(_("Not Permitted"), frappe.PermissionError)
diff --git a/erpnext/templates/pages/rfq.html b/erpnext/templates/pages/rfq.html
index b151987..591d046 100644
--- a/erpnext/templates/pages/rfq.html
+++ b/erpnext/templates/pages/rfq.html
@@ -34,16 +34,16 @@
<div id="rfq-items">
<div class="row cart-item-header">
<div class="col-sm-5 col-xs-12">
- Items
+ {{ _("Items") }}
</div>
<div class="col-sm-2 col-xs-4 text-right">
- Qty
+ {{ _("Qty") }}
</div>
<div class="col-sm-2 col-xs-4 text-right">
- Rate
+ {{ _("Rate") }}
</div>
<div class="col-sm-3 col-xs-4 text-right">
- Amount
+ {{ _("Amount") }}
</div>
</div>
<hr>
@@ -68,6 +68,31 @@
<textarea class="form-control terms-feedback" style="height: 100px;"></textarea>
</div>
</div>
+ <hr>
+ <div class="row">
+ <div class="result">
+ <div class="col-xs-12">
+ <p class="text-muted small">{{ _("Quotations: ") }}</p>
+ {% if doc.rfq_links %}
+ {% for d in doc.rfq_links %}
+ <div class="web-list-item transaction-list-item quotations" idx="{{d.name}}">
+ <div class="row">
+ <div class="col-sm-6">
+ <span class="indicator darkgrey"><a href="/quotations/{{d.name}}">{{d.name}}</a></span>
+ </div>
+ <div class="col-sm-3">
+ <span class="small darkgrey">{{d.status}}</span>
+ </div>
+ <div class="col-sm-3">
+ <span class="small darkgrey">{{d.transaction_date}}</span>
+ </div>
+ </div>
+ </div>
+ {% endfor %}
+ {% endif %}
+ </div>
+ </div>
+ </div>
</div>
</div>
diff --git a/erpnext/templates/pages/rfq.py b/erpnext/templates/pages/rfq.py
index decae41..abc2890 100644
--- a/erpnext/templates/pages/rfq.py
+++ b/erpnext/templates/pages/rfq.py
@@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
from frappe import _
+from frappe.utils import formatdate
from erpnext.controllers.website_list_for_contact import (get_customers_suppliers,
get_party_details)
@@ -13,6 +14,7 @@
context.doc = frappe.get_doc(frappe.form_dict.doctype, frappe.form_dict.name)
context.parents = frappe.form_dict.parents
context.doc.supplier = get_supplier()
+ context.doc.rfq_links = get_link_quotation(context.doc.supplier, context.doc.name)
unauthorized_user(context.doc.supplier)
update_supplier_details(context)
context["title"] = frappe.form_dict.name
@@ -41,4 +43,18 @@
context.doc.currency = supplier_doc.default_currency or frappe.db.get_value("Company", context.doc.company, "default_currency")
context.doc.currency_symbol = frappe.db.get_value("Currency", context.doc.currency, "symbol")
context.doc.number_format = frappe.db.get_value("Currency", context.doc.currency, "number_format")
- context.doc.buying_price_list = supplier_doc.default_price_list or ''
\ No newline at end of file
+ context.doc.buying_price_list = supplier_doc.default_price_list or ''
+
+def get_link_quotation(supplier, rfq):
+ quotation = frappe.db.sql(""" select distinct `tabSupplier Quotation Item`.parent as name,
+ `tabSupplier Quotation`.status, `tabSupplier Quotation`.transaction_date from
+ `tabSupplier Quotation Item`, `tabSupplier Quotation` where `tabSupplier Quotation`.docstatus < 2 and
+ `tabSupplier Quotation Item`.request_for_quotation =%(name)s and
+ `tabSupplier Quotation Item`.parent = `tabSupplier Quotation`.name and
+ `tabSupplier Quotation`.supplier = %(supplier)s order by `tabSupplier Quotation`.creation desc""",
+ {'name': rfq, 'supplier': supplier}, as_dict=1)
+
+ for data in quotation:
+ data.transaction_date = formatdate(data.transaction_date)
+
+ return quotation or None
diff --git a/erpnext/templates/print_formats/includes/item_table_description.html b/erpnext/templates/print_formats/includes/item_table_description.html
index e8a98f0..16e98e0 100644
--- a/erpnext/templates/print_formats/includes/item_table_description.html
+++ b/erpnext/templates/print_formats/includes/item_table_description.html
@@ -3,8 +3,7 @@
{% if doc.in_format_data("image") and doc.get("image") and not doc.is_print_hide("image")-%}
<div class="pull-left" style="width: 20%; margin-right: 10px;">
- <div class="square-image" style="background-image: url('{{ doc.image }}')">
- </div>
+ <img class="print-item-image" src="{{ doc.image }}" alt="">
</div>
{%- endif %}
diff --git a/erpnext/translations/fr.csv b/erpnext/translations/fr.csv
index 6292472..577bdf7 100644
--- a/erpnext/translations/fr.csv
+++ b/erpnext/translations/fr.csv
@@ -413,7 +413,7 @@
DocType: Account,Cost of Goods Sold,Coût des marchandises vendues
DocType: Purchase Invoice,Yearly,Annuel
apps/erpnext/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +225,Please enter Cost Center,S'il vous plaît entrer Centre de coûts
-DocType: Journal Entry Account,Sales Order,Bon de commande
+DocType: Journal Entry Account,Sales Order,commande client
apps/erpnext/erpnext/accounts/report/gross_profit/gross_profit.py +68,Avg. Selling Rate,Moy. Taux de vente
DocType: Assessment,Examiner Name,Nom de l'examinateur
apps/erpnext/erpnext/utilities/transaction_base.py +149,Quantity cannot be a fraction in row {0},La quantité ne peut pas être une fraction à la ligne {0}
@@ -1007,7 +1007,7 @@
DocType: GL Entry,Against,Contre
DocType: Item,Default Selling Cost Center,Coût des marchandises vendues
DocType: Sales Partner,Implementation Partner,Partenaire de mise en œuvre
-apps/erpnext/erpnext/controllers/selling_controller.py +231,Sales Order {0} is {1},Bon de commande {0} est {1}
+apps/erpnext/erpnext/controllers/selling_controller.py +231,Sales Order {0} is {1},commande client {0} est {1}
DocType: Opportunity,Contact Info,Information de contact
apps/erpnext/erpnext/config/stock.py +299,Making Stock Entries,Faire des entrées stock
DocType: Packing Slip,Net Weight UOM,Unité de mesure Poids Net
@@ -1152,7 +1152,7 @@
,Accounts Payable Summary,Le résumé des comptes à payer
apps/erpnext/erpnext/accounts/doctype/gl_entry/gl_entry.py +196,Not authorized to edit frozen Account {0},N'êtes pas autorisé à modifier le compte gelé {0}
DocType: Journal Entry,Get Outstanding Invoices,Obtenez les factures impayées
-apps/erpnext/erpnext/manufacturing/doctype/production_order/production_order.py +62,Sales Order {0} is not valid,Bon de commande {0} invalide
+apps/erpnext/erpnext/manufacturing/doctype/production_order/production_order.py +62,Sales Order {0} is not valid,commande client {0} invalide
apps/erpnext/erpnext/setup/doctype/company/company.py +185,"Sorry, companies cannot be merged","Désolé , les entreprises ne peuvent pas être fusionnés"
apps/erpnext/erpnext/stock/doctype/material_request/material_request.py +139,"The total Issue / Transfer quantity {0} in Material Request {1} \
cannot be greater than requested quantity {2} for Item {3}",La quantité Problème / transfert total {0} dans Material Request {1} \ ne peut pas être supérieure à la quantité demandée {2} pour le poste {3}
@@ -1607,7 +1607,7 @@
apps/erpnext/erpnext/controllers/buying_controller.py +300,Row #{0}: Rejected Warehouse is mandatory against rejected Item {1},Row # {0}: Entrepôt Rejeté est obligatoire contre Item rejeté {1}
apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +731,Payment,Paiement
DocType: Production Order Operation,Actual Time and Cost,Temps réel et coût
-apps/erpnext/erpnext/stock/doctype/material_request/material_request.py +54,Material Request of maximum {0} can be made for Item {1} against Sales Order {2},Demande de Matériel d'un maximum de {0} peut être faite pour l'article {1} par rapport au bon de commande {2}
+apps/erpnext/erpnext/stock/doctype/material_request/material_request.py +54,Material Request of maximum {0} can be made for Item {1} against Sales Order {2},Demande de Matériel d'un maximum de {0} peut être faite pour l'article {1} par rapport au commande client {2}
DocType: Employee,Salutation,Titre
DocType: Pricing Rule,Brand,Marque
DocType: Course,Course Abbreviation,Abréviation de cours
@@ -1883,7 +1883,7 @@
DocType: Quality Inspection,In Process,En cours
DocType: Authorization Rule,Itemwise Discount,Remise (par Article)
apps/erpnext/erpnext/config/accounts.py +69,Tree of financial accounts.,Arbre des comptes financiers.
-apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +334,{0} against Sales Order {1},{0} contre le bon de commande de vente {1}
+apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +334,{0} against Sales Order {1},{0} contre le commande client de vente {1}
DocType: Account,Fixed Asset,Actifs immobilisés
apps/erpnext/erpnext/config/stock.py +304,Serialized Inventory,Inventaire sérialisé
DocType: Activity Type,Default Billing Rate,Prix facturation par défaut
@@ -2182,7 +2182,7 @@
DocType: Purchase Receipt Item,Recd Quantity,Quantité reçue
apps/erpnext/erpnext/schools/doctype/program_enrollment/program_enrollment.py +54,Fee Records Created - {0},Records Fee Créé - {0}
DocType: Asset Category Account,Asset Category Account,Catégorie d'actif compte
-apps/erpnext/erpnext/manufacturing/doctype/production_order/production_order.py +103,Cannot produce more Item {0} than Sales Order quantity {1},Ne peut pas produire plus d'article {0} que de la qté du bon de commande {1}
+apps/erpnext/erpnext/manufacturing/doctype/production_order/production_order.py +103,Cannot produce more Item {0} than Sales Order quantity {1},Ne peut pas produire plus d'article {0} que de la qté du commande client {1}
apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +504,Stock Entry {0} is not submitted,Entrée stock {0} est pas soumis
DocType: Payment Reconciliation,Bank / Cash Account,Banque et liquidités
DocType: Tax Rule,Billing City,Ville de facturation
@@ -2532,7 +2532,7 @@
DocType: Program Enrollment Tool,Get Students,Obtenez étudiants
DocType: Serial No,Under Warranty,Sous garantie
apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +490,[Error],[Erreur]
-DocType: Sales Order,In Words will be visible once you save the Sales Order.,En Toutes Lettres. Sera visible une fois que vous enregistrerez le bon de commande.
+DocType: Sales Order,In Words will be visible once you save the Sales Order.,En Toutes Lettres. Sera visible une fois que vous enregistrerez le commande client.
,Employee Birthday,Anniversaire de l'employé
apps/erpnext/erpnext/controllers/status_updater.py +175,Limit Crossed,Limite Crossed
apps/erpnext/erpnext/setup/setup_wizard/industry_type.py +55,Venture Capital,Capital Risque
@@ -2769,7 +2769,7 @@
apps/erpnext/erpnext/accounts/page/pos/pos.js +1190,Please select customer,S'il vous plaît sélectionner client
DocType: C-Form,I,I
DocType: Company,Asset Depreciation Cost Center,Asset Centre Amortissements
-DocType: Sales Order Item,Sales Order Date,Date du bon de Commande
+DocType: Sales Order Item,Sales Order Date,Date du commande client
DocType: Sales Invoice Item,Delivered Qty,Qté livrée
DocType: Production Planning Tool,"If checked, all the children of each production item will be included in the Material Requests.","Si elle est cochée, tous les enfants de chaque élément de production seront inclus dans les demandes de matériel."
apps/erpnext/erpnext/stock/doctype/warehouse/warehouse.py +86,Warehouse {0}: Company is mandatory,Entrepôt {0}: Société est obligatoire
@@ -3459,7 +3459,7 @@
apps/erpnext/erpnext/accounts/report/sales_register/sales_register.py +69,Customer Id,Client Id
apps/erpnext/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.js +176,Mark Absent,Marquer absent
DocType: Journal Entry Account,Exchange Rate,Taux de change
-apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +471,Sales Order {0} is not submitted,Bon de commande {0} n'a pas été transmis
+apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +471,Sales Order {0} is not submitted,commande client {0} n'a pas été transmis
DocType: Homepage,Tag Line,Tag ligne
DocType: Fee Component,Fee Component,Component Fee
apps/erpnext/erpnext/buying/doctype/purchase_order/purchase_order.js +857,Add items from,Ajouter des articles de
diff --git a/license.txt b/license.txt
index 2c5df26..2a99aee 100644
--- a/license.txt
+++ b/license.txt
@@ -1,176 +1,675 @@
-ERPNext License Info
---------------------
-
-(c) 2013 Frappe Technologies Pvt Ltd. Mumbai
-ERPNext is a trademark of Frappe Technologies
-
-The ERPNext code is licensed under the GNU General Public License (v3) as mentioned below and the Documentation is licensed under Creative Commons (CC-BY-SA-3.0)
-
-GNU GENERAL PUBLIC LICENSE
---------------------------
+### GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
-http://www.gnu.org/copyleft/gpl.html
+Copyright (C) 2007 Free Software Foundation, Inc.
+<http://fsf.org/>
-TERMS AND CONDITIONS
-0. Definitions.
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
-“This License” refers to version 3 of the GNU General Public License.
+### Preamble
-“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.
+The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
-“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations.
+The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom
+to share and change all versions of a program--to make sure it remains
+free software for all its users. We, the Free Software Foundation, use
+the GNU General Public License for most of our software; it applies
+also to any other work released this way by its authors. You can apply
+it to your programs, too.
-To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work.
+When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
-A “covered work” means either the unmodified Program or a work based on the Program.
+To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you
+have certain responsibilities if you distribute copies of the
+software, or if you modify it: responsibilities to respect the freedom
+of others.
-To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.
+For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
-To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.
+Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
-An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.
-1. Source Code.
+For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
-The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work.
+Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the
+manufacturer can do so. This is fundamentally incompatible with the
+aim of protecting users' freedom to change the software. The
+systematic pattern of such abuse occurs in the area of products for
+individuals to use, which is precisely where it is most unacceptable.
+Therefore, we have designed this version of the GPL to prohibit the
+practice for those products. If such problems arise substantially in
+other domains, we stand ready to extend this provision to those
+domains in future versions of the GPL, as needed to protect the
+freedom of users.
-A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.
+Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish
+to avoid the special danger that patents applied to a free program
+could make it effectively proprietary. To prevent this, the GPL
+assures that patents cannot be used to render the program non-free.
+
+The precise terms and conditions for copying, distribution and
+modification follow.
+
+### TERMS AND CONDITIONS
+
+#### 0. Definitions.
+
+"This License" refers to version 3 of the GNU General Public License.
+
+"Copyright" also means copyright-like laws that apply to other kinds
+of works, such as semiconductor masks.
+
+"The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of
+an exact copy. The resulting work is called a "modified version" of
+the earlier work or a work "based on" the earlier work.
+
+A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user
+through a computer network, with no transfer of a copy, is not
+conveying.
+
+An interactive user interface displays "Appropriate Legal Notices" to
+the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+#### 1. Source Code.
+
+The "source code" for a work means the preferred form of the work for
+making modifications to it. "Object code" means any non-source form of
+a work.
+
+A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+The Corresponding Source need not include anything that users can
+regenerate automatically from other parts of the Corresponding Source.
+
+The Corresponding Source for a work in source code form is that same
+work.
+
+#### 2. Basic Permissions.
+
+All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+You may make, run and propagate covered works that you do not convey,
+without conditions so long as your license otherwise remains in force.
+You may convey covered works to others for the sole purpose of having
+them make modifications exclusively for you, or provide you with
+facilities for running those works, provided that you comply with the
+terms of this License in conveying all material for which you do not
+control copyright. Those thus making or running the covered works for
+you must do so exclusively on your behalf, under your direction and
+control, on terms that prohibit them from making any copies of your
+copyrighted material outside their relationship with you.
+
+Conveying under any other circumstances is permitted solely under the
+conditions stated below. Sublicensing is not allowed; section 10 makes
+it unnecessary.
+
+#### 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such
+circumvention is effected by exercising rights under this License with
+respect to the covered work, and you disclaim any intention to limit
+operation or modification of the work as a means of enforcing, against
+the work's users, your or third parties' legal rights to forbid
+circumvention of technological measures.
+
+#### 4. Conveying Verbatim Copies.
+
+You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+#### 5. Conveying Modified Source Versions.
+
+You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these
+conditions:
+
+- a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+- b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under
+ section 7. This requirement modifies the requirement in section 4
+ to "keep intact all notices".
+- c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+- d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+#### 6. Conveying Non-Source Forms.
+
+You may convey a covered work in object code form under the terms of
+sections 4 and 5, provided that you also convey the machine-readable
+Corresponding Source under the terms of this License, in one of these
+ways:
+
+- a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+- b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the Corresponding
+ Source from a network server at no charge.
+- c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+- d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+- e) Convey the object code using peer-to-peer transmission,
+ provided you inform other peers where the object code and
+ Corresponding Source of the work are being offered to the general
+ public at no charge under subsection 6d.
+
+A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal,
+family, or household purposes, or (2) anything designed or sold for
+incorporation into a dwelling. In determining whether a product is a
+consumer product, doubtful cases shall be resolved in favor of
+coverage. For a particular product received by a particular user,
+"normally used" refers to a typical or common use of that class of
+product, regardless of the status of the particular user or of the way
+in which the particular user actually uses, or expects or is expected
+to use, the product. A product is a consumer product regardless of
+whether the product has substantial commercial, industrial or
+non-consumer uses, unless such uses represent the only significant
+mode of use of the product.
+
+"Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to
+install and execute modified versions of a covered work in that User
+Product from a modified version of its Corresponding Source. The
+information must suffice to ensure that the continued functioning of
+the modified object code is in no case prevented or interfered with
+solely because modification has been made.
+
+If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or
+updates for a work that has been modified or installed by the
+recipient, or for the User Product in which it has been modified or
+installed. Access to a network may be denied when the modification
+itself materially and adversely affects the operation of the network
+or violates the rules and protocols for communication across the
+network.
+
+Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+#### 7. Additional Terms.
+
+"Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
-The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.
+When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
-The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.
+Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders
+of that material) supplement the terms of this License with terms:
-The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.
+- a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+- b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+- c) Prohibiting misrepresentation of the origin of that material,
+ or requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+- d) Limiting the use for publicity purposes of names of licensors
+ or authors of the material; or
+- e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+- f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions
+ of it) with contractual assumptions of liability to the recipient,
+ for any liability that these contractual assumptions directly
+ impose on those licensors and authors.
-The Corresponding Source for a work in source code form is that same work.
-2. Basic Permissions.
+All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
-All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.
+If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
-You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.
+Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions; the
+above requirements apply either way.
-Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
-3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+#### 8. Termination.
-No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.
+You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
-When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.
-4. Conveying Verbatim Copies.
+However, if you cease all violation of this License, then your license
+from a particular copyright holder is reinstated (a) provisionally,
+unless and until the copyright holder explicitly and finally
+terminates your license, and (b) permanently, if the copyright holder
+fails to notify you of the violation by some reasonable means prior to
+60 days after the cessation.
-You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.
+Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
-You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.
-5. Conveying Modified Source Versions.
+Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
-You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:
+#### 9. Acceptance Not Required for Having Copies.
- a) The work must carry prominent notices stating that you modified it, and giving a relevant date.
- b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”.
- c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.
- d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.
+You are not required to accept this License in order to receive or run
+a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
-A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.
-6. Conveying Non-Source Forms.
+#### 10. Automatic Licensing of Downstream Recipients.
-You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:
+Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
- a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.
- b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.
- c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.
- d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.
- e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.
+An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
-A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.
+You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
-A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.
+#### 11. Patents.
-“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.
+A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
-If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).
+A contributor's "essential patent claims" are all patent claims owned
+or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
-The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.
+Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
-Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.
-7. Additional Terms.
+In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
-“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.
+If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
-When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.
+If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
-Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:
+A patent license is "discriminatory" if it does not include within the
+scope of its coverage, prohibits the exercise of, or is conditioned on
+the non-exercise of one or more of the rights that are specifically
+granted under this License. You may not convey a covered work if you
+are a party to an arrangement with a third party that is in the
+business of distributing software, under which you make payment to the
+third party based on the extent of your activity of conveying the
+work, and under which the third party grants, to any of the parties
+who would receive the covered work from you, a discriminatory patent
+license (a) in connection with copies of the covered work conveyed by
+you (or copies made from those copies), or (b) primarily for and in
+connection with specific products or compilations that contain the
+covered work, unless you entered into that arrangement, or that patent
+license was granted, prior to 28 March 2007.
- a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
- b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or
- c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or
- d) Limiting the use for publicity purposes of names of licensors or authors of the material; or
- e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
- f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.
+Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
-All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.
+#### 12. No Surrender of Others' Freedom.
-If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.
+If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under
+this License and any other pertinent obligations, then as a
+consequence you may not convey it at all. For example, if you agree to
+terms that obligate you to collect a royalty for further conveying
+from those to whom you convey the Program, the only way you could
+satisfy both those terms and this License would be to refrain entirely
+from conveying the Program.
-Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.
-8. Termination.
+#### 13. Use with the GNU Affero General Public License.
-You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).
+Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
-However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.
+#### 14. Revised Versions of this License.
-Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.
+The Free Software Foundation may publish revised and/or new versions
+of the GNU General Public License from time to time. Such new versions
+will be similar in spirit to the present version, but may differ in
+detail to address new problems or concerns.
-Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.
-9. Acceptance Not Required for Having Copies.
+Each version is given a distinguishing version number. If the Program
+specifies that a certain numbered version of the GNU General Public
+License "or any later version" applies to it, you have the option of
+following the terms and conditions either of that numbered version or
+of any later version published by the Free Software Foundation. If the
+Program does not specify a version number of the GNU General Public
+License, you may choose any version ever published by the Free
+Software Foundation.
-You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.
-10. Automatic Licensing of Downstream Recipients.
+If the Program specifies that a proxy can decide which future versions
+of the GNU General Public License can be used, that proxy's public
+statement of acceptance of a version permanently authorizes you to
+choose that version for the Program.
-Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.
+Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
-An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.
+#### 15. Disclaimer of Warranty.
-You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.
-11. Patents.
+THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
+WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
+PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
+DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
+CORRECTION.
-A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”.
+#### 16. Limitation of Liability.
-A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR
+CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
+NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR
+LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM
+TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
+PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.
+#### 17. Interpretation of Sections 15 and 16.
-In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.
+If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
-If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.
+END OF TERMS AND CONDITIONS
-If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.
+### How to Apply These Terms to Your New Programs
-A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.
+If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
-Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.
-12. No Surrender of Others' Freedom.
+To do so, attach the following notices to the program. It is safest to
+attach them to the start of each source file to most effectively state
+the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
-If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.
-13. Use with the GNU Affero General Public License.
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
-Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.
-14. Revised Versions of this License.
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
-The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
-If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.
+Also add information on how to contact you by electronic and paper
+mail.
-Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.
-15. Disclaimer of Warranty.
+If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
-THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-16. Limitation of Liability.
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
-IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-17. Interpretation of Sections 15 and 16.
+The hypothetical commands \`show w' and \`show c' should show the
+appropriate parts of the General Public License. Of course, your
+program's commands might be different; for a GUI interface, you would
+use an "about box".
-If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.
+You should also get your employer (if you work as a programmer) or
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. For more information on this, and how to apply and follow
+the GNU GPL, see <http://www.gnu.org/licenses/>.
-END OF TERMS AND CONDITIONS
\ No newline at end of file
+The GNU General Public License does not permit incorporating your
+program into proprietary programs. If your program is a subroutine
+library, you may consider it more useful to permit linking proprietary
+applications with the library. If this is what you want to do, use the
+GNU Lesser General Public License instead of this License. But first,
+please read <http://www.gnu.org/philosophy/why-not-lgpl.html>.
\ No newline at end of file
diff --git a/patches.txt b/patches.txt
deleted file mode 100644
index 8f127fe..0000000
--- a/patches.txt
+++ /dev/null
@@ -1 +0,0 @@
-bench.patches.v3.deprecate_old_config