Merge branch 'develop' of https://github.com/frappe/erpnext.git into Item-Tax-Template-V12
# Conflicts:
# erpnext/patches.txt
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index e42f0d8..f031583 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -5,7 +5,7 @@
from erpnext.hooks import regional_overrides
from frappe.utils import getdate
-__version__ = '10.1.76'
+__version__ = '10.1.77'
def get_default_company(user=None):
'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js
index dad75b4..297bedc 100644
--- a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js
+++ b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js
@@ -39,6 +39,8 @@
});
frm.events.get_total_gain_loss(frm);
refresh_field("accounts");
+ } else {
+ frappe.msgprint(__("No records found"));
}
}
});
diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py
index ae77516..cdfe34b 100644
--- a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py
+++ b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py
@@ -67,17 +67,19 @@
and account_currency != %s
order by name""",(self.company, company_currency))
- account_details = frappe.db.sql("""
- select
- account, party_type, party, account_currency,
- sum(debit_in_account_currency) - sum(credit_in_account_currency) as balance_in_account_currency,
- sum(debit) - sum(credit) as balance
- from `tabGL Entry`
- where account in (%s)
- group by account, party_type, party
- having sum(debit) != sum(credit)
- order by account
- """ % ', '.join(['%s']*len(accounts)), tuple(accounts), as_dict=1)
+ account_details = []
+ if accounts:
+ account_details = frappe.db.sql("""
+ select
+ account, party_type, party, account_currency,
+ sum(debit_in_account_currency) - sum(credit_in_account_currency) as balance_in_account_currency,
+ sum(debit) - sum(credit) as balance
+ from `tabGL Entry`
+ where account in (%s)
+ group by account, party_type, party
+ having sum(debit) != sum(credit)
+ order by account
+ """ % ', '.join(['%s']*len(accounts)), tuple(accounts), as_dict=1)
return account_details
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.json b/erpnext/accounts/doctype/gl_entry/gl_entry.json
index 66d527d..333d39a 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.json
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.json
@@ -1,904 +1,938 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "ACC-GLE-.YYYY.-.#####",
- "beta": 0,
- "creation": "2013-01-10 16:34:06",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Document",
- "editable_grid": 0,
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "ACC-GLE-.YYYY.-.#####",
+ "beta": 0,
+ "creation": "2013-01-10 16:34:06",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Document",
+ "editable_grid": 0,
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "posting_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Posting Date",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "posting_date",
- "oldfieldtype": "Date",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "posting_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Posting Date",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "posting_date",
+ "oldfieldtype": "Date",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "transaction_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Transaction Date",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "transaction_date",
- "oldfieldtype": "Date",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "transaction_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Transaction Date",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "transaction_date",
+ "oldfieldtype": "Date",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Account",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "account",
- "oldfieldtype": "Link",
- "options": "Account",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Account",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "account",
+ "oldfieldtype": "Link",
+ "options": "Account",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "party_type",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Party Type",
- "length": 0,
- "no_copy": 0,
- "options": "DocType",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "party_type",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Party Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "DocType",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "party",
- "fieldtype": "Dynamic Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 1,
- "label": "Party",
- "length": 0,
- "no_copy": 0,
- "options": "party_type",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "party",
+ "fieldtype": "Dynamic Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 1,
+ "label": "Party",
+ "length": 0,
+ "no_copy": 0,
+ "options": "party_type",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "cost_center",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Cost Center",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "cost_center",
- "oldfieldtype": "Link",
- "options": "Cost Center",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "cost_center",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Cost Center",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "cost_center",
+ "oldfieldtype": "Link",
+ "options": "Cost Center",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "debit",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Debit Amount",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "debit",
- "oldfieldtype": "Currency",
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "debit",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Debit Amount",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "debit",
+ "oldfieldtype": "Currency",
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "credit",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Credit Amount",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "credit",
- "oldfieldtype": "Currency",
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "credit",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Credit Amount",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "credit",
+ "oldfieldtype": "Currency",
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "account_currency",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Account Currency",
- "length": 0,
- "no_copy": 0,
- "options": "Currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "account_currency",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Account Currency",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "debit_in_account_currency",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Debit Amount in Account Currency",
- "length": 0,
- "no_copy": 0,
- "options": "currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "debit_in_account_currency",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Debit Amount in Account Currency",
+ "length": 0,
+ "no_copy": 0,
+ "options": "currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "credit_in_account_currency",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Credit Amount in Account Currency",
- "length": 0,
- "no_copy": 0,
- "options": "currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "credit_in_account_currency",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Credit Amount in Account Currency",
+ "length": 0,
+ "no_copy": 0,
+ "options": "currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "against",
- "fieldtype": "Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Against",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "against",
- "oldfieldtype": "Text",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "against",
+ "fieldtype": "Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Against",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "against",
+ "oldfieldtype": "Text",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "against_voucher_type",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Against Voucher Type",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "against_voucher_type",
- "oldfieldtype": "Data",
- "options": "DocType",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "against_voucher_type",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Against Voucher Type",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "against_voucher_type",
+ "oldfieldtype": "Data",
+ "options": "DocType",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "against_voucher",
- "fieldtype": "Dynamic Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Against Voucher",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "against_voucher",
- "oldfieldtype": "Data",
- "options": "against_voucher_type",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "against_voucher",
+ "fieldtype": "Dynamic Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Against Voucher",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "against_voucher",
+ "oldfieldtype": "Data",
+ "options": "against_voucher_type",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "voucher_type",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Voucher Type",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "voucher_type",
- "oldfieldtype": "Select",
- "options": "DocType",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "voucher_type",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Voucher Type",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "voucher_type",
+ "oldfieldtype": "Select",
+ "options": "DocType",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "voucher_no",
- "fieldtype": "Dynamic Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 1,
- "label": "Voucher No",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "voucher_no",
- "oldfieldtype": "Data",
- "options": "voucher_type",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "voucher_no",
+ "fieldtype": "Dynamic Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 1,
+ "label": "Voucher No",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "voucher_no",
+ "oldfieldtype": "Data",
+ "options": "voucher_type",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "voucher_detail_no",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Voucher Detail No",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "voucher_detail_no",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Voucher Detail No",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "project",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Project",
- "length": 0,
- "no_copy": 0,
- "options": "Project",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "project",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Project",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Project",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "remarks",
- "fieldtype": "Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Remarks",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "remarks",
- "oldfieldtype": "Text",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "remarks",
+ "fieldtype": "Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Remarks",
+ "length": 0,
+ "no_copy": 1,
+ "oldfieldname": "remarks",
+ "oldfieldtype": "Text",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "is_opening",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Is Opening",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "is_opening",
- "oldfieldtype": "Select",
- "options": "No\nYes",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "is_opening",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Is Opening",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "is_opening",
+ "oldfieldtype": "Select",
+ "options": "No\nYes",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "is_advance",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Is Advance",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "is_advance",
- "oldfieldtype": "Select",
- "options": "No\nYes",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "is_advance",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Is Advance",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "is_advance",
+ "oldfieldtype": "Select",
+ "options": "No\nYes",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "fiscal_year",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Fiscal Year",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "fiscal_year",
- "oldfieldtype": "Select",
- "options": "Fiscal Year",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "fiscal_year",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Fiscal Year",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "fiscal_year",
+ "oldfieldtype": "Select",
+ "options": "Fiscal Year",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "company",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Company",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "company",
- "oldfieldtype": "Link",
- "options": "Company",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Company",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "company",
+ "oldfieldtype": "Link",
+ "options": "Company",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "finance_book",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Finance Book",
- "length": 0,
- "no_copy": 0,
- "options": "Finance Book",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "finance_book",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Finance Book",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Finance Book",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "fieldname": "to_rename",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "To Rename",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "icon": "fa fa-list",
- "idx": 1,
- "image_view": 0,
- "in_create": 1,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-08-21 16:15:45.156222",
- "modified_by": "Administrator",
- "module": "Accounts",
- "name": "GL Entry",
- "owner": "Administrator",
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "icon": "fa fa-list",
+ "idx": 1,
+ "image_view": 0,
+ "in_create": 1,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2019-01-07 07:05:00.366399",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "GL Entry",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Accounts User",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
+ "amend": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Accounts User",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
"write": 0
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "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": 0,
- "submit": 0,
+ "amend": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "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": 0,
+ "submit": 0,
"write": 0
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 0,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 0,
- "read": 1,
- "report": 1,
- "role": "Auditor",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
+ "amend": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 0,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 0,
+ "read": 1,
+ "report": 1,
+ "role": "Auditor",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
"write": 0
}
- ],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "search_fields": "voucher_no,account,posting_date,against_voucher",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 0,
- "track_seen": 0,
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "search_fields": "voucher_no,account,posting_date,against_voucher",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 0,
+ "track_seen": 0,
"track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py
index db93cf9..1fff11b 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.py
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py
@@ -6,27 +6,33 @@
from frappe import _
from frappe.utils import flt, fmt_money, getdate, formatdate
from frappe.model.document import Document
+from frappe.model.naming import set_name_from_naming_options
from erpnext.accounts.party import validate_party_gle_currency, validate_party_frozen_disabled
from erpnext.accounts.utils import get_account_currency
from erpnext.accounts.utils import get_fiscal_year
from erpnext.exceptions import InvalidAccountCurrency
exclude_from_linked_with = True
-
class GLEntry(Document):
+ def autoname(self):
+ """
+ Temporarily name doc for fast insertion
+ name will be changed using autoname options (in a scheduled job)
+ """
+ self.name = frappe.generate_hash(txt="", length=10)
+
def validate(self):
self.flags.ignore_submit_comment = True
self.check_mandatory()
self.validate_and_set_fiscal_year()
+ self.pl_must_have_cost_center()
+ self.validate_cost_center()
if not self.flags.from_repost:
- self.pl_must_have_cost_center()
self.check_pl_account()
- self.validate_cost_center()
self.validate_party()
self.validate_currency()
-
def on_update_with_args(self, adv_adj, update_outstanding = 'Yes', from_repost=False):
if not from_repost:
self.validate_account_details(adv_adj)
@@ -231,3 +237,17 @@
if d.against != new_against:
frappe.db.set_value("GL Entry", d.name, "against", new_against)
+
+
+def rename_gle_sle_docs():
+ for doctype in ["GL Entry", "Stock Ledger Entry"]:
+ rename_temporarily_named_docs(doctype)
+
+def rename_temporarily_named_docs(doctype):
+ """Rename temporarily named docs using autoname options"""
+ docs_to_rename = frappe.get_all(doctype, {"to_rename": "1"}, order_by="creation")
+ for doc in docs_to_rename:
+ oldname = doc.name
+ set_name_from_naming_options(frappe.get_meta(doctype).autoname, doc)
+ newname = doc.name
+ frappe.db.sql("""UPDATE `tab{}` SET name = %s, to_rename = 0 where name = %s""".format(doctype), (newname, oldname))
diff --git a/erpnext/accounts/doctype/gl_entry/test_gl_entry.py b/erpnext/accounts/doctype/gl_entry/test_gl_entry.py
index 6cc9bc8..01ddd29 100644
--- a/erpnext/accounts/doctype/gl_entry/test_gl_entry.py
+++ b/erpnext/accounts/doctype/gl_entry/test_gl_entry.py
@@ -3,7 +3,9 @@
from __future__ import unicode_literals
import frappe, unittest
+from frappe.model.naming import parse_naming_series
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
+from erpnext.accounts.doctype.gl_entry.gl_entry import rename_gle_sle_docs
class TestGLEntry(unittest.TestCase):
def test_round_off_entry(self):
@@ -23,3 +25,32 @@
and debit = 0 and credit = '.01'""", jv.name)
self.assertTrue(round_off_entry)
+
+ def test_rename_entries(self):
+ je = make_journal_entry("_Test Account Cost for Goods Sold - _TC", "_Test Bank - _TC", 100, submit=True)
+ rename_gle_sle_docs()
+ naming_series = parse_naming_series(parts=frappe.get_meta("GL Entry").autoname.split(".")[:-1])
+
+ je = make_journal_entry("_Test Account Cost for Goods Sold - _TC", "_Test Bank - _TC", 100, submit=True)
+
+ gl_entries = frappe.get_all("GL Entry",
+ fields=["name", "to_rename"],
+ filters={"voucher_type": "Journal Entry", "voucher_no": je.name},
+ order_by="creation"
+ )
+ self.assertTrue(all(entry.to_rename == 1 for entry in gl_entries))
+ old_naming_series_current_value = frappe.db.sql("SELECT current from tabSeries where name = %s", naming_series)[0][0]
+
+ rename_gle_sle_docs()
+
+ new_gl_entries = frappe.get_all("GL Entry",
+ fields=["name", "to_rename"],
+ filters={"voucher_type": "Journal Entry", "voucher_no": je.name},
+ order_by="creation"
+ )
+ self.assertTrue(all(entry.to_rename == 0 for entry in new_gl_entries))
+
+ self.assertTrue(all(new.name != old.name for new, old in zip(gl_entries, new_gl_entries)))
+
+ new_naming_series_current_value = frappe.db.sql("SELECT current from tabSeries where name = %s", naming_series)[0][0]
+ self.assertEquals(old_naming_series_current_value + 2, new_naming_series_current_value)
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 44c8fb9..bfee235 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -786,7 +786,7 @@
# check gl entries
gl_entries = frappe.db.sql("""select account, debit, credit
from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
- order by account asc, debit asc""", si.name, as_dict=1)
+ order by account asc, debit asc, credit asc""", si.name, as_dict=1)
self.assertTrue(gl_entries)
stock_in_hand = get_inventory_account('_Test Company')
@@ -819,7 +819,7 @@
set_perpetual_inventory(0)
frappe.db.sql("delete from `tabPOS Profile`")
-
+
def test_pos_si_without_payment(self):
set_perpetual_inventory()
make_pos_profile()
diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py
index 2ed664c..3a51ceb 100644
--- a/erpnext/accounts/report/gross_profit/gross_profit.py
+++ b/erpnext/accounts/report/gross_profit/gross_profit.py
@@ -184,7 +184,7 @@
def get_returned_invoice_items(self):
returned_invoices = frappe.db.sql("""
select
- si.name, si_item.item_code, si_item.qty, si_item.base_amount, si.return_against
+ si.name, si_item.item_code, si_item.stock_qty as qty, si_item.base_net_amount as base_amount, si.return_against
from
`tabSales Invoice` si, `tabSales Invoice Item` si_item
where
@@ -200,7 +200,7 @@
def skip_row(self, row, product_bundles):
if self.filters.get("group_by") != "Invoice":
- if not row.get(scrub(self.filters.get("group_by"))):
+ if not row.get(scrub(self.filters.get("group_by", ""))):
return True
elif row.get("is_return") == 1:
return True
@@ -316,7 +316,7 @@
on `tabSales Invoice Item`.parent = `tabSales Invoice`.name
{sales_team_table}
where
- `tabSales Invoice`.docstatus=1 {conditions} {match_cond}
+ `tabSales Invoice`.docstatus=1 and `tabSales Invoice`.is_opening!='Yes' {conditions} {match_cond}
order by
`tabSales Invoice`.posting_date desc, `tabSales Invoice`.posting_time desc"""
.format(conditions=conditions, sales_person_cols=sales_person_cols,
@@ -329,7 +329,7 @@
where company=%(company)s
order by
item_code desc, warehouse desc, posting_date desc,
- posting_time desc, name desc""", self.filters, as_dict=True)
+ posting_time desc, creation desc""", self.filters, as_dict=True)
self.sle = {}
for r in res:
if (r.item_code, r.warehouse) not in self.sle:
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index d3566fe..2a80305 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -655,7 +655,7 @@
or (voucher_type not in ('Journal Entry', 'Payment Entry')))
group by voucher_type, voucher_no
having (invoice_amount - payment_amount) > 0.005
- order by posting_date, name""".format(
+ order by posting_date, creation""".format(
dr_or_cr=dr_or_cr,
invoice = invoice,
payment_dr_or_cr=payment_dr_or_cr,
diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json
index 5296e22..6b3c3cc73 100644
--- a/erpnext/assets/doctype/asset/asset.json
+++ b/erpnext/assets/doctype/asset/asset.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
@@ -154,7 +155,7 @@
"columns": 0,
"fetch_from": "item_code.asset_category",
"fieldname": "asset_category",
- "fieldtype": "Read Only",
+ "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -165,12 +166,12 @@
"label": "Asset Category",
"length": 0,
"no_copy": 0,
- "options": "",
+ "options": "Asset Category",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 0,
+ "read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@@ -1881,7 +1882,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-08-21 14:44:24.507215",
+ "modified": "2019-01-15 16:12:48.314196",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset",
diff --git a/erpnext/config/desktop.py b/erpnext/config/desktop.py
index 2202b9e..cc7ee02 100644
--- a/erpnext/config/desktop.py
+++ b/erpnext/config/desktop.py
@@ -575,9 +575,9 @@
},
{
"module_name": "Quality Management",
- "color": "blue",
- "icon": "octicon octicon-package",
+ "color": "#1abc9c",
+ "icon": "fa fa-check-square-o",
"type": "module",
- "label": _("Quality Management")
+ "label": _("Quality")
}
- ]
+ ]
\ No newline at end of file
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 19616c5..06b2753 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -678,7 +678,9 @@
frappe.db.sql("delete from `tabSerial No` where purchase_document_no=%s", self.name)
def validate_schedule_date(self):
- if not self.schedule_date and self.get("items"):
+ if not self.get("items"):
+ return
+ if not self.schedule_date:
self.schedule_date = min([d.schedule_date for d in self.get("items")])
if self.schedule_date:
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 684a2cd..b8a361f 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -179,7 +179,7 @@
last_valuation_rate = frappe.db.sql("""
SELECT valuation_rate FROM `tabStock Ledger Entry` WHERE item_code = %s
AND warehouse = %s AND valuation_rate > 0
- ORDER BY posting_date DESC, posting_time DESC, name DESC LIMIT 1
+ ORDER BY posting_date DESC, posting_time DESC, creation DESC LIMIT 1
""", (it.item_code, it.warehouse))
if last_valuation_rate:
last_valuation_rate_in_sales_uom = last_valuation_rate[0][0] / (it.conversion_factor or 1)
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index 63e89ab..0c79274 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -413,7 +413,7 @@
for d in frappe.db.sql("""select distinct sle.voucher_type, sle.voucher_no
from `tabStock Ledger Entry` sle
where timestamp(sle.posting_date, sle.posting_time) >= timestamp(%s, %s) {condition}
- order by timestamp(sle.posting_date, sle.posting_time) asc, name asc""".format(condition=condition),
+ order by timestamp(sle.posting_date, sle.posting_time) asc, creation asc""".format(condition=condition),
tuple([posting_date, posting_time] + values), as_dict=True):
future_stock_vouchers.append([d.voucher_type, d.voucher_no])
diff --git a/erpnext/demo/user/purchase.py b/erpnext/demo/user/purchase.py
index 6993044..86757df 100644
--- a/erpnext/demo/user/purchase.py
+++ b/erpnext/demo/user/purchase.py
@@ -64,7 +64,7 @@
report = "Material Requests for which Supplier Quotations are not created"
for row in query_report.run(report)["result"][:random.randint(1, 3)]:
- if row[0] != "'Total'":
+ if row[0] != "Total":
sq = frappe.get_doc(make_supplier_quotation(row[0]))
sq.transaction_date = frappe.flags.current_date
sq.supplier = supplier
@@ -79,7 +79,7 @@
from erpnext.stock.doctype.material_request.material_request import make_purchase_order
report = "Requested Items To Be Ordered"
for row in query_report.run(report)["result"][:how_many("Purchase Order")]:
- if row[0] != "'Total'":
+ if row[0] != "Total":
try:
po = frappe.get_doc(make_purchase_order(row[0]))
po.supplier = supplier
diff --git a/erpnext/demo/user/stock.py b/erpnext/demo/user/stock.py
index 6036a26..60b1edc 100644
--- a/erpnext/demo/user/stock.py
+++ b/erpnext/demo/user/stock.py
@@ -25,7 +25,7 @@
if random.random() < 0.6:
from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt
report = "Purchase Order Items To Be Received"
- po_list =list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="'Total'"]))[:random.randint(1, 10)]
+ po_list =list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="Total"]))[:random.randint(1, 10)]
for po in po_list:
pr = frappe.get_doc(make_purchase_receipt(po))
@@ -49,7 +49,7 @@
from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note
report = "Ordered Items To Be Delivered"
for so in list(set([r[0] for r in query_report.run(report)["result"]
- if r[0]!="'Total'"]))[:random.randint(1, 3)]:
+ if r[0]!="Total"]))[:random.randint(1, 3)]:
dn = frappe.get_doc(make_delivery_note(so))
dn.posting_date = frappe.flags.current_date
for d in dn.get("items"):
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 621e262..ed6f21b 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -235,7 +235,9 @@
"hourly": [
'erpnext.hr.doctype.daily_work_summary_group.daily_work_summary_group.trigger_emails',
"erpnext.accounts.doctype.subscription.subscription.process_all",
- "erpnext.erpnext_integrations.doctype.amazon_mws_settings.amazon_mws_settings.schedule_get_order_details"
+ "erpnext.erpnext_integrations.doctype.amazon_mws_settings.amazon_mws_settings.schedule_get_order_details",
+ "erpnext.accounts.doctype.gl_entry.gl_entry.rename_gle_sle_docs",
+
],
"daily": [
"erpnext.stock.reorder_item.reorder_item",
diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js
index 2615b31..7b5339b 100644
--- a/erpnext/manufacturing/doctype/bom/bom.js
+++ b/erpnext/manufacturing/doctype/bom/bom.js
@@ -121,9 +121,11 @@
freeze: true,
args: {
update_parent: true,
- from_child_bom:false
+ from_child_bom:false,
+ save: false
},
callback: function(r) {
+ refresh_field("items");
if(!r.exc) frm.refresh_fields();
}
});
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index a8053cd..abbd1b0 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -8,6 +8,7 @@
from erpnext.setup.utils import get_exchange_rate
from frappe.website.website_generator import WebsiteGenerator
from erpnext.stock.get_item_details import get_conversion_factor
+from erpnext.stock.get_item_details import get_price_list_rate
import functools
@@ -109,7 +110,11 @@
"item_name": item.item_name,
"bom_no": item.bom_no,
"stock_qty": item.stock_qty,
- "include_item_in_manufacturing": item.include_item_in_manufacturing
+ "include_item_in_manufacturing": item.include_item_in_manufacturing,
+ "qty": item.qty,
+ "uom": item.uom,
+ "stock_uom": item.stock_uom,
+ "conversion_factor": item.conversion_factor
})
for r in ret:
if not item.get(r):
@@ -141,7 +146,7 @@
'uom' : item and args['stock_uom'] or '',
'conversion_factor': 1,
'bom_no' : args['bom_no'],
- 'rate' : rate / self.conversion_rate if self.conversion_rate else rate,
+ 'rate' : rate,
'qty' : args.get("qty") or args.get("stock_qty") or 1,
'stock_qty' : args.get("qty") or args.get("stock_qty") or 1,
'base_rate' : rate,
@@ -175,35 +180,56 @@
elif self.rm_cost_as_per == "Price List":
if not self.buying_price_list:
frappe.throw(_("Please select Price List"))
- rate = frappe.db.get_value("Item Price", {"price_list": self.buying_price_list,
- "item_code": arg["item_code"]}, "price_list_rate") or 0.0
-
- price_list_currency = frappe.db.get_value("Price List",
- self.buying_price_list, "currency")
- if price_list_currency != self.company_currency():
- rate = flt(rate * self.conversion_rate)
+ args = frappe._dict({
+ "doctype": "BOM",
+ "price_list": self.buying_price_list,
+ "qty": arg.get("qty"),
+ "uom": arg.get("uom") or arg.get("stock_uom"),
+ "stock_uom": arg.get("stock_uom"),
+ "transaction_type": "buying",
+ "company": self.company,
+ "currency": self.currency,
+ "conversion_rate": self.conversion_rate or 1,
+ "conversion_factor": arg.get("conversion_factor") or 1,
+ "plc_conversion_rate": 1
+ })
+ item_doc = frappe.get_doc("Item", arg.get("item_code"))
+ out = frappe._dict()
+ get_price_list_rate(args, item_doc, out)
+ rate = out.price_list_rate
if not rate:
- frappe.msgprint(_("{0} not found for Item {1}")
- .format(self.rm_cost_as_per, arg["item_code"]), alert=True)
+ if self.rm_cost_as_per == "Price List":
+ frappe.msgprint(_("Price not found for item {0} and price list {1}")
+ .format(arg["item_code"], self.buying_price_list), alert=True)
+ else:
+ frappe.msgprint(_("{0} not found for item {1}")
+ .format(self.rm_cost_as_per, arg["item_code"]), alert=True)
return flt(rate)
- def update_cost(self, update_parent=True, from_child_bom=False):
+ def update_cost(self, update_parent=True, from_child_bom=False, save=True):
if self.docstatus == 2:
return
existing_bom_cost = self.total_cost
for d in self.get("items"):
- rate = self.get_rm_rate({"item_code": d.item_code, "bom_no": d.bom_no})
- if rate:
- d.rate = rate * flt(d.conversion_factor) / flt(self.conversion_rate)
+ d.rate = self.get_rm_rate({
+ "item_code": d.item_code,
+ "bom_no": d.bom_no,
+ "qty": d.qty,
+ "uom": d.uom,
+ "stock_uom": d.stock_uom,
+ "conversion_factor": d.conversion_factor
+ })
+ d.amount = flt(d.rate) * flt(d.qty)
if self.docstatus == 1:
self.flags.ignore_validate_update_after_submit = True
self.calculate_cost()
- self.save()
+ if save:
+ self.save()
self.update_exploded_items()
# update parent BOMs
@@ -246,7 +272,7 @@
last_valuation_rate = frappe.db.sql("""select valuation_rate
from `tabStock Ledger Entry`
where item_code = %s and valuation_rate > 0
- order by posting_date desc, posting_time desc, name desc limit 1""", args['item_code'])
+ order by posting_date desc, posting_time desc, creation desc limit 1""", args['item_code'])
valuation_rate = flt(last_valuation_rate[0][0]) if last_valuation_rate else 0
diff --git a/erpnext/manufacturing/doctype/bom/test_bom.py b/erpnext/manufacturing/doctype/bom/test_bom.py
index a000050..6d85ef3 100644
--- a/erpnext/manufacturing/doctype/bom/test_bom.py
+++ b/erpnext/manufacturing/doctype/bom/test_bom.py
@@ -76,7 +76,7 @@
# update cost of all BOMs based on latest valuation rate
update_cost()
-
+
# check if new valuation rate updated in all BOMs
for d in frappe.db.sql("""select rate from `tabBOM Item`
where item_code='_Test Item 2' and docstatus=1 and parenttype='BOM'""", as_dict=1):
@@ -97,6 +97,7 @@
self.assertEqual(bom.base_total_cost, 486000)
def test_bom_cost_multi_uom_multi_currency(self):
+ frappe.db.set_value("Price List", "_Test Price List", "price_not_uom_dependant", 1)
for item_code, rate in (("_Test Item", 3600), ("_Test Item Home Desktop Manufactured", 3000)):
frappe.db.sql("delete from `tabItem Price` where price_list='_Test Price List' and item_code=%s",
item_code)
@@ -105,7 +106,7 @@
item_price.item_code = item_code
item_price.price_list_rate = rate
item_price.insert()
-
+
bom = frappe.copy_doc(test_records[2])
bom.set_rate_of_sub_assembly_item_based_on_bom = 0
bom.rm_cost_as_per = "Price List"
diff --git a/erpnext/manufacturing/doctype/bom_item/bom_item.json b/erpnext/manufacturing/doctype/bom_item/bom_item.json
index 8d4d69b..754540e 100644
--- a/erpnext/manufacturing/doctype/bom_item/bom_item.json
+++ b/erpnext/manufacturing/doctype/bom_item/bom_item.json
@@ -1023,6 +1023,71 @@
"set_only_once": 0,
"translatable": 0,
"unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "operation",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Item operation",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Operation",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "allow_alternative_item",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Allow Alternative Item",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
}
],
"has_web_view": 0,
@@ -1035,7 +1100,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2018-12-28 16:38:56.529079",
+ "modified": "2018-11-23 15:05:55.187136",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM Item",
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index 7cd3f6b..80cbf6c 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -7,9 +7,9 @@
from frappe import msgprint, _
from frappe.model.document import Document
from erpnext.manufacturing.doctype.bom.bom import validate_bom_no
-from frappe.utils import cstr, flt, cint, nowdate, add_days, comma_and, now_datetime
+from frappe.utils import cstr, flt, cint, nowdate, add_days, comma_and, now_datetime, ceil
from erpnext.manufacturing.doctype.work_order.work_order import get_item_details
-from six import string_types
+from six import string_types, iteritems
from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
class ProductionPlan(Document):
@@ -373,40 +373,46 @@
else :
msgprint(_("No material request created"))
-def get_exploded_items(bom_wise_item_details, company, bom_no, include_non_stock_items):
+def get_exploded_items(item_details, company, bom_no, include_non_stock_items, planned_qty=1):
for d in frappe.db.sql("""select bei.item_code, item.default_bom as bom,
- ifnull(sum(bei.stock_qty/ifnull(bom.quantity, 1)), 0) as qty, item.item_name,
+ ifnull(sum(bei.stock_qty/ifnull(bom.quantity, 1)), 0)*%s as qty, item.item_name,
bei.description, bei.stock_uom, item.min_order_qty, bei.source_warehouse,
- item.default_material_request_type, item.min_order_qty, item_default.default_warehouse
+ item.default_material_request_type, item.min_order_qty, item_default.default_warehouse,
+ item.purchase_uom, item_uom.conversion_factor
from
`tabBOM Explosion Item` bei
JOIN `tabBOM` bom ON bom.name = bei.parent
JOIN `tabItem` item ON item.name = bei.item_code
LEFT JOIN `tabItem Default` item_default
ON item_default.parent = item.name and item_default.company=%s
+ LEFT JOIN `tabUOM Conversion Detail` item_uom
+ ON item.name = item_uom.parent and item_uom.uom = item.purchase_uom
where
bei.docstatus < 2
and bom.name=%s and item.is_stock_item in (1, {0})
group by bei.item_code, bei.stock_uom""".format(0 if include_non_stock_items else 1),
- (company, bom_no), as_dict=1):
- bom_wise_item_details.setdefault(d.get('item_code'), d)
- return bom_wise_item_details
+ (planned_qty, company, bom_no), as_dict=1):
+ item_details.setdefault(d.get('item_code'), d)
+ return item_details
-def get_subitems(doc, data, bom_wise_item_details, bom_no, company, include_non_stock_items, include_subcontracted_items, parent_qty):
+def get_subitems(doc, data, item_details, bom_no, company, include_non_stock_items,
+ include_subcontracted_items, parent_qty, planned_qty=1):
items = frappe.db.sql("""
SELECT
bom_item.item_code, default_material_request_type, item.item_name,
- ifnull(%(parent_qty)s * sum(bom_item.stock_qty/ifnull(bom.quantity, 1)), 0) as qty,
+ ifnull(%(parent_qty)s * sum(bom_item.stock_qty/ifnull(bom.quantity, 1)) * %(planned_qty)s, 0) as qty,
item.is_sub_contracted_item as is_sub_contracted, bom_item.source_warehouse,
item.default_bom as default_bom, bom_item.description as description,
bom_item.stock_uom as stock_uom, item.min_order_qty as min_order_qty,
- item_default.default_warehouse
+ item_default.default_warehouse, item.purchase_uom, item_uom.conversion_factor
FROM
`tabBOM Item` bom_item
JOIN `tabBOM` bom ON bom.name = bom_item.parent
JOIN tabItem item ON bom_item.item_code = item.name
LEFT JOIN `tabItem Default` item_default
ON item.name = item_default.parent and item_default.company = %(company)s
+ LEFT JOIN `tabUOM Conversion Detail` item_uom
+ ON item.name = item_uom.parent and item_uom.uom = item.purchase_uom
where
bom.name = %(bom)s
and bom_item.docstatus < 2
@@ -414,45 +420,61 @@
group by bom_item.item_code""".format(0 if include_non_stock_items else 1),{
'bom': bom_no,
'parent_qty': parent_qty,
+ 'planned_qty': planned_qty,
'company': company
}, as_dict=1)
for d in items:
if not data.get('include_exploded_items') or not d.default_bom:
- if d.item_code in bom_wise_item_details:
- bom_wise_item_details[d.item_code].qty = bom_wise_item_details[d.item_code].qty + d.qty
+ if d.item_code in item_details:
+ item_details[d.item_code].qty = item_details[d.item_code].qty + d.qty
else:
- bom_wise_item_details[d.item_code] = d
+ item_details[d.item_code] = d
if data.get('include_exploded_items') and d.default_bom:
if ((d.default_material_request_type in ["Manufacture", "Purchase"] and
not d.is_sub_contracted) or (d.is_sub_contracted and include_subcontracted_items)):
if d.qty > 0:
- get_subitems(doc, data, bom_wise_item_details, d.default_bom, company, include_non_stock_items, include_subcontracted_items, d.qty)
- return bom_wise_item_details
+ get_subitems(doc, data, item_details, d.default_bom, company,
+ include_non_stock_items, include_subcontracted_items, d.qty)
+ return item_details
-def add_item_in_material_request_items(doc, planned_qty, ignore_existing_ordered_qty, item, row, data, warehouse, company):
- total_qty = row.qty * planned_qty
+def get_material_request_items(row, sales_order, company, ignore_existing_ordered_qty, warehouse):
+ total_qty = row['qty']
projected_qty, actual_qty = get_bin_details(row)
requested_qty = 0
if ignore_existing_ordered_qty:
requested_qty = total_qty
- else:
+ elif total_qty > projected_qty:
requested_qty = total_qty - projected_qty
- if requested_qty > 0 and requested_qty < row.min_order_qty:
- requested_qty = row.min_order_qty
- item_group_defaults = get_item_group_defaults(item, company)
+ if requested_qty > 0 and requested_qty < row['min_order_qty']:
+ requested_qty = row['min_order_qty']
+ item_group_defaults = get_item_group_defaults(row.item_code, company)
+
+ if not row['purchase_uom']:
+ row['purchase_uom'] = row['stock_uom']
+
+ if row['purchase_uom'] != row['stock_uom']:
+ if not row['conversion_factor']:
+ frappe.throw(_("UOM Conversion factor ({0} -> {1}) not found for item: {2}")
+ .format(row['purchase_uom'], row['stock_uom'], row.item_code))
+ requested_qty = requested_qty / row['conversion_factor']
+
+ if frappe.db.get_value("UOM", row['purchase_uom'], "must_be_whole_number"):
+ requested_qty = ceil(requested_qty)
+
if requested_qty > 0:
- doc.setdefault('mr_items', []).append({
- 'item_code': item,
+ return {
+ 'item_code': row.item_code,
'item_name': row.item_name,
'quantity': requested_qty,
- 'warehouse': warehouse or row.source_warehouse or row.default_warehouse or item_group_defaults.get("default_warehouse"),
+ 'warehouse': warehouse or row.get('source_warehouse') \
+ or row.get('default_warehouse') or item_group_defaults.get("default_warehouse"),
'actual_qty': actual_qty,
- 'min_order_qty': row.min_order_qty,
- 'sales_order': data.get('sales_order')
- })
+ 'min_order_qty': row['min_order_qty'],
+ 'sales_order': sales_order
+ }
def get_sales_orders(self):
so_filter = item_filter = ""
@@ -488,8 +510,8 @@
"project": self.project,
"item": self.item_code,
"company": self.company
- }, as_dict=1)
+ }, as_dict=1)
return open_so
@frappe.whitelist()
@@ -498,56 +520,96 @@
row = frappe._dict(json.loads(row))
conditions = ""
- warehouse = row.source_warehouse or row.default_warehouse or row.warehouse
+ warehouse = row.get('source_warehouse') or row.get('default_warehouse')
if warehouse:
- conditions = " and warehouse={0}".format(frappe.db.escape(warehouse))
+ lft, rgt = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"])
+ conditions = " and exists(select name from `tabWarehouse` where lft >= {0} and rgt <= {1} and name=`tabBin`.warehouse)".format(lft, rgt)
item_projected_qty = frappe.db.sql(""" select ifnull(sum(projected_qty),0) as projected_qty,
ifnull(sum(actual_qty),0) as actual_qty from `tabBin`
where item_code = %(item_code)s {conditions}
- """.format(conditions=conditions), { "item_code": row.item_code }, as_list=1)
+ """.format(conditions=conditions), { "item_code": row['item_code'] }, as_list=1)
return item_projected_qty and item_projected_qty[0] or (0,0)
@frappe.whitelist()
-def get_items_for_material_requests(doc, company=None):
+def get_items_for_material_requests(doc, sales_order=None, company=None):
if isinstance(doc, string_types):
doc = frappe._dict(json.loads(doc))
doc['mr_items'] = []
po_items = doc.get('po_items') if doc.get('po_items') else doc.get('items')
+ company = doc.get('company')
+ so_item_details = frappe._dict()
for data in po_items:
- warehouse = None
- bom_wise_item_details = {}
-
- if data.get('required_qty'):
- planned_qty = data.get('required_qty')
- bom_no = data.get('bom')
- ignore_existing_ordered_qty = data.get('ignore_existing_ordered_qty')
- include_non_stock_items = 1
- warehouse = data.get('for_warehouse')
- if data.get('include_exploded_items'):
- include_subcontracted_items = 1
+ warehouse = data.get('for_warehouse')
+ ignore_existing_ordered_qty = data.get('ignore_existing_ordered_qty') or doc.get('ignore_existing_ordered_qty')
+ planned_qty = data.get('required_qty') or data.get('planned_qty')
+ item_details = {}
+ if data.get("bom") or data.get("bom_no"):
+ if data.get('required_qty'):
+ bom_no = data.get('bom')
+ include_non_stock_items = 1
+ include_subcontracted_items = 1 if data.get('include_exploded_items') else 0
else:
- include_subcontracted_items = 0
- else:
- planned_qty = data.get('planned_qty')
- bom_no = data.get('bom_no')
- include_subcontracted_items = doc.get('include_subcontracted_items')
- company = doc.get('company')
- include_non_stock_items = doc.get('include_non_stock_items')
- ignore_existing_ordered_qty = doc.get('ignore_existing_ordered_qty')
- if not planned_qty:
- frappe.throw(_("For row {0}: Enter Planned Qty").format(data.get('idx')))
+ bom_no = data.get('bom_no')
+ include_subcontracted_items = doc.get('include_subcontracted_items')
+ include_non_stock_items = doc.get('include_non_stock_items')
- if data.get('include_exploded_items') and bom_no and include_subcontracted_items:
- # fetch exploded items from BOM
- bom_wise_item_details = get_exploded_items(bom_wise_item_details, company, bom_no, include_non_stock_items)
- else:
- bom_wise_item_details = get_subitems(doc, data, bom_wise_item_details, bom_no, company, include_non_stock_items, include_subcontracted_items, 1)
- for item, item_details in bom_wise_item_details.items():
- if item_details.qty > 0:
- add_item_in_material_request_items(doc, planned_qty, ignore_existing_ordered_qty, item, item_details, data, warehouse, company)
+ if not planned_qty:
+ frappe.throw(_("For row {0}: Enter Planned Qty").format(data.get('idx')))
- return doc['mr_items']
+ if bom_no:
+ if data.get('include_exploded_items') and include_subcontracted_items:
+ # fetch exploded items from BOM
+ item_details = get_exploded_items(item_details,
+ company, bom_no, include_non_stock_items, planned_qty=planned_qty)
+ else:
+ item_details = get_subitems(doc, data, item_details, bom_no, company,
+ include_non_stock_items, include_subcontracted_items, 1, planned_qty=planned_qty)
+ else:
+ item_master = frappe.get_doc('Item', data['item_code']).as_dict()
+ purchase_uom = item_master.purchase_uom or item_master.stock_uom
+ conversion_factor = 0
+ for d in item_master.get("uoms"):
+ if d.uom == purchase_uom:
+ conversion_factor = d.conversion_factor
+
+ item_details[item_master.name] = frappe._dict(
+ {
+ 'item_name' : item_master.item_name,
+ 'default_bom' : doc.bom,
+ 'purchase_uom' : purchase_uom,
+ 'default_warehouse': item_master.default_warehouse,
+ 'min_order_qty' : item_master.min_order_qty,
+ 'default_material_request_type' : item_master.default_material_request_type,
+ 'qty': planned_qty or 1,
+ 'is_sub_contracted' : item_master.is_subcontracted_item,
+ 'item_code' : item_master.name,
+ 'description' : item_master.description,
+ 'stock_uom' : item_master.stock_uom,
+ 'conversion_factor' : conversion_factor,
+ }
+ )
+ if not sales_order:
+ sales_order = doc.get("sales_order")
+
+ for item_code, details in iteritems(item_details):
+ so_item_details.setdefault(sales_order, frappe._dict())
+ if item_code in so_item_details.get(sales_order, {}):
+ so_item_details[sales_order][item_code]['qty'] = so_item_details[sales_order][item_code].get("qty", 0) + flt(details.qty)
+ else:
+ so_item_details[sales_order][item_code] = details
+
+ mr_items = []
+ for sales_order, item_code in iteritems(so_item_details):
+ item_dict = so_item_details[sales_order]
+ for details in item_dict.values():
+ if details.qty > 0:
+ items = get_material_request_items(details, sales_order, company,
+ ignore_existing_ordered_qty, warehouse)
+ if items:
+ mr_items.append(items)
+
+ return mr_items
diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
deleted file mode 100644
index dbc6552..0000000
--- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
+++ /dev/null
@@ -1,552 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-from __future__ import unicode_literals
-import frappe
-from frappe.utils import cstr, flt, cint, nowdate, add_days, comma_and
-
-from frappe import msgprint, _
-
-from frappe.model.document import Document
-from erpnext.manufacturing.doctype.bom.bom import validate_bom_no
-from erpnext.manufacturing.doctype.work_order.work_order import get_item_details
-
-class ProductionPlanningTool(Document):
- def clear_table(self, table_name):
- self.set(table_name, [])
-
- def validate_company(self):
- if not self.company:
- frappe.throw(_("Please enter Company"))
-
- def get_open_sales_orders(self):
- """ Pull sales orders which are pending to deliver based on criteria selected"""
- so_filter = item_filter = ""
- if self.from_date:
- so_filter += " and so.transaction_date >= %(from_date)s"
- if self.to_date:
- so_filter += " and so.transaction_date <= %(to_date)s"
- if self.customer:
- so_filter += " and so.customer = %(customer)s"
- if self.project:
- so_filter += " and so.project = %(project)s"
-
- if self.fg_item:
- item_filter += " and so_item.item_code = %(item)s"
-
- open_so = frappe.db.sql("""
- select distinct so.name, so.transaction_date, so.customer, so.base_grand_total
- from `tabSales Order` so, `tabSales Order Item` so_item
- where so_item.parent = so.name
- and so.docstatus = 1 and so.status not in ("Stopped", "Closed")
- and so.company = %(company)s
- and so_item.qty > so_item.delivered_qty {0} {1}
- and (exists (select name from `tabBOM` bom where bom.item=so_item.item_code
- and bom.is_active = 1)
- or exists (select name from `tabPacked Item` pi
- where pi.parent = so.name and pi.parent_item = so_item.item_code
- and exists (select name from `tabBOM` bom where bom.item=pi.item_code
- and bom.is_active = 1)))
- """.format(so_filter, item_filter), {
- "from_date": self.from_date,
- "to_date": self.to_date,
- "customer": self.customer,
- "project": self.project,
- "item": self.fg_item,
- "company": self.company
- }, as_dict=1)
-
- self.add_so_in_table(open_so)
-
- def add_so_in_table(self, open_so):
- """ Add sales orders in the table"""
- self.clear_table("sales_orders")
-
- so_list = []
- for r in open_so:
- if cstr(r['name']) not in so_list:
- pp_so = self.append('sales_orders', {})
- pp_so.sales_order = r['name']
- pp_so.sales_order_date = cstr(r['transaction_date'])
- pp_so.customer = cstr(r['customer'])
- pp_so.grand_total = flt(r['base_grand_total'])
-
- def get_pending_material_requests(self):
- """ Pull Material Requests that are pending based on criteria selected"""
- mr_filter = item_filter = ""
- if self.from_date:
- mr_filter += " and mr.transaction_date >= %(from_date)s"
- if self.to_date:
- mr_filter += " and mr.transaction_date <= %(to_date)s"
- if self.warehouse:
- mr_filter += " and mr_item.warehouse = %(warehouse)s"
-
- if self.fg_item:
- item_filter += " and mr_item.item_code = %(item)s"
-
- pending_mr = frappe.db.sql("""
- select distinct mr.name, mr.transaction_date
- from `tabMaterial Request` mr, `tabMaterial Request Item` mr_item
- where mr_item.parent = mr.name
- and mr.material_request_type = "Manufacture"
- and mr.docstatus = 1
- and mr_item.qty > ifnull(mr_item.ordered_qty,0) {0} {1}
- and (exists (select name from `tabBOM` bom where bom.item=mr_item.item_code
- and bom.is_active = 1))
- """.format(mr_filter, item_filter), {
- "from_date": self.from_date,
- "to_date": self.to_date,
- "warehouse": self.warehouse,
- "item": self.fg_item
- }, as_dict=1)
-
- self.add_mr_in_table(pending_mr)
-
- def add_mr_in_table(self, pending_mr):
- """ Add Material Requests in the table"""
- self.clear_table("material_requests")
-
- mr_list = []
- for r in pending_mr:
- if cstr(r['name']) not in mr_list:
- mr = self.append('material_requests', {})
- mr.material_request = r['name']
- mr.material_request_date = cstr(r['transaction_date'])
-
- def get_items(self):
- if self.get_items_from == "Sales Order":
- self.get_so_items()
- elif self.get_items_from == "Material Request":
- self.get_mr_items()
-
- def get_so_items(self):
- so_list = [d.sales_order for d in self.get('sales_orders') if d.sales_order]
- if not so_list:
- msgprint(_("Please enter Sales Orders in the above table"))
- return []
-
- item_condition = ""
- if self.fg_item:
- item_condition = ' and so_item.item_code = {0}'.format(frappe.db.escape(self.fg_item))
-
- items = frappe.db.sql("""select distinct parent, item_code, warehouse,
- (qty - delivered_qty)*conversion_factor as pending_qty
- from `tabSales Order Item` so_item
- where parent in (%s) and docstatus = 1 and qty > delivered_qty
- and exists (select name from `tabBOM` bom where bom.item=so_item.item_code
- and bom.is_active = 1) %s""" % \
- (", ".join(["%s"] * len(so_list)), item_condition), tuple(so_list), as_dict=1)
-
- if self.fg_item:
- item_condition = ' and pi.item_code = {0}'.format(frappe.db.escape(self.fg_item))
-
- packed_items = frappe.db.sql("""select distinct pi.parent, pi.item_code, pi.warehouse as warehouse,
- (((so_item.qty - so_item.delivered_qty) * pi.qty) / so_item.qty)
- as pending_qty
- from `tabSales Order Item` so_item, `tabPacked Item` pi
- where so_item.parent = pi.parent and so_item.docstatus = 1
- and pi.parent_item = so_item.item_code
- and so_item.parent in (%s) and so_item.qty > so_item.delivered_qty
- and exists (select name from `tabBOM` bom where bom.item=pi.item_code
- and bom.is_active = 1) %s""" % \
- (", ".join(["%s"] * len(so_list)), item_condition), tuple(so_list), as_dict=1)
-
- self.add_items(items + packed_items)
-
- def get_mr_items(self):
- mr_list = [d.material_request for d in self.get('material_requests') if d.material_request]
- if not mr_list:
- msgprint(_("Please enter Material Requests in the above table"))
- return []
-
- item_condition = ""
- if self.fg_item:
- item_condition = ' and mr_item.item_code =' + frappe.db.escape(self.fg_item, percent=False)
-
- items = frappe.db.sql("""select distinct parent, name, item_code, warehouse,
- (qty - ordered_qty) as pending_qty
- from `tabMaterial Request Item` mr_item
- where parent in (%s) and docstatus = 1 and qty > ordered_qty
- and exists (select name from `tabBOM` bom where bom.item=mr_item.item_code
- and bom.is_active = 1) %s""" % \
- (", ".join(["%s"] * len(mr_list)), item_condition), tuple(mr_list), as_dict=1)
-
- self.add_items(items)
-
-
- def add_items(self, items):
- self.clear_table("items")
- for p in items:
- item_details = get_item_details(p['item_code'])
- pi = self.append('items', {})
- pi.warehouse = p['warehouse']
- pi.item_code = p['item_code']
- pi.description = item_details and item_details.description or ''
- pi.stock_uom = item_details and item_details.stock_uom or ''
- pi.bom_no = item_details and item_details.bom_no or ''
- pi.planned_qty = flt(p['pending_qty'])
- pi.pending_qty = flt(p['pending_qty'])
-
- if self.get_items_from == "Sales Order":
- pi.sales_order = p['parent']
- elif self.get_items_from == "Material Request":
- pi.material_request = p['parent']
- pi.material_request_item = p['name']
-
- def validate_data(self):
- self.validate_company()
- for d in self.get('items'):
- if not d.bom_no:
- frappe.throw(_("Please select BOM for Item in Row {0}".format(d.idx)))
- else:
- validate_bom_no(d.item_code, d.bom_no)
-
- if not flt(d.planned_qty):
- frappe.throw(_("Please enter Planned Qty for Item {0} at row {1}").format(d.item_code, d.idx))
-
- def raise_work_orders(self):
- """It will raise work order (Draft) for all distinct FG items"""
- self.validate_data()
-
- from erpnext.utilities.transaction_base import validate_uom_is_integer
- validate_uom_is_integer(self, "stock_uom", "planned_qty")
-
- items = self.get_production_items()
-
- wo_list = []
- frappe.flags.mute_messages = True
-
- for key in items:
- work_order = self.create_work_order(items[key])
- if work_order:
- wo_list.append(work_order)
-
- frappe.flags.mute_messages = False
-
- if wo_list:
- wo_list = ["""<a href="#Form/Work Order/%s" target="_blank">%s</a>""" % \
- (p, p) for p in wo_list]
- msgprint(_("{0} created").format(comma_and(wo_list)))
- else :
- msgprint(_("No Work Orders created"))
-
- def get_production_items(self):
- item_dict = {}
- for d in self.get("items"):
- item_details= {
- "production_item" : d.item_code,
- "sales_order" : d.sales_order,
- "material_request" : d.material_request,
- "material_request_item" : d.material_request_item,
- "bom_no" : d.bom_no,
- "description" : d.description,
- "stock_uom" : d.stock_uom,
- "company" : self.company,
- "wip_warehouse" : "",
- "fg_warehouse" : d.warehouse,
- "status" : "Draft",
- "project" : frappe.db.get_value("Sales Order", d.sales_order, "project")
- }
-
- """ Club similar BOM and item for processing in case of Sales Orders """
- if self.get_items_from == "Material Request":
- item_details.update({
- "qty": d.planned_qty
- })
- item_dict[(d.item_code, d.material_request_item, d.warehouse)] = item_details
-
- else:
- item_details.update({
- "qty":flt(item_dict.get((d.item_code, d.sales_order, d.warehouse),{})
- .get("qty")) + flt(d.planned_qty)
- })
- item_dict[(d.item_code, d.sales_order, d.warehouse)] = item_details
-
- return item_dict
-
- def create_work_order(self, item_dict):
- """Create work order. Called from Production Planning Tool"""
- from erpnext.manufacturing.doctype.work_order.work_order import OverProductionError, get_default_warehouse
- warehouse = get_default_warehouse()
- wo = frappe.new_doc("Work Order")
- wo.update(item_dict)
- wo.set_work_order_operations()
- if warehouse:
- wo.wip_warehouse = warehouse.get('wip_warehouse')
- if not wo.fg_warehouse:
- wo.fg_warehouse = warehouse.get('fg_warehouse')
-
- try:
- wo.insert()
- return wo.name
- except OverProductionError:
- pass
-
- def get_so_wise_planned_qty(self):
- """
- bom_dict {
- bom_no: ['sales_order', 'qty']
- }
- """
- bom_dict = {}
- for d in self.get("items"):
- if self.get_items_from == "Material Request":
- bom_dict.setdefault(d.bom_no, []).append([d.material_request_item, flt(d.planned_qty)])
- else:
- bom_dict.setdefault(d.bom_no, []).append([d.sales_order, flt(d.planned_qty)])
- return bom_dict
-
- def download_raw_materials(self):
- """ Create csv data for required raw material to produce finished goods"""
- self.validate_data()
- bom_dict = self.get_so_wise_planned_qty()
- self.get_raw_materials(bom_dict)
- return self.get_csv()
-
- def get_raw_materials(self, bom_dict,non_stock_item=0):
- """ Get raw materials considering sub-assembly items
- {
- "item_code": [qty_required, description, stock_uom, min_order_qty]
- }
- """
- item_list = []
- precision = frappe.get_precision("BOM Item", "stock_qty")
-
- for bom, so_wise_qty in bom_dict.items():
- bom_wise_item_details = {}
- if self.use_multi_level_bom and self.only_raw_materials and self.include_subcontracted:
- # get all raw materials with sub assembly childs
- # Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
- for d in frappe.db.sql("""select fb.item_code,
- ifnull(sum(fb.stock_qty/ifnull(bom.quantity, 1)), 0) as qty,
- fb.description, fb.stock_uom, item.min_order_qty
- from `tabBOM Explosion Item` fb, `tabBOM` bom, `tabItem` item
- where bom.name = fb.parent and item.name = fb.item_code
- and (item.is_sub_contracted_item = 0 or ifnull(item.default_bom, "")="")
- """ + ("and item.is_stock_item = 1","")[non_stock_item] + """
- and fb.docstatus<2 and bom.name=%(bom)s
- group by fb.item_code, fb.stock_uom""", {"bom":bom}, as_dict=1):
- bom_wise_item_details.setdefault(d.item_code, d)
- else:
- # Get all raw materials considering SA items as raw materials,
- # so no childs of SA items
- bom_wise_item_details = self.get_subitems(bom_wise_item_details, bom,1, \
- self.use_multi_level_bom,self.only_raw_materials, self.include_subcontracted,non_stock_item)
-
- for item, item_details in bom_wise_item_details.items():
- for so_qty in so_wise_qty:
- item_list.append([item, flt(flt(item_details.qty) * so_qty[1], precision),
- item_details.description, item_details.stock_uom, item_details.min_order_qty,
- so_qty[0]])
-
- self.make_items_dict(item_list)
-
- def get_subitems(self,bom_wise_item_details, bom, parent_qty, include_sublevel, only_raw, supply_subs,non_stock_item=0):
- items = frappe.db.sql("""
- SELECT
- bom_item.item_code,
- default_material_request_type,
- ifnull(%(parent_qty)s * sum(bom_item.stock_qty/ifnull(bom.quantity, 1)), 0) as qty,
- item.is_sub_contracted_item as is_sub_contracted,
- item.default_bom as default_bom,
- bom_item.description as description,
- bom_item.stock_uom as stock_uom,
- item.min_order_qty as min_order_qty
- FROM
- `tabBOM Item` bom_item,
- `tabBOM` bom,
- tabItem item
- where
- bom.name = bom_item.parent
- and bom.name = %(bom)s
- and bom_item.docstatus < 2
- and bom_item.item_code = item.name
- """ + ("and item.is_stock_item = 1", "")[non_stock_item] + """
- group by bom_item.item_code""", {"bom": bom, "parent_qty": parent_qty}, as_dict=1)
-
- for d in items:
- if ((d.default_material_request_type == "Purchase"
- and not (d.is_sub_contracted and only_raw and include_sublevel))
- or (d.default_material_request_type == "Manufacture" and not only_raw)):
-
- if d.item_code in bom_wise_item_details:
- bom_wise_item_details[d.item_code].qty = bom_wise_item_details[d.item_code].qty + d.qty
- else:
- bom_wise_item_details[d.item_code] = d
-
- if include_sublevel and d.default_bom:
- if ((d.default_material_request_type == "Purchase" and d.is_sub_contracted and supply_subs)
- or (d.default_material_request_type == "Manufacture")):
-
- my_qty = 0
- projected_qty = self.get_item_projected_qty(d.item_code)
- if self.create_material_requests_for_all_required_qty:
- my_qty = d.qty
- else:
- total_required_qty = flt(bom_wise_item_details.get(d.item_code, frappe._dict()).qty)
- if (total_required_qty - d.qty) < projected_qty:
- my_qty = total_required_qty - projected_qty
- else:
- my_qty = d.qty
-
- if my_qty > 0:
- self.get_subitems(bom_wise_item_details,
- d.default_bom, my_qty, include_sublevel, only_raw, supply_subs)
-
- return bom_wise_item_details
-
- def make_items_dict(self, item_list):
- if not getattr(self, "item_dict", None):
- self.item_dict = {}
-
- for i in item_list:
- self.item_dict.setdefault(i[0], []).append([flt(i[1]), i[2], i[3], i[4], i[5]])
-
- def get_csv(self):
- item_list = [['Item Code', 'Description', 'Stock UOM', 'Required Qty', 'Warehouse',
- 'Quantity Requested for Purchase', 'Ordered Qty', 'Actual Qty']]
- for item in self.item_dict:
- total_qty = sum([flt(d[0]) for d in self.item_dict[item]])
- item_list.append([item, self.item_dict[item][0][1], self.item_dict[item][0][2], total_qty])
- item_qty = frappe.db.sql("""select warehouse, indented_qty, ordered_qty, actual_qty
- from `tabBin` where item_code = %s""", item, as_dict=1)
-
- i_qty, o_qty, a_qty = 0, 0, 0
- for w in item_qty:
- i_qty, o_qty, a_qty = i_qty + flt(w.indented_qty), o_qty + \
- flt(w.ordered_qty), a_qty + flt(w.actual_qty)
-
- item_list.append(['', '', '', '', w.warehouse, flt(w.indented_qty),
- flt(w.ordered_qty), flt(w.actual_qty)])
- if item_qty:
- item_list.append(['', '', '', '', 'Total', i_qty, o_qty, a_qty])
- else:
- item_list.append(['', '', '', '', 'Total', 0, 0, 0])
-
- return item_list
-
- def raise_material_requests(self):
- """
- Raise Material Request if projected qty is less than qty required
- Requested qty should be shortage qty considering minimum order qty
- """
- self.validate_data()
- if not self.purchase_request_for_warehouse:
- frappe.throw(_("Please enter Warehouse for which Material Request will be raised"))
-
- bom_dict = self.get_so_wise_planned_qty()
- self.get_raw_materials(bom_dict,self.create_material_requests_non_stock_request)
-
- if self.item_dict:
- self.create_material_request()
-
- def get_requested_items(self):
- items_to_be_requested = frappe._dict()
-
- if not self.create_material_requests_for_all_required_qty:
- item_projected_qty = self.get_projected_qty()
-
- for item, so_item_qty in self.item_dict.items():
- total_qty = sum([flt(d[0]) for d in so_item_qty])
- requested_qty = 0
-
- if self.create_material_requests_for_all_required_qty:
- requested_qty = total_qty
- elif total_qty > item_projected_qty.get(item, 0):
- # shortage
- requested_qty = total_qty - flt(item_projected_qty.get(item))
- # consider minimum order qty
-
- if requested_qty and requested_qty < flt(so_item_qty[0][3]):
- requested_qty = flt(so_item_qty[0][3])
-
- # distribute requested qty SO wise
- for item_details in so_item_qty:
- if requested_qty:
- sales_order = item_details[4] or "No Sales Order"
- if self.get_items_from == "Material Request":
- sales_order = "No Sales Order"
- if requested_qty <= item_details[0]:
- adjusted_qty = requested_qty
- else:
- adjusted_qty = item_details[0]
-
- items_to_be_requested.setdefault(item, {}).setdefault(sales_order, 0)
- items_to_be_requested[item][sales_order] += adjusted_qty
- requested_qty -= adjusted_qty
- else:
- break
-
- # requested qty >= total so qty, due to minimum order qty
- if requested_qty:
- items_to_be_requested.setdefault(item, {}).setdefault("No Sales Order", 0)
- items_to_be_requested[item]["No Sales Order"] += requested_qty
-
- return items_to_be_requested
-
- def get_item_projected_qty(self,item):
- conditions = ""
- if self.purchase_request_for_warehouse:
- conditions = " and warehouse={0}".format(frappe.db.escape(self.purchase_request_for_warehouse))
-
- item_projected_qty = frappe.db.sql("""
- select ifnull(sum(projected_qty),0) as qty
- from `tabBin`
- where item_code = %(item_code)s {conditions}
- """.format(conditions=conditions), { "item_code": item }, as_dict=1)
-
- return item_projected_qty[0].qty
-
- def get_projected_qty(self):
- items = self.item_dict.keys()
- item_projected_qty = frappe.db.sql("""select item_code, sum(projected_qty)
- from `tabBin` where item_code in (%s) and warehouse=%s group by item_code""" %
- (", ".join(["%s"]*len(items)), '%s'), tuple(items + [self.purchase_request_for_warehouse]))
-
- return dict(item_projected_qty)
-
- def create_material_request(self):
- items_to_be_requested = self.get_requested_items()
-
- material_request_list = []
- if items_to_be_requested:
- for item in items_to_be_requested:
- item_wrapper = frappe.get_doc("Item", item)
- material_request = frappe.new_doc("Material Request")
- material_request.update({
- "transaction_date": nowdate(),
- "status": "Draft",
- "company": self.company,
- "requested_by": frappe.session.user,
- "schedule_date": add_days(nowdate(), cint(item_wrapper.lead_time_days)),
- })
- material_request.update({"material_request_type": item_wrapper.default_material_request_type})
-
- for sales_order, requested_qty in items_to_be_requested[item].items():
- material_request.append("items", {
- "doctype": "Material Request Item",
- "__islocal": 1,
- "item_code": item,
- "item_name": item_wrapper.item_name,
- "description": item_wrapper.description,
- "uom": item_wrapper.stock_uom,
- "item_group": item_wrapper.item_group,
- "brand": item_wrapper.brand,
- "qty": requested_qty,
- "schedule_date": add_days(nowdate(), cint(item_wrapper.lead_time_days)),
- "warehouse": self.purchase_request_for_warehouse,
- "sales_order": sales_order if sales_order!="No Sales Order" else None,
- "project": frappe.db.get_value("Sales Order", sales_order, "project") \
- if sales_order!="No Sales Order" else None
- })
-
- material_request.flags.ignore_permissions = 1
- material_request.submit()
- material_request_list.append(material_request.name)
-
- if material_request_list:
- message = ["""<a href="#Form/Material Request/%s" target="_blank">%s</a>""" % \
- (p, p) for p in material_request_list]
- msgprint(_("Material Requests {0} created").format(comma_and(message)))
- else:
- msgprint(_("Nothing to request"))
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 4b65df8..76afe2f 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -1,9 +1,9 @@
execute:import unidecode # new requirement
erpnext.patches.v8_0.move_perpetual_inventory_setting
+erpnext.patches.v11_0.rename_production_order_to_work_order
erpnext.patches.v11_0.refactor_naming_series
erpnext.patches.v11_0.refactor_autoname_naming
erpnext.patches.v10_0.rename_schools_to_education
-erpnext.patches.v11_0.rename_production_order_to_work_order
erpnext.patches.v4_0.validate_v3_patch
erpnext.patches.v4_0.fix_employee_user_id
erpnext.patches.v4_0.remove_employee_role_if_no_employee
@@ -580,8 +580,9 @@
erpnext.patches.v10_0.repost_gle_for_purchase_receipts_with_rejected_items
erpnext.patches.v11_0.set_missing_gst_hsn_code
erpnext.patches.v11_0.rename_bom_wo_fields
-erpnext.patches.v11_0.rename_additional_salary_component_additional_salary
+erpnext.patches.v12_0.change_qms_icon
erpnext.patches.v12_0.rename_learn_to_help
erpnext.patches.v12_0.rename_accounts_desktop_icon_to_accounting
erpnext.patches.v12_0.replace_project_list_desktop_icon_with_projects_module_desktop_icon
erpnext.patches.v12_0.move_item_tax_to_item_tax_template
+erpnext.patches.v11_0.rename_additional_salary_component_additional_salary
diff --git a/erpnext/patches/v11_0/rename_supplier_type_to_supplier_group.py b/erpnext/patches/v11_0/rename_supplier_type_to_supplier_group.py
index 8313096..52d4621 100644
--- a/erpnext/patches/v11_0/rename_supplier_type_to_supplier_group.py
+++ b/erpnext/patches/v11_0/rename_supplier_type_to_supplier_group.py
@@ -1,3 +1,4 @@
+from __future__ import unicode_literals
import frappe
from frappe.model.rename_doc import rename_doc
from frappe.model.utils.rename_field import rename_field
diff --git a/erpnext/patches/v12_0/change_qms_icon.py b/erpnext/patches/v12_0/change_qms_icon.py
new file mode 100644
index 0000000..2b6c09a
--- /dev/null
+++ b/erpnext/patches/v12_0/change_qms_icon.py
@@ -0,0 +1,10 @@
+import frappe
+
+def execute():
+ qms_icons = frappe.get_all("Desktop Icon", filters={
+ "module_name": "Quality Management"
+ })
+
+ for icon in qms_icons:
+ frappe.db.set_value('Desktop Icon', icon.name, 'color', '#1abc9c')
+ frappe.db.set_value('Desktop Icon', icon.name, 'icon', 'fa fa-check-square-o')
diff --git a/erpnext/patches/v12_0/rename_quality_management_to_quality.py b/erpnext/patches/v12_0/rename_quality_management_to_quality.py
new file mode 100644
index 0000000..cdcf191
--- /dev/null
+++ b/erpnext/patches/v12_0/rename_quality_management_to_quality.py
@@ -0,0 +1,10 @@
+import frappe
+from frappe import _
+
+def execute():
+ quality_management_module_icons = frappe.get_all('Desktop Icon', filters={
+ 'module_name': 'Quality Management'
+ }, fields=['name'])
+
+ for icon in quality_management_module_icons:
+ frappe.db.set_value('Desktop Icon', icon.name, 'label', _('Quality'))
\ No newline at end of file
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index 75a1668..1fcb3c6 100755
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -12,6 +12,7 @@
class CircularReferenceError(frappe.ValidationError): pass
+class EndDateCannotBeGreaterThanProjectEndDateError(frappe.ValidationError): pass
class Task(NestedSet):
nsm_parent_field = 'parent_task'
@@ -43,6 +44,12 @@
if self.act_start_date and self.act_end_date and getdate(self.act_start_date) > getdate(self.act_end_date):
frappe.throw(_("'Actual Start Date' can not be greater than 'Actual End Date'"))
+ if(self.project):
+ if frappe.db.exists("Project", self.project):
+ expected_end_date = frappe.db.get_value("Project", self.project, "expected_end_date")
+ if self.exp_end_date and expected_end_date and getdate(self.exp_end_date) > getdate(expected_end_date) :
+ frappe.throw(_("Expected end date cannot be after Project: <b>'{0}'</b> Expected end date").format(self.project), EndDateCannotBeGreaterThanProjectEndDateError)
+
def validate_status(self):
if self.status!=self.get_db_value("status") and self.status == "Closed":
for d in self.depends_on:
diff --git a/erpnext/projects/doctype/task/test_task.py b/erpnext/projects/doctype/task/test_task.py
index 0966b76..6fb5412 100644
--- a/erpnext/projects/doctype/task/test_task.py
+++ b/erpnext/projects/doctype/task/test_task.py
@@ -5,11 +5,11 @@
import unittest
from frappe.utils import getdate, nowdate, add_days
-from erpnext.projects.doctype.task.task import CircularReferenceError
+from erpnext.projects.doctype.task.task import CircularReferenceError, EndDateCannotBeGreaterThanProjectEndDateError
class TestTask(unittest.TestCase):
def test_circular_reference(self):
- task1 = create_task("_Test Task 1", nowdate(), add_days(nowdate(), 10))
+ task1 = create_task("_Test Task 1", add_days(nowdate(), -15), add_days(nowdate(), -10))
task2 = create_task("_Test Task 2", add_days(nowdate(), 11), add_days(nowdate(), 15), task1.name)
task3 = create_task("_Test Task 3", add_days(nowdate(), 11), add_days(nowdate(), 15), task2.name)
@@ -97,7 +97,16 @@
self.assertEqual(frappe.db.get_value("Task", task.name, "status"), "Overdue")
-def create_task(subject, start=None, end=None, depends_on=None, project=None):
+ def test_end_date_validation(self):
+ task_end = create_task("Testing_Enddate_validation", add_days(nowdate(), 35), add_days(nowdate(), 45), save=False)
+ pro = frappe.get_doc("Project", task_end.project)
+ pro.expected_end_date = add_days(nowdate(), 40)
+ pro.save()
+ self.assertRaises(EndDateCannotBeGreaterThanProjectEndDateError, task_end.save)
+
+
+
+def create_task(subject, start=None, end=None, depends_on=None, project=None, save=True):
if not frappe.db.exists("Task", subject):
task = frappe.new_doc('Task')
task.status = "Open"
@@ -105,7 +114,8 @@
task.exp_start_date = start or nowdate()
task.exp_end_date = end or nowdate()
task.project = project or "_Test Project"
- task.save()
+ if save:
+ task.save()
else:
task = frappe.get_doc("Task", subject)
@@ -113,6 +123,7 @@
task.append("depends_on", {
"task": depends_on
})
- task.save()
+ if save:
+ task.save()
return task
\ No newline at end of file
diff --git a/erpnext/projects/doctype/timesheet/timesheet.js b/erpnext/projects/doctype/timesheet/timesheet.js
index 0eabb39..8692440 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.js
+++ b/erpnext/projects/doctype/timesheet/timesheet.js
@@ -42,12 +42,12 @@
if(frm.doc.docstatus==1) {
if(frm.doc.per_billed < 100 && frm.doc.total_billable_hours && frm.doc.total_billable_hours > frm.doc.total_billed_hours){
frm.add_custom_button(__('Create Sales Invoice'), function() { frm.trigger("make_invoice") },
- "fa fa-file-alt");
+ "fa fa-file-text");
}
if(!frm.doc.salary_slip && frm.doc.employee){
frm.add_custom_button(__('Create Salary Slip'), function() { frm.trigger("make_salary_slip") },
- "fa fa-file-alt");
+ "fa fa-file-text");
}
}
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index f409f61..200908b 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -416,6 +416,7 @@
item_code: item.item_code,
barcode: item.barcode,
serial_no: item.serial_no,
+ set_warehouse: me.frm.doc.set_warehouse,
warehouse: item.warehouse,
customer: me.frm.doc.customer,
supplier: me.frm.doc.supplier,
@@ -440,6 +441,7 @@
weight_per_unit: item.weight_per_unit,
weight_uom: item.weight_uom,
uom : item.uom,
+ stock_uom: item.stock_uom,
pos_profile: me.frm.doc.doctype == 'Sales Invoice' ? me.frm.doc.pos_profile : '',
cost_center: item.cost_center,
tax_category: me.frm.doc.tax_category,
diff --git a/erpnext/quality_management/doctype/customer_feedback/test_customer_feedback.py b/erpnext/quality_management/doctype/customer_feedback/test_customer_feedback.py
index 2ac6525..b5d6141 100644
--- a/erpnext/quality_management/doctype/customer_feedback/test_customer_feedback.py
+++ b/erpnext/quality_management/doctype/customer_feedback/test_customer_feedback.py
@@ -28,19 +28,4 @@
def get_feedback():
feedback = frappe.get_list("Customer Feedback", limit=1)
- return feedback[0]
-
-#def create_feedback_template():
-# template = frappe.get_doc({
-# "doctype": "Customer Feedback Template",
-# "template": "_Test Customer Feedback Template",
-# "scope": "Company",
-# "feedback_parameter": [
-# {
-# "parameter": "_Test Customer Feedback Template Parameter",
-# }
-# ]
-# })
-# template_exist = frappe.get_list("Customer Feedback Template", filters={"template": ""+ template.template +""}, fields=["name"])
-# if len(template_exist) == 0:
-# template.insert()
\ No newline at end of file
+ return feedback[0]
\ No newline at end of file
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index ea600e4..a1fba07 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -11,22 +11,49 @@
if not hasattr(doc, 'gstin'):
return
- if doc.gstin:
- doc.gstin = doc.gstin.upper()
- if doc.gstin not in ["NA", "na"]:
- p = re.compile("[0-9]{2}[a-zA-Z]{5}[0-9]{4}[a-zA-Z]{1}[1-9A-Za-z]{1}[Z]{1}[0-9a-zA-Z]{1}")
- if not p.match(doc.gstin):
- frappe.throw(_("Invalid GSTIN or Enter NA for Unregistered"))
+ doc.gstin = doc.gstin.upper().strip() if doc.gstin else ""
+ if not doc.gstin or doc.gstin == 'NA':
+ return
+
+ if len(doc.gstin) != 15:
+ frappe.throw(_("Invalid GSTIN! A GSTIN must have 15 characters."))
+
+ p = re.compile("^[0-9]{2}[A-Z]{4}[0-9A-Z]{1}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}[1-9A-Z]{1}[0-9A-Z]{1}$")
+ if not p.match(doc.gstin):
+ frappe.throw(_("Invalid GSTIN! The input you've entered doesn't match the format of GSTIN."))
+
+ validate_gstin_check_digit(doc.gstin)
if not doc.gst_state:
- if doc.state in states:
- doc.gst_state = doc.state
+ if not doc.state:
+ return
+ state = doc.state.lower()
+ states_lowercase = {s.lower():s for s in states}
+ if state in states_lowercase:
+ doc.gst_state = states_lowercase[state]
+ else:
+ return
- if doc.gst_state:
- doc.gst_state_number = state_numbers[doc.gst_state]
- if doc.gstin and doc.gstin != "NA" and doc.gst_state_number != doc.gstin[:2]:
- frappe.throw(_("First 2 digits of GSTIN should match with State number {0}")
- .format(doc.gst_state_number))
+ doc.gst_state_number = state_numbers[doc.gst_state]
+ if doc.gst_state_number != doc.gstin[:2]:
+ frappe.throw(_("Invalid GSTIN! First 2 digits of GSTIN should match with State number {0}.")
+ .format(doc.gst_state_number))
+
+def validate_gstin_check_digit(gstin):
+ ''' Function to validate the check digit of the GSTIN.'''
+ factor = 1
+ total = 0
+ code_point_chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ mod = len(code_point_chars)
+ input_chars = gstin[:-1]
+ for char in input_chars:
+ digit = factor * code_point_chars.find(char)
+ digit = (digit // mod) + (digit % mod)
+ total += digit
+ factor = 2 if factor == 1 else 1
+ if gstin[-1] != code_point_chars[((mod - (total % mod)) % mod)]:
+ frappe.throw(_("Invalid GSTIN! The check digit validation has failed. " +
+ "Please ensure you've typed the GSTIN correctly."))
def get_itemised_tax_breakup_header(item_doctype, tax_accounts):
if frappe.get_meta(item_doctype).has_field('gst_hsn_code'):
diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py
index c6f203b..906e90d 100644
--- a/erpnext/regional/report/gstr_1/gstr_1.py
+++ b/erpnext/regional/report/gstr_1/gstr_1.py
@@ -120,7 +120,7 @@
and customer in ({0})""".format(", ".join([frappe.db.escape(c.name) for c in customers]))
if self.filters.get("type_of_business") in ("B2C Large", "B2C Small"):
- b2c_limit = frappe.db.get_single_value('GSt Settings', 'b2c_limit')
+ b2c_limit = frappe.db.get_single_value('GST Settings', 'b2c_limit')
if not b2c_limit:
frappe.throw(_("Please set B2C Limit in GST Settings."))
@@ -201,7 +201,7 @@
if unidentified_gst_accounts:
frappe.msgprint(_("Following accounts might be selected in GST Settings:")
+ "<br>" + "<br>".join(unidentified_gst_accounts), alert=True)
-
+
# Build itemised tax for export invoices where tax table is blank
for invoice, items in iteritems(self.invoice_items):
if invoice not in self.items_based_on_tax_rate \
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index 4edd3d8..a8fae7b 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -177,6 +177,11 @@
frappe.throw(_("""New credit limit is less than current outstanding amount for the customer. Credit limit has to be atleast {0}""").format(outstanding_amt))
def on_trash(self):
+ if self.customer_primary_contact:
+ frappe.db.sql("""update `tabCustomer`
+ set customer_primary_contact=null, mobile_no=null, email_id=null
+ where name=%s""", self.name)
+
delete_contact_and_address('Customer', self.name)
if self.lead_name:
frappe.db.sql("update `tabLead` set status='Interested' where name=%s", self.lead_name)
diff --git a/erpnext/selling/doctype/customer/test_customer.py b/erpnext/selling/doctype/customer/test_customer.py
index bf2bdf1..47e80d4 100644
--- a/erpnext/selling/doctype/customer/test_customer.py
+++ b/erpnext/selling/doctype/customer/test_customer.py
@@ -156,6 +156,15 @@
so.save()
+ def test_delete_customer_contact(self):
+ customer = frappe.get_doc(
+ get_customer_dict('_Test Customer for delete')).insert(ignore_permissions=True)
+
+ customer.mobile_no = "8989889890"
+ customer.save()
+ self.assertTrue(customer.customer_primary_contact)
+ frappe.delete_doc('Customer', customer.name)
+
def test_disabled_customer(self):
make_test_records("Item")
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 058cfb6..9f84d9a 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -368,7 +368,7 @@
}
]
var d = new frappe.ui.Dialog({
- title: __("Select from Items having BOM"),
+ title: __("Items for Raw Material Request"),
fields: fields,
primary_action: function() {
var data = d.get_values();
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 1428ba4..bed8db6 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -346,11 +346,11 @@
delivered_qty += item.delivered_qty
tot_qty += item.qty
-
+
if tot_qty != 0:
self.db_set("per_delivered", flt(delivered_qty/tot_qty) * 100,
update_modified=False)
-
+
def set_indicator(self):
"""Set indicator for portal"""
@@ -369,20 +369,19 @@
def get_work_order_items(self, for_raw_material_request=0):
'''Returns items with BOM that already do not have a linked work order'''
items = []
-
for table in [self.items, self.packed_items]:
for i in table:
bom = get_default_bom_item(i.item_code)
- if bom:
- stock_qty = i.qty if i.doctype == 'Packed Item' else i.stock_qty
- if not for_raw_material_request:
- total_work_order_qty = flt(frappe.db.sql('''select sum(qty) from `tabWork Order`
- where production_item=%s and sales_order=%s and sales_order_item = %s and docstatus<2''', (i.item_code, self.name, i.name))[0][0])
- pending_qty = stock_qty - total_work_order_qty
- else:
- pending_qty = stock_qty
+ stock_qty = i.qty if i.doctype == 'Packed Item' else i.stock_qty
+ if not for_raw_material_request:
+ total_work_order_qty = flt(frappe.db.sql('''select sum(qty) from `tabWork Order`
+ where production_item=%s and sales_order=%s and sales_order_item = %s and docstatus<2''', (i.item_code, self.name, i.name))[0][0])
+ pending_qty = stock_qty - total_work_order_qty
+ else:
+ pending_qty = stock_qty
- if pending_qty:
+ if pending_qty:
+ if bom:
items.append(dict(
name= i.name,
item_code= i.item_code,
@@ -392,6 +391,16 @@
required_qty = pending_qty if for_raw_material_request else 0,
sales_order_item = i.name
))
+ else:
+ items.append(dict(
+ name= i.name,
+ item_code= i.item_code,
+ bom = '',
+ warehouse = i.warehouse,
+ pending_qty = pending_qty,
+ required_qty = pending_qty if for_raw_material_request else 0,
+ sales_order_item = i.name
+ ))
return items
def on_recurring(self, reference_doc, auto_repeat_doc):
@@ -920,10 +929,12 @@
for item in items.get('items'):
item["include_exploded_items"] = items.get('include_exploded_items')
item["ignore_existing_ordered_qty"] = items.get('ignore_existing_ordered_qty')
+ item["include_raw_materials_from_sales_order"] = items.get('include_raw_materials_from_sales_order')
- raw_materials = get_items_for_material_requests(items, company)
+ raw_materials = get_items_for_material_requests(items, sales_order, company)
if not raw_materials:
frappe.msgprint(_("Material Request not created, as quantity for Raw Materials already available."))
+ return
material_request = frappe.new_doc('Material Request')
material_request.update(dict(
diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.py b/erpnext/selling/report/sales_analytics/sales_analytics.py
index c078a08..3239fc6 100644
--- a/erpnext/selling/report/sales_analytics/sales_analytics.py
+++ b/erpnext/selling/report/sales_analytics/sales_analytics.py
@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe
from frappe import _, scrub
-from frappe.utils import getdate, flt
+from frappe.utils import getdate, flt, add_to_date, add_days
from six import iteritems
from erpnext.accounts.utils import get_fiscal_year
@@ -40,7 +40,7 @@
"fieldtype": "Data",
"width": 140
})
- for dummy, end_date in self.periodic_daterange:
+ for end_date in self.periodic_daterange:
period = self.get_period(end_date)
self.columns.append({
"label": _(period),
@@ -169,7 +169,7 @@
"entity_name": self.entity_names.get(entity)
}
total = 0
- for dummy, end_date in self.periodic_daterange:
+ for end_date in self.periodic_daterange:
period = self.get_period(end_date)
amount = flt(period_data.get(period, 0.0))
row[scrub(period)] = amount
@@ -188,7 +188,7 @@
"indent": self.depth_map.get(d.name)
}
total = 0
- for dummy, end_date in self.periodic_daterange:
+ for end_date in self.periodic_daterange:
period = self.get_period(end_date)
amount = flt(self.entity_periodic_data.get(d.name, {}).get(period, 0.0))
row[scrub(period)] = amount
@@ -219,12 +219,11 @@
period = "Quarter " + str(((posting_date.month-1)//3)+1) +" " + str(posting_date.year)
else:
year = get_fiscal_year(posting_date, company=self.filters.company)
- period = str(year[2])
-
+ period = str(year[0])
return period
def get_period_date_ranges(self):
- from dateutil.relativedelta import relativedelta
+ from dateutil.relativedelta import relativedelta, MO
from_date, to_date = getdate(self.filters.from_date), getdate(self.filters.to_date)
increment = {
@@ -234,18 +233,26 @@
"Yearly": 12
}.get(self.filters.range, 1)
+ if self.filters.range in ['Monthly', 'Quarterly']:
+ from_date = from_date.replace(day = 1)
+ elif self.filters.range == "Yearly":
+ from_date = get_fiscal_year(from_date)[1]
+ else:
+ from_date = from_date + relativedelta(from_date, weekday=MO(-1))
+
self.periodic_daterange = []
- for dummy in range(1, 53, increment):
+ for dummy in range(1, 53):
if self.filters.range == "Weekly":
- period_end_date = from_date + relativedelta(days=6)
+ period_end_date = add_days(from_date, 6)
else:
- period_end_date = from_date + relativedelta(months=increment, days=-1)
+ period_end_date = add_to_date(from_date, months=increment, days=-1)
if period_end_date > to_date:
period_end_date = to_date
- self.periodic_daterange.append([from_date, period_end_date])
- from_date = period_end_date + relativedelta(days=1)
+ self.periodic_daterange.append(period_end_date)
+
+ from_date = add_days(period_end_date, 1)
if period_end_date == to_date:
break
diff --git a/erpnext/setup/default_success_action.py b/erpnext/setup/default_success_action.py
index e8494a1..6c2a97a 100644
--- a/erpnext/setup/default_success_action.py
+++ b/erpnext/setup/default_success_action.py
@@ -1,3 +1,4 @@
+from __future__ import unicode_literals
from frappe import _
doctype_list = [
diff --git a/erpnext/setup/doctype/company/company_dashboard.py b/erpnext/setup/doctype/company/company_dashboard.py
index 6133226..5efcf38 100644
--- a/erpnext/setup/doctype/company/company_dashboard.py
+++ b/erpnext/setup/doctype/company/company_dashboard.py
@@ -13,7 +13,7 @@
'goal_doctype_link': 'company',
'goal_field': 'base_grand_total',
'date_field': 'posting_date',
- 'filter_str': 'docstatus = 1',
+ 'filter_str': "docstatus = 1 and is_opening != 'Yes'",
'aggregation': 'sum'
},
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index 48963c2..bf5996e 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -136,7 +136,10 @@
rgt = ('<', item_group.rgt),
),
or_filters = search_filters,
- order_by = 'weightage desc, name asc')
+ order_by = 'weightage desc, name asc',
+ start = start,
+ limit = limit
+ )
return [get_item_for_list_in_html(r) for r in data]
diff --git a/erpnext/startup/report_data_map.py b/erpnext/startup/report_data_map.py
index fec2dea..1eaf738 100644
--- a/erpnext/startup/report_data_map.py
+++ b/erpnext/startup/report_data_map.py
@@ -79,7 +79,7 @@
"actual_qty as qty", "voucher_type", "voucher_no", "project",
"incoming_rate as incoming_rate", "stock_uom", "serial_no",
"qty_after_transaction", "valuation_rate"],
- "order_by": "posting_date, posting_time, name",
+ "order_by": "posting_date, posting_time, creation",
"links": {
"item_code": ["Item", "name"],
"warehouse": ["Warehouse", "name"],
diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py
index f86a77d..aa5c69e 100644
--- a/erpnext/stock/doctype/bin/bin.py
+++ b/erpnext/stock/doctype/bin/bin.py
@@ -60,7 +60,7 @@
select * from `tabStock Ledger Entry`
where item_code = %s
and warehouse = %s
- order by timestamp(posting_date, posting_time) asc, name asc
+ order by timestamp(posting_date, posting_time) asc, creation asc
limit 1
""", (self.item_code, self.warehouse), as_dict=1)
return sle and sle[0] or None
diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py
index 2ab5bb3..de702ff 100644
--- a/erpnext/stock/doctype/item/test_item.py
+++ b/erpnext/stock/doctype/item/test_item.py
@@ -440,7 +440,7 @@
test_records = frappe.get_test_records('Item')
-def create_item(item_code, is_stock_item=None, valuation_rate=0, warehouse=None, is_customer_provided_item=None, customer=None, is_purchase_item=None):
+def create_item(item_code, is_stock_item=None, valuation_rate=0, warehouse=None, is_customer_provided_item=None, customer=None, is_purchase_item=None, opening_stock=None):
if not frappe.db.exists("Item", item_code):
item = frappe.new_doc("Item")
item.item_code = item_code
@@ -448,6 +448,7 @@
item.description = item_code
item.item_group = "All Item Groups"
item.is_stock_item = is_stock_item or 1
+ item.opening_stock = opening_stock or 0
item.valuation_rate = valuation_rate or 0.0
item.is_purchase_item = is_purchase_item
item.is_customer_provided_item = is_customer_provided_item
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index 5aaf872..4e4cb2e 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -136,7 +136,7 @@
sle_dict = {}
for sle in frappe.db.sql("""select * from `tabStock Ledger Entry`
where serial_no like %s and item_code=%s and ifnull(is_cancelled, 'No')='No'
- order by posting_date desc, posting_time desc, name desc""",
+ order by posting_date desc, posting_time desc, creation desc""",
("%%%s%%" % self.name, self.item_code), as_dict=1):
if self.name.upper() in get_serial_nos(sle.serial_no):
if cint(sle.actual_qty) > 0:
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index d9df18d..9095075 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -27,7 +27,7 @@
values.append(value)
return frappe.db.sql("""select * from `tabStock Ledger Entry` %s
- order by timestamp(posting_date, posting_time) desc, name desc limit 1"""% condition,
+ order by timestamp(posting_date, posting_time) desc, creation desc limit 1"""% condition,
values, as_dict=1)
class TestStockEntry(unittest.TestCase):
diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json
index 2bd8ba3..947f948 100644
--- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json
+++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json
@@ -1,840 +1,874 @@
{
- "allow_copy": 1,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "MAT-SLE-.YYYY.-.#####",
- "beta": 0,
- "creation": "2013-01-29 19:25:42",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Other",
- "editable_grid": 0,
- "engine": "InnoDB",
+ "allow_copy": 1,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "MAT-SLE-.YYYY.-.#####",
+ "beta": 0,
+ "creation": "2013-01-29 19:25:42",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Other",
+ "editable_grid": 0,
+ "engine": "InnoDB",
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item_code",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Item Code",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "item_code",
- "oldfieldtype": "Link",
- "options": "Item",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "100px",
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "item_code",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Item Code",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "item_code",
+ "oldfieldtype": "Link",
+ "options": "Item",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "100px",
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "100px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "serial_no",
- "fieldtype": "Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Serial No",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "100px",
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "serial_no",
+ "fieldtype": "Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Serial No",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "100px",
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "100px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "batch_no",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Batch No",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "batch_no",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "batch_no",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Batch No",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "batch_no",
+ "oldfieldtype": "Data",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "warehouse",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Warehouse",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "warehouse",
- "oldfieldtype": "Link",
- "options": "Warehouse",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "100px",
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "warehouse",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Warehouse",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "warehouse",
+ "oldfieldtype": "Link",
+ "options": "Warehouse",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "100px",
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "100px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "posting_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Posting Date",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "posting_date",
- "oldfieldtype": "Date",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "100px",
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "posting_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Posting Date",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "posting_date",
+ "oldfieldtype": "Date",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "100px",
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "100px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "posting_time",
- "fieldtype": "Time",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Posting Time",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "posting_time",
- "oldfieldtype": "Time",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "100px",
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "posting_time",
+ "fieldtype": "Time",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Posting Time",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "posting_time",
+ "oldfieldtype": "Time",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "100px",
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "100px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "voucher_type",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Voucher Type",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "voucher_type",
- "oldfieldtype": "Data",
- "options": "DocType",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "150px",
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "voucher_type",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Voucher Type",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "voucher_type",
+ "oldfieldtype": "Data",
+ "options": "DocType",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "150px",
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "150px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "voucher_no",
- "fieldtype": "Dynamic Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 1,
- "label": "Voucher No",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "voucher_no",
- "oldfieldtype": "Data",
- "options": "voucher_type",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "150px",
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "voucher_no",
+ "fieldtype": "Dynamic Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 1,
+ "label": "Voucher No",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "voucher_no",
+ "oldfieldtype": "Data",
+ "options": "voucher_type",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "150px",
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "150px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "voucher_detail_no",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Voucher Detail No",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "voucher_detail_no",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "150px",
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "voucher_detail_no",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Voucher Detail No",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "voucher_detail_no",
+ "oldfieldtype": "Data",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "150px",
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "150px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "actual_qty",
- "fieldtype": "Float",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Actual Quantity",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "actual_qty",
- "oldfieldtype": "Currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "150px",
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "actual_qty",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Actual Quantity",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "actual_qty",
+ "oldfieldtype": "Currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "150px",
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "150px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "incoming_rate",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Incoming Rate",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "incoming_rate",
- "oldfieldtype": "Currency",
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "incoming_rate",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Incoming Rate",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "incoming_rate",
+ "oldfieldtype": "Currency",
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "outgoing_rate",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Outgoing Rate",
- "length": 0,
- "no_copy": 0,
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "outgoing_rate",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Outgoing Rate",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "stock_uom",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Stock UOM",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "stock_uom",
- "oldfieldtype": "Data",
- "options": "UOM",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "150px",
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "stock_uom",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Stock UOM",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "stock_uom",
+ "oldfieldtype": "Data",
+ "options": "UOM",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "150px",
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "150px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "qty_after_transaction",
- "fieldtype": "Float",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Actual Qty After Transaction",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "bin_aqat",
- "oldfieldtype": "Currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "150px",
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "qty_after_transaction",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Actual Qty After Transaction",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "bin_aqat",
+ "oldfieldtype": "Currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "150px",
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "150px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "valuation_rate",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Valuation Rate",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "valuation_rate",
- "oldfieldtype": "Currency",
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "150px",
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "valuation_rate",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Valuation Rate",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "valuation_rate",
+ "oldfieldtype": "Currency",
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "150px",
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "150px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "stock_value",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Stock Value",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "stock_value",
- "oldfieldtype": "Currency",
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "stock_value",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Stock Value",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "stock_value",
+ "oldfieldtype": "Currency",
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "stock_value_difference",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Stock Value Difference",
- "length": 0,
- "no_copy": 0,
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "stock_value_difference",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Stock Value Difference",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "stock_queue",
- "fieldtype": "Text",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Stock Queue (FIFO)",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "fcfs_stack",
- "oldfieldtype": "Text",
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "stock_queue",
+ "fieldtype": "Text",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Stock Queue (FIFO)",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "fcfs_stack",
+ "oldfieldtype": "Text",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 1,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "project",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Project",
- "length": 0,
- "no_copy": 0,
- "options": "Project",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "project",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Project",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Project",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "company",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Company",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "company",
- "oldfieldtype": "Data",
- "options": "Company",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "150px",
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Company",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "company",
+ "oldfieldtype": "Data",
+ "options": "Company",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "150px",
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "150px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "fiscal_year",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Fiscal Year",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "fiscal_year",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "150px",
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "fiscal_year",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Fiscal Year",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "fiscal_year",
+ "oldfieldtype": "Data",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "150px",
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "150px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "is_cancelled",
- "fieldtype": "Select",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Is Cancelled",
- "length": 0,
- "no_copy": 0,
- "options": "\nNo\nYes",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "is_cancelled",
+ "fieldtype": "Select",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Is Cancelled",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nNo\nYes",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 1,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "fieldname": "to_rename",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "To Rename",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 1,
- "icon": "fa fa-list",
- "idx": 1,
- "image_view": 0,
- "in_create": 1,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-08-21 16:15:42.956035",
- "modified_by": "Administrator",
- "module": "Stock",
- "name": "Stock Ledger Entry",
- "owner": "Administrator",
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 1,
+ "icon": "fa fa-list",
+ "idx": 1,
+ "image_view": 0,
+ "in_create": 1,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2019-01-07 07:04:37.523024",
+ "modified_by": "Administrator",
+ "module": "Stock",
+ "name": "Stock Ledger Entry",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 0,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Stock User",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
+ "amend": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 0,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Stock User",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
"write": 0
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 0,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 0,
- "read": 1,
- "report": 1,
- "role": "Accounts Manager",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
+ "amend": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 0,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 0,
+ "read": 1,
+ "report": 1,
+ "role": "Accounts Manager",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
"write": 0
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 0,
- "track_seen": 0,
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 0,
+ "track_seen": 0,
"track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
index 0e9a99a..79da70e 100644
--- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
+++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
@@ -16,6 +16,13 @@
exclude_from_linked_with = True
class StockLedgerEntry(Document):
+ def autoname(self):
+ """
+ Temporarily name doc for fast insertion
+ name will be changed using autoname options (in a scheduled job)
+ """
+ self.name = frappe.generate_hash(txt="", length=10)
+
def validate(self):
self.flags.ignore_submit_comment = True
from erpnext.stock.utils import validate_warehouse_company
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index 6b5bb28..eb60ce5 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -271,27 +271,39 @@
@frappe.whitelist()
def get_items(warehouse, posting_date, posting_time, company):
- items = frappe.db.sql('''select i.name, i.item_name from `tabItem` i, `tabBin` bin where i.name=bin.item_code
- and i.disabled=0 and bin.warehouse=%s''', (warehouse), as_dict=True)
+ lft, rgt = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"])
+ items = frappe.db.sql("""
+ select i.name, i.item_name, bin.warehouse
+ from tabBin bin, tabItem i
+ where i.name=bin.item_code and i.disabled=0
+ and exists(select name from `tabWarehouse` where lft >= %s and rgt <= %s and name=bin.warehouse)
+ """, (lft, rgt))
- items += frappe.db.sql('''select i.name, i.item_name from `tabItem` i, `tabItem Default` id where i.name = id.parent
- and i.is_stock_item=1 and i.has_serial_no=0 and i.has_batch_no=0 and i.has_variants=0 and i.disabled=0
- and id.default_warehouse=%s and id.company=%s group by i.name''', (warehouse, company), as_dict=True)
+ items += frappe.db.sql("""
+ select i.name, i.item_name, id.default_warehouse
+ from tabItem i, `tabItem Default` id
+ where i.name = id.parent
+ and exists(select name from `tabWarehouse` where lft >= %s and rgt <= %s and name=id.default_warehouse)
+ and i.is_stock_item = 1 and i.has_serial_no = 0 and i.has_batch_no = 0
+ and i.has_variants = 0 and i.disabled = 0 and id.company=%s
+ group by i.name
+ """, (lft, rgt, company))
res = []
- for item in items:
- qty, rate = get_stock_balance(item.name, warehouse, posting_date, posting_time,
+ for d in set(items):
+ stock_bal = get_stock_balance(d[0], d[2], posting_date, posting_time,
with_valuation_rate=True)
- res.append({
- "item_code": item.name,
- "warehouse": warehouse,
- "qty": qty,
- "item_name": item.item_name,
- "valuation_rate": rate,
- "current_qty": qty,
- "current_valuation_rate": rate
- })
+ if frappe.db.get_value("Item", d[0], "disabled") == 0:
+ res.append({
+ "item_code": d[0],
+ "warehouse": d[2],
+ "qty": stock_bal[0],
+ "item_name": d[1],
+ "valuation_rate": stock_bal[1],
+ "current_qty": stock_bal[0],
+ "current_valuation_rate": stock_bal[1]
+ })
return res
diff --git a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
index 212bb51..2dc585b 100644
--- a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
@@ -10,7 +10,9 @@
from erpnext.accounts.utils import get_stock_and_account_difference
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
from erpnext.stock.stock_ledger import get_previous_sle, update_entries_after
-from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import EmptyStockReconciliationItemsError
+from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import EmptyStockReconciliationItemsError, get_items
+from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
+from erpnext.stock.doctype.item.test_item import create_item
class TestStockReconciliation(unittest.TestCase):
def setUp(self):
@@ -79,6 +81,19 @@
set_perpetual_inventory(0)
+ def test_get_items(self):
+ create_warehouse("_Test Warehouse Group 1", {"is_group": 1})
+ create_warehouse("_Test Warehouse Ledger 1",
+ {"is_group": 0, "parent_warehouse": "_Test Warehouse Group 1 - _TC"})
+
+ create_item("_Test Stock Reco Item", is_stock_item=1, valuation_rate=100,
+ warehouse="_Test Warehouse Ledger 1 - _TC", opening_stock=100)
+
+ items = get_items("_Test Warehouse Group 1 - _TC", nowdate(), nowtime(), "_Test Company")
+
+ self.assertEqual(["_Test Stock Reco Item", "_Test Warehouse Ledger 1 - _TC", 100],
+ [items[0]["item_code"], items[0]["warehouse"], items[0]["qty"]])
+
def insert_existing_sle(self):
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
diff --git a/erpnext/stock/doctype/warehouse/test_warehouse.py b/erpnext/stock/doctype/warehouse/test_warehouse.py
index 006945e..b033f86 100644
--- a/erpnext/stock/doctype/warehouse/test_warehouse.py
+++ b/erpnext/stock/doctype/warehouse/test_warehouse.py
@@ -90,7 +90,7 @@
self.assertTrue(frappe.db.get_value("Warehouse",
filters={"account": "Test Warehouse for Merging 2 - _TC"}))
-def create_warehouse(warehouse_name):
+def create_warehouse(warehouse_name, properties=None):
if not frappe.db.exists("Warehouse", warehouse_name + " - _TC"):
w = frappe.new_doc("Warehouse")
w.warehouse_name = warehouse_name
@@ -98,11 +98,13 @@
w.company = "_Test Company"
make_account_for_warehouse(warehouse_name, w)
w.account = warehouse_name + " - _TC"
+ if properties:
+ w.update(properties)
w.save()
def make_account_for_warehouse(warehouse_name, warehouse_obj):
if not frappe.db.exists("Account", warehouse_name + " - _TC"):
- parent_account = frappe.db.get_value('Account',
+ parent_account = frappe.db.get_value('Account',
{'company': warehouse_obj.company, 'is_group':1, 'account_type': 'Stock'},'name')
account = create_account(account_name=warehouse_name, \
account_type="Stock", parent_account= parent_account, company=warehouse_obj.company)
\ No newline at end of file
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index f86be14..8eaa284 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -36,6 +36,7 @@
"is_subcontracted": "Yes" / "No",
"ignore_pricing_rule": 0/1
"project": ""
+ "set_warehouse": ""
}
"""
args = process_args(args)
@@ -193,7 +194,6 @@
"project": "",
barcode: "",
serial_no: "",
- warehouse: "",
currency: "",
update_stock: "",
price_list: "",
@@ -223,7 +223,7 @@
item_defaults = get_item_defaults(item.name, args.company)
item_group_defaults = get_item_group_defaults(item.name, args.company)
- warehouse = user_default_warehouse or item_defaults.get("default_warehouse") or\
+ warehouse = args.get("set_warehouse") or user_default_warehouse or item_defaults.get("default_warehouse") or\
item_group_defaults.get("default_warehouse") or args.warehouse
if args.get('doctype') == "Material Request" and not args.get('material_request_type'):
@@ -254,8 +254,8 @@
"batch_no": None,
"uom": args.uom,
"min_order_qty": flt(item.min_order_qty) if args.doctype == "Material Request" else "",
- "qty": args.qty or 1.0,
- "stock_qty": args.qty or 1.0,
+ "qty": flt(args.qty) or 1.0,
+ "stock_qty": flt(args.qty) or 1.0,
"price_list_rate": 0.0,
"base_price_list_rate": 0.0,
"rate": 0.0,
@@ -275,7 +275,7 @@
"transaction_date": args.get("transaction_date")
})
- if item.enable_deferred_revenue:
+ if item.get("enable_deferred_revenue") or item.get("enable_deferred_expense"):
out.update(calculate_service_end_date(args, item))
# calculate conversion factor
@@ -365,9 +365,15 @@
if not item:
item = frappe.get_cached_doc("Item", args.item_code)
- enable_deferred = "enable_deferred_revenue" if args.doctype=="Sales Invoice" else "enable_deferred_expense"
- no_of_months = "no_of_months" if args.doctype=="Sales Invoice" else "no_of_months_exp"
- account = "deferred_revenue_account" if args.doctype=="Sales Invoice" else "deferred_expense_account"
+ doctype = args.get("parenttype") or args.get("doctype")
+ if doctype == "Sales Invoice":
+ enable_deferred = "enable_deferred_revenue"
+ no_of_months = "no_of_months"
+ account = "deferred_revenue_account"
+ else:
+ enable_deferred = "enable_deferred_expense"
+ no_of_months = "no_of_months_exp"
+ account = "deferred_expense_account"
service_start_date = args.service_start_date if args.service_start_date else args.transaction_date
service_end_date = add_months(service_start_date, item.get(no_of_months))
@@ -391,7 +397,7 @@
or args.expense_account)
def get_default_deferred_account(args, item, fieldname=None):
- if item.enable_deferred_revenue:
+ if item.get("enable_deferred_revenue") or item.get("enable_deferred_expense"):
return (item.get(fieldname)
or args.get(fieldname)
or frappe.get_cached_value('Company', args.company, "default_"+fieldname))
@@ -419,22 +425,24 @@
meta = frappe.get_meta(args.parenttype or args.doctype)
if meta.get_field("currency") or args.get('currency'):
+ pl_details = get_price_list_currency_and_exchange_rate(args)
+ args.update(pl_details)
validate_price_list(args)
if meta.get_field("currency") and args.price_list:
validate_conversion_rate(args, meta)
price_list_rate = get_price_list_rate_for(args, item_doc.name) or 0
+ # variant
+ if not price_list_rate and item_doc.variant_of:
+ price_list_rate = get_price_list_rate_for(args, item_doc.variant_of)
+
# insert in database
if not price_list_rate:
if args.price_list and args.rate:
insert_item_price(args)
return {}
- # variant
- if not price_list_rate and item_doc.variant_of:
- price_list_rate = get_price_list_rate_for(args, item_doc.variant_of)
-
out.price_list_rate = flt(price_list_rate) * flt(args.plc_conversion_rate) \
/ flt(args.conversion_rate)
@@ -603,9 +611,10 @@
validate_conversion_rate(args.price_list_currency, args.plc_conversion_rate,
meta.get_label("plc_conversion_rate"), args.company)
- args.plc_conversion_rate = flt(args.plc_conversion_rate,
- get_field_precision(meta.get_field("plc_conversion_rate"),
- frappe._dict({"fields": args})))
+ if meta.get_field("plc_conversion_rate"):
+ args.plc_conversion_rate = flt(args.plc_conversion_rate,
+ get_field_precision(meta.get_field("plc_conversion_rate"),
+ frappe._dict({"fields": args})))
def get_party_item_code(args, item_doc, out):
if args.transaction_type=="selling" and args.customer:
@@ -841,7 +850,7 @@
if not result:
throw(_("Price List {0} is disabled or does not exist").format(price_list))
- return result.price_not_uom_dependant
+ return not result.price_not_uom_dependant
def get_price_list_currency_and_exchange_rate(args):
diff --git a/erpnext/stock/report/stock_ageing/stock_ageing.py b/erpnext/stock/report/stock_ageing/stock_ageing.py
index ecdd96a..ae3d72e 100644
--- a/erpnext/stock/report/stock_ageing/stock_ageing.py
+++ b/erpnext/stock/report/stock_ageing/stock_ageing.py
@@ -81,7 +81,7 @@
company = %(company)s and
posting_date <= %(to_date)s
{sle_conditions}
- order by posting_date, posting_time, sle.name"""\
+ order by posting_date, posting_time, sle.creation"""\
.format(item_conditions=get_item_conditions(filters),
sle_conditions=get_sle_conditions(filters)), filters, as_dict=True)
diff --git a/erpnext/stock/report/stock_balance/stock_balance.py b/erpnext/stock/report/stock_balance/stock_balance.py
index cc1112c..14b1852 100644
--- a/erpnext/stock/report/stock_balance/stock_balance.py
+++ b/erpnext/stock/report/stock_balance/stock_balance.py
@@ -130,7 +130,7 @@
from
`tabStock Ledger Entry` sle force index (posting_sort_index)
where sle.docstatus < 2 %s %s
- order by sle.posting_date, sle.posting_time, sle.name""" %
+ order by sle.posting_date, sle.posting_time, sle.creation""" %
(item_conditions_sql, conditions), as_dict=1)
def get_item_warehouse_map(filters, sle):
diff --git a/erpnext/stock/report/stock_ledger/stock_ledger.py b/erpnext/stock/report/stock_ledger/stock_ledger.py
index 805b314..acb3df5 100644
--- a/erpnext/stock/report/stock_ledger/stock_ledger.py
+++ b/erpnext/stock/report/stock_ledger/stock_ledger.py
@@ -77,7 +77,7 @@
posting_date between %(from_date)s and %(to_date)s
{sle_conditions}
{item_conditions_sql}
- order by posting_date asc, posting_time asc, name asc"""\
+ order by posting_date asc, posting_time asc, creation asc"""\
.format(
sle_conditions=get_sle_conditions(filters),
item_conditions_sql = item_conditions_sql
diff --git a/erpnext/stock/stock_balance.py b/erpnext/stock/stock_balance.py
index 09d4e43..0dbb7f8 100644
--- a/erpnext/stock/stock_balance.py
+++ b/erpnext/stock/stock_balance.py
@@ -59,7 +59,7 @@
def get_balance_qty_from_sle(item_code, warehouse):
balance_qty = frappe.db.sql("""select qty_after_transaction from `tabStock Ledger Entry`
where item_code=%s and warehouse=%s and is_cancelled='No'
- order by posting_date desc, posting_time desc, name desc
+ order by posting_date desc, posting_time desc, creation desc
limit 1""", (item_code, warehouse))
return flt(balance_qty[0][0]) if balance_qty else 0.0
@@ -235,7 +235,7 @@
vouchers = frappe.db.sql("""select distinct voucher_type, voucher_no
from `tabStock Ledger Entry` sle
where voucher_type != "Serial No" and sle.warehouse in (%s)
- order by posting_date, posting_time, name""" %
+ order by posting_date, posting_time, creation""" %
', '.join(['%s']*len(warehouses_with_account)), tuple(warehouses_with_account))
rejected = []
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index 0ef2afa..c8706b2 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -432,7 +432,7 @@
where item_code = %%(item_code)s
and ifnull(is_cancelled, 'No')='No'
%(conditions)s
- order by timestamp(posting_date, posting_time) %(order)s, name %(order)s
+ order by timestamp(posting_date, posting_time) %(order)s, creation %(order)s
%(limit)s %(for_update)s""" % {
"conditions": conditions,
"limit": limit or "",
@@ -450,14 +450,14 @@
from `tabStock Ledger Entry`
where item_code = %s and warehouse = %s
and valuation_rate >= 0
- order by posting_date desc, posting_time desc, name desc limit 1""", (item_code, warehouse))
+ order by posting_date desc, posting_time desc, creation desc limit 1""", (item_code, warehouse))
if not last_valuation_rate:
# Get valuation rate from last sle for the item against any warehouse
last_valuation_rate = frappe.db.sql("""select valuation_rate
from `tabStock Ledger Entry`
where item_code = %s and valuation_rate > 0
- order by posting_date desc, posting_time desc, name desc limit 1""", item_code)
+ order by posting_date desc, posting_time desc, creation desc limit 1""", item_code)
if last_valuation_rate:
return flt(last_valuation_rate[0][0]) # as there is previous records, it might come with zero rate
diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py
index de31c54..c89fc10 100644
--- a/erpnext/stock/utils.py
+++ b/erpnext/stock/utils.py
@@ -62,7 +62,7 @@
SELECT item_code, stock_value, name, warehouse
FROM `tabStock Ledger Entry` sle
WHERE posting_date <= %s {0}
- ORDER BY timestamp(posting_date, posting_time) DESC, name DESC
+ ORDER BY timestamp(posting_date, posting_time) DESC, creation DESC
""".format(condition), values, as_dict=1)
sle_map = {}