Merge branch 'develop' into po_supplier_skip

This commit is contained in:
Deepesh Garg 2020-03-30 13:07:03 +05:30 committed by GitHub
commit f144b8b205
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
197 changed files with 2927 additions and 3265 deletions

View File

@ -15,18 +15,18 @@
ERPNext as a monolith includes the following areas for managing businesses: ERPNext as a monolith includes the following areas for managing businesses:
1. [Accounting](https://erpnext.com/docs/user/manual/en/accounts) 1. [Accounting](https://erpnext.com/open-source-accounting)
1. [Inventory](https://erpnext.com/docs/user/manual/en/stock) 1. [Inventory](https://erpnext.com/distribution/inventory-management-system)
1. [CRM](https://erpnext.com/docs/user/manual/en/CRM) 1. [CRM](https://erpnext.com/open-source-crm)
1. [Sales](https://erpnext.com/docs/user/manual/en/selling) 1. [Sales](https://erpnext.com/open-source-sales-purchase)
1. [Purchase](https://erpnext.com/docs/user/manual/en/buying) 1. [Purchase](https://erpnext.com/open-source-sales-purchase)
1. [HRMS](https://erpnext.com/docs/user/manual/en/human-resources) 1. [HRMS](https://erpnext.com/open-source-hrms)
1. [Project Management](https://erpnext.com/docs/user/manual/en/projects) 1. [Project Management](https://erpnext.com/open-source-projects)
1. [Support](https://erpnext.com/docs/user/manual/en/support) 1. [Support](https://erpnext.com/open-source-help-desk-software)
1. [Asset Management](https://erpnext.com/docs/user/manual/en/asset) 1. [Asset Management](https://erpnext.com/open-source-asset-management-software)
1. [Quality Management](https://erpnext.com/docs/user/manual/en/quality-management) 1. [Quality Management](https://erpnext.com/docs/user/manual/en/quality-management)
1. [Manufacturing](https://erpnext.com/docs/user/manual/en/manufacturing) 1. [Manufacturing](https://erpnext.com/open-source-manufacturing-erp-software)
1. [Website Management](https://erpnext.com/docs/user/manual/en/website) 1. [Website Management](https://erpnext.com/open-source-website-builder-software)
1. [Customize ERPNext](https://erpnext.com/docs/user/manual/en/customize-erpnext) 1. [Customize ERPNext](https://erpnext.com/docs/user/manual/en/customize-erpnext)
1. [And More](https://erpnext.com/docs/user/manual/en/) 1. [And More](https://erpnext.com/docs/user/manual/en/)

View File

@ -5,7 +5,7 @@ import frappe
from erpnext.hooks import regional_overrides from erpnext.hooks import regional_overrides
from frappe.utils import getdate from frappe.utils import getdate
__version__ = '12.2.0' __version__ = '12.0.0-dev'
def get_default_company(user=None): def get_default_company(user=None):
'''Get default company for user''' '''Get default company for user'''

View File

@ -13,7 +13,8 @@ from frappe.utils.nestedset import get_descendants_of
@frappe.whitelist() @frappe.whitelist()
@cache_source @cache_source
def get(chart_name = None, chart = None, no_cache = None, from_date = None, to_date = None): def get(chart_name = None, chart = None, no_cache = None, filters = None, from_date = None,
to_date = None, timespan = None, time_interval = None):
if chart_name: if chart_name:
chart = frappe.get_doc('Dashboard Chart', chart_name) chart = frappe.get_doc('Dashboard Chart', chart_name)
else: else:
@ -25,7 +26,7 @@ def get(chart_name = None, chart = None, no_cache = None, from_date = None, to_d
to_date = chart.to_date to_date = chart.to_date
timegrain = chart.time_interval timegrain = chart.time_interval
filters = frappe.parse_json(chart.filters_json) filters = frappe.parse_json(filters) or frappe.parse_json(chart.filters_json)
account = filters.get("account") account = filters.get("account")
company = filters.get("company") company = filters.get("company")

View File

@ -0,0 +1,137 @@
{
"cards": [
{
"links": "[\n {\n \"description\": \"Company (not Customer or Supplier) master.\",\n \"label\": \"Company\",\n \"name\": \"Company\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of financial accounts.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Chart of Accounts\",\n \"name\": \"Account\",\n \"onboard\": 1,\n \"route\": \"#Tree/Account\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounts Settings\",\n \"name\": \"Accounts Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Financial / accounting year.\",\n \"label\": \"Fiscal Year\",\n \"name\": \"Fiscal Year\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounting Dimension\",\n \"name\": \"Accounting Dimension\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Finance Book\",\n \"name\": \"Finance Book\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounting Period\",\n \"name\": \"Accounting Period\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Payment Terms based on conditions\",\n \"label\": \"Payment Term\",\n \"name\": \"Payment Term\",\n \"type\": \"doctype\"\n }\n]",
"title": "Accounting Masters"
},
{
"links": "[\n {\n \"description\": \"Accounting journal entries.\",\n \"label\": \"Journal Entry\",\n \"name\": \"Journal Entry\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"General Ledger\",\n \"name\": \"General Ledger\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Customer Ledger Summary\",\n \"name\": \"Customer Ledger Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Supplier Ledger Summary\",\n \"name\": \"Supplier Ledger Summary\",\n \"type\": \"report\"\n }\n]",
"title": "General Ledger"
},
{
"links": "[\n {\n \"description\": \"Bills raised to Customers.\",\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bank/Cash transactions against party or for internal transfer\",\n \"label\": \"Payment Entry\",\n \"name\": \"Payment Entry\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Payment Request\",\n \"label\": \"Payment Request\",\n \"name\": \"Payment Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable\",\n \"name\": \"Accounts Receivable\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable Summary\",\n \"name\": \"Accounts Receivable Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Register\",\n \"name\": \"Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales Register\",\n \"name\": \"Item-wise Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Ordered Items To Be Billed\",\n \"name\": \"Ordered Items To Be Billed\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Delivered Items To Be Billed\",\n \"name\": \"Delivered Items To Be Billed\",\n \"type\": \"report\"\n }\n]",
"title": "Accounts Receivable"
},
{
"links": "[\n {\n \"description\": \"Bills raised by Suppliers.\",\n \"label\": \"Purchase Invoice\",\n \"name\": \"Purchase Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Supplier database.\",\n \"label\": \"Supplier\",\n \"name\": \"Supplier\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bank/Cash transactions against party or for internal transfer\",\n \"label\": \"Payment Entry\",\n \"name\": \"Payment Entry\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Payable\",\n \"name\": \"Accounts Payable\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Payable Summary\",\n \"name\": \"Accounts Payable Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Purchase Register\",\n \"name\": \"Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Purchase Register\",\n \"name\": \"Item-wise Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Purchase Order Items To Be Billed\",\n \"name\": \"Purchase Order Items To Be Billed\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Received Items To Be Billed\",\n \"name\": \"Received Items To Be Billed\",\n \"type\": \"report\"\n }\n]",
"title": "Accounts Payable"
},
{
"icon": "fa fa-table",
"links": "[\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Trial Balance for Party\",\n \"name\": \"Trial Balance for Party\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Journal Entry\"\n ],\n \"doctype\": \"Journal Entry\",\n \"is_query_report\": true,\n \"label\": \"Payment Period Based On Invoice Date\",\n \"name\": \"Payment Period Based On Invoice Date\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Partners Commission\",\n \"name\": \"Sales Partners Commission\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customer Credit Balance\",\n \"name\": \"Customer Credit Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Payment Summary\",\n \"name\": \"Sales Payment Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Address\"\n ],\n \"doctype\": \"Address\",\n \"is_query_report\": true,\n \"label\": \"Address And Contacts\",\n \"name\": \"Address And Contacts\",\n \"type\": \"report\"\n }\n]",
"title": "Reports"
},
{
"links": "[\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Trial Balance\",\n \"name\": \"Trial Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Profit and Loss Statement\",\n \"name\": \"Profit and Loss Statement\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Balance Sheet\",\n \"name\": \"Balance Sheet\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Cash Flow\",\n \"name\": \"Cash Flow\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Consolidated Financial Statement\",\n \"name\": \"Consolidated Financial Statement\",\n \"type\": \"report\"\n }\n]",
"title": "Financial Statements"
},
{
"links": "[\n {\n \"description\": \"Enable / disable currencies.\",\n \"label\": \"Currency\",\n \"name\": \"Currency\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Currency exchange rate master.\",\n \"label\": \"Currency Exchange\",\n \"name\": \"Currency Exchange\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Exchange Rate Revaluation master.\",\n \"label\": \"Exchange Rate Revaluation\",\n \"name\": \"Exchange Rate Revaluation\",\n \"type\": \"doctype\"\n }\n]",
"title": "Multi Currency"
},
{
"icon": "fa fa-cog",
"links": "[\n {\n \"description\": \"Setup Gateway accounts.\",\n \"label\": \"Payment Gateway Account\",\n \"name\": \"Payment Gateway Account\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Template of terms or contract.\",\n \"label\": \"Terms and Conditions Template\",\n \"name\": \"Terms and Conditions\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"e.g. Bank, Cash, Credit Card\",\n \"label\": \"Mode of Payment\",\n \"name\": \"Mode of Payment\",\n \"type\": \"doctype\"\n }\n]",
"title": "Settings"
},
{
"links": "[\n {\n \"label\": \"Bank\",\n \"name\": \"Bank\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Bank Account\",\n \"name\": \"Bank Account\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Bank Statement Transaction Entry\",\n \"name\": \"Bank Statement Transaction Entry\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Bank Statement Settings\",\n \"name\": \"Bank Statement Settings\",\n \"type\": \"doctype\"\n }\n]",
"title": "Bank Statement"
},
{
"links": "[\n {\n \"description\": \"Match non-linked Invoices and Payments.\",\n \"label\": \"Match Payments with Invoices\",\n \"name\": \"Payment Reconciliation\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Update bank payment dates with journals.\",\n \"label\": \"Update Bank Transaction Dates\",\n \"name\": \"Bank Reconciliation\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Invoice Discounting\",\n \"name\": \"Invoice Discounting\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Journal Entry\"\n ],\n \"doctype\": \"Journal Entry\",\n \"is_query_report\": true,\n \"label\": \"Bank Reconciliation Statement\",\n \"name\": \"Bank Reconciliation Statement\",\n \"type\": \"report\"\n },\n {\n \"icon\": \"fa fa-bar-chart\",\n \"label\": \"Bank Reconciliation\",\n \"name\": \"bank-reconciliation\",\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Journal Entry\"\n ],\n \"doctype\": \"Journal Entry\",\n \"is_query_report\": true,\n \"label\": \"Bank Clearance Summary\",\n \"name\": \"Bank Clearance Summary\",\n \"type\": \"report\"\n },\n {\n \"label\": \"Bank Guarantee\",\n \"name\": \"Bank Guarantee\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Setup cheque dimensions for printing\",\n \"label\": \"Cheque Print Template\",\n \"name\": \"Cheque Print Template\",\n \"type\": \"doctype\"\n }\n]",
"title": "Banking and Payments"
},
{
"links": "[\n {\n \"label\": \"Subscription Plan\",\n \"name\": \"Subscription Plan\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Subscription\",\n \"name\": \"Subscription\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Subscription Settings\",\n \"name\": \"Subscription Settings\",\n \"type\": \"doctype\"\n }\n]",
"title": "Subscription Management"
},
{
"links": "[\n {\n \"label\": \"GST Settings\",\n \"name\": \"GST Settings\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"GST HSN Code\",\n \"name\": \"GST HSN Code\",\n \"type\": \"doctype\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GSTR-1\",\n \"name\": \"GSTR-1\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GSTR-2\",\n \"name\": \"GSTR-2\",\n \"type\": \"report\"\n },\n {\n \"label\": \"GSTR 3B Report\",\n \"name\": \"GSTR 3B Report\",\n \"type\": \"doctype\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Sales Register\",\n \"name\": \"GST Sales Register\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Purchase Register\",\n \"name\": \"GST Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Itemised Sales Register\",\n \"name\": \"GST Itemised Sales Register\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Itemised Purchase Register\",\n \"name\": \"GST Itemised Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"country\": \"India\",\n \"description\": \"C-Form records\",\n \"label\": \"C-Form\",\n \"name\": \"C-Form\",\n \"type\": \"doctype\"\n }\n]",
"title": "Goods and Services Tax (GST India)"
},
{
"icon": "fa fa-microchip ",
"links": "[\n {\n \"description\": \"List of available Shareholders with folio numbers\",\n \"label\": \"Shareholder\",\n \"name\": \"Shareholder\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"List of all share transactions\",\n \"label\": \"Share Transfer\",\n \"name\": \"Share Transfer\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Share Transfer\"\n ],\n \"doctype\": \"Share Transfer\",\n \"is_query_report\": true,\n \"label\": \"Share Ledger\",\n \"name\": \"Share Ledger\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Share Transfer\"\n ],\n \"doctype\": \"Share Transfer\",\n \"is_query_report\": true,\n \"label\": \"Share Balance\",\n \"name\": \"Share Balance\",\n \"type\": \"report\"\n }\n]",
"title": "Share Management"
},
{
"links": "[\n {\n \"description\": \"Tree of financial Cost Centers.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Chart of Cost Centers\",\n \"name\": \"Cost Center\",\n \"route\": \"#Tree/Cost Center\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Define budget for a financial year.\",\n \"label\": \"Budget\",\n \"name\": \"Budget\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounting Dimension\",\n \"name\": \"Accounting Dimension\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Cost Center\"\n ],\n \"doctype\": \"Cost Center\",\n \"is_query_report\": true,\n \"label\": \"Budget Variance Report\",\n \"name\": \"Budget Variance Report\",\n \"type\": \"report\"\n },\n {\n \"description\": \"Seasonality for setting budgets, targets etc.\",\n \"label\": \"Monthly Distribution\",\n \"name\": \"Monthly Distribution\",\n \"type\": \"doctype\"\n }\n]",
"title": "Cost Center and Budgeting"
},
{
"links": "[\n {\n \"label\": \"Opening Invoice Creation Tool\",\n \"name\": \"Opening Invoice Creation Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Chart of Accounts Importer\",\n \"name\": \"Chart of Accounts Importer\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Close Balance Sheet and book Profit or Loss.\",\n \"label\": \"Period Closing Voucher\",\n \"name\": \"Period Closing Voucher\",\n \"type\": \"doctype\"\n }\n]",
"title": "Opening and Closing"
},
{
"links": "[\n {\n \"description\": \"Tax template for selling transactions.\",\n \"label\": \"Sales Taxes and Charges Template\",\n \"name\": \"Sales Taxes and Charges Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for buying transactions.\",\n \"label\": \"Purchase Taxes and Charges Template\",\n \"name\": \"Purchase Taxes and Charges Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for item tax rates.\",\n \"label\": \"Item Tax Template\",\n \"name\": \"Item Tax Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax Category for overriding tax rates.\",\n \"label\": \"Tax Category\",\n \"name\": \"Tax Category\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax Rule for transactions.\",\n \"label\": \"Tax Rule\",\n \"name\": \"Tax Rule\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax Withholding rates to be applied on transactions.\",\n \"label\": \"Tax Withholding Category\",\n \"name\": \"Tax Withholding Category\",\n \"type\": \"doctype\"\n }\n]",
"title": "Taxes"
},
{
"links": "[\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Gross Profit\",\n \"name\": \"Gross Profit\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Profitability Analysis\",\n \"name\": \"Profitability Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Invoice Trends\",\n \"name\": \"Sales Invoice Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Purchase Invoice Trends\",\n \"name\": \"Purchase Invoice Trends\",\n \"type\": \"report\"\n }\n]",
"title": "Profitability"
}
],
"category": "Modules",
"charts": [
{
"chart_name": "Bank Balance",
"label": "Bank Balance",
"size": "Full"
}
],
"creation": "2020-03-02 15:41:59.515192",
"developer_mode_only": 0,
"disable_user_customization": 0,
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
"icon": "",
"idx": 0,
"is_standard": 1,
"label": "Accounting",
"modified": "2020-03-12 16:30:35.580450",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounting",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"shortcuts": [
{
"is_query_report": 0,
"link_to": "Account",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Journal Entry",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Payment Entry",
"type": "DocType"
},
{
"is_query_report": 1,
"link_to": "Accounts Receivable",
"type": "Report"
},
{
"is_query_report": 0,
"link_to": "General Ledger",
"type": "Report"
},
{
"is_query_report": 0,
"link_to": "Profit and Loss Statement",
"type": "Report"
},
{
"is_query_report": 0,
"link_to": "Trial Balance",
"type": "Report"
}
]
}

View File

@ -1,4 +1,5 @@
{ {
"actions": [],
"allow_copy": 1, "allow_copy": 1,
"allow_import": 1, "allow_import": 1,
"creation": "2013-01-30 12:49:46", "creation": "2013-01-30 12:49:46",
@ -196,10 +197,13 @@
], ],
"icon": "fa fa-money", "icon": "fa fa-money",
"idx": 1, "idx": 1,
"modified": "2019-10-10 19:10:02.967554", "is_tree": 1,
"links": [],
"modified": "2020-03-18 17:57:52.063233",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Account", "name": "Account",
"nsm_parent_field": "parent_account",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {

View File

@ -102,7 +102,7 @@ class Account(NestedSet):
if not frappe.db.get_value("Account", if not frappe.db.get_value("Account",
{'account_name': self.account_name, 'company': ancestors[0]}, 'name'): {'account_name': self.account_name, 'company': ancestors[0]}, 'name'):
frappe.throw(_("Please add the account to root level Company - %s" % ancestors[0])) frappe.throw(_("Please add the account to root level Company - %s" % ancestors[0]))
else: elif self.parent_account:
descendants = get_descendants_of('Company', self.company) descendants = get_descendants_of('Company', self.company)
if not descendants: return if not descendants: return
parent_acc_name_map = {} parent_acc_name_map = {}

View File

@ -663,16 +663,22 @@
"account_number": "1400" "account_number": "1400"
}, },
"Abziehbare Vorsteuer 7 %": { "Abziehbare Vorsteuer 7 %": {
"account_number": "1401" "account_number": "1401",
"account_type": "Tax",
"tax_rate": 7.0
}, },
"Abziehbare Vorsteuer aus innergem. Erwerb": { "Abziehbare Vorsteuer aus innergem. Erwerb": {
"account_number": "1402" "account_number": "1402"
}, },
"Abziehbare Vorsteuer aus innergem. Erwerb 19%": { "Abziehbare Vorsteuer aus innergem. Erwerb 19%": {
"account_number": "1404" "account_number": "1404",
"account_type": "Tax",
"tax_rate": 19.0
}, },
"Abziehbare Vorsteuer 19 %": { "Abziehbare Vorsteuer 19 %": {
"account_number": "1406" "account_number": "1406",
"account_type": "Tax",
"tax_rate": 19.0
}, },
"Abziehbare Vorsteuer nach \u00a7 13b UStG 19 %": { "Abziehbare Vorsteuer nach \u00a7 13b UStG 19 %": {
"account_number": "1407" "account_number": "1407"
@ -911,17 +917,31 @@
"is_group": 1, "is_group": 1,
"I - Gezeichnetes Kapital": { "I - Gezeichnetes Kapital": {
"account_type": "Equity", "account_type": "Equity",
"is_group": 1,
"Gezeichnetes Kapital": {
"account_type": "Equity",
"account_number": "2900"
},
"Ausstehende Einlagen auf das gezeichnete Kapital": {
"account_number": "2910",
"is_group": 1 "is_group": 1
}
}, },
"II - Kapitalr\u00fccklage": { "II - Kapitalr\u00fccklage": {
"account_type": "Equity", "account_type": "Equity",
"is_group": 1 "is_group": 1,
"Kapitalr\u00fccklage": {
"account_number": "2920"
}
}, },
"III - Gewinnr\u00fccklagen": { "III - Gewinnr\u00fccklagen": {
"account_type": "Equity", "account_type": "Equity",
"1 - gesetzliche R\u00fccklage": { "1 - gesetzliche R\u00fccklage": {
"account_type": "Equity", "account_type": "Equity",
"is_group": 1 "is_group": 1,
"Gesetzliche R\u00fccklage": {
"account_number": "2930"
}
}, },
"2 - R\u00fccklage f. Anteile an einem herrschenden oder mehrheitlich beteiligten Unternehmen": { "2 - R\u00fccklage f. Anteile an einem herrschenden oder mehrheitlich beteiligten Unternehmen": {
"account_type": "Equity", "account_type": "Equity",
@ -929,7 +949,10 @@
}, },
"3 - satzungsm\u00e4\u00dfige R\u00fccklagen": { "3 - satzungsm\u00e4\u00dfige R\u00fccklagen": {
"account_type": "Equity", "account_type": "Equity",
"is_group": 1 "is_group": 1,
"Satzungsm\u00e4\u00dfige R\u00fccklagen": {
"account_number": "2950"
}
}, },
"4 - andere Gewinnr\u00fccklagen": { "4 - andere Gewinnr\u00fccklagen": {
"account_type": "Equity", "account_type": "Equity",
@ -963,7 +986,13 @@
}, },
"IV - Gewinnvortrag/Verlustvortrag": { "IV - Gewinnvortrag/Verlustvortrag": {
"account_type": "Equity", "account_type": "Equity",
"is_group": 1 "is_group": 1,
"Gewinnvortrag vor Verwendung": {
"account_number": "2970"
},
"Verlustvortrag vor Verwendung": {
"account_number": "2978"
}
}, },
"V - Jahres\u00fcberschu\u00df/Jahresfehlbetrag": { "V - Jahres\u00fcberschu\u00df/Jahresfehlbetrag": {
"account_type": "Equity", "account_type": "Equity",
@ -1488,17 +1517,21 @@
}, },
"Umsatzsteuer 7 %": { "Umsatzsteuer 7 %": {
"account_number": "3801", "account_number": "3801",
"account_type": "Tax" "account_type": "Tax",
"tax_rate": 7.0
}, },
"Umsatzsteuer aus innergem. Erwerb": { "Umsatzsteuer aus innergem. Erwerb": {
"account_number": "3802" "account_number": "3802"
}, },
"Umsatzsteuer aus innergem. Erwerb 19 %": { "Umsatzsteuer aus innergem. Erwerb 19 %": {
"account_number": "3804" "account_number": "3804",
"account_type": "Tax",
"tax_rate": 19.0
}, },
"Umsatzsteuer 19 %": { "Umsatzsteuer 19 %": {
"account_number": "3806", "account_number": "3806",
"account_type": "Tax" "account_type": "Tax",
"tax_rate": 19.0
}, },
"Umsatzsteuer aus im Inland steuerpfl. EU-Lieferungen": { "Umsatzsteuer aus im Inland steuerpfl. EU-Lieferungen": {
"account_number": "3807" "account_number": "3807"
@ -1654,6 +1687,14 @@
"account_number": "4300", "account_number": "4300",
"account_type": "Income Account" "account_type": "Income Account"
}, },
"Erl\u00f6se 16 % USt": {
"account_number": "4340",
"account_type": "Income Account"
},
"Erl\u00f6se 19 % USt": {
"account_number": "4400",
"account_type": "Income Account"
},
"Erl\u00f6se aus im Inland steuerpfl. EU-Lieferungen 7 % USt": { "Erl\u00f6se aus im Inland steuerpfl. EU-Lieferungen 7 % USt": {
"account_number": "4310" "account_number": "4310"
}, },
@ -1681,19 +1722,6 @@
"Erl\u00f6se aus im anderen EU-Land steuerbaren Leistungen, im Inland nicht steuerbare Ums\u00e4tze": { "Erl\u00f6se aus im anderen EU-Land steuerbaren Leistungen, im Inland nicht steuerbare Ums\u00e4tze": {
"account_number": "4339" "account_number": "4339"
}, },
"Erl\u00f6se 16 % USt (Gruppe)": {
"is_group": 1,
"Erl\u00f6se 16 % USt": {
"account_number": "4340"
}
},
"Erl\u00f6se 19 % USt (Gruppe)": {
"is_group": 1,
"Erl\u00f6se 19 % USt": {
"account_number": "4400",
"account_type": "Income Account"
}
},
"Grundst\u00fccksertr\u00e4ge (Gruppe)": { "Grundst\u00fccksertr\u00e4ge (Gruppe)": {
"is_group": 1, "is_group": 1,
"Grundst\u00fccksertr\u00e4ge": { "Grundst\u00fccksertr\u00e4ge": {
@ -1752,14 +1780,12 @@
"2 - Herstellungskosten der zur Erzielung der Umsatzerl\u00f6se erbrachten Leistungen": { "2 - Herstellungskosten der zur Erzielung der Umsatzerl\u00f6se erbrachten Leistungen": {
"root_type": "Expense", "root_type": "Expense",
"is_group": 1, "is_group": 1,
"Herstellungskosten (Gruppe)": {
"Herstellungskosten": { "Herstellungskosten": {
"account_number": "6990", "account_number": "6990",
"account_type": "Cost of Goods Sold" "account_type": "Cost of Goods Sold"
}, },
"Herstellungskosten: Schwund": { "Herstellungskosten: Schwund": {
"account_type": "Stock Adjustment" "account_type": "Stock Adjustment"
}
}, },
"Aufwendungen f. Roh-, Hilfs- und Betriebsstoffe und f. bezogene Waren": { "Aufwendungen f. Roh-, Hilfs- und Betriebsstoffe und f. bezogene Waren": {
"account_number": "5000", "account_number": "5000",
@ -1935,6 +1961,7 @@
}, },
"Nachl\u00e4sse aus innergem. Erwerb 15 % Vorsteuer und 15 % Umsatzsteuer": { "Nachl\u00e4sse aus innergem. Erwerb 15 % Vorsteuer und 15 % Umsatzsteuer": {
"account_number": "5727" "account_number": "5727"
}
}, },
"Erhaltene Skonti (Gruppe)": { "Erhaltene Skonti (Gruppe)": {
"is_group": 1, "is_group": 1,
@ -1977,7 +2004,6 @@
"Erh. Skonti aus Erwerb Waren als letzter Abnehmer innerh. Dreiecksgesch. 19% Vorst. u. 19% Ust.": { "Erh. Skonti aus Erwerb Waren als letzter Abnehmer innerh. Dreiecksgesch. 19% Vorst. u. 19% Ust.": {
"account_number": "5793" "account_number": "5793"
} }
}
}, },
"Bezugsnebenkosten (Gruppe)": { "Bezugsnebenkosten (Gruppe)": {
"is_group": 1, "is_group": 1,

View File

@ -48,12 +48,6 @@ frappe.ui.form.on('Accounting Dimension', {
frm.set_value('label', frm.doc.document_type); frm.set_value('label', frm.doc.document_type);
frm.set_value('fieldname', frappe.model.scrub(frm.doc.document_type)); frm.set_value('fieldname', frappe.model.scrub(frm.doc.document_type));
if (frm.is_new()){
let row = frappe.model.add_child(frm.doc, "Accounting Dimension Detail", "dimension_defaults");
row.reference_document = frm.doc.document_type;
frm.refresh_fields("dimension_defaults");
}
frappe.db.get_value('Accounting Dimension', {'document_type': frm.doc.document_type}, 'document_type', (r) => { frappe.db.get_value('Accounting Dimension', {'document_type': frm.doc.document_type}, 'document_type', (r) => {
if (r && r.document_type) { if (r && r.document_type) {
frm.set_df_property('document_type', 'description', "Document type is already set as dimension"); frm.set_df_property('document_type', 'description', "Document type is already set as dimension");

View File

@ -1,4 +1,5 @@
{ {
"actions": [],
"autoname": "field:label", "autoname": "field:label",
"creation": "2019-05-04 18:13:37.002352", "creation": "2019-05-04 18:13:37.002352",
"doctype": "DocType", "doctype": "DocType",
@ -46,7 +47,8 @@
"options": "Accounting Dimension Detail" "options": "Accounting Dimension Detail"
} }
], ],
"modified": "2019-07-17 16:49:31.134385", "links": [],
"modified": "2020-03-22 20:34:39.805728",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Accounting Dimension", "name": "Accounting Dimension",
@ -63,9 +65,20 @@
"role": "System Manager", "role": "System Manager",
"share": 1, "share": 1,
"write": 1 "write": 1
},
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts Manager",
"share": 1,
"write": 1
} }
], ],
"quick_entry": 1,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "ASC", "sort_order": "ASC",
"track_changes": 1 "track_changes": 1

View File

@ -172,7 +172,7 @@ def get_doctypes_with_dimensions():
return doclist return doclist
def get_accounting_dimensions(as_list=True): def get_accounting_dimensions(as_list=True):
accounting_dimensions = frappe.get_all("Accounting Dimension", fields=["label", "fieldname", "disabled"]) accounting_dimensions = frappe.get_all("Accounting Dimension", fields=["label", "fieldname", "disabled", "document_type"])
if as_list: if as_list:
return [d.fieldname for d in accounting_dimensions] return [d.fieldname for d in accounting_dimensions]
@ -186,6 +186,18 @@ def get_checks_for_pl_and_bs_accounts():
return dimensions return dimensions
def get_dimension_with_children(doctype, dimension):
if isinstance(dimension, list):
dimension = dimension[0]
all_dimensions = []
lft, rgt = frappe.db.get_value(doctype, dimension, ["lft", "rgt"])
children = frappe.get_all(doctype, filters={"lft": [">=", lft], "rgt": ["<=", rgt]})
all_dimensions += [c.name for c in children]
return all_dimensions
@frappe.whitelist() @frappe.whitelist()
def get_dimension_filters(): def get_dimension_filters():
dimension_filters = frappe.db.sql(""" dimension_filters = frappe.db.sql("""

View File

@ -0,0 +1,8 @@
frappe.ui.form.on('Accounts Settings', {
refresh: function(frm) {
frm.set_df_property("acc_frozen_upto", "label", "Books Closed Through");
frm.set_df_property("frozen_accounts_modifier", "label", "Role Allowed to Close Books & Make Changes to Closed Periods");
frm.set_df_property("credit_controller", "label", "Credit Manager");
}
});

View File

@ -7,7 +7,20 @@ frappe.ui.form.on('Bank', {
}, },
refresh: function(frm) { refresh: function(frm) {
add_fields_to_mapping_table(frm); add_fields_to_mapping_table(frm);
frappe.dynamic_link = { doc: frm.doc, fieldname: 'name', doctype: 'Bank' };
frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
if (frm.doc.__islocal) {
frm.set_df_property('address_and_contact', 'hidden', 1);
frappe.contacts.clear_address_and_contact(frm);
} }
else {
frm.set_df_property('address_and_contact', 'hidden', 0);
frappe.contacts.render_address_and_contact(frm);
}
},
}); });

View File

@ -1,224 +1,137 @@
{ {
"allow_copy": 0, "actions": [],
"allow_events_in_timeline": 0, "allow_import": 1,
"allow_guest_to_view": 0, "allow_rename": 1,
"allow_import": 0,
"allow_rename": 0,
"autoname": "field:bank_name", "autoname": "field:bank_name",
"beta": 0,
"creation": "2018-04-07 16:59:59.496668", "creation": "2018-04-07 16:59:59.496668",
"custom": 0,
"docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "", "document_type": "Setup",
"editable_grid": 1, "editable_grid": 1,
"engine": "InnoDB", "engine": "InnoDB",
"field_order": [
"bank_details_section",
"bank_name",
"swift_number",
"column_break_1",
"branch_code",
"website",
"address_and_contact",
"address_html",
"column_break_13",
"contact_html",
"data_import_configuration_section",
"bank_transaction_mapping",
"section_break_4",
"plaid_access_token"
],
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "bank_name", "fieldname": "bank_name",
"fieldtype": "Data", "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": "Bank Name", "label": "Bank Name",
"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": 1, "reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 1 "unique": 1
}, },
{ {
"allow_bulk_edit": 0, "fieldname": "bank_details_section",
"allow_in_quick_entry": 0, "fieldtype": "Section Break",
"allow_on_submit": 0, "label": "Bank Details"
"bold": 0, },
{
"allow_in_quick_entry": 1,
"fieldname": "swift_number",
"fieldtype": "Data",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "SWIFT number",
"unique": 1
},
{
"fieldname": "column_break_1",
"fieldtype": "Column Break",
"search_index": 1
},
{
"allow_in_quick_entry": 1,
"fieldname": "branch_code",
"fieldtype": "Data",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Branch Code",
"unique": 1
},
{
"fieldname": "address_and_contact",
"fieldtype": "Section Break",
"label": "Address and Contact",
"options": "fa fa-map-marker"
},
{
"fieldname": "address_html",
"fieldtype": "HTML",
"label": "Address HTML"
},
{
"fieldname": "website",
"fieldtype": "Data",
"label": "Website"
},
{
"fieldname": "column_break_13",
"fieldtype": "Column Break"
},
{
"fieldname": "contact_html",
"fieldtype": "HTML",
"label": "Contact HTML"
},
{
"collapsible": 1, "collapsible": 1,
"columns": 0,
"fieldname": "data_import_configuration_section", "fieldname": "data_import_configuration_section",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "label": "Data Import Configuration"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Data Import Configuration",
"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": 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": "bank_transaction_mapping", "fieldname": "bank_transaction_mapping",
"fieldtype": "Table", "fieldtype": "Table",
"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": "Bank Transaction Mapping", "label": "Bank Transaction Mapping",
"length": 0, "options": "Bank Transaction Mapping"
"no_copy": 0,
"options": "Bank Transaction Mapping",
"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": "section_break_4", "fieldname": "section_break_4",
"fieldtype": "Section Break", "fieldtype": "Section Break"
"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,
"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": 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": "plaid_access_token", "fieldname": "plaid_access_token",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 1, "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": "Plaid Access Token", "label": "Plaid Access Token",
"length": 0,
"no_copy": 1, "no_copy": 1,
"permlevel": 0, "read_only": 1
"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, "links": [],
"hide_heading": 0, "modified": "2020-03-25 21:22:33.496264",
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-11-27 16:12:13.938776",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Bank", "name": "Bank",
"name_case": "",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {
"amend": 0,
"cancel": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
"export": 1, "export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "System Manager", "role": "System Manager",
"set_user_permissions": 0,
"share": 1, "share": 1,
"submit": 0,
"write": 1 "write": 1
} }
], ],
"quick_entry": 1, "quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",
"track_changes": 1, "track_changes": 1
"track_seen": 0,
"track_views": 0
} }

View File

@ -5,6 +5,12 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
from frappe.model.document import Document from frappe.model.document import Document
from frappe.contacts.address_and_contact import load_address_and_contact, delete_contact_and_address
class Bank(Document): class Bank(Document):
pass def onload(self):
"""Load address and contacts in `__onload`"""
load_address_and_contact(self)
def on_trash(self):
delete_contact_and_address('Bank', self.name)

View File

@ -24,8 +24,6 @@
"iban", "iban",
"column_break_12", "column_break_12",
"bank_account_no", "bank_account_no",
"branch_code",
"swift_number",
"address_and_contact", "address_and_contact",
"address_html", "address_html",
"website", "website",
@ -145,17 +143,6 @@
"label": "Bank Account No", "label": "Bank Account No",
"length": 30 "length": 30
}, },
{
"fieldname": "branch_code",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Branch Code"
},
{
"fieldname": "swift_number",
"fieldtype": "Data",
"label": "SWIFT number"
},
{ {
"fieldname": "address_and_contact", "fieldname": "address_and_contact",
"fieldtype": "Section Break", "fieldtype": "Section Break",
@ -213,7 +200,7 @@
} }
], ],
"links": [], "links": [],
"modified": "2020-01-29 20:42:26.458316", "modified": "2020-01-30 20:42:26.458316",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Bank Account", "name": "Bank Account",

View File

@ -4,8 +4,8 @@
cur_frm.add_fetch('bank_account','account','account'); cur_frm.add_fetch('bank_account','account','account');
cur_frm.add_fetch('bank_account','bank_account_no','bank_account_no'); cur_frm.add_fetch('bank_account','bank_account_no','bank_account_no');
cur_frm.add_fetch('bank_account','iban','iban'); cur_frm.add_fetch('bank_account','iban','iban');
cur_frm.add_fetch('bank_account','branch_code','branch_code'); cur_frm.add_fetch('bank','branch_code','branch_code');
cur_frm.add_fetch('bank_account','swift_number','swift_number'); cur_frm.add_fetch('bank','swift_number','swift_number');
frappe.ui.form.on('Bank Guarantee', { frappe.ui.form.on('Bank Guarantee', {
setup: function(frm) { setup: function(frm) {

View File

@ -6,6 +6,7 @@ from __future__ import unicode_literals
import frappe, json import frappe, json
from frappe.model.document import Document from frappe.model.document import Document
from frappe import _ from frappe import _
from frappe.desk.search import sanitize_searchfield
class BankGuarantee(Document): class BankGuarantee(Document):
def validate(self): def validate(self):
@ -22,5 +23,8 @@ class BankGuarantee(Document):
@frappe.whitelist() @frappe.whitelist()
def get_vouchar_detials(column_list, doctype, docname): def get_vouchar_detials(column_list, doctype, docname):
column_list = json.loads(column_list)
for col in column_list:
sanitize_searchfield(col)
return frappe.db.sql(''' select {columns} from `tab{doctype}` where name=%s''' return frappe.db.sql(''' select {columns} from `tab{doctype}` where name=%s'''
.format(columns=", ".join(json.loads(column_list)), doctype=doctype), docname, as_dict=1)[0] .format(columns=", ".join(json.loads(column_list)), doctype=doctype), docname, as_dict=1)[0]

View File

@ -32,10 +32,12 @@ frappe.ui.form.on('C-Form Invoice Detail', {
invoice_no(frm, cdt, cdn) { invoice_no(frm, cdt, cdn) {
let d = frappe.get_doc(cdt, cdn); let d = frappe.get_doc(cdt, cdn);
if (d.invoice_no) {
frm.call('get_invoice_details', { frm.call('get_invoice_details', {
invoice_no: d.invoice_no invoice_no: d.invoice_no
}).then(r => { }).then(r => {
frappe.model.set_value(cdt, cdn, r.message); frappe.model.set_value(cdt, cdn, r.message);
}); });
} }
}
}); });

View File

@ -124,11 +124,13 @@
], ],
"icon": "fa fa-money", "icon": "fa fa-money",
"idx": 1, "idx": 1,
"is_tree": 1,
"links": [], "links": [],
"modified": "2020-01-28 13:50:23.430434", "modified": "2020-03-18 17:59:04.321637",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Cost Center", "name": "Cost Center",
"nsm_parent_field": "parent_cost_center",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {

View File

@ -114,13 +114,13 @@
"fieldname": "debit_in_account_currency", "fieldname": "debit_in_account_currency",
"fieldtype": "Currency", "fieldtype": "Currency",
"label": "Debit Amount in Account Currency", "label": "Debit Amount in Account Currency",
"options": "currency" "options": "account_currency"
}, },
{ {
"fieldname": "credit_in_account_currency", "fieldname": "credit_in_account_currency",
"fieldtype": "Currency", "fieldtype": "Currency",
"label": "Credit Amount in Account Currency", "label": "Credit Amount in Account Currency",
"options": "currency" "options": "account_currency"
}, },
{ {
"fieldname": "against", "fieldname": "against",
@ -250,7 +250,7 @@
"icon": "fa fa-list", "icon": "fa fa-list",
"idx": 1, "idx": 1,
"in_create": 1, "in_create": 1,
"modified": "2020-02-10 04:54:57.777905", "modified": "2020-03-28 16:22:33.766994",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "GL Entry", "name": "GL Entry",

View File

@ -233,35 +233,14 @@ def update_outstanding_amt(account, party_type, party, against_voucher_type, aga
frappe.throw(_("Outstanding for {0} cannot be less than zero ({1})").format(against_voucher, fmt_money(bal))) frappe.throw(_("Outstanding for {0} cannot be less than zero ({1})").format(against_voucher, fmt_money(bal)))
if against_voucher_type in ["Sales Invoice", "Purchase Invoice", "Fees"]: if against_voucher_type in ["Sales Invoice", "Purchase Invoice", "Fees"]:
update_outstanding_amt_in_ref(against_voucher, against_voucher_type, bal)
def update_outstanding_amt_in_ref(against_voucher, against_voucher_type, bal):
data = []
# Update outstanding amt on against voucher
if against_voucher_type == "Fees":
ref_doc = frappe.get_doc(against_voucher_type, against_voucher) ref_doc = frappe.get_doc(against_voucher_type, against_voucher)
ref_doc.db_set('outstanding_amount', bal)
ref_doc.set_status(update=True)
return
elif against_voucher_type == "Purchase Invoice":
from erpnext.accounts.doctype.purchase_invoice.purchase_invoice import get_status
data = frappe.db.get_value(against_voucher_type, against_voucher,
["name as purchase_invoice", "outstanding_amount",
"is_return", "due_date", "docstatus"])
elif against_voucher_type == "Sales Invoice":
from erpnext.accounts.doctype.sales_invoice.sales_invoice import get_status
data = frappe.db.get_value(against_voucher_type, against_voucher,
["name as sales_invoice", "outstanding_amount", "is_discounted",
"is_return", "due_date", "docstatus"])
precision = frappe.get_precision(against_voucher_type, "outstanding_amount") # Didn't use db_set for optimisation purpose
data = list(data) ref_doc.outstanding_amount = bal
data.append(precision) frappe.db.set_value(against_voucher_type, against_voucher, 'outstanding_amount', bal)
status = get_status(data)
frappe.db.set_value(against_voucher_type, against_voucher, { ref_doc.set_status(update=True)
'outstanding_amount': bal,
'status': status
})
def validate_frozen_account(account, adv_adj=None): def validate_frozen_account(account, adv_adj=None):
frozen_account = frappe.db.get_value("Account", account, "freeze_account") frozen_account = frappe.db.get_value("Account", account, "freeze_account")

View File

@ -38,6 +38,7 @@ class TestGLEntry(unittest.TestCase):
filters={"voucher_type": "Journal Entry", "voucher_no": je.name}, filters={"voucher_type": "Journal Entry", "voucher_no": je.name},
order_by="creation" order_by="creation"
) )
self.assertTrue(all(entry.to_rename == 1 for entry in gl_entries)) 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] old_naming_series_current_value = frappe.db.sql("SELECT current from tabSeries where name = %s", naming_series)[0][0]

View File

@ -454,8 +454,10 @@ class JournalEntry(AccountsController):
def set_print_format_fields(self): def set_print_format_fields(self):
bank_amount = party_amount = total_amount = 0.0 bank_amount = party_amount = total_amount = 0.0
currency = bank_account_currency = party_account_currency = pay_to_recd_from= None currency = bank_account_currency = party_account_currency = pay_to_recd_from= None
party_type = None
for d in self.get('accounts'): for d in self.get('accounts'):
if d.party_type in ['Customer', 'Supplier'] and d.party: if d.party_type in ['Customer', 'Supplier'] and d.party:
party_type = d.party_type
if not pay_to_recd_from: if not pay_to_recd_from:
pay_to_recd_from = d.party pay_to_recd_from = d.party
@ -467,9 +469,9 @@ class JournalEntry(AccountsController):
bank_amount += (d.debit_in_account_currency or d.credit_in_account_currency) bank_amount += (d.debit_in_account_currency or d.credit_in_account_currency)
bank_account_currency = d.account_currency bank_account_currency = d.account_currency
if pay_to_recd_from: if party_type and pay_to_recd_from:
self.pay_to_recd_from = frappe.db.get_value(d.party_type, pay_to_recd_from, self.pay_to_recd_from = frappe.db.get_value(party_type, pay_to_recd_from,
"customer_name" if d.party_type=="Customer" else "supplier_name") "customer_name" if party_type=="Customer" else "supplier_name")
if bank_amount: if bank_amount:
total_amount = bank_amount total_amount = bank_amount
currency = bank_account_currency currency = bank_account_currency

View File

@ -33,7 +33,9 @@ frappe.ui.form.on('Payment Entry', {
frm.set_query("party_bank_account", function() { frm.set_query("party_bank_account", function() {
return { return {
filters: { filters: {
"is_company_account":0 "is_company_account":0,
party_type: frm.doc.party_type,
party: frm.doc.party
} }
} }
}); });

View File

@ -161,15 +161,15 @@ class TestPaymentEntry(unittest.TestCase):
pe.insert() pe.insert()
pe.submit() pe.submit()
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount")) outstanding_amount, status = frappe.db.get_value("Sales Invoice", si.name, ["outstanding_amount", "status"])
self.assertEqual(outstanding_amount, 0) self.assertEqual(flt(outstanding_amount), 0)
self.assertEqual(si.status, 'Paid') self.assertEqual(status, 'Paid')
pe.cancel() pe.cancel()
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount")) outstanding_amount, status = frappe.db.get_value("Sales Invoice", si.name, ["outstanding_amount", "status"])
self.assertEqual(outstanding_amount, 100) self.assertEqual(flt(outstanding_amount), 100)
self.assertEqual(si.status, 'Unpaid') self.assertEqual(status, 'Unpaid')
def test_payment_against_purchase_invoice_to_check_status(self): def test_payment_against_purchase_invoice_to_check_status(self):
pi = make_purchase_invoice(supplier="_Test Supplier USD", debit_to="_Test Payable USD - _TC", pi = make_purchase_invoice(supplier="_Test Supplier USD", debit_to="_Test Payable USD - _TC",
@ -182,15 +182,15 @@ class TestPaymentEntry(unittest.TestCase):
pe.insert() pe.insert()
pe.submit() pe.submit()
outstanding_amount = flt(frappe.db.get_value("Purchase Invoice", pi.name, "outstanding_amount")) outstanding_amount, status = frappe.db.get_value("Purchase Invoice", pi.name, ["outstanding_amount", "status"])
self.assertEqual(outstanding_amount, 0) self.assertEqual(flt(outstanding_amount), 0)
self.assertEqual(pi.status, 'Paid') self.assertEqual(status, 'Paid')
pe.cancel() pe.cancel()
outstanding_amount = flt(frappe.db.get_value("Purchase Invoice", pi.name, "outstanding_amount")) outstanding_amount, status = frappe.db.get_value("Purchase Invoice", pi.name, ["outstanding_amount", "status"])
self.assertEqual(outstanding_amount, 100) self.assertEqual(flt(outstanding_amount), 250)
self.assertEqual(pi.status, 'Unpaid') self.assertEqual(status, 'Unpaid')
def test_payment_entry_against_ec(self): def test_payment_entry_against_ec(self):

View File

@ -839,7 +839,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_from": "bank_account.branch_code", "fetch_from": "bank.branch_code",
"fieldname": "branch_code", "fieldname": "branch_code",
"fieldtype": "Read Only", "fieldtype": "Read Only",
"hidden": 0, "hidden": 0,
@ -873,7 +873,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_from": "bank_account.swift_number", "fetch_from": "bank.swift_number",
"fieldname": "swift_number", "fieldname": "swift_number",
"fieldtype": "Read Only", "fieldtype": "Read Only",
"hidden": 0, "hidden": 0,

View File

@ -125,27 +125,6 @@ class PurchaseInvoice(BuyingController):
else: else:
self.remarks = _("No Remarks") self.remarks = _("No Remarks")
def set_status(self, update=False, status=None, update_modified=True):
if self.is_new():
if self.get('amended_from'):
self.status = 'Draft'
return
if not status:
precision = self.precision("outstanding_amount")
args = [
self.name,
self.outstanding_amount,
self.is_return,
self.due_date,
self.docstatus,
precision
]
self.status = get_status(args)
if update:
self.db_set('status', self.status, update_modified = update_modified)
def set_missing_values(self, for_validate=False): def set_missing_values(self, for_validate=False):
if not self.credit_to: if not self.credit_to:
self.credit_to = get_party_account("Supplier", self.supplier, self.company) self.credit_to = get_party_account("Supplier", self.supplier, self.company)
@ -1042,34 +1021,6 @@ class PurchaseInvoice(BuyingController):
# calculate totals again after applying TDS # calculate totals again after applying TDS
self.calculate_taxes_and_totals() self.calculate_taxes_and_totals()
def get_status(*args):
purchase_invoice, outstanding_amount, is_return, due_date, docstatus, precision = args[0]
outstanding_amount = flt(outstanding_amount, precision)
due_date = getdate(due_date)
now_date = getdate()
if docstatus == 2:
status = "Cancelled"
elif docstatus == 1:
if outstanding_amount > 0 and due_date < now_date:
status = "Overdue"
elif outstanding_amount > 0 and due_date >= now_date:
status = "Unpaid"
#Check if outstanding amount is 0 due to debit note issued against invoice
elif outstanding_amount <= 0 and is_return == 0 and frappe.db.get_value('Purchase Invoice', {'is_return': 1, 'return_against': purchase_invoice, 'docstatus': 1}):
status = "Debit Note Issued"
elif is_return == 1:
status = "Return"
elif outstanding_amount <=0:
status = "Paid"
else:
status = "Submitted"
else:
status = "Draft"
return status
def get_list_context(context=None): def get_list_context(context=None):
from erpnext.controllers.website_list_for_contact import get_list_context from erpnext.controllers.website_list_for_contact import get_list_context
list_context = get_list_context(context) list_context = get_list_context(context)
@ -1130,3 +1081,6 @@ def block_invoice(name, release_date, hold_comment=None):
def make_inter_company_sales_invoice(source_name, target_doc=None): def make_inter_company_sales_invoice(source_name, target_doc=None):
from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_transaction from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_transaction
return make_inter_company_transaction("Purchase Invoice", source_name, target_doc) return make_inter_company_transaction("Purchase Invoice", source_name, target_doc)
def on_doctype_update():
frappe.db.add_index("Purchase Invoice", ["supplier", "is_return", "return_against"])

View File

@ -63,6 +63,7 @@
"warehouse_section", "warehouse_section",
"warehouse", "warehouse",
"rejected_warehouse", "rejected_warehouse",
"from_warehouse",
"quality_inspection", "quality_inspection",
"batch_no", "batch_no",
"col_br_wh", "col_br_wh",
@ -761,16 +762,22 @@
"fetch_from": "item_code.asset_category", "fetch_from": "item_code.asset_category",
"fieldname": "asset_category", "fieldname": "asset_category",
"fieldtype": "Data", "fieldtype": "Data",
"in_preview": 1,
"label": "Asset Category", "label": "Asset Category",
"options": "Asset Category", "options": "Asset Category",
"read_only": 1 "read_only": 1
},
{
"fieldname": "from_warehouse",
"fieldtype": "Link",
"ignore_user_permissions": 1,
"label": "Supplier Warehouse",
"options": "Warehouse"
} }
], ],
"idx": 1, "idx": 1,
"istable": 1, "istable": 1,
"links": [], "links": [],
"modified": "2020-03-05 14:20:17.297284", "modified": "2020-03-11 14:20:17.297284",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Purchase Invoice Item", "name": "Purchase Invoice Item",

View File

@ -207,7 +207,7 @@ def get_customers_list(pos_profile={}):
if pos_profile.get('customer_groups'): if pos_profile.get('customer_groups'):
# Get customers based on the customer groups defined in the POS profile # Get customers based on the customer groups defined in the POS profile
for d in pos_profile.get('customer_groups'): for d in pos_profile.get('customer_groups'):
customer_groups.extend([d.name for d in get_child_nodes('Customer Group', d.customer_group)]) customer_groups.extend([d.get('name') for d in get_child_nodes('Customer Group', d.get('customer_group'))])
cond = "customer_group in (%s)" % (', '.join(['%s'] * len(customer_groups))) cond = "customer_group in (%s)" % (', '.join(['%s'] * len(customer_groups)))
return frappe.db.sql(""" select name, customer_name, customer_group, return frappe.db.sql(""" select name, customer_name, customer_group,
@ -387,7 +387,9 @@ def get_pricing_rule_data(doc):
@frappe.whitelist() @frappe.whitelist()
def make_invoice(doc_list={}, email_queue_list={}, customers_list={}): def make_invoice(pos_profile, doc_list={}, email_queue_list={}, customers_list={}):
import json
if isinstance(doc_list, string_types): if isinstance(doc_list, string_types):
doc_list = json.loads(doc_list) doc_list = json.loads(doc_list)
@ -421,7 +423,11 @@ def make_invoice(doc_list={}, email_queue_list={}, customers_list={}):
name_list.append(name) name_list.append(name)
email_queue = make_email_queue(email_queue_list) email_queue = make_email_queue(email_queue_list)
customers = get_customers_list()
if isinstance(pos_profile, string_types):
pos_profile = json.loads(pos_profile)
customers = get_customers_list(pos_profile)
return { return {
'invoice': name_list, 'invoice': name_list,
'email_queue': email_queue, 'email_queue': email_queue,

View File

@ -1228,18 +1228,38 @@ class SalesInvoice(SellingController):
self.status = 'Draft' self.status = 'Draft'
return return
if not status:
precision = self.precision("outstanding_amount") precision = self.precision("outstanding_amount")
args = [ outstanding_amount = flt(self.outstanding_amount, precision)
self.name, due_date = getdate(self.due_date)
self.outstanding_amount, nowdate = getdate()
self.is_discounted,
self.is_return, discounting_status = None
self.due_date, if self.is_discounted:
self.docstatus, discountng_status = get_discounting_status(self.name)
precision,
] if not status:
self.status = get_status(args) if self.docstatus == 2:
status = "Cancelled"
elif self.docstatus == 1:
if outstanding_amount > 0 and due_date < nowdate and self.is_discounted and discountng_status=='Disbursed':
self.status = "Overdue and Discounted"
elif outstanding_amount > 0 and due_date < nowdate:
self.status = "Overdue"
elif outstanding_amount > 0 and due_date >= nowdate and self.is_discounted and discountng_status=='Disbursed':
self.status = "Unpaid and Discounted"
elif outstanding_amount > 0 and due_date >= nowdate:
self.status = "Unpaid"
#Check if outstanding amount is 0 due to credit note issued against invoice
elif outstanding_amount <= 0 and self.is_return == 0 and frappe.db.get_value('Sales Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1}):
self.status = "Credit Note Issued"
elif self.is_return == 1:
self.status = "Return"
elif outstanding_amount<=0:
self.status = "Paid"
else:
self.status = "Submitted"
else:
self.status = "Draft"
if update: if update:
self.db_set('status', self.status, update_modified = update_modified) self.db_set('status', self.status, update_modified = update_modified)
@ -1264,42 +1284,6 @@ def get_discounting_status(sales_invoice):
return status return status
def get_status(*args):
sales_invoice, outstanding_amount, is_discounted, is_return, due_date, docstatus, precision = args[0]
discounting_status = None
if is_discounted:
discounting_status = get_discounting_status(sales_invoice)
outstanding_amount = flt(outstanding_amount, precision)
due_date = getdate(due_date)
now_date = getdate()
if docstatus == 2:
status = "Cancelled"
elif docstatus == 1:
if outstanding_amount > 0 and due_date < now_date and is_discounted and discounting_status=='Disbursed':
status = "Overdue and Discounted"
elif outstanding_amount > 0 and due_date < now_date:
status = "Overdue"
elif outstanding_amount > 0 and due_date >= now_date and is_discounted and discounting_status=='Disbursed':
status = "Unpaid and Discounted"
elif outstanding_amount > 0 and due_date >= now_date:
status = "Unpaid"
#Check if outstanding amount is 0 due to credit note issued against invoice
elif outstanding_amount <= 0 and is_return == 0 and frappe.db.get_value('Sales Invoice', {'is_return': 1, 'return_against': sales_invoice, 'docstatus': 1}):
status = "Credit Note Issued"
elif is_return == 1:
status = "Return"
elif outstanding_amount <=0:
status = "Paid"
else:
status = "Submitted"
else:
status = "Draft"
return status
def validate_inter_company_party(doctype, party, company, inter_company_reference): def validate_inter_company_party(doctype, party, company, inter_company_reference):
if not party: if not party:
return return

View File

@ -786,7 +786,7 @@ class TestSalesInvoice(unittest.TestCase):
def test_make_pos_invoice(self): def test_make_pos_invoice(self):
from erpnext.accounts.doctype.sales_invoice.pos import make_invoice from erpnext.accounts.doctype.sales_invoice.pos import make_invoice
make_pos_profile() pos_profile = make_pos_profile()
pr = make_purchase_receipt(company= "_Test Company with perpetual inventory",supplier_warehouse= "Work In Progress - TCP1", item_code= "_Test FG Item",warehouse= "Stores - TCP1",cost_center= "Main - TCP1") pr = make_purchase_receipt(company= "_Test Company with perpetual inventory",supplier_warehouse= "Work In Progress - TCP1", item_code= "_Test FG Item",warehouse= "Stores - TCP1",cost_center= "Main - TCP1")
pos = create_sales_invoice(company= "_Test Company with perpetual inventory", debit_to="Debtors - TCP1", item_code= "_Test FG Item", warehouse="Stores - TCP1", income_account = "Sales - TCP1", expense_account = "Cost of Goods Sold - TCP1", cost_center = "Main - TCP1", do_not_save=True) pos = create_sales_invoice(company= "_Test Company with perpetual inventory", debit_to="Debtors - TCP1", item_code= "_Test FG Item", warehouse="Stores - TCP1", income_account = "Sales - TCP1", expense_account = "Cost of Goods Sold - TCP1", cost_center = "Main - TCP1", do_not_save=True)
@ -802,7 +802,7 @@ class TestSalesInvoice(unittest.TestCase):
pos.append("taxes", tax) pos.append("taxes", tax)
invoice_data = [{'09052016142': pos}] invoice_data = [{'09052016142': pos}]
si = make_invoice(invoice_data).get('invoice') si = make_invoice(pos_profile, invoice_data).get('invoice')
self.assertEqual(si[0], '09052016142') self.assertEqual(si[0], '09052016142')
sales_invoice = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': '09052016142', 'docstatus': 1}) sales_invoice = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': '09052016142', 'docstatus': 1})
@ -820,7 +820,7 @@ class TestSalesInvoice(unittest.TestCase):
if allow_negative_stock: if allow_negative_stock:
frappe.db.set_value('Stock Settings', None, 'allow_negative_stock', 0) frappe.db.set_value('Stock Settings', None, 'allow_negative_stock', 0)
make_pos_profile() pos_profile = make_pos_profile()
timestamp = cint(time.time()) timestamp = cint(time.time())
item = make_item("_Test POS Item") item = make_item("_Test POS Item")
@ -834,7 +834,7 @@ class TestSalesInvoice(unittest.TestCase):
{'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 330}] {'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 330}]
invoice_data = [{timestamp: pos}] invoice_data = [{timestamp: pos}]
si = make_invoice(invoice_data).get('invoice') si = make_invoice(pos_profile, invoice_data).get('invoice')
self.assertEqual(si[0], timestamp) self.assertEqual(si[0], timestamp)
sales_invoice = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': timestamp}) sales_invoice = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': timestamp})
@ -843,7 +843,7 @@ class TestSalesInvoice(unittest.TestCase):
timestamp = cint(time.time()) timestamp = cint(time.time())
pos["offline_pos_name"] = timestamp pos["offline_pos_name"] = timestamp
invoice_data = [{timestamp: pos}] invoice_data = [{timestamp: pos}]
si1 = make_invoice(invoice_data).get('invoice') si1 = make_invoice(pos_profile, invoice_data).get('invoice')
self.assertEqual(si1[0], timestamp) self.assertEqual(si1[0], timestamp)
sales_invoice1 = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': timestamp}) sales_invoice1 = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': timestamp})

View File

@ -136,12 +136,11 @@ def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False):
def make_entry(args, adv_adj, update_outstanding, from_repost=False): def make_entry(args, adv_adj, update_outstanding, from_repost=False):
args.update({"doctype": "GL Entry"}) gle = frappe.new_doc("GL Entry")
gle = frappe.get_doc(args) gle.update(args)
gle.flags.ignore_permissions = 1 gle.flags.ignore_permissions = 1
gle.flags.from_repost = from_repost gle.flags.from_repost = from_repost
gle.validate() gle.validate()
gle.flags.ignore_permissions = True
gle.db_insert() gle.db_insert()
gle.run_method("on_update_with_args", adv_adj, update_outstanding, from_repost) gle.run_method("on_update_with_args", adv_adj, update_outstanding, from_repost)
gle.flags.ignore_validate = True gle.flags.ignore_validate = True

View File

@ -1769,6 +1769,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
method: "erpnext.accounts.doctype.sales_invoice.pos.make_invoice", method: "erpnext.accounts.doctype.sales_invoice.pos.make_invoice",
freeze: true, freeze: true,
args: { args: {
pos_profile: me.pos_profile_data,
doc_list: me.si_docs, doc_list: me.si_docs,
email_queue_list: me.email_queue_list, email_queue_list: me.email_queue_list,
customers_list: me.customers_list customers_list: me.customers_list

View File

@ -218,15 +218,15 @@
<td></td> <td></td>
<td style="text-align: right"><b>{%= __("Total") %}</b></td> <td style="text-align: right"><b>{%= __("Total") %}</b></td>
<td style="text-align: right"> <td style="text-align: right">
{%= format_currency(data[i]["invoiced"], data[i]["currency"] ) %}</td> {%= format_currency(data[i]["invoiced"], data[0]["currency"] ) %}</td>
{% if(!filters.show_future_payments) { %} {% if(!filters.show_future_payments) { %}
<td style="text-align: right"> <td style="text-align: right">
{%= format_currency(data[i]["paid"], data[i]["currency"]) %}</td> {%= format_currency(data[i]["paid"], data[0]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i]["credit_note"], data[i]["currency"]) %} </td> <td style="text-align: right">{%= format_currency(data[i]["credit_note"], data[0]["currency"]) %} </td>
{% } %} {% } %}
<td style="text-align: right"> <td style="text-align: right">
{%= format_currency(data[i]["outstanding"], data[i]["currency"]) %}</td> {%= format_currency(data[i]["outstanding"], data[0]["currency"]) %}</td>
{% if(filters.show_future_payments) { %} {% if(filters.show_future_payments) { %}
{% if(report.report_name === "Accounts Receivable") { %} {% if(report.report_name === "Accounts Receivable") { %}
@ -234,8 +234,8 @@
{%= data[i]["po_no"] %}</td> {%= data[i]["po_no"] %}</td>
{% } %} {% } %}
<td style="text-align: right">{%= data[i]["future_ref"] %}</td> <td style="text-align: right">{%= data[i]["future_ref"] %}</td>
<td style="text-align: right">{%= format_currency(data[i]["future_amount"], data[i]["currency"]) %}</td> <td style="text-align: right">{%= format_currency(data[i]["future_amount"], data[0]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i]["remaining_balance"], data[i]["currency"]) %}</td> <td style="text-align: right">{%= format_currency(data[i]["remaining_balance"], data[0]["currency"]) %}</td>
{% } %} {% } %}
{% } %} {% } %}
{% } else { %} {% } else { %}
@ -256,10 +256,10 @@
{% } else { %} {% } else { %}
<td><b>{%= __("Total") %}</b></td> <td><b>{%= __("Total") %}</b></td>
{% } %} {% } %}
<td style="text-align: right">{%= format_currency(data[i]["invoiced"], data[i]["currency"]) %}</td> <td style="text-align: right">{%= format_currency(data[i]["invoiced"], data[0]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i]["paid"], data[i]["currency"]) %}</td> <td style="text-align: right">{%= format_currency(data[i]["paid"], data[0]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i]["credit_note"], data[i]["currency"]) %}</td> <td style="text-align: right">{%= format_currency(data[i]["credit_note"], data[0]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i]["outstanding"], data[i]["currency"]) %}</td> <td style="text-align: right">{%= format_currency(data[i]["outstanding"], data[0]["currency"]) %}</td>
{% } %} {% } %}
{% } %} {% } %}
</tr> </tr>

View File

@ -7,7 +7,7 @@ from frappe import _, scrub
from frappe.utils import getdate, nowdate, flt, cint, formatdate, cstr, now, time_diff_in_seconds from frappe.utils import getdate, nowdate, flt, cint, formatdate, cstr, now, time_diff_in_seconds
from collections import OrderedDict from collections import OrderedDict
from erpnext.accounts.utils import get_currency_precision from erpnext.accounts.utils import get_currency_precision
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
# This report gives a summary of all Outstanding Invoices considering the following # This report gives a summary of all Outstanding Invoices considering the following
@ -603,7 +603,6 @@ class ReceivablePayableReport(object):
self.add_supplier_filters(conditions, values) self.add_supplier_filters(conditions, values)
self.add_accounting_dimensions_filters(conditions, values) self.add_accounting_dimensions_filters(conditions, values)
return " and ".join(conditions), values return " and ".join(conditions), values
def get_order_by_condition(self): def get_order_by_condition(self):
@ -666,13 +665,16 @@ class ReceivablePayableReport(object):
doctype=doctype, lft=lft, rgt=rgt, key=key) doctype=doctype, lft=lft, rgt=rgt, key=key)
def add_accounting_dimensions_filters(self, conditions, values): def add_accounting_dimensions_filters(self, conditions, values):
accounting_dimensions = get_accounting_dimensions() accounting_dimensions = get_accounting_dimensions(as_list=False)
if accounting_dimensions: if accounting_dimensions:
for dimension in accounting_dimensions: for dimension in accounting_dimensions:
if self.filters.get(dimension): if self.filters.get(dimension.fieldname):
conditions.append("{0} = %s".format(dimension)) if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
values.append(self.filters.get(dimension)) self.filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
self.filters.get(dimension.fieldname))
conditions.append("{0} in %s".format(dimension.fieldname))
values.append(tuple(self.filters.get(dimension.fieldname)))
def get_gle_balance(self, gle): def get_gle_balance(self, gle):
# get the balance of the GL (debit - credit) or reverse balance based on report type # get the balance of the GL (debit - credit) or reverse balance based on report type

View File

@ -16,7 +16,7 @@ from frappe import _
from frappe.utils import (flt, getdate, get_first_day, add_months, add_days, formatdate, cstr) from frappe.utils import (flt, getdate, get_first_day, add_months, add_days, formatdate, cstr)
from six import itervalues from six import itervalues
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_values=False, def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_values=False,
company=None, reset_period_on_fy_change=True): company=None, reset_period_on_fy_change=True):
@ -389,7 +389,7 @@ def set_gl_entries_by_account(
def get_additional_conditions(from_date, ignore_closing_entries, filters): def get_additional_conditions(from_date, ignore_closing_entries, filters):
additional_conditions = [] additional_conditions = []
accounting_dimensions = get_accounting_dimensions() accounting_dimensions = get_accounting_dimensions(as_list=False)
if ignore_closing_entries: if ignore_closing_entries:
additional_conditions.append("ifnull(voucher_type, '')!='Period Closing Voucher'") additional_conditions.append("ifnull(voucher_type, '')!='Period Closing Voucher'")
@ -415,8 +415,11 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters):
if accounting_dimensions: if accounting_dimensions:
for dimension in accounting_dimensions: for dimension in accounting_dimensions:
if filters.get(dimension): if filters.get(dimension.fieldname):
additional_conditions.append("{0} in (%({0})s)".format(dimension)) if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
filters.get(dimension.fieldname))
additional_conditions.append("{0} in %({0})s".format(dimension.fieldname))
return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else "" return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else ""

View File

@ -2,7 +2,7 @@
<h4 class="text-center"> <h4 class="text-center">
{% if (filters.party_name) { %} {% if (filters.party_name) { %}
{%= filters.party_name %} {%= filters.party_name %}
{% } else if (filters.party && filters.show_name) { %} {% } else if (filters.party) { %}
{%= filters.party %} {%= filters.party %}
{% } else if (filters.account) { %} {% } else if (filters.account) { %}
{%= filters.account %} {%= filters.account %}

View File

@ -10,7 +10,7 @@ from frappe import _, _dict
from erpnext.accounts.utils import get_account_currency from erpnext.accounts.utils import get_account_currency
from erpnext.accounts.report.financial_statements import get_cost_centers_with_children from erpnext.accounts.report.financial_statements import get_cost_centers_with_children
from six import iteritems from six import iteritems
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
from collections import OrderedDict from collections import OrderedDict
def execute(filters=None): def execute(filters=None):
@ -131,7 +131,7 @@ def get_gl_entries(filters):
gl_entries = frappe.db.sql( gl_entries = frappe.db.sql(
""" """
select select
posting_date, account, party_type, party, name as gl_entry, posting_date, account, party_type, party,
voucher_type, voucher_no, cost_center, project, voucher_type, voucher_no, cost_center, project,
against_voucher_type, against_voucher, account_currency, against_voucher_type, against_voucher, account_currency,
remarks, against, is_opening {select_fields} remarks, against, is_opening {select_fields}
@ -194,12 +194,15 @@ def get_conditions(filters):
if match_conditions: if match_conditions:
conditions.append(match_conditions) conditions.append(match_conditions)
accounting_dimensions = get_accounting_dimensions() accounting_dimensions = get_accounting_dimensions(as_list=False)
if accounting_dimensions: if accounting_dimensions:
for dimension in accounting_dimensions: for dimension in accounting_dimensions:
if filters.get(dimension): if filters.get(dimension.fieldname):
conditions.append("{0} in (%({0})s)".format(dimension)) if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
filters.get(dimension.fieldname))
conditions.append("{0} in %({0})s".format(dimension.fieldname))
return "and {}".format(" and ".join(conditions)) if conditions else "" return "and {}".format(" and ".join(conditions)) if conditions else ""
@ -359,6 +362,12 @@ def get_columns(filters):
currency = get_company_currency(company) currency = get_company_currency(company)
columns = [ columns = [
{
"fieldname": "gl_entry",
"fieldtype": "Link",
"options": "GL Entry",
"hidden": 1
},
{ {
"label": _("Posting Date"), "label": _("Posting Date"),
"fieldname": "posting_date", "fieldname": "posting_date",

View File

@ -54,8 +54,8 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
'description': d.description, 'description': d.description,
'invoice': d.parent, 'invoice': d.parent,
'posting_date': d.posting_date, 'posting_date': d.posting_date,
'customer': d.supplier, 'supplier': d.supplier,
'customer_name': d.supplier_name 'supplier_name': d.supplier_name
} }
if additional_query_columns: if additional_query_columns:
@ -201,7 +201,8 @@ def get_columns(additional_table_columns, filters):
{ {
'label': _('Mode Of Payment'), 'label': _('Mode Of Payment'),
'fieldname': 'mode_of_payment', 'fieldname': 'mode_of_payment',
'fieldtype': 'Data', 'fieldtype': 'Link',
'options': 'Mode of Payment',
'width': 120 'width': 120
}, },
{ {
@ -309,6 +310,8 @@ def get_items(filters, additional_query_columns):
if additional_query_columns: if additional_query_columns:
additional_query_columns = ', ' + ', '.join(additional_query_columns) additional_query_columns = ', ' + ', '.join(additional_query_columns)
else:
additional_query_columns = ''
return frappe.db.sql(""" return frappe.db.sql("""
select select
@ -320,7 +323,7 @@ def get_items(filters, additional_query_columns):
`tabPurchase Invoice Item`.`purchase_receipt`, `tabPurchase Invoice Item`.`po_detail`, `tabPurchase Invoice Item`.`purchase_receipt`, `tabPurchase Invoice Item`.`po_detail`,
`tabPurchase Invoice Item`.`expense_account`, `tabPurchase Invoice Item`.`stock_qty`, `tabPurchase Invoice Item`.`expense_account`, `tabPurchase Invoice Item`.`stock_qty`,
`tabPurchase Invoice Item`.`stock_uom`, `tabPurchase Invoice Item`.`base_net_amount`, `tabPurchase Invoice Item`.`stock_uom`, `tabPurchase Invoice Item`.`base_net_amount`,
`tabPurchase Invoice`.supplier_name, `tabPurchase Invoice`.mode_of_payment {0} `tabPurchase Invoice`.`supplier_name`, `tabPurchase Invoice`.`mode_of_payment` {0}
from `tabPurchase Invoice`, `tabPurchase Invoice Item` from `tabPurchase Invoice`, `tabPurchase Invoice Item`
where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and
`tabPurchase Invoice`.docstatus = 1 %s `tabPurchase Invoice`.docstatus = 1 %s

View File

@ -373,6 +373,8 @@ def get_items(filters, additional_query_columns):
if additional_query_columns: if additional_query_columns:
additional_query_columns = ', ' + ', '.join(additional_query_columns) additional_query_columns = ', ' + ', '.join(additional_query_columns)
else:
additional_query_columns = ''
return frappe.db.sql(""" return frappe.db.sql("""
select select

View File

@ -6,7 +6,7 @@ import frappe
from frappe.utils import flt from frappe.utils import flt
from frappe import msgprint, _ from frappe import msgprint, _
from frappe.model.meta import get_field_precision from frappe.model.meta import get_field_precision
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
def execute(filters=None): def execute(filters=None):
return _execute(filters) return _execute(filters)
@ -341,14 +341,18 @@ def get_conditions(filters):
where parent=`tabSales Invoice`.name where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s)""" and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s)"""
accounting_dimensions = get_accounting_dimensions() accounting_dimensions = get_accounting_dimensions(as_list=False)
if accounting_dimensions: if accounting_dimensions:
for dimension in accounting_dimensions: for dimension in accounting_dimensions:
if filters.get(dimension): if filters.get(dimension.fieldname):
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
filters.get(dimension.fieldname))
conditions += """ and exists(select name from `tabSales Invoice Item` conditions += """ and exists(select name from `tabSales Invoice Item`
where parent=`tabSales Invoice`.name where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Item`.{0}, '') = %({0})s)""".format(dimension) and ifnull(`tabSales Invoice Item`.{0}, '') in %({0})s)""".format(dimension.fieldname)
return conditions return conditions

View File

@ -7,7 +7,7 @@ from frappe import _
from frappe.utils import flt, getdate, formatdate, cstr from frappe.utils import flt, getdate, formatdate, cstr
from erpnext.accounts.report.financial_statements \ from erpnext.accounts.report.financial_statements \
import filter_accounts, set_gl_entries_by_account, filter_out_zero_value_rows import filter_accounts, set_gl_entries_by_account, filter_out_zero_value_rows
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
value_fields = ("opening_debit", "opening_credit", "debit", "credit", "closing_debit", "closing_credit") value_fields = ("opening_debit", "opening_credit", "debit", "credit", "closing_debit", "closing_credit")
@ -109,7 +109,7 @@ def get_rootwise_opening_balances(filters, report_type):
additional_conditions += fb_conditions additional_conditions += fb_conditions
accounting_dimensions = get_accounting_dimensions() accounting_dimensions = get_accounting_dimensions(as_list=False)
query_filters = { query_filters = {
"company": filters.company, "company": filters.company,
@ -122,11 +122,14 @@ def get_rootwise_opening_balances(filters, report_type):
if accounting_dimensions: if accounting_dimensions:
for dimension in accounting_dimensions: for dimension in accounting_dimensions:
if filters.get(dimension): if filters.get(dimension.fieldname):
additional_conditions += """ and {0} in (%({0})s) """.format(dimension) if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
filters.get(dimension.fieldname))
additional_conditions += "and {0} in %({0})s".format(dimension.fieldname)
query_filters.update({ query_filters.update({
dimension: filters.get(dimension) dimension.fieldname: filters.get(dimension.fieldname)
}) })
gle = frappe.db.sql(""" gle = frappe.db.sql("""

View File

@ -0,0 +1,36 @@
{
"cards": [
{
"links": "[\n {\n \"label\": \"Crop\",\n \"name\": \"Crop\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Crop Cycle\",\n \"name\": \"Crop Cycle\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Location\",\n \"name\": \"Location\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]",
"title": "Crops & Lands"
},
{
"links": "[\n {\n \"label\": \"Plant Analysis\",\n \"name\": \"Plant Analysis\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Soil Analysis\",\n \"name\": \"Soil Analysis\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Water Analysis\",\n \"name\": \"Water Analysis\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Soil Texture\",\n \"name\": \"Soil Texture\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Weather\",\n \"name\": \"Weather\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Agriculture Analysis Criteria\",\n \"name\": \"Agriculture Analysis Criteria\",\n \"type\": \"doctype\"\n }\n]",
"title": "Analytics"
},
{
"links": "[\n {\n \"label\": \"Disease\",\n \"name\": \"Disease\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fertilizer\",\n \"name\": \"Fertilizer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]",
"title": "Diseases & Fertilizers"
}
],
"category": "Domains",
"charts": [],
"creation": "2020-03-02 17:23:34.339274",
"developer_mode_only": 0,
"disable_user_customization": 0,
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
"idx": 0,
"is_standard": 1,
"label": "Agriculture",
"modified": "2020-03-12 16:30:37.565413",
"modified_by": "Administrator",
"module": "Agriculture",
"name": "Agriculture",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"restrict_to_domain": "Agriculture",
"shortcuts": []
}

View File

@ -0,0 +1,53 @@
{
"cards": [
{
"links": "[\n {\n \"label\": \"Asset\",\n \"name\": \"Asset\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Location\",\n \"name\": \"Location\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Asset Category\",\n \"name\": \"Asset Category\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Transfer an asset from one warehouse to another\",\n \"label\": \"Asset Movement\",\n \"name\": \"Asset Movement\",\n \"type\": \"doctype\"\n }\n]",
"title": "Assets"
},
{
"links": "[\n {\n \"label\": \"Asset Maintenance Team\",\n \"name\": \"Asset Maintenance Team\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Asset Maintenance Team\"\n ],\n \"label\": \"Asset Maintenance\",\n \"name\": \"Asset Maintenance\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Asset Maintenance\"\n ],\n \"label\": \"Asset Maintenance Log\",\n \"name\": \"Asset Maintenance Log\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Asset\"\n ],\n \"label\": \"Asset Value Adjustment\",\n \"name\": \"Asset Value Adjustment\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Asset\"\n ],\n \"label\": \"Asset Repair\",\n \"name\": \"Asset Repair\",\n \"type\": \"doctype\"\n }\n]",
"title": "Maintenance"
},
{
"icon": "fa fa-table",
"links": "[\n {\n \"dependencies\": [\n \"Asset\"\n ],\n \"doctype\": \"Asset\",\n \"is_query_report\": true,\n \"label\": \"Asset Depreciation Ledger\",\n \"name\": \"Asset Depreciation Ledger\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Asset\"\n ],\n \"doctype\": \"Asset\",\n \"is_query_report\": true,\n \"label\": \"Asset Depreciations and Balances\",\n \"name\": \"Asset Depreciations and Balances\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Asset Maintenance\"\n ],\n \"doctype\": \"Asset Maintenance\",\n \"label\": \"Asset Maintenance\",\n \"name\": \"Asset Maintenance\",\n \"type\": \"report\"\n }\n]",
"title": "Reports"
}
],
"category": "Modules",
"charts": [],
"creation": "2020-03-02 15:43:27.634865",
"developer_mode_only": 0,
"disable_user_customization": 0,
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
"icon": "",
"idx": 0,
"is_standard": 1,
"label": "Assets",
"modified": "2020-03-12 16:30:38.651019",
"modified_by": "Administrator",
"module": "Assets",
"name": "Assets",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"shortcuts": [
{
"is_query_report": 0,
"link_to": "Asset",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Asset Movement",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Fixed Asset Register",
"type": "Report"
}
]
}

View File

@ -139,12 +139,14 @@
"read_only": 1 "read_only": 1
} }
], ],
"is_tree": 1,
"links": [], "links": [],
"modified": "2020-01-28 13:52:22.513425", "modified": "2020-03-18 18:00:08.885805",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Assets", "module": "Assets",
"name": "Location", "name": "Location",
"name_case": "Title Case", "name_case": "Title Case",
"nsm_parent_field": "parent_location",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {
@ -218,6 +220,8 @@
"write": 1 "write": 1
} }
], ],
"quick_entry": 1,
"restrict_to_domain": "Agriculture",
"show_name_in_global_search": 1, "show_name_in_global_search": 1,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",

View File

@ -0,0 +1,92 @@
{
"cards": [
{
"links": "[\n {\n \"description\": \"Supplier database.\",\n \"label\": \"Supplier\",\n \"name\": \"Supplier\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Supplier Group master.\",\n \"label\": \"Supplier Group\",\n \"name\": \"Supplier Group\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Contacts.\",\n \"label\": \"Contact\",\n \"name\": \"Contact\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Addresses.\",\n \"label\": \"Address\",\n \"name\": \"Address\",\n \"type\": \"doctype\"\n }\n]",
"title": "Supplier"
},
{
"icon": "fa fa-star",
"links": "[\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"description\": \"Purchase Orders given to Suppliers.\",\n \"label\": \"Purchase Order\",\n \"name\": \"Purchase Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"label\": \"Purchase Invoice\",\n \"name\": \"Purchase Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Request for purchase.\",\n \"label\": \"Material Request\",\n \"name\": \"Material Request\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"description\": \"Request for quotation.\",\n \"label\": \"Request for Quotation\",\n \"name\": \"Request for Quotation\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"description\": \"Quotations received from Suppliers.\",\n \"label\": \"Supplier Quotation\",\n \"name\": \"Supplier Quotation\",\n \"type\": \"doctype\"\n }\n]",
"title": "Purchasing"
},
{
"links": "[\n {\n \"description\": \"All Products or Services.\",\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Multiple Item prices.\",\n \"label\": \"Item Price\",\n \"name\": \"Item Price\",\n \"onboard\": 1,\n \"route\": \"#Report/Item Price\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Price List master.\",\n \"label\": \"Price List\",\n \"name\": \"Price List\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bundle items at time of sale.\",\n \"label\": \"Product Bundle\",\n \"name\": \"Product Bundle\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of Item Groups.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Item Group\",\n \"link\": \"Tree/Item Group\",\n \"name\": \"Item Group\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Rules for applying different promotional schemes.\",\n \"label\": \"Promotional Scheme\",\n \"name\": \"Promotional Scheme\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Rules for applying pricing and discount.\",\n \"label\": \"Pricing Rule\",\n \"name\": \"Pricing Rule\",\n \"type\": \"doctype\"\n }\n]",
"title": "Items and Pricing"
},
{
"icon": "fa fa-cog",
"links": "[\n {\n \"description\": \"Default settings for buying transactions.\",\n \"label\": \"Buying Settings\",\n \"name\": \"Buying Settings\",\n \"settings\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for buying transactions.\",\n \"label\": \"Purchase Taxes and Charges Template\",\n \"name\": \"Purchase Taxes and Charges Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Template of terms or contract.\",\n \"label\": \"Terms and Conditions Template\",\n \"name\": \"Terms and Conditions\",\n \"type\": \"doctype\"\n }\n]",
"title": "Settings"
},
{
"links": "[\n {\n \"description\": \"All Supplier scorecards.\",\n \"label\": \"Supplier Scorecard\",\n \"name\": \"Supplier Scorecard\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Templates of supplier scorecard variables.\",\n \"label\": \"Supplier Scorecard Variable\",\n \"name\": \"Supplier Scorecard Variable\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Templates of supplier scorecard criteria.\",\n \"label\": \"Supplier Scorecard Criteria\",\n \"name\": \"Supplier Scorecard Criteria\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Templates of supplier standings.\",\n \"label\": \"Supplier Scorecard Standing\",\n \"name\": \"Supplier Scorecard Standing\",\n \"type\": \"doctype\"\n }\n]",
"title": "Supplier Scorecard"
},
{
"icon": "fa fa-table",
"links": "[\n {\n \"is_query_report\": true,\n \"label\": \"Purchase Analytics\",\n \"name\": \"Purchase Analytics\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Supplier-Wise Sales Analytics\",\n \"name\": \"Supplier-Wise Sales Analytics\",\n \"onboard\": 1,\n \"reference_doctype\": \"Stock Ledger Entry\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Purchase Order Trends\",\n \"name\": \"Purchase Order Trends\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Procurement Tracker\",\n \"name\": \"Procurement Tracker\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Requested Items To Be Ordered\",\n \"name\": \"Requested Items To Be Ordered\",\n \"onboard\": 1,\n \"reference_doctype\": \"Material Request\",\n \"type\": \"report\"\n }\n]",
"title": "Key Reports"
},
{
"icon": "fa fa-list",
"links": "[\n {\n \"is_query_report\": true,\n \"label\": \"Items To Be Requested\",\n \"name\": \"Items To Be Requested\",\n \"onboard\": 1,\n \"reference_doctype\": \"Item\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Item-wise Purchase History\",\n \"name\": \"Item-wise Purchase History\",\n \"onboard\": 1,\n \"reference_doctype\": \"Item\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Material Requests for which Supplier Quotations are not created\",\n \"name\": \"Material Requests for which Supplier Quotations are not created\",\n \"reference_doctype\": \"Material Request\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Supplier Addresses And Contacts\",\n \"name\": \"Address And Contacts\",\n \"reference_doctype\": \"Address\",\n \"route_options\": {\n \"party_type\": \"Supplier\"\n },\n \"type\": \"report\"\n }\n]",
"title": "Other Reports"
}
],
"category": "Modules",
"charts": [
{
"chart_name": "Expenses",
"label": "Expenses",
"size": "Full"
}
],
"creation": "2020-01-28 11:50:26.195467",
"developer_mode_only": 0,
"disable_user_customization": 0,
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
"icon": "",
"idx": 0,
"is_standard": 1,
"label": "Buying",
"modified": "2020-03-12 16:30:40.779078",
"modified_by": "Administrator",
"module": "Buying",
"name": "Buying",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"shortcuts": [
{
"format": "{} Unpaid",
"is_query_report": 0,
"link_to": "Purchase Invoice",
"stats_filter": "{\n \"company\": [\"like\", '%' + frappe.defaults.get_global_default(\"company\") + '%'],\n \"status\": \"Unpaid\"\n}",
"type": "DocType"
},
{
"format": "{} to receive",
"is_query_report": 0,
"link_to": "Purchase Order",
"stats_filter": "{\n \"company\": [\"like\", '%' + frappe.defaults.get_global_default(\"company\") + '%'],\n \"status\": \"To Receive\"\n}",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Supplier Quotation",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Accounts Payable",
"type": "Report"
},
{
"is_query_report": 0,
"link_to": "Purchase Register",
"type": "Report"
}
]
}

View File

@ -0,0 +1,22 @@
{
"cards": [],
"charts": [],
"creation": "2020-01-28 11:49:55.003637",
"developer_mode_only": 0,
"disable_user_customization": 0,
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
"icon": "",
"idx": 0,
"is_standard": 1,
"label": "Communication",
"modified": "2020-03-12 16:30:40.534226",
"modified_by": "Administrator",
"module": "Communication",
"name": "Communication",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"shortcuts": []
}

View File

@ -745,7 +745,7 @@ class BuyingController(StockController):
asset.supplier = None asset.supplier = None
if asset.docstatus == 1 and delete_asset: if asset.docstatus == 1 and delete_asset:
frappe.throw(_('Cannot cancel this document as it is linked with submitted asset {0}.\ frappe.throw(_('Cannot cancel this document as it is linked with submitted asset {0}.\
Please cancel the it to continue.').format(asset.name)) Please cancel the it to continue.').format(frappe.utils.get_link_to_form('Asset', asset.name)))
asset.flags.ignore_validate_update_after_submit = True asset.flags.ignore_validate_update_after_submit = True
asset.flags.ignore_mandatory = True asset.flags.ignore_mandatory = True

View File

@ -69,6 +69,17 @@ status_map = {
["Cancelled", "eval:self.docstatus==2"], ["Cancelled", "eval:self.docstatus==2"],
["Closed", "eval:self.status=='Closed'"], ["Closed", "eval:self.status=='Closed'"],
], ],
"Purchase Invoice": [
["Draft", None],
["Submitted", "eval:self.docstatus==1"],
["Paid", "eval:self.outstanding_amount==0 and self.docstatus==1"],
["Return", "eval:self.is_return==1 and self.docstatus==1"],
["Debit Note Issued",
"eval:self.outstanding_amount <= 0 and self.docstatus==1 and self.is_return==0 and get_value('Purchase Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1})"],
["Unpaid", "eval:self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.docstatus==1"],
["Overdue", "eval:self.outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()) and self.docstatus==1"],
["Cancelled", "eval:self.docstatus==2"],
],
"Material Request": [ "Material Request": [
["Draft", None], ["Draft", None],
["Stopped", "eval:self.status == 'Stopped'"], ["Stopped", "eval:self.status == 'Stopped'"],

View File

@ -238,7 +238,7 @@ class StockController(AccountsController):
for d in self.items: for d in self.items:
if not d.batch_no: continue if not d.batch_no: continue
serial_nos = [d.name for d in frappe.get_all("Serial No", {'batch_no': d.batch_no})] serial_nos = [sr.name for sr in frappe.get_all("Serial No", {'batch_no': d.batch_no})]
if serial_nos: if serial_nos:
frappe.db.set_value("Serial No", { 'name': ['in', serial_nos] }, "batch_no", None) frappe.db.set_value("Serial No", { 'name': ['in', serial_nos] }, "batch_no", None)

View File

@ -0,0 +1,69 @@
{
"cards": [
{
"icon": "fa fa-star",
"links": "[\n {\n \"description\": \"Database of potential customers.\",\n \"label\": \"Lead\",\n \"name\": \"Lead\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Potential opportunities for selling.\",\n \"label\": \"Opportunity\",\n \"name\": \"Opportunity\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Contacts.\",\n \"label\": \"Contact\",\n \"name\": \"Contact\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Record of all communications of type email, phone, chat, visit, etc.\",\n \"label\": \"Communication\",\n \"name\": \"Communication\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Track Leads by Lead Source.\",\n \"label\": \"Lead Source\",\n \"name\": \"Lead Source\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Helps you keep tracks of Contracts based on Supplier, Customer and Employee\",\n \"label\": \"Contract\",\n \"name\": \"Contract\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Helps you manage appointments with your leads\",\n \"label\": \"Appointment\",\n \"name\": \"Appointment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Newsletter\",\n \"name\": \"Newsletter\",\n \"type\": \"doctype\"\n }\n]",
"title": "Sales Pipeline"
},
{
"icon": "fa fa-list",
"links": "[\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Details\",\n \"name\": \"Lead Details\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"icon\": \"fa fa-bar-chart\",\n \"label\": \"Sales Funnel\",\n \"name\": \"sales-funnel\",\n \"onboard\": 1,\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Prospects Engaged But Not Converted\",\n \"name\": \"Prospects Engaged But Not Converted\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Opportunity\"\n ],\n \"doctype\": \"Opportunity\",\n \"is_query_report\": true,\n \"label\": \"Minutes to First Response for Opportunity\",\n \"name\": \"Minutes to First Response for Opportunity\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Inactive Customers\",\n \"name\": \"Inactive Customers\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Campaign Efficiency\",\n \"name\": \"Campaign Efficiency\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Owner Efficiency\",\n \"name\": \"Lead Owner Efficiency\",\n \"type\": \"report\"\n }\n]",
"title": "Reports"
},
{
"icon": "fa fa-cog",
"links": "[\n {\n \"description\": \"Manage Customer Group Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Customer Group\",\n \"link\": \"Tree/Customer Group\",\n \"name\": \"Customer Group\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Territory Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Territory\",\n \"link\": \"Tree/Territory\",\n \"name\": \"Territory\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Sales Person Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Sales Person\",\n \"link\": \"Tree/Sales Person\",\n \"name\": \"Sales Person\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Sales campaigns.\",\n \"label\": \"Campaign\",\n \"name\": \"Campaign\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Sends Mails to lead or contact based on a Campaign schedule\",\n \"label\": \"Email Campaign\",\n \"name\": \"Email Campaign\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Send mass SMS to your contacts\",\n \"label\": \"SMS Center\",\n \"name\": \"SMS Center\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Logs for maintaining sms delivery status\",\n \"label\": \"SMS Log\",\n \"name\": \"SMS Log\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Setup SMS gateway settings\",\n \"label\": \"SMS Settings\",\n \"name\": \"SMS Settings\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Email Group\",\n \"name\": \"Email Group\",\n \"type\": \"doctype\"\n }\n]",
"title": "Settings"
},
{
"icon": "fa fa-star",
"links": "[\n {\n \"description\": \"Plan for maintenance visits.\",\n \"label\": \"Maintenance Schedule\",\n \"name\": \"Maintenance Schedule\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Visit report for maintenance call.\",\n \"label\": \"Maintenance Visit\",\n \"name\": \"Maintenance Visit\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Warranty Claim against Serial No.\",\n \"label\": \"Warranty Claim\",\n \"name\": \"Warranty Claim\",\n \"type\": \"doctype\"\n }\n]",
"title": "Maintenance"
}
],
"category": "Modules",
"charts": [],
"creation": "2020-01-23 14:48:30.183272",
"developer_mode_only": 0,
"disable_user_customization": 0,
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
"icon": "",
"idx": 0,
"is_standard": 1,
"label": "CRM",
"modified": "2020-03-12 16:30:41.142037",
"modified_by": "Administrator",
"module": "CRM",
"name": "CRM",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"shortcuts": [
{
"format": "Open",
"is_query_report": 0,
"link_to": "Lead",
"stats_filter": "{\"status\":\"Open\"}",
"type": "DocType"
},
{
"format": "{} Assigned",
"is_query_report": 0,
"link_to": "Opportunity",
"stats_filter": "{\"_assign\": [\"like\", '%' + frappe.session.user + '%']}",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Customer",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Sales Analytics",
"type": "Report"
}
]
}

View File

@ -1,4 +1,5 @@
{ {
"actions": [],
"allow_import": 1, "allow_import": 1,
"allow_rename": 1, "allow_rename": 1,
"autoname": "naming_series:", "autoname": "naming_series:",
@ -214,7 +215,8 @@
{ {
"fieldname": "opportunity_amount", "fieldname": "opportunity_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"label": "Opportunity Amount" "label": "Opportunity Amount",
"options": "currency"
}, },
{ {
"default": "0", "default": "0",
@ -418,7 +420,8 @@
], ],
"icon": "fa fa-info-sign", "icon": "fa fa-info-sign",
"idx": 195, "idx": 195,
"modified": "2019-09-30 12:58:37.385400", "links": [],
"modified": "2020-03-20 12:28:45.228994",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "CRM", "module": "CRM",
"name": "Opportunity", "name": "Opportunity",

View File

@ -6,18 +6,13 @@ from __future__ import unicode_literals
import frappe import frappe
from frappe.utils.make_random import get_random from frappe.utils.make_random import get_random
from erpnext.assets.doctype.asset.asset import make_purchase_invoice, make_sales_invoice from erpnext.assets.doctype.asset.asset import make_sales_invoice
from erpnext.assets.doctype.asset.depreciation import post_depreciation_entries, scrap_asset from erpnext.assets.doctype.asset.depreciation import post_depreciation_entries, scrap_asset
def work(): def work():
frappe.set_user(frappe.db.get_global('demo_accounts_user')) frappe.set_user(frappe.db.get_global('demo_accounts_user'))
asset_list = make_asset_purchase_entry()
if not asset_list:
# fixed_asset.work() already run
return
# Enable booking asset depreciation entry automatically # Enable booking asset depreciation entry automatically
frappe.db.set_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically", 1) frappe.db.set_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically", 1)
@ -33,19 +28,6 @@ def work():
# Sell a random asset # Sell a random asset
sell_an_asset() sell_an_asset()
def make_asset_purchase_entry():
asset_list = frappe.get_all("Asset", filters={"purchase_invoice": ["in", ("", None)]},
fields=["name", "item_code", "gross_purchase_amount", "company", "purchase_date"])
# make purchase invoice
for asset in asset_list:
pi = make_purchase_invoice(asset.name, asset.item_code, asset.gross_purchase_amount,
asset.company, asset.purchase_date)
pi.supplier = get_random("Supplier")
pi.save()
pi.submit()
return asset_list
def sell_an_asset(): def sell_an_asset():
asset = get_random_asset() asset = get_random_asset()
@ -56,6 +38,7 @@ def sell_an_asset():
si.save() si.save()
si.submit() si.submit()
def get_random_asset(): def get_random_asset():
return frappe.db.sql(""" select name, item_code, value_after_depreciation, gross_purchase_amount return frappe.db.sql(""" select name, item_code, value_after_depreciation, gross_purchase_amount
from `tabAsset` from `tabAsset`

View File

@ -0,0 +1,76 @@
{
"cards": [
{
"links": "[\n {\n \"label\": \"Student Attendance Tool\",\n \"name\": \"Student Attendance Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Assessment Result Tool\",\n \"name\": \"Assessment Result Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Group Creation Tool\",\n \"name\": \"Student Group Creation Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Program Enrollment Tool\",\n \"name\": \"Program Enrollment Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course Scheduling Tool\",\n \"name\": \"Course Scheduling Tool\",\n \"type\": \"doctype\"\n }\n]",
"title": "Tools"
},
{
"links": "[\n {\n \"dependencies\": [\n \"Program Enrollment\"\n ],\n \"doctype\": \"Program Enrollment\",\n \"is_query_report\": true,\n \"label\": \"Student and Guardian Contact Details\",\n \"name\": \"Student and Guardian Contact Details\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Student Attendance\"\n ],\n \"doctype\": \"Student Attendance\",\n \"is_query_report\": true,\n \"label\": \"Student Monthly Attendance Sheet\",\n \"name\": \"Student Monthly Attendance Sheet\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Fees\"\n ],\n \"doctype\": \"Fees\",\n \"is_query_report\": true,\n \"label\": \"Student Fee Collection\",\n \"name\": \"Student Fee Collection\",\n \"type\": \"report\"\n }\n]",
"title": "Other Reports"
},
{
"links": "[\n {\n \"label\": \"Student Category\",\n \"name\": \"Student Category\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Batch Name\",\n \"name\": \"Student Batch Name\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Grading Scale\",\n \"name\": \"Grading Scale\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Academic Term\",\n \"name\": \"Academic Term\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Academic Year\",\n \"name\": \"Academic Year\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Education Settings\",\n \"name\": \"Education Settings\",\n \"type\": \"doctype\"\n }\n]",
"title": "Settings"
},
{
"links": "[\n {\n \"label\": \"Article\",\n \"name\": \"Article\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Video\",\n \"name\": \"Video\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Quiz\",\n \"name\": \"Quiz\",\n \"type\": \"doctype\"\n }\n]",
"title": "Content Masters"
},
{
"links": "[\n {\n \"label\": \"Student Attendance\",\n \"name\": \"Student Attendance\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Leave Application\",\n \"name\": \"Student Leave Application\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Student Attendance\"\n ],\n \"doctype\": \"Student Attendance\",\n \"is_query_report\": true,\n \"label\": \"Absent Student Report\",\n \"name\": \"Absent Student Report\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Student Attendance\"\n ],\n \"doctype\": \"Student Attendance\",\n \"is_query_report\": true,\n \"label\": \"Student Batch-Wise Attendance\",\n \"name\": \"Student Batch-Wise Attendance\",\n \"type\": \"report\"\n }\n]",
"title": "Attendance"
},
{
"links": "[\n {\n \"label\": \"Student Applicant\",\n \"name\": \"Student Applicant\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Admission\",\n \"name\": \"Student Admission\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Program Enrollment\",\n \"name\": \"Program Enrollment\",\n \"type\": \"doctype\"\n }\n]",
"title": "Admission"
},
{
"links": "[\n {\n \"label\": \"Assessment Plan\",\n \"name\": \"Assessment Plan\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Assessment Group\",\n \"link\": \"Tree/Assessment Group\",\n \"name\": \"Assessment Group\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Assessment Result\",\n \"name\": \"Assessment Result\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Assessment Criteria\",\n \"name\": \"Assessment Criteria\",\n \"type\": \"doctype\"\n }\n]",
"title": "Assessment"
},
{
"links": "[\n {\n \"label\": \"Student\",\n \"name\": \"Student\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Guardian\",\n \"name\": \"Guardian\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Log\",\n \"name\": \"Student Log\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Group\",\n \"name\": \"Student Group\",\n \"type\": \"doctype\"\n }\n]",
"title": "Student"
},
{
"links": "[\n {\n \"label\": \"Program\",\n \"name\": \"Program\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course\",\n \"name\": \"Course\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Topic\",\n \"name\": \"Topic\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Instructor\",\n \"name\": \"Instructor\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Room\",\n \"name\": \"Room\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]",
"title": "Masters"
},
{
"links": "[\n {\n \"label\": \"Course Enrollment\",\n \"name\": \"Course Enrollment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course Activity\",\n \"name\": \"Course Activity\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Quiz Activity\",\n \"name\": \"Quiz Activity\",\n \"type\": \"doctype\"\n }\n]",
"title": "LMS Activity"
},
{
"links": "[\n {\n \"label\": \"Course Schedule\",\n \"name\": \"Course Schedule\",\n \"route\": \"#List/Course Schedule/Calendar\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course Scheduling Tool\",\n \"name\": \"Course Scheduling Tool\",\n \"type\": \"doctype\"\n }\n]",
"title": "Schedule"
},
{
"links": "[\n {\n \"label\": \"Fees\",\n \"name\": \"Fees\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fee Schedule\",\n \"name\": \"Fee Schedule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fee Structure\",\n \"name\": \"Fee Structure\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fee Category\",\n \"name\": \"Fee Category\",\n \"type\": \"doctype\"\n }\n]",
"title": "Fees"
},
{
"links": "[\n {\n \"dependencies\": [\n \"Assessment Result\"\n ],\n \"doctype\": \"Assessment Result\",\n \"is_query_report\": true,\n \"label\": \"Course wise Assessment Report\",\n \"name\": \"Course wise Assessment Report\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Assessment Result\"\n ],\n \"doctype\": \"Assessment Result\",\n \"is_query_report\": true,\n \"label\": \"Final Assessment Grades\",\n \"name\": \"Final Assessment Grades\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Assessment Plan\"\n ],\n \"doctype\": \"Assessment Plan\",\n \"is_query_report\": true,\n \"label\": \"Assessment Plan Status\",\n \"name\": \"Assessment Plan Status\",\n \"type\": \"report\"\n },\n {\n \"label\": \"Student Report Generation Tool\",\n \"name\": \"Student Report Generation Tool\",\n \"type\": \"doctype\"\n }\n]",
"title": "Assessment Reports"
}
],
"category": "Domains",
"charts": [],
"creation": "2020-03-02 17:22:57.066401",
"developer_mode_only": 0,
"disable_user_customization": 0,
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
"idx": 0,
"is_standard": 1,
"label": "Education",
"modified": "2020-03-12 16:30:37.217514",
"modified_by": "Administrator",
"module": "Education",
"name": "Education",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"restrict_to_domain": "Education",
"shortcuts": []
}

View File

@ -1,274 +1,90 @@
{ {
"allow_copy": 0, "actions": [],
"allow_guest_to_view": 0,
"allow_import": 1, "allow_import": 1,
"allow_rename": 1, "allow_rename": 1,
"autoname": "field:assessment_group_name", "autoname": "field:assessment_group_name",
"beta": 0,
"creation": "2016-08-04 04:42:48.319388", "creation": "2016-08-04 04:42:48.319388",
"custom": 0,
"docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "",
"editable_grid": 1, "editable_grid": 1,
"field_order": [
"assessment_group_name",
"is_group",
"section_break_2",
"parent_assessment_group",
"lft",
"rgt",
"old_parent"
],
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "assessment_group_name", "fieldname": "assessment_group_name",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Assessment Group Name", "label": "Assessment Group Name",
"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": 1, "reqd": 1,
"search_index": 0, "unique": 1
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0, "default": "0",
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "is_group", "fieldname": "is_group",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "label": "Is Group"
"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 Group",
"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": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_2", "fieldname": "section_break_2",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 1, "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,
"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": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "parent_assessment_group", "fieldname": "parent_assessment_group",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Parent Assessment Group", "label": "Parent Assessment Group",
"length": 0,
"no_copy": 0,
"options": "Assessment Group", "options": "Assessment Group",
"permlevel": 0, "reqd": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "lft", "fieldname": "lft",
"fieldtype": "Int", "fieldtype": "Int",
"hidden": 0, "label": "lft"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "lft",
"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": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "rgt", "fieldname": "rgt",
"fieldtype": "Int", "fieldtype": "Int",
"hidden": 0, "label": "rgt"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "rgt",
"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": 0,
"set_only_once": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "old_parent", "fieldname": "old_parent",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1, "ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "old_parent", "label": "old_parent",
"length": 0, "options": "Assessment Group"
"no_copy": 0,
"options": "Assessment Group",
"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,
"unique": 0
} }
], ],
"has_web_view": 0, "is_tree": 1,
"hide_heading": 0, "links": [],
"hide_toolbar": 0, "modified": "2020-03-18 18:01:14.710416",
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-11-10 19:09:25.366400",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Education", "module": "Education",
"name": "Assessment Group", "name": "Assessment Group",
"name_case": "", "nsm_parent_field": "parent_assessment_group",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
"export": 1, "export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "Academics User", "role": "Academics User",
"set_user_permissions": 0,
"share": 1, "share": 1,
"submit": 0,
"write": 1 "write": 1
} }
], ],
"quick_entry": 1, "quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"restrict_to_domain": "Education", "restrict_to_domain": "Education",
"show_name_in_global_search": 0,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC"
"track_changes": 0,
"track_seen": 0
} }

View File

@ -74,7 +74,7 @@
} }
], ],
"image_field": "hero_image", "image_field": "hero_image",
"modified": "2019-06-12 12:34:23.748157", "modified": "2020-03-29 12:50:27.677589",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Education", "module": "Education",
"name": "Course", "name": "Course",
@ -103,6 +103,30 @@
"role": "Instructor", "role": "Instructor",
"share": 1, "share": 1,
"write": 1 "write": 1
},
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Administrator",
"share": 1,
"write": 1
},
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Education Manager",
"share": 1,
"write": 1
} }
], ],
"restrict_to_domain": "Education", "restrict_to_domain": "Education",

View File

@ -0,0 +1,44 @@
{
"cards": [
{
"icon": "icon-cog",
"links": "[\n {\n \"label\": \"Healthcare Settings\",\n \"name\": \"Healthcare Settings\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Medical Department\",\n \"name\": \"Medical Department\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Appointment Type\",\n \"name\": \"Appointment Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Prescription Dosage\",\n \"name\": \"Prescription Dosage\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Prescription Duration\",\n \"name\": \"Prescription Duration\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Complaint\",\n \"name\": \"Complaint\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Diagnosis\",\n \"name\": \"Diagnosis\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Lab Test Sample\",\n \"name\": \"Lab Test Sample\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Lab Test UOM\",\n \"name\": \"Lab Test UOM\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Antibiotic\",\n \"name\": \"Antibiotic\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Sensitivity\",\n \"name\": \"Sensitivity\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Lab Test Template\",\n \"name\": \"Lab Test Template\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Clinical Procedure Template\",\n \"name\": \"Clinical Procedure Template\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Healthcare Service Unit Type\",\n \"name\": \"Healthcare Service Unit Type\",\n \"type\": \"doctype\"\n }\n]",
"title": "Settings"
},
{
"icon": "icon-list",
"links": "[\n {\n \"label\": \"Lab Test\",\n \"name\": \"Lab Test\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Sample Collection\",\n \"name\": \"Sample Collection\",\n \"type\": \"doctype\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Lab Test Report\",\n \"name\": \"Lab Test Report\",\n \"type\": \"report\"\n }\n]",
"title": "Laboratory"
},
{
"icon": "icon-list",
"links": "[\n {\n \"label\": \"Patient\",\n \"name\": \"Patient\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Healthcare Practitioner\",\n \"name\": \"Healthcare Practitioner\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Practitioner Schedule\",\n \"name\": \"Practitioner Schedule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Medical Code Standard\",\n \"name\": \"Medical Code Standard\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Medical Code\",\n \"name\": \"Medical Code\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Healthcare Service Unit\",\n \"name\": \"Healthcare Service Unit\",\n \"type\": \"doctype\"\n }\n]",
"title": "Masters"
},
{
"icon": "icon-star",
"links": "[\n {\n \"label\": \"Patient Appointment\",\n \"name\": \"Patient Appointment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Patient Encounter\",\n \"name\": \"Patient Encounter\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Record Patient Vitals\",\n \"label\": \"Vital Signs\",\n \"name\": \"Vital Signs\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Patient History\",\n \"name\": \"patient_history\",\n \"type\": \"page\"\n },\n {\n \"label\": \"Appointment Analytics\",\n \"name\": \"appointment-analytic\",\n \"type\": \"page\"\n },\n {\n \"label\": \"Clinical Procedure\",\n \"name\": \"Clinical Procedure\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Inpatient Record\",\n \"name\": \"Inpatient Record\",\n \"type\": \"doctype\"\n }\n]",
"title": "Consultation"
}
],
"category": "Domains",
"charts": [],
"creation": "2020-03-02 17:23:17.919682",
"developer_mode_only": 0,
"disable_user_customization": 0,
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
"idx": 0,
"is_standard": 1,
"label": "Healthcare",
"modified": "2020-03-12 16:30:36.952979",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Healthcare",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"restrict_to_domain": "Healthcare",
"shortcuts": []
}

View File

@ -1,542 +1,205 @@
{ {
"allow_copy": 0, "actions": [],
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 1, "allow_import": 1,
"allow_rename": 1, "allow_rename": 1,
"autoname": "field:healthcare_service_unit_name", "autoname": "field:healthcare_service_unit_name",
"beta": 1, "beta": 1,
"creation": "2016-09-21 13:48:14.731437", "creation": "2016-09-21 13:48:14.731437",
"custom": 0,
"description": "Healthcare Service Unit", "description": "Healthcare Service Unit",
"docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "Setup", "document_type": "Setup",
"editable_grid": 1, "editable_grid": 1,
"field_order": [
"healthcare_service_unit_name",
"parent_healthcare_service_unit",
"is_group",
"service_unit_type",
"allow_appointments",
"overlap_appointments",
"inpatient_occupancy",
"occupancy_status",
"warehouse",
"company",
"lft",
"rgt",
"old_parent"
],
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "healthcare_service_unit_name", "fieldname": "healthcare_service_unit_name",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 1, "in_global_search": 1,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Service Unit", "label": "Service Unit",
"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": 1, "reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 1 "unique": 1
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1, "bold": 1,
"collapsible": 0,
"columns": 0,
"fieldname": "parent_healthcare_service_unit", "fieldname": "parent_healthcare_service_unit",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1, "ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Parent Service Unit", "label": "Parent Service Unit",
"length": 0, "options": "Healthcare Service Unit"
"no_copy": 0,
"options": "Healthcare Service Unit",
"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": 1, "bold": 1,
"collapsible": 0,
"columns": 0,
"default": "0", "default": "0",
"depends_on": "eval:doc.inpatient_occupancy != 1 && doc.allow_appointments != 1", "depends_on": "eval:doc.inpatient_occupancy != 1 && doc.allow_appointments != 1",
"fieldname": "is_group", "fieldname": "is_group",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0, "label": "Is Group"
"label": "Is Group",
"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": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1, "bold": 1,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.is_group != 1", "depends_on": "eval:doc.is_group != 1",
"fieldname": "service_unit_type", "fieldname": "service_unit_type",
"fieldtype": "Link", "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": "Service Unit Type", "label": "Service Unit Type",
"length": 0, "options": "Healthcare Service Unit Type"
"no_copy": 0,
"options": "Healthcare Service Unit Type",
"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": 1, "bold": 1,
"collapsible": 0,
"columns": 0,
"default": "0", "default": "0",
"depends_on": "eval:doc.is_group != 1 && doc.inpatient_occupancy != 1", "depends_on": "eval:doc.is_group != 1 && doc.inpatient_occupancy != 1",
"fetch_from": "service_unit_type.allow_appointments", "fetch_from": "service_unit_type.allow_appointments",
"fieldname": "allow_appointments", "fieldname": "allow_appointments",
"fieldtype": "Check", "fieldtype": "Check",
"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": "Allow Appointments", "label": "Allow Appointments",
"length": 0,
"no_copy": 1, "no_copy": 1,
"permlevel": 0, "read_only": 1
"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,
"default": "0", "default": "0",
"depends_on": "eval:doc.is_group != 1 && doc.allow_appointments == 1 && doc.inpatient_occupany != 1", "depends_on": "eval:doc.is_group != 1 && doc.allow_appointments == 1 && doc.inpatient_occupany != 1",
"fetch_from": "service_unit_type.overlap_appointments", "fetch_from": "service_unit_type.overlap_appointments",
"fieldname": "overlap_appointments", "fieldname": "overlap_appointments",
"fieldtype": "Check", "fieldtype": "Check",
"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": "Allow Overlap", "label": "Allow Overlap",
"length": 0,
"no_copy": 1, "no_copy": 1,
"permlevel": 0, "read_only": 1
"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": 1, "bold": 1,
"collapsible": 0,
"columns": 0,
"default": "0", "default": "0",
"depends_on": "eval:doc.allow_appointments != 1 && doc.is_group != 1", "depends_on": "eval:doc.allow_appointments != 1 && doc.is_group != 1",
"fetch_from": "service_unit_type.inpatient_occupancy", "fetch_from": "service_unit_type.inpatient_occupancy",
"fieldname": "inpatient_occupancy", "fieldname": "inpatient_occupancy",
"fieldtype": "Check", "fieldtype": "Check",
"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": "Inpatient Occupancy", "label": "Inpatient Occupancy",
"length": 0,
"no_copy": 1, "no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1, "read_only": 1,
"remember_last_selected_value": 0, "search_index": 1
"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,
"default": "",
"depends_on": "eval:doc.inpatient_occupancy == 1", "depends_on": "eval:doc.inpatient_occupancy == 1",
"fieldname": "occupancy_status", "fieldname": "occupancy_status",
"fieldtype": "Select", "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": "Occupancy Status", "label": "Occupancy Status",
"length": 0,
"no_copy": 1, "no_copy": 1,
"options": "Vacant\nOccupied", "options": "Vacant\nOccupied",
"permlevel": 0, "read_only": 1
"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": 1, "bold": 1,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.is_group != 1", "depends_on": "eval:doc.is_group != 1",
"fieldname": "warehouse", "fieldname": "warehouse",
"fieldtype": "Link", "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": "Warehouse", "label": "Warehouse",
"length": 0,
"no_copy": 1, "no_copy": 1,
"options": "Warehouse", "options": "Warehouse"
"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": "company", "fieldname": "company",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1, "ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 1, "in_standard_filter": 1,
"label": "Company", "label": "Company",
"length": 0,
"no_copy": 0,
"options": "Company", "options": "Company",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 1, "remember_last_selected_value": 1,
"report_hide": 0,
"reqd": 1, "reqd": 1,
"search_index": 1, "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": "lft", "fieldname": "lft",
"fieldtype": "Int", "fieldtype": "Int",
"hidden": 1, "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": "lft", "label": "lft",
"length": 0,
"no_copy": 1, "no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1, "print_hide": 1,
"print_hide_if_no_value": 0, "search_index": 1
"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": "rgt", "fieldname": "rgt",
"fieldtype": "Int", "fieldtype": "Int",
"hidden": 1, "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": "rgt", "label": "rgt",
"length": 0,
"no_copy": 1, "no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1, "print_hide": 1,
"print_hide_if_no_value": 0, "search_index": 1
"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": "old_parent", "fieldname": "old_parent",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 1, "hidden": 1,
"ignore_user_permissions": 1, "ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Old Parent", "label": "Old Parent",
"length": 0,
"no_copy": 1, "no_copy": 1,
"options": "Healthcare Service Unit", "options": "Healthcare Service Unit",
"permlevel": 0,
"precision": "",
"print_hide": 1, "print_hide": 1,
"print_hide_if_no_value": 0, "report_hide": 1
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 1,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
} }
], ],
"has_web_view": 0, "is_tree": 1,
"hide_heading": 0, "links": [],
"hide_toolbar": 0, "modified": "2020-03-18 18:02:23.713439",
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-10-04 21:09:52.261882",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Healthcare", "module": "Healthcare",
"name": "Healthcare Service Unit", "name": "Healthcare Service Unit",
"name_case": "", "nsm_parent_field": "parent_healthcare_service_unit",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1, "email": 1,
"export": 1, "export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "Nursing User", "role": "Nursing User",
"set_user_permissions": 0, "share": 1
"share": 1,
"submit": 0,
"write": 0
}, },
{ {
"amend": 0,
"cancel": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
"export": 1, "export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "Healthcare Administrator", "role": "Healthcare Administrator",
"set_user_permissions": 0,
"share": 1, "share": 1,
"submit": 0,
"write": 1 "write": 1
}, },
{ {
"amend": 0,
"cancel": 0,
"create": 1, "create": 1,
"delete": 0,
"email": 1, "email": 1,
"export": 1, "export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "Physician", "role": "Physician",
"set_user_permissions": 0,
"share": 1, "share": 1,
"submit": 0,
"write": 1 "write": 1
} }
], ],
"quick_entry": 1, "quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"restrict_to_domain": "Healthcare", "restrict_to_domain": "Healthcare",
"search_fields": "healthcare_service_unit_name", "search_fields": "healthcare_service_unit_name",
"show_name_in_global_search": 0,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",
"title_field": "healthcare_service_unit_name", "title_field": "healthcare_service_unit_name",
"track_changes": 1, "track_changes": 1
"track_seen": 0,
"track_views": 0
} }

View File

@ -386,5 +386,5 @@ def get_procedure_prescribed(patient):
return frappe.db.sql("""select pp.name, pp.procedure, pp.parent, ct.practitioner, return frappe.db.sql("""select pp.name, pp.procedure, pp.parent, ct.practitioner,
ct.encounter_date, pp.practitioner, pp.date, pp.department ct.encounter_date, pp.practitioner, pp.date, pp.department
from `tabPatient Encounter` ct, `tabProcedure Prescription` pp from `tabPatient Encounter` ct, `tabProcedure Prescription` pp
where ct.patient='{0}' and pp.parent=ct.name and pp.appointment_booked=0 where ct.patient=%(patient)s and pp.parent=ct.name and pp.appointment_booked=0
order by ct.creation desc""".format(patient)) order by ct.creation desc""", {"patient": patient})

View File

@ -0,0 +1,123 @@
{
"cards": [
{
"links": "[\n {\n \"label\": \"Employee\",\n \"name\": \"Employee\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Employment Type\",\n \"name\": \"Employment Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Branch\",\n \"name\": \"Branch\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Department\",\n \"name\": \"Department\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Designation\",\n \"name\": \"Designation\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Employee Grade\",\n \"name\": \"Employee Grade\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Group\",\n \"name\": \"Employee Group\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Employee Health Insurance\",\n \"name\": \"Employee Health Insurance\",\n \"type\": \"doctype\"\n }\n]",
"title": "Employee"
},
{
"links": "[\n {\n \"dependencies\": [\n \"Job Applicant\"\n ],\n \"label\": \"Employee Onboarding\",\n \"name\": \"Employee Onboarding\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Skill Map\",\n \"name\": \"Employee Skill Map\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Promotion\",\n \"name\": \"Employee Promotion\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Transfer\",\n \"name\": \"Employee Transfer\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Separation\",\n \"name\": \"Employee Separation\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Onboarding Template\",\n \"name\": \"Employee Onboarding Template\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Separation Template\",\n \"name\": \"Employee Separation Template\",\n \"type\": \"doctype\"\n }\n]",
"title": "Employee Lifecycle"
},
{
"links": "[\n {\n \"label\": \"Shift Type\",\n \"name\": \"Shift Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Shift Request\",\n \"name\": \"Shift Request\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Shift Assignment\",\n \"name\": \"Shift Assignment\",\n \"type\": \"doctype\"\n }\n]",
"title": "Shift Management"
},
{
"links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Application\",\n \"name\": \"Leave Application\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Allocation\",\n \"name\": \"Leave Allocation\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Leave Type\"\n ],\n \"label\": \"Leave Policy\",\n \"name\": \"Leave Policy\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Period\",\n \"name\": \"Leave Period\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Leave Type\",\n \"name\": \"Leave Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Holiday List\",\n \"name\": \"Holiday List\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Compensatory Leave Request\",\n \"name\": \"Compensatory Leave Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Encashment\",\n \"name\": \"Leave Encashment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Leave Block List\",\n \"name\": \"Leave Block List\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Leave Application\"\n ],\n \"doctype\": \"Leave Application\",\n \"is_query_report\": true,\n \"label\": \"Employee Leave Balance\",\n \"name\": \"Employee Leave Balance\",\n \"type\": \"report\"\n }\n]",
"title": "Leaves"
},
{
"links": "[\n {\n \"label\": \"Salary Structure\",\n \"name\": \"Salary Structure\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Salary Structure\",\n \"Employee\"\n ],\n \"label\": \"Salary Structure Assignment\",\n \"name\": \"Salary Structure Assignment\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Payroll Entry\",\n \"name\": \"Payroll Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Slip\",\n \"name\": \"Salary Slip\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Payroll Period\",\n \"name\": \"Payroll Period\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Component\",\n \"name\": \"Salary Component\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Additional Salary\",\n \"name\": \"Additional Salary\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Retention Bonus\",\n \"name\": \"Retention Bonus\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Incentive\",\n \"name\": \"Employee Incentive\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"is_query_report\": true,\n \"label\": \"Salary Register\",\n \"name\": \"Salary Register\",\n \"type\": \"report\"\n }\n]",
"title": "Payroll"
},
{
"links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"hide_count\": true,\n \"label\": \"Employee Attendance Tool\",\n \"name\": \"Employee Attendance Tool\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Attendance\",\n \"name\": \"Attendance\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Attendance Request\",\n \"name\": \"Attendance Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"hide_count\": true,\n \"label\": \"Upload Attendance\",\n \"name\": \"Upload Attendance\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"hide_count\": true,\n \"label\": \"Employee Checkin\",\n \"name\": \"Employee Checkin\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Attendance\"\n ],\n \"doctype\": \"Attendance\",\n \"is_query_report\": true,\n \"label\": \"Monthly Attendance Sheet\",\n \"name\": \"Monthly Attendance Sheet\",\n \"type\": \"report\"\n }\n]",
"title": "Attendance"
},
{
"links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Expense Claim\",\n \"name\": \"Expense Claim\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Advance\",\n \"name\": \"Employee Advance\",\n \"type\": \"doctype\"\n }\n]",
"title": "Expense Claims"
},
{
"icon": "fa fa-cog",
"links": "[\n {\n \"label\": \"HR Settings\",\n \"name\": \"HR Settings\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Daily Work Summary Group\",\n \"name\": \"Daily Work Summary Group\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Team Updates\",\n \"name\": \"team-updates\",\n \"type\": \"page\"\n }\n]",
"title": "Settings"
},
{
"links": "[\n {\n \"label\": \"Vehicle\",\n \"name\": \"Vehicle\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Vehicle Log\",\n \"name\": \"Vehicle Log\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Vehicle\"\n ],\n \"doctype\": \"Vehicle\",\n \"is_query_report\": true,\n \"label\": \"Vehicle Expenses\",\n \"name\": \"Vehicle Expenses\",\n \"type\": \"report\"\n }\n]",
"title": "Fleet Management"
},
{
"links": "[\n {\n \"label\": \"Job Opening\",\n \"name\": \"Job Opening\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Job Applicant\",\n \"name\": \"Job Applicant\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Job Offer\",\n \"name\": \"Job Offer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Staffing Plan\",\n \"name\": \"Staffing Plan\",\n \"type\": \"doctype\"\n }\n]",
"title": "Recruitment"
},
{
"links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Loan Application\",\n \"name\": \"Loan Application\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan\",\n \"name\": \"Loan\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Type\",\n \"name\": \"Loan Type\",\n \"type\": \"doctype\"\n }\n]",
"title": "Loans"
},
{
"links": "[\n {\n \"label\": \"Training Program\",\n \"name\": \"Training Program\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Training Event\",\n \"name\": \"Training Event\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Training Result\",\n \"name\": \"Training Result\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Training Feedback\",\n \"name\": \"Training Feedback\",\n \"type\": \"doctype\"\n }\n]",
"title": "Training"
},
{
"icon": "fa fa-list",
"links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"doctype\": \"Employee\",\n \"is_query_report\": true,\n \"label\": \"Employee Birthday\",\n \"name\": \"Employee Birthday\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"doctype\": \"Employee\",\n \"is_query_report\": true,\n \"label\": \"Employees working on a holiday\",\n \"name\": \"Employees working on a holiday\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"doctype\": \"Employee\",\n \"is_query_report\": true,\n \"label\": \"Department Analytics\",\n \"name\": \"Department Analytics\",\n \"type\": \"report\"\n }\n]",
"title": "Reports"
},
{
"links": "[\n {\n \"label\": \"Appraisal\",\n \"name\": \"Appraisal\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Appraisal Template\",\n \"name\": \"Appraisal Template\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Energy Point Rule\",\n \"name\": \"Energy Point Rule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Energy Point Log\",\n \"name\": \"Energy Point Log\",\n \"type\": \"doctype\"\n }\n]",
"title": "Performance"
},
{
"links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Declaration\",\n \"name\": \"Employee Tax Exemption Declaration\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Proof Submission\",\n \"name\": \"Employee Tax Exemption Proof Submission\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Benefit Application\",\n \"name\": \"Employee Benefit Application\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Benefit Claim\",\n \"name\": \"Employee Benefit Claim\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Category\",\n \"name\": \"Employee Tax Exemption Category\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Sub Category\",\n \"name\": \"Employee Tax Exemption Sub Category\",\n \"type\": \"doctype\"\n }\n]",
"title": "Employee Tax and Benefits"
}
],
"category": "Modules",
"charts": [],
"creation": "2020-03-02 15:48:58.322521",
"developer_mode_only": 0,
"disable_user_customization": 0,
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
"icon": "",
"idx": 0,
"is_standard": 1,
"label": "HR",
"modified": "2020-03-12 16:30:35.211246",
"modified_by": "Administrator",
"module": "HR",
"name": "HR",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"shortcuts": [
{
"format": "{} Active",
"is_query_report": 0,
"link_to": "Employee",
"stats_filter": "{\"status\":\"Active\"}",
"type": "DocType"
},
{
"format": "{} Unpaid",
"is_query_report": 0,
"link_to": "Expense Claim",
"stats_filter": "{\"approval_status\":\"Draft\"}",
"type": "DocType"
},
{
"format": "{} Open",
"is_query_report": 0,
"link_to": "Job Applicant",
"stats_filter": "{\n \"status\": \"Open\"\n}",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Salary Structure",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Leave Application",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Salary Register",
"type": "Report"
}
]
}

View File

@ -129,11 +129,13 @@
], ],
"icon": "fa fa-sitemap", "icon": "fa fa-sitemap",
"idx": 1, "idx": 1,
"is_tree": 1,
"links": [], "links": [],
"modified": "2019-12-12 14:48:35.254308", "modified": "2020-03-18 18:03:27.784362",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "HR", "module": "HR",
"name": "Department", "name": "Department",
"nsm_parent_field": "parent_department",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {

View File

@ -48,12 +48,17 @@ def get_abbreviated_name(name, company):
@frappe.whitelist() @frappe.whitelist()
def get_children(doctype, parent=None, company=None, is_root=False): def get_children(doctype, parent=None, company=None, is_root=False):
condition = '' condition = ''
var_dict = {
"name": get_root_of("Department"),
"parent": parent,
"company": company,
}
if company == parent: if company == parent:
condition = "name='{0}'".format(get_root_of("Department")) condition = "name=%(name)s"
elif company: elif company:
condition = "parent_department='{0}' and company='{1}'".format(parent, company) condition = "parent_department=%(parent)s and company=%(company)s"
else: else:
condition = "parent_department = '{0}'".format(parent) condition = "parent_department = %(parent)s"
return frappe.db.sql(""" return frappe.db.sql("""
select select
@ -62,7 +67,7 @@ def get_children(doctype, parent=None, company=None, is_root=False):
from `tab{doctype}` from `tab{doctype}`
where where
{condition} {condition}
order by name""".format(doctype=doctype, condition=condition), as_dict=1) order by name""".format(doctype=doctype, condition=condition), var_dict, as_dict=1)
@frappe.whitelist() @frappe.whitelist()
def add_node(): def add_node():

View File

@ -190,6 +190,7 @@ def get_benefit_component_amount(employee, start_date, end_date, salary_componen
component_max_benefit, depends_on_payment_days = frappe.db.get_value("Salary Component", component_max_benefit, depends_on_payment_days = frappe.db.get_value("Salary Component",
salary_component, ["max_benefit_amount", "depends_on_payment_days"]) salary_component, ["max_benefit_amount", "depends_on_payment_days"])
benefit_amount = 0
if benefit_application: if benefit_application:
benefit_amount = frappe.db.get_value("Employee Benefit Application Detail", benefit_amount = frappe.db.get_value("Employee Benefit Application Detail",
{"parent": benefit_application[0][0], "earning_component": salary_component}, "amount") {"parent": benefit_application[0][0], "earning_component": salary_component}, "amount")

View File

@ -71,7 +71,7 @@
"label": "Amount", "label": "Amount",
"oldfieldname": "tax_amount", "oldfieldname": "tax_amount",
"oldfieldtype": "Currency", "oldfieldtype": "Currency",
"options": "currency" "options": "Company:company:default_currency"
}, },
{ {
"columns": 2, "columns": 2,
@ -81,7 +81,7 @@
"label": "Total", "label": "Total",
"oldfieldname": "total", "oldfieldname": "total",
"oldfieldtype": "Currency", "oldfieldtype": "Currency",
"options": "currency", "options": "Company:company:default_currency",
"read_only": 1 "read_only": 1
}, },
{ {
@ -95,7 +95,7 @@
], ],
"istable": 1, "istable": 1,
"links": [], "links": [],
"modified": "2019-12-11 13:50:02.883328", "modified": "2020-03-11 13:25:06.721917",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "HR", "module": "HR",
"name": "Expense Taxes and Charges", "name": "Expense Taxes and Charges",

View File

@ -6,11 +6,14 @@ from __future__ import unicode_literals
import frappe import frappe
import unittest import unittest
from frappe.utils import nowdate,flt, cstr,random_string from frappe.utils import nowdate,flt, cstr,random_string
# test_records = frappe.get_test_records('Vehicle Log')
class TestVehicleLog(unittest.TestCase): class TestVehicleLog(unittest.TestCase):
def test_make_vehicle_log_and_syncing_of_odometer_value(self): def test_make_vehicle_log_and_syncing_of_odometer_value(self):
employee_id=frappe.db.sql("""select name from `tabEmployee` order by modified desc limit 1""")[0][0] employee_id = frappe.db.sql("""select name from `tabEmployee` where status='Active' order by modified desc limit 1""")
employee_id = employee_id[0][0] if employee_id else None
license_plate = get_vehicle(employee_id) license_plate = get_vehicle(employee_id)
vehicle_log = frappe.get_doc({ vehicle_log = frappe.get_doc({
"doctype": "Vehicle Log", "doctype": "Vehicle Log",
"license_plate": cstr(license_plate), "license_plate": cstr(license_plate),

View File

@ -3,11 +3,6 @@
frappe.ui.form.on("Vehicle Log", { frappe.ui.form.on("Vehicle Log", {
refresh: function(frm) { refresh: function(frm) {
if(frm.doc.license_plate && frm.doc.__islocal){
frm.events.set_vehicle_details(frm);
}
if(frm.doc.docstatus == 1) { if(frm.doc.docstatus == 1) {
frm.add_custom_button(__('Expense Claim'), function() { frm.add_custom_button(__('Expense Claim'), function() {
frm.events.expense_claim(frm); frm.events.expense_claim(frm);
@ -16,27 +11,6 @@ frappe.ui.form.on("Vehicle Log", {
} }
}, },
license_plate: function(frm) {
if(frm.doc.license_plate){
frm.events.set_vehicle_details(frm);
}
},
set_vehicle_details: function(frm) {
frappe.call({
method: "erpnext.hr.doctype.vehicle_log.vehicle_log.get_make_model",
args: {
license_plate: frm.doc.license_plate
},
callback: function(r) {
frappe.model.set_value(cur_frm.doctype, cur_frm.docname, "make", r.message[0]);
frappe.model.set_value(cur_frm.doctype, cur_frm.docname, "model", r.message[1]);
frappe.model.set_value(cur_frm.doctype, cur_frm.docname, "last_odometer", r.message[2]);
frappe.model.set_value(cur_frm.doctype, cur_frm.docname, "employee", r.message[3]);
}
});
},
expense_claim: function(frm){ expense_claim: function(frm){
frappe.call({ frappe.call({
method: "erpnext.hr.doctype.vehicle_log.vehicle_log.make_expense_claim", method: "erpnext.hr.doctype.vehicle_log.vehicle_log.make_expense_claim",

View File

@ -1,5 +1,4 @@
{ {
"actions": [],
"autoname": "naming_series:", "autoname": "naming_series:",
"creation": "2016-09-03 14:14:51.788550", "creation": "2016-09-03 14:14:51.788550",
"doctype": "DocType", "doctype": "DocType",
@ -56,6 +55,8 @@
"reqd": 1 "reqd": 1
}, },
{ {
"fetch_from": "license_plate.employee",
"fetch_if_empty": 1,
"fieldname": "employee", "fieldname": "employee",
"fieldtype": "Link", "fieldtype": "Link",
"in_list_view": 1, "in_list_view": 1,
@ -73,11 +74,13 @@
"fieldtype": "Column Break" "fieldtype": "Column Break"
}, },
{ {
"fetch_from": "license_plate.model",
"fieldname": "model", "fieldname": "model",
"fieldtype": "Read Only", "fieldtype": "Read Only",
"label": "Model" "label": "Model"
}, },
{ {
"fetch_from": "license_plate.make",
"fieldname": "make", "fieldname": "make",
"fieldtype": "Read Only", "fieldtype": "Read Only",
"label": "Make" "label": "Make"
@ -152,6 +155,7 @@
"read_only": 1 "read_only": 1
}, },
{ {
"fetch_from": "license_plate.last_odometer",
"fieldname": "last_odometer", "fieldname": "last_odometer",
"fieldtype": "Int", "fieldtype": "Int",
"label": "last Odometer Value ", "label": "last Odometer Value ",
@ -164,8 +168,7 @@
} }
], ],
"is_submittable": 1, "is_submittable": 1,
"links": [], "modified": "2020-03-18 16:45:45.060761",
"modified": "2020-01-28 12:43:34.419647",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "HR", "module": "HR",
"name": "Vehicle Log", "name": "Vehicle Log",

View File

@ -12,18 +12,7 @@ from frappe.model.document import Document
class VehicleLog(Document): class VehicleLog(Document):
def validate(self): def validate(self):
if flt(self.odometer) < flt(self.last_odometer): if flt(self.odometer) < flt(self.last_odometer):
frappe.throw(_("Current Odometer reading entered should be greater than initial Vehicle Odometer {0}").format(self.last_odometer)) frappe.throw(_("Current Odometer Value should be greater than Last Odometer Value {0}").format(self.last_odometer))
for service_detail in self.service_detail:
if (service_detail.service_item or service_detail.type or service_detail.frequency or service_detail.expense_amount):
if not (service_detail.service_item and service_detail.type and service_detail.frequency and service_detail.expense_amount):
frappe.throw(_("Service Item,Type,frequency and expense amount are required"))
def before_insert(self):
model_details = get_make_model(self.license_plate)
self.make = model_details[0]
self.model = model_details[1]
self.last_odometer = model_details[2]
self.employee = model_details[3]
def on_submit(self): def on_submit(self):
frappe.db.set_value("Vehicle", self.license_plate, "last_odometer", self.odometer) frappe.db.set_value("Vehicle", self.license_plate, "last_odometer", self.odometer)
@ -34,35 +23,26 @@ class VehicleLog(Document):
updated_odometer_value = int(frappe.db.get_value("Vehicle", self.license_plate, "last_odometer")) - distance_travelled updated_odometer_value = int(frappe.db.get_value("Vehicle", self.license_plate, "last_odometer")) - distance_travelled
frappe.db.set_value("Vehicle", self.license_plate, "last_odometer", updated_odometer_value) frappe.db.set_value("Vehicle", self.license_plate, "last_odometer", updated_odometer_value)
@frappe.whitelist()
def get_make_model(license_plate):
vehicle=frappe.get_doc("Vehicle",license_plate)
return (vehicle.make, vehicle.model, vehicle.last_odometer, vehicle.employee)
@frappe.whitelist() @frappe.whitelist()
def make_expense_claim(docname): def make_expense_claim(docname):
def check_exp_claim_exists(): expense_claim = frappe.db.exists("Expense Claim", {"vehicle_log": docname})
exp_claim = frappe.db.sql("""select name from `tabExpense Claim` where vehicle_log=%s""",vehicle_log.name) if expense_claim:
return exp_claim[0][0] if exp_claim else "" frappe.throw(_("Expense Claim {0} already exists for the Vehicle Log").format(expense_claim))
def calc_service_exp():
total_exp_amt=0
exp_claim = check_exp_claim_exists()
if exp_claim:
frappe.throw(_("Expense Claim {0} already exists for the Vehicle Log").format(exp_claim))
for serdetail in vehicle_log.service_detail:
total_exp_amt = total_exp_amt + serdetail.expense_amount
return total_exp_amt
vehicle_log = frappe.get_doc("Vehicle Log", docname) vehicle_log = frappe.get_doc("Vehicle Log", docname)
service_expense = sum([flt(d.expense_amount) for d in vehicle_log.service_detail])
claim_amount = service_expense + flt(vehicle_log.price)
if not claim_amount:
frappe.throw(_("No additional expenses has been added"))
exp_claim = frappe.new_doc("Expense Claim") exp_claim = frappe.new_doc("Expense Claim")
exp_claim.employee = vehicle_log.employee exp_claim.employee = vehicle_log.employee
exp_claim.vehicle_log = vehicle_log.name exp_claim.vehicle_log = vehicle_log.name
exp_claim.remark = _("Expense Claim for Vehicle Log {0}").format(vehicle_log.name) exp_claim.remark = _("Expense Claim for Vehicle Log {0}").format(vehicle_log.name)
fuel_price=vehicle_log.price
total_claim_amt=calc_service_exp() + fuel_price
exp_claim.append("expenses", { exp_claim.append("expenses", {
"expense_date": vehicle_log.date, "expense_date": vehicle_log.date,
"description": _("Vehicle Expenses"), "description": _("Vehicle Expenses"),
"amount":total_claim_amt "amount": claim_amount
}) })
return exp_claim.as_dict() return exp_claim.as_dict()

View File

@ -1,153 +1,57 @@
{ {
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2016-09-03 19:20:14.561962", "creation": "2016-09-03 19:20:14.561962",
"custom": 0,
"docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "Document", "document_type": "Document",
"editable_grid": 1, "editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"service_item",
"type",
"frequency",
"expense_amount"
],
"fields": [ "fields": [
{ {
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "service_item", "fieldname": "service_item",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Service Item", "label": "Service Item",
"length": 0,
"no_copy": 0,
"options": "\nBrake Oil\nBrake Pad\nClutch Plate\nEngine Oil\nOil Change\nWheels", "options": "\nBrake Oil\nBrake Pad\nClutch Plate\nEngine Oil\nOil Change\nWheels",
"permlevel": 0, "reqd": 1
"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,
"unique": 0
}, },
{ {
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "type", "fieldname": "type",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Type", "label": "Type",
"length": 0,
"no_copy": 0,
"options": "\nInspection\nService\nChange", "options": "\nInspection\nService\nChange",
"permlevel": 0, "reqd": 1
"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,
"unique": 0
}, },
{ {
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "frequency", "fieldname": "frequency",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Frequency", "label": "Frequency",
"length": 0,
"no_copy": 0,
"options": "\nMileage\nMonthly\nQuarterly\nHalf Yearly\nYearly", "options": "\nMileage\nMonthly\nQuarterly\nHalf Yearly\nYearly",
"permlevel": 0, "reqd": 1
"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,
"unique": 0
}, },
{ {
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "expense_amount", "fieldname": "expense_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Expense", "label": "Expense",
"length": 0, "reqd": 1
"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": 0,
"set_only_once": 0,
"unique": 0
} }
], ],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "modified": "2020-03-18 16:49:46.645004",
"modified": "2017-01-09 11:10:29.476907",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "HR", "module": "HR",
"name": "Vehicle Service", "name": "Vehicle Service",
"name_case": "",
"owner": "Administrator", "owner": "Administrator",
"permissions": [], "permissions": [],
"quick_entry": 1, "quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",
"track_changes": 1, "track_changes": 1
"track_seen": 0
} }

View File

@ -0,0 +1,54 @@
{
"cards": [
{
"links": "[\n {\n \"description\": \"Loan Type for interest and penalty rates\",\n \"label\": \"Loan Type\",\n \"name\": \"Loan Type\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Loan Applications from customers and employees.\",\n \"label\": \"Loan Application\",\n \"name\": \"Loan Application\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Loans provided to customers and employees.\",\n \"label\": \"Loan\",\n \"name\": \"Loan\",\n \"type\": \"doctype\"\n }\n]",
"title": "Loan"
},
{
"links": "[\n {\n \"label\": \"Process Loan Security Shortfall\",\n \"name\": \"Process Loan Security Shortfall\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Process Loan Interest Accrual\",\n \"name\": \"Process Loan Interest Accrual\",\n \"type\": \"doctype\"\n }\n]",
"title": "Loan Processes"
},
{
"links": "[\n {\n \"label\": \"Loan Disbursement\",\n \"name\": \"Loan Disbursement\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Repayment\",\n \"name\": \"Loan Repayment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Interest Accrual\",\n \"name\": \"Loan Interest Accrual\",\n \"type\": \"doctype\"\n }\n]",
"title": "Disbursement and Repayment"
},
{
"links": "[\n {\n \"label\": \"Loan Security Type\",\n \"name\": \"Loan Security Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security Price\",\n \"name\": \"Loan Security Price\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security\",\n \"name\": \"Loan Security\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security Pledge\",\n \"name\": \"Loan Security Pledge\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security Unpledge\",\n \"name\": \"Loan Security Unpledge\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security Shortfall\",\n \"name\": \"Loan Security Shortfall\",\n \"type\": \"doctype\"\n }\n]",
"title": "Loan Security"
},
{
"links": "[\n {\n \"dependencies\": [\n \"Loan Repayment\"\n ],\n \"doctype\": \"Loan Repayment\",\n \"incomplete_dependencies\": [\n \"Loan Repayment\"\n ],\n \"is_query_report\": true,\n \"label\": \"Loan Repayment and Closure\",\n \"name\": \"Loan Repayment and Closure\",\n \"route\": \"#query-report/Loan Repayment and Closure\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Loan Security Pledge\"\n ],\n \"doctype\": \"Loan Security Pledge\",\n \"incomplete_dependencies\": [\n \"Loan Security Pledge\"\n ],\n \"is_query_report\": true,\n \"label\": \"Loan Security Status\",\n \"name\": \"Loan Security Status\",\n \"route\": \"#query-report/Loan Security Status\",\n \"type\": \"report\"\n }\n]",
"title": "Reports"
}
],
"category": "Modules",
"charts": [],
"creation": "2020-03-12 16:35:55.299820",
"developer_mode_only": 0,
"disable_user_customization": 0,
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
"idx": 0,
"is_standard": 1,
"label": "Loan Management",
"modified": "2020-03-12 16:38:00.347959",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Loan Management",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"shortcuts": [
{
"is_query_report": 0,
"link_to": "Loan Application",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Loan",
"type": "DocType"
}
]
}

View File

@ -273,11 +273,11 @@ class TestLoan(unittest.TestCase):
penalty_amount = (accrued_interest_amount * 4 * 25) / (100 * days_in_year(get_datetime(first_date).year)) penalty_amount = (accrued_interest_amount * 4 * 25) / (100 * days_in_year(get_datetime(first_date).year))
lia = frappe.get_all("Loan Interest Accrual", fields=["is_paid"], lia1 = frappe.get_value("Loan Interest Accrual", {"loan": loan.name, "is_paid": 1}, 'name')
filters={"loan": loan.name}, order_by="posting_date") lia2 = frappe.get_value("Loan Interest Accrual", {"loan": loan.name, "is_paid": 0}, 'name')
self.assertTrue(lia[0].get('is_paid')) self.assertTrue(lia1)
self.assertFalse(lia[1].get('is_paid')) self.assertTrue(lia2)
def test_security_shortfall(self): def test_security_shortfall(self):
pledges = [] pledges = []
@ -294,18 +294,21 @@ class TestLoan(unittest.TestCase):
make_loan_disbursement_entry(loan.name, loan.loan_amount) make_loan_disbursement_entry(loan.name, loan.loan_amount)
frappe.db.sql(""" UPDATE `tabLoan Security Price` SET loan_security_price = %s frappe.db.sql(""" UPDATE `tabLoan Security Price` SET loan_security_price = 100
where loan_security=%s""", (100, 'Test Security 2')) where loan_security='Test Security 2'""")
check_for_ltv_shortfall() check_for_ltv_shortfall()
loan_security_shortfall = frappe.get_doc("Loan Security Shortfall", {"loan": loan.name}) loan_security_shortfall = frappe.get_doc("Loan Security Shortfall", {"loan": loan.name})
self.assertTrue(loan_security_shortfall) self.assertTrue(loan_security_shortfall)
self.assertEquals(loan_security_shortfall.loan_amount, 1000000.00) self.assertEquals(loan_security_shortfall.loan_amount, 1000000.00)
self.assertEquals(loan_security_shortfall.security_value, 400000.00) self.assertEquals(loan_security_shortfall.security_value, 400000.00)
self.assertEquals(loan_security_shortfall.shortfall_amount, 600000.00) self.assertEquals(loan_security_shortfall.shortfall_amount, 600000.00)
frappe.db.sql(""" UPDATE `tabLoan Security Price` SET loan_security_price = 250
where loan_security='Test Security 2'""")
def create_loan_accounts(): def create_loan_accounts():
if not frappe.db.exists("Account", "Loans and Advances (Assets) - _TC"): if not frappe.db.exists("Account", "Loans and Advances (Assets) - _TC"):
frappe.get_doc({ frappe.get_doc({
@ -399,7 +402,8 @@ def create_loan_security_type():
"doctype": "Loan Security Type", "doctype": "Loan Security Type",
"loan_security_type": "Stock", "loan_security_type": "Stock",
"unit_of_measure": "Nos", "unit_of_measure": "Nos",
"haircut": 50.00 "haircut": 50.00,
"loan_to_value_ratio": 50
}).insert(ignore_permissions=True) }).insert(ignore_permissions=True)
def create_loan_security(): def create_loan_security():

View File

@ -130,6 +130,7 @@ def make_accrual_interest_entry_for_term_loans(posting_date=None):
loan.loan_account, loan.principal_amount + loan.balance_loan_amount, loan.interest_amount, loan.loan_account, loan.principal_amount + loan.balance_loan_amount, loan.interest_amount,
payable_principal = loan.principal_amount , posting_date=posting_date) payable_principal = loan.principal_amount , posting_date=posting_date)
if accrued_entries:
frappe.db.sql("""UPDATE `tabRepayment Schedule` frappe.db.sql("""UPDATE `tabRepayment Schedule`
SET is_accrued = 1 where name in (%s)""" #nosec SET is_accrued = 1 where name in (%s)""" #nosec
% ", ".join(['%s']*len(accrued_entries)), tuple(accrued_entries)) % ", ".join(['%s']*len(accrued_entries)), tuple(accrued_entries))

View File

@ -0,0 +1,52 @@
{
"cards": [
{
"icon": "fa fa-star",
"links": "[\n {\n \"dependencies\": [\n \"Item\",\n \"BOM\"\n ],\n \"description\": \"Orders released for production.\",\n \"label\": \"Work Order\",\n \"name\": \"Work Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"BOM\"\n ],\n \"description\": \"Generate Material Requests (MRP) and Work Orders.\",\n \"label\": \"Production Plan\",\n \"name\": \"Production Plan\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Stock Entry\",\n \"name\": \"Stock Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Activity Type\"\n ],\n \"description\": \"Time Sheet for manufacturing.\",\n \"label\": \"Timesheet\",\n \"name\": \"Timesheet\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Job Card\",\n \"name\": \"Job Card\",\n \"type\": \"doctype\"\n }\n]",
"title": "Production"
},
{
"links": "[\n {\n \"description\": \"All Products or Services.\",\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Bill of Materials (BOM)\",\n \"label\": \"Bill of Materials\",\n \"name\": \"BOM\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Where manufacturing operations are carried.\",\n \"label\": \"Workstation\",\n \"name\": \"Workstation\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Details of the operations carried out.\",\n \"label\": \"Operation\",\n \"name\": \"Operation\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Routing\",\n \"name\": \"Routing\",\n \"type\": \"doctype\"\n }\n]",
"title": "Bill of Materials"
},
{
"icon": "fa fa-list",
"links": "[\n {\n \"dependencies\": [\n \"Work Order\"\n ],\n \"doctype\": \"Work Order\",\n \"is_query_report\": true,\n \"label\": \"Open Work Orders\",\n \"name\": \"Open Work Orders\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Work Order\"\n ],\n \"doctype\": \"Work Order\",\n \"is_query_report\": true,\n \"label\": \"Work Orders in Progress\",\n \"name\": \"Work Orders in Progress\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Work Order\"\n ],\n \"doctype\": \"Work Order\",\n \"is_query_report\": true,\n \"label\": \"Issued Items Against Work Order\",\n \"name\": \"Issued Items Against Work Order\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Work Order\"\n ],\n \"doctype\": \"Work Order\",\n \"is_query_report\": true,\n \"label\": \"Completed Work Orders\",\n \"name\": \"Completed Work Orders\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Work Order\"\n ],\n \"doctype\": \"Work Order\",\n \"is_query_report\": true,\n \"label\": \"Production Analytics\",\n \"name\": \"Production Analytics\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"BOM\"\n ],\n \"doctype\": \"BOM\",\n \"is_query_report\": true,\n \"label\": \"BOM Search\",\n \"name\": \"BOM Search\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"BOM\"\n ],\n \"doctype\": \"BOM\",\n \"is_query_report\": true,\n \"label\": \"BOM Stock Report\",\n \"name\": \"BOM Stock Report\",\n \"type\": \"report\"\n }\n]",
"title": "Reports"
},
{
"icon": "fa fa-wrench",
"links": "[\n {\n \"description\": \"Replace BOM and update latest price in all BOMs\",\n \"label\": \"BOM Update Tool\",\n \"name\": \"BOM Update Tool\",\n \"type\": \"doctype\"\n },\n {\n \"data_doctype\": \"BOM\",\n \"description\": \"Compare BOMs for changes in Raw Materials and Operations\",\n \"label\": \"BOM Comparison Tool\",\n \"name\": \"bom-comparison-tool\",\n \"type\": \"page\"\n }\n]",
"title": "Tools"
},
{
"links": "[\n {\n \"description\": \"Global settings for all manufacturing processes.\",\n \"label\": \"Manufacturing Settings\",\n \"name\": \"Manufacturing Settings\",\n \"type\": \"doctype\"\n }\n]",
"title": "Settings"
},
{
"icon": "fa fa-facetime-video",
"links": "[\n {\n \"label\": \"Work Order\",\n \"name\": \"Work Order\",\n \"type\": \"help\",\n \"youtube_id\": \"ZotgLyp2YFY\"\n }\n]",
"title": "Help"
}
],
"category": "Domains",
"charts": [],
"creation": "2020-03-02 17:11:37.032604",
"developer_mode_only": 0,
"disable_user_customization": 0,
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
"idx": 0,
"is_standard": 1,
"label": "Manufacturing",
"modified": "2020-03-12 16:30:36.389877",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Manufacturing",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"restrict_to_domain": "Manufacturing",
"shortcuts": []
}

View File

@ -498,6 +498,14 @@ class BOM(WebsiteGenerator):
self.scrap_material_cost = total_sm_cost self.scrap_material_cost = total_sm_cost
self.base_scrap_material_cost = base_total_sm_cost self.base_scrap_material_cost = base_total_sm_cost
def update_new_bom(self, old_bom, new_bom, rate):
for d in self.get("items"):
if d.bom_no != old_bom: continue
d.bom_no = new_bom
d.rate = rate
d.amount = (d.stock_qty or d.qty) * rate
def update_exploded_items(self): def update_exploded_items(self):
""" Update Flat BOM, following will be correct data""" """ Update Flat BOM, following will be correct data"""
self.get_exploded_items() self.get_exploded_items()
@ -827,6 +835,10 @@ def add_operations_cost(stock_entry, work_order=None, expense_account=None):
def get_bom_diff(bom1, bom2): def get_bom_diff(bom1, bom2):
from frappe.model import table_fields from frappe.model import table_fields
if bom1 == bom2:
frappe.throw(_("BOM 1 {0} and BOM 2 {1} should not be same")
.format(frappe.bold(bom1), frappe.bold(bom2)))
doc1 = frappe.get_doc('BOM', bom1) doc1 = frappe.get_doc('BOM', bom1)
doc2 = frappe.get_doc('BOM', bom2) doc2 = frappe.get_doc('BOM', bom2)

View File

@ -14,10 +14,13 @@ import click
class BOMUpdateTool(Document): class BOMUpdateTool(Document):
def replace_bom(self): def replace_bom(self):
self.validate_bom() self.validate_bom()
self.update_new_bom()
unit_cost = get_new_bom_unit_cost(self.new_bom)
self.update_new_bom(unit_cost)
frappe.cache().delete_key('bom_children') frappe.cache().delete_key('bom_children')
bom_list = self.get_parent_boms(self.new_bom) bom_list = self.get_parent_boms(self.new_bom)
updated_bom = []
with click.progressbar(bom_list) as bom_list: with click.progressbar(bom_list) as bom_list:
pass pass
for bom in bom_list: for bom in bom_list:
@ -26,7 +29,9 @@ class BOMUpdateTool(Document):
# this is only used for versioning and we do not want # this is only used for versioning and we do not want
# to make separate db calls by using load_doc_before_save # to make separate db calls by using load_doc_before_save
# which proves to be expensive while doing bulk replace # which proves to be expensive while doing bulk replace
bom_obj._doc_before_save = bom_obj.as_dict() bom_obj._doc_before_save = bom_obj
bom_obj.update_new_bom(self.current_bom, self.new_bom, unit_cost)
bom_obj.update_exploded_items()
bom_obj.calculate_cost() bom_obj.calculate_cost()
bom_obj.update_parent_cost() bom_obj.update_parent_cost()
bom_obj.db_update() bom_obj.db_update()
@ -43,14 +48,10 @@ class BOMUpdateTool(Document):
!= frappe.db.get_value("BOM", self.new_bom, "item"): != frappe.db.get_value("BOM", self.new_bom, "item"):
frappe.throw(_("The selected BOMs are not for the same item")) frappe.throw(_("The selected BOMs are not for the same item"))
def update_new_bom(self): def update_new_bom(self, unit_cost):
new_bom_unitcost = frappe.db.sql("""SELECT `total_cost`/`quantity`
FROM `tabBOM` WHERE name = %s""", self.new_bom)
new_bom_unitcost = flt(new_bom_unitcost[0][0]) if new_bom_unitcost else 0
frappe.db.sql("""update `tabBOM Item` set bom_no=%s, frappe.db.sql("""update `tabBOM Item` set bom_no=%s,
rate=%s, amount=stock_qty*%s where bom_no = %s and docstatus < 2 and parenttype='BOM'""", rate=%s, amount=stock_qty*%s where bom_no = %s and docstatus < 2 and parenttype='BOM'""",
(self.new_bom, new_bom_unitcost, new_bom_unitcost, self.current_bom)) (self.new_bom, unit_cost, unit_cost, self.current_bom))
def get_parent_boms(self, bom, bom_list=[]): def get_parent_boms(self, bom, bom_list=[]):
data = frappe.db.sql("""SELECT DISTINCT parent FROM `tabBOM Item` data = frappe.db.sql("""SELECT DISTINCT parent FROM `tabBOM Item`
@ -65,12 +66,18 @@ class BOMUpdateTool(Document):
return list(set(bom_list)) return list(set(bom_list))
def get_new_bom_unit_cost(bom):
new_bom_unitcost = frappe.db.sql("""SELECT `total_cost`/`quantity`
FROM `tabBOM` WHERE name = %s""", bom)
return flt(new_bom_unitcost[0][0]) if new_bom_unitcost else 0
@frappe.whitelist() @frappe.whitelist()
def enqueue_replace_bom(args): def enqueue_replace_bom(args):
if isinstance(args, string_types): if isinstance(args, string_types):
args = json.loads(args) args = json.loads(args)
frappe.enqueue("erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.replace_bom", args=args, timeout=4000) frappe.enqueue("erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.replace_bom", args=args, timeout=40000)
frappe.msgprint(_("Queued for replacing the BOM. It may take a few minutes.")) frappe.msgprint(_("Queued for replacing the BOM. It may take a few minutes."))
@frappe.whitelist() @frappe.whitelist()

View File

@ -14,6 +14,7 @@ from erpnext.stock.utils import get_bin
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
from erpnext.stock.doctype.item.test_item import make_item from erpnext.stock.doctype.item.test_item import make_item
from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
class TestWorkOrder(unittest.TestCase): class TestWorkOrder(unittest.TestCase):
def setUp(self): def setUp(self):
@ -82,6 +83,37 @@ class TestWorkOrder(unittest.TestCase):
wo_order.set_work_order_operations() wo_order.set_work_order_operations()
self.assertEqual(wo_order.planned_operating_cost, cost*2) self.assertEqual(wo_order.planned_operating_cost, cost*2)
def test_resered_qty_for_partial_completion(self):
item = "_Test Item"
warehouse = create_warehouse("Test Warehouse for reserved_qty - _TC")
bin1_at_start = get_bin(item, warehouse)
# reset to correct value
bin1_at_start.update_reserved_qty_for_production()
wo_order = make_wo_order_test_record(item="_Test FG Item", qty=2,
source_warehouse=warehouse, skip_transfer=1)
bin1_on_submit = get_bin(item, warehouse)
# reserved qty for production is updated
self.assertEqual(cint(bin1_at_start.reserved_qty_for_production) + 2,
cint(bin1_on_submit.reserved_qty_for_production))
test_stock_entry.make_stock_entry(item_code="_Test Item",
target=warehouse, qty=100, basic_rate=100)
test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
target=warehouse, qty=100, basic_rate=100)
s = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 1))
s.submit()
bin1_at_completion = get_bin(item, warehouse)
self.assertEqual(cint(bin1_at_completion.reserved_qty_for_production),
cint(bin1_on_submit.reserved_qty_for_production) - 1)
def test_production_item(self): def test_production_item(self):
wo_order = make_wo_order_test_record(item="_Test FG Item", qty=1, do_not_save=True) wo_order = make_wo_order_test_record(item="_Test FG Item", qty=1, do_not_save=True)
frappe.db.set_value("Item", "_Test FG Item", "end_of_life", "2000-1-1") frappe.db.set_value("Item", "_Test FG Item", "end_of_life", "2000-1-1")
@ -404,7 +436,7 @@ def make_wo_order_test_record(**args):
wo_order.company = args.company or "_Test Company" wo_order.company = args.company or "_Test Company"
wo_order.stock_uom = args.stock_uom or "_Test UOM" wo_order.stock_uom = args.stock_uom or "_Test UOM"
wo_order.use_multi_level_bom=0 wo_order.use_multi_level_bom=0
wo_order.skip_transfer=1 wo_order.skip_transfer=args.skip_transfer or 0
wo_order.get_items_and_operations_from_bom() wo_order.get_items_and_operations_from_bom()
wo_order.sales_order = args.sales_order or None wo_order.sales_order = args.sales_order or None
wo_order.planned_start_date = args.planned_start_date or now() wo_order.planned_start_date = args.planned_start_date or now()

View File

@ -279,7 +279,7 @@ class WorkOrder(Document):
if enable_capacity_planning and job_card_doc: if enable_capacity_planning and job_card_doc:
row.planned_start_time = job_card_doc.time_logs[-1].from_time row.planned_start_time = job_card_doc.time_logs[-1].from_time
row.planned_end_time = job_card_doc.time_logs[-1].to_time row.planned_end_time = job_card_doc.time_logs[-1].to_time
print(row.planned_start_time, original_start_time, plan_days)
if date_diff(row.planned_start_time, original_start_time) > plan_days: if date_diff(row.planned_start_time, original_start_time) > plan_days:
frappe.message_log.pop() frappe.message_log.pop()
frappe.throw(_("Unable to find the time slot in the next {0} days for the operation {1}.") frappe.throw(_("Unable to find the time slot in the next {0} days for the operation {1}.")
@ -314,7 +314,7 @@ class WorkOrder(Document):
stock_entry = frappe.db.sql("""select name from `tabStock Entry` stock_entry = frappe.db.sql("""select name from `tabStock Entry`
where work_order = %s and docstatus = 1""", self.name) where work_order = %s and docstatus = 1""", self.name)
if stock_entry: if stock_entry:
frappe.throw(_("Cannot cancel because submitted Stock Entry {0} exists").format(stock_entry[0][0])) frappe.throw(_("Cannot cancel because submitted Stock Entry {0} exists").format(frappe.utils.get_link_to_form('Stock Entry', stock_entry[0][0])))
def update_planned_qty(self): def update_planned_qty(self):
update_bin_qty(self.production_item, self.fg_warehouse, { update_bin_qty(self.production_item, self.fg_warehouse, {
@ -468,6 +468,9 @@ class WorkOrder(Document):
update bin reserved_qty_for_production update bin reserved_qty_for_production
called from Stock Entry for production, after submit, cancel called from Stock Entry for production, after submit, cancel
''' '''
# calculate consumed qty based on submitted stock entries
self.update_consumed_qty_for_required_items()
if self.docstatus==1: if self.docstatus==1:
# calculate transferred qty based on submitted stock entries # calculate transferred qty based on submitted stock entries
self.update_transaferred_qty_for_required_items() self.update_transaferred_qty_for_required_items()
@ -475,9 +478,6 @@ class WorkOrder(Document):
# update in bin # update in bin
self.update_reserved_qty_for_production() self.update_reserved_qty_for_production()
# calculate consumed qty based on submitted stock entries
self.update_consumed_qty_for_required_items()
def update_reserved_qty_for_production(self, items=None): def update_reserved_qty_for_production(self, items=None):
'''update reserved_qty_for_production in bins''' '''update reserved_qty_for_production in bins'''
for d in self.required_items: for d in self.required_items:

View File

@ -22,7 +22,14 @@ erpnext.BOMComparisonTool = class BOMComparisonTool {
fieldname: 'name1', fieldname: 'name1',
fieldtype: 'Link', fieldtype: 'Link',
options: 'BOM', options: 'BOM',
change: () => this.fetch_and_render() change: () => this.fetch_and_render(),
get_query: () => {
return {
filters: {
"name": ["not in", [this.form.get_value("name2") || ""]]
}
}
}
}, },
{ {
fieldtype: 'Column Break' fieldtype: 'Column Break'
@ -32,7 +39,14 @@ erpnext.BOMComparisonTool = class BOMComparisonTool {
fieldname: 'name2', fieldname: 'name2',
fieldtype: 'Link', fieldtype: 'Link',
options: 'BOM', options: 'BOM',
change: () => this.fetch_and_render() change: () => this.fetch_and_render(),
get_query: () => {
return {
filters: {
"name": ["not in", [this.form.get_value("name1") || ""]]
}
}
}
}, },
{ {
fieldtype: 'Section Break' fieldtype: 'Section Break'

View File

@ -0,0 +1,50 @@
{
"cards": [
{
"icon": "icon-list",
"links": "[\n {\n \"description\": \"Define various loan types\",\n \"label\": \"Loan Type\",\n \"name\": \"Loan Type\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Loan Application\",\n \"label\": \"Loan Application\",\n \"name\": \"Loan Application\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan\",\n \"name\": \"Loan\",\n \"type\": \"doctype\"\n }\n]",
"title": "Loan Management"
},
{
"links": "[\n {\n \"description\": \"Grant information.\",\n \"label\": \"Grant Application\",\n \"name\": \"Grant Application\",\n \"type\": \"doctype\"\n }\n]",
"title": "Grant Application"
},
{
"links": "[\n {\n \"description\": \"Member information.\",\n \"label\": \"Member\",\n \"name\": \"Member\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Memebership Details\",\n \"label\": \"Membership\",\n \"name\": \"Membership\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Memebership Type Details\",\n \"label\": \"Membership Type\",\n \"name\": \"Membership Type\",\n \"type\": \"doctype\"\n }\n]",
"title": "Membership"
},
{
"links": "[\n {\n \"description\": \"Volunteer information.\",\n \"label\": \"Volunteer\",\n \"name\": \"Volunteer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Volunteer Type information.\",\n \"label\": \"Volunteer Type\",\n \"name\": \"Volunteer Type\",\n \"type\": \"doctype\"\n }\n]",
"title": "Volunteer"
},
{
"icon": "fa fa-star",
"links": "[\n {\n \"description\": \"Chapter information.\",\n \"label\": \"Chapter\",\n \"name\": \"Chapter\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]",
"title": "Chapter"
},
{
"links": "[\n {\n \"description\": \"Donor information.\",\n \"label\": \"Donor\",\n \"name\": \"Donor\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Donor Type information.\",\n \"label\": \"Donor Type\",\n \"name\": \"Donor Type\",\n \"type\": \"doctype\"\n }\n]",
"title": "Donor"
}
],
"category": "Domains",
"charts": [],
"creation": "2020-03-02 17:23:47.811421",
"developer_mode_only": 0,
"disable_user_customization": 0,
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
"idx": 0,
"is_standard": 1,
"label": "Non Profit",
"modified": "2020-03-12 16:30:36.683012",
"modified_by": "Administrator",
"module": "Non Profit",
"name": "Non Profit",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"restrict_to_domain": "Non Profit",
"shortcuts": []
}

View File

@ -658,4 +658,5 @@ erpnext.patches.v12_0.set_permission_einvoicing
erpnext.patches.v12_0.set_published_in_hub_tracked_item erpnext.patches.v12_0.set_published_in_hub_tracked_item
erpnext.patches.v12_0.set_job_offer_applicant_email erpnext.patches.v12_0.set_job_offer_applicant_email
erpnext.patches.v12_0.create_irs_1099_field_united_states erpnext.patches.v12_0.create_irs_1099_field_united_states
erpnext.patches.v12_0.move_bank_account_swift_number_to_bank
erpnext.patches.v12_0.rename_bank_reconciliation_fields # 2020-01-22 erpnext.patches.v12_0.rename_bank_reconciliation_fields # 2020-01-22

View File

@ -0,0 +1,14 @@
from __future__ import unicode_literals
import frappe
def execute():
frappe.reload_doc('accounts', 'doctype', 'bank', force=1)
frappe.db.sql("""
UPDATE `tabBank` b, `tabBank Account` ba
SET b.swift_number = ba.swift_number, b.branch_code = ba.branch_code
WHERE b.name = ba.bank
""")
frappe.reload_doc('accounts', 'doctype', 'bank_account')
frappe.reload_doc('accounts', 'doctype', 'payment_request')

View File

@ -0,0 +1,61 @@
{
"cards": [
{
"icon": "fa fa-star",
"links": "[\n {\n \"description\": \"Project master.\",\n \"label\": \"Project\",\n \"name\": \"Project\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Project activity / task.\",\n \"label\": \"Task\",\n \"name\": \"Task\",\n \"onboard\": 1,\n \"route\": \"#List/Task\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Make project from a template.\",\n \"label\": \"Project Template\",\n \"name\": \"Project Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Define Project type.\",\n \"label\": \"Project Type\",\n \"name\": \"Project Type\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Project\"\n ],\n \"description\": \"Project Update.\",\n \"label\": \"Project Update\",\n \"name\": \"Project Update\",\n \"type\": \"doctype\"\n }\n]",
"title": "Projects"
},
{
"links": "[\n {\n \"description\": \"Timesheet for tasks.\",\n \"label\": \"Timesheet\",\n \"name\": \"Timesheet\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Types of activities for Time Logs\",\n \"label\": \"Activity Type\",\n \"name\": \"Activity Type\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Activity Type\"\n ],\n \"description\": \"Cost of various activities\",\n \"label\": \"Activity Cost\",\n \"name\": \"Activity Cost\",\n \"type\": \"doctype\"\n }\n]",
"title": "Time Tracking"
},
{
"icon": "fa fa-list",
"links": "[\n {\n \"dependencies\": [\n \"Timesheet\"\n ],\n \"doctype\": \"Timesheet\",\n \"is_query_report\": true,\n \"label\": \"Daily Timesheet Summary\",\n \"name\": \"Daily Timesheet Summary\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Project\"\n ],\n \"doctype\": \"Project\",\n \"is_query_report\": true,\n \"label\": \"Project wise Stock Tracking\",\n \"name\": \"Project wise Stock Tracking\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Project\"\n ],\n \"doctype\": \"Project\",\n \"is_query_report\": true,\n \"label\": \"Project Billing Summary\",\n \"name\": \"Project Billing Summary\",\n \"type\": \"report\"\n }\n]",
"title": "Reports"
}
],
"category": "Modules",
"charts": [],
"creation": "2020-03-02 15:46:04.874669",
"developer_mode_only": 0,
"disable_user_customization": 0,
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
"icon": "",
"idx": 0,
"is_standard": 1,
"label": "Projects",
"modified": "2020-03-12 16:30:41.538685",
"modified_by": "Administrator",
"module": "Projects",
"name": "Projects",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"shortcuts": [
{
"format": "{} Assigned",
"is_query_report": 0,
"link_to": "Task",
"stats_filter": "{\n \"_assign\": [\"like\", '%' + frappe.session.user + '%'],\n \"status\": \"Open\"\n}",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Project",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Timesheet",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Project Billing Summary",
"type": "Report"
}
]
}

View File

@ -1,4 +1,5 @@
{ {
"actions": [],
"allow_import": 1, "allow_import": 1,
"autoname": "TASK-.YYYY.-.#####", "autoname": "TASK-.YYYY.-.#####",
"creation": "2013-01-29 19:25:50", "creation": "2013-01-29 19:25:50",
@ -200,7 +201,6 @@
{ {
"fieldname": "description", "fieldname": "description",
"fieldtype": "Text Editor", "fieldtype": "Text Editor",
"in_preview": 1,
"label": "Task Description", "label": "Task Description",
"oldfieldname": "description", "oldfieldname": "description",
"oldfieldtype": "Text Editor", "oldfieldtype": "Text Editor",
@ -361,11 +361,14 @@
], ],
"icon": "fa fa-check", "icon": "fa fa-check",
"idx": 1, "idx": 1,
"is_tree": 1,
"links": [],
"max_attachments": 5, "max_attachments": 5,
"modified": "2019-09-10 13:46:24.631754", "modified": "2020-03-18 18:08:44.153211",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Projects", "module": "Projects",
"name": "Task", "name": "Task",
"nsm_parent_field": "parent_task",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {

View File

@ -4,7 +4,7 @@
erpnext.TransactionController = erpnext.taxes_and_totals.extend({ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
setup: function() { setup: function() {
this._super(); this._super();
frappe.flags.hide_serial_batch_dialog = false; frappe.flags.hide_serial_batch_dialog = true;
frappe.ui.form.on(this.frm.doctype + " Item", "rate", function(frm, cdt, cdn) { frappe.ui.form.on(this.frm.doctype + " Item", "rate", function(frm, cdt, cdn) {
var item = frappe.get_doc(cdt, cdn); var item = frappe.get_doc(cdt, cdn);
var has_margin_field = frappe.meta.has_field(cdt, 'margin_type'); var has_margin_field = frappe.meta.has_field(cdt, 'margin_type');
@ -165,6 +165,16 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
return (doc.rule_applied) ? "green" : "red"; return (doc.rule_applied) ? "green" : "red";
}); });
} }
let batch_no_field = this.frm.get_docfield("items", "batch_no");
if (batch_no_field) {
batch_no_field.get_route_options_for_new_doc = function(row) {
return {
"item": row.doc.item_code
}
};
}
}, },
onload: function() { onload: function() {
var me = this; var me = this;
@ -519,6 +529,15 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
} }
}, },
() => me.toggle_conversion_factor(item), () => me.toggle_conversion_factor(item),
() => {
if (show_batch_dialog)
return frappe.db.get_value("Item", item.item_code, ["has_batch_no", "has_serial_no"])
.then((r) => {
if(r.message.has_batch_no || r.message.has_serial_no) {
frappe.flags.hide_serial_batch_dialog = false;
}
});
},
() => { () => {
if(show_batch_dialog && !frappe.flags.hide_serial_batch_dialog) { if(show_batch_dialog && !frappe.flags.hide_serial_batch_dialog) {
var d = locals[cdt][cdn]; var d = locals[cdt][cdn];
@ -528,7 +547,9 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
erpnext.show_serial_batch_selector(me.frm, d, (item) => { erpnext.show_serial_batch_selector(me.frm, d, (item) => {
me.frm.script_manager.trigger('qty', item.doctype, item.name); me.frm.script_manager.trigger('qty', item.doctype, item.name);
}); if (!me.frm.doc.set_warehouse)
me.frm.script_manager.trigger('warehouse', item.doctype, item.name);
}, undefined, !frappe.flags.hide_serial_batch_dialog);
} }
}, },
() => me.conversion_factor(doc, cdt, cdn, true), () => me.conversion_factor(doc, cdt, cdn, true),

View File

@ -1,11 +1,13 @@
frappe.provide('frappe.ui.form'); frappe.provide('frappe.ui.form');
erpnext.doctypes_with_dimensions = ["GL Entry", "Sales Invoice", "Purchase Invoice", "Payment Entry", "Asset", let default_dimensions = {};
let doctypes_with_dimensions = ["GL Entry", "Sales Invoice", "Purchase Invoice", "Payment Entry", "Asset",
"Expense Claim", "Stock Entry", "Budget", "Payroll Entry", "Delivery Note", "Shipping Rule", "Loyalty Program", "Expense Claim", "Stock Entry", "Budget", "Payroll Entry", "Delivery Note", "Shipping Rule", "Loyalty Program",
"Fee Schedule", "Fee Structure", "Stock Reconciliation", "Travel Request", "Fees", "POS Profile", "Opening Invoice Creation Tool", "Fee Schedule", "Fee Structure", "Stock Reconciliation", "Travel Request", "Fees", "POS Profile", "Opening Invoice Creation Tool",
"Subscription", "Purchase Order", "Journal Entry", "Material Request", "Purchase Receipt", "Landed Cost Item", "Asset"]; "Subscription", "Purchase Order", "Journal Entry", "Material Request", "Purchase Receipt", "Landed Cost Item", "Asset"];
erpnext.child_docs = ["Sales Invoice Item", "Purchase Invoice Item", "Purchase Order Item", "Journal Entry Account", let child_docs = ["Sales Invoice Item", "Purchase Invoice Item", "Purchase Order Item", "Journal Entry Account",
"Material Request Item", "Delivery Note Item", "Purchase Receipt Item", "Stock Entry Detail", "Payment Entry Deduction", "Material Request Item", "Delivery Note Item", "Purchase Receipt Item", "Stock Entry Detail", "Payment Entry Deduction",
"Landed Cost Item", "Asset Value Adjustment", "Opening Invoice Creation Tool Item", "Subscription Plan"]; "Landed Cost Item", "Asset Value Adjustment", "Opening Invoice Creation Tool Item", "Subscription Plan"];
@ -13,11 +15,11 @@ frappe.call({
method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.get_dimension_filters", method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.get_dimension_filters",
callback: function(r) { callback: function(r) {
erpnext.dimension_filters = r.message[0]; erpnext.dimension_filters = r.message[0];
erpnext.default_dimensions = r.message[1]; default_dimensions = r.message[1];
} }
}); });
erpnext.doctypes_with_dimensions.forEach((doctype) => { doctypes_with_dimensions.forEach((doctype) => {
frappe.ui.form.on(doctype, { frappe.ui.form.on(doctype, {
onload: function(frm) { onload: function(frm) {
erpnext.dimension_filters.forEach((dimension) => { erpnext.dimension_filters.forEach((dimension) => {
@ -27,39 +29,40 @@ erpnext.doctypes_with_dimensions.forEach((doctype) => {
"is_group": 0 "is_group": 0
}); });
} }
if (Object.keys(erpnext.default_dimensions).length > 0) {
if (frappe.meta.has_field(doctype, dimension['fieldname'])) {
if (frm.is_new() && frappe.meta.has_field(doctype, 'company') && frm.doc.company) {
frm.set_value(dimension['fieldname'], erpnext.default_dimensions[frm.doc.company][dimension['document_type']]);
}
}
if (frm.doc.items && frm.doc.items.length) {
frm.doc.items[0][dimension['fieldname']] = erpnext.default_dimensions[frm.doc.company][dimension['document_type']];
}
if (frm.doc.accounts && frm.doc.accounts.length) {
frm.doc.accounts[0][dimension['fieldname']] = erpnext.default_dimensions[frm.doc.company][dimension['document_type']];
}
}
}); });
}); });
}, },
company: function(frm) { company: function(frm) {
if(frm.doc.company && (Object.keys(erpnext.default_dimensions).length > 0)) { if(frm.doc.company && (Object.keys(default_dimensions || {}).length > 0)
&& default_dimensions[frm.doc.company]) {
frm.trigger('update_dimension');
}
},
update_dimension: function(frm) {
erpnext.dimension_filters.forEach((dimension) => { erpnext.dimension_filters.forEach((dimension) => {
if (frm.is_new()) {
if (frm.doc.company && Object.keys(default_dimensions || {}).length > 0
&& default_dimensions[frm.doc.company]) {
if (frappe.meta.has_field(doctype, dimension['fieldname'])) { if (frappe.meta.has_field(doctype, dimension['fieldname'])) {
frm.set_value(dimension['fieldname'], erpnext.default_dimensions[frm.doc.company][dimension['document_type']]); frm.set_value(dimension['fieldname'],
default_dimensions[frm.doc.company][dimension['document_type']]);
}
$.each(frm.doc.items || frm.doc.accounts || [], function(i, row) {
frappe.model.set_value(row.doctype, row.name, dimension['fieldname'],
default_dimensions[frm.doc.company][dimension['document_type']])
});
}
} }
}); });
} }
},
}); });
}); });
erpnext.child_docs.forEach((doctype) => { child_docs.forEach((doctype) => {
frappe.ui.form.on(doctype, { frappe.ui.form.on(doctype, {
items_add: function(frm, cdt, cdn) { items_add: function(frm, cdt, cdn) {
erpnext.dimension_filters.forEach((dimension) => { erpnext.dimension_filters.forEach((dimension) => {
@ -75,14 +78,6 @@ erpnext.child_docs.forEach((doctype) => {
}); });
}, },
company: function(frm) {
if(frm.doc.company) {
erpnext.dimension_filters.forEach((dimension) => {
frm.set_value(dimension['fieldname'], erpnext.default_dimensions[frm.doc.company][dimension['document_type']]);
});
}
},
items_add: function(frm, cdt, cdn) { items_add: function(frm, cdt, cdn) {
erpnext.dimension_filters.forEach((dimension) => { erpnext.dimension_filters.forEach((dimension) => {
var row = frappe.get_doc(cdt, cdn); var row = frappe.get_doc(cdt, cdn);

View File

@ -5,14 +5,13 @@ erpnext.SerialNoBatchSelector = Class.extend({
this.show_dialog = show_dialog; this.show_dialog = show_dialog;
// frm, item, warehouse_details, has_batch, oldest // frm, item, warehouse_details, has_batch, oldest
let d = this.item; let d = this.item;
if (d && d.has_batch_no && (!d.batch_no || this.show_dialog)) { this.has_batch = 0; this.has_serial_no = 0;
this.has_batch = 1;
this.setup(); if (d && d.has_batch_no && (!d.batch_no || this.show_dialog)) this.has_batch = 1;
// !(this.show_dialog == false) ensures that show_dialog is implictly true, even when undefined // !(this.show_dialog == false) ensures that show_dialog is implictly true, even when undefined
} else if(d && d.has_serial_no && !(this.show_dialog == false)) { if(d && d.has_serial_no && !(this.show_dialog == false)) this.has_serial_no = 1;
this.has_batch = 0;
this.setup(); this.setup();
}
}, },
setup: function() { setup: function() {
@ -36,16 +35,16 @@ erpnext.SerialNoBatchSelector = Class.extend({
label: __('Item Code'), label: __('Item Code'),
default: me.item_code default: me.item_code
}, },
{fieldtype:'Column Break'},
{ {
fieldname: 'warehouse', fieldname: 'warehouse',
fieldtype:'Link', fieldtype:'Link',
options: 'Warehouse', options: 'Warehouse',
reqd: me.has_batch && !me.has_serial_no ? 0 : 1,
label: __(me.warehouse_details.type), label: __(me.warehouse_details.type),
default: me.warehouse_details.name, default: typeof me.warehouse_details.name == "string" ? me.warehouse_details.name : '',
onchange: function(e) { onchange: function(e) {
if(me.has_batch) { if(me.has_batch && !me.has_serial_no) {
fields = fields.concat(me.get_batch_fields()); fields = fields.concat(me.get_batch_fields());
} else { } else {
fields = fields.concat(me.get_serial_no_fields()); fields = fields.concat(me.get_serial_no_fields());
@ -74,15 +73,16 @@ erpnext.SerialNoBatchSelector = Class.extend({
{ {
fieldname: 'qty', fieldname: 'qty',
fieldtype:'Float', fieldtype:'Float',
read_only: me.has_batch, read_only: me.has_batch && !me.has_serial_no,
label: __(me.has_batch ? 'Total Qty' : 'Qty'), label: __(me.has_batch && !me.has_serial_no ? 'Total Qty' : 'Qty'),
default: 0 default: 0
}, },
{ {
fieldname: 'auto_fetch_button', fieldname: 'auto_fetch_button',
fieldtype:'Button', fieldtype:'Button',
hidden: me.has_batch, hidden: me.has_batch && !me.has_serial_no,
label: __('Fetch based on FIFO'), label: __('Auto Fetch'),
description: __('Fetch Serial Numbers based on FIFO'),
click: () => { click: () => {
let qty = this.dialog.fields_dict.qty.get_value(); let qty = this.dialog.fields_dict.qty.get_value();
let numbers = frappe.call({ let numbers = frappe.call({
@ -90,7 +90,7 @@ erpnext.SerialNoBatchSelector = Class.extend({
args: { args: {
qty: qty, qty: qty,
item_code: me.item_code, item_code: me.item_code,
warehouse: me.warehouse_details.name, warehouse: typeof me.warehouse_details.name == "string" ? me.warehouse_details.name : '',
batch_no: me.item.batch_no || null batch_no: me.item.batch_no || null
} }
}); });
@ -109,10 +109,12 @@ erpnext.SerialNoBatchSelector = Class.extend({
} }
]; ];
if (this.has_batch) { if (this.has_batch && !this.has_serial_no) {
title = __("Select Batch Numbers"); title = __("Select Batch Numbers");
fields = fields.concat(this.get_batch_fields()); fields = fields.concat(this.get_batch_fields());
} else { } else {
// if only serial no OR
// if both batch_no & serial_no then only select serial_no and auto set batches nos
title = __("Select Serial Numbers"); title = __("Select Serial Numbers");
fields = fields.concat(this.get_serial_no_fields()); fields = fields.concat(this.get_serial_no_fields());
} }
@ -122,25 +124,31 @@ erpnext.SerialNoBatchSelector = Class.extend({
fields: fields fields: fields
}); });
if (this.item.serial_no) {
this.dialog.fields_dict.serial_no.set_value(this.item.serial_no);
}
this.dialog.set_primary_action(__('Insert'), function() { this.dialog.set_primary_action(__('Insert'), function() {
me.values = me.dialog.get_values(); me.values = me.dialog.get_values();
if(me.validate()) { if(me.validate()) {
me.set_items(); frappe.run_serially([
me.dialog.hide(); () => me.update_batch_items(),
() => me.update_serial_no_item(),
() => me.update_batch_serial_no_items(),
() => {
refresh_field("items");
if (me.callback) {
return me.callback(me.item);
}
},
() => me.dialog.hide()
])
} }
}); });
if(this.show_dialog) { if(this.show_dialog) {
let d = this.item; let d = this.item;
if (d.has_serial_no && d.serial_no) { if (this.item.serial_no) {
this.dialog.set_value('serial_no', d.serial_no); this.dialog.fields_dict.serial_no.set_value(this.item.serial_no);
} }
if (d.has_batch_no && d.batch_no) { if (this.has_batch && !this.has_serial_no && d.batch_no) {
this.frm.doc.items.forEach(data => { this.frm.doc.items.forEach(data => {
if(data.item_code == d.item_code) { if(data.item_code == d.item_code) {
this.dialog.fields_dict.batches.df.data.push({ this.dialog.fields_dict.batches.df.data.push({
@ -155,7 +163,7 @@ erpnext.SerialNoBatchSelector = Class.extend({
} }
} }
if (this.has_batch) { if (this.has_batch && !this.has_serial_no) {
this.update_total_qty(); this.update_total_qty();
} }
@ -174,7 +182,7 @@ erpnext.SerialNoBatchSelector = Class.extend({
frappe.throw(__("Please select a warehouse")); frappe.throw(__("Please select a warehouse"));
return false; return false;
} }
if(this.has_batch) { if(this.has_batch && !this.has_serial_no) {
if(values.batches.length === 0 || !values.batches) { if(values.batches.length === 0 || !values.batches) {
frappe.throw(__("Please select batches for batched item " frappe.throw(__("Please select batches for batched item "
+ values.item_code)); + values.item_code));
@ -193,34 +201,23 @@ erpnext.SerialNoBatchSelector = Class.extend({
} else { } else {
let serial_nos = values.serial_no || ''; let serial_nos = values.serial_no || '';
if (!serial_nos || !serial_nos.replace(/\s/g, '').length) { if (!serial_nos || !serial_nos.replace(/\s/g, '').length) {
if (!this.show_dialog) {
frappe.throw(__("Please enter serial numbers for serialized item " frappe.throw(__("Please enter serial numbers for serialized item "
+ values.item_code)); + values.item_code));
return false; return false;
} }
}
return true; return true;
} }
}, },
set_items: function() { update_batch_items() {
var me = this; // clones an items if muliple batches are selected.
if(this.has_batch) { if(this.has_batch && !this.has_serial_no) {
this.values.batches.map((batch, i) => { this.values.batches.map((batch, i) => {
let batch_no = batch.batch_no; let batch_no = batch.batch_no;
let row = ''; let row = '';
if (i !== 0 && !this.batch_exists(batch_no)) { if (i !== 0 && !this.batch_exists(batch_no)) {
row = this.frm.add_child("items", { row = this.frm.add_child("items", { ...this.item });
'item_code': this.item.item_code,
'item_name': this.item.item_name,
'price_list_rate': this.item.price_list_rate,
'rate': this.item.rate,
'qty': batch.selected_qty,
'batch_no': batch_no,
'actual_qty': this.item.actual_qty,
'discount_percentage': this.item.discount_percentage
});
} else { } else {
row = this.frm.doc.items.find(i => i.batch_no === batch_no); row = this.frm.doc.items.find(i => i.batch_no === batch_no);
} }
@ -228,16 +225,59 @@ erpnext.SerialNoBatchSelector = Class.extend({
if (!row) { if (!row) {
row = this.item; row = this.item;
} }
// this ensures that qty & batch no is set
this.map_row_values(row, batch, 'batch_no', this.map_row_values(row, batch, 'batch_no',
'selected_qty', this.values.warehouse); 'selected_qty', this.values.warehouse);
}); });
} else { }
},
update_serial_no_item() {
// just updates serial no for the item
if(this.has_serial_no && !this.has_batch) {
this.map_row_values(this.item, this.values, 'serial_no', 'qty'); this.map_row_values(this.item, this.values, 'serial_no', 'qty');
} }
},
refresh_field("items"); update_batch_serial_no_items() {
this.callback && this.callback(this.item); // if serial no selected is from different batches, adds new rows for each batch.
if(this.has_batch && this.has_serial_no) {
const selected_serial_nos = this.values.serial_no.split(/\n/g).filter(s => s);
return frappe.db.get_list("Serial No", {
filters: { 'name': ["in", selected_serial_nos]},
fields: ["batch_no", "name"]
}).then((data) => {
// data = [{batch_no: 'batch-1', name: "SR-001"},
// {batch_no: 'batch-2', name: "SR-003"}, {batch_no: 'batch-2', name: "SR-004"}]
const batch_serial_map = data.reduce((acc, d) => {
if (!acc[d['batch_no']]) acc[d['batch_no']] = [];
acc[d['batch_no']].push(d['name'])
return acc
}, {})
// batch_serial_map = { "batch-1": ['SR-001'], "batch-2": ["SR-003", "SR-004"]}
Object.keys(batch_serial_map).map((batch_no, i) => {
let row = '';
const serial_no = batch_serial_map[batch_no];
if (i == 0) {
row = this.item;
this.map_row_values(row, {qty: serial_no.length, batch_no: batch_no}, 'batch_no',
'qty', this.values.warehouse);
} else if (!this.batch_exists(batch_no)) {
row = this.frm.add_child("items", { ...this.item });
row.batch_no = batch_no;
} else {
row = this.frm.doc.items.find(i => i.batch_no === batch_no);
}
const values = {
'qty': serial_no.length,
'serial_no': serial_no.join('\n')
}
this.map_row_values(row, values, 'serial_no',
'qty', this.values.warehouse);
});
})
}
}, },
batch_exists: function(batch) { batch_exists: function(batch) {
@ -287,7 +327,7 @@ erpnext.SerialNoBatchSelector = Class.extend({
return { return {
filters: { filters: {
item_code: me.item_code, item_code: me.item_code,
warehouse: me.warehouse || me.warehouse_details.name warehouse: me.warehouse || typeof me.warehouse_details.name == "string" ? me.warehouse_details.name : ''
}, },
query: 'erpnext.controllers.queries.get_batch_no' query: 'erpnext.controllers.queries.get_batch_no'
}; };
@ -313,11 +353,15 @@ erpnext.SerialNoBatchSelector = Class.extend({
frappe.throw(__(`Batch ${val} already selected.`)); frappe.throw(__(`Batch ${val} already selected.`));
return; return;
} }
let batch_number = me.item.batch_no ||
this.grid_row.on_grid_fields_dict.batch_no.get_value();
if (me.warehouse_details.name) { if (me.warehouse_details.name) {
frappe.call({ frappe.call({
method: 'erpnext.stock.doctype.batch.batch.get_batch_qty', method: 'erpnext.stock.doctype.batch.batch.get_batch_qty',
args: { args: {
batch_no: me.item.batch_no, batch_no: batch_number,
warehouse: me.warehouse_details.name, warehouse: me.warehouse_details.name,
item_code: me.item_code item_code: me.item_code
}, },
@ -444,7 +488,7 @@ erpnext.SerialNoBatchSelector = Class.extend({
{ {
fieldname: 'serial_no', fieldname: 'serial_no',
fieldtype: 'Small Text', fieldtype: 'Small Text',
label: __(me.has_batch ? 'Selected Batch Numbers' : 'Selected Serial Numbers'), label: __(me.has_batch && !me.has_serial_no ? 'Selected Batch Numbers' : 'Selected Serial Numbers'),
onchange: function() { onchange: function() {
me.serial_list = this.get_value() me.serial_list = this.get_value()
.replace(/\n/g, ' ').match(/\S+/g) || []; .replace(/\n/g, ' ').match(/\S+/g) || [];

View File

@ -0,0 +1,56 @@
{
"cards": [
{
"links": "[\n {\n \"description\": \"Quality Goal.\",\n \"label\": \"Quality Goal\",\n \"name\": \"Quality Goal\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Quality Procedure.\",\n \"label\": \"Quality Procedure\",\n \"name\": \"Quality Procedure\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of Quality Procedures.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Tree of Procedures\",\n \"name\": \"Quality Procedure\",\n \"route\": \"#Tree/Quality Procedure\",\n \"type\": \"doctype\"\n }\n]",
"title": "Goal and Procedure"
},
{
"links": "[\n {\n \"description\": \"Quality Feedback\",\n \"label\": \"Quality Feedback\",\n \"name\": \"Quality Feedback\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Quality Feedback Template\",\n \"label\": \"Quality Feedback Template\",\n \"name\": \"Quality Feedback Template\",\n \"type\": \"doctype\"\n }\n]",
"title": "Feedback"
},
{
"links": "[\n {\n \"description\": \"Quality Meeting\",\n \"label\": \"Quality Meeting\",\n \"name\": \"Quality Meeting\",\n \"type\": \"doctype\"\n }\n]",
"title": "Meeting"
},
{
"links": "[\n {\n \"description\": \"Quality Review\",\n \"label\": \"Quality Review\",\n \"name\": \"Quality Review\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Quality Action\",\n \"label\": \"Quality Action\",\n \"name\": \"Quality Action\",\n \"type\": \"doctype\"\n }\n]",
"title": "Review and Action"
}
],
"category": "Modules",
"charts": [],
"creation": "2020-03-02 15:49:28.632014",
"developer_mode_only": 0,
"disable_user_customization": 0,
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
"icon": "",
"idx": 0,
"is_standard": 1,
"label": "Quality",
"modified": "2020-03-12 16:30:39.093081",
"modified_by": "Administrator",
"module": "Quality Management",
"name": "Quality",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"shortcuts": [
{
"is_query_report": 0,
"link_to": "Quality Goal",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Quality Procedure",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Quality Inspection",
"type": "DocType"
}
]
}

View File

@ -1,4 +1,5 @@
{ {
"actions": [],
"autoname": "format:PRC-{quality_procedure_name}", "autoname": "format:PRC-{quality_procedure_name}",
"creation": "2018-10-06 00:06:29.756804", "creation": "2018-10-06 00:06:29.756804",
"doctype": "DocType", "doctype": "DocType",
@ -69,10 +70,13 @@
"reqd": 1 "reqd": 1
} }
], ],
"modified": "2019-08-05 13:09:29.945082", "is_tree": 1,
"links": [],
"modified": "2020-03-18 18:09:29.371627",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Quality Management", "module": "Quality Management",
"name": "Quality Procedure", "name": "Quality Procedure",
"nsm_parent_field": "parent_quality_procedure",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {

View File

@ -478,7 +478,7 @@ def get_gstins_for_company(company):
`tabDynamic Link`.parent = `tabAddress`.name and `tabDynamic Link`.parent = `tabAddress`.name and
`tabDynamic Link`.parenttype = 'Address' and `tabDynamic Link`.parenttype = 'Address' and
`tabDynamic Link`.link_doctype = 'Company' and `tabDynamic Link`.link_doctype = 'Company' and
`tabDynamic Link`.link_name = '{0}'""".format(company)) `tabDynamic Link`.link_name = %(company)s""", {"company": company})
return company_gstins return company_gstins
def get_address_details(data, doc, company_address, billing_address): def get_address_details(data, doc, company_address, billing_address):

View File

@ -109,7 +109,7 @@ def get_transactions(filters, as_dict=1):
WHERE gl.company = %(company)s WHERE gl.company = %(company)s
AND DATE(gl.posting_date) >= %(from_date)s AND DATE(gl.posting_date) >= %(from_date)s
AND DATE(gl.posting_date) <= %(to_date)s AND DATE(gl.posting_date) <= %(to_date)s
ORDER BY 'Belegdatum', gl.voucher_no""", filters, as_dict=as_dict, as_utf8=1) ORDER BY 'Belegdatum', gl.voucher_no""", filters, as_dict=as_dict)
return gl_entries return gl_entries
@ -160,7 +160,7 @@ def get_customers(filters):
and ccl.company = par.company and ccl.company = par.company
WHERE par.company = %(company)s WHERE par.company = %(company)s
AND par.parenttype = 'Customer'""", filters, as_dict=1, as_utf8=1) AND par.parenttype = 'Customer'""", filters, as_dict=1)
def get_suppliers(filters): def get_suppliers(filters):
@ -217,7 +217,7 @@ def get_suppliers(filters):
and con.is_primary_contact = '1' and con.is_primary_contact = '1'
WHERE par.company = %(company)s WHERE par.company = %(company)s
AND par.parenttype = 'Supplier'""", filters, as_dict=1, as_utf8=1) AND par.parenttype = 'Supplier'""", filters, as_dict=1)
def get_account_names(filters): def get_account_names(filters):

View File

@ -13,9 +13,9 @@ def execute(filters=None):
dict(fieldtype='Data', label='GST Category', fieldname="gst_category", width=120), dict(fieldtype='Data', label='GST Category', fieldname="gst_category", width=120),
dict(fieldtype='Data', label='Export Type', fieldname="export_type", width=120), dict(fieldtype='Data', label='Export Type', fieldname="export_type", width=120),
dict(fieldtype='Data', label='E-Commerce GSTIN', fieldname="ecommerce_gstin", width=130), dict(fieldtype='Data', label='E-Commerce GSTIN', fieldname="ecommerce_gstin", width=130),
dict(fieldtype='Data', label='HSN Code', fieldname="hsn_code", width=120), dict(fieldtype='Data', label='HSN Code', fieldname="gst_hsn_code", width=120),
dict(fieldtype='Data', label='Supplier Invoice No', fieldname="supplier_invoice_no", width=120), dict(fieldtype='Data', label='Supplier Invoice No', fieldname="bill_no", width=120),
dict(fieldtype='Date', label='Supplier Invoice Date', fieldname="supplier_invoice_date", width=100) dict(fieldtype='Date', label='Supplier Invoice Date', fieldname="bill_date", width=100)
], additional_query_columns=[ ], additional_query_columns=[
'supplier_gstin', 'supplier_gstin',
'company_gstin', 'company_gstin',

View File

@ -54,8 +54,8 @@ class Gstr1Report(object):
return self.columns, self.data return self.columns, self.data
def get_data(self): def get_data(self):
if self.filters.get("type_of_business") == "B2C Small": if self.filters.get("type_of_business") in ("B2C Small", "B2C Large"):
self.get_b2cs_data() self.get_b2c_data()
else: else:
for inv, items_based_on_rate in self.items_based_on_tax_rate.items(): for inv, items_based_on_rate in self.items_based_on_tax_rate.items():
invoice_details = self.invoices.get(inv) invoice_details = self.invoices.get(inv)
@ -69,7 +69,7 @@ class Gstr1Report(object):
if taxable_value: if taxable_value:
self.data.append(row) self.data.append(row)
def get_b2cs_data(self): def get_b2c_data(self):
b2cs_output = {} b2cs_output = {}
for inv, items_based_on_rate in self.items_based_on_tax_rate.items(): for inv, items_based_on_rate in self.items_based_on_tax_rate.items():
@ -84,7 +84,10 @@ class Gstr1Report(object):
"rate": "", "rate": "",
"taxable_value": 0, "taxable_value": 0,
"cess_amount": 0, "cess_amount": 0,
"type": "" "type": "",
"invoice_number": invoice_details.get("invoice_number"),
"posting_date": invoice_details.get("posting_date"),
"invoice_value": invoice_details.get("base_grand_total"),
}) })
row = b2cs_output.get((rate, place_of_supply, ecommerce_gstin)) row = b2cs_output.get((rate, place_of_supply, ecommerce_gstin))
@ -164,7 +167,7 @@ class Gstr1Report(object):
frappe.throw(_("Please set B2C Limit in GST Settings.")) frappe.throw(_("Please set B2C Limit in GST Settings."))
if self.filters.get("type_of_business") == "B2C Large": if self.filters.get("type_of_business") == "B2C Large":
conditions += """ and SUBSTR(place_of_supply, 1, 2) != SUBSTR(company_gstin, 1, 2) conditions += """ and ifnull(SUBSTR(place_of_supply, 1, 2),'') != ifnull(SUBSTR(company_gstin, 1, 2),'')
and grand_total > {0} and is_return != 1 and gst_category ='Unregistered' """.format(flt(b2c_limit)) and grand_total > {0} and is_return != 1 and gst_category ='Unregistered' """.format(flt(b2c_limit))
elif self.filters.get("type_of_business") == "B2C Small": elif self.filters.get("type_of_business") == "B2C Small":
@ -581,6 +584,11 @@ def get_b2b_json(res, gstin):
if not gst_in: continue if not gst_in: continue
for number, invoice in iteritems(res[gst_in]): for number, invoice in iteritems(res[gst_in]):
if not invoice[0]["place_of_supply"]:
frappe.throw(_("""{0} not entered in Invoice {1}.
Please update and try again""").format(frappe.bold("Place Of Supply"),
frappe.bold(invoice[0]['invoice_number'])))
inv_item = get_basic_invoice_detail(invoice[0]) inv_item = get_basic_invoice_detail(invoice[0])
inv_item["pos"] = "%02d" % int(invoice[0]["place_of_supply"].split('-')[0]) inv_item["pos"] = "%02d" % int(invoice[0]["place_of_supply"].split('-')[0])
inv_item["rchrg"] = invoice[0]["reverse_charge"] inv_item["rchrg"] = invoice[0]["reverse_charge"]
@ -606,6 +614,9 @@ def get_b2cs_json(data, gstin):
out = [] out = []
for d in data: for d in data:
if not d.get("place_of_supply"):
frappe.throw(_("""{0} not entered in some invoices.
Please update and try again""").format(frappe.bold("Place Of Supply")))
pos = d.get('place_of_supply').split('-')[0] pos = d.get('place_of_supply').split('-')[0]
tax_details = {} tax_details = {}
@ -642,6 +653,10 @@ def get_b2cs_json(data, gstin):
def get_b2cl_json(res, gstin): def get_b2cl_json(res, gstin):
out = [] out = []
for pos in res: for pos in res:
if not pos:
frappe.throw(_("""{0} not entered in some invoices.
Please update and try again""").format(frappe.bold("Place Of Supply")))
b2cl_item, inv = {"pos": "%02d" % int(pos.split('-')[0]), "inv": []}, [] b2cl_item, inv = {"pos": "%02d" % int(pos.split('-')[0]), "inv": []}, []
for row in res[pos]: for row in res[pos]:

View File

@ -0,0 +1,4 @@
from __future__ import unicode_literals
def setup(company=None, patch=True):
pass

View File

@ -0,0 +1,28 @@
{
"cards": [
{
"links": "[\n {\n \"description\": \"Setup default values for POS Invoices\",\n \"label\": \"Point-of-Sale Profile\",\n \"name\": \"POS Profile\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"POS Profile\"\n ],\n \"description\": \"Point of Sale\",\n \"label\": \"POS\",\n \"name\": \"pos\",\n \"onboard\": 1,\n \"type\": \"page\"\n },\n {\n \"description\": \"Cashier Closing\",\n \"label\": \"Cashier Closing\",\n \"name\": \"Cashier Closing\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Setup mode of POS (Online / Offline)\",\n \"label\": \"POS Settings\",\n \"name\": \"POS Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"To make Customer based incentive schemes.\",\n \"label\": \"Loyalty Program\",\n \"name\": \"Loyalty Program\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"To view logs of Loyalty Points assigned to a Customer.\",\n \"label\": \"Loyalty Point Entry\",\n \"name\": \"Loyalty Point Entry\",\n \"type\": \"doctype\"\n }\n]",
"title": "Retail Operations"
}
],
"category": "Domains",
"charts": [],
"creation": "2020-03-02 17:18:32.505616",
"developer_mode_only": 0,
"disable_user_customization": 0,
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
"idx": 0,
"is_standard": 1,
"label": "Retail",
"modified": "2020-03-12 16:30:36.154297",
"modified_by": "Administrator",
"module": "Selling",
"name": "Retail",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"restrict_to_domain": "Retail",
"shortcuts": []
}

View File

@ -0,0 +1,85 @@
{
"cards": [
{
"links": "[\n {\n \"description\": \"All Products or Services.\",\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Price List\"\n ],\n \"description\": \"Multiple Item prices.\",\n \"label\": \"Item Price\",\n \"name\": \"Item Price\",\n \"onboard\": 1,\n \"route\": \"#Report/Item Price\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Price List master.\",\n \"label\": \"Price List\",\n \"name\": \"Price List\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of Item Groups.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Item Group\",\n \"link\": \"Tree/Item Group\",\n \"name\": \"Item Group\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Bundle items at time of sale.\",\n \"label\": \"Product Bundle\",\n \"name\": \"Product Bundle\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Rules for applying different promotional schemes.\",\n \"label\": \"Promotional Scheme\",\n \"name\": \"Promotional Scheme\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Rules for applying pricing and discount.\",\n \"label\": \"Pricing Rule\",\n \"name\": \"Pricing Rule\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Rules for adding shipping costs.\",\n \"label\": \"Shipping Rule\",\n \"name\": \"Shipping Rule\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Define coupon codes.\",\n \"label\": \"Coupon Code\",\n \"name\": \"Coupon Code\",\n \"type\": \"doctype\"\n }\n]",
"title": "Items and Pricing"
},
{
"icon": "fa fa-cog",
"links": "[\n {\n \"description\": \"Default settings for selling transactions.\",\n \"label\": \"Selling Settings\",\n \"name\": \"Selling Settings\",\n \"settings\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Template of terms or contract.\",\n \"label\": \"Terms and Conditions Template\",\n \"name\": \"Terms and Conditions\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for selling transactions.\",\n \"label\": \"Sales Taxes and Charges Template\",\n \"name\": \"Sales Taxes and Charges Template\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Track Leads by Lead Source.\",\n \"label\": \"Lead Source\",\n \"name\": \"Lead Source\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Customer Group Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Customer Group\",\n \"link\": \"Tree/Customer Group\",\n \"name\": \"Customer Group\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Contacts.\",\n \"label\": \"Contact\",\n \"name\": \"Contact\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Addresses.\",\n \"label\": \"Address\",\n \"name\": \"Address\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Territory Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Territory\",\n \"link\": \"Tree/Territory\",\n \"name\": \"Territory\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Sales campaigns.\",\n \"label\": \"Campaign\",\n \"name\": \"Campaign\",\n \"type\": \"doctype\"\n }\n]",
"title": "Settings"
},
{
"icon": "fa fa-list",
"links": "[\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Details\",\n \"name\": \"Lead Details\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Address\"\n ],\n \"doctype\": \"Address\",\n \"is_query_report\": true,\n \"label\": \"Customer Addresses And Contacts\",\n \"name\": \"Address And Contacts\",\n \"route_options\": {\n \"party_type\": \"Customer\"\n },\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"BOM\"\n ],\n \"doctype\": \"BOM\",\n \"is_query_report\": true,\n \"label\": \"BOM Search\",\n \"name\": \"BOM Search\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Available Stock for Packing Items\",\n \"name\": \"Available Stock for Packing Items\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Pending SO Items For Purchase Request\",\n \"name\": \"Pending SO Items For Purchase Request\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customer Credit Balance\",\n \"name\": \"Customer Credit Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customers Without Any Sales Transactions\",\n \"name\": \"Customers Without Any Sales Transactions\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Sales Partners Commission\",\n \"name\": \"Sales Partners Commission\",\n \"type\": \"report\"\n }\n]",
"title": "Other Reports"
},
{
"icon": "fa fa-star",
"links": "[\n {\n \"description\": \"Customer Database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Quotes to Leads or Customers.\",\n \"label\": \"Quotation\",\n \"name\": \"Quotation\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Confirmed orders from Customers.\",\n \"label\": \"Sales Order\",\n \"name\": \"Sales Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Invoices for Costumers.\",\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Blanket Orders from Costumers.\",\n \"label\": \"Blanket Order\",\n \"name\": \"Blanket Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Manage Sales Partners.\",\n \"label\": \"Sales Partner\",\n \"name\": \"Sales Partner\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Manage Sales Person Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Sales Person\",\n \"link\": \"Tree/Sales Person\",\n \"name\": \"Sales Person\",\n \"type\": \"doctype\"\n }\n]",
"title": "Sales"
},
{
"icon": "fa fa-table",
"links": "[\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Analytics\",\n \"name\": \"Sales Analytics\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"icon\": \"fa fa-bar-chart\",\n \"label\": \"Sales Funnel\",\n \"name\": \"sales-funnel\",\n \"onboard\": 1,\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"icon\": \"fa fa-bar-chart\",\n \"is_query_report\": true,\n \"label\": \"Customer Acquisition and Loyalty\",\n \"name\": \"Customer Acquisition and Loyalty\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Inactive Customers\",\n \"name\": \"Inactive Customers\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Ordered Items To Be Delivered\",\n \"name\": \"Ordered Items To Be Delivered\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Person-wise Transaction Summary\",\n \"name\": \"Sales Person-wise Transaction Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales History\",\n \"name\": \"Item-wise Sales History\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Quotation\"\n ],\n \"doctype\": \"Quotation\",\n \"is_query_report\": true,\n \"label\": \"Quotation Trends\",\n \"name\": \"Quotation Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Trends\",\n \"name\": \"Sales Order Trends\",\n \"type\": \"report\"\n }\n]",
"title": "Key Reports"
}
],
"category": "Modules",
"charts": [
{
"chart_name": "Income",
"label": "Income",
"size": "Full"
}
],
"creation": "2020-01-28 11:49:12.092882",
"developer_mode_only": 0,
"disable_user_customization": 0,
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
"icon": "",
"idx": 0,
"is_standard": 1,
"label": "Selling",
"modified": "2020-03-12 16:30:38.207013",
"modified_by": "Administrator",
"module": "Selling",
"name": "Selling",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"shortcuts": [
{
"is_query_report": 0,
"link_to": "Sales Invoice",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Sales Order",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Quotation",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Delivery Note",
"type": "DocType"
},
{
"is_query_report": 0,
"link_to": "Accounts Receivable",
"type": "Report"
},
{
"is_query_report": 0,
"link_to": "Sales Register",
"type": "Report"
}
]
}

View File

@ -76,6 +76,7 @@ class Customer(TransactionBase):
def validate_default_bank_account(self): def validate_default_bank_account(self):
if self.default_bank_account: if self.default_bank_account:
is_company_account = frappe.db.get_value('Bank Account', self.default_bank_account, 'is_company_account') is_company_account = frappe.db.get_value('Bank Account', self.default_bank_account, 'is_company_account')
if not is_company_account:
frappe.throw(_("{0} is not a company bank account").format(frappe.bold(self.default_bank_account))) frappe.throw(_("{0} is not a company bank account").format(frappe.bold(self.default_bank_account)))
def on_update(self): def on_update(self):
@ -267,9 +268,11 @@ def make_quotation(source_name, target_doc=None):
target_doc.run_method("set_other_charges") target_doc.run_method("set_other_charges")
target_doc.run_method("calculate_taxes_and_totals") target_doc.run_method("calculate_taxes_and_totals")
price_list = frappe.get_value("Customer", source_name, 'default_price_list') price_list, currency = frappe.db.get_value("Customer", {'name': source_name}, ['default_price_list', 'default_currency'])
if price_list: if price_list:
target_doc.selling_price_list = price_list target_doc.selling_price_list = price_list
if currency:
target_doc.currency = currency
return target_doc return target_doc

View File

@ -641,7 +641,6 @@ def make_sales_invoice(source_name, target_doc=None, ignore_permissions=False):
target.set_advances() target.set_advances()
def set_missing_values(source, target): def set_missing_values(source, target):
target.is_pos = 0
target.ignore_pricing_rule = 1 target.ignore_pricing_rule = 1
target.flags.ignore_permissions = True target.flags.ignore_permissions = True
target.run_method("set_missing_values") target.run_method("set_missing_values")

View File

@ -121,8 +121,8 @@ def get_columns(filters):
}, },
{ {
"label": _("Billed Amount"), "label": _("Billed Amount"),
"fieldname": "rate", "fieldtype": "currency",
"options": "billed_amount", "fieldname": "billed_amount",
"width": 120 "width": 120
}, },
{ {

View File

@ -413,15 +413,20 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
*/ */
set_batch_number: function(cdt, cdn) { set_batch_number: function(cdt, cdn) {
const doc = frappe.get_doc(cdt, cdn); const doc = frappe.get_doc(cdt, cdn);
if (doc && doc.has_batch_no) { if (doc && doc.has_batch_no && doc.warehouse) {
this._set_batch_number(doc); this._set_batch_number(doc);
} }
}, },
_set_batch_number: function(doc) { _set_batch_number: function(doc) {
let args = {'item_code': doc.item_code, 'warehouse': doc.warehouse, 'qty': flt(doc.qty) * flt(doc.conversion_factor)};
if (doc.has_serial_no && doc.serial_no) {
args['serial_no'] = doc.serial_no
}
return frappe.call({ return frappe.call({
method: 'erpnext.stock.doctype.batch.batch.get_batch_no', method: 'erpnext.stock.doctype.batch.batch.get_batch_no',
args: {'item_code': doc.item_code, 'warehouse': doc.warehouse, 'qty': flt(doc.qty) * flt(doc.conversion_factor)}, args: args,
callback: function(r) { callback: function(r) {
if(r.message) { if(r.message) {
frappe.model.set_value(doc.doctype, doc.name, 'batch_no', r.message); frappe.model.set_value(doc.doctype, doc.name, 'batch_no', r.message);

View File

@ -0,0 +1,112 @@
{
"cards": [],
"category": "Modules",
"charts": [],
"creation": "2020-03-12 14:47:51.166455",
"developer_mode_only": 0,
"disable_user_customization": 0,
"docstatus": 0,
"doctype": "Desk Page",
"extends": "Settings",
"extends_another_page": 1,
"idx": 0,
"is_standard": 1,
"label": "ERPNext Settings",
"modified": "2020-03-12 18:03:17.126782",
"modified_by": "Administrator",
"module": "Setup",
"name": "ERPNext Settings",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"shortcuts": [
{
"icon": "octicon octicon-rocket",
"is_query_report": 0,
"link_to": "Projects Settings",
"type": "DocType"
},
{
"icon": "octicon octicon-repo",
"is_query_report": 0,
"link_to": "Accounts Settings",
"type": "DocType"
},
{
"icon": "octicon octicon-package",
"is_query_report": 0,
"link_to": "Stock Settings",
"type": "DocType"
},
{
"icon": "octicon octicon-organization",
"is_query_report": 0,
"link_to": "HR Settings",
"type": "DocType"
},
{
"icon": "octicon octicon-tag",
"is_query_report": 0,
"link_to": "Selling Settings",
"type": "DocType"
},
{
"icon": "octicon octicon-briefcase",
"is_query_report": 0,
"link_to": "Buying Settings",
"type": "DocType"
},
{
"icon": "fa fa-life-ring",
"is_query_report": 0,
"link_to": "Support Settings",
"type": "DocType"
},
{
"icon": "fa fa-shopping-cart",
"is_query_report": 0,
"link_to": "Shopping Cart Settings",
"type": "DocType"
},
{
"icon": "fa fa-globe",
"is_query_report": 0,
"link_to": "Portal Settings",
"type": "DocType"
},
{
"icon": "octicon octicon-tools",
"is_query_report": 0,
"link_to": "Manufacturing Settings",
"restrict_to_domain": "Manufacturing",
"type": "DocType"
},
{
"icon": "octicon octicon-mortar-board",
"is_query_report": 0,
"link_to": "Education Settings",
"restrict_to_domain": "Education",
"type": "DocType"
},
{
"icon": "fa fa-bed",
"is_query_report": 0,
"link_to": "Hotel Settings",
"restrict_to_domain": "Hospitality",
"type": "DocType"
},
{
"icon": "fa fa-heartbeat",
"is_query_report": 0,
"link_to": "Healthcare Settings",
"restrict_to_domain": "Healthcare",
"type": "DocType"
},
{
"icon": "fa fa-cog",
"is_query_report": 0,
"link_to": "Domain Settings",
"type": "DocType"
}
]
}

Some files were not shown because too many files have changed in this diff Show More