Merge pull request #5296 from KanchanChauhan/websitemakeover
New look to the website
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
deleted file mode 100644
index fdc30d2..0000000
--- a/.github/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,29 +0,0 @@
-### Issue Description
-
-Description...
-
----
-
-### Checklist
-
-- [ ] This is a bug report / feature request and not just a problem I am facing.
- (Go to https://discuss.erpnext.com for help)
-- [ ] I have searched https://github.com/frappe/erpnext/issues and didn't find a similar issue
-- [ ] I have mentioned steps to reproduce the issue
-- [ ] I have added screenshots / video / mockups
-- [ ] I have not edited the code of Frappe and ERPNext
-- [ ] I have mentioned a python error traceback or javascript error [optional]
-
----
-
-### Specs
-
-- ERPNext version:
-- Frappe version:
-- Operating System:
-- Browser:
-- Language:
-
----
-
-> **Note:** If you are reporting a security issue, please send a private email to <info@frappe.io>
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
deleted file mode 100644
index abb0e23..0000000
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ /dev/null
@@ -1,14 +0,0 @@
-### Pull Request Description
-
-Describe your pull request here with screenshots. Optionally, link the issue that this pull request fixes.
-
----
-
-### Checklist
-
-- [ ] Documentation
-- [ ] Front-end Testing
-- [ ] Test Cases
-- [ ] Blog Post / Help
-- [ ] Awesome! We are good for merging.
-
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index ed2d7c5..0000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# Contributing to Frappe / ERPNext
-
-## Questions
-
-If you have questions on how to use ERPNext or want help in customization or debugging of your scripts, please post on https://discuss.erpnext.com. This is only for bug reports and feature requests.
-
-## Reporting issues
-
-We only accept issues that are bug reports or feature requests. Bugs must be isolated and reproducible problems. Please read the following guidelines before opening any issue.
-
-1. **Search for existing issues:** We want to avoid duplication, and you'd help us out a lot by first checking if someone else has reported the same issue. The issue may have already been resolved with a fix available.
-1. **Report each issue separately:** Don't club multiple, unreleated issues in one note.
-1. **Mention the version number:** Please mention the application, browser and platform version numbers.
-
-### Issues
-
-1. **Share as much information as possible:** Include operating system and version, browser and version, when did you last update ERPNext, how is it customized, etc. where appropriate. Also include steps to reproduce the bug.
-1. **Include Screenshots if possible:** Consider adding screenshots annotated with what goes wrong.
-1. **Find and post the trace for bugs:** If you are reporting an issue from the browser, Open the Javascript Console and paste us any error messages you see.
-1. **Security Issues:** If you are reporting a security issue, please send a private email to <info@frappe.io>.
-
-
-### Feature Requests
-
-1. We need as much information you can to consider a feature request.
-1. Think about **how** you want us to build the feature. Consider including:
- 1. Mockups (wireframes of features)
- 1. Screenshots (annotated with what should change)
- 1. Screenshots from other products if you want us to implement features present in other products.
-1. Basically, the more you help us, the faster your request is likely to be completed.
-1. A one line feature request like **Implement Capacity Planning** will be closed.
-
-## Pull Requests
-
-General guidelines for sending pull requests:
-
-#### Don't Repeat Yourself (DRY)
-
-We believe that the most effective way to manage a product like this is to ensure that
-there is minimum repetition of code. So before contributing a function, please make sure
-that such a feature or function does not exist else where. If it does, the try and extend
-that function to accommodate your use case.
-
-#### Don't create new DocTypes Unless Absolutely Necessary
-
-DocTypes are easy to create but hard to maintain. If you find that there is a another DocType with a similar functionality, then please try and extend that functionality. For example, by adding a "type" field to classify the new type of record.
-
-#### Tabs or spaces?
-
-Tabs!
-
-#### Release Checklist
-
-- Describe, in detail, what is in the pull request
-- How to use the new feature?
-- Test cases
-- Change log
-- Manual Pull Request Link
-- Screencast. Should include:
- - New Forms
- - Linked Forms
- - Linked Reports
- - Print Views
-
-### Copyright
-
-Please see README.md
-
diff --git a/erpnext/__version__.py b/erpnext/__version__.py
index 93ce6d8..8559b8c 100644
--- a/erpnext/__version__.py
+++ b/erpnext/__version__.py
@@ -1,2 +1,2 @@
from __future__ import unicode_literals
-__version__ = '6.27.11'
+__version__ = '6.27.15'
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index 104bef7..a551d06 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -87,7 +87,7 @@
return
existing_is_group = frappe.db.get_value("Account", self.name, "is_group")
- if self.is_group != existing_is_group:
+ if cint(self.is_group) != cint(existing_is_group):
if self.check_gle_exists():
throw(_("Account with existing transaction cannot be converted to ledger"))
elif self.is_group:
diff --git a/erpnext/accounts/doctype/asset/asset.js b/erpnext/accounts/doctype/asset/asset.js
index 0dfdb21..0479a4e 100644
--- a/erpnext/accounts/doctype/asset/asset.js
+++ b/erpnext/accounts/doctype/asset/asset.js
@@ -24,6 +24,7 @@
refresh: function(frm) {
frappe.ui.form.trigger("Asset", "is_existing_asset");
+ frm.toggle_display("next_depreciation_date", frm.doc.docstatus < 1);
if (frm.doc.docstatus==1) {
if (frm.doc.status=='Submitted' && !frm.doc.is_existing_asset && !frm.doc.purchase_invoice) {
@@ -32,6 +33,10 @@
});
}
if (in_list(["Submitted", "Partially Depreciated", "Fully Depreciated"], frm.doc.status)) {
+ frm.add_custom_button("Transfer Asset", function() {
+ erpnext.asset.transfer_asset(frm);
+ });
+
frm.add_custom_button("Scrap Asset", function() {
erpnext.asset.scrap_asset(frm);
});
@@ -45,9 +50,56 @@
erpnext.asset.restore_asset(frm);
});
}
+
+ frm.trigger("show_graph");
}
},
+ show_graph: function(frm) {
+ var x_intervals = ["x", frm.doc.purchase_date];
+ var asset_values = ["Asset Value", frm.doc.gross_purchase_amount];
+ var last_depreciation_date = frm.doc.purchase_date;
+
+ if(frm.doc.opening_accumulated_depreciation) {
+ last_depreciation_date = frappe.datetime.add_months(frm.doc.next_depreciation_date,
+ -1*frm.doc.frequency_of_depreciation);
+
+ x_intervals.push(last_depreciation_date);
+ asset_values.push(flt(frm.doc.gross_purchase_amount) -
+ flt(frm.doc.opening_accumulated_depreciation));
+ }
+
+ $.each(frm.doc.schedules || [], function(i, v) {
+ x_intervals.push(v.schedule_date);
+ asset_value = flt(frm.doc.gross_purchase_amount) - flt(v.accumulated_depreciation_amount);
+ if(v.journal_entry) {
+ last_depreciation_date = v.schedule_date;
+ asset_values.push(asset_value)
+ } else {
+ if (in_list(["Scrapped", "Sold"], frm.doc.status)) {
+ asset_values.push(null)
+ } else {
+ asset_values.push(asset_value)
+ }
+ }
+ })
+
+ if(in_list(["Scrapped", "Sold"], frm.doc.status)) {
+ x_intervals.push(frm.doc.disposal_date);
+ asset_values.push(0);
+ last_depreciation_date = frm.doc.disposal_date;
+ }
+
+ frm.dashboard.reset();
+ frm.dashboard.add_graph({
+ x: 'x',
+ columns: [x_intervals, asset_values],
+ regions: {
+ 'Asset Value': [{'start': last_depreciation_date, 'style':'dashed'}]
+ }
+ });
+ },
+
is_existing_asset: function(frm) {
frm.toggle_enable("supplier", frm.doc.is_existing_asset);
frm.toggle_reqd("next_depreciation_date", !frm.doc.is_existing_asset);
@@ -112,4 +164,55 @@
}
})
})
+}
+
+erpnext.asset.transfer_asset = function(frm) {
+ var dialog = new frappe.ui.Dialog({
+ title: __("Transfer Asset"),
+ fields: [
+ {
+ "label": __("Target Warehouse"),
+ "fieldname": "target_warehouse",
+ "fieldtype": "Link",
+ "options": "Warehouse",
+ "get_query": function () {
+ return {
+ filters: [["Warehouse", "company", "in", ["", cstr(frm.doc.company)]]]
+ }
+ },
+ "reqd": 1
+ },
+ {
+ "label": __("Date"),
+ "fieldname": "transfer_date",
+ "fieldtype": "Datetime",
+ "reqd": 1,
+ "default": frappe.datetime.now_datetime()
+ }
+ ]
+ });
+
+ dialog.set_primary_action(__("Transfer"), function() {
+ args = dialog.get_values();
+ if(!args) return;
+ dialog.hide();
+ return frappe.call({
+ type: "GET",
+ method: "erpnext.accounts.doctype.asset.asset.transfer_asset",
+ args: {
+ args: {
+ "asset": frm.doc.name,
+ "transaction_date": args.transfer_date,
+ "source_warehouse": frm.doc.warehouse,
+ "target_warehouse": args.target_warehouse,
+ "company": frm.doc.company
+ }
+ },
+ freeze: true,
+ callback: function(r) {
+ cur_frm.reload_doc();
+ }
+ })
+ });
+ dialog.show();
}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/asset/asset.json b/erpnext/accounts/doctype/asset/asset.json
index 70c1c16..c272a58 100644
--- a/erpnext/accounts/doctype/asset/asset.json
+++ b/erpnext/accounts/doctype/asset/asset.json
@@ -97,7 +97,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
- "in_list_view": 0,
+ "in_list_view": 1,
"label": "Status",
"length": 0,
"no_copy": 1,
@@ -114,6 +114,31 @@
"unique": 0
},
{
+ "allow_on_submit": 1,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "image",
+ "fieldtype": "Attach Image",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Image",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "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,
@@ -706,13 +731,14 @@
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 72,
+ "image_field": "image",
"in_create": 0,
"in_dialog": 0,
"is_submittable": 1,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-04-20 18:09:07.573716",
+ "modified": "2016-04-22 11:15:40.055518",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Asset",
diff --git a/erpnext/accounts/doctype/asset/asset.py b/erpnext/accounts/doctype/asset/asset.py
index da229fe..23bb08b 100644
--- a/erpnext/accounts/doctype/asset/asset.py
+++ b/erpnext/accounts/doctype/asset/asset.py
@@ -190,4 +190,17 @@
"qty": 1
})
si.set_missing_values()
- return si
\ No newline at end of file
+ return si
+
+@frappe.whitelist()
+def transfer_asset(args):
+ import json
+ args = json.loads(args)
+ movement_entry = frappe.new_doc("Asset Movement")
+ movement_entry.update(args)
+ movement_entry.insert()
+ movement_entry.submit()
+
+ frappe.db.commit()
+
+ frappe.msgprint(_("Asset Movement record {0} created").format("<a href='#Form/Asset Movement/{0}'>{0}</a>".format(movement_entry.name)))
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/asset_movement/__init__.py b/erpnext/accounts/doctype/asset_movement/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/doctype/asset_movement/__init__.py
diff --git a/erpnext/accounts/doctype/asset_movement/asset_movement.js b/erpnext/accounts/doctype/asset_movement/asset_movement.js
new file mode 100644
index 0000000..680eedc
--- /dev/null
+++ b/erpnext/accounts/doctype/asset_movement/asset_movement.js
@@ -0,0 +1,15 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Asset Movement', {
+ onload: function(frm) {
+ frm.add_fetch("asset", "warehouse", "source_warehouse");
+
+ frm.set_query("target_warehouse", function() {
+ return {
+ filters: [["Warehouse", "company", "in", ["", cstr(frm.doc.company)]]]
+ }
+ })
+
+ }
+});
diff --git a/erpnext/accounts/doctype/asset_movement/asset_movement.json b/erpnext/accounts/doctype/asset_movement/asset_movement.json
new file mode 100644
index 0000000..59b8823
--- /dev/null
+++ b/erpnext/accounts/doctype/asset_movement/asset_movement.json
@@ -0,0 +1,274 @@
+{
+ "allow_copy": 0,
+ "allow_import": 1,
+ "allow_rename": 0,
+ "autoname": "AM-.#####",
+ "creation": "2016-04-25 18:00:23.559973",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "fields": [
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "asset",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Asset",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Asset",
+ "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,
+ "fieldname": "transaction_date",
+ "fieldtype": "Datetime",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Transaction 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,
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Company",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 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,
+ "fieldname": "source_warehouse",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Source Warehouse",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Warehouse",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "target_warehouse",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Target Warehouse",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Warehouse",
+ "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,
+ "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": "Asset Movement",
+ "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,
+ "in_create": 0,
+ "in_dialog": 0,
+ "is_submittable": 1,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2016-04-25 19:14:08.853429",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Asset Movement",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 1,
+ "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": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 1,
+ "write": 1
+ },
+ {
+ "amend": 1,
+ "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": "Accounts Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 1,
+ "write": 1
+ },
+ {
+ "amend": 1,
+ "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": "Stock 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",
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/asset_movement/asset_movement.py b/erpnext/accounts/doctype/asset_movement/asset_movement.py
new file mode 100644
index 0000000..574c499
--- /dev/null
+++ b/erpnext/accounts/doctype/asset_movement/asset_movement.py
@@ -0,0 +1,48 @@
+# -*- 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.model.document import Document
+
+class AssetMovement(Document):
+ def validate(self):
+ self.validate_asset()
+ self.validate_warehouses()
+
+ def validate_asset(self):
+ status, company = frappe.db.get_value("Asset", self.asset, ["status", "company"])
+ if status in ("Draft", "Scrapped", "Sold"):
+ frappe.throw(_("{0} asset cannot be transferred").format(status))
+
+ if company != self.company:
+ frappe.throw(_("Asset {0} does not belong to company {1}").format(self.asset, self.company))
+
+ def validate_warehouses(self):
+ if not self.source_warehouse:
+ self.source_warehouse = frappe.db.get_value("Asset", self.asset, "warehouse")
+
+ if self.source_warehouse == self.target_warehouse:
+ frappe.throw(_("Source and Target Warehouse cannot be same"))
+
+ def on_submit(self):
+ self.set_latest_warehouse_in_asset()
+
+ def on_cancel(self):
+ self.set_latest_warehouse_in_asset()
+
+ def set_latest_warehouse_in_asset(self):
+ latest_movement_entry = frappe.db.sql("""select target_warehouse from `tabAsset Movement`
+ where asset=%s and docstatus=1 and company=%s
+ order by transaction_date desc limit 1""", (self.asset, self.company))
+
+ if latest_movement_entry:
+ warehouse = latest_movement_entry[0][0]
+ else:
+ warehouse = frappe.db.sql("""select source_warehouse from `tabAsset Movement`
+ where asset=%s and docstatus=2 and company=%s
+ order by transaction_date asc limit 1""", (self.asset, self.company))[0][0]
+
+ frappe.db.set_value("Asset", self.asset, "warehouse", warehouse)
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/asset_movement/test_asset_movement.py b/erpnext/accounts/doctype/asset_movement/test_asset_movement.py
new file mode 100644
index 0000000..9880efc
--- /dev/null
+++ b/erpnext/accounts/doctype/asset_movement/test_asset_movement.py
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+from frappe.utils import now
+import unittest
+from erpnext.accounts.doctype.asset.test_asset import create_asset
+
+
+class TestAssetMovement(unittest.TestCase):
+ def test_movement(self):
+ asset = create_asset()
+
+ if asset.docstatus == 0:
+ asset.submit()
+
+ movement1 = create_asset_movement(asset, target_warehouse="_Test Warehouse 1 - _TC")
+ self.assertEqual(frappe.db.get_value("Asset", asset.name, "warehouse"), "_Test Warehouse 1 - _TC")
+
+ movement2 = create_asset_movement(asset, target_warehouse="_Test Warehouse 2 - _TC")
+ self.assertEqual(frappe.db.get_value("Asset", asset.name, "warehouse"), "_Test Warehouse 2 - _TC")
+
+ movement1.cancel()
+ self.assertEqual(frappe.db.get_value("Asset", asset.name, "warehouse"), "_Test Warehouse 2 - _TC")
+
+ movement2.cancel()
+ self.assertEqual(frappe.db.get_value("Asset", asset.name, "warehouse"), "_Test Warehouse - _TC")
+
+ asset.load_from_db()
+ asset.cancel()
+ frappe.delete_doc("Asset", asset.name)
+
+
+def create_asset_movement(asset, target_warehouse, transaction_date=None):
+ if not transaction_date:
+ transaction_date = now()
+
+ movement = frappe.new_doc("Asset Movement")
+ movement.update({
+ "asset": asset.name,
+ "transaction_date": transaction_date,
+ "target_warehouse": target_warehouse,
+ "company": asset.company
+ })
+
+ movement.insert()
+ movement.submit()
+
+ return movement
diff --git a/erpnext/accounts/doctype/c_form/c_form.js b/erpnext/accounts/doctype/c_form/c_form.js
index eed81cb..92cdb63 100644
--- a/erpnext/accounts/doctype/c_form/c_form.js
+++ b/erpnext/accounts/doctype/c_form/c_form.js
@@ -3,12 +3,12 @@
//c-form js file
// -----------------------------
-frappe.require("assets/erpnext/js/utils.js");
+
cur_frm.fields_dict.invoices.grid.get_field("invoice_no").get_query = function(doc) {
return {
filters: {
- "docstatus": 1,
+ "docstatus": 1,
"customer": doc.customer,
"company": doc.company,
"c_form_applicable": 'Yes',
diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
index c3f399d..2fd838b 100644
--- a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
+++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
@@ -41,6 +41,11 @@
def on_update(self):
check_duplicate_fiscal_year(self)
+
+ def on_trash(self):
+ global_defaults = frappe.get_doc("Global Defaults")
+ if global_defaults.current_fiscal_year == self.name:
+ frappe.throw(_("You cannot delete Fiscal Year {0}. Fiscal Year {0} is set as default in Global Settings").format(self.name))
def validate_overlap(self):
existing_fiscal_years = frappe.db.sql("""select name from `tabFiscal Year`
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js
index fc29bc7..bc337a1 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.js
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js
@@ -3,7 +3,7 @@
frappe.provide("erpnext.accounts");
frappe.provide("erpnext.journal_entry");
-frappe.require("assets/erpnext/js/utils.js");
+
frappe.ui.form.on("Journal Entry", {
refresh: function(frm) {
diff --git a/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.json b/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.json
index 5659f1f..9255eda 100644
--- a/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.json
+++ b/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.json
@@ -13,9 +13,10 @@
"bold": 0,
"collapsible": 0,
"fieldname": "invoice_type",
- "fieldtype": "Data",
+ "fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Invoice Type",
@@ -24,6 +25,7 @@
"options": "Sales Invoice\nPurchase Invoice\nJournal Entry",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
@@ -36,17 +38,19 @@
"bold": 0,
"collapsible": 0,
"fieldname": "invoice_number",
- "fieldtype": "Data",
+ "fieldtype": "Dynamic Link",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Invoice Number",
"length": 0,
"no_copy": 0,
- "options": "",
+ "options": "invoice_type",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
@@ -62,6 +66,7 @@
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Invoice Date",
@@ -69,6 +74,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
@@ -84,6 +90,7 @@
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "",
@@ -91,6 +98,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -106,6 +114,7 @@
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Amount",
@@ -113,6 +122,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
@@ -128,6 +138,7 @@
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Outstanding Amount",
@@ -135,6 +146,7 @@
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
@@ -145,21 +157,24 @@
],
"hide_heading": 0,
"hide_toolbar": 0,
+ "idx": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2015-11-16 06:29:51.516537",
+ "modified": "2016-04-29 05:47:14.124370",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation Invoice",
"name_case": "",
"owner": "Administrator",
"permissions": [],
+ "quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"sort_field": "modified",
- "sort_order": "DESC"
+ "sort_order": "DESC",
+ "track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/accounts/page/financial_analytics/financial_analytics.js b/erpnext/accounts/page/financial_analytics/financial_analytics.js
index ef373aa..c892738 100644
--- a/erpnext/accounts/page/financial_analytics/financial_analytics.js
+++ b/erpnext/accounts/page/financial_analytics/financial_analytics.js
@@ -12,7 +12,7 @@
};
-frappe.require("assets/erpnext/js/account_tree_grid.js");
+{% include "erpnext/public/js/account_tree_grid.js" %}
erpnext.FinancialAnalytics = erpnext.AccountTreeGrid.extend({
filters: [
diff --git a/erpnext/accounts/report/balance_sheet/balance_sheet.js b/erpnext/accounts/report/balance_sheet/balance_sheet.js
index 933b40e..a20d47c 100644
--- a/erpnext/accounts/report/balance_sheet/balance_sheet.js
+++ b/erpnext/accounts/report/balance_sheet/balance_sheet.js
@@ -1,6 +1,8 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-frappe.require("assets/erpnext/js/financial_statements.js");
+frappe.require("assets/erpnext/js/financial_statements.js", function() {
+ frappe.query_reports["Balance Sheet"] = erpnext.financial_statements;
+});
-frappe.query_reports["Balance Sheet"] = erpnext.financial_statements;
+
diff --git a/erpnext/accounts/report/cash_flow/cash_flow.js b/erpnext/accounts/report/cash_flow/cash_flow.js
index 464bd17..f5ddd15 100644
--- a/erpnext/accounts/report/cash_flow/cash_flow.js
+++ b/erpnext/accounts/report/cash_flow/cash_flow.js
@@ -1,12 +1,12 @@
// Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
-frappe.require("assets/erpnext/js/financial_statements.js");
+frappe.require("assets/erpnext/js/financial_statements.js", function() {
+ frappe.query_reports["Cash Flow"] = erpnext.financial_statements;
-frappe.query_reports["Cash Flow"] = erpnext.financial_statements;
-
-frappe.query_reports["Cash Flow"]["filters"].push({
- "fieldname": "accumulated_values",
- "label": __("Accumulated Values"),
- "fieldtype": "Check"
-})
\ No newline at end of file
+ frappe.query_reports["Cash Flow"]["filters"].push({
+ "fieldname": "accumulated_values",
+ "label": __("Accumulated Values"),
+ "fieldtype": "Check"
+ });
+});
\ No newline at end of file
diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
index f1e706e..9e7cdb6 100644
--- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
+++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
@@ -14,7 +14,7 @@
item_list = get_items(filters)
aii_account_map = get_aii_accounts()
if item_list:
- item_tax, tax_accounts = get_tax_accounts(item_list, columns)
+ item_row_tax, tax_accounts = get_tax_accounts(item_list, columns)
columns.append({
"fieldname": "currency",
@@ -23,7 +23,7 @@
"width": 80
})
company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
- print company_currency
+
data = []
for d in item_list:
purchase_receipt = None
@@ -39,7 +39,7 @@
purchase_receipt, expense_account, d.qty, d.base_net_rate, d.base_net_amount]
for tax in tax_accounts:
- row.append(item_tax.get(d.parent, {}).get(d.item_code, {}).get(tax, 0))
+ row.append(item_row_tax.get(d.name, {}).get(tax, 0))
total_tax = sum(row[last_col:])
row += [total_tax, d.base_net_amount + total_tax, company_currency]
@@ -76,29 +76,40 @@
conditions = get_conditions(filters)
match_conditions = frappe.build_match_conditions("Purchase Invoice")
- return frappe.db.sql("""select pi_item.parent, pi.posting_date, pi.credit_to, pi.company,
- pi.supplier, pi.remarks, pi.base_net_total, pi_item.item_code, pi_item.item_name, pi_item.item_group,
- pi_item.project, pi_item.purchase_order, pi_item.purchase_receipt, pi_item.po_detail,
- pi_item.expense_account, pi_item.qty, pi_item.base_net_rate, pi_item.base_net_amount, pi.supplier_name
+ return frappe.db.sql("""
+ select
+ pi_item.name, pi_item.parent, pi.posting_date, pi.credit_to, pi.company,
+ pi.supplier, pi.remarks, pi.base_net_total, pi_item.item_code, pi_item.item_name,
+ pi_item.item_group, pi_item.project, pi_item.purchase_order, pi_item.purchase_receipt,
+ pi_item.po_detail, pi_item.expense_account, pi_item.qty, pi_item.base_net_rate,
+ pi_item.base_net_amount, pi.supplier_name
from `tabPurchase Invoice` pi, `tabPurchase Invoice Item` pi_item
where pi.name = pi_item.parent and pi.docstatus = 1 %s %s
- order by pi.posting_date desc, pi_item.item_code desc""" % (conditions, match_conditions), filters, as_dict=1)
+ order by pi.posting_date desc, pi_item.item_code desc
+ """ % (conditions, match_conditions), filters, as_dict=1)
def get_aii_accounts():
return dict(frappe.db.sql("select name, stock_received_but_not_billed from tabCompany"))
def get_tax_accounts(item_list, columns):
import json
- item_tax = {}
+ item_row_tax = {}
tax_accounts = []
- invoice_wise_items = {}
+ invoice_item_row = {}
+ item_row_map = {}
for d in item_list:
- invoice_wise_items.setdefault(d.parent, []).append(d)
+ invoice_item_row.setdefault(d.parent, []).append(d)
+ item_row_map.setdefault(d.parent, {}).setdefault(d.item_code, []).append(d)
- tax_details = frappe.db.sql("""select parent, account_head, item_wise_tax_detail, charge_type, base_tax_amount_after_discount_amount
- from `tabPurchase Taxes and Charges` where parenttype = 'Purchase Invoice'
- and docstatus = 1 and (account_head is not null and account_head != '') and category in ('Total', 'Valuation and Total')
- and parent in (%s)""" % ', '.join(['%s']*len(invoice_wise_items)), tuple(invoice_wise_items.keys()))
+ tax_details = frappe.db.sql("""
+ select
+ parent, account_head, item_wise_tax_detail, charge_type, base_tax_amount_after_discount_amount
+ from `tabPurchase Taxes and Charges`
+ where parenttype = 'Purchase Invoice' and docstatus = 1
+ and (account_head is not null and account_head != '')
+ and category in ('Total', 'Valuation and Total')
+ and parent in (%s)
+ """ % ', '.join(['%s']*len(invoice_item_row)), tuple(invoice_item_row.keys()))
for parent, account_head, item_wise_tax_detail, charge_type, tax_amount in tax_details:
if account_head not in tax_accounts:
@@ -107,19 +118,26 @@
if item_wise_tax_detail:
try:
item_wise_tax_detail = json.loads(item_wise_tax_detail)
- for item, tax_amount in item_wise_tax_detail.items():
- item_tax.setdefault(parent, {}).setdefault(item, {})[account_head] = \
- flt(tax_amount[1]) if isinstance(tax_amount, list) else flt(tax_amount)
-
+
+ for item_code, tax_amount in item_wise_tax_detail.items():
+ tax_amount = flt(tax_amount[1]) if isinstance(tax_amount, list) else flt(tax_amount)
+
+ item_net_amount = sum([flt(d.base_net_amount)
+ for d in item_row_map.get(parent, {}).get(item_code, [])])
+
+ for d in item_row_map.get(parent, {}).get(item_code, []):
+ item_tax_amount = flt((tax_amount * d.base_net_amount) / item_net_amount) if item_net_amount else 0
+ item_row_tax.setdefault(d.name, {})[account_head] = item_tax_amount
+
except ValueError:
continue
elif charge_type == "Actual" and tax_amount:
- for d in invoice_wise_items.get(parent, []):
- item_tax.setdefault(parent, {}).setdefault(d.item_code, {})[account_head] = \
- (tax_amount * d.base_net_amount) / d.base_net_total
+ for d in invoice_item_row.get(parent, []):
+ item_row_tax.setdefault(d.name, {})[account_head] = \
+ flt((tax_amount * d.base_net_amount) / d.base_net_total)
tax_accounts.sort()
columns += [account_head + ":Currency/currency:80" for account_head in tax_accounts]
columns += ["Total Tax:Currency/currency:80", "Total:Currency/currency:80"]
- return item_tax, tax_accounts
+ return item_row_tax, tax_accounts
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 2401202..beca96e 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
@@ -13,7 +13,7 @@
item_list = get_items(filters)
if item_list:
- item_tax, tax_accounts = get_tax_accounts(item_list, columns)
+ item_row_tax, tax_accounts = get_tax_accounts(item_list, columns)
columns.append({
"fieldname": "currency",
"label": _("Currency"),
@@ -36,7 +36,7 @@
delivery_note, d.income_account, d.qty, d.base_net_rate, d.base_net_amount]
for tax in tax_accounts:
- row.append(item_tax.get(d.parent, {}).get(d.item_code, {}).get(tax, 0))
+ row.append(item_row_tax.get(d.name, {}).get(tax, 0))
total_tax = sum(row[last_col:])
row += [total_tax, d.base_net_amount + total_tax, company_currency]
@@ -73,49 +73,66 @@
def get_items(filters):
conditions = get_conditions(filters)
- return frappe.db.sql("""select si_item.parent, si.posting_date, si.debit_to, si.project,
- si.customer, si.remarks, si.territory, si.company, si.base_net_total, 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.qty, si_item.base_net_rate, si_item.base_net_amount, si.customer_name,
- si.customer_group, si_item.so_detail
+ return frappe.db.sql("""
+ select
+ si_item.name, si_item.parent, si.posting_date, si.debit_to, si.project,
+ si.customer, si.remarks, si.territory, si.company, si.base_net_total,
+ 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.qty,
+ si_item.base_net_rate, si_item.base_net_amount, si.customer_name,
+ si.customer_group, si_item.so_detail
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)
def get_tax_accounts(item_list, columns):
import json
- item_tax = {}
+ item_row_tax = {}
tax_accounts = []
- invoice_wise_items = {}
+ invoice_item_row = {}
+ item_row_map = {}
for d in item_list:
- invoice_wise_items.setdefault(d.parent, []).append(d)
+ invoice_item_row.setdefault(d.parent, []).append(d)
+ item_row_map.setdefault(d.parent, {}).setdefault(d.item_code, []).append(d)
- tax_details = frappe.db.sql("""select parent, account_head, item_wise_tax_detail,
- charge_type, base_tax_amount_after_discount_amount
- from `tabSales Taxes and Charges` where parenttype = 'Sales Invoice'
- and docstatus = 1 and (account_head is not null and account_head != '')
- and parent in (%s)""" % ', '.join(['%s']*len(invoice_wise_items)),
- tuple(invoice_wise_items.keys()))
+ tax_details = frappe.db.sql("""
+ select
+ parent, account_head, item_wise_tax_detail,
+ charge_type, base_tax_amount_after_discount_amount
+ from `tabSales Taxes and Charges`
+ where
+ parenttype = 'Sales Invoice' and docstatus = 1
+ and (account_head is not null and account_head != '')
+ and parent in (%s)
+ """ % ', '.join(['%s']*len(invoice_item_row)), tuple(invoice_item_row.keys()))
for parent, account_head, item_wise_tax_detail, charge_type, tax_amount in tax_details:
if account_head not in tax_accounts:
tax_accounts.append(account_head)
-
+
if item_wise_tax_detail:
try:
item_wise_tax_detail = json.loads(item_wise_tax_detail)
- for item, tax_amount in item_wise_tax_detail.items():
- item_tax.setdefault(parent, {}).setdefault(item, {})[account_head] = \
- flt(tax_amount[1]) if isinstance(tax_amount, list) else flt(tax_amount)
+
+ for item_code, tax_amount in item_wise_tax_detail.items():
+ tax_amount = flt(tax_amount[1]) if isinstance(tax_amount, list) else flt(tax_amount)
+
+ item_net_amount = sum([flt(d.base_net_amount)
+ for d in item_row_map.get(parent, {}).get(item_code, [])])
+
+ for d in item_row_map.get(parent, {}).get(item_code, []):
+ item_tax_amount = flt((tax_amount * d.base_net_amount) / item_net_amount) if item_net_amount else 0
+ item_row_tax.setdefault(d.name, {})[account_head] = item_tax_amount
+
except ValueError:
continue
elif charge_type == "Actual" and tax_amount:
- for d in invoice_wise_items.get(parent, []):
- item_tax.setdefault(parent, {}).setdefault(d.item_code, {})[account_head] = \
+ for d in invoice_item_row.get(parent, []):
+ item_row_tax.setdefault(d.name, {})[account_head] = \
flt((tax_amount * d.base_net_amount) / d.base_net_total)
tax_accounts.sort()
columns += [account_head + ":Currency/currency:80" for account_head in tax_accounts]
columns += ["Total Tax:Currency/currency:80", "Total:Currency/currency:80"]
- return item_tax, tax_accounts
+ return item_row_tax, tax_accounts
diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
index 98a972b..91ec9d9 100644
--- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
+++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
@@ -1,15 +1,12 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-frappe.require("assets/erpnext/js/financial_statements.js");
+frappe.require("assets/erpnext/js/financial_statements.js", function() {
+ frappe.query_reports["Profit and Loss Statement"] = $.extend({}, erpnext.financial_statements);
-frappe.query_reports["Profit and Loss Statement"] = $.extend({}, erpnext.financial_statements);
-
-frappe.query_reports["Profit and Loss Statement"]["filters"].push({
- "fieldname": "accumulated_values",
- "label": __("Accumulated Values"),
- "fieldtype": "Check"
-});
-
-console.log(frappe.query_reports["Profit and Loss Statement"]);
-
+ frappe.query_reports["Profit and Loss Statement"]["filters"].push({
+ "fieldname": "accumulated_values",
+ "label": __("Accumulated Values"),
+ "fieldtype": "Check"
+ });
+});
\ No newline at end of file
diff --git a/erpnext/accounts/report/purchase_invoice_trends/purchase_invoice_trends.js b/erpnext/accounts/report/purchase_invoice_trends/purchase_invoice_trends.js
index 4b34ae5..cc00b2a 100644
--- a/erpnext/accounts/report/purchase_invoice_trends/purchase_invoice_trends.js
+++ b/erpnext/accounts/report/purchase_invoice_trends/purchase_invoice_trends.js
@@ -1,8 +1,8 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-frappe.require("assets/erpnext/js/purchase_trends_filters.js");
-
-frappe.query_reports["Purchase Invoice Trends"] = {
- filters: get_filters()
- }
\ No newline at end of file
+frappe.require("assets/erpnext/js/purchase_trends_filters.js", function() {
+ frappe.query_reports["Purchase Invoice Trends"] = {
+ filters: get_filters()
+ }
+});
\ No newline at end of file
diff --git a/erpnext/accounts/report/purchase_register/purchase_register.py b/erpnext/accounts/report/purchase_register/purchase_register.py
index 7934bf2..53cb7af66 100644
--- a/erpnext/accounts/report/purchase_register/purchase_register.py
+++ b/erpnext/accounts/report/purchase_register/purchase_register.py
@@ -119,16 +119,22 @@
def get_invoices(filters):
conditions = get_conditions(filters)
- return frappe.db.sql("""select name, posting_date, credit_to, supplier, supplier_name,
- bill_no, bill_date, remarks, base_net_total, base_grand_total, outstanding_amount
- from `tabPurchase Invoice` where docstatus = 1 %s
+ return frappe.db.sql("""
+ select
+ name, posting_date, credit_to, supplier, supplier_name,
+ bill_no, bill_date, remarks, base_net_total, base_grand_total, outstanding_amount
+ from `tabPurchase Invoice`
+ where docstatus = 1 %s
order by posting_date desc, name desc""" % conditions, filters, as_dict=1)
def get_invoice_expense_map(invoice_list):
- expense_details = frappe.db.sql("""select parent, expense_account, sum(base_net_amount) as amount
- from `tabPurchase Invoice Item` where parent in (%s) group by parent, expense_account""" %
- ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
+ expense_details = frappe.db.sql("""
+ select parent, expense_account, sum(base_net_amount) as amount
+ from `tabPurchase Invoice Item`
+ where parent in (%s)
+ group by parent, expense_account
+ """ % ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
invoice_expense_map = {}
for d in expense_details:
@@ -138,9 +144,12 @@
return invoice_expense_map
def get_invoice_tax_map(invoice_list, invoice_expense_map, expense_accounts):
- tax_details = frappe.db.sql("""select parent, account_head, sum(base_tax_amount_after_discount_amount) as tax_amount
- from `tabPurchase Taxes and Charges` where parent in (%s) group by parent, account_head""" %
- ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
+ tax_details = frappe.db.sql("""
+ select parent, account_head, sum(base_tax_amount_after_discount_amount) as tax_amount
+ from `tabPurchase Taxes and Charges`
+ where parent in (%s) and category in ('Total', 'Valuation and Total')
+ group by parent, account_head
+ """ % ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
invoice_tax_map = {}
for d in tax_details:
@@ -156,10 +165,11 @@
return invoice_expense_map, invoice_tax_map
def get_invoice_po_pr_map(invoice_list):
- pi_items = frappe.db.sql("""select parent, purchase_order, purchase_receipt, po_detail,
- project from `tabPurchase Invoice Item` where parent in (%s)
- and (ifnull(purchase_order, '') != '' or ifnull(purchase_receipt, '') != '')""" %
- ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
+ pi_items = frappe.db.sql("""
+ select parent, purchase_order, purchase_receipt, po_detail, project
+ from `tabPurchase Invoice Item`
+ where parent in (%s) and (ifnull(purchase_order, '') != '' or ifnull(purchase_receipt, '') != '')
+ """ % ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
invoice_po_pr_map = {}
for d in pi_items:
diff --git a/erpnext/accounts/report/sales_invoice_trends/sales_invoice_trends.js b/erpnext/accounts/report/sales_invoice_trends/sales_invoice_trends.js
index 471e7ba..0f92223 100644
--- a/erpnext/accounts/report/sales_invoice_trends/sales_invoice_trends.js
+++ b/erpnext/accounts/report/sales_invoice_trends/sales_invoice_trends.js
@@ -1,8 +1,8 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-frappe.require("assets/erpnext/js/sales_trends_filters.js");
-
-frappe.query_reports["Sales Invoice Trends"] = {
- filters: get_filters()
- }
\ No newline at end of file
+frappe.require("assets/erpnext/js/sales_trends_filters.js", function() {
+ frappe.query_reports["Sales Invoice Trends"] = {
+ filters: get_filters()
+ }
+});
\ 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 97c8f6c..a20b1cb 100644
--- a/erpnext/accounts/report/trial_balance/trial_balance.js
+++ b/erpnext/accounts/report/trial_balance/trial_balance.js
@@ -1,65 +1,66 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-frappe.require("assets/erpnext/js/financial_statements.js");
-
-frappe.query_reports["Trial Balance"] = {
- "filters": [
- {
- "fieldname": "company",
- "label": __("Company"),
- "fieldtype": "Link",
- "options": "Company",
- "default": frappe.defaults.get_user_default("Company"),
- "reqd": 1
- },
- {
- "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.require("assets/erpnext/js/financial_statements.js", function() {
+ frappe.query_reports["Trial Balance"] = {
+ "filters": [
+ {
+ "fieldname": "company",
+ "label": __("Company"),
+ "fieldtype": "Link",
+ "options": "Company",
+ "default": frappe.defaults.get_user_default("Company"),
+ "reqd": 1
+ },
+ {
+ "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);
+ query_report.filters_by_name.from_date.set_input(fy.year_start_date);
+ query_report.filters_by_name.to_date.set_input(fy.year_end_date);
+ query_report.trigger_refresh();
+ });
}
- frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
- var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
- query_report.filters_by_name.from_date.set_input(fy.year_start_date);
- 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"),
- },
- {
- "fieldname": "with_period_closing_entry",
- "label": __("Period Closing Entry"),
- "fieldtype": "Check",
- "default": 1
- },
- {
- "fieldname": "show_zero_values",
- "label": __("Show zero values"),
- "fieldtype": "Check"
- },
- ],
- "formatter": erpnext.financial_statements.formatter,
- "tree": true,
- "name_field": "account",
- "parent_field": "parent_account",
- "initial_depth": 3
-}
+ },
+ {
+ "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"),
+ },
+ {
+ "fieldname": "with_period_closing_entry",
+ "label": __("Period Closing Entry"),
+ "fieldtype": "Check",
+ "default": 1
+ },
+ {
+ "fieldname": "show_zero_values",
+ "label": __("Show zero values"),
+ "fieldtype": "Check"
+ },
+ ],
+ "formatter": erpnext.financial_statements.formatter,
+ "tree": true,
+ "name_field": "account",
+ "parent_field": "parent_account",
+ "initial_depth": 3
+ }
+});
+
diff --git a/erpnext/accounts/report/trial_balance/trial_balance.py b/erpnext/accounts/report/trial_balance/trial_balance.py
index e53d47e..a51e9b0 100644
--- a/erpnext/accounts/report/trial_balance/trial_balance.py
+++ b/erpnext/accounts/report/trial_balance/trial_balance.py
@@ -161,6 +161,8 @@
def prepare_data(accounts, filters, total_row, parent_children_map):
data = []
+ company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
+
for d in accounts:
has_value = False
row = {
@@ -169,7 +171,8 @@
"parent_account": d.parent_account,
"indent": d.indent,
"from_date": filters.from_date,
- "to_date": filters.to_date
+ "to_date": filters.to_date,
+ "currency": company_currency
}
prepare_opening_and_closing(d)
@@ -201,37 +204,50 @@
"fieldname": "opening_debit",
"label": _("Opening (Dr)"),
"fieldtype": "Currency",
+ "options": "currency",
"width": 120
},
{
"fieldname": "opening_credit",
"label": _("Opening (Cr)"),
"fieldtype": "Currency",
+ "options": "currency",
"width": 120
},
{
"fieldname": "debit",
"label": _("Debit"),
"fieldtype": "Currency",
+ "options": "currency",
"width": 120
},
{
"fieldname": "credit",
"label": _("Credit"),
"fieldtype": "Currency",
+ "options": "currency",
"width": 120
},
{
"fieldname": "closing_debit",
"label": _("Closing (Dr)"),
"fieldtype": "Currency",
+ "options": "currency",
"width": 120
},
{
"fieldname": "closing_credit",
"label": _("Closing (Cr)"),
"fieldtype": "Currency",
+ "options": "currency",
"width": 120
+ },
+ {
+ "fieldname": "currency",
+ "label": _("Currency"),
+ "fieldtype": "Link",
+ "options": "Currency",
+ "hidden": 1
}
]
diff --git a/erpnext/accounts/report/trial_balance_for_party/trial_balance_for_party.py b/erpnext/accounts/report/trial_balance_for_party/trial_balance_for_party.py
index ceabaab..58222ac 100644
--- a/erpnext/accounts/report/trial_balance_for_party/trial_balance_for_party.py
+++ b/erpnext/accounts/report/trial_balance_for_party/trial_balance_for_party.py
@@ -21,7 +21,7 @@
def get_data(filters, show_party_name):
party_name_field = "customer_name" if filters.get("party_type")=="Customer" else "supplier_name"
parties = frappe.get_all(filters.get("party_type"), fields = ["name", party_name_field], order_by="name")
-
+ company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
opening_balances = get_opening_balances(filters)
balances_within_period = get_balances_within_period(filters)
@@ -57,6 +57,10 @@
"closing_credit": closing_credit
})
+ row.update({
+ "currency": company_currency
+ })
+
has_value = False
if (opening_debit or opening_credit or debit or credit or closing_debit or closing_credit):
has_value =True
@@ -69,7 +73,8 @@
data.append({
"party": "'" + _("Totals") + "'",
"debit": total_debit,
- "credit": total_credit
+ "credit": total_credit,
+ "currency": company_currency
})
return data
@@ -138,37 +143,50 @@
"fieldname": "opening_debit",
"label": _("Opening (Dr)"),
"fieldtype": "Currency",
+ "options": "currency",
"width": 120
},
{
"fieldname": "opening_credit",
"label": _("Opening (Cr)"),
"fieldtype": "Currency",
+ "options": "currency",
"width": 120
},
{
"fieldname": "debit",
"label": _("Debit"),
"fieldtype": "Currency",
+ "options": "currency",
"width": 120
},
{
"fieldname": "credit",
"label": _("Credit"),
"fieldtype": "Currency",
+ "options": "currency",
"width": 120
},
{
"fieldname": "closing_debit",
"label": _("Closing (Dr)"),
"fieldtype": "Currency",
+ "options": "currency",
"width": 120
},
{
"fieldname": "closing_credit",
"label": _("Closing (Cr)"),
"fieldtype": "Currency",
+ "options": "currency",
"width": 120
+ },
+ {
+ "fieldname": "currency",
+ "label": _("Currency"),
+ "fieldtype": "Link",
+ "options": "Currency",
+ "hidden": 1
}
]
diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js
index b38b90e..8617a26 100644
--- a/erpnext/buying/doctype/purchase_common/purchase_common.js
+++ b/erpnext/buying/doctype/purchase_common/purchase_common.js
@@ -4,9 +4,8 @@
frappe.provide("erpnext.buying");
cur_frm.cscript.tax_table = "Purchase Taxes and Charges";
-{% include 'erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.js' %}
-frappe.require("assets/erpnext/js/controllers/transaction.js");
+{% include 'erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.js' %}
cur_frm.email_field = "contact_email";
@@ -129,12 +128,12 @@
item.rejected_qty = flt(item.received_qty - item.qty, precision("rejected_qty", item));
}
}
-
+
this._super(doc, cdt, cdn);
this.conversion_factor(doc, cdt, cdn);
-
+
},
-
+
received_qty: function(doc, cdt, cdn) {
var item = frappe.get_doc(cdt, cdn);
frappe.model.round_floats_in(item, ["qty", "received_qty"]);
@@ -142,7 +141,7 @@
item.qty = (item.qty < item.received_qty) ? item.qty : item.received_qty;
this.qty(doc, cdt, cdn);
},
-
+
rejected_qty: function(doc, cdt, cdn) {
var item = frappe.get_doc(cdt, cdn);
frappe.model.round_floats_in(item, ["received_qty", "rejected_qty"]);
@@ -152,7 +151,7 @@
__(frappe.meta.get_label(item.doctype, "received_qty", item.name))]));
item.qty = item.rejected_qty = 0.0;
} else {
-
+
item.qty = flt(item.received_qty - item.rejected_qty, precision("qty", item));
}
@@ -236,7 +235,7 @@
erpnext.utils.get_address_display(this.frm, "shipping_address",
"shipping_address_display", is_your_company_address=true)
},
-
+
tc_name: function() {
this.get_terms();
}
diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js
index b8002dd..7218531 100644
--- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js
+++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js
@@ -4,7 +4,7 @@
{% include 'erpnext/buying/doctype/purchase_common/purchase_common.js' %};
-frappe.require("assets/erpnext/js/utils.js");
+
frappe.ui.form.on("Request for Quotation",{
setup: function(frm){
diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js
index db8ab02..d502a3d 100644
--- a/erpnext/buying/doctype/supplier/supplier.js
+++ b/erpnext/buying/doctype/supplier/supplier.js
@@ -3,7 +3,6 @@
frappe.ui.form.on("Supplier", {
before_load: function(frm) {
- frm.hide_first = true;
frappe.setup_language_field(frm);
},
refresh: function(frm) {
diff --git a/erpnext/buying/report/purchase_order_trends/purchase_order_trends.js b/erpnext/buying/report/purchase_order_trends/purchase_order_trends.js
index dcf1df1..f7fe90f 100644
--- a/erpnext/buying/report/purchase_order_trends/purchase_order_trends.js
+++ b/erpnext/buying/report/purchase_order_trends/purchase_order_trends.js
@@ -1,8 +1,8 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-frappe.require("assets/erpnext/js/purchase_trends_filters.js");
-
-frappe.query_reports["Purchase Order Trends"] = {
- filters: get_filters()
- }
\ No newline at end of file
+frappe.require("assets/erpnext/js/purchase_trends_filters.js", function() {
+ frappe.query_reports["Purchase Order Trends"] = {
+ filters: get_filters()
+ }
+});
\ No newline at end of file
diff --git a/erpnext/config/accounts.py b/erpnext/config/accounts.py
index 72ed0f9..d0629e7 100644
--- a/erpnext/config/accounts.py
+++ b/erpnext/config/accounts.py
@@ -221,6 +221,11 @@
"name": "Period Closing Voucher",
"description": _("Close Balance Sheet and book Profit or Loss.")
},
+ {
+ "type": "doctype",
+ "name": "Asset Movement",
+ "description": _("Transfer an asset from one warehouse to another")
+ },
]
},
{
diff --git a/erpnext/crm/doctype/opportunity/opportunity.js b/erpnext/crm/doctype/opportunity/opportunity.js
index 337b631..c918dad 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.js
+++ b/erpnext/crm/doctype/opportunity/opportunity.js
@@ -2,7 +2,7 @@
// License: GNU General Public License v3. See license.txt
frappe.provide("erpnext.crm");
-frappe.require("assets/erpnext/js/utils.js");
+
cur_frm.email_field = "contact_email";
frappe.ui.form.on("Opportunity", {
customer: function(frm) {
diff --git a/erpnext/docs/assets/img/accounts/asset-graph.png b/erpnext/docs/assets/img/accounts/asset-graph.png
new file mode 100644
index 0000000..5b300bb
--- /dev/null
+++ b/erpnext/docs/assets/img/accounts/asset-graph.png
Binary files differ
diff --git a/erpnext/docs/assets/img/accounts/asset-movement-using-button.png b/erpnext/docs/assets/img/accounts/asset-movement-using-button.png
new file mode 100644
index 0000000..b9ca68d
--- /dev/null
+++ b/erpnext/docs/assets/img/accounts/asset-movement-using-button.png
Binary files differ
diff --git a/erpnext/docs/assets/img/accounts/asset-movement.png b/erpnext/docs/assets/img/accounts/asset-movement.png
new file mode 100644
index 0000000..39f7b34
--- /dev/null
+++ b/erpnext/docs/assets/img/accounts/asset-movement.png
Binary files differ
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 2acdd37..1cdbd1e 100644
--- a/erpnext/docs/user/manual/en/accounts/managing-fixed-assets.md
+++ b/erpnext/docs/user/manual/en/accounts/managing-fixed-assets.md
@@ -45,6 +45,10 @@
In the depreciation entry, the "Accumulated Depreciation Account" is credited and "Depreciation Expense Account" is debited. The related accounts can be set in the Asset Category or Company.
+For better visibility, net value of the asset on different depreciation dates are shown in a line graph.
+
+<img class="screenshot" alt="Asset" src="{{docs_base_url}}/assets/img/accounts/asset-graph.png">
+
## Purchase an asset
@@ -71,4 +75,14 @@
You can scrap an asset anytime using the "Scrap Asset" button in the Asset record. The "Gain/Loss Account on Asset Disposal" mentioned in the Company is debited by the Current Value (After Depreciation) of the asset. After scrapping, you can also restore the asset using "Restore Asset" button.
-<img class="screenshot" alt="Asset" src="{{docs_base_url}}/assets/img/accounts/scrap-journal-entry.png">
\ No newline at end of file
+<img class="screenshot" alt="Asset" src="{{docs_base_url}}/assets/img/accounts/scrap-journal-entry.png">
+
+## Asset Movement
+
+The movement of the assets (from one warehouse to another) is also tracked via Asset Movement form.
+
+<img class="screenshot" alt="Asset" src="{{docs_base_url}}/assets/img/accounts/asset-movement.png">
+
+There is also a dedicated button "Transfer Asset" inside the Asset form to track the Asset Movement.
+
+<img class="screenshot" alt="Asset" src="{{docs_base_url}}/assets/img/accounts/asset-movement-using-button.png">
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/customize-erpnext/articles/making-custom-reports-in-erpnext.md b/erpnext/docs/user/manual/en/customize-erpnext/articles/making-custom-reports-in-erpnext.md
index 46af27e..7bc965b 100644
--- a/erpnext/docs/user/manual/en/customize-erpnext/articles/making-custom-reports-in-erpnext.md
+++ b/erpnext/docs/user/manual/en/customize-erpnext/articles/making-custom-reports-in-erpnext.md
@@ -12,12 +12,12 @@
Query Report is written in SQL which pull values from account's database and fetch in the report. Though SQL queries can be written from front end, like HTML, its restricted in hosted users. Because it will allow users with no access to specific report to query data directly from the database.
-Check Purchase Order Item to be Received report in Stock module for example of Query report. Click [here](https://frappe.github.io/frappe/user/guides/reports-and-printing/how-to-make-query-report.html) to learn how to create Query Report.
+Check Purchase Order Item to be Received report in Stock module for example of Query report. Click [here](https://frappe.github.io/frappe/user/en/guides/reports-and-printing/how-to-make-query-report.html) to learn how to create Query Report.
### 3. Script Report
Script Reports are written in Python and stored on server side. These are complex reports which involves logic and calculation. Since these reports are written on server side, customizing it from hosted account is not possible.
-Check Financial Analytics report in Accounts module for example of Script Report. Click [here](https://frappe.github.io/frappe/user/guides/reports-and-printing/how-to-make-script-reports.html) to learn how to create Script Report.
+Check Financial Analytics report in Accounts module for example of Script Report. Click [here](https://frappe.github.io/frappe/user/en/guides/reports-and-printing/how-to-make-script-reports.html) to learn how to create Script Report.
<!-- markdown -->
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/setting-up/articles/integrating-erpnext-with-other-application.md b/erpnext/docs/user/manual/en/setting-up/articles/integrating-erpnext-with-other-application.md
index 2d2c179..3cbf159 100644
--- a/erpnext/docs/user/manual/en/setting-up/articles/integrating-erpnext-with-other-application.md
+++ b/erpnext/docs/user/manual/en/setting-up/articles/integrating-erpnext-with-other-application.md
@@ -2,6 +2,6 @@
For now, ERPNext has out-of-the-box integration available for some applications like Shopify, your SMS gateway and payment gateway. To integrate ERPNext with other application, you can use REST API of Frappe. Check following links to learn more about REST API of Frappe.
-[Frappe Rest API](https://frappe.github.io/frappe/user/guides/integration/rest_api.html)
+[Frappe Rest API](https://frappe.github.io/frappe/user/en/guides/integration/rest_api.html)
<!-- markdown -->
\ No newline at end of file
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 85fee1f..2be21d6 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -7,7 +7,7 @@
app_description = """ERP made simple"""
app_icon = "icon-th"
app_color = "#e74c3c"
-app_version = "6.27.11"
+app_version = "6.27.15"
app_email = "info@erpnext.com"
app_license = "GNU General Public License (v3)"
source_link = "https://github.com/frappe/erpnext"
@@ -32,6 +32,8 @@
on_session_creation = "erpnext.shopping_cart.utils.set_cart_count"
on_logout = "erpnext.shopping_cart.utils.clear_cart_count"
+remember_selected = ['Company', 'Cost Center', 'Project']
+
# website
update_website_context = "erpnext.shopping_cart.utils.update_website_context"
my_account_context = "erpnext.shopping_cart.utils.update_my_account_context"
diff --git a/erpnext/hr/doctype/employee/employee.js b/erpnext/hr/doctype/employee/employee.js
index a7198e3..8857bad 100755
--- a/erpnext/hr/doctype/employee/employee.js
+++ b/erpnext/hr/doctype/employee/employee.js
@@ -4,7 +4,6 @@
frappe.provide("erpnext.hr");
erpnext.hr.EmployeeController = frappe.ui.form.Controller.extend({
setup: function() {
- this.frm.hide_first = true;
this.frm.fields_dict.user_id.get_query = function(doc, cdt, cdn) {
return { query:"frappe.core.doctype.user.user.user_query"} }
this.frm.fields_dict.reports_to.get_query = function(doc, cdt, cdn) {
diff --git a/erpnext/hr/doctype/process_payroll/process_payroll.py b/erpnext/hr/doctype/process_payroll/process_payroll.py
index a71200c..51e3740 100644
--- a/erpnext/hr/doctype/process_payroll/process_payroll.py
+++ b/erpnext/hr/doctype/process_payroll/process_payroll.py
@@ -206,3 +206,5 @@
'month_end_date': med,
'month_days': month_days
})
+ else:
+ frappe.throw(_("Fiscal Year {0} not found").format(year))
\ No newline at end of file
diff --git a/erpnext/hr/doctype/upload_attendance/upload_attendance.js b/erpnext/hr/doctype/upload_attendance/upload_attendance.js
index 47ffec0..c49720c 100644
--- a/erpnext/hr/doctype/upload_attendance/upload_attendance.js
+++ b/erpnext/hr/doctype/upload_attendance/upload_attendance.js
@@ -2,7 +2,7 @@
// License: GNU General Public License v3. See license.txt
-frappe.require("assets/erpnext/js/utils.js");
+
frappe.provide("erpnext.hr");
erpnext.hr.AttendanceControlPanel = frappe.ui.form.Controller.extend({
diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js
index 5b97397..710862b 100644
--- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js
+++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js
@@ -1,7 +1,7 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-frappe.require("assets/erpnext/js/utils.js");
+
cur_frm.cscript.onload = function(doc) {
cur_frm.set_value("company", frappe.defaults.get_user_default("Company"))
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index ccc4629..3ee0158 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -169,7 +169,7 @@
erpnext.patches.v6_0.multi_currency
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
+erpnext.patches.v5_0.reset_values_in_tools # 02-05-2016
execute:frappe.delete_doc("Page", "users")
erpnext.patches.v5_0.update_material_transferred_for_manufacturing_again
erpnext.patches.v5_0.index_on_account_and_gl_entry
@@ -259,7 +259,6 @@
erpnext.patches.v6_24.map_customer_address_to_shipping_address_on_po
erpnext.patches.v6_27.fix_recurring_order_status
erpnext.patches.v6_20x.remove_customer_supplier_roles
-erpnext.patches.v6_24.rename_item_field
erpnext.patches.v7_0.update_party_status
erpnext.patches.v7_0.update_item_projected
erpnext.patches.v6_20x.update_product_bundle_description
diff --git a/erpnext/patches/v5_0/reset_values_in_tools.py b/erpnext/patches/v5_0/reset_values_in_tools.py
index 2825e4f..5aac83e 100644
--- a/erpnext/patches/v5_0/reset_values_in_tools.py
+++ b/erpnext/patches/v5_0/reset_values_in_tools.py
@@ -6,6 +6,7 @@
def execute():
for dt in ["Payment Tool", "Bank Reconciliation", "Payment Reconciliation", "Leave Control Panel",
- "Salary Manager", "Upload Attenadance", "Production Planning Tool", "BOM Replace Tool"]:
+ "Salary Manager", "Upload Attenadance", "Production Planning Tool", "BOM Replace Tool", "Customize Form",
+ "Employee Attendance Tool", "Rename Tool", "BOM Replace Tool", "Process Payroll", "Naming Series"]:
frappe.db.sql("delete from `tabSingles` where doctype=%s", dt)
\ No newline at end of file
diff --git a/erpnext/projects/doctype/project/project.js b/erpnext/projects/doctype/project/project.js
index 6f0da36..4835287 100644
--- a/erpnext/projects/doctype/project/project.js
+++ b/erpnext/projects/doctype/project/project.js
@@ -3,8 +3,6 @@
frappe.ui.form.on("Project", {
onload: function(frm) {
- frm.hide_first = true;
-
var so = frappe.meta.get_docfield("Project", "sales_order");
so.get_route_options_for_new_doc = function(field) {
if(frm.is_new()) return;
@@ -45,22 +43,32 @@
});
}
- frm.dashboard.show_dashboard();
- frm.dashboard.add_section(frappe.render_template('project_dashboard', {project: frm.doc}));
-
- // var bars = [];
- // bars.push({
- // 'title': __('Percent Complete'),
- // 'width': (frm.doc.percent_complete || 1) + '%',
- // 'progress_class': 'progress-bar-success'
- // })
- //
- // var message = __("{0}% complete", [frm.doc.percent_complete]);
- //
- // frm.dashboard.add_progress(__('Status'), bars, message);
-
+ frm.trigger('show_dashboard');
}
+ },
+ show_dashboard: function(frm) {
+ frm.dashboard.show_heatmap = true;
+ frm.dashboard.heatmap_message = __('This is based on the Time Logs created against this project');
+ frm.dashboard.show_dashboard();
+ if(frm.doc.__onload.activity_summary.length) {
+ var hours = $.map(frm.doc.__onload.activity_summary, function(d) { return d.total_hours });
+ var max_count = Math.max.apply(null, hours);
+ var sum = hours.reduce(function(a, b) { return a + b; }, 0);
+ var section = frm.dashboard.add_section(
+ frappe.render_template('project_dashboard',
+ {
+ data: frm.doc.__onload.activity_summary,
+ max_count: max_count,
+ sum: sum
+ }));
+
+ section.on('click', '.time-log-link', function() {
+ var activity_type = $(this).attr('data-activity_type');
+ frappe.set_route('List', 'Time Log',
+ {'activity_type': activity_type, 'project': frm.doc.name});
+ });
+ }
}
});
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index 4f78a59..e7f5b7a 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -27,6 +27,8 @@
})
self.set_onload('links', self.meta.get_links_setup())
+ self.set_onload('activity_summary', frappe.db.sql('''select activity_type, sum(hours) as total_hours
+ from `tabTime Log` where project=%s group by activity_type order by total_hours desc''', self.name, as_dict=True))
def __setup__(self):
self.onload()
@@ -154,8 +156,17 @@
from frappe.desk.notifications import get_open_count
return {
'count': get_open_count('Project', name),
+ 'timeline_data': get_timeline_data(name)
}
+def get_timeline_data(name):
+ '''Return timeline for attendance'''
+ return dict(frappe.db.sql('''select unix_timestamp(from_time), count(*)
+ from `tabTime Log` where project=%s
+ and from_time > date_sub(curdate(), interval 1 year)
+ and docstatus < 2
+ group by date(from_time)''', name))
+
def get_project_list(doctype, txt, filters, limit_start, limit_page_length=20):
return frappe.db.sql('''select distinct project.*
from tabProject project, `tabProject User` project_user
diff --git a/erpnext/projects/doctype/project/project_dashboard.html b/erpnext/projects/doctype/project/project_dashboard.html
index efd6861..34a2d04 100644
--- a/erpnext/projects/doctype/project/project_dashboard.html
+++ b/erpnext/projects/doctype/project/project_dashboard.html
@@ -1,10 +1,26 @@
-<h5 style="margin-top: 0px;">Tasks</h5>
-{% if(project.tasks.length) { %}
- {% project.tasks.forEach(function(d) { %}
- <p><span class="indicator {{
- {"Open": "red", "Closed": "green", "Cancelled": "darkgrey"}[d.status] || "orange" }}"><a style="font-weight: normal"
- href="#Form/Task/{{ d.task_id }}">{{ d.title }}</a></span></p>
- {% }); %}
-{% } else { %}
- <p class="text-muted small">No Tasks Defined</p>
-{% } %}
\ No newline at end of file
+<h5 style="margin-top: 0px;">Activity Summary</h5>
+<h6 style="margin-bottom: 25px;">{{ __("Total hours: {0}", [flt(sum, 2) ]) }}</h6>
+{% for d in data %}
+<div class="row">
+ <div class="col-xs-4">
+ <a class="small time-log-link" data-activity_type="{{ d.activity_type || "" }}">
+ {{ d.activity_type || __("Unknown") }}</a>
+ </div>
+ <div class="col-xs-8">
+ <span class="inline-graph">
+ <span class="inline-graph-half">
+ </span>
+ <span class="inline-graph-half" title="{{ __("hours") }}">
+ <span class="inline-graph-count">
+ {{ __("{0} hours", [flt(d.total_hours, 2)]) }}
+ </span>
+ <span class="inline-graph-bar">
+ <span class="inline-graph-bar-inner dark"
+ style="width: {{ cint(d.total_hours/max_count * 100) }}%">
+ </span>
+ </span>
+ </span>
+ </span>
+ </div>
+</div>
+{% endfor %}
\ No newline at end of file
diff --git a/erpnext/projects/doctype/time_log/time_log.js b/erpnext/projects/doctype/time_log/time_log.js
index 7648a53..10e3bc7 100644
--- a/erpnext/projects/doctype/time_log/time_log.js
+++ b/erpnext/projects/doctype/time_log/time_log.js
@@ -1,111 +1,105 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-frappe.provide("erpnext.projects");
-
-frappe.ui.form.on("Time Log", "onload", function(frm) {
- if (frm.doc.__islocal) {
- if (frm.doc.for_manufacturing) {
- frappe.ui.form.trigger("Time Log", "production_order");
+frappe.ui.form.on("Time Log", {
+ onload: function(frm) {
+ if (frm.doc.__islocal) {
+ if (frm.doc.for_manufacturing) {
+ frappe.ui.form.trigger("Time Log", "production_order");
+ }
+ if (frm.doc.from_time && frm.doc.to_time) {
+ frappe.ui.form.trigger("Time Log", "to_time");
+ }
}
- if (frm.doc.from_time && frm.doc.to_time) {
- frappe.ui.form.trigger("Time Log", "to_time");
- }
- }
-});
-
-frappe.ui.form.on("Time Log", "refresh", function(frm) {
- // set default user if created
- if (frm.doc.__islocal && !frm.doc.user) {
- frm.set_value("user", user);
- }
-
- frm.toggle_reqd("activity_type", !frm.doc.for_manufacturing);
-});
-
-
-// set to time if hours is updated
-frappe.ui.form.on("Time Log", "hours", function(frm) {
- if(!frm.doc.from_time) {
- frm.set_value("from_time", frappe.datetime.now_datetime());
- }
- var d = moment(frm.doc.from_time);
- d.add(frm.doc.hours, "hours");
- frm._setting_hours = true;
- frm.set_value("to_time", d.format(moment.defaultDatetimeFormat));
- frm._setting_hours = false;
-});
-
-// clear production order if making time log
-frappe.ui.form.on("Time Log", "before_save", function(frm) {
- frm.doc.production_order && frappe.model.remove_from_locals("Production Order",
- frm.doc.production_order);
-});
-
-// set hours if to_time is updated
-frappe.ui.form.on("Time Log", "to_time", function(frm) {
- if(frm._setting_hours) return;
- frm.set_value("hours", moment(cur_frm.doc.to_time).diff(moment(cur_frm.doc.from_time),
- "seconds") / 3600);
-
-});
-
-var calculate_cost = function(frm) {
- frm.set_value("costing_amount", frm.doc.costing_rate * frm.doc.hours);
- if (frm.doc.billable==1){
- frm.set_value("billing_amount", (frm.doc.billing_rate * frm.doc.hours) + frm.doc.additional_cost);
- }
-}
-
-var get_activity_cost = function(frm) {
- if (frm.doc.activity_type){
- return frappe.call({
- method: "erpnext.projects.doctype.time_log.time_log.get_activity_cost",
- args: {
- "employee": frm.doc.employee,
- "activity_type": frm.doc.activity_type
- },
- callback: function(r) {
- if(!r.exc && r.message) {
- frm.set_value("costing_rate", r.message.costing_rate);
- frm.set_value("billing_rate", r.message.billing_rate);
- calculate_cost(frm);
+ frm.set_query('task', function() {
+ return {
+ filters:{
+ 'project': frm.doc.project
}
}
});
- }
-}
+ },
+ refresh: function(frm) {
+ // set default user if created
+ if (frm.doc.__islocal && !frm.doc.user) {
+ frm.set_value("user", user);
+ }
+ if (frm.doc.status==='In Progress' && !frm.is_new()) {
+ frm.add_custom_button(__('Finish'), function() {
+ frappe.prompt({
+ fieldtype: 'Datetime',
+ fieldname: 'to_time',
+ label: __('End Time'),
+ 'default': dateutil.now_datetime()
+ }, function(value) {
+ frm.set_value('to_time', value.to_time);
+ frm.save();
+ });
+ }).addClass('btn-primary');
+ }
-frappe.ui.form.on("Time Log", "hours", function(frm) {
- calculate_cost(frm);
-});
-frappe.ui.form.on("Time Log", "additional_cost", function(frm) {
- calculate_cost(frm);
-});
+ frm.toggle_reqd("activity_type", !frm.doc.for_manufacturing);
+ },
+ hours: function(frm) {
+ if(!frm.doc.from_time) {
+ frm.set_value("from_time", frappe.datetime.now_datetime());
+ }
+ var d = moment(frm.doc.from_time);
+ d.add(frm.doc.hours, "hours");
+ frm._setting_hours = true;
+ frm.set_value("to_time", d.format(moment.defaultDatetimeFormat));
+ frm._setting_hours = false;
-frappe.ui.form.on("Time Log", "activity_type", function(frm) {
- get_activity_cost(frm);
-});
-
-frappe.ui.form.on("Time Log", "employee", function(frm) {
- get_activity_cost(frm);
-});
-
-frappe.ui.form.on("Time Log", "billable", function(frm) {
- if (frm.doc.billable==1) {
- calculate_cost(frm);
- }
- else {
- frm.set_value("billing_amount", 0);
- frm.set_value("additional_cost", 0);
- }
-});
-
-cur_frm.fields_dict['task'].get_query = function(doc) {
- return {
- filters:{
- 'project': doc.project
+ frm.trigger('calculate_cost');
+ },
+ before_save: function(frm) {
+ frm.doc.production_order && frappe.model.remove_from_locals("Production Order",
+ frm.doc.production_order);
+ },
+ to_time: function(frm) {
+ if(frm._setting_hours) return;
+ frm.set_value("hours", moment(cur_frm.doc.to_time).diff(moment(cur_frm.doc.from_time),
+ "seconds") / 3600);
+ },
+ calculate_cost: function(frm) {
+ frm.set_value("costing_amount", frm.doc.costing_rate * frm.doc.hours);
+ if (frm.doc.billable==1){
+ frm.set_value("billing_amount", (frm.doc.billing_rate * frm.doc.hours) + frm.doc.additional_cost);
+ }
+ },
+ additional_cost: function(frm) {
+ frm.trigger('calculate_cost');
+ },
+ activity_type: function(frm) {
+ if (frm.doc.activity_type){
+ return frappe.call({
+ method: "erpnext.projects.doctype.time_log.time_log.get_activity_cost",
+ args: {
+ "employee": frm.doc.employee,
+ "activity_type": frm.doc.activity_type
+ },
+ callback: function(r) {
+ if(!r.exc && r.message) {
+ frm.set_value("costing_rate", r.message.costing_rate);
+ frm.set_value("billing_rate", r.message.billing_rate);
+ frm.trigger('calculate_cost');
+ }
+ }
+ });
+ }
+ },
+ employee: function(frm) {
+ frm.trigger('activity_type');
+ },
+ billable: function(frm) {
+ if (frm.doc.billable==1) {
+ frm.trigger('calculate_cost');
+ }
+ else {
+ frm.set_value("billing_amount", 0);
+ frm.set_value("additional_cost", 0);
}
}
-}
+
+});
diff --git a/erpnext/projects/doctype/time_log/time_log.json b/erpnext/projects/doctype/time_log/time_log.json
index 050fc54..25d62c4 100644
--- a/erpnext/projects/doctype/time_log/time_log.json
+++ b/erpnext/projects/doctype/time_log/time_log.json
@@ -89,7 +89,7 @@
},
{
"allow_on_submit": 0,
- "bold": 0,
+ "bold": 1,
"collapsible": 0,
"depends_on": "",
"fieldname": "project",
@@ -115,7 +115,7 @@
},
{
"allow_on_submit": 0,
- "bold": 0,
+ "bold": 1,
"collapsible": 0,
"depends_on": "",
"fieldname": "task",
@@ -153,7 +153,7 @@
"label": "Status",
"length": 0,
"no_copy": 0,
- "options": "Draft\nSubmitted\nBatched for Billing\nBilled\nCancelled",
+ "options": "In Progress\nTo Submit\nSubmitted\nBatched for Billing\nBilled\nCancelled",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@@ -190,8 +190,9 @@
},
{
"allow_on_submit": 0,
- "bold": 0,
+ "bold": 1,
"collapsible": 0,
+ "default": "now",
"fieldname": "from_time",
"fieldtype": "Datetime",
"hidden": 0,
@@ -239,7 +240,7 @@
},
{
"allow_on_submit": 0,
- "bold": 0,
+ "bold": 1,
"collapsible": 0,
"fieldname": "to_time",
"fieldtype": "Datetime",
@@ -256,7 +257,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
@@ -460,7 +461,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "depends_on": "eval:doc.for_manufacturing",
+ "depends_on": "for_manufacturing",
"fieldname": "section_break_11",
"fieldtype": "Section Break",
"hidden": 0,
@@ -644,7 +645,8 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "depends_on": "",
+ "collapsible_depends_on": "",
+ "depends_on": "costing_rate",
"fieldname": "section_break_24",
"fieldtype": "Section Break",
"hidden": 0,
@@ -652,6 +654,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "label": "Cost",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -747,6 +750,7 @@
"bold": 0,
"collapsible": 0,
"default": "0",
+ "depends_on": "billable",
"description": "",
"fieldname": "billing_rate",
"fieldtype": "Currency",
@@ -800,6 +804,7 @@
"bold": 0,
"collapsible": 0,
"default": "0",
+ "depends_on": "billable",
"description": "Will be updated only if Time Log is 'Billable'",
"fieldname": "billing_amount",
"fieldtype": "Currency",
@@ -934,7 +939,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-04-15 07:51:03.097280",
+ "modified": "2016-04-29 05:19:18.247260",
"modified_by": "Administrator",
"module": "Projects",
"name": "Time Log",
diff --git a/erpnext/projects/doctype/time_log/time_log.py b/erpnext/projects/doctype/time_log/time_log.py
index e2641eb..9545bd7 100644
--- a/erpnext/projects/doctype/time_log/time_log.py
+++ b/erpnext/projects/doctype/time_log/time_log.py
@@ -45,16 +45,19 @@
def set_status(self):
self.status = {
- 0: "Draft",
+ 0: "To Submit",
1: "Submitted",
2: "Cancelled"
}[self.docstatus or 0]
+ if not self.to_time:
+ self.status = 'In Progress'
+
if self.time_log_batch:
- self.status="Batched for Billing"
+ self.status= "Batched for Billing"
if self.sales_invoice:
- self.status="Billed"
+ self.status= "Billed"
def set_title(self):
"""Set default title for the Time Log"""
@@ -88,8 +91,8 @@
existing = frappe.db.sql("""select name, from_time, to_time from `tabTime Log`
where `{0}`=%(val)s and
(
- (%(from_time)s > from_time and %(from_time)s < to_time) or
- (%(to_time)s > from_time and %(to_time)s < to_time) or
+ (%(from_time)s > from_time and %(from_time)s < to_time) or
+ (%(to_time)s > from_time and %(to_time)s < to_time) or
(%(from_time)s <= from_time and %(to_time)s >= to_time))
and name!=%(name)s
and docstatus < 2""".format(fieldname),
@@ -233,7 +236,7 @@
self.billing_amount = self.billing_rate * self.hours
else:
self.billing_amount = 0
-
+
if self.additional_cost and self.billable:
self.billing_amount += self.additional_cost
@@ -247,11 +250,11 @@
elif self.project:
frappe.get_doc("Project", self.project).update_project()
-
+
def has_webform_permission(doc):
project_user = frappe.db.get_value("Project User", {"parent": doc.project, "user":frappe.session.user} , "user")
if project_user:
- return True
+ return True
@frappe.whitelist()
diff --git a/erpnext/projects/doctype/time_log/time_log_list.js b/erpnext/projects/doctype/time_log/time_log_list.js
index 5396928..e9e7d05 100644
--- a/erpnext/projects/doctype/time_log/time_log_list.js
+++ b/erpnext/projects/doctype/time_log/time_log_list.js
@@ -4,9 +4,15 @@
// render
frappe.listview_settings['Time Log'] = {
add_fields: ["status", "billable", "activity_type", "task", "project", "hours", "for_manufacturing", "billing_amount"],
-
+
+ has_indicator_for_draft: true,
+
get_indicator: function(doc) {
- if (doc.status== "Batched for Billing") {
+ if (doc.status== "Draft") {
+ return [__("Draft"), "red", "status,=,Draft"]
+ } else if (doc.status== "In Progress") {
+ return [__("In Progress"), "orange", "status,=,In Progress"]
+ } else if (doc.status== "Batched for Billing") {
return [__("Batched for Billing"), "darkgrey", "status,=,Batched for Billing"]
} else if (doc.status== "Billed") {
return [__("Billed"), "green", "status,=,Billed"]
@@ -14,7 +20,7 @@
return [__("Billable"), "orange", "billable,=,1"]
}
},
-
+
selectable: true,
onload: function(me) {
me.page.add_menu_item(__("Make Time Log Batch"), function() {
diff --git a/erpnext/public/build.json b/erpnext/public/build.json
index 16e7488..1831907 100644
--- a/erpnext/public/build.json
+++ b/erpnext/public/build.json
@@ -11,16 +11,24 @@
"public/js/feature_setup.js",
"public/js/utils.js",
"public/js/queries.js",
+ "public/js/sms_manager.js",
"public/js/utils/party.js",
"public/js/templates/address_list.html",
"public/js/templates/contact_list.html",
+ "public/js/controllers/stock_controller.js",
+ "public/js/controllers/taxes_and_totals.js",
+ "public/js/controllers/transaction.js",
"public/js/pos/pos.html",
"public/js/pos/pos_bill_item.html",
"public/js/pos/pos_item.html",
"public/js/pos/pos_tax_row.html",
"public/js/pos/pos.js",
- "public/js/utils/item_selector.js",
- "public/js/utils/inventory.js",
- "public/js/templates/item_selector.html"
+ "public/js/templates/item_selector.html",
+ "public/js/utils/item_selector.js"
+ ],
+ "js/item-dashboard.min.js": [
+ "stock/dashboard/item_dashboard.html",
+ "stock/dashboard/item_dashboard_list.html",
+ "stock/dashboard/item_dashboard.js"
]
}
diff --git a/erpnext/public/css/erpnext.css b/erpnext/public/css/erpnext.css
index 75fab56..6777e1e 100644
--- a/erpnext/public/css/erpnext.css
+++ b/erpnext/public/css/erpnext.css
@@ -107,7 +107,7 @@
}
.erpnext-icon {
width: 24px;
- margin-right: 0px;
+ ackmargin-right: 0px;
margin-top: -3px;
}
.pos .discount-amount-area .discount-field-col {
@@ -116,3 +116,11 @@
.pos .discount-amount-area .input-group {
margin-top: 2px;
}
+.dashboard-list-item {
+ background-color: inherit;
+ padding: 7px 15px;
+ border-bottom: 1px solid #d1d8dd;
+}
+.dashboard-list-item:last-child {
+ border-bottom: none;
+}
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index b4e712a..1a234a3 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -1,9 +1,6 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-frappe.provide("erpnext");
-frappe.require("assets/erpnext/js/controllers/stock_controller.js");
-
erpnext.taxes_and_totals = erpnext.stock.StockController.extend({
calculate_taxes_and_totals: function(update_paid_amount) {
this.discount_amount_applied = false;
@@ -59,7 +56,7 @@
"to_currency": company_currency
}));
}
-
+
}
},
@@ -256,7 +253,7 @@
me.round_off_totals(tax);
// adjust Discount Amount loss in last tax iteration
- if ((i == me.frm.doc["taxes"].length - 1) && me.discount_amount_applied
+ if ((i == me.frm.doc["taxes"].length - 1) && me.discount_amount_applied
&& me.frm.doc.apply_discount_on == "Grand Total" && me.frm.doc.discount_amount)
me.adjust_discount_amount_loss(tax);
}
@@ -321,10 +318,10 @@
tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount +
discount_amount_loss, precision("tax_amount", tax));
tax.total = flt(tax.total + discount_amount_loss, precision("total", tax));
-
+
this.set_in_company_currency(tax, ["total", "tax_amount_after_discount_amount"]);
},
-
+
manipulate_grand_total_for_inclusive_tax: function() {
var me = this;
// if fully inclusive taxes and diff
@@ -342,8 +339,8 @@
last_tax.tax_amount += diff;
last_tax.tax_amount_after_discount += diff;
last_tax.total += diff;
-
- this.set_in_company_currency(last_tax,
+
+ this.set_in_company_currency(last_tax,
["total", "tax_amount", "tax_amount_after_discount_amount"]);
}
}
@@ -392,14 +389,14 @@
// rounded totals
if(frappe.meta.get_docfield(this.frm.doc.doctype, "rounded_total", this.frm.doc.name)) {
- this.frm.doc.rounded_total = round_based_on_smallest_currency_fraction(this.frm.doc.grand_total,
+ this.frm.doc.rounded_total = round_based_on_smallest_currency_fraction(this.frm.doc.grand_total,
this.frm.doc.currency, precision("rounded_total"));
}
if(frappe.meta.get_docfield(this.frm.doc.doctype, "base_rounded_total", this.frm.doc.name)) {
var company_currency = this.get_company_currency();
-
- this.frm.doc.base_rounded_total =
- round_based_on_smallest_currency_fraction(this.frm.doc.base_grand_total,
+
+ this.frm.doc.base_rounded_total =
+ round_based_on_smallest_currency_fraction(this.frm.doc.base_grand_total,
company_currency, precision("base_rounded_total"));
}
},
@@ -497,28 +494,28 @@
this.calculate_outstanding_amount(update_paid_amount);
},
-
+
calculate_outstanding_amount: function(update_paid_amount) {
// NOTE:
// paid_amount and write_off_amount is only for POS Invoice
// total_advance is only for non POS Invoice
if(this.frm.doc.is_return || this.frm.doc.docstatus > 0) return;
-
+
frappe.model.round_floats_in(this.frm.doc, ["grand_total", "total_advance", "write_off_amount"]);
- if(this.frm.doc.party_account_currency == this.frm.doc.currency) {
- var total_amount_to_pay = flt((this.frm.doc.grand_total - this.frm.doc.total_advance
+ if(this.frm.doc.party_account_currency == this.frm.doc.currency) {
+ var total_amount_to_pay = flt((this.frm.doc.grand_total - this.frm.doc.total_advance
- this.frm.doc.write_off_amount), precision("grand_total"));
} else {
var total_amount_to_pay = flt(
- (flt(this.frm.doc.grand_total*this.frm.doc.conversion_rate, precision("grand_total"))
- - this.frm.doc.total_advance - this.frm.doc.base_write_off_amount),
+ (flt(this.frm.doc.grand_total*this.frm.doc.conversion_rate, precision("grand_total"))
+ - this.frm.doc.total_advance - this.frm.doc.base_write_off_amount),
precision("base_grand_total")
);
}
-
+
if(this.frm.doc.doctype == "Sales Invoice" || this.frm.doc.doctype == "Purchase Invoice") {
frappe.model.round_floats_in(this.frm.doc, ["paid_amount"]);
-
+
if(this.frm.doc.is_pos || this.frm.doc.is_paid) {
if(!this.frm.doc.paid_amount || update_paid_amount===undefined || update_paid_amount) {
this.frm.doc.paid_amount = flt(total_amount_to_pay);
@@ -529,16 +526,16 @@
this.set_in_company_currency(this.frm.doc, ["paid_amount"]);
this.frm.refresh_field("paid_amount");
this.frm.refresh_field("base_paid_amount");
-
- var paid_amount = (this.frm.doc.party_account_currency == this.frm.doc.currency) ?
+
+ var paid_amount = (this.frm.doc.party_account_currency == this.frm.doc.currency) ?
this.frm.doc.paid_amount : this.frm.doc.base_paid_amount;
-
- var outstanding_amount = flt(total_amount_to_pay - flt(paid_amount),
+
+ var outstanding_amount = flt(total_amount_to_pay - flt(paid_amount),
precision("outstanding_amount"));
-
+
} else if(this.frm.doc.doctype == "Purchase Invoice") {
var outstanding_amount = flt(total_amount_to_pay, precision("outstanding_amount"));
- }
+ }
this.frm.set_value("outstanding_amount", outstanding_amount);
}
})
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 78584fa..3f6ea5a 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -1,11 +1,85 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-frappe.provide("erpnext");
-frappe.require("assets/erpnext/js/controllers/taxes_and_totals.js");
-frappe.require("assets/erpnext/js/utils.js");
-
erpnext.TransactionController = erpnext.taxes_and_totals.extend({
+ setup: function() {
+ frappe.ui.form.on(this.frm.doctype + " Item", "rate", function(frm, cdt, cdn) {
+ var item = frappe.get_doc(cdt, cdn);
+ frappe.model.round_floats_in(item, ["rate", "price_list_rate"]);
+
+ if(item.price_list_rate) {
+ item.discount_percentage = flt((1 - item.rate / item.price_list_rate) * 100.0, precision("discount_percentage", item));
+ } else {
+ item.discount_percentage = 0.0;
+ }
+
+ cur_frm.cscript.set_gross_profit(item);
+ cur_frm.cscript.calculate_taxes_and_totals();
+ })
+
+ frappe.ui.form.on(this.frm.cscript.tax_table, "rate", function(frm, cdt, cdn) {
+ cur_frm.cscript.calculate_taxes_and_totals();
+ });
+
+ frappe.ui.form.on(this.frm.cscript.tax_table, "tax_amount", function(frm, cdt, cdn) {
+ cur_frm.cscript.calculate_taxes_and_totals();
+ });
+
+ frappe.ui.form.on(this.frm.cscript.tax_table, "row_id", function(frm, cdt, cdn) {
+ cur_frm.cscript.calculate_taxes_and_totals();
+ });
+
+ frappe.ui.form.on(this.frm.cscript.tax_table, "included_in_print_rate", function(frm, cdt, cdn) {
+ cur_frm.cscript.set_dynamic_labels();
+ cur_frm.cscript.calculate_taxes_and_totals();
+ });
+
+ frappe.ui.form.on(this.frm.doctype, "apply_discount_on", function(frm) {
+ if(frm.doc.additional_discount_percentage) {
+ frm.trigger("additional_discount_percentage");
+ } else {
+ cur_frm.cscript.calculate_taxes_and_totals();
+ }
+ });
+
+ frappe.ui.form.on(this.frm.doctype, "additional_discount_percentage", function(frm) {
+ if (frm.via_discount_amount) {
+ return;
+ }
+
+ if(!frm.doc.apply_discount_on) {
+ frappe.msgprint(__("Please set 'Apply Additional Discount On'"));
+ return
+ }
+
+ frm.via_discount_percentage = true;
+
+ if(frm.doc.additional_discount_percentage && frm.doc.discount_amount) {
+ // Reset discount amount and net / grand total
+ frm.set_value("discount_amount", 0);
+ }
+
+ var total = flt(frm.doc[frappe.model.scrub(frm.doc.apply_discount_on)]);
+ var discount_amount = flt(total*flt(frm.doc.additional_discount_percentage) / 100,
+ precision("discount_amount"));
+
+ frm.set_value("discount_amount", discount_amount);
+ delete frm.via_discount_percentage;
+ });
+
+ frappe.ui.form.on(this.frm.doctype, "discount_amount", function(frm) {
+ frm.cscript.set_dynamic_labels();
+
+ if (!frm.via_discount_percentage) {
+ frm.via_discount_amount = true;
+ frm.set_value("additional_discount_percentage", 0);
+ delete frm.via_discount_amount;
+ }
+
+ frm.cscript.calculate_taxes_and_totals();
+ });
+
+ },
onload: function() {
var me = this;
//this.frm.show_print_first = true;
@@ -126,7 +200,6 @@
},
send_sms: function() {
- frappe.require("assets/erpnext/js/sms_manager.js");
var sms_man = new SMSManager(this.frm.doc);
},
@@ -309,8 +382,8 @@
if (this.frm.doc.posting_date) var date = this.frm.doc.posting_date;
else var date = this.frm.doc.transaction_date;
-
- if (frappe.meta.get_docfield(this.frm.doctype, "shipping_address") &&
+
+ if (frappe.meta.get_docfield(this.frm.doctype, "shipping_address") &&
in_list(['Purchase Order', 'Purchase Receipt', 'Purchase Invoice'], this.frm.doctype)){
erpnext.utils.get_shipping_address(this.frm, function(){
set_party_account(set_pricing);
@@ -909,80 +982,4 @@
-});
-
-frappe.ui.form.on(cur_frm.doctype + " Item", "rate", function(frm, cdt, cdn) {
- var item = frappe.get_doc(cdt, cdn);
- frappe.model.round_floats_in(item, ["rate", "price_list_rate"]);
-
- if(item.price_list_rate) {
- item.discount_percentage = flt((1 - item.rate / item.price_list_rate) * 100.0, precision("discount_percentage", item));
- } else {
- item.discount_percentage = 0.0;
- }
-
- cur_frm.cscript.set_gross_profit(item);
- cur_frm.cscript.calculate_taxes_and_totals();
-})
-
-frappe.ui.form.on(cur_frm.cscript.tax_table, "rate", function(frm, cdt, cdn) {
- cur_frm.cscript.calculate_taxes_and_totals();
-})
-
-frappe.ui.form.on(cur_frm.cscript.tax_table, "tax_amount", function(frm, cdt, cdn) {
- cur_frm.cscript.calculate_taxes_and_totals();
-})
-
-frappe.ui.form.on(cur_frm.cscript.tax_table, "row_id", function(frm, cdt, cdn) {
- cur_frm.cscript.calculate_taxes_and_totals();
-})
-
-frappe.ui.form.on(cur_frm.cscript.tax_table, "included_in_print_rate", function(frm, cdt, cdn) {
- cur_frm.cscript.set_dynamic_labels();
- cur_frm.cscript.calculate_taxes_and_totals();
-})
-
-frappe.ui.form.on(cur_frm.doctype, "apply_discount_on", function(frm) {
- if(frm.doc.additional_discount_percentage) {
- frm.trigger("additional_discount_percentage");
- } else {
- cur_frm.cscript.calculate_taxes_and_totals();
- }
-})
-
-frappe.ui.form.on(cur_frm.doctype, "additional_discount_percentage", function(frm) {
- if (frm.via_discount_amount) {
- return;
- }
-
- if(!frm.doc.apply_discount_on) {
- frappe.msgprint(__("Please set 'Apply Additional Discount On'"));
- return
- }
-
- frm.via_discount_percentage = true;
-
- if(frm.doc.additional_discount_percentage && frm.doc.discount_amount) {
- // Reset discount amount and net / grand total
- frm.set_value("discount_amount", 0);
- }
-
- var total = flt(frm.doc[frappe.model.scrub(frm.doc.apply_discount_on)]);
- var discount_amount = flt(total*flt(frm.doc.additional_discount_percentage) / 100,
- precision("discount_amount"));
-
- frm.set_value("discount_amount", discount_amount);
- delete frm.via_discount_percentage;
-});
-
-frappe.ui.form.on(cur_frm.doctype, "discount_amount", function(frm) {
- frm.cscript.set_dynamic_labels();
-
- if (!frm.via_discount_percentage) {
- frm.via_discount_amount = true;
- frm.set_value("additional_discount_percentage", 0);
- delete frm.via_discount_amount;
- }
-
- frm.cscript.calculate_taxes_and_totals();
-});
+});
\ No newline at end of file
diff --git a/erpnext/public/js/stock_analytics.js b/erpnext/public/js/stock_analytics.js
index a8229ba..e9f9758 100644
--- a/erpnext/public/js/stock_analytics.js
+++ b/erpnext/public/js/stock_analytics.js
@@ -1,213 +1,214 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-frappe.require("assets/erpnext/js/stock_grid_report.js");
+frappe.require("assets/erpnext/js/stock_grid_report.js", function() {
+ erpnext.StockAnalytics = erpnext.StockGridReport.extend({
+ init: function(wrapper, opts) {
+ var args = {
+ title: __("Stock Analytics"),
+ page: wrapper,
+ parent: $(wrapper).find('.layout-main'),
+ page: wrapper.page,
+ doctypes: ["Item", "Item Group", "Warehouse", "Stock Ledger Entry", "Brand",
+ "Fiscal Year", "Serial No"],
+ tree_grid: {
+ show: true,
+ parent_field: "parent_item_group",
+ formatter: function(item) {
+ if(!item.is_group) {
+ return repl("<a \
+ onclick='frappe.cur_grid_report.show_stock_ledger(\"%(value)s\")'>\
+ %(value)s</a>", {
+ value: item.name,
+ });
+ } else {
+ return item.name;
+ }
-erpnext.StockAnalytics = erpnext.StockGridReport.extend({
- init: function(wrapper, opts) {
- var args = {
- title: __("Stock Analytics"),
- page: wrapper,
- parent: $(wrapper).find('.layout-main'),
- page: wrapper.page,
- doctypes: ["Item", "Item Group", "Warehouse", "Stock Ledger Entry", "Brand",
- "Fiscal Year", "Serial No"],
- tree_grid: {
- show: true,
- parent_field: "parent_item_group",
- formatter: function(item) {
- if(!item.is_group) {
- return repl("<a \
- onclick='frappe.cur_grid_report.show_stock_ledger(\"%(value)s\")'>\
- %(value)s</a>", {
- value: item.name,
- });
- } else {
- return item.name;
}
-
- }
- },
- }
-
- if(opts) $.extend(args, opts);
-
- this._super(args);
- },
- setup_columns: function() {
- var std_columns = [
- {id: "_check", name: __("Plot"), field: "_check", width: 30,
- formatter: this.check_formatter},
- {id: "name", name: __("Item"), field: "name", width: 300,
- formatter: this.tree_formatter},
- {id: "brand", name: __("Brand"), field: "brand", width: 100},
- {id: "stock_uom", name: __("UOM"), field: "stock_uom", width: 100},
- {id: "opening", name: __("Opening"), field: "opening", hidden: true,
- formatter: this.currency_formatter}
- ];
-
- this.make_date_range_columns();
- this.columns = std_columns.concat(this.columns);
- },
- filters: [
- {fieldtype:"Select", label: __("Value or Qty"), fieldname: "value_or_qty",
- options:[{label:__("Value"), value:"Value"}, {label:__("Quantity"), value:"Quantity"}],
- filter: function(val, item, opts, me) {
- return me.apply_zero_filter(val, item, opts, me);
- }},
- {fieldtype:"Select", label: __("Brand"), link:"Brand", fieldname: "brand",
- default_value: __("Select Brand..."), filter: function(val, item, opts) {
- return val == opts.default_value || item.brand == val || item._show;
- }, link_formatter: {filter_input: "brand"}},
- {fieldtype:"Select", label: __("Warehouse"), link:"Warehouse", fieldname: "warehouse",
- default_value: __("Select Warehouse...")},
- {fieldtype:"Date", label: __("From Date"), fieldname: "from_date"},
- {fieldtype:"Date", label: __("To Date"), fieldname: "to_date"},
- {fieldtype:"Select", label: __("Range"), fieldname: "range",
- options:[
- {label:__("Daily"), value:"Daily"},
- {label:__("Weekly"), value:"Weekly"},
- {label:__("Monthly"), value:"Monthly"},
- {label:__("Quarterly"), value:"Quarterly"},
- {label:__("Yearly"), value:"Yearly"},
- ]}
- ],
- setup_filters: function() {
- var me = this;
- this._super();
-
- this.trigger_refresh_on_change(["value_or_qty", "brand", "warehouse", "range"]);
-
- this.show_zero_check();
- this.setup_plot_check();
- },
- init_filter_values: function() {
- this._super();
- this.filter_inputs.range && this.filter_inputs.range.val('Monthly');
- },
- prepare_data: function() {
- var me = this;
-
- if(!this.data) {
- var items = this.prepare_tree("Item", "Item Group");
-
- me.parent_map = {};
- me.item_by_name = {};
- me.data = [];
-
- $.each(items, function(i, v) {
- var d = copy_dict(v);
-
- me.data.push(d);
- me.item_by_name[d.name] = d;
- if(d.parent_item_group) {
- me.parent_map[d.name] = d.parent_item_group;
- }
- me.reset_item_values(d);
- });
- this.set_indent();
- this.data[0].checked = true;
- } else {
- // otherwise, only reset values
- $.each(this.data, function(i, d) {
- me.reset_item_values(d);
- d["closing_qty_value"] = 0;
- });
- }
-
- this.prepare_balances();
- this.update_groups();
-
- },
- prepare_balances: function() {
- var me = this;
- var from_date = dateutil.str_to_obj(this.from_date);
- var to_date = dateutil.str_to_obj(this.to_date);
- var data = frappe.report_dump.data["Stock Ledger Entry"];
-
- this.item_warehouse = {};
- this.serialized_buying_rates = this.get_serialized_buying_rates();
-
- for(var i=0, j=data.length; i<j; i++) {
- var sl = data[i];
- sl.posting_datetime = sl.posting_date + " " + sl.posting_time;
- var posting_datetime = dateutil.str_to_obj(sl.posting_datetime);
-
- if(me.is_default("warehouse") ? true : me.warehouse == sl.warehouse) {
- var item = me.item_by_name[sl.item_code];
- if(item.closing_qty_value==undefined) item.closing_qty_value = 0;
-
- if(me.value_or_qty!="Quantity") {
- var wh = me.get_item_warehouse(sl.warehouse, sl.item_code);
- var valuation_method = item.valuation_method ?
- item.valuation_method : sys_defaults.valuation_method;
- var is_fifo = valuation_method == "FIFO";
-
- if(sl.voucher_type=="Stock Reconciliation") {
- var diff = (sl.qty_after_transaction * sl.valuation_rate) - item.closing_qty_value;
- wh.fifo_stack = [[sl.qty_after_transaction, sl.valuation_rate, sl.posting_date]];
- wh.balance_qty = sl.qty_after_transaction;
- wh.balance_value = sl.valuation_rate * sl.qty_after_transaction;
- } else {
- var diff = me.get_value_diff(wh, sl, is_fifo);
- }
- } else {
- if(sl.voucher_type=="Stock Reconciliation") {
- var diff = sl.qty_after_transaction - item.closing_qty_value;
- } else {
- var diff = sl.qty;
- }
- }
-
- if(posting_datetime < from_date) {
- item.opening += diff;
- } else if(posting_datetime <= to_date) {
- item[me.column_map[sl.posting_date].field] += diff;
- } else {
- break;
- }
-
- item.closing_qty_value += diff;
+ },
}
- }
- },
- update_groups: function() {
- var me = this;
- $.each(this.data, function(i, item) {
- // update groups
- if(!item.is_group && me.apply_filter(item, "brand")) {
- var balance = item.opening;
- $.each(me.columns, function(i, col) {
- if(col.formatter==me.currency_formatter && !col.hidden) {
- item[col.field] = balance + item[col.field];
- balance = item[col.field];
- }
- });
- var parent = me.parent_map[item.name];
- while(parent) {
- parent_group = me.item_by_name[parent];
- $.each(me.columns, function(c, col) {
- if (col.formatter == me.currency_formatter) {
- parent_group[col.field] =
- flt(parent_group[col.field])
- + flt(item[col.field]);
+ if(opts) $.extend(args, opts);
+
+ this._super(args);
+ },
+ setup_columns: function() {
+ var std_columns = [
+ {id: "_check", name: __("Plot"), field: "_check", width: 30,
+ formatter: this.check_formatter},
+ {id: "name", name: __("Item"), field: "name", width: 300,
+ formatter: this.tree_formatter},
+ {id: "brand", name: __("Brand"), field: "brand", width: 100},
+ {id: "stock_uom", name: __("UOM"), field: "stock_uom", width: 100},
+ {id: "opening", name: __("Opening"), field: "opening", hidden: true,
+ formatter: this.currency_formatter}
+ ];
+
+ this.make_date_range_columns();
+ this.columns = std_columns.concat(this.columns);
+ },
+ filters: [
+ {fieldtype:"Select", label: __("Value or Qty"), fieldname: "value_or_qty",
+ options:[{label:__("Value"), value:"Value"}, {label:__("Quantity"), value:"Quantity"}],
+ filter: function(val, item, opts, me) {
+ return me.apply_zero_filter(val, item, opts, me);
+ }},
+ {fieldtype:"Select", label: __("Brand"), link:"Brand", fieldname: "brand",
+ default_value: __("Select Brand..."), filter: function(val, item, opts) {
+ return val == opts.default_value || item.brand == val || item._show;
+ }, link_formatter: {filter_input: "brand"}},
+ {fieldtype:"Select", label: __("Warehouse"), link:"Warehouse", fieldname: "warehouse",
+ default_value: __("Select Warehouse...")},
+ {fieldtype:"Date", label: __("From Date"), fieldname: "from_date"},
+ {fieldtype:"Date", label: __("To Date"), fieldname: "to_date"},
+ {fieldtype:"Select", label: __("Range"), fieldname: "range",
+ options:[
+ {label:__("Daily"), value:"Daily"},
+ {label:__("Weekly"), value:"Weekly"},
+ {label:__("Monthly"), value:"Monthly"},
+ {label:__("Quarterly"), value:"Quarterly"},
+ {label:__("Yearly"), value:"Yearly"},
+ ]}
+ ],
+ setup_filters: function() {
+ var me = this;
+ this._super();
+
+ this.trigger_refresh_on_change(["value_or_qty", "brand", "warehouse", "range"]);
+
+ this.show_zero_check();
+ this.setup_plot_check();
+ },
+ init_filter_values: function() {
+ this._super();
+ this.filter_inputs.range && this.filter_inputs.range.val('Monthly');
+ },
+ prepare_data: function() {
+ var me = this;
+
+ if(!this.data) {
+ var items = this.prepare_tree("Item", "Item Group");
+
+ me.parent_map = {};
+ me.item_by_name = {};
+ me.data = [];
+
+ $.each(items, function(i, v) {
+ var d = copy_dict(v);
+
+ me.data.push(d);
+ me.item_by_name[d.name] = d;
+ if(d.parent_item_group) {
+ me.parent_map[d.name] = d.parent_item_group;
+ }
+ me.reset_item_values(d);
+ });
+ this.set_indent();
+ this.data[0].checked = true;
+ } else {
+ // otherwise, only reset values
+ $.each(this.data, function(i, d) {
+ me.reset_item_values(d);
+ d["closing_qty_value"] = 0;
+ });
+ }
+
+ this.prepare_balances();
+ this.update_groups();
+
+ },
+ prepare_balances: function() {
+ var me = this;
+ var from_date = dateutil.str_to_obj(this.from_date);
+ var to_date = dateutil.str_to_obj(this.to_date);
+ var data = frappe.report_dump.data["Stock Ledger Entry"];
+
+ this.item_warehouse = {};
+ this.serialized_buying_rates = this.get_serialized_buying_rates();
+
+ for(var i=0, j=data.length; i<j; i++) {
+ var sl = data[i];
+ sl.posting_datetime = sl.posting_date + " " + sl.posting_time;
+ var posting_datetime = dateutil.str_to_obj(sl.posting_datetime);
+
+ if(me.is_default("warehouse") ? true : me.warehouse == sl.warehouse) {
+ var item = me.item_by_name[sl.item_code];
+ if(item.closing_qty_value==undefined) item.closing_qty_value = 0;
+
+ if(me.value_or_qty!="Quantity") {
+ var wh = me.get_item_warehouse(sl.warehouse, sl.item_code);
+ var valuation_method = item.valuation_method ?
+ item.valuation_method : sys_defaults.valuation_method;
+ var is_fifo = valuation_method == "FIFO";
+
+ if(sl.voucher_type=="Stock Reconciliation") {
+ var diff = (sl.qty_after_transaction * sl.valuation_rate) - item.closing_qty_value;
+ wh.fifo_stack = [[sl.qty_after_transaction, sl.valuation_rate, sl.posting_date]];
+ wh.balance_qty = sl.qty_after_transaction;
+ wh.balance_value = sl.valuation_rate * sl.qty_after_transaction;
+ } else {
+ var diff = me.get_value_diff(wh, sl, is_fifo);
+ }
+ } else {
+ if(sl.voucher_type=="Stock Reconciliation") {
+ var diff = sl.qty_after_transaction - item.closing_qty_value;
+ } else {
+ var diff = sl.qty;
+ }
+ }
+
+ if(posting_datetime < from_date) {
+ item.opening += diff;
+ } else if(posting_datetime <= to_date) {
+ item[me.column_map[sl.posting_date].field] += diff;
+ } else {
+ break;
+ }
+
+ item.closing_qty_value += diff;
+ }
+ }
+ },
+ update_groups: function() {
+ var me = this;
+ $.each(this.data, function(i, item) {
+ // update groups
+ if(!item.is_group && me.apply_filter(item, "brand")) {
+ var balance = item.opening;
+ $.each(me.columns, function(i, col) {
+ if(col.formatter==me.currency_formatter && !col.hidden) {
+ item[col.field] = balance + item[col.field];
+ balance = item[col.field];
}
});
- parent = me.parent_map[parent];
+
+ var parent = me.parent_map[item.name];
+ while(parent) {
+ parent_group = me.item_by_name[parent];
+ $.each(me.columns, function(c, col) {
+ if (col.formatter == me.currency_formatter) {
+ parent_group[col.field] =
+ flt(parent_group[col.field])
+ + flt(item[col.field]);
+ }
+ });
+ parent = me.parent_map[parent];
+ }
}
- }
- });
- },
- get_plot_points: function(item, col, idx) {
- return [[dateutil.user_to_obj(col.name).getTime(), item[col.field]]]
- },
- show_stock_ledger: function(item_code) {
- frappe.route_options = {
- item_code: item_code,
- from_date: this.from_date,
- to_date: this.to_date
- };
- frappe.set_route("query-report", "Stock Ledger");
- }
+ });
+ },
+ get_plot_points: function(item, col, idx) {
+ return [[dateutil.user_to_obj(col.name).getTime(), item[col.field]]]
+ },
+ show_stock_ledger: function(item_code) {
+ frappe.route_options = {
+ item_code: item_code,
+ from_date: this.from_date,
+ to_date: this.to_date
+ };
+ frappe.set_route("query-report", "Stock Ledger");
+ }
+ });
});
+
diff --git a/erpnext/public/js/utils/inventory.js b/erpnext/public/js/utils/inventory.js
deleted file mode 100644
index 80cd6a5..0000000
--- a/erpnext/public/js/utils/inventory.js
+++ /dev/null
@@ -1,77 +0,0 @@
-erpnext.get_item_dashboard_data = function(data, max_count, show_item) {
- if(!max_count) max_count = 0;
- data.forEach(function(d) {
- d.actual_or_pending = d.projected_qty + d.reserved_qty + d.reserved_qty_for_production;
- d.pending_qty = 0;
- d.total_reserved = d.reserved_qty + d.reserved_qty_for_production;
- if(d.actual_or_pending > d.actual_qty) {
- d.pending_qty = d.actual_or_pending - d.actual_qty;
- }
-
- max_count = Math.max(d.actual_or_pending, d.actual_qty,
- d.total_reserved, max_count);
- });
- return {
- data: data,
- max_count: max_count,
- show_item: show_item || false
- }
-}
-
-frappe.provide('erpnext.inventory');
-
-erpnext.inventory.move_item = function(item, source, target, actual_qty, callback) {
- var dialog = new frappe.ui.Dialog({
- title: target ? __('Add Item') : __('Move Item'),
- fields: [
- {fieldname: 'item_code', label: __('Item'),
- fieldtype: 'Link', options: 'Item', read_only: 1},
- {fieldname: 'source', label: __('Source Warehouse'),
- fieldtype: 'Link', options: 'Warehouse', read_only: 1},
- {fieldname: 'target', label: __('Target Warehouse'),
- fieldtype: 'Link', options: 'Warehouse', reqd: 1},
- {fieldname: 'qty', label: __('Quantity'), reqd: 1,
- fieldtype: 'Float', description: __('Available {0}', [actual_qty]) },
- ],
- })
- dialog.show();
- dialog.get_field('item_code').set_input(item);
-
- if(source) {
- dialog.get_field('source').set_input(source);
- } else {
- dialog.get_field('source').df.hidden = 1;
- dialog.get_field('source').refresh();
- }
-
- if(target) {
- dialog.get_field('target').df.read_only = 1;
- dialog.get_field('target').value = target;
- dialog.get_field('target').refresh();
- }
-
- dialog.set_primary_action(__('Submit'), function() {
- values = dialog.get_values();
- if(!values) {
- return;
- }
- if(source && values.qty > actual_qty) {
- frappe.msgprint(__('Quantity must be less than or equal to {0}', [actual_qty]));
- return;
- }
- if(values.source === values.target) {
- frappe.msgprint(__('Source and target warehouse must be different'));
- }
-
- frappe.call({
- method: 'erpnext.stock.doctype.stock_entry.stock_entry_utils.make_stock_entry',
- args: values,
- callback: function(r) {
- frappe.show_alert(__('Stock Entry {0} created',
- ['<a href="#Form/Stock Entry/'+r.message.name+'">' + r.message.name+ '</a>']));
- dialog.hide();
- callback(r);
- },
- });
- });
-}
\ No newline at end of file
diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less
index 23ee841..58e8e62 100644
--- a/erpnext/public/less/erpnext.less
+++ b/erpnext/public/less/erpnext.less
@@ -132,7 +132,7 @@
}
.erpnext-icon {
- width: 24px;
+ width: 24px;ack
margin-right: 0px;
margin-top: -3px;
}
@@ -145,4 +145,14 @@
.input-group {
margin-top: 2px;
}
-}
\ No newline at end of file
+}
+
+.dashboard-list-item {
+ background-color: inherit;
+ padding: 7px 15px;
+ border-bottom: 1px solid @border-color;
+}
+
+.dashboard-list-item:last-child {
+ border-bottom: none;
+}
diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js
index 5645280..87d028f 100644
--- a/erpnext/selling/doctype/customer/customer.js
+++ b/erpnext/selling/doctype/customer/customer.js
@@ -3,7 +3,6 @@
frappe.ui.form.on("Customer", {
before_load: function(frm) {
- frm.hide_first = true;
frappe.setup_language_field(frm);
},
refresh: function(frm) {
diff --git a/erpnext/selling/doctype/installation_note/installation_note.js b/erpnext/selling/doctype/installation_note/installation_note.js
index f0e1eab..09deea2 100644
--- a/erpnext/selling/doctype/installation_note/installation_note.js
+++ b/erpnext/selling/doctype/installation_note/installation_note.js
@@ -1,7 +1,7 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-frappe.require("assets/erpnext/js/utils.js");
+
frappe.ui.form.on_change("Installation Note", "customer",
function(frm) { erpnext.utils.get_party_details(frm); });
diff --git a/erpnext/selling/report/quotation_trends/quotation_trends.js b/erpnext/selling/report/quotation_trends/quotation_trends.js
index ba62bf1..294aea0 100644
--- a/erpnext/selling/report/quotation_trends/quotation_trends.js
+++ b/erpnext/selling/report/quotation_trends/quotation_trends.js
@@ -1,8 +1,9 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-frappe.require("assets/erpnext/js/sales_trends_filters.js");
+frappe.require("assets/erpnext/js/sales_trends_filters.js", function() {
+ frappe.query_reports["Quotation Trends"] = {
+ filters: get_filters()
+ }
+});
-frappe.query_reports["Quotation Trends"] = {
- filters: get_filters()
- }
\ No newline at end of file
diff --git a/erpnext/selling/report/sales_order_trends/sales_order_trends.js b/erpnext/selling/report/sales_order_trends/sales_order_trends.js
index cee6004..863afb8 100644
--- a/erpnext/selling/report/sales_order_trends/sales_order_trends.js
+++ b/erpnext/selling/report/sales_order_trends/sales_order_trends.js
@@ -1,8 +1,8 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-frappe.require("assets/erpnext/js/sales_trends_filters.js");
-
-frappe.query_reports["Sales Order Trends"] = {
- filters: get_filters()
- }
\ No newline at end of file
+frappe.require("assets/erpnext/js/sales_trends_filters.js", function() {
+ frappe.query_reports["Sales Order Trends"] = {
+ filters: get_filters()
+ }
+});
\ No newline at end of file
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index 167024b..5906a4f 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -5,11 +5,10 @@
cur_frm.cscript.tax_table = "Sales Taxes and Charges";
{% include 'erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js' %}
-frappe.provide("erpnext.selling");
-frappe.require("assets/erpnext/js/controllers/transaction.js");
cur_frm.email_field = "contact_email";
+frappe.provide("erpnext.selling");
erpnext.selling.SellingController = erpnext.TransactionController.extend({
onload: function() {
this._super();
@@ -182,7 +181,7 @@
warehouse: function(doc, cdt, cdn) {
var me = this;
var item = frappe.get_doc(cdt, cdn);
-
+
if(item.item_code && item.warehouse) {
return this.frm.call({
method: "erpnext.stock.get_item_details.get_bin_details",
diff --git a/erpnext/stock/dashboard/__init__.py b/erpnext/stock/dashboard/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/stock/dashboard/__init__.py
diff --git a/erpnext/stock/dashboard/item_dashboard.html b/erpnext/stock/dashboard/item_dashboard.html
new file mode 100644
index 0000000..1e18969
--- /dev/null
+++ b/erpnext/stock/dashboard/item_dashboard.html
@@ -0,0 +1,7 @@
+<div>
+ <div class="result">
+ </div>
+ <div class="more hidden" style="padding: 15px;">
+ <a class="btn btn-default btn-xs btn-more">More</a>
+ </div>
+</div>
\ No newline at end of file
diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js
new file mode 100644
index 0000000..99edb0f
--- /dev/null
+++ b/erpnext/stock/dashboard/item_dashboard.js
@@ -0,0 +1,181 @@
+frappe.provide('erpnext.stock');
+
+erpnext.stock.ItemDashboard = Class.extend({
+ init: function(opts) {
+ $.extend(this, opts);
+ this.make();
+ },
+ make: function() {
+ var me = this;
+ this.start = 0;
+ if(!this.sort_by) {
+ this.sort_by = 'projected_qty';
+ this.sort_order = 'asc';
+ }
+
+ this.content = $(frappe.render_template('item_dashboard')).appendTo(this.parent);
+ this.result = this.content.find('.result');
+
+ // move
+ this.content.on('click', '.btn-move', function() {
+ erpnext.stock.move_item($(this).attr('data-item'), $(this).attr('data-warehouse'),
+ null, $(this).attr('data-actual_qty'), null, function() { me.refresh(); });
+ });
+
+ this.content.on('click', '.btn-add', function() {
+ erpnext.stock.move_item($(this).attr('data-item'), null, $(this).attr('data-warehouse'),
+ $(this).attr('data-actual_qty'), $(this).attr('data-rate'),
+ function() { me.refresh(); });
+ });
+
+ // more
+ this.content.find('.btn-more').on('click', function() {
+ me.start += 20;
+ me.refresh();
+ });
+
+ },
+ refresh: function() {
+ if(this.before_refresh) {
+ this.before_refresh();
+ }
+
+ var me = this;
+ frappe.call({
+ method: 'erpnext.stock.dashboard.item_dashboard.get_data',
+ args: {
+ item_code: this.item_code,
+ warehouse: this.warehouse,
+ start: this.start,
+ sort_by: this.sort_by,
+ sort_order: this.sort_order,
+ },
+ callback: function(r) {
+ me.render(r.message);
+ }
+ });
+ },
+ render: function(data) {
+ if(this.start===0) {
+ this.max_count = 0;
+ this.result.empty();
+ }
+
+ var context = this.get_item_dashboard_data(data, this.max_count, true);
+ this.max_count = this.max_count;
+
+ // show more button
+ if(data.length===21) {
+ this.content.find('.more').removeClass('hidden');
+
+ // remove the last element
+ data.splice(-1);
+ } else {
+ this.content.find('.more').addClass('hidden');
+ }
+
+ $(frappe.render_template('item_dashboard_list', context)).appendTo(this.result);
+
+ },
+ get_item_dashboard_data: function(data, max_count, show_item) {
+ if(!max_count) max_count = 0;
+ data.forEach(function(d) {
+ d.actual_or_pending = d.projected_qty + d.reserved_qty + d.reserved_qty_for_production;
+ d.pending_qty = 0;
+ d.total_reserved = d.reserved_qty + d.reserved_qty_for_production;
+ if(d.actual_or_pending > d.actual_qty) {
+ d.pending_qty = d.actual_or_pending - d.actual_qty;
+ }
+
+ max_count = Math.max(d.actual_or_pending, d.actual_qty,
+ d.total_reserved, max_count);
+ });
+ return {
+ data: data,
+ max_count: max_count,
+ show_item: show_item || false
+ }
+ }
+})
+
+erpnext.stock.move_item = function(item, source, target, actual_qty, rate, callback) {
+ var dialog = new frappe.ui.Dialog({
+ title: target ? __('Add Item') : __('Move Item'),
+ fields: [
+ {fieldname: 'item_code', label: __('Item'),
+ fieldtype: 'Link', options: 'Item', read_only: 1},
+ {fieldname: 'source', label: __('Source Warehouse'),
+ fieldtype: 'Link', options: 'Warehouse', read_only: 1},
+ {fieldname: 'target', label: __('Target Warehouse'),
+ fieldtype: 'Link', options: 'Warehouse', reqd: 1},
+ {fieldname: 'qty', label: __('Quantity'), reqd: 1,
+ fieldtype: 'Float', description: __('Available {0}', [actual_qty]) },
+ {fieldname: 'rate', label: __('Rate'), fieldtype: 'Currency', hidden: 1 },
+ ],
+ })
+ dialog.show();
+ dialog.get_field('item_code').set_input(item);
+
+ if(source) {
+ dialog.get_field('source').set_input(source);
+ } else {
+ dialog.get_field('source').df.hidden = 1;
+ dialog.get_field('source').refresh();
+ }
+
+ if(rate) {
+ dialog.get_field('rate').set_value(rate);
+ dialog.get_field('rate').df.hidden = 0;
+ dialog.get_field('rate').refresh();
+ }
+
+ if(target) {
+ dialog.get_field('target').df.read_only = 1;
+ dialog.get_field('target').value = target;
+ dialog.get_field('target').refresh();
+ }
+
+ dialog.set_primary_action(__('Submit'), function() {
+ var values = dialog.get_values();
+ if(!values) {
+ return;
+ }
+ if(source && values.qty > actual_qty) {
+ frappe.msgprint(__('Quantity must be less than or equal to {0}', [actual_qty]));
+ return;
+ }
+ if(values.source === values.target) {
+ frappe.msgprint(__('Source and target warehouse must be different'));
+ }
+
+ frappe.call({
+ method: 'erpnext.stock.doctype.stock_entry.stock_entry_utils.make_stock_entry',
+ args: values,
+ callback: function(r) {
+ frappe.show_alert(__('Stock Entry {0} created',
+ ['<a href="#Form/Stock Entry/'+r.message.name+'">' + r.message.name+ '</a>']));
+ dialog.hide();
+ callback(r);
+ },
+ });
+ });
+
+ $('<p style="margin-left: 10px;"><a class="link-open text-muted small">'
+ + __("Add more items or open full form") + '</a></p>')
+ .appendTo(dialog.body)
+ .find('.link-open')
+ .on('click', function() {
+ frappe.model.with_doctype('Stock Entry', function() {
+ var doc = frappe.model.get_new_doc('Stock Entry');
+ doc.from_warehouse = dialog.get_value('source');
+ doc.to_warehouse = dialog.get_value('target');
+ row = frappe.model.add_child(doc, 'items');
+ row.item_code = dialog.get_value('item_code');
+ row.f_warehouse = dialog.get_value('target');
+ row.t_warehouse = dialog.get_value('target');
+ row.qty = dialog.get_value('qty');
+ row.basic_rate = dialog.get_value('rate');
+ frappe.set_route('Form', doc.doctype, doc.name);
+ })
+ });
+}
\ No newline at end of file
diff --git a/erpnext/stock/page/stock_balance/stock_balance.py b/erpnext/stock/dashboard/item_dashboard.py
similarity index 92%
rename from erpnext/stock/page/stock_balance/stock_balance.py
rename to erpnext/stock/dashboard/item_dashboard.py
index e96f925..5a00b3d 100644
--- a/erpnext/stock/page/stock_balance/stock_balance.py
+++ b/erpnext/stock/dashboard/item_dashboard.py
@@ -10,5 +10,5 @@
if warehouse:
filters['warehouse'] = warehouse
return frappe.get_list("Bin", filters=filters, fields=['item_code', 'warehouse',
- 'projected_qty', 'reserved_qty', 'reserved_qty_for_production', 'actual_qty'],
+ 'projected_qty', 'reserved_qty', 'reserved_qty_for_production', 'actual_qty', 'valuation_rate'],
order_by='{0} {1}'.format(sort_by, sort_order), start=start, page_length = 21)
\ No newline at end of file
diff --git a/erpnext/stock/doctype/item/item_dashboard.html b/erpnext/stock/dashboard/item_dashboard_list.html
similarity index 92%
rename from erpnext/stock/doctype/item/item_dashboard.html
rename to erpnext/stock/dashboard/item_dashboard_list.html
index 813aef3..f9ffbb3 100644
--- a/erpnext/stock/doctype/item/item_dashboard.html
+++ b/erpnext/stock/dashboard/item_dashboard_list.html
@@ -1,5 +1,5 @@
{% for d in data %}
- <li class="list-group-item" style="background-color: inherit;">
+ <div class="dashboard-list-item">
<div class="row">
<div class="col-sm-3 small" style="margin-top: 8px;">
<a data-type="warehouse" data-name="{{ d.warehouse }}">{{ d.warehouse }}</a>
@@ -47,8 +47,9 @@
<button style="margin-left: 7px;" class="btn btn-default btn-xs btn-add"
data-warehouse="{{ d.warehouse }}"
data-actual_qty="{{ d.actual_qty }}"
- data-item="{{ d.item_code }}">{{ __("Add") }}</a>
+ data-item="{{ d.item_code }}"
+ data-rate="{{ d.valuation_rate }}">{{ __("Add") }}</a>
</div>
</div>
- </li>
+ </div>
{% endfor %}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js
index 2cde790..7f2be4f 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -5,7 +5,6 @@
frappe.ui.form.on("Item", {
onload: function(frm) {
- frm.hide_first = true;
erpnext.item.setup_queries(frm);
if (frm.doc.variant_of){
frm.fields_dict["attributes"].grid.set_column_disp("attribute_value", true);
@@ -41,6 +40,7 @@
// make sensitive fields(has_serial_no, is_stock_item, valuation_method)
// read only if any stock ledger entry exists
+
erpnext.item.make_dashboard(frm);
// clear intro
@@ -76,19 +76,7 @@
erpnext.item.toggle_attributes(frm);
- frm.dashboard.show_heatmap = frm.doc.is_stock_item;
- frm.dashboard.heatmap_message = __('This is based on stock movement. See {0} for details',
- ['<a href="#query-report/Stock Ledger">' + __('Stock Ledger') + '</a>']);
- frm.dashboard.show_dashboard();
- },
- dashboard_update: function(frm) {
- if(frm.dashboard_data.stock_data && frm.dashboard_data.stock_data.length) {
- var context = erpnext.get_item_dashboard_data(frm.dashboard_data.stock_data, 0);
- frm.dashboard.add_section('<h5 style="margin-top: 0px;">Stock Levels</h5>\
- <ul class="list-group">' + frappe.render_template('item_dashboard', context), true)
- + '</ul>';
- }
},
validate: function(frm){
@@ -184,6 +172,20 @@
frm.dashboard.reset();
if(frm.doc.__islocal)
return;
+
+ frm.dashboard.show_heatmap = frm.doc.is_stock_item;
+ frm.dashboard.heatmap_message = __('This is based on stock movement. See {0} for details',
+ ['<a href="#query-report/Stock Ledger">' + __('Stock Ledger') + '</a>']);
+ frm.dashboard.show_dashboard();
+
+ frappe.require('assets/js/item-dashboard.min.js', function() {
+ var section = frm.dashboard.add_section('<h5 style="margin-top: 0px;">Stock Levels</h5>');
+ erpnext.item.item_dashboard = new erpnext.stock.ItemDashboard({
+ parent: section,
+ item_code: frm.doc.name
+ });
+ erpnext.item.item_dashboard.refresh();
+ });
},
edit_prices_button: function(frm) {
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index de40a20..d403b18 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -508,9 +508,22 @@
clear_cache(self.page_name)
frappe.db.set_value("Item", newdn, "item_code", newdn)
+
if merge:
self.set_last_purchase_rate(newdn)
self.recalculate_bin_qty(newdn)
+
+ for dt in ("Sales Taxes and Charges", "Purchase Taxes and Charges"):
+ for d in frappe.db.sql("""select name, item_wise_tax_detail from `tab{0}`
+ where ifnull(item_wise_tax_detail, '') != ''""".format(dt), as_dict=1):
+
+ item_wise_tax_detail = json.loads(d.item_wise_tax_detail)
+ if olddn in item_wise_tax_detail:
+ item_wise_tax_detail[newdn] = item_wise_tax_detail[olddn]
+ item_wise_tax_detail.pop(olddn)
+
+ frappe.db.set_value(dt, d.name, "item_wise_tax_detail",
+ json.dumps(item_wise_tax_detail), update_modified=False)
def set_last_purchase_rate(self, newdn):
last_purchase_rate = get_last_purchase_details(newdn).get("base_rate", 0)
@@ -607,7 +620,8 @@
variant = get_variant(self.variant_of, args, self.name)
if variant:
frappe.throw(_("Item variant {0} exists with same attributes")
- .format(variant), ItemVariantExistsError)
+ .format(variant), ItemVariantExistsError)
+
@frappe.whitelist()
def get_dashboard_data(name):
@@ -618,7 +632,6 @@
return {
'count': get_open_count('Item', name),
'timeline_data': get_timeline_data(name),
- 'stock_data': get_stock_data(name)
}
def get_timeline_data(name):
@@ -628,11 +641,6 @@
and posting_date > date_sub(curdate(), interval 1 year)
group by posting_date''', name))
-def get_stock_data(name):
- return frappe.get_all('Bin', fields=['warehouse', 'actual_qty', 'projected_qty',
- 'reserved_qty', 'reserved_qty_for_production'],
- filters={'item_code': name}, order_by = 'warehouse asc')
-
def validate_end_of_life(item_code, end_of_life=None, disabled=None, verbose=1):
if (not end_of_life) or (disabled is None):
end_of_life, disabled = frappe.db.get_value("Item", item_code, ["end_of_life", "disabled"])
diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js
index 5a86c89..15a5759 100644
--- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js
+++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js
@@ -3,7 +3,6 @@
frappe.provide("erpnext.stock");
-frappe.require("assets/erpnext/js/controllers/stock_controller.js");
erpnext.stock.LandedCostVoucher = erpnext.stock.StockController.extend({
setup: function() {
@@ -11,16 +10,16 @@
this.frm.fields_dict.purchase_receipts.grid.get_field('receipt_document').get_query =
function(doc, cdt ,cdn) {
var d = locals[cdt][cdn]
-
+
var filters = [
[d.receipt_document_type, 'docstatus', '=', '1'],
[d.receipt_document_type, 'company', '=', me.frm.doc.company],
]
-
+
if(d.receipt_document_type == "Purchase Invoice") {
filters.push(["Purchase Invoice", "update_stock", "=", "1"])
}
-
+
if(!me.frm.doc.company) msgprint(__("Please enter company first"));
return {
filters:filters
diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js
index a4bae78..1dcbcb7 100644
--- a/erpnext/stock/doctype/material_request/material_request.js
+++ b/erpnext/stock/doctype/material_request/material_request.js
@@ -3,7 +3,7 @@
{% include 'erpnext/buying/doctype/purchase_common/purchase_common.js' %};
-frappe.require("assets/erpnext/js/utils.js");
+
frappe.ui.form.on("Material Request Item", {
"qty": function(frm, doctype, name) {
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 46f8c70..76b0395 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -1,7 +1,5 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors // License: GNU General Public License v3. See license.txt
-frappe.require("assets/erpnext/js/controllers/stock_controller.js");
-frappe.require("assets/erpnext/js/utils.js");
frappe.provide("erpnext.stock");
erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry_utils.py b/erpnext/stock/doctype/stock_entry/stock_entry_utils.py
index 4cb0d90..0ac9410 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry_utils.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry_utils.py
@@ -67,7 +67,7 @@
"s_warehouse": args.source,
"t_warehouse": args.target,
"qty": args.qty,
- "basic_rate": args.basic_rate,
+ "basic_rate": args.rate or args.basic_rate,
"conversion_factor": 1.0,
"serial_no": args.serial_no,
'cost_center': args.cost_center
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
index f5f4e03..ead110c 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
@@ -1,8 +1,6 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-frappe.require("assets/erpnext/js/controllers/stock_controller.js");
-frappe.require("assets/erpnext/js/utils.js");
frappe.provide("erpnext.stock");
frappe.ui.form.on("Stock Reconciliation", {
diff --git a/erpnext/stock/page/stock_analytics/stock_analytics.js b/erpnext/stock/page/stock_analytics/stock_analytics.js
index bd2d9f6..f86201f 100644
--- a/erpnext/stock/page/stock_analytics/stock_analytics.js
+++ b/erpnext/stock/page/stock_analytics/stock_analytics.js
@@ -1,19 +1,16 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
+frappe.require("assets/erpnext/js/stock_analytics.js", function() {
+ frappe.pages['stock-analytics'].on_page_load = function(wrapper) {
+ frappe.ui.make_app_page({
+ parent: wrapper,
+ title: __('Stock Analytics'),
+ single_column: true
+ });
-frappe.pages['stock-analytics'].on_page_load = function(wrapper) {
- frappe.ui.make_app_page({
- parent: wrapper,
- title: __('Stock Analytics'),
- single_column: true
- });
+ new erpnext.StockAnalytics(wrapper);
- new erpnext.StockAnalytics(wrapper);
-
-
- frappe.breadcrumbs.add("Stock")
-
-};
-
-frappe.require("assets/erpnext/js/stock_analytics.js");
+ frappe.breadcrumbs.add("Stock")
+ };
+});
diff --git a/erpnext/stock/page/stock_balance/stock_balance.html b/erpnext/stock/page/stock_balance/stock_balance.html
deleted file mode 100644
index 560f843..0000000
--- a/erpnext/stock/page/stock_balance/stock_balance.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<div class="padding">
- <div class="result list-group">
- </div>
- <div class="more hidden" style="padding-top: 15px;">
- <a class="btn btn-default btn-xs btn-more">More</a>
- </div>
-</div>
\ No newline at end of file
diff --git a/erpnext/stock/page/stock_balance/stock_balance.js b/erpnext/stock/page/stock_balance/stock_balance.js
index 0fc8984..2b6fd8d 100644
--- a/erpnext/stock/page/stock_balance/stock_balance.js
+++ b/erpnext/stock/page/stock_balance/stock_balance.js
@@ -1,11 +1,10 @@
-{% include 'erpnext/stock/doctype/item/item_dashboard.html' %}
-
frappe.pages['stock-balance'].on_page_load = function(wrapper) {
var page = frappe.ui.make_app_page({
parent: wrapper,
title: 'Stock Balance',
single_column: true
});
+ page.start = 0;
page.warehouse_field = page.add_field({
fieldname: 'wareshouse',
@@ -13,8 +12,8 @@
fieldtype:'Link',
options:'Warehouse',
change: function() {
- page.start = 0;
- refresh()
+ page.item_dashboard.start = 0;
+ page.item_dashboard.refresh();
}
});
@@ -24,35 +23,11 @@
fieldtype:'Link',
options:'Item',
change: function() {
- page.start = 0;
- refresh()
+ page.item_dashboard.start = 0;
+ page.item_dashboard.refresh();
}
});
- page.start = 0;
- page.sort_by = 'projected_qty';
- page.sort_order = 'asc';
-
- page.content = $(frappe.render_template('stock_balance')).appendTo(page.main);
- page.result = page.content.find('.result');
-
- // more
- page.content.find('.btn-more').on('click', function() {
- page.start += 20;
- refresh();
- });
-
- // move
- page.content.on('click', '.btn-move', function() {
- erpnext.inventory.move_item($(this).attr('data-item'), $(this).attr('data-warehouse'),
- null, $(this).attr('data-actual_qty'), function() { refresh(); });
- });
-
- page.content.on('click', '.btn-add', function() {
- erpnext.inventory.move_item($(this).attr('data-item'), null, $(this).attr('data-warehouse'),
- $(this).attr('data-actual_qty'), function() { refresh(); });
- });
-
page.sort_selector = new frappe.ui.SortSelector({
parent: page.wrapper.find('.page-form'),
args: {
@@ -66,73 +41,44 @@
]
},
change: function(sort_by, sort_order) {
- page.sort_by = sort_by;
- page.sort_order = sort_order;
- page.start = 0;
- refresh();
+ page.item_dashboard.sort_by = sort_by;
+ page.item_dashboard.sort_order = sort_order;
+ page.item_dashboard.start = 0;
+ page.item_dashboard.refresh();
}
});
page.sort_selector.wrapper.css({'margin-right': '15px', 'margin-top': '4px'});
- var refresh = function() {
- var item_code = page.item_field.get_value();
- var warehouse = page.warehouse_field.get_value();
- frappe.call({
- method: 'erpnext.stock.page.stock_balance.stock_balance.get_data',
- args: {
- item_code: item_code,
- warehouse: warehouse,
- start: page.start,
- sort_by: page.sort_by,
- sort_order: page.sort_order,
- },
- callback: function(r) {
- render(r.message);
- }
- });
- }
+ frappe.require('assets/js/item-dashboard.min.js', function() {
+ page.item_dashboard = new erpnext.stock.ItemDashboard({
+ parent: page.main,
+ })
- var render = function(data) {
- if(page.start===0) {
- page.max_count = 0;
- page.result.empty();
+ page.item_dashboard.before_refresh = function() {
+ this.item_code = page.item_field.get_value();
+ this.warehouse = page.warehouse_field.get_value();
}
- var context = erpnext.get_item_dashboard_data(data, page.max_count, true);
- page.max_count = context.max_count;
+ page.item_dashboard.refresh();
- // show more button
- if(data.length===21) {
- page.content.find('.more').removeClass('hidden');
-
- // remove the last element
- data.splice(-1);
- } else {
- page.content.find('.more').addClass('hidden');
+ // item click
+ var setup_click = function(doctype) {
+ page.main.on('click', 'a[data-type="'+ doctype.toLowerCase() +'"]', function() {
+ var name = $(this).attr('data-name');
+ var field = page[doctype.toLowerCase() + '_field'];
+ if(field.get_value()===name) {
+ frappe.set_route('Form', doctype, name)
+ } else {
+ field.set_input(name);
+ page.item_dashboard.refresh();
+ }
+ });
}
- $(frappe.render_template('item_dashboard', context)).appendTo(page.result);
+ setup_click('Item');
+ setup_click('Warehouse');
+ });
- }
-
- refresh();
-
- // item click
- var setup_click = function(doctype) {
- page.result.on('click', 'a[data-type="'+ doctype.toLowerCase() +'"]', function() {
- var name = $(this).attr('data-name');
- var field = page[doctype.toLowerCase() + '_field'];
- if(field.get_value()===name) {
- frappe.set_route('Form', doctype, name)
- } else {
- field.set_input(name);
- refresh();
- }
- });
- }
-
- setup_click('Item');
- setup_click('Warehouse');
}
\ No newline at end of file
diff --git a/erpnext/stock/report/delivery_note_trends/delivery_note_trends.js b/erpnext/stock/report/delivery_note_trends/delivery_note_trends.js
index 45955fb..0e12907 100644
--- a/erpnext/stock/report/delivery_note_trends/delivery_note_trends.js
+++ b/erpnext/stock/report/delivery_note_trends/delivery_note_trends.js
@@ -1,8 +1,9 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-frappe.require("assets/erpnext/js/sales_trends_filters.js");
+frappe.require("assets/erpnext/js/sales_trends_filters.js", function() {
+ frappe.query_reports["Delivery Note Trends"] = {
+ filters: get_filters()
+ }
+});
-frappe.query_reports["Delivery Note Trends"] = {
- filters: get_filters()
- }
\ No newline at end of file
diff --git a/erpnext/stock/report/purchase_receipt_trends/purchase_receipt_trends.js b/erpnext/stock/report/purchase_receipt_trends/purchase_receipt_trends.js
index 19a58ef..d94b49e 100644
--- a/erpnext/stock/report/purchase_receipt_trends/purchase_receipt_trends.js
+++ b/erpnext/stock/report/purchase_receipt_trends/purchase_receipt_trends.js
@@ -1,8 +1,9 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-frappe.require("assets/erpnext/js/purchase_trends_filters.js");
+frappe.require("assets/erpnext/js/purchase_trends_filters.js", function() {
+ frappe.query_reports["Purchase Receipt Trends"] = {
+ filters: get_filters()
+ }
+});
-frappe.query_reports["Purchase Receipt Trends"] = {
- filters: get_filters()
- }
\ No newline at end of file
diff --git a/erpnext/support/doctype/maintenance_visit/maintenance_visit.js b/erpnext/support/doctype/maintenance_visit/maintenance_visit.js
index b37c47b..a267eb3 100644
--- a/erpnext/support/doctype/maintenance_visit/maintenance_visit.js
+++ b/erpnext/support/doctype/maintenance_visit/maintenance_visit.js
@@ -2,7 +2,7 @@
// License: GNU General Public License v3. See license.txt
frappe.provide("erpnext.support");
-frappe.require("assets/erpnext/js/utils.js");
+
frappe.ui.form.on_change("Maintenance Visit", "customer", function(frm) {
erpnext.utils.get_party_details(frm) });
diff --git a/erpnext/support/doctype/warranty_claim/warranty_claim.js b/erpnext/support/doctype/warranty_claim/warranty_claim.js
index 3928577..0511ff6 100644
--- a/erpnext/support/doctype/warranty_claim/warranty_claim.js
+++ b/erpnext/support/doctype/warranty_claim/warranty_claim.js
@@ -2,7 +2,8 @@
// License: GNU General Public License v3. See license.txt
frappe.provide("erpnext.support");
-frappe.require("assets/erpnext/js/utils.js");
+
+{% include "erpnext/public/js/utils.js" %}
frappe.ui.form.on("Warranty Claim", {
customer: function(frm) {
diff --git a/erpnext/templates/form_grid/item_grid.html b/erpnext/templates/form_grid/item_grid.html
index 1c50e15..c596890 100644
--- a/erpnext/templates/form_grid/item_grid.html
+++ b/erpnext/templates/form_grid/item_grid.html
@@ -13,7 +13,7 @@
<div class="row">
<div class="col-sm-6 col-xs-8">
{% if(doc.warehouse) {
- var label_class = "label-default",
+ var color = "grey",
title = "Warehouse",
actual_qty = (frm.doc.doctype==="Sales Order"
? doc.projected_qty : doc.actual_qty);
@@ -21,16 +21,16 @@
&& in_list(["Sales Order Item", "Delivery Note Item"], doc.doctype)) {
if(actual_qty != undefined) {
if(actual_qty >= doc.qty) {
- var label_class = "label-success";
+ var color = "green";
var title = "In Stock"
} else {
- var label_class = "label-danger";
+ var color = "red";
var title = "Not In Stock"
}
}
} %}
- <span class="pull-right" title="{%= title %}">
- <span class="label {%= label_class %}">
+ <span class="pull-right" title="{%= title %}" style="margin-left: 10px;">
+ <span class="indicator {{ color }}">
{%= doc.warehouse %}
</span>
</span>
diff --git a/erpnext/templates/form_grid/stock_entry_grid.html b/erpnext/templates/form_grid/stock_entry_grid.html
index a2bf1df..8604881 100644
--- a/erpnext/templates/form_grid/stock_entry_grid.html
+++ b/erpnext/templates/form_grid/stock_entry_grid.html
@@ -16,21 +16,27 @@
{% if(doc.item_name != doc.item_code) { %}
<br>{%= doc.item_name %}{% } %}
{% include "templates/form_grid/includes/visible_cols.html" %}
- {% if(frm.doc.docstatus==0 && doc.s_warehouse && doc.actual_qty < doc.qty) { %}
- <span class="text-danger small" style="margin-left: 15px;">
- Not in Stock
- </span>
- {% } %}
</div>
<!-- warehouse -->
<div class="col-sm-3 col-xs-4">
- {% if(doc.s_warehouse) { %}
- <span class="label label-default grid-label" title="{% __("Source" )%}">
- {%= doc.s_warehouse || "" %}</span>
- {% } %}
- {% if(doc.t_warehouse) { %}<span class="label label-primary grid-label" title="{% __("Target" )%}">
- {%= doc.t_warehouse || "" %}</span>{% } %}
+ {% if(doc.s_warehouse) {
+ if(frm.doc.docstatus==0) {
+ var color = (doc.s_warehouse && doc.actual_qty < doc.qty) ? "red" : "green";
+ var title = color === "red" ? __("Not in Stock") : __("In Stock");
+ } else {
+ var color = "grey";
+ var title = __("Source");
+ }
+ %}
+ <span class="indicator {{ color }}" title="{{ title }}">
+ {%= doc.s_warehouse %}</span>
+ {% }; %}
+ {% if(doc.t_warehouse) { %}
+ <div><span class="indicator {{ doc.docstatus==1 ? "blue" : "grey" }}" title="{{ __("Target" ) }}">
+ {%= doc.t_warehouse %}</span>
+ </div>
+ {% }; %}
</div>
<!-- qty -->
diff --git a/erpnext/translations/ar.csv b/erpnext/translations/ar.csv
index c413ea0..9a6e5c5 100644
--- a/erpnext/translations/ar.csv
+++ b/erpnext/translations/ar.csv
@@ -512,8 +512,8 @@
apps/erpnext/erpnext/setup/setup_wizard/install_fixtures.py +139,Proposal Writing,الكتابة الاقتراح
apps/erpnext/erpnext/setup/doctype/sales_person/sales_person.py +35,Another Sales Person {0} exists with the same Employee id,شخص آخر مبيعات {0} موجود مع نفس الرقم الوظيفي
apps/erpnext/erpnext/config/accounts.py +70,Masters,الماجستير
-apps/erpnext/erpnext/config/accounts.py +135,Update Bank Transaction Dates,تواريخ عملية البنك التحديث
-apps/erpnext/erpnext/stock/stock_ledger.py +337,Negative Stock Error ({6}) for Item {0} in Warehouse {1} on {2} {3} in {4} {5},خطأ الأسهم السلبية ( { } 6 ) القطعة ل {0} في {1} في معرض النماذج ثلاثية على {2} {3} {4} في {5}
+apps/erpnext/erpnext/config/accounts.py +127,Update Bank Transaction Dates,تواريخ عملية البنك التحديث
+apps/erpnext/erpnext/stock/stock_ledger.py +337,Negative Stock Error ({6}) for Item {0} in Warehouse {1} on {2} {3} in {4} {5},خطأ الأسهم السلبية ( {6} ) القطعة ل {0} في {1} في معرض النماذج ثلاثية على {2} {3} {4} في {5}
apps/erpnext/erpnext/config/projects.py +30,Time Tracking,تتبع الوقت
DocType: Fiscal Year Company,Fiscal Year Company,الشركة السنة المالية
DocType: Packing Slip Item,DN Detail,DN التفاصيل
@@ -643,7 +643,7 @@
#### Description of Columns
-1. Calculation Type:
+1. Calculation Type:
- This can be on **Net Total** (that is the sum of basic amount).
- **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.
- **Actual** (as mentioned).
@@ -654,19 +654,19 @@
6. Amount: Tax amount.
7. Total: Cumulative total to this point.
8. Enter Row: If based on ""Previous Row Total"" you can select the row number which will be taken as a base for this calculation (default is the previous row).
-9. Is this Tax included in Basic Rate?: If you check this, it means that this tax will not be shown below the item table, but will be included in the Basic Rate in your main item table. This is useful where you want give a flat price (inclusive of all taxes) price to customers.","قالب الضرائب القياسية التي يمكن تطبيقها على جميع عمليات البيع. يمكن أن يحتوي هذا القالب قائمة رؤساء الضريبية، وكذلك غيرهم من رؤساء حساب / الدخل مثل ""شحن""، ""التأمين""، ""معالجة""، وغيرها
+9. Is this Tax included in Basic Rate?: If you check this, it means that this tax will not be shown below the item table, but will be included in the Basic Rate in your main item table. This is useful where you want give a flat price (inclusive of all taxes) price to customers.","قالب الضرائب القياسية التي يمكن تطبيقها على جميع عمليات البيع. يمكن أن يحتوي هذا القالب قائمة رؤساء الضريبية، وكذلك غيرهم من رؤساء حساب / الدخل مثل ""شحن""، ""التأمين""، ""معالجة""، وغيرها
- #### ملاحظة
+ #### ملاحظة
معدل الضريبة لك تعريف هنا سوف يكون معدل الضريبة موحد لجميع الأصناف ** **. إذا كانت هناك بنود ** ** التي لها أسعار مختلفة، وأنها يجب أن يضاف في * الضرائب البند ** الجدول في البند ** ** الرئيسي.
- #### وصف الأعمدة
+ #### وصف الأعمدة
- 1. نوع الحساب:
+ 1. نوع الحساب:
- وهذا يمكن أن يكون على ** صافي إجمالي ** (وهذا هو مجموع المبلغ الأساسي).
- ** في الصف السابق الكل / المكونات ** (للضرائب أو رسوم التراكمية). إذا قمت بتحديد هذا الخيار، سيتم تطبيق الضريبة كنسبة مئوية من الصف السابق (في الجدول الضرائب) كمية أو المجموع.
- ** ** الفعلية (كما ذكر).
- 2. رئيس الحساب: حساب دفتر الأستاذ والتي بموجبها سيتم حجز هذه الضريبة
+ 2. رئيس الحساب: حساب دفتر الأستاذ والتي بموجبها سيتم حجز هذه الضريبة
3. مركز التكلفة: إذا الضرائب / الرسوم هو الدخل (مثل الشحن) أو حساب فإنه يحتاج إلى أن يتم الحجز مقابل مركز التكلفة.
4. الوصف: وصف الضريبية (التي ستتم طباعتها في الفواتير / الاقتباس).
5. معدل: معدل الضريبة.
@@ -1973,7 +1973,7 @@
#### Description of Columns
-1. Calculation Type:
+1. Calculation Type:
- This can be on **Net Total** (that is the sum of basic amount).
- **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.
- **Actual** (as mentioned).
@@ -1985,19 +1985,19 @@
7. Total: Cumulative total to this point.
8. Enter Row: If based on ""Previous Row Total"" you can select the row number which will be taken as a base for this calculation (default is the previous row).
9. Consider Tax or Charge for: In this section you can specify if the tax / charge is only for valuation (not a part of total) or only for total (does not add value to the item) or for both.
-10. Add or Deduct: Whether you want to add or deduct the tax.","قالب الضرائب القياسية التي يمكن تطبيقها على جميع المعاملات شراء. يمكن أن يحتوي هذا القالب قائمة رؤساء الضريبية، وكذلك غيرهم من رؤساء حساب مثل ""شحن""، ""التأمين""، ""معالجة""، وغيرها
+10. Add or Deduct: Whether you want to add or deduct the tax.","قالب الضرائب القياسية التي يمكن تطبيقها على جميع المعاملات شراء. يمكن أن يحتوي هذا القالب قائمة رؤساء الضريبية، وكذلك غيرهم من رؤساء حساب مثل ""شحن""، ""التأمين""، ""معالجة""، وغيرها
- #### ملاحظة
+ #### ملاحظة
معدل الضريبة التي تحدد هنا سوف يكون معدل الضريبة موحد لجميع الأصناف ** **. إذا كانت هناك بنود ** ** التي لها أسعار مختلفة، وأنها يجب أن يضاف في * الضرائب البند ** الجدول في البند ** ** الرئيسي.
- #### وصف الأعمدة
+ #### وصف الأعمدة
- 1. نوع الحساب:
+ 1. نوع الحساب:
- وهذا يمكن أن يكون على ** صافي إجمالي ** (وهذا هو مجموع المبلغ الأساسي).
- ** في الصف السابق الكل / المكونات ** (للضرائب أو رسوم التراكمية). إذا قمت بتحديد هذا الخيار، سيتم تطبيق الضريبة كنسبة مئوية من الصف السابق (في الجدول الضرائب) كمية أو المجموع.
- ** ** الفعلية (كما ذكر).
- 2. رئيس الحساب: حساب دفتر الأستاذ والتي بموجبها سيتم حجز هذه الضريبة
+ 2. رئيس الحساب: حساب دفتر الأستاذ والتي بموجبها سيتم حجز هذه الضريبة
3. مركز التكلفة: إذا الضرائب / الرسوم هو الدخل (مثل الشحن) أو حساب فإنه يحتاج إلى أن يتم الحجز مقابل مركز التكلفة.
4. الوصف: وصف الضريبية (التي ستتم طباعتها في الفواتير / الاقتباس).
5. معدل: معدل الضريبة.
@@ -2168,7 +2168,7 @@
1. Ways of addressing disputes, indemnity, liability, etc.
1. Address and Contact of your Company.","الشروط والأحكام التي يمكن أن تضاف إلى المبيعات والمشتريات القياسية.
- أمثلة:
+ أمثلة:
1. صلاحية العرض.
1. شروط الدفع (مقدما، وعلى الائتمان، وجزء مسبقا الخ).
@@ -2177,7 +2177,7 @@
1. الضمان إن وجدت.
1. عودة السياسة.
1. شروط الشحن، إذا كان ذلك ممكنا.
- 1. سبل معالجة النزاعات، التعويض، والمسؤولية، الخ
+ 1. سبل معالجة النزاعات، التعويض، والمسؤولية، الخ
1. معالجة والاتصال من الشركة الخاصة بك."
DocType: Attendance,Leave Type,ترك نوع
apps/erpnext/erpnext/controllers/stock_controller.py +173,Expense / Difference account ({0}) must be a 'Profit or Loss' account,"حساب / حساب الفرق ({0}) يجب أن يكون الربح أو الخسارة ""حساب"
@@ -2460,7 +2460,7 @@
apps/erpnext/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py +102,Email sent to supplier {0},البريد الإلكتروني المرسلة إلى المورد {0}
apps/erpnext/erpnext/hr/doctype/leave_block_list/leave_block_list.py +19,Date is repeated,ويتكرر التاريخ
apps/erpnext/erpnext/accounts/print_format/payment_receipt_voucher/payment_receipt_voucher.html +27,Authorized Signatory,المفوض بالتوقيع
-apps/erpnext/erpnext/hr/doctype/leave_application/leave_application.py +187,Leave approver must be one of {0},"الموافق عل الاجازة يجب ان يكون واحد من
+apps/erpnext/erpnext/hr/doctype/leave_application/leave_application.py +187,Leave approver must be one of {0},"الموافق عل الاجازة يجب ان يكون واحد من
{0}"
DocType: Hub Settings,Seller Email,البائع البريد الإلكتروني
DocType: Project,Total Purchase Cost (via Purchase Invoice),مجموع تكلفة الشراء (عن طريق شراء الفاتورة)
@@ -3069,7 +3069,7 @@
apps/erpnext/erpnext/setup/setup_wizard/industry_type.py +15,Brokerage,سمسرة
DocType: Address,Postal Code,الرمز البريدي
DocType: Production Order Operation,"in Minutes
-Updated via 'Time Log'","في دقائق
+Updated via 'Time Log'","في دقائق
تحديث عبر 'وقت دخول """
DocType: Customer,From Lead,من العميل المحتمل
apps/erpnext/erpnext/config/manufacturing.py +13,Orders released for production.,أوامر الإفراج عن الإنتاج.
@@ -3237,7 +3237,7 @@
apps/erpnext/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py +42,Bank Statement balance as per General Ledger,بنك ميزان بيان وفقا لدفتر الأستاذ العام
DocType: Job Applicant,Applicant Name,اسم مقدم الطلب
DocType: Authorization Rule,Customer / Item Name,العميل / أسم البند
-DocType: Product Bundle,"Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**.
+DocType: Product Bundle,"Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**.
The package **Item** will have ""Is Stock Item"" as ""No"" and ""Is Sales Item"" as ""Yes"".
@@ -3370,17 +3370,17 @@
{% if phone %}Phone: {{ phone }}<br>{% endif -%}
{% if fax %}Fax: {{ fax }}<br>{% endif -%}
{% if email_id %}Email: {{ email_id }}<br>{% endif -%}
-</code></pre>","<H4> افتراضي قالب </ H4>
- <p> ويستخدم <a href=""http://jinja.pocoo.org/docs/templates/""> جينجا قالبي templating </A> وجميع مجالات عنوان ( بما في ذلك الحقول المخصصة إن وجدت) سوف تكون متاحة </ P>
- <قبل> <كود> {{address_line1}} العلامة & lt؛ BR & GT؛
- {٪ إذا address_line2٪} {{address_line2}} العلامة & lt؛ BR & GT؛ { ENDIF٪ -٪}
- {{مدينة}} العلامة & lt؛ BR & GT؛
- {٪ إذا الدولة٪} {{دولة}} العلامة & lt؛ BR & GT؛ {٪ ENDIF -٪}
- {٪ إذا كان الرقم السري٪} PIN: {{الرقم السري}} العلامة & lt؛ BR & GT؛ {٪ ENDIF -٪}
- {{البلاد}} العلامة & lt؛ BR & GT؛
- {٪ إذا كان الهاتف٪} الهاتف: {{هاتف}} العلامة & lt؛ BR & GT؛ { ٪ ENDIF -٪}
- {٪ إذا الفاكس٪} فاكس: {{الفاكس}} العلامة & lt؛ BR & GT؛ {٪ ENDIF -٪}
- {٪ إذا٪ email_id} البريد الإلكتروني: {{email_id}} العلامة & lt؛ BR & GT ؛ {٪ ENDIF -٪}
+</code></pre>","<H4> افتراضي قالب </ H4>
+ <p> ويستخدم <a href=""http://jinja.pocoo.org/docs/templates/""> جينجا قالبي templating </A> وجميع مجالات عنوان ( بما في ذلك الحقول المخصصة إن وجدت) سوف تكون متاحة </ P>
+ <قبل> <كود> {{address_line1}} العلامة & lt؛ BR & GT؛
+ {٪ إذا address_line2٪} {{address_line2}} العلامة & lt؛ BR & GT؛ { ENDIF٪ -٪}
+ {{مدينة}} العلامة & lt؛ BR & GT؛
+ {٪ إذا الدولة٪} {{دولة}} العلامة & lt؛ BR & GT؛ {٪ ENDIF -٪}
+ {٪ إذا كان الرقم السري٪} PIN: {{الرقم السري}} العلامة & lt؛ BR & GT؛ {٪ ENDIF -٪}
+ {{البلاد}} العلامة & lt؛ BR & GT؛
+ {٪ إذا كان الهاتف٪} الهاتف: {{هاتف}} العلامة & lt؛ BR & GT؛ { ٪ ENDIF -٪}
+ {٪ إذا الفاكس٪} فاكس: {{الفاكس}} العلامة & lt؛ BR & GT؛ {٪ ENDIF -٪}
+ {٪ إذا٪ email_id} البريد الإلكتروني: {{email_id}} العلامة & lt؛ BR & GT ؛ {٪ ENDIF -٪}
</ الرمز> </ PRE>"
DocType: Salary Slip Deduction,Default Amount,المبلغ الافتراضي
apps/erpnext/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +96,Warehouse not found in the system,لم يتم العثور على المستودع في النظام
@@ -3561,7 +3561,7 @@
apps/erpnext/erpnext/crm/doctype/newsletter_list/newsletter_list.js +40,New Newsletter,النشرة الإخبارية جديدة
apps/erpnext/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py +148,Start date should be less than end date for Item {0},يجب أن يكون تاريخ البدء أقل من تاريخ انتهاء القطعة ل {0}
DocType: Item,"Example: ABCD.#####
-If series is set and Serial No is not mentioned in transactions, then automatic serial number will be created based on this series. If you always want to explicitly mention Serial Nos for this item. leave this blank.","مثال: ABCD #####
+If series is set and Serial No is not mentioned in transactions, then automatic serial number will be created based on this series. If you always want to explicitly mention Serial Nos for this item. leave this blank.","مثال: ABCD #####
إذا تم تعيين سلسلة وليس المذكورة لا المسلسل في المعاملات، سيتم إنشاء الرقم التسلسلي ثم التلقائي على أساس هذه السلسلة. إذا كنت تريد دائما أن يذكر صراحة المسلسل رقم لهذا البند. ترك هذا فارغا."
DocType: Upload Attendance,Upload Attendance,تحميل الحضور
apps/erpnext/erpnext/stock/doctype/stock_entry/stock_entry.js +119,BOM and Manufacturing Quantity are required,ويلزم BOM والتصنيع الكمية
diff --git a/setup.py b/setup.py
index de74510..fb914f8 100644
--- a/setup.py
+++ b/setup.py
@@ -1,7 +1,7 @@
from setuptools import setup, find_packages
from pip.req import parse_requirements
-version = "6.27.11"
+version = "6.27.15"
requirements = parse_requirements("requirements.txt", session="")
setup(