mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-23 15:09:20 +00:00
Merge branch 'develop' into refactor-addiional-salary
This commit is contained in:
19
CODEOWNERS
Normal file
19
CODEOWNERS
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Each line is a file pattern followed by one or more owners.
|
||||||
|
|
||||||
|
# These owners will be the default owners for everything in
|
||||||
|
# the repo. Unless a later match takes precedence,
|
||||||
|
|
||||||
|
* @nabinhait
|
||||||
|
manufacturing/ @rohitwaghchaure
|
||||||
|
accounts/ @deepeshgarg007 @nextchamp-saqib
|
||||||
|
loan_management/ @deepeshgarg007
|
||||||
|
pos* @nextchamp-saqib
|
||||||
|
assets/ @nextchamp-saqib
|
||||||
|
stock/ @marination @rohitwaghchaure
|
||||||
|
buying/ @marination @rohitwaghchaure
|
||||||
|
hr/ @Anurag810
|
||||||
|
projects/ @hrwX
|
||||||
|
support/ @hrwX
|
||||||
|
healthcare/ @ruchamahabal
|
||||||
|
erpnext_integrations/ @Mangesh-Khairnar
|
||||||
|
requirements.txt @gavindsouza
|
||||||
@@ -1,83 +1,96 @@
|
|||||||
{
|
{
|
||||||
"cards": [
|
"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]",
|
"hidden": 0,
|
||||||
"title": "Accounting Masters"
|
"label": "Accounting Masters",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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]",
|
"hidden": 0,
|
||||||
"title": "General Ledger"
|
"label": "General Ledger",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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]",
|
"hidden": 0,
|
||||||
"title": "Accounts Receivable"
|
"label": "Accounts Receivable",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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]",
|
"hidden": 0,
|
||||||
"title": "Accounts Payable"
|
"label": "Accounts Payable",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"icon": "fa fa-table",
|
"hidden": 0,
|
||||||
"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]",
|
"label": "Reports",
|
||||||
"title": "Reports"
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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]",
|
"hidden": 0,
|
||||||
"title": "Financial Statements"
|
"label": "Financial Statements",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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]",
|
"hidden": 0,
|
||||||
"title": "Multi Currency"
|
"label": "Multi Currency",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"icon": "fa fa-cog",
|
"hidden": 0,
|
||||||
"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]",
|
"label": "Settings",
|
||||||
"title": "Settings"
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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]",
|
"hidden": 0,
|
||||||
"title": "Bank Statement"
|
"label": "Bank Statement",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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]",
|
"hidden": 0,
|
||||||
"title": "Banking and Payments"
|
"label": "Banking and Payments",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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]",
|
"hidden": 0,
|
||||||
"title": "Subscription Management"
|
"label": "Subscription Management",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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]",
|
"hidden": 0,
|
||||||
"title": "Goods and Services Tax (GST India)"
|
"label": "Goods and Services Tax (GST India)",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"icon": "fa fa-microchip ",
|
"hidden": 0,
|
||||||
"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]",
|
"label": "Share Management",
|
||||||
"title": "Share Management"
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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]",
|
"hidden": 0,
|
||||||
"title": "Cost Center and Budgeting"
|
"label": "Cost Center and Budgeting",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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]",
|
"hidden": 0,
|
||||||
"title": "Opening and Closing"
|
"label": "Opening and Closing",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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]",
|
"hidden": 0,
|
||||||
"title": "Taxes"
|
"label": "Taxes",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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]",
|
"hidden": 0,
|
||||||
"title": "Profitability"
|
"label": "Profitability",
|
||||||
|
"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]"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"category": "Modules",
|
"category": "Modules",
|
||||||
"charts": [
|
"charts": [
|
||||||
{
|
{
|
||||||
"chart_name": "Bank Balance",
|
"chart_name": "Bank Balance",
|
||||||
"label": "Bank Balance",
|
"label": "Bank Balance"
|
||||||
"size": "Full"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"creation": "2020-03-02 15:41:59.515192",
|
"creation": "2020-03-02 15:41:59.515192",
|
||||||
@@ -90,7 +103,7 @@
|
|||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"label": "Accounting",
|
"label": "Accounting",
|
||||||
"modified": "2020-03-12 16:30:35.580450",
|
"modified": "2020-04-01 11:28:50.925719",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Accounting",
|
"name": "Accounting",
|
||||||
@@ -99,37 +112,37 @@
|
|||||||
"pin_to_top": 0,
|
"pin_to_top": 0,
|
||||||
"shortcuts": [
|
"shortcuts": [
|
||||||
{
|
{
|
||||||
"is_query_report": 0,
|
"label": "Account",
|
||||||
"link_to": "Account",
|
"link_to": "Account",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"is_query_report": 0,
|
"label": "Journal Entry",
|
||||||
"link_to": "Journal Entry",
|
"link_to": "Journal Entry",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"is_query_report": 0,
|
"label": "Payment Entry",
|
||||||
"link_to": "Payment Entry",
|
"link_to": "Payment Entry",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"is_query_report": 1,
|
"label": "Accounts Receivable",
|
||||||
"link_to": "Accounts Receivable",
|
"link_to": "Accounts Receivable",
|
||||||
"type": "Report"
|
"type": "Report"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"is_query_report": 0,
|
"label": "General Ledger",
|
||||||
"link_to": "General Ledger",
|
"link_to": "General Ledger",
|
||||||
"type": "Report"
|
"type": "Report"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"is_query_report": 0,
|
"label": "Profit and Loss Statement",
|
||||||
"link_to": "Profit and Loss Statement",
|
"link_to": "Profit and Loss Statement",
|
||||||
"type": "Report"
|
"type": "Report"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"is_query_report": 0,
|
"label": "Trial Balance",
|
||||||
"link_to": "Trial Balance",
|
"link_to": "Trial Balance",
|
||||||
"type": "Report"
|
"type": "Report"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ class Account(NestedSet):
|
|||||||
throw(_("Root cannot be edited."), RootNotEditable)
|
throw(_("Root cannot be edited."), RootNotEditable)
|
||||||
|
|
||||||
if not self.parent_account and not self.is_group:
|
if not self.parent_account and not self.is_group:
|
||||||
frappe.throw(_("Root Account must be a group"))
|
frappe.throw(_("The root account {0} must be a group").format(frappe.bold(self.name)))
|
||||||
|
|
||||||
def validate_root_company_and_sync_account_to_children(self):
|
def validate_root_company_and_sync_account_to_children(self):
|
||||||
# ignore validation while creating new compnay or while syncing to child companies
|
# ignore validation while creating new compnay or while syncing to child companies
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
frappe.provide("frappe.treeview_settings")
|
frappe.provide("frappe.treeview_settings")
|
||||||
|
|
||||||
frappe.treeview_settings["Account"] = {
|
frappe.treeview_settings["Account"] = {
|
||||||
breadcrumbs: "Accounts",
|
breadcrumb: "Accounts",
|
||||||
title: __("Chart Of Accounts"),
|
title: __("Chart Of Accounts"),
|
||||||
get_tree_root: false,
|
get_tree_root: false,
|
||||||
filters: [
|
filters: [
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ class TestAccount(unittest.TestCase):
|
|||||||
acc.account_name = "Accumulated Depreciation"
|
acc.account_name = "Accumulated Depreciation"
|
||||||
acc.parent_account = "Fixed Assets - _TC"
|
acc.parent_account = "Fixed Assets - _TC"
|
||||||
acc.company = "_Test Company"
|
acc.company = "_Test Company"
|
||||||
|
acc.account_type = "Accumulated Depreciation"
|
||||||
acc.insert()
|
acc.insert()
|
||||||
|
|
||||||
doc = frappe.get_doc("Account", "Securities and Deposits - _TC")
|
doc = frappe.get_doc("Account", "Securities and Deposits - _TC")
|
||||||
@@ -149,7 +150,7 @@ def _make_test_records(verbose):
|
|||||||
|
|
||||||
# fixed asset depreciation
|
# fixed asset depreciation
|
||||||
["_Test Fixed Asset", "Current Assets", 0, "Fixed Asset", None],
|
["_Test Fixed Asset", "Current Assets", 0, "Fixed Asset", None],
|
||||||
["_Test Accumulated Depreciations", "Current Assets", 0, None, None],
|
["_Test Accumulated Depreciations", "Current Assets", 0, "Accumulated Depreciation", None],
|
||||||
["_Test Depreciations", "Expenses", 0, None, None],
|
["_Test Depreciations", "Expenses", 0, None, None],
|
||||||
["_Test Gain/Loss on Asset Disposal", "Expenses", 0, None, None],
|
["_Test Gain/Loss on Asset Disposal", "Expenses", 0, None, None],
|
||||||
|
|
||||||
|
|||||||
@@ -1,134 +0,0 @@
|
|||||||
{
|
|
||||||
"allow_copy": 0,
|
|
||||||
"allow_events_in_timeline": 0,
|
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 1,
|
|
||||||
"allow_rename": 1,
|
|
||||||
"autoname": "field:account_subtype",
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2018-10-25 15:46:08.054586",
|
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
|
||||||
"engine": "InnoDB",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "account_subtype",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Account Subtype",
|
|
||||||
"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": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"has_web_view": 0,
|
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-10-25 15:47:03.841390",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Accounts",
|
|
||||||
"name": "Account Subtype",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
|
||||||
{
|
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
|
||||||
"delete": 1,
|
|
||||||
"email": 1,
|
|
||||||
"export": 1,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "System Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
|
||||||
"delete": 1,
|
|
||||||
"email": 1,
|
|
||||||
"export": 1,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Accounts Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
|
||||||
"delete": 1,
|
|
||||||
"email": 1,
|
|
||||||
"export": 1,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Accounts User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"quick_entry": 1,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 0,
|
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/* eslint-disable */
|
|
||||||
// rename this file from _test_[name] to test_[name] to activate
|
|
||||||
// and remove above this line
|
|
||||||
|
|
||||||
QUnit.test("test: Account Subtype", function (assert) {
|
|
||||||
let done = assert.async();
|
|
||||||
|
|
||||||
// number of asserts
|
|
||||||
assert.expect(1);
|
|
||||||
|
|
||||||
frappe.run_serially([
|
|
||||||
// insert a new Account Subtype
|
|
||||||
() => frappe.tests.make('Account Subtype', [
|
|
||||||
// values to be set
|
|
||||||
{key: 'value'}
|
|
||||||
]),
|
|
||||||
() => {
|
|
||||||
assert.equal(cur_frm.doc.key, 'value');
|
|
||||||
},
|
|
||||||
() => done()
|
|
||||||
]);
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
|
||||||
// For license information, please see license.txt
|
|
||||||
|
|
||||||
frappe.ui.form.on('Account Type', {
|
|
||||||
refresh: function() {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
{
|
|
||||||
"allow_copy": 0,
|
|
||||||
"allow_events_in_timeline": 0,
|
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 1,
|
|
||||||
"allow_rename": 1,
|
|
||||||
"autoname": "field:account_type",
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2018-10-25 15:45:45.789963",
|
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
|
||||||
"engine": "InnoDB",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "account_type",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Account Type",
|
|
||||||
"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": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"has_web_view": 0,
|
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-10-25 15:46:51.042604",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Accounts",
|
|
||||||
"name": "Account Type",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
|
||||||
{
|
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
|
||||||
"delete": 1,
|
|
||||||
"email": 1,
|
|
||||||
"export": 1,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "System Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
|
||||||
"delete": 1,
|
|
||||||
"email": 1,
|
|
||||||
"export": 1,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Accounts Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
|
||||||
"delete": 1,
|
|
||||||
"email": 1,
|
|
||||||
"export": 1,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Accounts User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"quick_entry": 1,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 0,
|
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
|
||||||
# See license.txt
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
class TestAccountType(unittest.TestCase):
|
|
||||||
pass
|
|
||||||
@@ -193,7 +193,7 @@ def get_dimension_with_children(doctype, dimension):
|
|||||||
|
|
||||||
all_dimensions = []
|
all_dimensions = []
|
||||||
lft, rgt = frappe.db.get_value(doctype, dimension, ["lft", "rgt"])
|
lft, rgt = frappe.db.get_value(doctype, dimension, ["lft", "rgt"])
|
||||||
children = frappe.get_all(doctype, filters={"lft": [">=", lft], "rgt": ["<=", rgt]})
|
children = frappe.get_all(doctype, filters={"lft": [">=", lft], "rgt": ["<=", rgt]}, order_by="lft")
|
||||||
all_dimensions += [c.name for c in children]
|
all_dimensions += [c.name for c in children]
|
||||||
|
|
||||||
return all_dimensions
|
return all_dimensions
|
||||||
|
|||||||
@@ -64,13 +64,13 @@
|
|||||||
"fieldname": "account_type",
|
"fieldname": "account_type",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Account Type",
|
"label": "Account Type",
|
||||||
"options": "Account Type"
|
"options": "Bank Account Type"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "account_subtype",
|
"fieldname": "account_subtype",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Account Subtype",
|
"label": "Account Subtype",
|
||||||
"options": "Account Subtype"
|
"options": "Bank Account Subtype"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_7",
|
"fieldname": "column_break_7",
|
||||||
@@ -200,7 +200,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-01-30 20:42:26.458316",
|
"modified": "2020-04-06 21:00:45.379804",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Bank Account",
|
"name": "Bank Account",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on('Account Subtype', {
|
frappe.ui.form.on('Bank Account Subtype', {
|
||||||
refresh: function() {
|
refresh: function() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
{
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
|
"allow_import": 1,
|
||||||
|
"allow_rename": 1,
|
||||||
|
"autoname": "field:account_subtype",
|
||||||
|
"beta": 0,
|
||||||
|
"creation": "2018-10-25 15:46:08.054586",
|
||||||
|
"custom": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "account_subtype",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Account Subtype",
|
||||||
|
"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": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"has_web_view": 0,
|
||||||
|
"hide_heading": 0,
|
||||||
|
"hide_toolbar": 0,
|
||||||
|
"idx": 0,
|
||||||
|
"image_view": 0,
|
||||||
|
"in_create": 0,
|
||||||
|
"is_submittable": 0,
|
||||||
|
"issingle": 0,
|
||||||
|
"istable": 0,
|
||||||
|
"max_attachments": 0,
|
||||||
|
"modified": "2018-10-25 15:47:03.841390",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Bank Account Subtype",
|
||||||
|
"name_case": "",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "System Manager",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 0,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Accounts Manager",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 0,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Accounts User",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 0,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quick_entry": 1,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_onload": 0,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 0,
|
||||||
|
"track_seen": 0,
|
||||||
|
"track_views": 0
|
||||||
|
}
|
||||||
@@ -5,5 +5,5 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
class AccountType(Document):
|
class BankAccountSubtype(Document):
|
||||||
pass
|
pass
|
||||||
@@ -2,15 +2,15 @@
|
|||||||
// rename this file from _test_[name] to test_[name] to activate
|
// rename this file from _test_[name] to test_[name] to activate
|
||||||
// and remove above this line
|
// and remove above this line
|
||||||
|
|
||||||
QUnit.test("test: Account Type", function (assert) {
|
QUnit.test("test: Bank Account Subtype", function (assert) {
|
||||||
let done = assert.async();
|
let done = assert.async();
|
||||||
|
|
||||||
// number of asserts
|
// number of asserts
|
||||||
assert.expect(1);
|
assert.expect(1);
|
||||||
|
|
||||||
frappe.run_serially([
|
frappe.run_serially([
|
||||||
// insert a new Account Type
|
// insert a new Bank Account Subtype
|
||||||
() => frappe.tests.make('Account Type', [
|
() => frappe.tests.make('Bank Account Subtype', [
|
||||||
// values to be set
|
// values to be set
|
||||||
{key: 'value'}
|
{key: 'value'}
|
||||||
]),
|
]),
|
||||||
@@ -5,5 +5,5 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
class TestAccountSubtype(unittest.TestCase):
|
class TestBankAccountSubtype(unittest.TestCase):
|
||||||
pass
|
pass
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('Bank Account Type', {
|
||||||
|
// refresh: function(frm) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
});
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"allow_import": 1,
|
||||||
|
"allow_rename": 1,
|
||||||
|
"autoname": "field:account_type",
|
||||||
|
"creation": "2018-10-25 15:45:45.789963",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"account_type"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "account_type",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Account Type",
|
||||||
|
"unique": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"links": [],
|
||||||
|
"modified": "2020-04-10 21:13:09.137898",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Bank Account Type",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "System Manager",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Accounts Manager",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Accounts User",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quick_entry": 1,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC"
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class BankAccountType(Document):
|
||||||
|
pass
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestBankAccountType(unittest.TestCase):
|
||||||
|
pass
|
||||||
@@ -9,6 +9,7 @@ from frappe.utils import flt, getdate, add_months, get_last_day, fmt_money, nowd
|
|||||||
from frappe.model.naming import make_autoname
|
from frappe.model.naming import make_autoname
|
||||||
from erpnext.accounts.utils import get_fiscal_year
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
||||||
|
|
||||||
class BudgetError(frappe.ValidationError): pass
|
class BudgetError(frappe.ValidationError): pass
|
||||||
class DuplicateBudgetError(frappe.ValidationError): pass
|
class DuplicateBudgetError(frappe.ValidationError): pass
|
||||||
@@ -98,30 +99,32 @@ def validate_expense_against_budget(args):
|
|||||||
if not (args.get('account') and args.get('cost_center')) and args.item_code:
|
if not (args.get('account') and args.get('cost_center')) and args.item_code:
|
||||||
args.cost_center, args.account = get_item_details(args)
|
args.cost_center, args.account = get_item_details(args)
|
||||||
|
|
||||||
if not (args.cost_center or args.project) and not args.account:
|
if not args.account:
|
||||||
return
|
return
|
||||||
|
|
||||||
for budget_against in ['project', 'cost_center']:
|
for budget_against in ['project', 'cost_center'] + get_accounting_dimensions():
|
||||||
if (args.get(budget_against) and args.account
|
if (args.get(budget_against) and args.account
|
||||||
and frappe.db.get_value("Account", {"name": args.account, "root_type": "Expense"})):
|
and frappe.db.get_value("Account", {"name": args.account, "root_type": "Expense"})):
|
||||||
|
|
||||||
if args.project and budget_against == 'project':
|
doctype = frappe.unscrub(budget_against)
|
||||||
condition = "and b.project=%s" % frappe.db.escape(args.project)
|
|
||||||
args.budget_against_field = "Project"
|
|
||||||
|
|
||||||
elif args.cost_center and budget_against == 'cost_center':
|
if frappe.get_cached_value('DocType', doctype, 'is_tree'):
|
||||||
cc_lft, cc_rgt = frappe.db.get_value("Cost Center", args.cost_center, ["lft", "rgt"])
|
lft, rgt = frappe.db.get_value(doctype, args.get(budget_against), ["lft", "rgt"])
|
||||||
condition = """and exists(select name from `tabCost Center`
|
condition = """and exists(select name from `tab%s`
|
||||||
where lft<=%s and rgt>=%s and name=b.cost_center)""" % (cc_lft, cc_rgt)
|
where lft<=%s and rgt>=%s and name=b.%s)""" % (doctype, lft, rgt, budget_against) #nosec
|
||||||
args.budget_against_field = "Cost Center"
|
args.is_tree = True
|
||||||
|
else:
|
||||||
|
condition = "and b.%s=%s" % (budget_against, frappe.db.escape(args.get(budget_against)))
|
||||||
|
args.is_tree = False
|
||||||
|
|
||||||
args.budget_against = args.get(budget_against)
|
args.budget_against_field = budget_against
|
||||||
|
args.budget_against_doctype = doctype
|
||||||
|
|
||||||
budget_records = frappe.db.sql("""
|
budget_records = frappe.db.sql("""
|
||||||
select
|
select
|
||||||
b.{budget_against_field} as budget_against, ba.budget_amount, b.monthly_distribution,
|
b.{budget_against_field} as budget_against, ba.budget_amount, b.monthly_distribution,
|
||||||
ifnull(b.applicable_on_material_request, 0) as for_material_request,
|
ifnull(b.applicable_on_material_request, 0) as for_material_request,
|
||||||
ifnull(applicable_on_purchase_order,0) as for_purchase_order,
|
ifnull(applicable_on_purchase_order, 0) as for_purchase_order,
|
||||||
ifnull(applicable_on_booking_actual_expenses,0) as for_actual_expenses,
|
ifnull(applicable_on_booking_actual_expenses,0) as for_actual_expenses,
|
||||||
b.action_if_annual_budget_exceeded, b.action_if_accumulated_monthly_budget_exceeded,
|
b.action_if_annual_budget_exceeded, b.action_if_accumulated_monthly_budget_exceeded,
|
||||||
b.action_if_annual_budget_exceeded_on_mr, b.action_if_accumulated_monthly_budget_exceeded_on_mr,
|
b.action_if_annual_budget_exceeded_on_mr, b.action_if_accumulated_monthly_budget_exceeded_on_mr,
|
||||||
@@ -132,9 +135,7 @@ def validate_expense_against_budget(args):
|
|||||||
b.name=ba.parent and b.fiscal_year=%s
|
b.name=ba.parent and b.fiscal_year=%s
|
||||||
and ba.account=%s and b.docstatus=1
|
and ba.account=%s and b.docstatus=1
|
||||||
{condition}
|
{condition}
|
||||||
""".format(condition=condition,
|
""".format(condition=condition, budget_against_field=budget_against), (args.fiscal_year, args.account), as_dict=True) #nosec
|
||||||
budget_against_field=frappe.scrub(args.get("budget_against_field"))),
|
|
||||||
(args.fiscal_year, args.account), as_dict=True)
|
|
||||||
|
|
||||||
if budget_records:
|
if budget_records:
|
||||||
validate_budget_records(args, budget_records)
|
validate_budget_records(args, budget_records)
|
||||||
@@ -230,10 +231,10 @@ def get_ordered_amount(args, budget):
|
|||||||
|
|
||||||
def get_other_condition(args, budget, for_doc):
|
def get_other_condition(args, budget, for_doc):
|
||||||
condition = "expense_account = '%s'" % (args.expense_account)
|
condition = "expense_account = '%s'" % (args.expense_account)
|
||||||
budget_against_field = frappe.scrub(args.get("budget_against_field"))
|
budget_against_field = args.get("budget_against_field")
|
||||||
|
|
||||||
if budget_against_field and args.get(budget_against_field):
|
if budget_against_field and args.get(budget_against_field):
|
||||||
condition += " and child.%s = '%s'" %(budget_against_field, args.get(budget_against_field))
|
condition += " and child.%s = '%s'" % (budget_against_field, args.get(budget_against_field))
|
||||||
|
|
||||||
if args.get('fiscal_year'):
|
if args.get('fiscal_year'):
|
||||||
date_field = 'schedule_date' if for_doc == 'Material Request' else 'transaction_date'
|
date_field = 'schedule_date' if for_doc == 'Material Request' else 'transaction_date'
|
||||||
@@ -246,19 +247,30 @@ def get_other_condition(args, budget, for_doc):
|
|||||||
return condition
|
return condition
|
||||||
|
|
||||||
def get_actual_expense(args):
|
def get_actual_expense(args):
|
||||||
|
if not args.budget_against_doctype:
|
||||||
|
args.budget_against_doctype = frappe.unscrub(args.budget_against_field)
|
||||||
|
|
||||||
|
budget_against_field = args.get('budget_against_field')
|
||||||
condition1 = " and gle.posting_date <= %(month_end_date)s" \
|
condition1 = " and gle.posting_date <= %(month_end_date)s" \
|
||||||
if args.get("month_end_date") else ""
|
if args.get("month_end_date") else ""
|
||||||
if args.budget_against_field == "Cost Center":
|
|
||||||
lft_rgt = frappe.db.get_value(args.budget_against_field,
|
if args.is_tree:
|
||||||
args.budget_against, ["lft", "rgt"], as_dict=1)
|
lft_rgt = frappe.db.get_value(args.budget_against_doctype,
|
||||||
|
args.get(budget_against_field), ["lft", "rgt"], as_dict=1)
|
||||||
|
|
||||||
args.update(lft_rgt)
|
args.update(lft_rgt)
|
||||||
condition2 = """and exists(select name from `tabCost Center`
|
|
||||||
where lft>=%(lft)s and rgt<=%(rgt)s and name=gle.cost_center)"""
|
|
||||||
|
|
||||||
elif args.budget_against_field == "Project":
|
condition2 = """and exists(select name from `tab{doctype}`
|
||||||
condition2 = "and exists(select name from `tabProject` where name=gle.project and gle.project = %(budget_against)s)"
|
where lft>=%(lft)s and rgt<=%(rgt)s
|
||||||
|
and name=gle.{budget_against_field})""".format(doctype=args.budget_against_doctype, #nosec
|
||||||
|
budget_against_field=budget_against_field)
|
||||||
|
else:
|
||||||
|
condition2 = """and exists(select name from `tab{doctype}`
|
||||||
|
where name=gle.{budget_against} and
|
||||||
|
gle.{budget_against} = %({budget_against})s)""".format(doctype=args.budget_against_doctype,
|
||||||
|
budget_against = budget_against_field)
|
||||||
|
|
||||||
return flt(frappe.db.sql("""
|
amount = flt(frappe.db.sql("""
|
||||||
select sum(gle.debit) - sum(gle.credit)
|
select sum(gle.debit) - sum(gle.credit)
|
||||||
from `tabGL Entry` gle
|
from `tabGL Entry` gle
|
||||||
where gle.account=%(account)s
|
where gle.account=%(account)s
|
||||||
@@ -267,7 +279,9 @@ def get_actual_expense(args):
|
|||||||
and gle.company=%(company)s
|
and gle.company=%(company)s
|
||||||
and gle.docstatus=1
|
and gle.docstatus=1
|
||||||
{condition2}
|
{condition2}
|
||||||
""".format(condition1=condition1, condition2=condition2), (args))[0][0])
|
""".format(condition1=condition1, condition2=condition2), (args))[0][0]) #nosec
|
||||||
|
|
||||||
|
return amount
|
||||||
|
|
||||||
def get_accumulated_monthly_budget(monthly_distribution, posting_date, fiscal_year, annual_budget):
|
def get_accumulated_monthly_budget(monthly_distribution, posting_date, fiscal_year, annual_budget):
|
||||||
distribution = {}
|
distribution = {}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journ
|
|||||||
|
|
||||||
class TestBudget(unittest.TestCase):
|
class TestBudget(unittest.TestCase):
|
||||||
def test_monthly_budget_crossed_ignore(self):
|
def test_monthly_budget_crossed_ignore(self):
|
||||||
set_total_expense_zero("2013-02-28", "Cost Center")
|
set_total_expense_zero("2013-02-28", "cost_center")
|
||||||
|
|
||||||
budget = make_budget(budget_against="Cost Center")
|
budget = make_budget(budget_against="Cost Center")
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ class TestBudget(unittest.TestCase):
|
|||||||
budget.cancel()
|
budget.cancel()
|
||||||
|
|
||||||
def test_monthly_budget_crossed_stop1(self):
|
def test_monthly_budget_crossed_stop1(self):
|
||||||
set_total_expense_zero("2013-02-28", "Cost Center")
|
set_total_expense_zero("2013-02-28", "cost_center")
|
||||||
|
|
||||||
budget = make_budget(budget_against="Cost Center")
|
budget = make_budget(budget_against="Cost Center")
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ class TestBudget(unittest.TestCase):
|
|||||||
budget.cancel()
|
budget.cancel()
|
||||||
|
|
||||||
def test_exception_approver_role(self):
|
def test_exception_approver_role(self):
|
||||||
set_total_expense_zero("2013-02-28", "Cost Center")
|
set_total_expense_zero("2013-02-28", "cost_center")
|
||||||
|
|
||||||
budget = make_budget(budget_against="Cost Center")
|
budget = make_budget(budget_against="Cost Center")
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ class TestBudget(unittest.TestCase):
|
|||||||
budget.cancel()
|
budget.cancel()
|
||||||
|
|
||||||
def test_monthly_budget_crossed_stop2(self):
|
def test_monthly_budget_crossed_stop2(self):
|
||||||
set_total_expense_zero("2013-02-28", "Project")
|
set_total_expense_zero("2013-02-28", "project")
|
||||||
|
|
||||||
budget = make_budget(budget_against="Project")
|
budget = make_budget(budget_against="Project")
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ class TestBudget(unittest.TestCase):
|
|||||||
budget.cancel()
|
budget.cancel()
|
||||||
|
|
||||||
def test_yearly_budget_crossed_stop1(self):
|
def test_yearly_budget_crossed_stop1(self):
|
||||||
set_total_expense_zero("2013-02-28", "Cost Center")
|
set_total_expense_zero("2013-02-28", "cost_center")
|
||||||
|
|
||||||
budget = make_budget(budget_against="Cost Center")
|
budget = make_budget(budget_against="Cost Center")
|
||||||
|
|
||||||
@@ -141,7 +141,7 @@ class TestBudget(unittest.TestCase):
|
|||||||
budget.cancel()
|
budget.cancel()
|
||||||
|
|
||||||
def test_yearly_budget_crossed_stop2(self):
|
def test_yearly_budget_crossed_stop2(self):
|
||||||
set_total_expense_zero("2013-02-28", "Project")
|
set_total_expense_zero("2013-02-28", "project")
|
||||||
|
|
||||||
budget = make_budget(budget_against="Project")
|
budget = make_budget(budget_against="Project")
|
||||||
|
|
||||||
@@ -153,7 +153,7 @@ class TestBudget(unittest.TestCase):
|
|||||||
budget.cancel()
|
budget.cancel()
|
||||||
|
|
||||||
def test_monthly_budget_on_cancellation1(self):
|
def test_monthly_budget_on_cancellation1(self):
|
||||||
set_total_expense_zero("2013-02-28", "Cost Center")
|
set_total_expense_zero("2013-02-28", "cost_center")
|
||||||
|
|
||||||
budget = make_budget(budget_against="Cost Center")
|
budget = make_budget(budget_against="Cost Center")
|
||||||
|
|
||||||
@@ -177,7 +177,7 @@ class TestBudget(unittest.TestCase):
|
|||||||
budget.cancel()
|
budget.cancel()
|
||||||
|
|
||||||
def test_monthly_budget_on_cancellation2(self):
|
def test_monthly_budget_on_cancellation2(self):
|
||||||
set_total_expense_zero("2013-02-28", "Project")
|
set_total_expense_zero("2013-02-28", "project")
|
||||||
|
|
||||||
budget = make_budget(budget_against="Project")
|
budget = make_budget(budget_against="Project")
|
||||||
|
|
||||||
@@ -201,8 +201,8 @@ class TestBudget(unittest.TestCase):
|
|||||||
budget.cancel()
|
budget.cancel()
|
||||||
|
|
||||||
def test_monthly_budget_against_group_cost_center(self):
|
def test_monthly_budget_against_group_cost_center(self):
|
||||||
set_total_expense_zero("2013-02-28", "Cost Center")
|
set_total_expense_zero("2013-02-28", "cost_center")
|
||||||
set_total_expense_zero("2013-02-28", "Cost Center", "_Test Cost Center 2 - _TC")
|
set_total_expense_zero("2013-02-28", "cost_center", "_Test Cost Center 2 - _TC")
|
||||||
|
|
||||||
budget = make_budget(budget_against="Cost Center", cost_center="_Test Company - _TC")
|
budget = make_budget(budget_against="Cost Center", cost_center="_Test Company - _TC")
|
||||||
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
|
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
|
||||||
@@ -241,25 +241,30 @@ class TestBudget(unittest.TestCase):
|
|||||||
|
|
||||||
|
|
||||||
def set_total_expense_zero(posting_date, budget_against_field=None, budget_against_CC=None):
|
def set_total_expense_zero(posting_date, budget_against_field=None, budget_against_CC=None):
|
||||||
if budget_against_field == "Project":
|
if budget_against_field == "project":
|
||||||
budget_against = "_Test Project"
|
budget_against = "_Test Project"
|
||||||
else:
|
else:
|
||||||
budget_against = budget_against_CC or "_Test Cost Center - _TC"
|
budget_against = budget_against_CC or "_Test Cost Center - _TC"
|
||||||
existing_expense = get_actual_expense(frappe._dict({
|
|
||||||
|
args = frappe._dict({
|
||||||
"account": "_Test Account Cost for Goods Sold - _TC",
|
"account": "_Test Account Cost for Goods Sold - _TC",
|
||||||
"cost_center": "_Test Cost Center - _TC",
|
"cost_center": "_Test Cost Center - _TC",
|
||||||
"monthly_end_date": posting_date,
|
"monthly_end_date": posting_date,
|
||||||
"company": "_Test Company",
|
"company": "_Test Company",
|
||||||
"fiscal_year": "_Test Fiscal Year 2013",
|
"fiscal_year": "_Test Fiscal Year 2013",
|
||||||
"budget_against_field": budget_against_field,
|
"budget_against_field": budget_against_field,
|
||||||
"budget_against": budget_against
|
})
|
||||||
}))
|
|
||||||
|
if not args.get(budget_against_field):
|
||||||
|
args[budget_against_field] = budget_against
|
||||||
|
|
||||||
|
existing_expense = get_actual_expense(args)
|
||||||
|
|
||||||
if existing_expense:
|
if existing_expense:
|
||||||
if budget_against_field == "Cost Center":
|
if budget_against_field == "cost_center":
|
||||||
make_journal_entry("_Test Account Cost for Goods Sold - _TC",
|
make_journal_entry("_Test Account Cost for Goods Sold - _TC",
|
||||||
"_Test Bank - _TC", -existing_expense, "_Test Cost Center - _TC", posting_date="2013-02-28", submit=True)
|
"_Test Bank - _TC", -existing_expense, "_Test Cost Center - _TC", posting_date="2013-02-28", submit=True)
|
||||||
elif budget_against_field == "Project":
|
elif budget_against_field == "project":
|
||||||
make_journal_entry("_Test Account Cost for Goods Sold - _TC",
|
make_journal_entry("_Test Account Cost for Goods Sold - _TC",
|
||||||
"_Test Bank - _TC", -existing_expense, "_Test Cost Center - _TC", submit=True, project="_Test Project", posting_date="2013-02-28")
|
"_Test Bank - _TC", -existing_expense, "_Test Cost Center - _TC", submit=True, project="_Test Project", posting_date="2013-02-28")
|
||||||
|
|
||||||
|
|||||||
@@ -152,10 +152,9 @@ def build_forest(data):
|
|||||||
return [parent_account]
|
return [parent_account]
|
||||||
elif account_name == child:
|
elif account_name == child:
|
||||||
parent_account_list = return_parent(data, parent_account)
|
parent_account_list = return_parent(data, parent_account)
|
||||||
if not parent_account_list:
|
if not parent_account_list and parent_account:
|
||||||
frappe.throw(_("The parent account {0} does not exists in the uploaded template").format(
|
frappe.throw(_("The parent account {0} does not exists in the uploaded template").format(
|
||||||
frappe.bold(parent_account)))
|
frappe.bold(parent_account)))
|
||||||
|
|
||||||
return [child] + parent_account_list
|
return [child] + parent_account_list
|
||||||
|
|
||||||
charts_map, paths = {}, []
|
charts_map, paths = {}, []
|
||||||
@@ -164,7 +163,7 @@ def build_forest(data):
|
|||||||
error_messages = []
|
error_messages = []
|
||||||
|
|
||||||
for i in data:
|
for i in data:
|
||||||
account_name, _, account_number, is_group, account_type, root_type = i
|
account_name, dummy, account_number, is_group, account_type, root_type = i
|
||||||
|
|
||||||
if not account_name:
|
if not account_name:
|
||||||
error_messages.append("Row {0}: Please enter Account Name".format(line_no))
|
error_messages.append("Row {0}: Please enter Account Name".format(line_no))
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
frappe.treeview_settings["Cost Center"] = {
|
frappe.treeview_settings["Cost Center"] = {
|
||||||
breadcrumbs: "Accounts",
|
breadcrumb: "Accounts",
|
||||||
get_tree_root: false,
|
get_tree_root: false,
|
||||||
filters: [{
|
filters: [{
|
||||||
fieldname: "company",
|
fieldname: "company",
|
||||||
|
|||||||
@@ -30,18 +30,10 @@ frappe.ui.form.on('Exchange Rate Revaluation', {
|
|||||||
frm.doc.accounts.forEach(d=> {
|
frm.doc.accounts.forEach(d=> {
|
||||||
total_amt = total_amt + d['new_balance_in_base_currency'];
|
total_amt = total_amt + d['new_balance_in_base_currency'];
|
||||||
});
|
});
|
||||||
if(total_amt === r.sum) {
|
if(total_amt !== r.sum) {
|
||||||
frm.add_custom_button(__("Journal Entry"), function(){
|
frm.add_custom_button(__('Journal Entry'), function() {
|
||||||
frappe.route_options = {
|
|
||||||
'reference_type': 'Exchange Rate Revaluation',
|
|
||||||
'reference_name': frm.doc.name
|
|
||||||
};
|
|
||||||
frappe.set_route("List", "Journal Entry");
|
|
||||||
}, __("View"));
|
|
||||||
} else {
|
|
||||||
frm.add_custom_button(__('Create Journal Entry'), function() {
|
|
||||||
return frm.events.make_jv(frm);
|
return frm.events.make_jv(frm);
|
||||||
});
|
}, __('Create'));
|
||||||
}
|
}
|
||||||
}, 'Journal Entry');
|
}, 'Journal Entry');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
def get_data():
|
||||||
|
return {
|
||||||
|
'fieldname': 'reference_name',
|
||||||
|
'transactions': [
|
||||||
|
{
|
||||||
|
'items': ['Journal Entry']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -106,6 +106,21 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frm.set_query('payment_term', 'references', function(frm, cdt, cdn) {
|
||||||
|
const child = locals[cdt][cdn];
|
||||||
|
if (in_list(['Purchase Invoice', 'Sales Invoice'], child.reference_doctype) && child.reference_name) {
|
||||||
|
let payment_term_list = frappe.get_list('Payment Schedule', {'parent': child.reference_name});
|
||||||
|
|
||||||
|
payment_term_list = payment_term_list.map(pt => pt.payment_term);
|
||||||
|
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
'name': ['in', payment_term_list]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
frm.set_query("reference_name", "references", function(doc, cdt, cdn) {
|
frm.set_query("reference_name", "references", function(doc, cdt, cdn) {
|
||||||
const child = locals[cdt][cdn];
|
const child = locals[cdt][cdn];
|
||||||
const filters = {"docstatus": 1, "company": doc.company};
|
const filters = {"docstatus": 1, "company": doc.company};
|
||||||
@@ -156,8 +171,11 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
|
|
||||||
frm.toggle_display("base_paid_amount", frm.doc.paid_from_account_currency != company_currency);
|
frm.toggle_display("base_paid_amount", frm.doc.paid_from_account_currency != company_currency);
|
||||||
|
|
||||||
frm.toggle_display("base_received_amount", (frm.doc.paid_to_account_currency != company_currency &&
|
frm.toggle_display("base_received_amount", (
|
||||||
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency));
|
frm.doc.paid_to_account_currency != company_currency
|
||||||
|
&& frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency
|
||||||
|
&& frm.doc.base_paid_amount != frm.doc.base_received_amount
|
||||||
|
));
|
||||||
|
|
||||||
frm.toggle_display("received_amount", (frm.doc.payment_type=="Internal Transfer" ||
|
frm.toggle_display("received_amount", (frm.doc.payment_type=="Internal Transfer" ||
|
||||||
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency))
|
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency))
|
||||||
@@ -284,7 +302,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
frm.set_value("contact_email", "");
|
frm.set_value("contact_email", "");
|
||||||
frm.set_value("contact_person", "");
|
frm.set_value("contact_person", "");
|
||||||
}
|
}
|
||||||
if(frm.doc.payment_type && frm.doc.party_type && frm.doc.party) {
|
if(frm.doc.payment_type && frm.doc.party_type && frm.doc.party && frm.doc.company) {
|
||||||
if(!frm.doc.posting_date) {
|
if(!frm.doc.posting_date) {
|
||||||
frappe.msgprint(__("Please select Posting Date before selecting Party"))
|
frappe.msgprint(__("Please select Posting Date before selecting Party"))
|
||||||
frm.set_value("party", "");
|
frm.set_value("party", "");
|
||||||
@@ -501,6 +519,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
paid_amount: function(frm) {
|
paid_amount: function(frm) {
|
||||||
frm.set_value("base_paid_amount", flt(frm.doc.paid_amount) * flt(frm.doc.source_exchange_rate));
|
frm.set_value("base_paid_amount", flt(frm.doc.paid_amount) * flt(frm.doc.source_exchange_rate));
|
||||||
frm.trigger("reset_received_amount");
|
frm.trigger("reset_received_amount");
|
||||||
|
frm.events.hide_unhide_fields(frm);
|
||||||
},
|
},
|
||||||
|
|
||||||
received_amount: function(frm) {
|
received_amount: function(frm) {
|
||||||
@@ -524,6 +543,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
frm.events.set_unallocated_amount(frm);
|
frm.events.set_unallocated_amount(frm);
|
||||||
|
|
||||||
frm.set_paid_amount_based_on_received_amount = false;
|
frm.set_paid_amount_based_on_received_amount = false;
|
||||||
|
frm.events.hide_unhide_fields(frm);
|
||||||
},
|
},
|
||||||
|
|
||||||
reset_received_amount: function(frm) {
|
reset_received_amount: function(frm) {
|
||||||
@@ -1028,4 +1048,4 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -71,9 +71,9 @@ class PaymentEntry(AccountsController):
|
|||||||
self.update_outstanding_amounts()
|
self.update_outstanding_amounts()
|
||||||
self.update_advance_paid()
|
self.update_advance_paid()
|
||||||
self.update_expense_claim()
|
self.update_expense_claim()
|
||||||
|
self.update_payment_schedule()
|
||||||
self.set_status()
|
self.set_status()
|
||||||
|
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
self.setup_party_account_field()
|
self.setup_party_account_field()
|
||||||
self.make_gl_entries(cancel=1)
|
self.make_gl_entries(cancel=1)
|
||||||
@@ -81,7 +81,13 @@ class PaymentEntry(AccountsController):
|
|||||||
self.update_advance_paid()
|
self.update_advance_paid()
|
||||||
self.update_expense_claim()
|
self.update_expense_claim()
|
||||||
self.delink_advance_entry_references()
|
self.delink_advance_entry_references()
|
||||||
|
self.update_payment_schedule(cancel=1)
|
||||||
|
self.set_payment_req_status()
|
||||||
self.set_status()
|
self.set_status()
|
||||||
|
|
||||||
|
def set_payment_req_status(self):
|
||||||
|
from erpnext.accounts.doctype.payment_request.payment_request import update_payment_req_status
|
||||||
|
update_payment_req_status(self, None)
|
||||||
|
|
||||||
def update_outstanding_amounts(self):
|
def update_outstanding_amounts(self):
|
||||||
self.set_missing_ref_details(force=True)
|
self.set_missing_ref_details(force=True)
|
||||||
@@ -89,10 +95,10 @@ class PaymentEntry(AccountsController):
|
|||||||
def validate_duplicate_entry(self):
|
def validate_duplicate_entry(self):
|
||||||
reference_names = []
|
reference_names = []
|
||||||
for d in self.get("references"):
|
for d in self.get("references"):
|
||||||
if (d.reference_doctype, d.reference_name) in reference_names:
|
if (d.reference_doctype, d.reference_name, d.payment_term) in reference_names:
|
||||||
frappe.throw(_("Row #{0}: Duplicate entry in References {1} {2}")
|
frappe.throw(_("Row #{0}: Duplicate entry in References {1} {2}")
|
||||||
.format(d.idx, d.reference_doctype, d.reference_name))
|
.format(d.idx, d.reference_doctype, d.reference_name))
|
||||||
reference_names.append((d.reference_doctype, d.reference_name))
|
reference_names.append((d.reference_doctype, d.reference_name, d.payment_term))
|
||||||
|
|
||||||
def set_bank_account_data(self):
|
def set_bank_account_data(self):
|
||||||
if self.bank_account:
|
if self.bank_account:
|
||||||
@@ -280,6 +286,36 @@ class PaymentEntry(AccountsController):
|
|||||||
frappe.throw(_("Against Journal Entry {0} does not have any unmatched {1} entry")
|
frappe.throw(_("Against Journal Entry {0} does not have any unmatched {1} entry")
|
||||||
.format(d.reference_name, dr_or_cr))
|
.format(d.reference_name, dr_or_cr))
|
||||||
|
|
||||||
|
def update_payment_schedule(self, cancel=0):
|
||||||
|
invoice_payment_amount_map = {}
|
||||||
|
invoice_paid_amount_map = {}
|
||||||
|
|
||||||
|
for reference in self.get('references'):
|
||||||
|
if reference.payment_term and reference.reference_name:
|
||||||
|
key = (reference.payment_term, reference.reference_name)
|
||||||
|
invoice_payment_amount_map.setdefault(key, 0.0)
|
||||||
|
invoice_payment_amount_map[key] += reference.allocated_amount
|
||||||
|
|
||||||
|
if not invoice_paid_amount_map.get(reference.reference_name):
|
||||||
|
payment_schedule = frappe.get_all('Payment Schedule', filters={'parent': reference.reference_name},
|
||||||
|
fields=['paid_amount', 'payment_amount', 'payment_term'])
|
||||||
|
for term in payment_schedule:
|
||||||
|
invoice_key = (term.payment_term, reference.reference_name)
|
||||||
|
invoice_paid_amount_map.setdefault(invoice_key, {})
|
||||||
|
invoice_paid_amount_map[invoice_key]['outstanding'] = term.payment_amount - term.paid_amount
|
||||||
|
|
||||||
|
for key, amount in iteritems(invoice_payment_amount_map):
|
||||||
|
if cancel:
|
||||||
|
frappe.db.sql(""" UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` - %s
|
||||||
|
WHERE parent = %s and payment_term = %s""", (amount, key[1], key[0]))
|
||||||
|
else:
|
||||||
|
outstanding = invoice_paid_amount_map.get(key)['outstanding']
|
||||||
|
if amount > outstanding:
|
||||||
|
frappe.throw(_('Cannot allocate more than {0} against payment term {1}').format(outstanding, key[0]))
|
||||||
|
|
||||||
|
frappe.db.sql(""" UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` + %s
|
||||||
|
WHERE parent = %s and payment_term = %s""", (amount, key[1], key[0]))
|
||||||
|
|
||||||
def set_status(self):
|
def set_status(self):
|
||||||
if self.docstatus == 2:
|
if self.docstatus == 2:
|
||||||
self.status = 'Cancelled'
|
self.status = 'Cancelled'
|
||||||
@@ -1007,15 +1043,22 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
|||||||
if doc.doctype == "Purchase Invoice" and doc.invoice_is_blocked():
|
if doc.doctype == "Purchase Invoice" and doc.invoice_is_blocked():
|
||||||
frappe.msgprint(_('{0} is on hold till {1}').format(doc.name, doc.release_date))
|
frappe.msgprint(_('{0} is on hold till {1}').format(doc.name, doc.release_date))
|
||||||
else:
|
else:
|
||||||
pe.append("references", {
|
if (doc.doctype in ('Sales Invoice', 'Purchase Invoice')
|
||||||
'reference_doctype': dt,
|
and frappe.get_value('Payment Terms Template',
|
||||||
'reference_name': dn,
|
{'name': doc.payment_terms_template}, 'allocate_payment_based_on_payment_terms')):
|
||||||
"bill_no": doc.get("bill_no"),
|
|
||||||
"due_date": doc.get("due_date"),
|
for reference in get_reference_as_per_payment_terms(doc.payment_schedule, dt, dn, doc, grand_total, outstanding_amount):
|
||||||
'total_amount': grand_total,
|
pe.append('references', reference)
|
||||||
'outstanding_amount': outstanding_amount,
|
else:
|
||||||
'allocated_amount': outstanding_amount
|
pe.append("references", {
|
||||||
})
|
'reference_doctype': dt,
|
||||||
|
'reference_name': dn,
|
||||||
|
"bill_no": doc.get("bill_no"),
|
||||||
|
"due_date": doc.get("due_date"),
|
||||||
|
'total_amount': grand_total,
|
||||||
|
'outstanding_amount': outstanding_amount,
|
||||||
|
'allocated_amount': outstanding_amount
|
||||||
|
})
|
||||||
|
|
||||||
pe.setup_party_account_field()
|
pe.setup_party_account_field()
|
||||||
pe.set_missing_values()
|
pe.set_missing_values()
|
||||||
@@ -1024,6 +1067,22 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
|||||||
pe.set_amounts()
|
pe.set_amounts()
|
||||||
return pe
|
return pe
|
||||||
|
|
||||||
|
def get_reference_as_per_payment_terms(payment_schedule, dt, dn, doc, grand_total, outstanding_amount):
|
||||||
|
references = []
|
||||||
|
for payment_term in payment_schedule:
|
||||||
|
references.append({
|
||||||
|
'reference_doctype': dt,
|
||||||
|
'reference_name': dn,
|
||||||
|
'bill_no': doc.get('bill_no'),
|
||||||
|
'due_date': doc.get('due_date'),
|
||||||
|
'total_amount': grand_total,
|
||||||
|
'outstanding_amount': outstanding_amount,
|
||||||
|
'payment_term': payment_term.payment_term,
|
||||||
|
'allocated_amount': flt(payment_term.payment_amount - payment_term.paid_amount,
|
||||||
|
payment_term.precision('payment_amount'))
|
||||||
|
})
|
||||||
|
|
||||||
|
return references
|
||||||
|
|
||||||
def get_paid_amount(dt, dn, party_type, party, account, due_date):
|
def get_paid_amount(dt, dn, party_type, party, account, due_date):
|
||||||
if party_type=="Customer":
|
if party_type=="Customer":
|
||||||
|
|||||||
@@ -171,6 +171,32 @@ class TestPaymentEntry(unittest.TestCase):
|
|||||||
self.assertEqual(flt(outstanding_amount), 100)
|
self.assertEqual(flt(outstanding_amount), 100)
|
||||||
self.assertEqual(status, 'Unpaid')
|
self.assertEqual(status, 'Unpaid')
|
||||||
|
|
||||||
|
def test_payment_entry_against_payment_terms(self):
|
||||||
|
si = create_sales_invoice(do_not_save=1, qty=1, rate=200)
|
||||||
|
create_payment_terms_template()
|
||||||
|
si.payment_terms_template = 'Test Receivable Template'
|
||||||
|
|
||||||
|
si.append('taxes', {
|
||||||
|
"charge_type": "On Net Total",
|
||||||
|
"account_head": "_Test Account Service Tax - _TC",
|
||||||
|
"cost_center": "_Test Cost Center - _TC",
|
||||||
|
"description": "Service Tax",
|
||||||
|
"rate": 18
|
||||||
|
})
|
||||||
|
si.save()
|
||||||
|
|
||||||
|
si.submit()
|
||||||
|
|
||||||
|
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC")
|
||||||
|
pe.submit()
|
||||||
|
si.load_from_db()
|
||||||
|
|
||||||
|
self.assertEqual(pe.references[0].payment_term, 'Basic Amount Receivable')
|
||||||
|
self.assertEqual(pe.references[1].payment_term, 'Tax Receivable')
|
||||||
|
self.assertEqual(si.payment_schedule[0].paid_amount, 200.0)
|
||||||
|
self.assertEqual(si.payment_schedule[1].paid_amount, 36.0)
|
||||||
|
|
||||||
|
|
||||||
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",
|
||||||
currency="USD", conversion_rate=50)
|
currency="USD", conversion_rate=50)
|
||||||
@@ -609,4 +635,38 @@ class TestPaymentEntry(unittest.TestCase):
|
|||||||
self.assertEqual(expected_party_account_balance, party_account_balance)
|
self.assertEqual(expected_party_account_balance, party_account_balance)
|
||||||
|
|
||||||
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
|
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
|
||||||
accounts_settings.save()
|
accounts_settings.save()
|
||||||
|
|
||||||
|
def create_payment_terms_template():
|
||||||
|
|
||||||
|
create_payment_term('Basic Amount Receivable')
|
||||||
|
create_payment_term('Tax Receivable')
|
||||||
|
|
||||||
|
if not frappe.db.exists('Payment Terms Template', 'Test Receivable Template'):
|
||||||
|
payment_term_template = frappe.get_doc({
|
||||||
|
'doctype': 'Payment Terms Template',
|
||||||
|
'template_name': 'Test Receivable Template',
|
||||||
|
'allocate_payment_based_on_payment_terms': 1,
|
||||||
|
'terms': [{
|
||||||
|
'doctype': 'Payment Terms Template Detail',
|
||||||
|
'payment_term': 'Basic Amount Receivable',
|
||||||
|
'invoice_portion': 84.746,
|
||||||
|
'credit_days_based_on': 'Day(s) after invoice date',
|
||||||
|
'credit_days': 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'doctype': 'Payment Terms Template Detail',
|
||||||
|
'payment_term': 'Tax Receivable',
|
||||||
|
'invoice_portion': 15.254,
|
||||||
|
'credit_days_based_on': 'Day(s) after invoice date',
|
||||||
|
'credit_days': 2
|
||||||
|
}]
|
||||||
|
}).insert()
|
||||||
|
|
||||||
|
|
||||||
|
def create_payment_term(name):
|
||||||
|
if not frappe.db.exists('Payment Term', name):
|
||||||
|
frappe.get_doc({
|
||||||
|
'doctype': 'Payment Term',
|
||||||
|
'payment_term_name': name
|
||||||
|
}).insert()
|
||||||
@@ -1,343 +1,107 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_events_in_timeline": 0,
|
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2016-06-01 16:55:32.196722",
|
"creation": "2016-06-01 16:55:32.196722",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"reference_doctype",
|
||||||
|
"reference_name",
|
||||||
|
"due_date",
|
||||||
|
"bill_no",
|
||||||
|
"payment_term",
|
||||||
|
"column_break_4",
|
||||||
|
"total_amount",
|
||||||
|
"outstanding_amount",
|
||||||
|
"allocated_amount",
|
||||||
|
"exchange_rate"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 2,
|
"columns": 2,
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "reference_doctype",
|
"fieldname": "reference_doctype",
|
||||||
"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": "Type",
|
"label": "Type",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "DocType",
|
"options": "DocType",
|
||||||
"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,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 2,
|
"columns": 2,
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "reference_name",
|
"fieldname": "reference_name",
|
||||||
"fieldtype": "Dynamic Link",
|
"fieldtype": "Dynamic Link",
|
||||||
"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": "Name",
|
"label": "Name",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "reference_doctype",
|
"options": "reference_doctype",
|
||||||
"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,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "due_date",
|
"fieldname": "due_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"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": "Due Date",
|
"label": "Due Date",
|
||||||
"length": 0,
|
"read_only": 1
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"depends_on": "",
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "bill_no",
|
"fieldname": "bill_no",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Supplier Invoice No",
|
"label": "Supplier Invoice No",
|
||||||
"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,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "column_break_4",
|
"fieldname": "column_break_4",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column 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": 2,
|
"columns": 2,
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "total_amount",
|
"fieldname": "total_amount",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"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": "Total Amount",
|
"label": "Total Amount",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"print_hide_if_no_value": 0,
|
"read_only": 1
|
||||||
"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": 2,
|
"columns": 2,
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "outstanding_amount",
|
"fieldname": "outstanding_amount",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"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": "Outstanding",
|
"label": "Outstanding",
|
||||||
"length": 0,
|
"read_only": 1
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 2,
|
"columns": 2,
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "allocated_amount",
|
"fieldname": "allocated_amount",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"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": "Allocated"
|
||||||
"label": "Allocated",
|
|
||||||
"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,
|
|
||||||
"depends_on": "eval:(doc.reference_doctype=='Purchase Invoice')",
|
"depends_on": "eval:(doc.reference_doctype=='Purchase Invoice')",
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "exchange_rate",
|
"fieldname": "exchange_rate",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"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": "Exchange Rate",
|
"label": "Exchange Rate",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"print_hide_if_no_value": 0,
|
"read_only": 1
|
||||||
"read_only": 1,
|
},
|
||||||
"remember_last_selected_value": 0,
|
{
|
||||||
"report_hide": 0,
|
"fieldname": "payment_term",
|
||||||
"reqd": 0,
|
"fieldtype": "Link",
|
||||||
"search_index": 0,
|
"label": "Payment Term",
|
||||||
"set_only_once": 0,
|
"options": "Payment Term"
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 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,
|
"links": [],
|
||||||
"modified": "2019-05-01 13:24:56.586677",
|
"modified": "2020-03-13 12:07:19.362539",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Entry Reference",
|
"name": "Payment Entry Reference",
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"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
|
|
||||||
}
|
}
|
||||||
@@ -15,11 +15,11 @@ frappe.ui.form.on('Payment Order', {
|
|||||||
if (frm.doc.docstatus == 0) {
|
if (frm.doc.docstatus == 0) {
|
||||||
frm.add_custom_button(__('Payment Request'), function() {
|
frm.add_custom_button(__('Payment Request'), function() {
|
||||||
frm.trigger("get_from_payment_request");
|
frm.trigger("get_from_payment_request");
|
||||||
}, __("Get from"));
|
}, __("Get Payments from"));
|
||||||
|
|
||||||
frm.add_custom_button(__('Payment Entry'), function() {
|
frm.add_custom_button(__('Payment Entry'), function() {
|
||||||
frm.trigger("get_from_payment_entry");
|
frm.trigger("get_from_payment_entry");
|
||||||
}, __("Get from"));
|
}, __("Get Payments from"));
|
||||||
|
|
||||||
frm.trigger('remove_button');
|
frm.trigger('remove_button');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,6 @@
|
|||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 1,
|
|
||||||
"fieldname": "references",
|
"fieldname": "references",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"label": "Payment Order Reference",
|
"label": "Payment Order Reference",
|
||||||
@@ -108,7 +107,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-05-14 17:12:24.912666",
|
"modified": "2020-04-06 18:00:56.022642",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Order",
|
"name": "Payment Order",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -66,6 +66,8 @@ class PaymentRequest(Document):
|
|||||||
if self.payment_request_type == 'Outward':
|
if self.payment_request_type == 'Outward':
|
||||||
self.db_set('status', 'Initiated')
|
self.db_set('status', 'Initiated')
|
||||||
return
|
return
|
||||||
|
elif self.payment_request_type == 'Inward':
|
||||||
|
self.db_set('status', 'Requested')
|
||||||
|
|
||||||
send_mail = self.payment_gateway_validation()
|
send_mail = self.payment_gateway_validation()
|
||||||
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
||||||
@@ -88,6 +90,7 @@ class PaymentRequest(Document):
|
|||||||
if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart"):
|
if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart"):
|
||||||
from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
|
from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
|
||||||
si = make_sales_invoice(self.reference_name, ignore_permissions=True)
|
si = make_sales_invoice(self.reference_name, ignore_permissions=True)
|
||||||
|
si.allocate_advances_automatically = True
|
||||||
si = si.insert(ignore_permissions=True)
|
si = si.insert(ignore_permissions=True)
|
||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
@@ -415,17 +418,31 @@ def make_payment_entry(docname):
|
|||||||
doc = frappe.get_doc("Payment Request", docname)
|
doc = frappe.get_doc("Payment Request", docname)
|
||||||
return doc.create_payment_entry(submit=False).as_dict()
|
return doc.create_payment_entry(submit=False).as_dict()
|
||||||
|
|
||||||
def make_status_as_paid(doc, method):
|
def update_payment_req_status(doc, method):
|
||||||
|
from erpnext.accounts.doctype.payment_entry.payment_entry import get_reference_details
|
||||||
|
|
||||||
for ref in doc.references:
|
for ref in doc.references:
|
||||||
payment_request_name = frappe.db.get_value("Payment Request",
|
payment_request_name = frappe.db.get_value("Payment Request",
|
||||||
{"reference_doctype": ref.reference_doctype, "reference_name": ref.reference_name,
|
{"reference_doctype": ref.reference_doctype, "reference_name": ref.reference_name,
|
||||||
"docstatus": 1})
|
"docstatus": 1})
|
||||||
|
|
||||||
if payment_request_name:
|
if payment_request_name:
|
||||||
doc = frappe.get_doc("Payment Request", payment_request_name)
|
ref_details = get_reference_details(ref.reference_doctype, ref.reference_name, doc.party_account_currency)
|
||||||
if doc.status != "Paid":
|
pay_req_doc = frappe.get_doc('Payment Request', payment_request_name)
|
||||||
doc.db_set('status', 'Paid')
|
status = pay_req_doc.status
|
||||||
frappe.db.commit()
|
|
||||||
|
if status != "Paid" and not ref_details.outstanding_amount:
|
||||||
|
status = 'Paid'
|
||||||
|
elif status != "Partially Paid" and ref_details.outstanding_amount != ref_details.total_amount:
|
||||||
|
status = 'Partially Paid'
|
||||||
|
elif ref_details.outstanding_amount == ref_details.total_amount:
|
||||||
|
if pay_req_doc.payment_request_type == 'Outward':
|
||||||
|
status = 'Initiated'
|
||||||
|
elif pay_req_doc.payment_request_type == 'Inward':
|
||||||
|
status = 'Requested'
|
||||||
|
|
||||||
|
pay_req_doc.db_set('status', status)
|
||||||
|
frappe.db.commit()
|
||||||
|
|
||||||
def get_dummy_message(doc):
|
def get_dummy_message(doc):
|
||||||
return frappe.render_template("""{% if doc.contact_person -%}
|
return frappe.render_template("""{% if doc.contact_person -%}
|
||||||
|
|||||||
@@ -4,14 +4,20 @@ frappe.listview_settings['Payment Request'] = {
|
|||||||
if(doc.status == "Draft") {
|
if(doc.status == "Draft") {
|
||||||
return [__("Draft"), "darkgrey", "status,=,Draft"];
|
return [__("Draft"), "darkgrey", "status,=,Draft"];
|
||||||
}
|
}
|
||||||
|
if(doc.status == "Requested") {
|
||||||
|
return [__("Requested"), "green", "status,=,Requested"];
|
||||||
|
}
|
||||||
else if(doc.status == "Initiated") {
|
else if(doc.status == "Initiated") {
|
||||||
return [__("Initiated"), "green", "status,=,Initiated"];
|
return [__("Initiated"), "green", "status,=,Initiated"];
|
||||||
}
|
}
|
||||||
|
else if(doc.status == "Partially Paid") {
|
||||||
|
return [__("Partially Paid"), "orange", "status,=,Partially Paid"];
|
||||||
|
}
|
||||||
else if(doc.status == "Paid") {
|
else if(doc.status == "Paid") {
|
||||||
return [__("Paid"), "blue", "status,=,Paid"];
|
return [__("Paid"), "blue", "status,=,Paid"];
|
||||||
}
|
}
|
||||||
else if(doc.status == "Cancelled") {
|
else if(doc.status == "Cancelled") {
|
||||||
return [__("Cancelled"), "orange", "status,=,Cancelled"];
|
return [__("Cancelled"), "red", "status,=,Cancelled"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,23 @@ class TestPaymentRequest(unittest.TestCase):
|
|||||||
self.assertEqual(expected_gle[gle.account][2], gle.credit)
|
self.assertEqual(expected_gle[gle.account][2], gle.credit)
|
||||||
self.assertEqual(expected_gle[gle.account][3], gle.against_voucher)
|
self.assertEqual(expected_gle[gle.account][3], gle.against_voucher)
|
||||||
|
|
||||||
|
def test_status(self):
|
||||||
|
si_usd = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
||||||
|
currency="USD", conversion_rate=50)
|
||||||
|
|
||||||
|
pr = make_payment_request(dt="Sales Invoice", dn=si_usd.name, recipient_id="saurabh@erpnext.com",
|
||||||
|
mute_email=1, payment_gateway="_Test Gateway - USD", submit_doc=1, return_doc=1)
|
||||||
|
|
||||||
|
pe = pr.create_payment_entry()
|
||||||
|
pr.load_from_db()
|
||||||
|
|
||||||
|
self.assertEqual(pr.status, 'Paid')
|
||||||
|
|
||||||
|
pe.cancel()
|
||||||
|
pr.load_from_db()
|
||||||
|
|
||||||
|
self.assertEqual(pr.status, 'Requested')
|
||||||
|
|
||||||
def test_multiple_payment_entries_against_sales_order(self):
|
def test_multiple_payment_entries_against_sales_order(self):
|
||||||
# Make Sales Order, grand_total = 1000
|
# Make Sales Order, grand_total = 1000
|
||||||
so = make_sales_order()
|
so = make_sales_order()
|
||||||
|
|||||||
@@ -1,243 +1,82 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_guest_to_view": 0,
|
"creation": "2017-08-10 15:38:00.080575",
|
||||||
"allow_import": 0,
|
"doctype": "DocType",
|
||||||
"allow_rename": 0,
|
"editable_grid": 1,
|
||||||
"autoname": "",
|
"engine": "InnoDB",
|
||||||
"beta": 0,
|
"field_order": [
|
||||||
"creation": "2017-08-10 15:38:00.080575",
|
"payment_term",
|
||||||
"custom": 0,
|
"description",
|
||||||
"docstatus": 0,
|
"due_date",
|
||||||
"doctype": "DocType",
|
"invoice_portion",
|
||||||
"document_type": "",
|
"payment_amount",
|
||||||
"editable_grid": 1,
|
"mode_of_payment",
|
||||||
"engine": "InnoDB",
|
"paid_amount"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 2,
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "payment_term",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Payment Term",
|
||||||
"columns": 2,
|
"options": "Payment Term",
|
||||||
"fieldname": "payment_term",
|
"print_hide": 1
|
||||||
"fieldtype": "Link",
|
},
|
||||||
"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": "Payment Term",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Payment Term",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 1,
|
|
||||||
"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,
|
"columns": 2,
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "description",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Small Text",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Description"
|
||||||
"columns": 2,
|
},
|
||||||
"fetch_from": "",
|
|
||||||
"fieldname": "description",
|
|
||||||
"fieldtype": "Small Text",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Description",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"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,
|
"columns": 2,
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "due_date",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Date",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Due Date",
|
||||||
"columns": 2,
|
"reqd": 1
|
||||||
"fieldname": "due_date",
|
},
|
||||||
"fieldtype": "Date",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Due Date",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"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,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 2,
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "invoice_portion",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Percent",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Invoice Portion",
|
||||||
"columns": 2,
|
"print_hide": 1
|
||||||
"fetch_from": "",
|
},
|
||||||
"fieldname": "invoice_portion",
|
|
||||||
"fieldtype": "Percent",
|
|
||||||
"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": "Invoice Portion",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 1,
|
|
||||||
"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,
|
"columns": 2,
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "payment_amount",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Currency",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Payment Amount",
|
||||||
"columns": 2,
|
"options": "currency",
|
||||||
"fieldname": "payment_amount",
|
"reqd": 1
|
||||||
"fieldtype": "Currency",
|
},
|
||||||
"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": "Payment Amount",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "mode_of_payment",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"label": "Mode of Payment",
|
||||||
"bold": 0,
|
"options": "Mode of Payment"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
{
|
||||||
"fieldname": "mode_of_payment",
|
"fieldname": "paid_amount",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"label": "Paid Amount"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Mode of Payment",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Mode of Payment",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"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,
|
"istable": 1,
|
||||||
"hide_heading": 0,
|
"links": [],
|
||||||
"hide_toolbar": 0,
|
"modified": "2020-03-13 17:58:24.729526",
|
||||||
"idx": 0,
|
"modified_by": "Administrator",
|
||||||
"image_view": 0,
|
"module": "Accounts",
|
||||||
"in_create": 0,
|
"name": "Payment Schedule",
|
||||||
"is_submittable": 0,
|
"owner": "Administrator",
|
||||||
"issingle": 0,
|
"permissions": [],
|
||||||
"istable": 1,
|
"quick_entry": 1,
|
||||||
"max_attachments": 0,
|
"sort_field": "modified",
|
||||||
"modified": "2018-09-06 17:35:44.580209",
|
"sort_order": "DESC",
|
||||||
"modified_by": "Administrator",
|
"track_changes": 1
|
||||||
"module": "Accounts",
|
|
||||||
"name": "Payment Schedule",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [],
|
|
||||||
"quick_entry": 1,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 1,
|
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
}
|
||||||
@@ -1,164 +1,84 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_guest_to_view": 0,
|
"allow_import": 1,
|
||||||
"allow_import": 1,
|
"allow_rename": 1,
|
||||||
"allow_rename": 1,
|
"autoname": "field:template_name",
|
||||||
"autoname": "field:template_name",
|
"creation": "2017-08-10 15:34:28.058054",
|
||||||
"beta": 0,
|
"doctype": "DocType",
|
||||||
"creation": "2017-08-10 15:34:28.058054",
|
"editable_grid": 1,
|
||||||
"custom": 0,
|
"engine": "InnoDB",
|
||||||
"docstatus": 0,
|
"field_order": [
|
||||||
"doctype": "DocType",
|
"template_name",
|
||||||
"document_type": "",
|
"allocate_payment_based_on_payment_terms",
|
||||||
"editable_grid": 1,
|
"terms"
|
||||||
"engine": "InnoDB",
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "template_name",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Data",
|
||||||
"bold": 0,
|
"label": "Template Name",
|
||||||
"collapsible": 0,
|
"unique": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "template_name",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Template 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": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "terms",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Table",
|
||||||
"bold": 0,
|
"label": "Payment Terms",
|
||||||
"collapsible": 0,
|
"options": "Payment Terms Template Detail",
|
||||||
"columns": 0,
|
"reqd": 1
|
||||||
"fieldname": "terms",
|
},
|
||||||
"fieldtype": "Table",
|
{
|
||||||
"hidden": 0,
|
"default": "0",
|
||||||
"ignore_user_permissions": 0,
|
"description": "If this checkbox is checked, paid amount will be splitted and allocated as per the amounts in payment schedule against each payment term",
|
||||||
"ignore_xss_filter": 0,
|
"fieldname": "allocate_payment_based_on_payment_terms",
|
||||||
"in_filter": 0,
|
"fieldtype": "Check",
|
||||||
"in_global_search": 0,
|
"label": "Allocate Payment Based On Payment Terms"
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Payment Terms",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Payment Terms Template Detail",
|
|
||||||
"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,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"links": [],
|
||||||
"hide_heading": 0,
|
"modified": "2020-04-01 15:35:18.112619",
|
||||||
"hide_toolbar": 0,
|
"modified_by": "Administrator",
|
||||||
"idx": 0,
|
"module": "Accounts",
|
||||||
"image_view": 0,
|
"name": "Payment Terms Template",
|
||||||
"in_create": 0,
|
"owner": "Administrator",
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-01-24 11:13:31.158613",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Accounts",
|
|
||||||
"name": "Payment Terms Template",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"apply_user_permissions": 0,
|
"delete": 1,
|
||||||
"cancel": 0,
|
"email": 1,
|
||||||
"create": 1,
|
"export": 1,
|
||||||
"delete": 1,
|
"print": 1,
|
||||||
"email": 1,
|
"read": 1,
|
||||||
"export": 1,
|
"report": 1,
|
||||||
"if_owner": 0,
|
"role": "System Manager",
|
||||||
"import": 0,
|
"share": 1,
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "System Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"apply_user_permissions": 0,
|
"delete": 1,
|
||||||
"cancel": 0,
|
"email": 1,
|
||||||
"create": 1,
|
"export": 1,
|
||||||
"delete": 1,
|
"print": 1,
|
||||||
"email": 1,
|
"read": 1,
|
||||||
"export": 1,
|
"report": 1,
|
||||||
"if_owner": 0,
|
"role": "Accounts User",
|
||||||
"import": 0,
|
"share": 1,
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Accounts User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"apply_user_permissions": 0,
|
"delete": 1,
|
||||||
"cancel": 0,
|
"email": 1,
|
||||||
"create": 1,
|
"export": 1,
|
||||||
"delete": 1,
|
"print": 1,
|
||||||
"email": 1,
|
"read": 1,
|
||||||
"export": 1,
|
"report": 1,
|
||||||
"if_owner": 0,
|
"role": "Accounts Manager",
|
||||||
"import": 0,
|
"share": 1,
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Accounts Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 0,
|
"sort_field": "modified",
|
||||||
"read_only": 0,
|
"sort_order": "DESC",
|
||||||
"read_only_onload": 0,
|
"track_changes": 1
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 1,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
}
|
||||||
@@ -237,6 +237,7 @@ def get_pricing_rule_for_item(args, price_list_rate=0, doc=None, for_validate=Fa
|
|||||||
if pricing_rule.mixed_conditions or pricing_rule.apply_rule_on_other:
|
if pricing_rule.mixed_conditions or pricing_rule.apply_rule_on_other:
|
||||||
item_details.update({
|
item_details.update({
|
||||||
'apply_rule_on_other_items': json.dumps(pricing_rule.apply_rule_on_other_items),
|
'apply_rule_on_other_items': json.dumps(pricing_rule.apply_rule_on_other_items),
|
||||||
|
'price_or_product_discount': pricing_rule.price_or_product_discount,
|
||||||
'apply_rule_on': (frappe.scrub(pricing_rule.apply_rule_on_other)
|
'apply_rule_on': (frappe.scrub(pricing_rule.apply_rule_on_other)
|
||||||
if pricing_rule.apply_rule_on_other else frappe.scrub(pricing_rule.get('apply_on')))
|
if pricing_rule.apply_rule_on_other else frappe.scrub(pricing_rule.get('apply_on')))
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -178,7 +178,8 @@ def filter_pricing_rules(args, pricing_rules, doc=None):
|
|||||||
|
|
||||||
if pricing_rules[0].mixed_conditions and doc:
|
if pricing_rules[0].mixed_conditions and doc:
|
||||||
stock_qty, amount, items = get_qty_and_rate_for_mixed_conditions(doc, pr_doc, args)
|
stock_qty, amount, items = get_qty_and_rate_for_mixed_conditions(doc, pr_doc, args)
|
||||||
pricing_rules[0].apply_rule_on_other_items = items
|
for pricing_rule_args in pricing_rules:
|
||||||
|
pricing_rule_args.apply_rule_on_other_items = items
|
||||||
|
|
||||||
elif pricing_rules[0].is_cumulative:
|
elif pricing_rules[0].is_cumulative:
|
||||||
items = [args.get(frappe.scrub(pr_doc.get('apply_on')))]
|
items = [args.get(frappe.scrub(pr_doc.get('apply_on')))]
|
||||||
@@ -329,9 +330,9 @@ def get_qty_and_rate_for_mixed_conditions(doc, pr_doc, args):
|
|||||||
if pr_doc.mixed_conditions:
|
if pr_doc.mixed_conditions:
|
||||||
amt = args.get('qty') * args.get("price_list_rate")
|
amt = args.get('qty') * args.get("price_list_rate")
|
||||||
if args.get("item_code") != row.get("item_code"):
|
if args.get("item_code") != row.get("item_code"):
|
||||||
amt = row.get('qty') * row.get("price_list_rate")
|
amt = flt(row.get('qty')) * flt(row.get("price_list_rate") or args.get("rate"))
|
||||||
|
|
||||||
sum_qty += row.get("stock_qty") or args.get("stock_qty")
|
sum_qty += flt(row.get("stock_qty")) or flt(args.get("stock_qty")) or flt(args.get("qty"))
|
||||||
sum_amt += amt
|
sum_amt += amt
|
||||||
|
|
||||||
if pr_doc.is_cumulative:
|
if pr_doc.is_cumulative:
|
||||||
|
|||||||
@@ -174,7 +174,8 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
|||||||
read_only: 0,
|
read_only: 0,
|
||||||
fieldtype:'Date',
|
fieldtype:'Date',
|
||||||
label: __('Release Date'),
|
label: __('Release Date'),
|
||||||
default: me.frm.doc.release_date
|
default: me.frm.doc.release_date,
|
||||||
|
reqd: 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: 'hold_comment',
|
fieldname: 'hold_comment',
|
||||||
@@ -260,12 +261,25 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
|||||||
price_list: this.frm.doc.buying_price_list
|
price_list: this.frm.doc.buying_price_list
|
||||||
}, function() {
|
}, function() {
|
||||||
me.apply_pricing_rule();
|
me.apply_pricing_rule();
|
||||||
|
|
||||||
me.frm.doc.apply_tds = me.frm.supplier_tds ? 1 : 0;
|
me.frm.doc.apply_tds = me.frm.supplier_tds ? 1 : 0;
|
||||||
|
me.frm.doc.tax_withholding_category = me.frm.supplier_tds;
|
||||||
me.frm.set_df_property("apply_tds", "read_only", me.frm.supplier_tds ? 0 : 1);
|
me.frm.set_df_property("apply_tds", "read_only", me.frm.supplier_tds ? 0 : 1);
|
||||||
|
me.frm.set_df_property("tax_withholding_category", "hidden", me.frm.supplier_tds ? 0 : 1);
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
apply_tds: function(frm) {
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
if (!me.frm.doc.apply_tds) {
|
||||||
|
me.frm.set_value("tax_withholding_category", '');
|
||||||
|
me.frm.set_df_property("tax_withholding_category", "hidden", 1);
|
||||||
|
} else {
|
||||||
|
me.frm.set_value("tax_withholding_category", me.frm.supplier_tds);
|
||||||
|
me.frm.set_df_property("tax_withholding_category", "hidden", 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
credit_to: function() {
|
credit_to: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
if(this.frm.doc.credit_to) {
|
if(this.frm.doc.credit_to) {
|
||||||
|
|||||||
@@ -13,23 +13,19 @@
|
|||||||
"supplier_name",
|
"supplier_name",
|
||||||
"tax_id",
|
"tax_id",
|
||||||
"due_date",
|
"due_date",
|
||||||
"is_paid",
|
"tax_withholding_category",
|
||||||
"is_return",
|
|
||||||
"apply_tds",
|
|
||||||
"column_break1",
|
"column_break1",
|
||||||
"company",
|
"company",
|
||||||
"posting_date",
|
"posting_date",
|
||||||
"posting_time",
|
"posting_time",
|
||||||
"set_posting_time",
|
"set_posting_time",
|
||||||
|
"is_paid",
|
||||||
|
"is_return",
|
||||||
|
"apply_tds",
|
||||||
"amended_from",
|
"amended_from",
|
||||||
"accounting_dimensions_section",
|
"accounting_dimensions_section",
|
||||||
"cost_center",
|
"cost_center",
|
||||||
"dimension_col_break",
|
"dimension_col_break",
|
||||||
"sb_14",
|
|
||||||
"on_hold",
|
|
||||||
"release_date",
|
|
||||||
"cb_17",
|
|
||||||
"hold_comment",
|
|
||||||
"supplier_invoice_details",
|
"supplier_invoice_details",
|
||||||
"bill_no",
|
"bill_no",
|
||||||
"column_break_15",
|
"column_break_15",
|
||||||
@@ -73,9 +69,9 @@
|
|||||||
"base_total",
|
"base_total",
|
||||||
"base_net_total",
|
"base_net_total",
|
||||||
"column_break_28",
|
"column_break_28",
|
||||||
|
"total_net_weight",
|
||||||
"total",
|
"total",
|
||||||
"net_total",
|
"net_total",
|
||||||
"total_net_weight",
|
|
||||||
"taxes_section",
|
"taxes_section",
|
||||||
"tax_category",
|
"tax_category",
|
||||||
"column_break_49",
|
"column_break_49",
|
||||||
@@ -137,10 +133,15 @@
|
|||||||
"terms",
|
"terms",
|
||||||
"printing_settings",
|
"printing_settings",
|
||||||
"letter_head",
|
"letter_head",
|
||||||
"group_same_items",
|
|
||||||
"column_break_112",
|
|
||||||
"select_print_heading",
|
"select_print_heading",
|
||||||
|
"column_break_112",
|
||||||
|
"group_same_items",
|
||||||
"language",
|
"language",
|
||||||
|
"sb_14",
|
||||||
|
"on_hold",
|
||||||
|
"release_date",
|
||||||
|
"cb_17",
|
||||||
|
"hold_comment",
|
||||||
"more_info",
|
"more_info",
|
||||||
"credit_to",
|
"credit_to",
|
||||||
"party_account_currency",
|
"party_account_currency",
|
||||||
@@ -190,6 +191,7 @@
|
|||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "Supplier",
|
"options": "Supplier",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
|
"reqd": 1,
|
||||||
"search_index": 1
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1232,6 +1234,7 @@
|
|||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"collapsible": 1,
|
||||||
"fieldname": "subscription_section",
|
"fieldname": "subscription_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Subscription Section",
|
"label": "Subscription Section",
|
||||||
@@ -1292,13 +1295,21 @@
|
|||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Is Internal Supplier",
|
"label": "Is Internal Supplier",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "tax_withholding_category",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 1,
|
||||||
|
"label": "Tax Withholding Category",
|
||||||
|
"options": "Tax Withholding Category",
|
||||||
|
"print_hide": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 204,
|
"idx": 204,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2019-12-30 19:13:49.610538",
|
"modified": "2020-04-18 13:05:25.199832",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Purchase Invoice",
|
"name": "Purchase Invoice",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe, erpnext
|
import frappe, erpnext
|
||||||
from frappe.utils import cint, cstr, formatdate, flt, getdate, nowdate
|
from frappe.utils import cint, cstr, formatdate, flt, getdate, nowdate, get_link_to_form
|
||||||
from frappe import _, throw
|
from frappe import _, throw
|
||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
|
|
||||||
@@ -146,10 +146,14 @@ class PurchaseInvoice(BuyingController):
|
|||||||
["account_type", "report_type", "account_currency"], as_dict=True)
|
["account_type", "report_type", "account_currency"], as_dict=True)
|
||||||
|
|
||||||
if account.report_type != "Balance Sheet":
|
if account.report_type != "Balance Sheet":
|
||||||
frappe.throw(_("Credit To account must be a Balance Sheet account"))
|
frappe.throw(_("Please ensure {} account is a Balance Sheet account. \
|
||||||
|
You can change the parent account to a Balance Sheet account or select a different account.")
|
||||||
|
.format(frappe.bold("Credit To")), title=_("Invalid Account"))
|
||||||
|
|
||||||
if self.supplier and account.account_type != "Payable":
|
if self.supplier and account.account_type != "Payable":
|
||||||
frappe.throw(_("Credit To account must be a Payable account"))
|
frappe.throw(_("Please ensure {} account is a Payable account. \
|
||||||
|
Change the account type to Payable or select a different account.")
|
||||||
|
.format(frappe.bold("Credit To")), title=_("Invalid Account"))
|
||||||
|
|
||||||
self.party_account_currency = account.account_currency
|
self.party_account_currency = account.account_currency
|
||||||
|
|
||||||
@@ -267,16 +271,30 @@ class PurchaseInvoice(BuyingController):
|
|||||||
|
|
||||||
def po_required(self):
|
def po_required(self):
|
||||||
if frappe.db.get_value("Buying Settings", None, "po_required") == 'Yes':
|
if frappe.db.get_value("Buying Settings", None, "po_required") == 'Yes':
|
||||||
|
|
||||||
|
if frappe.get_value('Supplier', self.supplier, 'allow_purchase_invoice_creation_without_purchase_order'):
|
||||||
|
return
|
||||||
|
|
||||||
for d in self.get('items'):
|
for d in self.get('items'):
|
||||||
if not d.purchase_order:
|
if not d.purchase_order:
|
||||||
throw(_("As per the Buying Settings if Purchase Order Required == 'YES', then for creating Purchase Invoice, user need to create Purchase Order first for item {0}").format(d.item_code))
|
throw(_("""Purchase Order Required for item {0}
|
||||||
|
To submit the invoice without purchase order please set
|
||||||
|
{1} as {2} in {3}""").format(frappe.bold(d.item_code), frappe.bold(_('Purchase Order Required')),
|
||||||
|
frappe.bold('No'), get_link_to_form('Buying Settings', 'Buying Settings', 'Buying Settings')))
|
||||||
|
|
||||||
def pr_required(self):
|
def pr_required(self):
|
||||||
stock_items = self.get_stock_items()
|
stock_items = self.get_stock_items()
|
||||||
if frappe.db.get_value("Buying Settings", None, "pr_required") == 'Yes':
|
if frappe.db.get_value("Buying Settings", None, "pr_required") == 'Yes':
|
||||||
|
|
||||||
|
if frappe.get_value('Supplier', self.supplier, 'allow_purchase_invoice_creation_without_purchase_receipt'):
|
||||||
|
return
|
||||||
|
|
||||||
for d in self.get('items'):
|
for d in self.get('items'):
|
||||||
if not d.purchase_receipt and d.item_code in stock_items:
|
if not d.purchase_receipt and d.item_code in stock_items:
|
||||||
throw(_("As per the Buying Settings if Purchase Reciept Required == 'YES', then for creating Purchase Invoice, user need to create Purchase Receipt first for item {0}").format(d.item_code))
|
throw(_("""Purchase Receipt Required for item {0}
|
||||||
|
To submit the invoice without purchase receipt please set
|
||||||
|
{1} as {2} in {3}""").format(frappe.bold(d.item_code), frappe.bold(_('Purchase Receipt Required')),
|
||||||
|
frappe.bold('No'), get_link_to_form('Buying Settings', 'Buying Settings', 'Buying Settings')))
|
||||||
|
|
||||||
def validate_write_off_account(self):
|
def validate_write_off_account(self):
|
||||||
if self.write_off_amount and not self.write_off_account:
|
if self.write_off_amount and not self.write_off_account:
|
||||||
@@ -984,7 +1002,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
if not self.apply_tds:
|
if not self.apply_tds:
|
||||||
return
|
return
|
||||||
|
|
||||||
tax_withholding_details = get_party_tax_withholding_details(self)
|
tax_withholding_details = get_party_tax_withholding_details(self, self.tax_withholding_category)
|
||||||
|
|
||||||
if not tax_withholding_details:
|
if not tax_withholding_details:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -12,15 +12,11 @@
|
|||||||
"item_name",
|
"item_name",
|
||||||
"description_section",
|
"description_section",
|
||||||
"description",
|
"description",
|
||||||
"item_group",
|
|
||||||
"brand",
|
"brand",
|
||||||
"image_section",
|
"col_break7",
|
||||||
|
"item_group",
|
||||||
"image",
|
"image",
|
||||||
"image_view",
|
"image_view",
|
||||||
"manufacture_details",
|
|
||||||
"manufacturer",
|
|
||||||
"column_break_13",
|
|
||||||
"manufacturer_part_no",
|
|
||||||
"quantity_and_rate",
|
"quantity_and_rate",
|
||||||
"received_qty",
|
"received_qty",
|
||||||
"qty",
|
"qty",
|
||||||
@@ -55,20 +51,19 @@
|
|||||||
"item_tax_amount",
|
"item_tax_amount",
|
||||||
"landed_cost_voucher_amount",
|
"landed_cost_voucher_amount",
|
||||||
"rm_supp_cost",
|
"rm_supp_cost",
|
||||||
"item_weight_details",
|
|
||||||
"weight_per_unit",
|
|
||||||
"total_weight",
|
|
||||||
"column_break_38",
|
|
||||||
"weight_uom",
|
|
||||||
"warehouse_section",
|
"warehouse_section",
|
||||||
"warehouse",
|
"warehouse",
|
||||||
"rejected_warehouse",
|
|
||||||
"from_warehouse",
|
"from_warehouse",
|
||||||
"quality_inspection",
|
"quality_inspection",
|
||||||
"batch_no",
|
|
||||||
"col_br_wh",
|
|
||||||
"serial_no",
|
"serial_no",
|
||||||
|
"col_br_wh",
|
||||||
|
"rejected_warehouse",
|
||||||
|
"batch_no",
|
||||||
"rejected_serial_no",
|
"rejected_serial_no",
|
||||||
|
"manufacture_details",
|
||||||
|
"manufacturer",
|
||||||
|
"column_break_13",
|
||||||
|
"manufacturer_part_no",
|
||||||
"accounting",
|
"accounting",
|
||||||
"expense_account",
|
"expense_account",
|
||||||
"col_break5",
|
"col_break5",
|
||||||
@@ -92,6 +87,11 @@
|
|||||||
"po_detail",
|
"po_detail",
|
||||||
"purchase_receipt",
|
"purchase_receipt",
|
||||||
"pr_detail",
|
"pr_detail",
|
||||||
|
"item_weight_details",
|
||||||
|
"weight_per_unit",
|
||||||
|
"total_weight",
|
||||||
|
"column_break_38",
|
||||||
|
"weight_uom",
|
||||||
"accounting_dimensions_section",
|
"accounting_dimensions_section",
|
||||||
"project",
|
"project",
|
||||||
"dimension_col_break",
|
"dimension_col_break",
|
||||||
@@ -550,23 +550,21 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "brand",
|
"fieldname": "brand",
|
||||||
"fieldtype": "Data",
|
|
||||||
"hidden": 1,
|
|
||||||
"label": "Brand",
|
|
||||||
"oldfieldname": "brand",
|
|
||||||
"oldfieldtype": "Data",
|
|
||||||
"print_hide": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "item_group",
|
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Item Group",
|
"label": "Brand",
|
||||||
"oldfieldname": "item_group",
|
|
||||||
"oldfieldtype": "Link",
|
|
||||||
"options": "Item Group",
|
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"options": "Brand"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fetch_from": "item_code.item_group",
|
||||||
|
"fetch_if_empty": 1,
|
||||||
|
"fieldname": "item_group",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Item Group",
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 1,
|
||||||
|
"options": "Item Group"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Tax detail table fetched from item master as a string and stored in this field.\nUsed for Taxes and Charges",
|
"description": "Tax detail table fetched from item master as a string and stored in this field.\nUsed for Taxes and Charges",
|
||||||
@@ -720,12 +718,6 @@
|
|||||||
"fieldname": "section_break_82",
|
"fieldname": "section_break_82",
|
||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"collapsible": 1,
|
|
||||||
"fieldname": "image_section",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"label": "Image"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"fieldname": "accounting_dimensions_section",
|
"fieldname": "accounting_dimensions_section",
|
||||||
@@ -737,6 +729,7 @@
|
|||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"collapsible": 1,
|
||||||
"fieldname": "manufacture_details",
|
"fieldname": "manufacture_details",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Manufacture"
|
"label": "Manufacture"
|
||||||
@@ -754,14 +747,13 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "manufacturer_part_no",
|
"fieldname": "manufacturer_part_no",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Manufacturer Part Number",
|
"label": "Manufacturer Part Number"
|
||||||
"read_only": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "is_fixed_asset",
|
"depends_on": "is_fixed_asset",
|
||||||
"fetch_from": "item_code.asset_category",
|
"fetch_from": "item_code.asset_category",
|
||||||
"fieldname": "asset_category",
|
"fieldname": "asset_category",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Link",
|
||||||
"label": "Asset Category",
|
"label": "Asset Category",
|
||||||
"options": "Asset Category",
|
"options": "Asset Category",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
@@ -772,12 +764,17 @@
|
|||||||
"ignore_user_permissions": 1,
|
"ignore_user_permissions": 1,
|
||||||
"label": "Supplier Warehouse",
|
"label": "Supplier Warehouse",
|
||||||
"options": "Warehouse"
|
"options": "Warehouse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collapsible": 1,
|
||||||
|
"fieldname": "col_break7",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-03-11 14:20:17.297284",
|
"modified": "2020-04-22 10:37:35.103176",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Purchase Invoice Item",
|
"name": "Purchase Invoice Item",
|
||||||
@@ -785,4 +782,4 @@
|
|||||||
"permissions": [],
|
"permissions": [],
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC"
|
"sort_order": "DESC"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"autoname": "hash",
|
"autoname": "hash",
|
||||||
"creation": "2013-05-21 16:16:04",
|
"creation": "2013-05-21 16:16:04",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@@ -14,11 +15,11 @@
|
|||||||
"col_break1",
|
"col_break1",
|
||||||
"account_head",
|
"account_head",
|
||||||
"description",
|
"description",
|
||||||
|
"section_break_10",
|
||||||
|
"rate",
|
||||||
"accounting_dimensions_section",
|
"accounting_dimensions_section",
|
||||||
"cost_center",
|
"cost_center",
|
||||||
"dimension_col_break",
|
"dimension_col_break",
|
||||||
"section_break_10",
|
|
||||||
"rate",
|
|
||||||
"section_break_9",
|
"section_break_9",
|
||||||
"tax_amount",
|
"tax_amount",
|
||||||
"tax_amount_after_discount_amount",
|
"tax_amount_after_discount_amount",
|
||||||
@@ -27,8 +28,7 @@
|
|||||||
"base_tax_amount",
|
"base_tax_amount",
|
||||||
"base_total",
|
"base_total",
|
||||||
"base_tax_amount_after_discount_amount",
|
"base_tax_amount_after_discount_amount",
|
||||||
"item_wise_tax_detail",
|
"item_wise_tax_detail"
|
||||||
"parenttype"
|
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -53,6 +53,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"columns": 2,
|
"columns": 2,
|
||||||
|
"default": "On Net Total",
|
||||||
"fieldname": "charge_type",
|
"fieldname": "charge_type",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@@ -196,15 +197,6 @@
|
|||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "parenttype",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"hidden": 1,
|
|
||||||
"label": "Parenttype",
|
|
||||||
"oldfieldname": "parenttype",
|
|
||||||
"oldfieldtype": "Data",
|
|
||||||
"print_hide": 1
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "accounting_dimensions_section",
|
"fieldname": "accounting_dimensions_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
@@ -217,11 +209,14 @@
|
|||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2019-05-25 23:08:38.281025",
|
"links": [],
|
||||||
|
"modified": "2020-03-12 14:53:47.679439",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Purchase Taxes and Charges",
|
"name": "Purchase Taxes and Charges",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
@@ -26,16 +26,24 @@ frappe.ui.form.on("Sales Invoice", {
|
|||||||
&& !frm.doc.is_return && !frm.doc.ewaybill) {
|
&& !frm.doc.is_return && !frm.doc.ewaybill) {
|
||||||
|
|
||||||
frm.add_custom_button('E-Way Bill JSON', () => {
|
frm.add_custom_button('E-Way Bill JSON', () => {
|
||||||
var w = window.open(
|
frappe.call({
|
||||||
frappe.urllib.get_full_url(
|
method: 'erpnext.regional.india.utils.generate_ewb_json',
|
||||||
"/api/method/erpnext.regional.india.utils.generate_ewb_json?"
|
args: {
|
||||||
+ "dt=" + encodeURIComponent(frm.doc.doctype)
|
'dt': frm.doc.doctype,
|
||||||
+ "&dn=" + encodeURIComponent(frm.doc.name)
|
'dn': [frm.doc.name]
|
||||||
)
|
},
|
||||||
);
|
callback: function(r) {
|
||||||
if (!w) {
|
if (r.message) {
|
||||||
frappe.msgprint(__("Please enable pop-ups")); return;
|
const args = {
|
||||||
}
|
cmd: 'erpnext.regional.india.utils.download_ewb_json',
|
||||||
|
data: r.message,
|
||||||
|
docname: frm.doc.name
|
||||||
|
};
|
||||||
|
open_url_post(frappe.request.url, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}, __("Create"));
|
}, __("Create"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,17 +16,23 @@ frappe.listview_settings['Sales Invoice'].onload = function (doclist) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var w = window.open(
|
frappe.call({
|
||||||
frappe.urllib.get_full_url(
|
method: 'erpnext.regional.india.utils.generate_ewb_json',
|
||||||
"/api/method/erpnext.regional.india.utils.generate_ewb_json?"
|
args: {
|
||||||
+ "dt=" + encodeURIComponent(doclist.doctype)
|
'dt': doclist.doctype,
|
||||||
+ "&dn=" + encodeURIComponent(docnames)
|
'dn': docnames
|
||||||
)
|
},
|
||||||
);
|
callback: function(r) {
|
||||||
if (!w) {
|
if (r.message) {
|
||||||
frappe.msgprint(__("Please enable pop-ups")); return;
|
const args = {
|
||||||
}
|
cmd: 'erpnext.regional.india.utils.download_ewb_json',
|
||||||
|
data: r.message,
|
||||||
|
docname: docnames
|
||||||
|
};
|
||||||
|
open_url_post(frappe.request.url, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
doclist.page.add_actions_menu_item(__('Generate E-Way Bill JSON'), action, false);
|
doclist.page.add_actions_menu_item(__('Generate E-Way Bill JSON'), action, false);
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
|||||||
me.frm.script_manager.trigger("is_pos");
|
me.frm.script_manager.trigger("is_pos");
|
||||||
me.frm.refresh_fields();
|
me.frm.refresh_fields();
|
||||||
}
|
}
|
||||||
|
erpnext.queries.setup_warehouse_query(this.frm);
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function(doc, dt, dn) {
|
refresh: function(doc, dt, dn) {
|
||||||
@@ -586,7 +587,9 @@ frappe.ui.form.on('Sales Invoice', {
|
|||||||
frm.set_query("account_for_change_amount", function() {
|
frm.set_query("account_for_change_amount", function() {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
account_type: ['in', ["Cash", "Bank"]]
|
account_type: ['in', ["Cash", "Bank"]],
|
||||||
|
company: frm.doc.company,
|
||||||
|
is_group: 0
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -667,7 +670,8 @@ frappe.ui.form.on('Sales Invoice', {
|
|||||||
frm.fields_dict["loyalty_redemption_account"].get_query = function() {
|
frm.fields_dict["loyalty_redemption_account"].get_query = function() {
|
||||||
return {
|
return {
|
||||||
filters:{
|
filters:{
|
||||||
"company": frm.doc.company
|
"company": frm.doc.company,
|
||||||
|
"is_group": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -676,7 +680,8 @@ frappe.ui.form.on('Sales Invoice', {
|
|||||||
frm.fields_dict["loyalty_redemption_cost_center"].get_query = function() {
|
frm.fields_dict["loyalty_redemption_cost_center"].get_query = function() {
|
||||||
return {
|
return {
|
||||||
filters:{
|
filters:{
|
||||||
"company": frm.doc.company
|
"company": frm.doc.company,
|
||||||
|
"is_group": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -794,7 +799,7 @@ frappe.ui.form.on('Sales Invoice', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
if (frappe.boot.active_domains.includes("Healthcare")){
|
if (frappe.boot.active_domains.includes("Healthcare")) {
|
||||||
frm.set_df_property("patient", "hidden", 0);
|
frm.set_df_property("patient", "hidden", 0);
|
||||||
frm.set_df_property("patient_name", "hidden", 0);
|
frm.set_df_property("patient_name", "hidden", 0);
|
||||||
frm.set_df_property("ref_practitioner", "hidden", 0);
|
frm.set_df_property("ref_practitioner", "hidden", 0);
|
||||||
@@ -807,7 +812,7 @@ frappe.ui.form.on('Sales Invoice', {
|
|||||||
},"Get items from");
|
},"Get items from");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
frm.set_df_property("patient", "hidden", 1);
|
frm.set_df_property("patient", "hidden", 1);
|
||||||
frm.set_df_property("patient_name", "hidden", 1);
|
frm.set_df_property("patient_name", "hidden", 1);
|
||||||
frm.set_df_property("ref_practitioner", "hidden", 1);
|
frm.set_df_property("ref_practitioner", "hidden", 1);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
"creation": "2013-05-24 19:29:05",
|
"creation": "2013-05-24 19:29:05",
|
||||||
@@ -74,9 +75,9 @@
|
|||||||
"base_total",
|
"base_total",
|
||||||
"base_net_total",
|
"base_net_total",
|
||||||
"column_break_32",
|
"column_break_32",
|
||||||
|
"total_net_weight",
|
||||||
"total",
|
"total",
|
||||||
"net_total",
|
"net_total",
|
||||||
"total_net_weight",
|
|
||||||
"taxes_section",
|
"taxes_section",
|
||||||
"taxes_and_charges",
|
"taxes_and_charges",
|
||||||
"column_break_38",
|
"column_break_38",
|
||||||
@@ -1577,7 +1578,8 @@
|
|||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 181,
|
"idx": 181,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2020-02-10 04:57:11.221180",
|
"links": [],
|
||||||
|
"modified": "2020-04-17 12:38:41.435728",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Invoice",
|
"name": "Sales Invoice",
|
||||||
|
|||||||
@@ -437,13 +437,18 @@ class SalesInvoice(SellingController):
|
|||||||
if (not for_validate) or (for_validate and not self.get(fieldname)):
|
if (not for_validate) or (for_validate and not self.get(fieldname)):
|
||||||
self.set(fieldname, pos.get(fieldname))
|
self.set(fieldname, pos.get(fieldname))
|
||||||
|
|
||||||
customer_price_list = frappe.get_value("Customer", self.customer, 'default_price_list')
|
|
||||||
|
|
||||||
if pos.get("company_address"):
|
if pos.get("company_address"):
|
||||||
self.company_address = pos.get("company_address")
|
self.company_address = pos.get("company_address")
|
||||||
|
|
||||||
if not customer_price_list:
|
if self.customer:
|
||||||
self.set('selling_price_list', pos.get('selling_price_list'))
|
customer_price_list, customer_group = frappe.get_value("Customer", self.customer, ['default_price_list', 'customer_group'])
|
||||||
|
customer_group_price_list = frappe.get_value("Customer Group", customer_group, 'default_price_list')
|
||||||
|
selling_price_list = customer_price_list or customer_group_price_list or pos.get('selling_price_list')
|
||||||
|
else:
|
||||||
|
selling_price_list = pos.get('selling_price_list')
|
||||||
|
|
||||||
|
if selling_price_list:
|
||||||
|
self.set('selling_price_list', selling_price_list)
|
||||||
|
|
||||||
if not for_validate:
|
if not for_validate:
|
||||||
self.update_stock = cint(pos.get("update_stock"))
|
self.update_stock = cint(pos.get("update_stock"))
|
||||||
@@ -474,13 +479,17 @@ class SalesInvoice(SellingController):
|
|||||||
["account_type", "report_type", "account_currency"], as_dict=True)
|
["account_type", "report_type", "account_currency"], as_dict=True)
|
||||||
|
|
||||||
if not account:
|
if not account:
|
||||||
frappe.throw(_("Debit To is required"))
|
frappe.throw(_("Debit To is required"), title=_("Account Missing"))
|
||||||
|
|
||||||
if account.report_type != "Balance Sheet":
|
if account.report_type != "Balance Sheet":
|
||||||
frappe.throw(_("Debit To account must be a Balance Sheet account"))
|
frappe.throw(_("Please ensure {} account is a Balance Sheet account. \
|
||||||
|
You can change the parent account to a Balance Sheet account or select a different account.")
|
||||||
|
.format(frappe.bold("Debit To")), title=_("Invalid Account"))
|
||||||
|
|
||||||
if self.customer and account.account_type != "Receivable":
|
if self.customer and account.account_type != "Receivable":
|
||||||
frappe.throw(_("Debit To account must be a Receivable account"))
|
frappe.throw(_("Please ensure {} account is a Receivable account. \
|
||||||
|
Change the account type to Receivable or select a different account.")
|
||||||
|
.format(frappe.bold("Debit To")), title=_("Invalid Account"))
|
||||||
|
|
||||||
self.party_account_currency = account.account_currency
|
self.party_account_currency = account.account_currency
|
||||||
|
|
||||||
@@ -542,12 +551,17 @@ class SalesInvoice(SellingController):
|
|||||||
"""check in manage account if sales order / delivery note required or not."""
|
"""check in manage account if sales order / delivery note required or not."""
|
||||||
if self.is_return:
|
if self.is_return:
|
||||||
return
|
return
|
||||||
dic = {'Sales Order':['so_required', 'is_pos'],'Delivery Note':['dn_required', 'update_stock']}
|
|
||||||
for i in dic:
|
prev_doc_field_map = {'Sales Order': ['so_required', 'is_pos'],'Delivery Note': ['dn_required', 'update_stock']}
|
||||||
if frappe.db.get_single_value('Selling Settings', dic[i][0]) == 'Yes':
|
for key, value in iteritems(prev_doc_field_map):
|
||||||
|
if frappe.db.get_single_value('Selling Settings', value[0]) == 'Yes':
|
||||||
|
|
||||||
|
if frappe.get_value('Customer', self.customer, value[0]):
|
||||||
|
continue
|
||||||
|
|
||||||
for d in self.get('items'):
|
for d in self.get('items'):
|
||||||
if (d.item_code and not d.get(i.lower().replace(' ','_')) and not self.get(dic[i][1])):
|
if (d.item_code and not d.get(key.lower().replace(' ', '_')) and not self.get(value[1])):
|
||||||
msgprint(_("{0} is mandatory for Item {1}").format(i,d.item_code), raise_exception=1)
|
msgprint(_("{0} is mandatory for Item {1}").format(key, d.item_code), raise_exception=1)
|
||||||
|
|
||||||
|
|
||||||
def validate_proj_cust(self):
|
def validate_proj_cust(self):
|
||||||
|
|||||||
@@ -1892,7 +1892,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
data = get_ewb_data("Sales Invoice", si.name)
|
data = get_ewb_data("Sales Invoice", [si.name])
|
||||||
|
|
||||||
self.assertEqual(data['version'], '1.0.1118')
|
self.assertEqual(data['version'], '1.0.1118')
|
||||||
self.assertEqual(data['billLists'][0]['fromGstin'], '27AAECE4835E1ZR')
|
self.assertEqual(data['billLists'][0]['fromGstin'], '27AAECE4835E1ZR')
|
||||||
@@ -1948,7 +1948,7 @@ def create_sales_invoice(**args):
|
|||||||
"gst_hsn_code": "999800",
|
"gst_hsn_code": "999800",
|
||||||
"warehouse": args.warehouse or "_Test Warehouse - _TC",
|
"warehouse": args.warehouse or "_Test Warehouse - _TC",
|
||||||
"qty": args.qty or 1,
|
"qty": args.qty or 1,
|
||||||
"rate": args.rate or 100,
|
"rate": args.rate if args.get("rate") is not None else 100,
|
||||||
"income_account": args.income_account or "Sales - _TC",
|
"income_account": args.income_account or "Sales - _TC",
|
||||||
"expense_account": args.expense_account or "Cost of Goods Sold - _TC",
|
"expense_account": args.expense_account or "Cost of Goods Sold - _TC",
|
||||||
"cost_center": args.cost_center or "_Test Cost Center - _TC",
|
"cost_center": args.cost_center or "_Test Cost Center - _TC",
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class ShippingRule(Document):
|
|||||||
if not shipping_country:
|
if not shipping_country:
|
||||||
frappe.throw(_('Shipping Address does not have country, which is required for this Shipping Rule'))
|
frappe.throw(_('Shipping Address does not have country, which is required for this Shipping Rule'))
|
||||||
if shipping_country not in [d.country for d in self.countries]:
|
if shipping_country not in [d.country for d in self.countries]:
|
||||||
frappe.throw(_('Shipping rule not applicable for country {0}').format(shipping_country))
|
frappe.throw(_('Shipping rule not applicable for country {0} in Shipping Address').format(shipping_country))
|
||||||
|
|
||||||
def add_shipping_rule_to_tax_table(self, doc, shipping_amount):
|
def add_shipping_rule_to_tax_table(self, doc, shipping_amount):
|
||||||
shipping_charge = {
|
shipping_charge = {
|
||||||
|
|||||||
@@ -6,23 +6,42 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt, getdate
|
||||||
from erpnext.accounts.utils import get_fiscal_year
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
|
|
||||||
class TaxWithholdingCategory(Document):
|
class TaxWithholdingCategory(Document):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_party_tax_withholding_details(ref_doc):
|
def get_party_tax_withholding_details(ref_doc, tax_withholding_category=None):
|
||||||
tax_withholding_category = frappe.db.get_value('Supplier', ref_doc.supplier, 'tax_withholding_category')
|
|
||||||
|
pan_no = ''
|
||||||
|
suppliers = []
|
||||||
|
|
||||||
|
if not tax_withholding_category:
|
||||||
|
tax_withholding_category, pan_no = frappe.db.get_value('Supplier', ref_doc.supplier, ['tax_withholding_category', 'pan'])
|
||||||
|
|
||||||
if not tax_withholding_category:
|
if not tax_withholding_category:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if not pan_no:
|
||||||
|
pan_no = frappe.db.get_value('Supplier', ref_doc.supplier, 'pan')
|
||||||
|
|
||||||
|
# Get others suppliers with the same PAN No
|
||||||
|
if pan_no:
|
||||||
|
suppliers = [d.name for d in frappe.get_all('Supplier', fields=['name'], filters={'pan': pan_no})]
|
||||||
|
|
||||||
|
if not suppliers:
|
||||||
|
suppliers.append(ref_doc.supplier)
|
||||||
|
|
||||||
fy = get_fiscal_year(ref_doc.posting_date, company=ref_doc.company)
|
fy = get_fiscal_year(ref_doc.posting_date, company=ref_doc.company)
|
||||||
tax_details = get_tax_withholding_details(tax_withholding_category, fy[0], ref_doc.company)
|
tax_details = get_tax_withholding_details(tax_withholding_category, fy[0], ref_doc.company)
|
||||||
if not tax_details:
|
if not tax_details:
|
||||||
frappe.throw(_('Please set associated account in Tax Withholding Category {0} against Company {1}')
|
frappe.throw(_('Please set associated account in Tax Withholding Category {0} against Company {1}')
|
||||||
.format(tax_withholding_category, ref_doc.company))
|
.format(tax_withholding_category, ref_doc.company))
|
||||||
tds_amount = get_tds_amount(ref_doc, tax_details, fy)
|
|
||||||
|
tds_amount = get_tds_amount(suppliers, ref_doc.net_total, ref_doc.company,
|
||||||
|
tax_details, fy, ref_doc.posting_date, pan_no)
|
||||||
|
|
||||||
tax_row = get_tax_row(tax_details, tds_amount)
|
tax_row = get_tax_row(tax_details, tds_amount)
|
||||||
|
|
||||||
return tax_row
|
return tax_row
|
||||||
@@ -51,6 +70,7 @@ def get_tax_withholding_rates(tax_withholding, fiscal_year):
|
|||||||
frappe.throw(_("No Tax Withholding data found for the current Fiscal Year."))
|
frappe.throw(_("No Tax Withholding data found for the current Fiscal Year."))
|
||||||
|
|
||||||
def get_tax_row(tax_details, tds_amount):
|
def get_tax_row(tax_details, tds_amount):
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"category": "Total",
|
"category": "Total",
|
||||||
"add_deduct_tax": "Deduct",
|
"add_deduct_tax": "Deduct",
|
||||||
@@ -60,25 +80,36 @@ def get_tax_row(tax_details, tds_amount):
|
|||||||
"tax_amount": tds_amount
|
"tax_amount": tds_amount
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_tds_amount(ref_doc, tax_details, fiscal_year_details):
|
def get_tds_amount(suppliers, net_total, company, tax_details, fiscal_year_details, posting_date, pan_no=None):
|
||||||
fiscal_year, year_start_date, year_end_date = fiscal_year_details
|
fiscal_year, year_start_date, year_end_date = fiscal_year_details
|
||||||
tds_amount = 0
|
tds_amount = 0
|
||||||
tds_deducted = 0
|
tds_deducted = 0
|
||||||
|
|
||||||
def _get_tds(amount):
|
def _get_tds(amount, rate):
|
||||||
if amount <= 0:
|
if amount <= 0:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
return amount * tax_details.rate / 100
|
return amount * rate / 100
|
||||||
|
|
||||||
|
ldc_name = frappe.db.get_value('Lower Deduction Certificate',
|
||||||
|
{
|
||||||
|
'pan_no': pan_no,
|
||||||
|
'fiscal_year': fiscal_year
|
||||||
|
}, 'name')
|
||||||
|
ldc = ''
|
||||||
|
|
||||||
|
if ldc_name:
|
||||||
|
ldc = frappe.get_doc('Lower Deduction Certificate', ldc_name)
|
||||||
|
|
||||||
entries = frappe.db.sql("""
|
entries = frappe.db.sql("""
|
||||||
select voucher_no, credit
|
select voucher_no, credit
|
||||||
from `tabGL Entry`
|
from `tabGL Entry`
|
||||||
where party=%s and fiscal_year=%s and credit > 0
|
where company = %s and
|
||||||
""", (ref_doc.supplier, fiscal_year), as_dict=1)
|
party in %s and fiscal_year=%s and credit > 0
|
||||||
|
""", (company, tuple(suppliers), fiscal_year), as_dict=1)
|
||||||
|
|
||||||
vouchers = [d.voucher_no for d in entries]
|
vouchers = [d.voucher_no for d in entries]
|
||||||
advance_vouchers = get_advance_vouchers(ref_doc.supplier, fiscal_year)
|
advance_vouchers = get_advance_vouchers(suppliers, fiscal_year=fiscal_year, company=company)
|
||||||
|
|
||||||
tds_vouchers = vouchers + advance_vouchers
|
tds_vouchers = vouchers + advance_vouchers
|
||||||
|
|
||||||
@@ -93,7 +124,20 @@ def get_tds_amount(ref_doc, tax_details, fiscal_year_details):
|
|||||||
tds_deducted = tds_deducted[0][0] if tds_deducted and tds_deducted[0][0] else 0
|
tds_deducted = tds_deducted[0][0] if tds_deducted and tds_deducted[0][0] else 0
|
||||||
|
|
||||||
if tds_deducted:
|
if tds_deducted:
|
||||||
tds_amount = _get_tds(ref_doc.net_total)
|
if ldc:
|
||||||
|
limit_consumed = frappe.db.get_value('Purchase Invoice',
|
||||||
|
{
|
||||||
|
'supplier': ('in', suppliers),
|
||||||
|
'apply_tds': 1,
|
||||||
|
'docstatus': 1
|
||||||
|
}, 'sum(net_total)')
|
||||||
|
|
||||||
|
if ldc and is_valid_certificate(ldc.valid_from, ldc.valid_upto, posting_date, limit_consumed, net_total,
|
||||||
|
ldc.certificate_limit):
|
||||||
|
|
||||||
|
tds_amount = get_ltds_amount(net_total, limit_consumed, ldc.certificate_limit, ldc.rate, tax_details)
|
||||||
|
else:
|
||||||
|
tds_amount = _get_tds(net_total, tax_details.rate)
|
||||||
else:
|
else:
|
||||||
supplier_credit_amount = frappe.get_all('Purchase Invoice Item',
|
supplier_credit_amount = frappe.get_all('Purchase Invoice Item',
|
||||||
fields = ['sum(net_amount)'],
|
fields = ['sum(net_amount)'],
|
||||||
@@ -106,43 +150,79 @@ def get_tds_amount(ref_doc, tax_details, fiscal_year_details):
|
|||||||
fields = ['sum(credit_in_account_currency)'],
|
fields = ['sum(credit_in_account_currency)'],
|
||||||
filters = {
|
filters = {
|
||||||
'parent': ('in', vouchers), 'docstatus': 1,
|
'parent': ('in', vouchers), 'docstatus': 1,
|
||||||
'party': ref_doc.supplier,
|
'party': ('in', suppliers),
|
||||||
'reference_type': ('not in', ['Purchase Invoice'])
|
'reference_type': ('not in', ['Purchase Invoice'])
|
||||||
}, as_list=1)
|
}, as_list=1)
|
||||||
|
|
||||||
supplier_credit_amount += (jv_supplier_credit_amt[0][0]
|
supplier_credit_amount += (jv_supplier_credit_amt[0][0]
|
||||||
if jv_supplier_credit_amt and jv_supplier_credit_amt[0][0] else 0)
|
if jv_supplier_credit_amt and jv_supplier_credit_amt[0][0] else 0)
|
||||||
|
|
||||||
supplier_credit_amount += ref_doc.net_total
|
supplier_credit_amount += net_total
|
||||||
|
|
||||||
debit_note_amount = get_debit_note_amount(ref_doc.supplier, year_start_date, year_end_date)
|
debit_note_amount = get_debit_note_amount(suppliers, year_start_date, year_end_date)
|
||||||
supplier_credit_amount -= debit_note_amount
|
supplier_credit_amount -= debit_note_amount
|
||||||
|
|
||||||
if ((tax_details.get('threshold', 0) and supplier_credit_amount >= tax_details.threshold)
|
if ((tax_details.get('threshold', 0) and supplier_credit_amount >= tax_details.threshold)
|
||||||
or (tax_details.get('cumulative_threshold', 0) and supplier_credit_amount >= tax_details.cumulative_threshold)):
|
or (tax_details.get('cumulative_threshold', 0) and supplier_credit_amount >= tax_details.cumulative_threshold)):
|
||||||
tds_amount = _get_tds(supplier_credit_amount)
|
|
||||||
|
if ldc and is_valid_certificate(ldc.valid_from, ldc.valid_upto, posting_date, tds_deducted, net_total,
|
||||||
|
ldc.certificate_limit):
|
||||||
|
tds_amount = get_ltds_amount(supplier_credit_amount, 0, ldc.certificate_limit, ldc.rate,
|
||||||
|
tax_details)
|
||||||
|
else:
|
||||||
|
tds_amount = _get_tds(supplier_credit_amount, tax_details.rate)
|
||||||
|
|
||||||
return tds_amount
|
return tds_amount
|
||||||
|
|
||||||
def get_advance_vouchers(supplier, fiscal_year=None, company=None, from_date=None, to_date=None):
|
def get_advance_vouchers(suppliers, fiscal_year=None, company=None, from_date=None, to_date=None):
|
||||||
condition = "fiscal_year=%s" % fiscal_year
|
condition = "fiscal_year=%s" % fiscal_year
|
||||||
|
|
||||||
|
if company:
|
||||||
|
condition += "and company =%s" % (company)
|
||||||
if from_date and to_date:
|
if from_date and to_date:
|
||||||
condition = "company=%s and posting_date between %s and %s" % (company, from_date, to_date)
|
condition += "and posting_date between %s and %s" % (company, from_date, to_date)
|
||||||
|
|
||||||
|
## Appending the same supplier again if length of suppliers list is 1
|
||||||
|
## since tuple of single element list contains None, For example ('Test Supplier 1', )
|
||||||
|
## and the below query fails
|
||||||
|
if len(suppliers) == 1:
|
||||||
|
suppliers.append(suppliers[0])
|
||||||
|
|
||||||
return frappe.db.sql_list("""
|
return frappe.db.sql_list("""
|
||||||
select distinct voucher_no
|
select distinct voucher_no
|
||||||
from `tabGL Entry`
|
from `tabGL Entry`
|
||||||
where party=%s and %s and debit > 0
|
where party in %s and %s and debit > 0
|
||||||
""", (supplier, condition)) or []
|
""", (tuple(suppliers), condition)) or []
|
||||||
|
|
||||||
def get_debit_note_amount(supplier, year_start_date, year_end_date, company=None):
|
def get_debit_note_amount(suppliers, year_start_date, year_end_date, company=None):
|
||||||
condition = ""
|
condition = "and 1=1"
|
||||||
if company:
|
if company:
|
||||||
condition = " and company=%s " % company
|
condition = " and company=%s " % company
|
||||||
|
|
||||||
|
if len(suppliers) == 1:
|
||||||
|
suppliers.append(suppliers[0])
|
||||||
|
|
||||||
return flt(frappe.db.sql("""
|
return flt(frappe.db.sql("""
|
||||||
select abs(sum(net_total))
|
select abs(sum(net_total))
|
||||||
from `tabPurchase Invoice`
|
from `tabPurchase Invoice`
|
||||||
where supplier=%s %s and is_return=1 and docstatus=1
|
where supplier in %s and is_return=1 and docstatus=1
|
||||||
and posting_date between %s and %s
|
and posting_date between %s and %s %s
|
||||||
""", (supplier, condition, year_start_date, year_end_date)))
|
""", (tuple(suppliers), year_start_date, year_end_date, condition)))
|
||||||
|
|
||||||
|
def get_ltds_amount(current_amount, deducted_amount, certificate_limit, rate, tax_details):
|
||||||
|
if current_amount < (certificate_limit - deducted_amount):
|
||||||
|
return current_amount * rate/100
|
||||||
|
else:
|
||||||
|
ltds_amount = (certificate_limit - deducted_amount)
|
||||||
|
tds_amount = current_amount - ltds_amount
|
||||||
|
|
||||||
|
return ltds_amount * rate/100 + tds_amount * tax_details.rate/100
|
||||||
|
|
||||||
|
def is_valid_certificate(valid_from, valid_upto, posting_date, deducted_amount, current_amount, certificate_limit):
|
||||||
|
valid = False
|
||||||
|
|
||||||
|
if ((getdate(valid_from) <= getdate(posting_date) <= getdate(valid_upto)) and
|
||||||
|
certificate_limit > deducted_amount):
|
||||||
|
valid = True
|
||||||
|
|
||||||
|
return valid
|
||||||
@@ -11,7 +11,7 @@ from frappe.utils import (add_days, getdate, formatdate, date_diff,
|
|||||||
add_years, get_timestamp, nowdate, flt, cstr, add_months, get_last_day)
|
add_years, get_timestamp, nowdate, flt, cstr, add_months, get_last_day)
|
||||||
from frappe.contacts.doctype.address.address import (get_address_display,
|
from frappe.contacts.doctype.address.address import (get_address_display,
|
||||||
get_default_address, get_company_address)
|
get_default_address, get_company_address)
|
||||||
from frappe.contacts.doctype.contact.contact import get_contact_details, get_default_contact
|
from frappe.contacts.doctype.contact.contact import get_contact_details
|
||||||
from erpnext.exceptions import PartyFrozen, PartyDisabled, InvalidAccountCurrency
|
from erpnext.exceptions import PartyFrozen, PartyDisabled, InvalidAccountCurrency
|
||||||
from erpnext.accounts.utils import get_fiscal_year
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
from erpnext import get_company_currency
|
from erpnext import get_company_currency
|
||||||
@@ -162,8 +162,9 @@ def get_default_price_list(party):
|
|||||||
def set_price_list(party_details, party, party_type, given_price_list, pos=None):
|
def set_price_list(party_details, party, party_type, given_price_list, pos=None):
|
||||||
# price list
|
# price list
|
||||||
price_list = get_permitted_documents('Price List')
|
price_list = get_permitted_documents('Price List')
|
||||||
|
|
||||||
if price_list:
|
# if there is only one permitted document based on user permissions, set it
|
||||||
|
if price_list and len(price_list) == 1:
|
||||||
price_list = price_list[0]
|
price_list = price_list[0]
|
||||||
elif pos and party_type == 'Customer':
|
elif pos and party_type == 'Customer':
|
||||||
customer_price_list = frappe.get_value('Customer', party.name, 'default_price_list')
|
customer_price_list = frappe.get_value('Customer', party.name, 'default_price_list')
|
||||||
@@ -613,3 +614,26 @@ def get_partywise_advanced_payment_amount(party_type, posting_date = None):
|
|||||||
|
|
||||||
if data:
|
if data:
|
||||||
return frappe._dict(data)
|
return frappe._dict(data)
|
||||||
|
|
||||||
|
def get_default_contact(doctype, name):
|
||||||
|
"""
|
||||||
|
Returns default contact for the given doctype and name.
|
||||||
|
Can be ordered by `contact_type` to either is_primary_contact or is_billing_contact.
|
||||||
|
"""
|
||||||
|
out = frappe.db.sql("""
|
||||||
|
SELECT dl.parent, c.is_primary_contact, c.is_billing_contact
|
||||||
|
FROM `tabDynamic Link` dl
|
||||||
|
INNER JOIN tabContact c ON c.name = dl.parent
|
||||||
|
WHERE
|
||||||
|
dl.link_doctype=%s AND
|
||||||
|
dl.link_name=%s AND
|
||||||
|
dl.parenttype = "Contact"
|
||||||
|
ORDER BY is_primary_contact DESC, is_billing_contact DESC
|
||||||
|
""", (doctype, name))
|
||||||
|
if out:
|
||||||
|
try:
|
||||||
|
return out[0][0]
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|||||||
@@ -344,26 +344,28 @@ class ReceivablePayableReport(object):
|
|||||||
def allocate_outstanding_based_on_payment_terms(self, row):
|
def allocate_outstanding_based_on_payment_terms(self, row):
|
||||||
self.get_payment_terms(row)
|
self.get_payment_terms(row)
|
||||||
for term in row.payment_terms:
|
for term in row.payment_terms:
|
||||||
term.outstanding = term.invoiced
|
|
||||||
|
|
||||||
# update "paid" and "oustanding" for this term
|
# update "paid" and "oustanding" for this term
|
||||||
self.allocate_closing_to_term(row, term, 'paid')
|
if not term.paid:
|
||||||
|
self.allocate_closing_to_term(row, term, 'paid')
|
||||||
|
|
||||||
# update "credit_note" and "oustanding" for this term
|
# update "credit_note" and "oustanding" for this term
|
||||||
if term.outstanding:
|
if term.outstanding:
|
||||||
self.allocate_closing_to_term(row, term, 'credit_note')
|
self.allocate_closing_to_term(row, term, 'credit_note')
|
||||||
|
|
||||||
|
row.payment_terms = sorted(row.payment_terms, key=lambda x: x['due_date'])
|
||||||
|
|
||||||
def get_payment_terms(self, row):
|
def get_payment_terms(self, row):
|
||||||
# build payment_terms for row
|
# build payment_terms for row
|
||||||
payment_terms_details = frappe.db.sql("""
|
payment_terms_details = frappe.db.sql("""
|
||||||
select
|
select
|
||||||
si.name, si.party_account_currency, si.currency, si.conversion_rate,
|
si.name, si.party_account_currency, si.currency, si.conversion_rate,
|
||||||
ps.due_date, ps.payment_amount, ps.description
|
ps.due_date, ps.payment_amount, ps.description, ps.paid_amount
|
||||||
from `tab{0}` si, `tabPayment Schedule` ps
|
from `tab{0}` si, `tabPayment Schedule` ps
|
||||||
where
|
where
|
||||||
si.name = ps.parent and
|
si.name = ps.parent and
|
||||||
si.name = %s
|
si.name = %s
|
||||||
order by ps.due_date
|
order by ps.paid_amount desc, due_date
|
||||||
""".format(row.voucher_type), row.voucher_no, as_dict = 1)
|
""".format(row.voucher_type), row.voucher_no, as_dict = 1)
|
||||||
|
|
||||||
|
|
||||||
@@ -389,11 +391,14 @@ class ReceivablePayableReport(object):
|
|||||||
"invoiced": invoiced,
|
"invoiced": invoiced,
|
||||||
"invoice_grand_total": row.invoiced,
|
"invoice_grand_total": row.invoiced,
|
||||||
"payment_term": d.description,
|
"payment_term": d.description,
|
||||||
"paid": 0.0,
|
"paid": d.paid_amount,
|
||||||
"credit_note": 0.0,
|
"credit_note": 0.0,
|
||||||
"outstanding": 0.0
|
"outstanding": invoiced - d.paid_amount
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
if d.paid_amount:
|
||||||
|
row['paid'] -= d.paid_amount
|
||||||
|
|
||||||
def allocate_closing_to_term(self, row, term, key):
|
def allocate_closing_to_term(self, row, term, key):
|
||||||
if row[key]:
|
if row[key]:
|
||||||
if row[key] > term.outstanding:
|
if row[key] > term.outstanding:
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ from erpnext.accounts.report.financial_statements import (get_period_list, get_c
|
|||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
|
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
|
||||||
|
filters.period_start_date, filters.period_end_date, filters.filter_based_on,
|
||||||
filters.periodicity, company=filters.company)
|
filters.periodicity, company=filters.company)
|
||||||
|
|
||||||
currency = filters.presentation_currency or frappe.get_cached_value('Company', filters.company, "default_currency")
|
currency = filters.presentation_currency or frappe.get_cached_value('Company', filters.company, "default_currency")
|
||||||
@@ -58,7 +59,10 @@ def execute(filters=None):
|
|||||||
|
|
||||||
chart = get_chart_data(filters, columns, asset, liability, equity)
|
chart = get_chart_data(filters, columns, asset, liability, equity)
|
||||||
|
|
||||||
return columns, data, message, chart
|
report_summary = get_report_summary(period_list, asset, liability, equity, provisional_profit_loss,
|
||||||
|
total_credit, currency, filters)
|
||||||
|
|
||||||
|
return columns, data, message, chart, report_summary
|
||||||
|
|
||||||
def get_provisional_profit_loss(asset, liability, equity, period_list, company, currency=None, consolidated=False):
|
def get_provisional_profit_loss(asset, liability, equity, period_list, company, currency=None, consolidated=False):
|
||||||
provisional_profit_loss = {}
|
provisional_profit_loss = {}
|
||||||
@@ -120,6 +124,56 @@ def check_opening_balance(asset, liability, equity):
|
|||||||
return _("Previous Financial Year is not closed"),opening_balance
|
return _("Previous Financial Year is not closed"),opening_balance
|
||||||
return None,None
|
return None,None
|
||||||
|
|
||||||
|
def get_report_summary(period_list, asset, liability, equity, provisional_profit_loss, total_credit, currency,
|
||||||
|
filters, consolidated=False):
|
||||||
|
|
||||||
|
net_asset, net_liability, net_equity, net_provisional_profit_loss = 0.0, 0.0, 0.0, 0.0
|
||||||
|
|
||||||
|
if filters.get('accumulated_values'):
|
||||||
|
period_list = [period_list[-1]]
|
||||||
|
|
||||||
|
for period in period_list:
|
||||||
|
key = period if consolidated else period.key
|
||||||
|
if asset:
|
||||||
|
net_asset += asset[-2].get(key)
|
||||||
|
if liability:
|
||||||
|
net_liability += liability[-2].get(key)
|
||||||
|
if equity:
|
||||||
|
net_equity += equity[-2].get(key)
|
||||||
|
if provisional_profit_loss:
|
||||||
|
net_provisional_profit_loss += provisional_profit_loss.get(key)
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"value": net_asset,
|
||||||
|
"label": "Total Asset",
|
||||||
|
"indicator": "Green",
|
||||||
|
"datatype": "Currency",
|
||||||
|
"currency": currency
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": net_liability,
|
||||||
|
"label": "Total Liability",
|
||||||
|
"datatype": "Currency",
|
||||||
|
"indicator": "Red",
|
||||||
|
"currency": currency
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": net_equity,
|
||||||
|
"label": "Total Equity",
|
||||||
|
"datatype": "Currency",
|
||||||
|
"indicator": "Blue",
|
||||||
|
"currency": currency
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": net_provisional_profit_loss,
|
||||||
|
"label": "Provisional Profit / Loss (Credit)",
|
||||||
|
"indicator": "Green" if net_provisional_profit_loss > 0 else "Red",
|
||||||
|
"datatype": "Currency",
|
||||||
|
"currency": currency
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
def get_chart_data(filters, columns, asset, liability, equity):
|
def get_chart_data(filters, columns, asset, liability, equity):
|
||||||
labels = [d.get("label") for d in columns[2:]]
|
labels = [d.get("label") for d in columns[2:]]
|
||||||
|
|
||||||
|
|||||||
@@ -9,14 +9,9 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
|||||||
// filter. It won't be used in cash flow for now so we pop it. Please take
|
// filter. It won't be used in cash flow for now so we pop it. Please take
|
||||||
// of this if you are working here.
|
// of this if you are working here.
|
||||||
|
|
||||||
frappe.query_reports["Cash Flow"]["filters"].splice(5, 1);
|
frappe.query_reports["Cash Flow"]["filters"].splice(8, 1);
|
||||||
|
|
||||||
frappe.query_reports["Cash Flow"]["filters"].push(
|
frappe.query_reports["Cash Flow"]["filters"].push(
|
||||||
{
|
|
||||||
"fieldname": "accumulated_values",
|
|
||||||
"label": __("Accumulated Values"),
|
|
||||||
"fieldtype": "Check"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "include_default_book_entries",
|
"fieldname": "include_default_book_entries",
|
||||||
"label": __("Include Default Book Entries"),
|
"label": __("Include Default Book Entries"),
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from frappe.utils import cint, cstr
|
|||||||
from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
|
from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
|
||||||
from erpnext.accounts.report.profit_and_loss_statement.profit_and_loss_statement import get_net_profit_loss
|
from erpnext.accounts.report.profit_and_loss_statement.profit_and_loss_statement import get_net_profit_loss
|
||||||
from erpnext.accounts.utils import get_fiscal_year
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
|
from six import iteritems
|
||||||
|
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
@@ -16,7 +17,8 @@ def execute(filters=None):
|
|||||||
return execute_custom(filters=filters)
|
return execute_custom(filters=filters)
|
||||||
|
|
||||||
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
|
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
|
||||||
filters.periodicity, filters.accumulated_values, filters.company)
|
filters.period_start_date, filters.period_end_date, filters.filter_based_on,
|
||||||
|
filters.periodicity, company=filters.company)
|
||||||
|
|
||||||
cash_flow_accounts = get_cash_flow_accounts()
|
cash_flow_accounts = get_cash_flow_accounts()
|
||||||
|
|
||||||
@@ -29,6 +31,7 @@ def execute(filters=None):
|
|||||||
net_profit_loss = get_net_profit_loss(income, expense, period_list, filters.company)
|
net_profit_loss = get_net_profit_loss(income, expense, period_list, filters.company)
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
|
summary_data = {}
|
||||||
company_currency = frappe.get_cached_value('Company', filters.company, "default_currency")
|
company_currency = frappe.get_cached_value('Company', filters.company, "default_currency")
|
||||||
|
|
||||||
for cash_flow_account in cash_flow_accounts:
|
for cash_flow_account in cash_flow_accounts:
|
||||||
@@ -64,14 +67,16 @@ def execute(filters=None):
|
|||||||
section_data.append(account_data)
|
section_data.append(account_data)
|
||||||
|
|
||||||
add_total_row_account(data, section_data, cash_flow_account['section_footer'],
|
add_total_row_account(data, section_data, cash_flow_account['section_footer'],
|
||||||
period_list, company_currency)
|
period_list, company_currency, summary_data)
|
||||||
|
|
||||||
add_total_row_account(data, data, _("Net Change in Cash"), period_list, company_currency)
|
add_total_row_account(data, data, _("Net Change in Cash"), period_list, company_currency, summary_data)
|
||||||
columns = get_columns(filters.periodicity, period_list, filters.accumulated_values, filters.company)
|
columns = get_columns(filters.periodicity, period_list, filters.accumulated_values, filters.company)
|
||||||
|
|
||||||
chart = get_chart_data(columns, data)
|
chart = get_chart_data(columns, data)
|
||||||
|
|
||||||
return columns, data, None, chart
|
report_summary = get_report_summary(summary_data, company_currency)
|
||||||
|
|
||||||
|
return columns, data, None, chart, report_summary
|
||||||
|
|
||||||
def get_cash_flow_accounts():
|
def get_cash_flow_accounts():
|
||||||
operation_accounts = {
|
operation_accounts = {
|
||||||
@@ -157,7 +162,7 @@ def get_start_date(period, accumulated_values, company):
|
|||||||
|
|
||||||
return start_date
|
return start_date
|
||||||
|
|
||||||
def add_total_row_account(out, data, label, period_list, currency, consolidated = False):
|
def add_total_row_account(out, data, label, period_list, currency, summary_data, consolidated = False):
|
||||||
total_row = {
|
total_row = {
|
||||||
"account_name": "'" + _("{0}").format(label) + "'",
|
"account_name": "'" + _("{0}").format(label) + "'",
|
||||||
"account": "'" + _("{0}").format(label) + "'",
|
"account": "'" + _("{0}").format(label) + "'",
|
||||||
@@ -176,6 +181,24 @@ def add_total_row_account(out, data, label, period_list, currency, consolidated
|
|||||||
out.append(total_row)
|
out.append(total_row)
|
||||||
out.append({})
|
out.append({})
|
||||||
|
|
||||||
|
summary_data[label] = total_row["total"]
|
||||||
|
|
||||||
|
def get_report_summary(summary_data, currency):
|
||||||
|
report_summary = []
|
||||||
|
|
||||||
|
for label, value in iteritems(summary_data):
|
||||||
|
report_summary.append(
|
||||||
|
{
|
||||||
|
"value": value,
|
||||||
|
"label": label,
|
||||||
|
"datatype": "Currency",
|
||||||
|
"currency": currency
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return report_summary
|
||||||
|
|
||||||
|
|
||||||
def get_chart_data(columns, data):
|
def get_chart_data(columns, data):
|
||||||
labels = [d.get("label") for d in columns[2:]]
|
labels = [d.get("label") for d in columns[2:]]
|
||||||
datasets = [{'name':account.get('account').replace("'", ""), 'values': [account.get('total')]} for account in data if account.get('parent_account') == None and account.get('currency')]
|
datasets = [{'name':account.get('account').replace("'", ""), 'values': [account.get('total')]} for account in data if account.get('parent_account') == None and account.get('currency')]
|
||||||
|
|||||||
@@ -12,6 +12,39 @@ frappe.query_reports["Consolidated Financial Statement"] = {
|
|||||||
"default": frappe.defaults.get_user_default("Company"),
|
"default": frappe.defaults.get_user_default("Company"),
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"filter_based_on",
|
||||||
|
"label": __("Filter Based On"),
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"options": ["Fiscal Year", "Date Range"],
|
||||||
|
"default": ["Fiscal Year"],
|
||||||
|
"reqd": 1,
|
||||||
|
on_change: function() {
|
||||||
|
let filter_based_on = frappe.query_report.get_filter_value('filter_based_on');
|
||||||
|
frappe.query_report.toggle_filter_display('from_fiscal_year', filter_based_on === 'Date Range');
|
||||||
|
frappe.query_report.toggle_filter_display('to_fiscal_year', filter_based_on === 'Date Range');
|
||||||
|
frappe.query_report.toggle_filter_display('period_start_date', filter_based_on === 'Fiscal Year');
|
||||||
|
frappe.query_report.toggle_filter_display('period_end_date', filter_based_on === 'Fiscal Year');
|
||||||
|
|
||||||
|
frappe.query_report.refresh();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"period_start_date",
|
||||||
|
"label": __("Start Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.nowdate(),
|
||||||
|
"hidden": 1,
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"period_end_date",
|
||||||
|
"label": __("End Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.add_months(frappe.datetime.nowdate(), 12),
|
||||||
|
"hidden": 1,
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"from_fiscal_year",
|
"fieldname":"from_fiscal_year",
|
||||||
"label": __("Start Year"),
|
"label": __("Start Year"),
|
||||||
@@ -61,5 +94,17 @@ frappe.query_reports["Consolidated Financial Statement"] = {
|
|||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"default": 1
|
"default": 1
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"formatter": function(value, row, column, data, default_formatter) {
|
||||||
|
value = default_formatter(value, row, column, data);
|
||||||
|
|
||||||
|
if (!data.parent_account) {
|
||||||
|
value = $(`<span>${value}</span>`);
|
||||||
|
|
||||||
|
var $value = $(value).css("font-weight", "bold");
|
||||||
|
|
||||||
|
value = $value.wrap("<p></p>").parent().html();
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,15 +4,15 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe, erpnext
|
import frappe, erpnext
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import flt, cint
|
from frappe.utils import flt, cint, getdate
|
||||||
from erpnext.accounts.report.utils import get_currency, convert_to_presentation_currency
|
from erpnext.accounts.report.utils import get_currency, convert_to_presentation_currency
|
||||||
from erpnext.accounts.report.financial_statements import get_fiscal_year_data, sort_accounts
|
from erpnext.accounts.report.financial_statements import get_fiscal_year_data, sort_accounts
|
||||||
from erpnext.accounts.report.balance_sheet.balance_sheet import (get_provisional_profit_loss,
|
from erpnext.accounts.report.balance_sheet.balance_sheet import (get_provisional_profit_loss,
|
||||||
check_opening_balance, get_chart_data)
|
check_opening_balance, get_chart_data, get_report_summary as get_bs_summary)
|
||||||
from erpnext.accounts.report.profit_and_loss_statement.profit_and_loss_statement import (get_net_profit_loss,
|
from erpnext.accounts.report.profit_and_loss_statement.profit_and_loss_statement import (get_net_profit_loss,
|
||||||
get_chart_data as get_pl_chart_data)
|
get_chart_data as get_pl_chart_data, get_report_summary as get_pl_summary)
|
||||||
from erpnext.accounts.report.cash_flow.cash_flow import (get_cash_flow_accounts, get_account_type_based_gl_data,
|
from erpnext.accounts.report.cash_flow.cash_flow import (get_cash_flow_accounts, get_account_type_based_gl_data,
|
||||||
add_total_row_account)
|
add_total_row_account, get_report_summary as get_cash_flow_summary)
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
columns, data, message, chart = [], [], [], []
|
columns, data, message, chart = [], [], [], []
|
||||||
@@ -25,17 +25,17 @@ def execute(filters=None):
|
|||||||
columns = get_columns(companies_column)
|
columns = get_columns(companies_column)
|
||||||
|
|
||||||
if filters.get('report') == "Balance Sheet":
|
if filters.get('report') == "Balance Sheet":
|
||||||
data, message, chart = get_balance_sheet_data(fiscal_year, companies, columns, filters)
|
data, message, chart, report_summary = get_balance_sheet_data(fiscal_year, companies, columns, filters)
|
||||||
elif filters.get('report') == "Profit and Loss Statement":
|
elif filters.get('report') == "Profit and Loss Statement":
|
||||||
data, message, chart = get_profit_loss_data(fiscal_year, companies, columns, filters)
|
data, message, chart, report_summary = get_profit_loss_data(fiscal_year, companies, columns, filters)
|
||||||
else:
|
else:
|
||||||
if cint(frappe.db.get_single_value('Accounts Settings', 'use_custom_cash_flow')):
|
if cint(frappe.db.get_single_value('Accounts Settings', 'use_custom_cash_flow')):
|
||||||
from erpnext.accounts.report.cash_flow.custom_cash_flow import execute as execute_custom
|
from erpnext.accounts.report.cash_flow.custom_cash_flow import execute as execute_custom
|
||||||
return execute_custom(filters=filters)
|
return execute_custom(filters=filters)
|
||||||
|
|
||||||
data = get_cash_flow_data(fiscal_year, companies, filters)
|
data, report_summary = get_cash_flow_data(fiscal_year, companies, filters)
|
||||||
|
|
||||||
return columns, data, message, chart
|
return columns, data, message, chart, report_summary
|
||||||
|
|
||||||
def get_balance_sheet_data(fiscal_year, companies, columns, filters):
|
def get_balance_sheet_data(fiscal_year, companies, columns, filters):
|
||||||
asset = get_data(companies, "Asset", "Debit", fiscal_year, filters=filters)
|
asset = get_data(companies, "Asset", "Debit", fiscal_year, filters=filters)
|
||||||
@@ -75,9 +75,12 @@ def get_balance_sheet_data(fiscal_year, companies, columns, filters):
|
|||||||
if total_credit:
|
if total_credit:
|
||||||
data.append(total_credit)
|
data.append(total_credit)
|
||||||
|
|
||||||
|
report_summary = get_bs_summary(companies, asset, liability, equity, provisional_profit_loss, total_credit,
|
||||||
|
company_currency, filters, True)
|
||||||
|
|
||||||
chart = get_chart_data(filters, columns, asset, liability, equity)
|
chart = get_chart_data(filters, columns, asset, liability, equity)
|
||||||
|
|
||||||
return data, message, chart
|
return data, message, chart, report_summary
|
||||||
|
|
||||||
def get_profit_loss_data(fiscal_year, companies, columns, filters):
|
def get_profit_loss_data(fiscal_year, companies, columns, filters):
|
||||||
income, expense, net_profit_loss = get_income_expense_data(companies, fiscal_year, filters)
|
income, expense, net_profit_loss = get_income_expense_data(companies, fiscal_year, filters)
|
||||||
@@ -90,7 +93,9 @@ def get_profit_loss_data(fiscal_year, companies, columns, filters):
|
|||||||
|
|
||||||
chart = get_pl_chart_data(filters, columns, income, expense, net_profit_loss)
|
chart = get_pl_chart_data(filters, columns, income, expense, net_profit_loss)
|
||||||
|
|
||||||
return data, None, chart
|
report_summary = get_pl_summary(companies, '', income, expense, net_profit_loss, True)
|
||||||
|
|
||||||
|
return data, None, chart, report_summary
|
||||||
|
|
||||||
def get_income_expense_data(companies, fiscal_year, filters):
|
def get_income_expense_data(companies, fiscal_year, filters):
|
||||||
company_currency = get_company_currency(filters)
|
company_currency = get_company_currency(filters)
|
||||||
@@ -108,6 +113,7 @@ def get_cash_flow_data(fiscal_year, companies, filters):
|
|||||||
income, expense, net_profit_loss = get_income_expense_data(companies, fiscal_year, filters)
|
income, expense, net_profit_loss = get_income_expense_data(companies, fiscal_year, filters)
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
|
summary_data = {}
|
||||||
company_currency = get_company_currency(filters)
|
company_currency = get_company_currency(filters)
|
||||||
|
|
||||||
for cash_flow_account in cash_flow_accounts:
|
for cash_flow_account in cash_flow_accounts:
|
||||||
@@ -142,11 +148,13 @@ def get_cash_flow_data(fiscal_year, companies, filters):
|
|||||||
section_data.append(account_data)
|
section_data.append(account_data)
|
||||||
|
|
||||||
add_total_row_account(data, section_data, cash_flow_account['section_footer'],
|
add_total_row_account(data, section_data, cash_flow_account['section_footer'],
|
||||||
companies, company_currency, True)
|
companies, company_currency, summary_data, True)
|
||||||
|
|
||||||
add_total_row_account(data, data, _("Net Change in Cash"), companies, company_currency, True)
|
add_total_row_account(data, data, _("Net Change in Cash"), companies, company_currency, summary_data, True)
|
||||||
|
|
||||||
return data
|
report_summary = get_cash_flow_summary(summary_data, company_currency)
|
||||||
|
|
||||||
|
return data, report_summary
|
||||||
|
|
||||||
def get_account_type_based_data(account_type, companies, fiscal_year, filters):
|
def get_account_type_based_data(account_type, companies, fiscal_year, filters):
|
||||||
data = {}
|
data = {}
|
||||||
@@ -200,17 +208,24 @@ def get_data(companies, root_type, balance_must_be, fiscal_year, filters=None, i
|
|||||||
|
|
||||||
company_currency = get_company_currency(filters)
|
company_currency = get_company_currency(filters)
|
||||||
|
|
||||||
|
if filters.filter_based_on == 'Fiscal Year':
|
||||||
|
start_date = fiscal_year.year_start_date
|
||||||
|
end_date = fiscal_year.year_end_date
|
||||||
|
else:
|
||||||
|
start_date = filters.period_start_date
|
||||||
|
end_date = filters.period_end_date
|
||||||
|
|
||||||
gl_entries_by_account = {}
|
gl_entries_by_account = {}
|
||||||
for root in frappe.db.sql("""select lft, rgt from tabAccount
|
for root in frappe.db.sql("""select lft, rgt from tabAccount
|
||||||
where root_type=%s and ifnull(parent_account, '') = ''""", root_type, as_dict=1):
|
where root_type=%s and ifnull(parent_account, '') = ''""", root_type, as_dict=1):
|
||||||
|
|
||||||
set_gl_entries_by_account(fiscal_year.year_start_date,
|
set_gl_entries_by_account(start_date,
|
||||||
fiscal_year.year_end_date, root.lft, root.rgt, filters,
|
end_date, root.lft, root.rgt, filters,
|
||||||
gl_entries_by_account, accounts_by_name, ignore_closing_entries=False)
|
gl_entries_by_account, accounts_by_name, ignore_closing_entries=False)
|
||||||
|
|
||||||
calculate_values(accounts_by_name, gl_entries_by_account, companies, fiscal_year, filters)
|
calculate_values(accounts_by_name, gl_entries_by_account, companies, start_date, filters)
|
||||||
accumulate_values_into_parents(accounts, accounts_by_name, companies)
|
accumulate_values_into_parents(accounts, accounts_by_name, companies)
|
||||||
out = prepare_data(accounts, fiscal_year, balance_must_be, companies, company_currency)
|
out = prepare_data(accounts, start_date, end_date, balance_must_be, companies, company_currency)
|
||||||
|
|
||||||
if out:
|
if out:
|
||||||
add_total_row(out, root_type, balance_must_be, companies, company_currency)
|
add_total_row(out, root_type, balance_must_be, companies, company_currency)
|
||||||
@@ -221,7 +236,7 @@ def get_company_currency(filters=None):
|
|||||||
return (filters.get('presentation_currency')
|
return (filters.get('presentation_currency')
|
||||||
or frappe.get_cached_value('Company', filters.company, "default_currency"))
|
or frappe.get_cached_value('Company', filters.company, "default_currency"))
|
||||||
|
|
||||||
def calculate_values(accounts_by_name, gl_entries_by_account, companies, fiscal_year, filters):
|
def calculate_values(accounts_by_name, gl_entries_by_account, companies, start_date, filters):
|
||||||
for entries in gl_entries_by_account.values():
|
for entries in gl_entries_by_account.values():
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
key = entry.account_number or entry.account_name
|
key = entry.account_number or entry.account_name
|
||||||
@@ -233,7 +248,7 @@ def calculate_values(accounts_by_name, gl_entries_by_account, companies, fiscal_
|
|||||||
and entry.company in companies.get(company)):
|
and entry.company in companies.get(company)):
|
||||||
d[company] = d.get(company, 0.0) + flt(entry.debit) - flt(entry.credit)
|
d[company] = d.get(company, 0.0) + flt(entry.debit) - flt(entry.credit)
|
||||||
|
|
||||||
if entry.posting_date < fiscal_year.year_start_date:
|
if entry.posting_date < getdate(start_date):
|
||||||
d["opening_balance"] = d.get("opening_balance", 0.0) + flt(entry.debit) - flt(entry.credit)
|
d["opening_balance"] = d.get("opening_balance", 0.0) + flt(entry.debit) - flt(entry.credit)
|
||||||
|
|
||||||
def accumulate_values_into_parents(accounts, accounts_by_name, companies):
|
def accumulate_values_into_parents(accounts, accounts_by_name, companies):
|
||||||
@@ -287,10 +302,8 @@ def get_accounts(root_type, filters):
|
|||||||
`tabAccount` where company = %s and root_type = %s
|
`tabAccount` where company = %s and root_type = %s
|
||||||
""" , (filters.get('company'), root_type), as_dict=1)
|
""" , (filters.get('company'), root_type), as_dict=1)
|
||||||
|
|
||||||
def prepare_data(accounts, fiscal_year, balance_must_be, companies, company_currency):
|
def prepare_data(accounts, start_date, end_date, balance_must_be, companies, company_currency):
|
||||||
data = []
|
data = []
|
||||||
year_start_date = fiscal_year.year_start_date
|
|
||||||
year_end_date = fiscal_year.year_end_date
|
|
||||||
|
|
||||||
for d in accounts:
|
for d in accounts:
|
||||||
# add to output
|
# add to output
|
||||||
@@ -301,8 +314,8 @@ def prepare_data(accounts, fiscal_year, balance_must_be, companies, company_curr
|
|||||||
"account": _(d.account_name),
|
"account": _(d.account_name),
|
||||||
"parent_account": _(d.parent_account),
|
"parent_account": _(d.parent_account),
|
||||||
"indent": flt(d.indent),
|
"indent": flt(d.indent),
|
||||||
"year_start_date": year_start_date,
|
"year_start_date": start_date,
|
||||||
"year_end_date": year_end_date,
|
"year_end_date": end_date,
|
||||||
"currency": company_currency,
|
"currency": company_currency,
|
||||||
"opening_balance": d.get("opening_balance", 0.0) * (1 if balance_must_be == "Debit" else -1)
|
"opening_balance": d.get("opening_balance", 0.0) * (1 if balance_must_be == "Debit" else -1)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -18,17 +18,20 @@ from frappe.utils import (flt, getdate, get_first_day, add_months, add_days, for
|
|||||||
from six import itervalues
|
from six import itervalues
|
||||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
|
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, period_start_date, period_end_date, filter_based_on, periodicity, accumulated_values=False,
|
||||||
company=None, reset_period_on_fy_change=True):
|
company=None, reset_period_on_fy_change=True):
|
||||||
"""Get a list of dict {"from_date": from_date, "to_date": to_date, "key": key, "label": label}
|
"""Get a list of dict {"from_date": from_date, "to_date": to_date, "key": key, "label": label}
|
||||||
Periodicity can be (Yearly, Quarterly, Monthly)"""
|
Periodicity can be (Yearly, Quarterly, Monthly)"""
|
||||||
|
|
||||||
fiscal_year = get_fiscal_year_data(from_fiscal_year, to_fiscal_year)
|
if filter_based_on == 'Fiscal Year':
|
||||||
validate_fiscal_year(fiscal_year, from_fiscal_year, to_fiscal_year)
|
fiscal_year = get_fiscal_year_data(from_fiscal_year, to_fiscal_year)
|
||||||
|
validate_fiscal_year(fiscal_year, from_fiscal_year, to_fiscal_year)
|
||||||
# start with first day, so as to avoid year to_dates like 2-April if ever they occur]
|
year_start_date = getdate(fiscal_year.year_start_date)
|
||||||
year_start_date = getdate(fiscal_year.year_start_date)
|
year_end_date = getdate(fiscal_year.year_end_date)
|
||||||
year_end_date = getdate(fiscal_year.year_end_date)
|
else:
|
||||||
|
validate_dates(period_start_date, period_end_date)
|
||||||
|
year_start_date = getdate(period_start_date)
|
||||||
|
year_end_date = getdate(period_end_date)
|
||||||
|
|
||||||
months_to_add = {
|
months_to_add = {
|
||||||
"Yearly": 12,
|
"Yearly": 12,
|
||||||
@@ -42,6 +45,9 @@ def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_v
|
|||||||
start_date = year_start_date
|
start_date = year_start_date
|
||||||
months = get_months(year_start_date, year_end_date)
|
months = get_months(year_start_date, year_end_date)
|
||||||
|
|
||||||
|
if (months // months_to_add) != (months / months_to_add):
|
||||||
|
months += months_to_add
|
||||||
|
|
||||||
for i in range(months // months_to_add):
|
for i in range(months // months_to_add):
|
||||||
period = frappe._dict({
|
period = frappe._dict({
|
||||||
"from_date": start_date
|
"from_date": start_date
|
||||||
@@ -103,9 +109,18 @@ def get_fiscal_year_data(from_fiscal_year, to_fiscal_year):
|
|||||||
|
|
||||||
|
|
||||||
def validate_fiscal_year(fiscal_year, from_fiscal_year, to_fiscal_year):
|
def validate_fiscal_year(fiscal_year, from_fiscal_year, to_fiscal_year):
|
||||||
if not fiscal_year.get('year_start_date') and not fiscal_year.get('year_end_date'):
|
if not fiscal_year.get('year_start_date') or not fiscal_year.get('year_end_date'):
|
||||||
|
frappe.throw(_("Start Year and End Year are mandatory"))
|
||||||
|
|
||||||
|
if getdate(fiscal_year.get('year_end_date')) < getdate(fiscal_year.get('year_start_date')):
|
||||||
frappe.throw(_("End Year cannot be before Start Year"))
|
frappe.throw(_("End Year cannot be before Start Year"))
|
||||||
|
|
||||||
|
def validate_dates(from_date, to_date):
|
||||||
|
if not from_date or not to_date:
|
||||||
|
frappe.throw("From Date and To Date are mandatory")
|
||||||
|
|
||||||
|
if to_date < from_date:
|
||||||
|
frappe.throw("To Date cannot be less than From Date")
|
||||||
|
|
||||||
def get_months(start_date, end_date):
|
def get_months(start_date, end_date):
|
||||||
diff = (12 * end_date.year + end_date.month) - (12 * start_date.year + start_date.month)
|
diff = (12 * end_date.year + end_date.month) - (12 * start_date.year + start_date.month)
|
||||||
@@ -151,7 +166,7 @@ def get_data(
|
|||||||
|
|
||||||
calculate_values(
|
calculate_values(
|
||||||
accounts_by_name, gl_entries_by_account, period_list, accumulated_values, ignore_accumulated_values_for_fy)
|
accounts_by_name, gl_entries_by_account, period_list, accumulated_values, ignore_accumulated_values_for_fy)
|
||||||
accumulate_values_into_parents(accounts, accounts_by_name, period_list, accumulated_values)
|
accumulate_values_into_parents(accounts, accounts_by_name, period_list)
|
||||||
out = prepare_data(accounts, balance_must_be, period_list, company_currency)
|
out = prepare_data(accounts, balance_must_be, period_list, company_currency)
|
||||||
out = filter_out_zero_value_rows(out, parent_children_map)
|
out = filter_out_zero_value_rows(out, parent_children_map)
|
||||||
|
|
||||||
@@ -191,7 +206,7 @@ def calculate_values(
|
|||||||
d["opening_balance"] = d.get("opening_balance", 0.0) + flt(entry.debit) - flt(entry.credit)
|
d["opening_balance"] = d.get("opening_balance", 0.0) + flt(entry.debit) - flt(entry.credit)
|
||||||
|
|
||||||
|
|
||||||
def accumulate_values_into_parents(accounts, accounts_by_name, period_list, accumulated_values):
|
def accumulate_values_into_parents(accounts, accounts_by_name, period_list):
|
||||||
"""accumulate children's values in parent accounts"""
|
"""accumulate children's values in parent accounts"""
|
||||||
for d in reversed(accounts):
|
for d in reversed(accounts):
|
||||||
if d.parent_account:
|
if d.parent_account:
|
||||||
@@ -419,7 +434,9 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters):
|
|||||||
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
|
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
|
||||||
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
|
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
|
||||||
filters.get(dimension.fieldname))
|
filters.get(dimension.fieldname))
|
||||||
additional_conditions.append("{0} in %({0})s".format(dimension.fieldname))
|
additional_conditions.append("{0} in %({0})s".format(dimension.fieldname))
|
||||||
|
else:
|
||||||
|
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 ""
|
||||||
|
|
||||||
|
|||||||
@@ -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) { %}
|
{% } else if (filters.party && filters.party.length) { %}
|
||||||
{%= filters.party %}
|
{%= filters.party %}
|
||||||
{% } else if (filters.account) { %}
|
{% } else if (filters.account) { %}
|
||||||
{%= filters.account %}
|
{%= filters.account %}
|
||||||
|
|||||||
@@ -202,7 +202,9 @@ def get_conditions(filters):
|
|||||||
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
|
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
|
||||||
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
|
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
|
||||||
filters.get(dimension.fieldname))
|
filters.get(dimension.fieldname))
|
||||||
conditions.append("{0} in %({0})s".format(dimension.fieldname))
|
conditions.append("{0} in %({0})s".format(dimension.fieldname))
|
||||||
|
else:
|
||||||
|
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 ""
|
||||||
|
|
||||||
@@ -363,6 +365,7 @@ def get_columns(filters):
|
|||||||
|
|
||||||
columns = [
|
columns = [
|
||||||
{
|
{
|
||||||
|
"label": _("GL Entry"),
|
||||||
"fieldname": "gl_entry",
|
"fieldname": "gl_entry",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "GL Entry",
|
"options": "GL Entry",
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ from frappe.utils import flt
|
|||||||
from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
|
from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
|
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
|
||||||
filters.periodicity, filters.accumulated_values, filters.company)
|
filters.periodicity, filters.accumulated_values, filters.company)
|
||||||
@@ -27,17 +26,19 @@ def execute(filters=None):
|
|||||||
|
|
||||||
|
|
||||||
gross_income = get_revenue(income, period_list)
|
gross_income = get_revenue(income, period_list)
|
||||||
|
|
||||||
gross_expense = get_revenue(expense, period_list)
|
gross_expense = get_revenue(expense, period_list)
|
||||||
|
|
||||||
if(len(gross_income)==0 and len(gross_expense)== 0):
|
if(len(gross_income)==0 and len(gross_expense)== 0):
|
||||||
data.append({"account_name": "'" + _("Nothing is included in gross") + "'",
|
data.append({
|
||||||
"account": "'" + _("Nothing is included in gross") + "'"})
|
"account_name": "'" + _("Nothing is included in gross") + "'",
|
||||||
|
"account": "'" + _("Nothing is included in gross") + "'"
|
||||||
|
})
|
||||||
return columns, data
|
return columns, data
|
||||||
|
|
||||||
data.append({"account_name": "'" + _("Included in Gross Profit") + "'",
|
data.append({
|
||||||
"account": "'" + _("Included in Gross Profit") + "'"})
|
"account_name": "'" + _("Included in Gross Profit") + "'",
|
||||||
|
"account": "'" + _("Included in Gross Profit") + "'"
|
||||||
|
})
|
||||||
|
|
||||||
data.append({})
|
data.append({})
|
||||||
data.extend(gross_income or [])
|
data.extend(gross_income or [])
|
||||||
@@ -111,7 +112,6 @@ def set_total(node, value, complete_list, totals):
|
|||||||
|
|
||||||
|
|
||||||
def get_profit(gross_income, gross_expense, period_list, company, profit_type, currency=None, consolidated=False):
|
def get_profit(gross_income, gross_expense, period_list, company, profit_type, currency=None, consolidated=False):
|
||||||
|
|
||||||
profit_loss = {
|
profit_loss = {
|
||||||
"account_name": "'" + _(profit_type) + "'",
|
"account_name": "'" + _(profit_type) + "'",
|
||||||
"account": "'" + _(profit_type) + "'",
|
"account": "'" + _(profit_type) + "'",
|
||||||
@@ -123,7 +123,9 @@ def get_profit(gross_income, gross_expense, period_list, company, profit_type, c
|
|||||||
|
|
||||||
for period in period_list:
|
for period in period_list:
|
||||||
key = period if consolidated else period.key
|
key = period if consolidated else period.key
|
||||||
profit_loss[key] = flt(gross_income[0].get(key, 0)) - flt(gross_expense[0].get(key, 0))
|
gross_income_for_period = flt(gross_income[0].get(key, 0)) if gross_income else 0
|
||||||
|
gross_expense_for_period = flt(gross_expense[0].get(key, 0)) if gross_expense else 0
|
||||||
|
profit_loss[key] = gross_income_for_period - gross_expense_for_period
|
||||||
|
|
||||||
if profit_loss[key]:
|
if profit_loss[key]:
|
||||||
has_value=True
|
has_value=True
|
||||||
@@ -143,12 +145,18 @@ def get_net_profit(non_gross_income, gross_income, gross_expense, non_gross_expe
|
|||||||
|
|
||||||
for period in period_list:
|
for period in period_list:
|
||||||
key = period if consolidated else period.key
|
key = period if consolidated else period.key
|
||||||
total_income = flt(gross_income[0].get(key, 0)) + flt(non_gross_income[0].get(key, 0))
|
gross_income_for_period = flt(gross_income[0].get(key, 0)) if gross_income else 0
|
||||||
total_expense = flt(gross_expense[0].get(key, 0)) + flt(non_gross_expense[0].get(key, 0))
|
non_gross_income_for_period = flt(non_gross_income[0].get(key, 0)) if non_gross_income else 0
|
||||||
|
|
||||||
|
gross_expense_for_period = flt(gross_expense[0].get(key, 0)) if gross_expense else 0
|
||||||
|
non_gross_expense_for_period = flt(non_gross_expense[0].get(key, 0)) if non_gross_expense else 0
|
||||||
|
|
||||||
|
total_income = gross_income_for_period + non_gross_income_for_period
|
||||||
|
total_expense = gross_expense_for_period + non_gross_expense_for_period
|
||||||
profit_loss[key] = flt(total_income) - flt(total_expense)
|
profit_loss[key] = flt(total_income) - flt(total_expense)
|
||||||
|
|
||||||
if profit_loss[key]:
|
if profit_loss[key]:
|
||||||
has_value=True
|
has_value=True
|
||||||
|
|
||||||
if has_value:
|
if has_value:
|
||||||
return profit_loss
|
return profit_loss
|
||||||
@@ -55,27 +55,27 @@ def get_columns(group_wise_columns, filters):
|
|||||||
columns = []
|
columns = []
|
||||||
column_map = frappe._dict({
|
column_map = frappe._dict({
|
||||||
"parent": _("Sales Invoice") + ":Link/Sales Invoice:120",
|
"parent": _("Sales Invoice") + ":Link/Sales Invoice:120",
|
||||||
"posting_date": _("Posting Date") + ":Date",
|
"posting_date": _("Posting Date") + ":Date:100",
|
||||||
"posting_time": _("Posting Time"),
|
"posting_time": _("Posting Time") + ":Data:100",
|
||||||
"item_code": _("Item Code") + ":Link/Item",
|
"item_code": _("Item Code") + ":Link/Item:100",
|
||||||
"item_name": _("Item Name"),
|
"item_name": _("Item Name") + ":Data:100",
|
||||||
"item_group": _("Item Group") + ":Link/Item Group",
|
"item_group": _("Item Group") + ":Link/Item Group:100",
|
||||||
"brand": _("Brand"),
|
"brand": _("Brand") + ":Link/Brand:100",
|
||||||
"description": _("Description"),
|
"description": _("Description") +":Data:100",
|
||||||
"warehouse": _("Warehouse") + ":Link/Warehouse",
|
"warehouse": _("Warehouse") + ":Link/Warehouse:100",
|
||||||
"qty": _("Qty") + ":Float",
|
"qty": _("Qty") + ":Float:80",
|
||||||
"base_rate": _("Avg. Selling Rate") + ":Currency/currency",
|
"base_rate": _("Avg. Selling Rate") + ":Currency/currency:100",
|
||||||
"buying_rate": _("Valuation Rate") + ":Currency/currency",
|
"buying_rate": _("Valuation Rate") + ":Currency/currency:100",
|
||||||
"base_amount": _("Selling Amount") + ":Currency/currency",
|
"base_amount": _("Selling Amount") + ":Currency/currency:100",
|
||||||
"buying_amount": _("Buying Amount") + ":Currency/currency",
|
"buying_amount": _("Buying Amount") + ":Currency/currency:100",
|
||||||
"gross_profit": _("Gross Profit") + ":Currency/currency",
|
"gross_profit": _("Gross Profit") + ":Currency/currency:100",
|
||||||
"gross_profit_percent": _("Gross Profit %") + ":Percent",
|
"gross_profit_percent": _("Gross Profit %") + ":Percent:100",
|
||||||
"project": _("Project") + ":Link/Project",
|
"project": _("Project") + ":Link/Project:100",
|
||||||
"sales_person": _("Sales person"),
|
"sales_person": _("Sales person"),
|
||||||
"allocated_amount": _("Allocated Amount") + ":Currency/currency",
|
"allocated_amount": _("Allocated Amount") + ":Currency/currency:100",
|
||||||
"customer": _("Customer") + ":Link/Customer",
|
"customer": _("Customer") + ":Link/Customer:100",
|
||||||
"customer_group": _("Customer Group") + ":Link/Customer Group",
|
"customer_group": _("Customer Group") + ":Link/Customer Group:100",
|
||||||
"territory": _("Territory") + ":Link/Territory"
|
"territory": _("Territory") + ":Link/Territory:100"
|
||||||
})
|
})
|
||||||
|
|
||||||
for col in group_wise_columns.get(scrub(filters.group_by)):
|
for col in group_wise_columns.get(scrub(filters.group_by)):
|
||||||
@@ -85,7 +85,8 @@ def get_columns(group_wise_columns, filters):
|
|||||||
"fieldname": "currency",
|
"fieldname": "currency",
|
||||||
"label" : _("Currency"),
|
"label" : _("Currency"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Currency"
|
"options": "Currency",
|
||||||
|
"hidden": 1
|
||||||
})
|
})
|
||||||
|
|
||||||
return columns
|
return columns
|
||||||
@@ -277,7 +278,7 @@ class GrossProfitGenerator(object):
|
|||||||
from `tabPurchase Invoice Item` a
|
from `tabPurchase Invoice Item` a
|
||||||
where a.item_code = %s and a.docstatus=1
|
where a.item_code = %s and a.docstatus=1
|
||||||
and modified <= %s
|
and modified <= %s
|
||||||
order by a.modified desc limit 1""", (item_code,self.filters.to_date))
|
order by a.modified desc limit 1""", (item_code, self.filters.to_date))
|
||||||
else:
|
else:
|
||||||
last_purchase_rate = frappe.db.sql("""
|
last_purchase_rate = frappe.db.sql("""
|
||||||
select (a.base_rate / a.conversion_factor)
|
select (a.base_rate / a.conversion_factor)
|
||||||
|
|||||||
@@ -15,11 +15,6 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
|||||||
return frappe.db.get_link_options('Project', txt);
|
return frappe.db.get_link_options('Project', txt);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "accumulated_values",
|
|
||||||
"label": __("Accumulated Values"),
|
|
||||||
"fieldtype": "Check"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "include_default_book_entries",
|
"fieldname": "include_default_book_entries",
|
||||||
"label": __("Include Default Book Entries"),
|
"label": __("Include Default Book Entries"),
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ from erpnext.accounts.report.financial_statements import (get_period_list, get_c
|
|||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
|
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
|
||||||
filters.periodicity, filters.accumulated_values, filters.company)
|
filters.period_start_date, filters.period_end_date, filters.filter_based_on, filters.periodicity,
|
||||||
|
company=filters.company)
|
||||||
|
|
||||||
income = get_data(filters.company, "Income", "Credit", period_list, filters = filters,
|
income = get_data(filters.company, "Income", "Credit", period_list, filters = filters,
|
||||||
accumulated_values=filters.accumulated_values,
|
accumulated_values=filters.accumulated_values,
|
||||||
@@ -31,20 +32,22 @@ def execute(filters=None):
|
|||||||
|
|
||||||
chart = get_chart_data(filters, columns, income, expense, net_profit_loss)
|
chart = get_chart_data(filters, columns, income, expense, net_profit_loss)
|
||||||
|
|
||||||
report_summary = get_report_summary(columns, income, expense, net_profit_loss, filters.periodicity, period_list)
|
default_currency = frappe.get_cached_value('Company', filters.company, "default_currency")
|
||||||
|
report_summary = get_report_summary(period_list, filters.periodicity, income, expense, net_profit_loss, default_currency)
|
||||||
|
|
||||||
return columns, data, None, chart, report_summary
|
return columns, data, None, chart, report_summary
|
||||||
|
|
||||||
def get_report_summary(columns, income, expense, net_profit_loss, period_list, periodicity):
|
def get_report_summary(period_list, periodicity, income, expense, net_profit_loss, default_currency, consolidated=False):
|
||||||
income_data, expense_data, net_profit = [], [], []
|
net_income, net_expense, net_profit = 0.0, 0.0, 0.0
|
||||||
|
|
||||||
for p in columns[2:]:
|
for period in period_list:
|
||||||
|
key = period if consolidated else period.key
|
||||||
if income:
|
if income:
|
||||||
income_data.append(income[-2].get(p.get("fieldname")))
|
net_income += income[-2].get(key)
|
||||||
if expense:
|
if expense:
|
||||||
expense_data.append(expense[-2].get(p.get("fieldname")))
|
net_expense += expense[-2].get(key)
|
||||||
if net_profit_loss:
|
if net_profit_loss:
|
||||||
net_profit.append(net_profit_loss.get(p.get("fieldname")))
|
net_profit += net_profit_loss.get(key)
|
||||||
|
|
||||||
if (len(period_list) == 1 and periodicity== 'Yearly'):
|
if (len(period_list) == 1 and periodicity== 'Yearly'):
|
||||||
profit_label = _("Profit This Year")
|
profit_label = _("Profit This Year")
|
||||||
@@ -57,23 +60,23 @@ def get_report_summary(columns, income, expense, net_profit_loss, period_list, p
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
"value": net_profit[-1],
|
"value": net_profit,
|
||||||
"indicator": "Green" if net_profit[-1] > 0 else "Red",
|
"indicator": "Green" if net_profit > 0 else "Red",
|
||||||
"label": profit_label,
|
"label": profit_label,
|
||||||
"datatype": "Currency",
|
"datatype": "Currency",
|
||||||
"currency": net_profit_loss.get("currency")
|
"currency": net_profit_loss.get("currency") if net_profit_loss else default_currency
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"value": income_data[-1],
|
"value": net_income,
|
||||||
"label": income_label,
|
"label": income_label,
|
||||||
"datatype": "Currency",
|
"datatype": "Currency",
|
||||||
"currency": income[-1].get('currency')
|
"currency": income[-1].get('currency') if income else default_currency
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"value": expense_data[-1],
|
"value": net_expense,
|
||||||
"label": expense_label,
|
"label": expense_label,
|
||||||
"datatype": "Currency",
|
"datatype": "Currency",
|
||||||
"currency": expense[-1].get('currency')
|
"currency": expense[-1].get('currency') if expense else default_currency
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,33 @@ frappe.query_reports["Purchase Register"] = {
|
|||||||
"label": __("Mode of Payment"),
|
"label": __("Mode of Payment"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Mode of Payment"
|
"options": "Mode of Payment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"cost_center",
|
||||||
|
"label": __("Cost Center"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Cost Center"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"warehouse",
|
||||||
|
"label": __("Warehouse"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Warehouse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"item_group",
|
||||||
|
"label": __("Item Group"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Item Group"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
erpnext.dimension_filters.forEach((dimension) => {
|
||||||
|
frappe.query_reports["Purchase Register"].filters.splice(7, 0 ,{
|
||||||
|
"fieldname": dimension["fieldname"],
|
||||||
|
"label": __(dimension["label"]),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": dimension["document_type"]
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
from frappe import msgprint, _
|
from frappe import msgprint, _
|
||||||
|
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)
|
||||||
@@ -66,7 +67,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
|||||||
total_tax += tax_amount
|
total_tax += tax_amount
|
||||||
row.append(tax_amount)
|
row.append(tax_amount)
|
||||||
|
|
||||||
# total tax, grand total, rounded total & outstanding amount
|
# total tax, grand total, rounded total & outstanding amount
|
||||||
row += [total_tax, inv.base_grand_total, flt(inv.base_grand_total, 0), inv.outstanding_amount]
|
row += [total_tax, inv.base_grand_total, flt(inv.base_grand_total, 0), inv.outstanding_amount]
|
||||||
data.append(row)
|
data.append(row)
|
||||||
|
|
||||||
@@ -134,6 +135,38 @@ def get_conditions(filters):
|
|||||||
|
|
||||||
if filters.get("mode_of_payment"): conditions += " and ifnull(mode_of_payment, '') = %(mode_of_payment)s"
|
if filters.get("mode_of_payment"): conditions += " and ifnull(mode_of_payment, '') = %(mode_of_payment)s"
|
||||||
|
|
||||||
|
if filters.get("cost_center"):
|
||||||
|
conditions += """ and exists(select name from `tabPurchase Invoice Item`
|
||||||
|
where parent=`tabPurchase Invoice`.name
|
||||||
|
and ifnull(`tabPurchase Invoice Item`.cost_center, '') = %(cost_center)s)"""
|
||||||
|
|
||||||
|
if filters.get("warehouse"):
|
||||||
|
conditions += """ and exists(select name from `tabPurchase Invoice Item`
|
||||||
|
where parent=`tabPurchase Invoice`.name
|
||||||
|
and ifnull(`tabPurchase Invoice Item`.warehouse, '') = %(warehouse)s)"""
|
||||||
|
|
||||||
|
if filters.get("item_group"):
|
||||||
|
conditions += """ and exists(select name from `tabPurchase Invoice Item`
|
||||||
|
where parent=`tabPurchase Invoice`.name
|
||||||
|
and ifnull(`tabPurchase Invoice Item`.item_group, '') = %(item_group)s)"""
|
||||||
|
|
||||||
|
accounting_dimensions = get_accounting_dimensions(as_list=False)
|
||||||
|
|
||||||
|
if accounting_dimensions:
|
||||||
|
common_condition = """
|
||||||
|
and exists(select name from `tabPurchase Invoice Item`
|
||||||
|
where parent=`tabPurchase Invoice`.name
|
||||||
|
"""
|
||||||
|
for dimension in accounting_dimensions:
|
||||||
|
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 += common_condition + "and ifnull(`tabPurchase Invoice Item`.{0}, '') in %({0})s)".format(dimension.fieldname)
|
||||||
|
else:
|
||||||
|
conditions += common_condition + "and ifnull(`tabPurchase Invoice Item`.{0}, '') in (%({0})s))".format(dimension.fieldname)
|
||||||
|
|
||||||
return conditions
|
return conditions
|
||||||
|
|
||||||
def get_invoices(filters, additional_query_columns):
|
def get_invoices(filters, additional_query_columns):
|
||||||
|
|||||||
@@ -344,16 +344,19 @@ def get_conditions(filters):
|
|||||||
accounting_dimensions = get_accounting_dimensions(as_list=False)
|
accounting_dimensions = get_accounting_dimensions(as_list=False)
|
||||||
|
|
||||||
if accounting_dimensions:
|
if accounting_dimensions:
|
||||||
|
common_condition = """
|
||||||
|
and exists(select name from `tabSales Invoice Item`
|
||||||
|
where parent=`tabSales Invoice`.name
|
||||||
|
"""
|
||||||
for dimension in accounting_dimensions:
|
for dimension in accounting_dimensions:
|
||||||
if filters.get(dimension.fieldname):
|
if filters.get(dimension.fieldname):
|
||||||
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
|
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
|
||||||
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
|
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
|
||||||
filters.get(dimension.fieldname))
|
filters.get(dimension.fieldname))
|
||||||
|
|
||||||
conditions += """ and exists(select name from `tabSales Invoice Item`
|
conditions += common_condition + "and ifnull(`tabSales Invoice Item`.{0}, '') in %({0})s)".format(dimension.fieldname)
|
||||||
where parent=`tabSales Invoice`.name
|
else:
|
||||||
and ifnull(`tabSales Invoice Item`.{0}, '') in %({0})s)""".format(dimension.fieldname)
|
conditions += common_condition + "and ifnull(`tabSales Invoice Item`.{0}, '') in (%({0})s))".format(dimension.fieldname)
|
||||||
|
|
||||||
|
|
||||||
return conditions
|
return conditions
|
||||||
|
|
||||||
|
|||||||
@@ -44,9 +44,14 @@ def get_result(filters):
|
|||||||
out = []
|
out = []
|
||||||
for supplier in filters.supplier:
|
for supplier in filters.supplier:
|
||||||
tds = frappe.get_doc("Tax Withholding Category", supplier.tax_withholding_category)
|
tds = frappe.get_doc("Tax Withholding Category", supplier.tax_withholding_category)
|
||||||
rate = [d.tax_withholding_rate for d in tds.rates if d.fiscal_year == filters.fiscal_year][0]
|
rate = [d.tax_withholding_rate for d in tds.rates if d.fiscal_year == filters.fiscal_year]
|
||||||
|
|
||||||
|
if rate:
|
||||||
|
rate = rate[0]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
account = [d.account for d in tds.accounts if d.company == filters.company][0]
|
account = [d.account for d in tds.accounts if d.company == filters.company][0]
|
||||||
|
|
||||||
except IndexError:
|
except IndexError:
|
||||||
account = []
|
account = []
|
||||||
total_invoiced_amount, tds_deducted = get_invoice_and_tds_amount(supplier.name, account,
|
total_invoiced_amount, tds_deducted = get_invoice_and_tds_amount(supplier.name, account,
|
||||||
@@ -76,7 +81,7 @@ def get_invoice_and_tds_amount(supplier, account, company, from_date, to_date):
|
|||||||
supplier_credit_amount = flt(sum([d.credit for d in entries]))
|
supplier_credit_amount = flt(sum([d.credit for d in entries]))
|
||||||
|
|
||||||
vouchers = [d.voucher_no for d in entries]
|
vouchers = [d.voucher_no for d in entries]
|
||||||
vouchers += get_advance_vouchers(supplier, company=company,
|
vouchers += get_advance_vouchers([supplier], company=company,
|
||||||
from_date=from_date, to_date=to_date)
|
from_date=from_date, to_date=to_date)
|
||||||
|
|
||||||
tds_deducted = 0
|
tds_deducted = 0
|
||||||
@@ -89,7 +94,7 @@ def get_invoice_and_tds_amount(supplier, account, company, from_date, to_date):
|
|||||||
""".format(', '.join(["'%s'" % d for d in vouchers])),
|
""".format(', '.join(["'%s'" % d for d in vouchers])),
|
||||||
(account, from_date, to_date, company))[0][0])
|
(account, from_date, to_date, company))[0][0])
|
||||||
|
|
||||||
debit_note_amount = get_debit_note_amount(supplier, from_date, to_date, company=company)
|
debit_note_amount = get_debit_note_amount([supplier], from_date, to_date, company=company)
|
||||||
|
|
||||||
total_invoiced_amount = supplier_credit_amount + tds_deducted - debit_note_amount
|
total_invoiced_amount = supplier_credit_amount + tds_deducted - debit_note_amount
|
||||||
|
|
||||||
|
|||||||
@@ -126,7 +126,9 @@ def get_rootwise_opening_balances(filters, report_type):
|
|||||||
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
|
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
|
||||||
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
|
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
|
||||||
filters.get(dimension.fieldname))
|
filters.get(dimension.fieldname))
|
||||||
additional_conditions += "and {0} in %({0})s".format(dimension.fieldname)
|
additional_conditions += "and {0} in %({0})s".format(dimension.fieldname)
|
||||||
|
else:
|
||||||
|
additional_conditions += "and {0} in (%({0})s)".format(dimension.fieldname)
|
||||||
|
|
||||||
query_filters.update({
|
query_filters.update({
|
||||||
dimension.fieldname: filters.get(dimension.fieldname)
|
dimension.fieldname: filters.get(dimension.fieldname)
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
{
|
{
|
||||||
"cards": [
|
"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]",
|
"hidden": 0,
|
||||||
"title": "Crops & Lands"
|
"label": "Crops & Lands",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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]",
|
"hidden": 0,
|
||||||
"title": "Analytics"
|
"label": "Analytics",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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]",
|
"hidden": 0,
|
||||||
"title": "Diseases & Fertilizers"
|
"label": "Diseases & Fertilizers",
|
||||||
|
"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]"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"category": "Domains",
|
"category": "Domains",
|
||||||
@@ -24,7 +27,7 @@
|
|||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"label": "Agriculture",
|
"label": "Agriculture",
|
||||||
"modified": "2020-03-12 16:30:37.565413",
|
"modified": "2020-04-01 11:28:51.032822",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Agriculture",
|
"module": "Agriculture",
|
||||||
"name": "Agriculture",
|
"name": "Agriculture",
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
{
|
{
|
||||||
"cards": [
|
"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]",
|
"hidden": 0,
|
||||||
"title": "Assets"
|
"label": "Assets",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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]",
|
"hidden": 0,
|
||||||
"title": "Maintenance"
|
"label": "Maintenance",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"icon": "fa fa-table",
|
"hidden": 0,
|
||||||
"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]",
|
"label": "Reports",
|
||||||
"title": "Reports"
|
"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]"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"category": "Modules",
|
"category": "Modules",
|
||||||
@@ -26,7 +28,7 @@
|
|||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"label": "Assets",
|
"label": "Assets",
|
||||||
"modified": "2020-03-12 16:30:38.651019",
|
"modified": "2020-04-01 11:28:51.072198",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Assets",
|
"module": "Assets",
|
||||||
"name": "Assets",
|
"name": "Assets",
|
||||||
@@ -35,17 +37,17 @@
|
|||||||
"pin_to_top": 0,
|
"pin_to_top": 0,
|
||||||
"shortcuts": [
|
"shortcuts": [
|
||||||
{
|
{
|
||||||
"is_query_report": 0,
|
"label": "Asset",
|
||||||
"link_to": "Asset",
|
"link_to": "Asset",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"is_query_report": 0,
|
"label": "Asset Movement",
|
||||||
"link_to": "Asset Movement",
|
"link_to": "Asset Movement",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"is_query_report": 0,
|
"label": "Fixed Asset Register",
|
||||||
"link_to": "Fixed Asset Register",
|
"link_to": "Fixed Asset Register",
|
||||||
"type": "Report"
|
"type": "Report"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,12 +11,34 @@ from frappe.model.document import Document
|
|||||||
class AssetCategory(Document):
|
class AssetCategory(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_finance_books()
|
self.validate_finance_books()
|
||||||
|
self.validate_accounts()
|
||||||
|
|
||||||
def validate_finance_books(self):
|
def validate_finance_books(self):
|
||||||
for d in self.finance_books:
|
for d in self.finance_books:
|
||||||
for field in ("Total Number of Depreciations", "Frequency of Depreciation"):
|
for field in ("Total Number of Depreciations", "Frequency of Depreciation"):
|
||||||
if cint(d.get(frappe.scrub(field)))<1:
|
if cint(d.get(frappe.scrub(field)))<1:
|
||||||
frappe.throw(_("Row {0}: {1} must be greater than 0").format(d.idx, field), frappe.MandatoryError)
|
frappe.throw(_("Row {0}: {1} must be greater than 0").format(d.idx, field), frappe.MandatoryError)
|
||||||
|
|
||||||
|
def validate_accounts(self):
|
||||||
|
account_type_map = {
|
||||||
|
'fixed_asset_account': { 'account_type': 'Fixed Asset' },
|
||||||
|
'accumulated_depreciation_account': { 'account_type': 'Accumulated Depreciation' },
|
||||||
|
'depreciation_expense_account': { 'root_type': 'Expense' },
|
||||||
|
'capital_work_in_progress_account': { 'account_type': 'Capital Work in Progress' }
|
||||||
|
}
|
||||||
|
for d in self.accounts:
|
||||||
|
for fieldname in account_type_map.keys():
|
||||||
|
if d.get(fieldname):
|
||||||
|
selected_account = d.get(fieldname)
|
||||||
|
key_to_match = next(iter(account_type_map.get(fieldname))) # acount_type or root_type
|
||||||
|
selected_key_type = frappe.db.get_value('Account', selected_account, key_to_match)
|
||||||
|
expected_key_type = account_type_map[fieldname][key_to_match]
|
||||||
|
|
||||||
|
if selected_key_type != expected_key_type:
|
||||||
|
frappe.throw(_("Row #{}: {} of {} should be {}. Please modify the account or select a different account.")
|
||||||
|
.format(d.idx, frappe.unscrub(key_to_match), frappe.bold(selected_account), frappe.bold(expected_key_type)),
|
||||||
|
title=_("Invalid Account"))
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_asset_category_account(fieldname, item=None, asset=None, account=None, asset_category = None, company = None):
|
def get_asset_category_account(fieldname, item=None, asset=None, account=None, asset_category = None, company = None):
|
||||||
|
|||||||
@@ -24,26 +24,6 @@ frappe.ui.form.on('Asset Maintenance', {
|
|||||||
return indicator;
|
return indicator;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
frm.set_query('select_serial_no', function(doc){
|
|
||||||
return {
|
|
||||||
asset: frm.doc.asset_name
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
select_serial_no: (frm) => {
|
|
||||||
let serial_nos = frm.doc.serial_no || frm.doc.select_serial_no;
|
|
||||||
if (serial_nos) {
|
|
||||||
serial_nos = serial_nos.split('\n');
|
|
||||||
serial_nos.push(frm.doc.select_serial_no);
|
|
||||||
|
|
||||||
const unique_sn = serial_nos.filter(function(elem, index, self) {
|
|
||||||
return index === self.indexOf(elem);
|
|
||||||
});
|
|
||||||
|
|
||||||
frm.set_value("serial_no", unique_sn.join('\n'));
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: (frm) => {
|
refresh: (frm) => {
|
||||||
@@ -93,25 +73,6 @@ frappe.ui.form.on('Asset Maintenance Task', {
|
|||||||
},
|
},
|
||||||
end_date: (frm, cdt, cdn) => {
|
end_date: (frm, cdt, cdn) => {
|
||||||
get_next_due_date(frm, cdt, cdn);
|
get_next_due_date(frm, cdt, cdn);
|
||||||
},
|
|
||||||
assign_to: (frm, cdt, cdn) => {
|
|
||||||
var d = locals[cdt][cdn];
|
|
||||||
if (frm.doc.__islocal) {
|
|
||||||
frappe.model.set_value(cdt, cdn, "assign_to", "");
|
|
||||||
frappe.model.set_value(cdt, cdn, "assign_to_name", "");
|
|
||||||
frappe.throw(__("Please save before assigning task."));
|
|
||||||
}
|
|
||||||
if (d.assign_to) {
|
|
||||||
return frappe.call({
|
|
||||||
method: 'erpnext.assets.doctype.asset_maintenance.asset_maintenance.assign_tasks',
|
|
||||||
args: {
|
|
||||||
asset_maintenance_name: frm.doc.name,
|
|
||||||
assign_to_member: d.assign_to,
|
|
||||||
maintenance_task: d.maintenance_task,
|
|
||||||
next_due_date: d.next_due_date
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -16,12 +16,11 @@ class AssetMaintenance(Document):
|
|||||||
throw(_("Start date should be less than end date for task {0}").format(task.maintenance_task))
|
throw(_("Start date should be less than end date for task {0}").format(task.maintenance_task))
|
||||||
if getdate(task.next_due_date) < getdate(nowdate()):
|
if getdate(task.next_due_date) < getdate(nowdate()):
|
||||||
task.maintenance_status = "Overdue"
|
task.maintenance_status = "Overdue"
|
||||||
|
if not task.assign_to and self.docstatus == 0:
|
||||||
|
throw(_("Row #{}: Please asign task to a member.").format(task.idx))
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
for task in self.get('asset_maintenance_tasks'):
|
for task in self.get('asset_maintenance_tasks'):
|
||||||
if not task.assign_to:
|
|
||||||
task.db_set("assign_to", self.maintenance_manager)
|
|
||||||
task.db_set("assign_to_name", self.maintenance_manager_name)
|
|
||||||
assign_tasks(self.name, task.assign_to, task.maintenance_task, task.next_due_date)
|
assign_tasks(self.name, task.assign_to, task.maintenance_task, task.next_due_date)
|
||||||
self.sync_maintenance_tasks()
|
self.sync_maintenance_tasks()
|
||||||
|
|
||||||
@@ -108,7 +107,7 @@ def update_maintenance_log(asset_maintenance, item_code, item_name, task):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_team_members(doctype, txt, searchfield, start, page_len, filters):
|
def get_team_members(doctype, txt, searchfield, start, page_len, filters):
|
||||||
return frappe.db.get_values('Maintenance Team Member', {'parent':filters.get("maintenance_team")})
|
return frappe.db.get_values('Maintenance Team Member', { 'parent': filters.get("maintenance_team") })
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_maintenance_log(asset_name):
|
def get_maintenance_log(asset_name):
|
||||||
|
|||||||
@@ -125,13 +125,15 @@ def get_maintenance_tasks():
|
|||||||
"start_date": nowdate(),
|
"start_date": nowdate(),
|
||||||
"periodicity": "Monthly",
|
"periodicity": "Monthly",
|
||||||
"maintenance_type": "Preventive Maintenance",
|
"maintenance_type": "Preventive Maintenance",
|
||||||
"maintenance_status": "Planned"
|
"maintenance_status": "Planned",
|
||||||
|
"assign_to": "marcus@abc.com"
|
||||||
},
|
},
|
||||||
{"maintenance_task": "Check Gears",
|
{"maintenance_task": "Check Gears",
|
||||||
"start_date": nowdate(),
|
"start_date": nowdate(),
|
||||||
"periodicity": "Yearly",
|
"periodicity": "Yearly",
|
||||||
"maintenance_type": "Calibration",
|
"maintenance_type": "Calibration",
|
||||||
"maintenance_status": "Planned"
|
"maintenance_status": "Planned",
|
||||||
|
"assign_to": "thalia@abc.com"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -1,44 +1,46 @@
|
|||||||
{
|
{
|
||||||
"cards": [
|
"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]",
|
"hidden": 0,
|
||||||
"title": "Supplier"
|
"label": "Supplier",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"icon": "fa fa-star",
|
"hidden": 0,
|
||||||
"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]",
|
"label": "Purchasing",
|
||||||
"title": "Purchasing"
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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]",
|
"hidden": 0,
|
||||||
"title": "Items and Pricing"
|
"label": "Items and Pricing",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"icon": "fa fa-cog",
|
"hidden": 0,
|
||||||
"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]",
|
"label": "Settings",
|
||||||
"title": "Settings"
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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]",
|
"hidden": 0,
|
||||||
"title": "Supplier Scorecard"
|
"label": "Supplier Scorecard",
|
||||||
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"icon": "fa fa-table",
|
"hidden": 0,
|
||||||
"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]",
|
"label": "Key Reports",
|
||||||
"title": "Key Reports"
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"icon": "fa fa-list",
|
"hidden": 0,
|
||||||
"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]",
|
"label": "Other Reports",
|
||||||
"title": "Other Reports"
|
"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]"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"category": "Modules",
|
"category": "Modules",
|
||||||
"charts": [
|
"charts": [
|
||||||
{
|
{
|
||||||
"chart_name": "Expenses",
|
"chart_name": "Expenses",
|
||||||
"label": "Expenses",
|
"label": "Expenses"
|
||||||
"size": "Full"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"creation": "2020-01-28 11:50:26.195467",
|
"creation": "2020-01-28 11:50:26.195467",
|
||||||
@@ -51,7 +53,7 @@
|
|||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"label": "Buying",
|
"label": "Buying",
|
||||||
"modified": "2020-03-12 16:30:40.779078",
|
"modified": "2020-04-01 11:28:51.192097",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Buying",
|
"name": "Buying",
|
||||||
@@ -61,30 +63,30 @@
|
|||||||
"shortcuts": [
|
"shortcuts": [
|
||||||
{
|
{
|
||||||
"format": "{} Unpaid",
|
"format": "{} Unpaid",
|
||||||
"is_query_report": 0,
|
"label": "Purchase Invoice",
|
||||||
"link_to": "Purchase Invoice",
|
"link_to": "Purchase Invoice",
|
||||||
"stats_filter": "{\n \"company\": [\"like\", '%' + frappe.defaults.get_global_default(\"company\") + '%'],\n \"status\": \"Unpaid\"\n}",
|
"stats_filter": "{\n \"company\": [\"like\", '%' + frappe.defaults.get_global_default(\"company\") + '%'],\n \"status\": \"Unpaid\"\n}",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"format": "{} to receive",
|
"format": "{} to receive",
|
||||||
"is_query_report": 0,
|
"label": "Purchase Order",
|
||||||
"link_to": "Purchase Order",
|
"link_to": "Purchase Order",
|
||||||
"stats_filter": "{\n \"company\": [\"like\", '%' + frappe.defaults.get_global_default(\"company\") + '%'],\n \"status\": \"To Receive\"\n}",
|
"stats_filter": "{\n \"company\": [\"like\", '%' + frappe.defaults.get_global_default(\"company\") + '%'],\n \"status\": \"To Receive\"\n}",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"is_query_report": 0,
|
"label": "Supplier Quotation",
|
||||||
"link_to": "Supplier Quotation",
|
"link_to": "Supplier Quotation",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"is_query_report": 0,
|
"label": "Accounts Payable",
|
||||||
"link_to": "Accounts Payable",
|
"link_to": "Accounts Payable",
|
||||||
"type": "Report"
|
"type": "Report"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"is_query_report": 0,
|
"label": "Purchase Register",
|
||||||
"link_to": "Purchase Register",
|
"link_to": "Purchase Register",
|
||||||
"type": "Report"
|
"type": "Report"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,15 +27,6 @@ frappe.ui.form.on("Purchase Order", {
|
|||||||
frm.set_indicator_formatter('item_code',
|
frm.set_indicator_formatter('item_code',
|
||||||
function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" })
|
function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" })
|
||||||
|
|
||||||
frm.set_query("blanket_order", "items", function() {
|
|
||||||
return {
|
|
||||||
filters: {
|
|
||||||
"company": frm.doc.company,
|
|
||||||
"docstatus": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
frm.set_query("expense_account", "items", function() {
|
frm.set_query("expense_account", "items", function() {
|
||||||
return {
|
return {
|
||||||
query: "erpnext.controllers.queries.get_expense_account",
|
query: "erpnext.controllers.queries.get_expense_account",
|
||||||
@@ -365,9 +356,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
|||||||
method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order",
|
method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order",
|
||||||
source_doctype: "Material Request",
|
source_doctype: "Material Request",
|
||||||
target: me.frm,
|
target: me.frm,
|
||||||
setters: {
|
setters: {},
|
||||||
company: me.frm.doc.company
|
|
||||||
},
|
|
||||||
get_query_filters: {
|
get_query_filters: {
|
||||||
material_request_type: "Purchase",
|
material_request_type: "Purchase",
|
||||||
docstatus: 1,
|
docstatus: 1,
|
||||||
@@ -384,7 +373,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
|||||||
source_doctype: "Supplier Quotation",
|
source_doctype: "Supplier Quotation",
|
||||||
target: me.frm,
|
target: me.frm,
|
||||||
setters: {
|
setters: {
|
||||||
company: me.frm.doc.company
|
supplier: me.frm.doc.supplier
|
||||||
},
|
},
|
||||||
get_query_filters: {
|
get_query_filters: {
|
||||||
docstatus: 1,
|
docstatus: 1,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
"creation": "2013-05-21 16:16:39",
|
"creation": "2013-05-21 16:16:39",
|
||||||
@@ -53,19 +54,19 @@
|
|||||||
"items_section",
|
"items_section",
|
||||||
"scan_barcode",
|
"scan_barcode",
|
||||||
"items",
|
"items",
|
||||||
"section_break_48",
|
|
||||||
"pricing_rules",
|
|
||||||
"raw_material_details",
|
|
||||||
"set_reserve_warehouse",
|
|
||||||
"supplied_items",
|
|
||||||
"sb_last_purchase",
|
"sb_last_purchase",
|
||||||
"total_qty",
|
"total_qty",
|
||||||
"base_total",
|
"base_total",
|
||||||
"base_net_total",
|
"base_net_total",
|
||||||
"column_break_26",
|
"column_break_26",
|
||||||
|
"total_net_weight",
|
||||||
"total",
|
"total",
|
||||||
"net_total",
|
"net_total",
|
||||||
"total_net_weight",
|
"section_break_48",
|
||||||
|
"pricing_rules",
|
||||||
|
"raw_material_details",
|
||||||
|
"set_reserve_warehouse",
|
||||||
|
"supplied_items",
|
||||||
"taxes_section",
|
"taxes_section",
|
||||||
"tax_category",
|
"tax_category",
|
||||||
"column_break_50",
|
"column_break_50",
|
||||||
@@ -104,23 +105,25 @@
|
|||||||
"payment_schedule_section",
|
"payment_schedule_section",
|
||||||
"payment_terms_template",
|
"payment_terms_template",
|
||||||
"payment_schedule",
|
"payment_schedule",
|
||||||
|
"tracking_section",
|
||||||
|
"per_billed",
|
||||||
|
"column_break_75",
|
||||||
|
"per_received",
|
||||||
"terms_section_break",
|
"terms_section_break",
|
||||||
"tc_name",
|
"tc_name",
|
||||||
"terms",
|
"terms",
|
||||||
"more_info",
|
"more_info",
|
||||||
"status",
|
"status",
|
||||||
"ref_sq",
|
"ref_sq",
|
||||||
|
"column_break_74",
|
||||||
"party_account_currency",
|
"party_account_currency",
|
||||||
"inter_company_order_reference",
|
"inter_company_order_reference",
|
||||||
"column_break_74",
|
|
||||||
"per_received",
|
|
||||||
"per_billed",
|
|
||||||
"column_break5",
|
"column_break5",
|
||||||
"letter_head",
|
"letter_head",
|
||||||
"select_print_heading",
|
"select_print_heading",
|
||||||
"column_break_86",
|
"column_break_86",
|
||||||
"group_same_items",
|
|
||||||
"language",
|
"language",
|
||||||
|
"group_same_items",
|
||||||
"subscription_section",
|
"subscription_section",
|
||||||
"from_date",
|
"from_date",
|
||||||
"to_date",
|
"to_date",
|
||||||
@@ -170,8 +173,8 @@
|
|||||||
"search_index": 1
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Fetch items based on Default Supplier.",
|
|
||||||
"depends_on": "eval:doc.supplier && doc.docstatus===0 && (!(doc.items && doc.items.length) || (doc.items.length==1 && !doc.items[0].item_code))",
|
"depends_on": "eval:doc.supplier && doc.docstatus===0 && (!(doc.items && doc.items.length) || (doc.items.length==1 && !doc.items[0].item_code))",
|
||||||
|
"description": "Fetch items based on Default Supplier.",
|
||||||
"fieldname": "get_items_from_open_material_requests",
|
"fieldname": "get_items_from_open_material_requests",
|
||||||
"fieldtype": "Button",
|
"fieldtype": "Button",
|
||||||
"label": "Get Items from Open Material Requests"
|
"label": "Get Items from Open Material Requests"
|
||||||
@@ -219,7 +222,7 @@
|
|||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"fieldname": "schedule_date",
|
"fieldname": "schedule_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Reqd By Date"
|
"label": "Required By"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
@@ -431,6 +434,7 @@
|
|||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"description": "Sets 'Warehouse' in each row of the Items table.",
|
||||||
"fieldname": "set_warehouse",
|
"fieldname": "set_warehouse",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Set Target Warehouse",
|
"label": "Set Target Warehouse",
|
||||||
@@ -826,6 +830,7 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"collapsible": 1,
|
||||||
"fieldname": "payment_schedule_section",
|
"fieldname": "payment_schedule_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Payment Terms"
|
"label": "Payment Terms"
|
||||||
@@ -916,7 +921,8 @@
|
|||||||
"fieldname": "inter_company_order_reference",
|
"fieldname": "inter_company_order_reference",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Inter Company Order Reference",
|
"label": "Inter Company Order Reference",
|
||||||
"options": "Sales Order"
|
"options": "Sales Order",
|
||||||
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_74",
|
"fieldname": "column_break_74",
|
||||||
@@ -929,8 +935,6 @@
|
|||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "% Received",
|
"label": "% Received",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldname": "per_received",
|
|
||||||
"oldfieldtype": "Currency",
|
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
@@ -941,8 +945,6 @@
|
|||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "% Billed",
|
"label": "% Billed",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldname": "per_billed",
|
|
||||||
"oldfieldtype": "Currency",
|
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
@@ -997,6 +999,7 @@
|
|||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"collapsible": 1,
|
||||||
"fieldname": "subscription_section",
|
"fieldname": "subscription_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Subscription Section"
|
"label": "Subscription Section"
|
||||||
@@ -1049,12 +1052,23 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Set Reserve Warehouse",
|
"label": "Set Reserve Warehouse",
|
||||||
"options": "Warehouse"
|
"options": "Warehouse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collapsible": 1,
|
||||||
|
"fieldname": "tracking_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Tracking"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_75",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 105,
|
"idx": 105,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2020-01-14 18:54:39.694448",
|
"links": [],
|
||||||
|
"modified": "2020-04-24 12:13:14.186280",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order",
|
"name": "Purchase Order",
|
||||||
|
|||||||
@@ -18,10 +18,6 @@
|
|||||||
"col_break1",
|
"col_break1",
|
||||||
"image",
|
"image",
|
||||||
"image_view",
|
"image_view",
|
||||||
"manufacture_details",
|
|
||||||
"manufacturer",
|
|
||||||
"column_break_14",
|
|
||||||
"manufacturer_part_no",
|
|
||||||
"quantity_and_rate",
|
"quantity_and_rate",
|
||||||
"qty",
|
"qty",
|
||||||
"stock_uom",
|
"stock_uom",
|
||||||
@@ -44,7 +40,6 @@
|
|||||||
"base_amount",
|
"base_amount",
|
||||||
"pricing_rules",
|
"pricing_rules",
|
||||||
"is_free_item",
|
"is_free_item",
|
||||||
"is_fixed_asset",
|
|
||||||
"section_break_29",
|
"section_break_29",
|
||||||
"net_rate",
|
"net_rate",
|
||||||
"net_amount",
|
"net_amount",
|
||||||
@@ -52,11 +47,6 @@
|
|||||||
"base_net_rate",
|
"base_net_rate",
|
||||||
"base_net_amount",
|
"base_net_amount",
|
||||||
"billed_amt",
|
"billed_amt",
|
||||||
"item_weight_details",
|
|
||||||
"weight_per_unit",
|
|
||||||
"total_weight",
|
|
||||||
"column_break_40",
|
|
||||||
"weight_uom",
|
|
||||||
"warehouse_and_reference",
|
"warehouse_and_reference",
|
||||||
"warehouse",
|
"warehouse",
|
||||||
"delivered_by_supplier",
|
"delivered_by_supplier",
|
||||||
@@ -80,20 +70,31 @@
|
|||||||
"column_break_60",
|
"column_break_60",
|
||||||
"received_qty",
|
"received_qty",
|
||||||
"returned_qty",
|
"returned_qty",
|
||||||
|
"manufacture_details",
|
||||||
|
"manufacturer",
|
||||||
|
"column_break_14",
|
||||||
|
"manufacturer_part_no",
|
||||||
|
"more_info_section_break",
|
||||||
|
"is_fixed_asset",
|
||||||
|
"item_tax_rate",
|
||||||
"accounting_details",
|
"accounting_details",
|
||||||
"expense_account",
|
"expense_account",
|
||||||
"column_break_68",
|
"column_break_68",
|
||||||
|
"item_weight_details",
|
||||||
|
"weight_per_unit",
|
||||||
|
"total_weight",
|
||||||
|
"column_break_40",
|
||||||
|
"weight_uom",
|
||||||
"accounting_dimensions_section",
|
"accounting_dimensions_section",
|
||||||
"cost_center",
|
"cost_center",
|
||||||
"dimension_col_break",
|
"dimension_col_break",
|
||||||
"section_break_72",
|
"section_break_72",
|
||||||
"page_break",
|
"page_break"
|
||||||
"item_tax_rate"
|
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"bold": 1,
|
"bold": 1,
|
||||||
"columns": 3,
|
"columns": 2,
|
||||||
"fieldname": "item_code",
|
"fieldname": "item_code",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@@ -133,7 +134,7 @@
|
|||||||
"fieldname": "schedule_date",
|
"fieldname": "schedule_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Reqd By Date",
|
"label": "Required By",
|
||||||
"oldfieldname": "schedule_date",
|
"oldfieldname": "schedule_date",
|
||||||
"oldfieldtype": "Date",
|
"oldfieldtype": "Date",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
@@ -216,15 +217,16 @@
|
|||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"columns": 1,
|
||||||
"fieldname": "uom",
|
"fieldname": "uom",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
"label": "UOM",
|
"label": "UOM",
|
||||||
"oldfieldname": "uom",
|
"oldfieldname": "uom",
|
||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "UOM",
|
"options": "UOM",
|
||||||
"print_width": "100px",
|
"print_width": "100px",
|
||||||
"reqd": 1,
|
"reqd": 1
|
||||||
"width": "100px"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "conversion_factor",
|
"fieldname": "conversion_factor",
|
||||||
@@ -685,6 +687,7 @@
|
|||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"collapsible": 1,
|
||||||
"fieldname": "manufacture_details",
|
"fieldname": "manufacture_details",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Manufacture"
|
"label": "Manufacture"
|
||||||
@@ -702,8 +705,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "manufacturer_part_no",
|
"fieldname": "manufacturer_part_no",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Manufacturer Part Number",
|
"label": "Manufacturer Part Number"
|
||||||
"read_only": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
@@ -718,12 +720,17 @@
|
|||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Is Fixed Asset",
|
"label": "Is Fixed Asset",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "more_info_section_break",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "More Information"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2019-12-06 13:17:12.142799",
|
"modified": "2020-04-21 11:55:58.643393",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order Item",
|
"name": "Purchase Order Item",
|
||||||
|
|||||||
@@ -1,20 +1,26 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"creation": "2013-02-22 01:27:42",
|
"creation": "2013-02-22 01:27:42",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"main_item_code",
|
"main_item_code",
|
||||||
"rm_item_code",
|
|
||||||
"required_qty",
|
|
||||||
"supplied_qty",
|
|
||||||
"rate",
|
|
||||||
"amount",
|
|
||||||
"column_break_6",
|
|
||||||
"bom_detail_no",
|
"bom_detail_no",
|
||||||
"reference_name",
|
|
||||||
"conversion_factor",
|
|
||||||
"stock_uom",
|
"stock_uom",
|
||||||
"reserve_warehouse"
|
"conversion_factor",
|
||||||
|
"column_break_6",
|
||||||
|
"rm_item_code",
|
||||||
|
"reference_name",
|
||||||
|
"reserve_warehouse",
|
||||||
|
"section_break2",
|
||||||
|
"rate",
|
||||||
|
"col_break2",
|
||||||
|
"amount",
|
||||||
|
"section_break1",
|
||||||
|
"required_qty",
|
||||||
|
"col_break1",
|
||||||
|
"supplied_qty"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -120,15 +126,34 @@
|
|||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Supplied Qty",
|
"label": "Supplied Qty",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "section_break1",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "col_break1",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "section_break2",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "col_break2",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"hide_toolbar": 1,
|
"hide_toolbar": 1,
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2019-08-20 13:37:32.702068",
|
"links": [],
|
||||||
|
"modified": "2020-03-12 15:43:53.862897",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order Item Supplied",
|
"name": "Purchase Order Item Supplied",
|
||||||
"owner": "dhanalekshmi@webnotestech.com",
|
"owner": "dhanalekshmi@webnotestech.com",
|
||||||
"permissions": []
|
"permissions": [],
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC"
|
||||||
}
|
}
|
||||||
@@ -1,24 +1,31 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"creation": "2013-02-22 01:27:42",
|
"creation": "2013-02-22 01:27:42",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"main_item_code",
|
"main_item_code",
|
||||||
"rm_item_code",
|
|
||||||
"description",
|
"description",
|
||||||
"batch_no",
|
"bom_detail_no",
|
||||||
"serial_no",
|
|
||||||
"col_break1",
|
"col_break1",
|
||||||
"required_qty",
|
"rm_item_code",
|
||||||
"consumed_qty",
|
|
||||||
"stock_uom",
|
"stock_uom",
|
||||||
"rate",
|
|
||||||
"amount",
|
|
||||||
"conversion_factor",
|
"conversion_factor",
|
||||||
"current_stock",
|
|
||||||
"reference_name",
|
"reference_name",
|
||||||
"bom_detail_no"
|
"secbreak_1",
|
||||||
|
"rate",
|
||||||
|
"col_break2",
|
||||||
|
"amount",
|
||||||
|
"secbreak_2",
|
||||||
|
"required_qty",
|
||||||
|
"col_break3",
|
||||||
|
"consumed_qty",
|
||||||
|
"current_stock",
|
||||||
|
"secbreak_3",
|
||||||
|
"batch_no",
|
||||||
|
"col_break4",
|
||||||
|
"serial_no"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -152,11 +159,36 @@
|
|||||||
"oldfieldname": "bom_detail_no",
|
"oldfieldname": "bom_detail_no",
|
||||||
"oldfieldtype": "Data",
|
"oldfieldtype": "Data",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "secbreak_1",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "col_break2",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "secbreak_2",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "col_break3",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "secbreak_3",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "col_break4",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2019-11-21 16:25:29.909112",
|
"links": [],
|
||||||
|
"modified": "2020-04-10 18:09:33.997618",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Receipt Item Supplied",
|
"name": "Purchase Receipt Item Supplied",
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
"supplier_type",
|
"supplier_type",
|
||||||
"pan",
|
"pan",
|
||||||
"language",
|
"language",
|
||||||
|
"allow_purchase_invoice_creation_without_purchase_order",
|
||||||
|
"allow_purchase_invoice_creation_without_purchase_receipt",
|
||||||
"disabled",
|
"disabled",
|
||||||
"warn_rfqs",
|
"warn_rfqs",
|
||||||
"warn_pos",
|
"warn_pos",
|
||||||
@@ -364,13 +366,25 @@
|
|||||||
"fieldname": "is_frozen",
|
"fieldname": "is_frozen",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Is Frozen"
|
"label": "Is Frozen"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "allow_purchase_invoice_creation_without_purchase_order",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Allow Purchase Invoice Creation Without Purchase Order"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "allow_purchase_invoice_creation_without_purchase_receipt",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Allow Purchase Invoice Creation Without Purchase Receipt"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-user",
|
"icon": "fa fa-user",
|
||||||
"idx": 370,
|
"idx": 370,
|
||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2019-12-19 18:17:16.614567",
|
"modified": "2020-03-17 09:48:30.578242",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Supplier",
|
"name": "Supplier",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"autoname": "hash",
|
"autoname": "hash",
|
||||||
"creation": "2013-05-22 12:43:10",
|
"creation": "2013-05-22 12:43:10",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@@ -522,8 +523,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "manufacturer_part_no",
|
"fieldname": "manufacturer_part_no",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Manufacturer Part Number",
|
"label": "Manufacturer Part Number"
|
||||||
"read_only": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_15",
|
"fieldname": "column_break_15",
|
||||||
@@ -532,7 +532,8 @@
|
|||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2019-06-02 05:32:46.019237",
|
"links": [],
|
||||||
|
"modified": "2020-04-07 18:35:51.175947",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Supplier Quotation Item",
|
"name": "Supplier Quotation Item",
|
||||||
|
|||||||
@@ -141,19 +141,18 @@ def get_conditions(filters):
|
|||||||
conditions = ""
|
conditions = ""
|
||||||
|
|
||||||
if filters.get("company"):
|
if filters.get("company"):
|
||||||
conditions += " AND company=%s"% frappe.db.escape(filters.get('company'))
|
conditions += " AND par.company=%s" % frappe.db.escape(filters.get('company'))
|
||||||
|
|
||||||
if filters.get("cost_center") or filters.get("project"):
|
if filters.get("cost_center") or filters.get("project"):
|
||||||
conditions += """
|
conditions += """
|
||||||
AND (cost_center=%s
|
AND (child.`cost_center`=%s OR child.`project`=%s)
|
||||||
OR project=%s)
|
""" % (frappe.db.escape(filters.get('cost_center')), frappe.db.escape(filters.get('project')))
|
||||||
"""% (frappe.db.escape(filters.get('cost_center')), frappe.db.escape(filters.get('project')))
|
|
||||||
|
|
||||||
if filters.get("from_date"):
|
if filters.get("from_date"):
|
||||||
conditions += " AND transaction_date>=%s"% filters.get('from_date')
|
conditions += " AND par.transaction_date>='%s'" % filters.get('from_date')
|
||||||
|
|
||||||
if filters.get("to_date"):
|
if filters.get("to_date"):
|
||||||
conditions += " AND transaction_date<=%s"% filters.get('to_date')
|
conditions += " AND par.transaction_date<='%s'" % filters.get('to_date')
|
||||||
return conditions
|
return conditions
|
||||||
|
|
||||||
def get_data(filters):
|
def get_data(filters):
|
||||||
@@ -162,7 +161,6 @@ def get_data(filters):
|
|||||||
mr_records, procurement_record_against_mr = get_mapped_mr_details(conditions)
|
mr_records, procurement_record_against_mr = get_mapped_mr_details(conditions)
|
||||||
pr_records = get_mapped_pr_records()
|
pr_records = get_mapped_pr_records()
|
||||||
pi_records = get_mapped_pi_records()
|
pi_records = get_mapped_pi_records()
|
||||||
print(pi_records)
|
|
||||||
|
|
||||||
procurement_record=[]
|
procurement_record=[]
|
||||||
if procurement_record_against_mr:
|
if procurement_record_against_mr:
|
||||||
@@ -198,16 +196,16 @@ def get_mapped_mr_details(conditions):
|
|||||||
mr_records = {}
|
mr_records = {}
|
||||||
mr_details = frappe.db.sql("""
|
mr_details = frappe.db.sql("""
|
||||||
SELECT
|
SELECT
|
||||||
mr.transaction_date,
|
par.transaction_date,
|
||||||
mr.per_ordered,
|
par.per_ordered,
|
||||||
mr_item.name,
|
child.name,
|
||||||
mr_item.parent,
|
child.parent,
|
||||||
mr_item.amount
|
child.amount
|
||||||
FROM `tabMaterial Request` mr, `tabMaterial Request Item` mr_item
|
FROM `tabMaterial Request` par, `tabMaterial Request Item` child
|
||||||
WHERE
|
WHERE
|
||||||
mr.per_ordered>=0
|
par.per_ordered>=0
|
||||||
AND mr.name=mr_item.parent
|
AND par.name=child.parent
|
||||||
AND mr.docstatus=1
|
AND par.docstatus=1
|
||||||
{conditions}
|
{conditions}
|
||||||
""".format(conditions=conditions), as_dict=1) #nosec
|
""".format(conditions=conditions), as_dict=1) #nosec
|
||||||
|
|
||||||
@@ -254,29 +252,29 @@ def get_mapped_pr_records():
|
|||||||
def get_po_entries(conditions):
|
def get_po_entries(conditions):
|
||||||
return frappe.db.sql("""
|
return frappe.db.sql("""
|
||||||
SELECT
|
SELECT
|
||||||
po_item.name,
|
child.name,
|
||||||
po_item.parent,
|
child.parent,
|
||||||
po_item.cost_center,
|
child.cost_center,
|
||||||
po_item.project,
|
child.project,
|
||||||
po_item.warehouse,
|
child.warehouse,
|
||||||
po_item.material_request,
|
child.material_request,
|
||||||
po_item.material_request_item,
|
child.material_request_item,
|
||||||
po_item.description,
|
child.description,
|
||||||
po_item.stock_uom,
|
child.stock_uom,
|
||||||
po_item.qty,
|
child.qty,
|
||||||
po_item.amount,
|
child.amount,
|
||||||
po_item.base_amount,
|
child.base_amount,
|
||||||
po_item.schedule_date,
|
child.schedule_date,
|
||||||
po.transaction_date,
|
par.transaction_date,
|
||||||
po.supplier,
|
par.supplier,
|
||||||
po.status,
|
par.status,
|
||||||
po.owner
|
par.owner
|
||||||
FROM `tabPurchase Order` po, `tabPurchase Order Item` po_item
|
FROM `tabPurchase Order` par, `tabPurchase Order Item` child
|
||||||
WHERE
|
WHERE
|
||||||
po.docstatus = 1
|
par.docstatus = 1
|
||||||
AND po.name = po_item.parent
|
AND par.name = child.parent
|
||||||
AND po.status not in ("Closed","Completed","Cancelled")
|
AND par.status not in ("Closed","Completed","Cancelled")
|
||||||
{conditions}
|
{conditions}
|
||||||
GROUP BY
|
GROUP BY
|
||||||
po.name,po_item.item_code
|
par.name, child.item_code
|
||||||
""".format(conditions=conditions), as_dict=1) #nosec
|
""".format(conditions=conditions), as_dict=1) #nosec
|
||||||
@@ -2,131 +2,68 @@ from __future__ import unicode_literals
|
|||||||
from frappe import _
|
from frappe import _
|
||||||
|
|
||||||
def get_data():
|
def get_data():
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
|
||||||
"label": _("Consultation"),
|
|
||||||
"icon": "icon-star",
|
|
||||||
"items": [
|
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Patient Appointment",
|
|
||||||
"label": _("Patient Appointment"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Patient Encounter",
|
|
||||||
"label": _("Patient Encounter"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Vital Signs",
|
|
||||||
"label": _("Vital Signs"),
|
|
||||||
"description": _("Record Patient Vitals"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "page",
|
|
||||||
"name": "patient_history",
|
|
||||||
"label": _("Patient History"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "page",
|
|
||||||
"name": "appointment-analytic",
|
|
||||||
"label": _("Appointment Analytics"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Clinical Procedure",
|
|
||||||
"label": _("Clinical Procedure"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Inpatient Record",
|
|
||||||
"label": _("Inpatient Record"),
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": _("Laboratory"),
|
|
||||||
"icon": "icon-list",
|
|
||||||
"items": [
|
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Lab Test",
|
|
||||||
"label": _("Lab Test"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Sample Collection",
|
|
||||||
"label": _("Sample Collection"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "report",
|
|
||||||
"name": "Lab Test Report",
|
|
||||||
"is_query_report": True,
|
|
||||||
"label": _("Lab Test Report"),
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"label": _("Masters"),
|
"label": _("Masters"),
|
||||||
"icon": "icon-list",
|
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Patient",
|
"name": "Patient",
|
||||||
"label": _("Patient"),
|
"label": _("Patient"),
|
||||||
"onboard": 1,
|
"onboard": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Healthcare Practitioner",
|
"name": "Healthcare Practitioner",
|
||||||
"label": _("Healthcare Practitioner"),
|
"label": _("Healthcare Practitioner"),
|
||||||
"onboard": 1,
|
"onboard": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Practitioner Schedule",
|
"name": "Practitioner Schedule",
|
||||||
"label": _("Practitioner Schedule"),
|
"label": _("Practitioner Schedule"),
|
||||||
},
|
"onboard": 1
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Medical Code Standard",
|
|
||||||
"label": _("Medical Code Standard"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Medical Code",
|
|
||||||
"label": _("Medical Code"),
|
|
||||||
"onboard": 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Healthcare Service Unit",
|
|
||||||
"label": _("Healthcare Service Unit")
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": _("Settings"),
|
|
||||||
"icon": "icon-cog",
|
|
||||||
"items": [
|
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Healthcare Settings",
|
|
||||||
"label": _("Healthcare Settings"),
|
|
||||||
"onboard": 1,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Medical Department",
|
"name": "Medical Department",
|
||||||
"label": _("Medical Department"),
|
"label": _("Medical Department"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Healthcare Service Unit Type",
|
||||||
|
"label": _("Healthcare Service Unit Type")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Healthcare Service Unit",
|
||||||
|
"label": _("Healthcare Service Unit")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Medical Code Standard",
|
||||||
|
"label": _("Medical Code Standard")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Medical Code",
|
||||||
|
"label": _("Medical Code")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Consultation Setup"),
|
||||||
|
"items": [
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Appointment Type",
|
"name": "Appointment Type",
|
||||||
"label": _("Appointment Type"),
|
"label": _("Appointment Type"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Clinical Procedure Template",
|
||||||
|
"label": _("Clinical Procedure Template")
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Prescription Dosage",
|
"name": "Prescription Dosage",
|
||||||
@@ -137,6 +74,36 @@ def get_data():
|
|||||||
"name": "Prescription Duration",
|
"name": "Prescription Duration",
|
||||||
"label": _("Prescription Duration")
|
"label": _("Prescription Duration")
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Antibiotic",
|
||||||
|
"label": _("Antibiotic")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Consultation"),
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Patient Appointment",
|
||||||
|
"label": _("Patient Appointment")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Clinical Procedure",
|
||||||
|
"label": _("Clinical Procedure")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Patient Encounter",
|
||||||
|
"label": _("Patient Encounter")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Vital Signs",
|
||||||
|
"label": _("Vital Signs")
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Complaint",
|
"name": "Complaint",
|
||||||
@@ -147,40 +114,140 @@ def get_data():
|
|||||||
"name": "Diagnosis",
|
"name": "Diagnosis",
|
||||||
"label": _("Diagnosis")
|
"label": _("Diagnosis")
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Fee Validity",
|
||||||
|
"label": _("Fee Validity")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Settings"),
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Healthcare Settings",
|
||||||
|
"label": _("Healthcare Settings"),
|
||||||
|
"onboard": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Laboratory Setup"),
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Lab Test Template",
|
||||||
|
"label": _("Lab Test Template")
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Lab Test Sample",
|
"name": "Lab Test Sample",
|
||||||
"label": _("Lab Test Sample"),
|
"label": _("Lab Test Sample")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Lab Test UOM",
|
"name": "Lab Test UOM",
|
||||||
"label": _("Lab Test UOM")
|
"label": _("Lab Test UOM")
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Antibiotic",
|
|
||||||
"label": _("Antibiotic")
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Sensitivity",
|
"name": "Sensitivity",
|
||||||
"label": _("Sensitivity")
|
"label": _("Sensitivity")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Laboratory"),
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Lab Test",
|
||||||
|
"label": _("Lab Test")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Lab Test Template",
|
"name": "Sample Collection",
|
||||||
"label": _("Lab Test Template")
|
"label": _("Sample Collection")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Clinical Procedure Template",
|
"name": "Dosage Form",
|
||||||
"label": _("Clinical Procedure Template"),
|
"label": _("Dosage Form")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Records and History"),
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "page",
|
||||||
|
"name": "patient_history",
|
||||||
|
"label": _("Patient History"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Healthcare Service Unit Type",
|
"name": "Patient Medical Record",
|
||||||
"label": _("Healthcare Service Unit Type")
|
"label": _("Patient Medical Record")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Inpatient Record",
|
||||||
|
"label": _("Inpatient Record")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Reports"),
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "report",
|
||||||
|
"is_query_report": True,
|
||||||
|
"name": "Patient Appointment Analytics",
|
||||||
|
"doctype": "Patient Appointment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "report",
|
||||||
|
"is_query_report": True,
|
||||||
|
"name": "Lab Test Report",
|
||||||
|
"doctype": "Lab Test",
|
||||||
|
"label": _("Lab Test Report")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Rehabilitation"),
|
||||||
|
"icon": "icon-cog",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Exercise Type",
|
||||||
|
"label": _("Exercise Type")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Exercise Difficulty Level",
|
||||||
|
"label": _("Exercise Difficulty Level")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Therapy Type",
|
||||||
|
"label": _("Therapy Type")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Therapy Plan",
|
||||||
|
"label": _("Therapy Plan")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Therapy Session",
|
||||||
|
"label": _("Therapy Session")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Motor Assessment Scale",
|
||||||
|
"label": _("Motor Assessment Scale")
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ from erpnext.accounts.doctype.pricing_rule.utils import (apply_pricing_rule_on_t
|
|||||||
from erpnext.exceptions import InvalidCurrency
|
from erpnext.exceptions import InvalidCurrency
|
||||||
from six import text_type
|
from six import text_type
|
||||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
||||||
|
from erpnext.stock.get_item_details import get_item_warehouse
|
||||||
|
|
||||||
force_item_fields = ("item_group", "brand", "stock_uom", "is_fixed_asset", "item_tax_rate", "pricing_rules")
|
force_item_fields = ("item_group", "brand", "stock_uom", "is_fixed_asset", "item_tax_rate", "pricing_rules")
|
||||||
|
|
||||||
@@ -438,7 +439,7 @@ class AccountsController(TransactionBase):
|
|||||||
|
|
||||||
if account_currency not in valid_currency:
|
if account_currency not in valid_currency:
|
||||||
frappe.throw(_("Account {0} is invalid. Account Currency must be {1}")
|
frappe.throw(_("Account {0} is invalid. Account Currency must be {1}")
|
||||||
.format(account, _(" or ").join(valid_currency)))
|
.format(account, (' ' + _("or") + ' ').join(valid_currency)))
|
||||||
|
|
||||||
def clear_unallocated_advances(self, childtype, parentfield):
|
def clear_unallocated_advances(self, childtype, parentfield):
|
||||||
self.set(parentfield, self.get(parentfield, {"allocated_amount": ["not in", [0, None, ""]]}))
|
self.set(parentfield, self.get(parentfield, {"allocated_amount": ["not in", [0, None, ""]]}))
|
||||||
@@ -818,7 +819,7 @@ class AccountsController(TransactionBase):
|
|||||||
else:
|
else:
|
||||||
for d in self.get("payment_schedule"):
|
for d in self.get("payment_schedule"):
|
||||||
if d.invoice_portion:
|
if d.invoice_portion:
|
||||||
d.payment_amount = grand_total * flt(d.invoice_portion) / 100
|
d.payment_amount = flt(grand_total * flt(d.invoice_portion) / 100, d.precision('payment_amount'))
|
||||||
|
|
||||||
def set_due_date(self):
|
def set_due_date(self):
|
||||||
due_dates = [d.due_date for d in self.get("payment_schedule") if d.due_date]
|
due_dates = [d.due_date for d in self.get("payment_schedule") if d.due_date]
|
||||||
@@ -833,7 +834,7 @@ class AccountsController(TransactionBase):
|
|||||||
|
|
||||||
for d in self.get("payment_schedule"):
|
for d in self.get("payment_schedule"):
|
||||||
if self.doctype == "Sales Order" and getdate(d.due_date) < getdate(self.transaction_date):
|
if self.doctype == "Sales Order" and getdate(d.due_date) < getdate(self.transaction_date):
|
||||||
frappe.throw(_("Row {0}: Due Date cannot be before posting date").format(d.idx))
|
frappe.throw(_("Row {0}: Due Date in the Payment Terms table cannot be before Posting Date").format(d.idx))
|
||||||
elif d.due_date in dates:
|
elif d.due_date in dates:
|
||||||
li.append(_("{0} in row {1}").format(d.due_date, d.idx))
|
li.append(_("{0} in row {1}").format(d.due_date, d.idx))
|
||||||
dates.append(d.due_date)
|
dates.append(d.due_date)
|
||||||
@@ -1122,36 +1123,39 @@ def get_supplier_block_status(party_name):
|
|||||||
}
|
}
|
||||||
return info
|
return info
|
||||||
|
|
||||||
def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_code):
|
def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, trans_item):
|
||||||
"""
|
"""
|
||||||
Returns a Sales Order Item child item containing the default values
|
Returns a Sales Order Item child item containing the default values
|
||||||
"""
|
"""
|
||||||
p_doctype = frappe.get_doc(parent_doctype, parent_doctype_name)
|
p_doc = frappe.get_doc(parent_doctype, parent_doctype_name)
|
||||||
child_item = frappe.new_doc('Sales Order Item', p_doctype, child_docname)
|
child_item = frappe.new_doc('Sales Order Item', p_doc, child_docname)
|
||||||
item = frappe.get_doc("Item", item_code)
|
item = frappe.get_doc("Item", trans_item.get('item_code'))
|
||||||
child_item.item_code = item.item_code
|
child_item.item_code = item.item_code
|
||||||
child_item.item_name = item.item_name
|
child_item.item_name = item.item_name
|
||||||
child_item.description = item.description
|
child_item.description = item.description
|
||||||
child_item.reqd_by_date = p_doctype.delivery_date
|
child_item.delivery_date = trans_item.get('delivery_date') or p_doc.delivery_date
|
||||||
child_item.uom = item.stock_uom
|
child_item.uom = item.stock_uom
|
||||||
child_item.conversion_factor = get_conversion_factor(item_code, item.stock_uom).get("conversion_factor") or 1.0
|
child_item.conversion_factor = get_conversion_factor(item.item_code, item.stock_uom).get("conversion_factor") or 1.0
|
||||||
child_item.warehouse = p_doctype.set_warehouse or p_doctype.items[0].warehouse
|
child_item.warehouse = get_item_warehouse(item, p_doc, overwrite_warehouse=True)
|
||||||
|
if not child_item.warehouse:
|
||||||
|
frappe.throw(_("Cannot find {} for item {}. Please set the same in Item Master or Stock Settings.")
|
||||||
|
.format(frappe.bold("default warehouse"), frappe.bold(item.item_code)))
|
||||||
return child_item
|
return child_item
|
||||||
|
|
||||||
|
|
||||||
def set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_code):
|
def set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, trans_item):
|
||||||
"""
|
"""
|
||||||
Returns a Purchase Order Item child item containing the default values
|
Returns a Purchase Order Item child item containing the default values
|
||||||
"""
|
"""
|
||||||
p_doctype = frappe.get_doc(parent_doctype, parent_doctype_name)
|
p_doc = frappe.get_doc(parent_doctype, parent_doctype_name)
|
||||||
child_item = frappe.new_doc('Purchase Order Item', p_doctype, child_docname)
|
child_item = frappe.new_doc('Purchase Order Item', p_doc, child_docname)
|
||||||
item = frappe.get_doc("Item", item_code)
|
item = frappe.get_doc("Item", trans_item.get('item_code'))
|
||||||
child_item.item_code = item.item_code
|
child_item.item_code = item.item_code
|
||||||
child_item.item_name = item.item_name
|
child_item.item_name = item.item_name
|
||||||
child_item.description = item.description
|
child_item.description = item.description
|
||||||
child_item.schedule_date = p_doctype.schedule_date
|
child_item.schedule_date = trans_item.get('schedule_date') or p_doc.schedule_date
|
||||||
child_item.uom = item.stock_uom
|
child_item.uom = item.stock_uom
|
||||||
child_item.conversion_factor = get_conversion_factor(item_code, item.stock_uom).get("conversion_factor") or 1.0
|
child_item.conversion_factor = get_conversion_factor(item.item_code, item.stock_uom).get("conversion_factor") or 1.0
|
||||||
child_item.base_rate = 1 # Initiallize value will update in parent validation
|
child_item.base_rate = 1 # Initiallize value will update in parent validation
|
||||||
child_item.base_amount = 1 # Initiallize value will update in parent validation
|
child_item.base_amount = 1 # Initiallize value will update in parent validation
|
||||||
return child_item
|
return child_item
|
||||||
@@ -1195,9 +1199,9 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
|||||||
if not d.get("docname"):
|
if not d.get("docname"):
|
||||||
new_child_flag = True
|
new_child_flag = True
|
||||||
if parent_doctype == "Sales Order":
|
if parent_doctype == "Sales Order":
|
||||||
child_item = set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, d.get("item_code"))
|
child_item = set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, d)
|
||||||
if parent_doctype == "Purchase Order":
|
if parent_doctype == "Purchase Order":
|
||||||
child_item = set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, d.get("item_code"))
|
child_item = set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, d)
|
||||||
else:
|
else:
|
||||||
child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname"))
|
child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname"))
|
||||||
if flt(child_item.get("rate")) == flt(d.get("rate")) and flt(child_item.get("qty")) == flt(d.get("qty")):
|
if flt(child_item.get("rate")) == flt(d.get("rate")) and flt(child_item.get("qty")) == flt(d.get("qty")):
|
||||||
@@ -1242,6 +1246,7 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
|||||||
|
|
||||||
child_item.flags.ignore_validate_update_after_submit = True
|
child_item.flags.ignore_validate_update_after_submit = True
|
||||||
if new_child_flag:
|
if new_child_flag:
|
||||||
|
parent.load_from_db()
|
||||||
child_item.idx = len(parent.items) + 1
|
child_item.idx = len(parent.items) + 1
|
||||||
child_item.insert()
|
child_item.insert()
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ class BuyingController(StockController):
|
|||||||
self.validate_warehouse()
|
self.validate_warehouse()
|
||||||
self.validate_from_warehouse()
|
self.validate_from_warehouse()
|
||||||
self.set_supplier_address()
|
self.set_supplier_address()
|
||||||
|
self.validate_asset_return()
|
||||||
|
|
||||||
if self.doctype=="Purchase Invoice":
|
if self.doctype=="Purchase Invoice":
|
||||||
self.validate_purchase_receipt_if_update_stock()
|
self.validate_purchase_receipt_if_update_stock()
|
||||||
@@ -100,6 +101,19 @@ class BuyingController(StockController):
|
|||||||
for d in tax_for_valuation:
|
for d in tax_for_valuation:
|
||||||
d.category = 'Total'
|
d.category = 'Total'
|
||||||
msgprint(_('Tax Category has been changed to "Total" because all the Items are non-stock items'))
|
msgprint(_('Tax Category has been changed to "Total" because all the Items are non-stock items'))
|
||||||
|
|
||||||
|
def validate_asset_return(self):
|
||||||
|
if self.doctype not in ['Purchase Receipt', 'Purchase Invoice'] or not self.is_return:
|
||||||
|
return
|
||||||
|
|
||||||
|
purchase_doc_field = 'purchase_receipt' if self.doctype == 'Purchase Receipt' else 'purchase_invoice'
|
||||||
|
not_cancelled_asset = [d.name for d in frappe.db.get_all("Asset", {
|
||||||
|
purchase_doc_field: self.return_against,
|
||||||
|
"docstatus": 1
|
||||||
|
})]
|
||||||
|
if self.is_return and len(not_cancelled_asset):
|
||||||
|
frappe.throw(_("{} has submitted assets linked to it. You need to cancel the assets to create purchase return.".format(self.return_against)),
|
||||||
|
title=_("Not Allowed"))
|
||||||
|
|
||||||
def get_asset_items(self):
|
def get_asset_items(self):
|
||||||
if self.doctype not in ['Purchase Order', 'Purchase Invoice', 'Purchase Receipt']:
|
if self.doctype not in ['Purchase Order', 'Purchase Invoice', 'Purchase Receipt']:
|
||||||
|
|||||||
@@ -179,6 +179,12 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
|
|||||||
# scan description only if items are less than 50000
|
# scan description only if items are less than 50000
|
||||||
description_cond = 'or tabItem.description LIKE %(txt)s'
|
description_cond = 'or tabItem.description LIKE %(txt)s'
|
||||||
|
|
||||||
|
extra_cond = " and tabItem.has_variants=0"
|
||||||
|
if (filters and isinstance(filters, dict)
|
||||||
|
and filters.get("doctype") == "BOM"):
|
||||||
|
extra_cond = ""
|
||||||
|
del filters["doctype"]
|
||||||
|
|
||||||
return frappe.db.sql("""select tabItem.name,
|
return frappe.db.sql("""select tabItem.name,
|
||||||
if(length(tabItem.item_name) > 40,
|
if(length(tabItem.item_name) > 40,
|
||||||
concat(substr(tabItem.item_name, 1, 40), "..."), item_name) as item_name,
|
concat(substr(tabItem.item_name, 1, 40), "..."), item_name) as item_name,
|
||||||
@@ -188,11 +194,11 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
|
|||||||
{columns}
|
{columns}
|
||||||
from tabItem
|
from tabItem
|
||||||
where tabItem.docstatus < 2
|
where tabItem.docstatus < 2
|
||||||
and tabItem.has_variants=0
|
|
||||||
and tabItem.disabled=0
|
and tabItem.disabled=0
|
||||||
and (tabItem.end_of_life > %(today)s or ifnull(tabItem.end_of_life, '0000-00-00')='0000-00-00')
|
and (tabItem.end_of_life > %(today)s or ifnull(tabItem.end_of_life, '0000-00-00')='0000-00-00')
|
||||||
and ({scond} or tabItem.item_code IN (select parent from `tabItem Barcode` where barcode LIKE %(txt)s)
|
and ({scond} or tabItem.item_code IN (select parent from `tabItem Barcode` where barcode LIKE %(txt)s)
|
||||||
{description_cond})
|
{description_cond})
|
||||||
|
{extra_cond}
|
||||||
{fcond} {mcond}
|
{fcond} {mcond}
|
||||||
order by
|
order by
|
||||||
if(locate(%(_txt)s, name), locate(%(_txt)s, name), 99999),
|
if(locate(%(_txt)s, name), locate(%(_txt)s, name), 99999),
|
||||||
@@ -203,6 +209,7 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
|
|||||||
key=searchfield,
|
key=searchfield,
|
||||||
columns=columns,
|
columns=columns,
|
||||||
scond=searchfields,
|
scond=searchfields,
|
||||||
|
extra_cond=extra_cond,
|
||||||
fcond=get_filters_cond(doctype, filters, conditions).replace('%', '%%'),
|
fcond=get_filters_cond(doctype, filters, conditions).replace('%', '%%'),
|
||||||
mcond=get_match_cond(doctype).replace('%', '%%'),
|
mcond=get_match_cond(doctype).replace('%', '%%'),
|
||||||
description_cond = description_cond),
|
description_cond = description_cond),
|
||||||
@@ -364,6 +371,19 @@ def get_account_list(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
fields = ["name", "parent_account"],
|
fields = ["name", "parent_account"],
|
||||||
limit_start=start, limit_page_length=page_len, as_list=True)
|
limit_start=start, limit_page_length=page_len, as_list=True)
|
||||||
|
|
||||||
|
def get_blanket_orders(doctype, txt, searchfield, start, page_len, filters):
|
||||||
|
return frappe.db.sql("""select distinct bo.name, bo.blanket_order_type, bo.to_date
|
||||||
|
from `tabBlanket Order` bo, `tabBlanket Order Item` boi
|
||||||
|
where
|
||||||
|
boi.parent = bo.name
|
||||||
|
and boi.item_code = {item_code}
|
||||||
|
and bo.blanket_order_type = '{blanket_order_type}'
|
||||||
|
and bo.company = {company}
|
||||||
|
and bo.docstatus = 1"""
|
||||||
|
.format(item_code = frappe.db.escape(filters.get("item")),
|
||||||
|
blanket_order_type = filters.get("blanket_order_type"),
|
||||||
|
company = frappe.db.escape(filters.get("company"))
|
||||||
|
))
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_income_account(doctype, txt, searchfield, start, page_len, filters):
|
def get_income_account(doctype, txt, searchfield, start, page_len, filters):
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ class SellingController(StockController):
|
|||||||
set_default_income_account_for_item(self)
|
set_default_income_account_for_item(self)
|
||||||
self.set_customer_address()
|
self.set_customer_address()
|
||||||
self.validate_for_duplicate_items()
|
self.validate_for_duplicate_items()
|
||||||
|
self.validate_target_warehouse()
|
||||||
|
|
||||||
def set_missing_values(self, for_validate=False):
|
def set_missing_values(self, for_validate=False):
|
||||||
|
|
||||||
@@ -403,6 +404,14 @@ class SellingController(StockController):
|
|||||||
else:
|
else:
|
||||||
chk_dupl_itm.append(f)
|
chk_dupl_itm.append(f)
|
||||||
|
|
||||||
|
def validate_target_warehouse(self):
|
||||||
|
items = self.get("items") + (self.get("packed_items") or [])
|
||||||
|
|
||||||
|
for d in items:
|
||||||
|
if d.get("target_warehouse") and d.get("warehouse") == d.get("target_warehouse"):
|
||||||
|
warehouse = frappe.bold(d.get("target_warehouse"))
|
||||||
|
frappe.throw(_("Row {0}: Delivery Warehouse ({1}) and Customer Warehouse ({2}) can not be same")
|
||||||
|
.format(d.idx, warehouse, warehouse))
|
||||||
|
|
||||||
def validate_items(self):
|
def validate_items(self):
|
||||||
# validate items to see if they have is_sales_item enabled
|
# validate items to see if they have is_sales_item enabled
|
||||||
|
|||||||
@@ -69,16 +69,16 @@ status_map = {
|
|||||||
["Cancelled", "eval:self.docstatus==2"],
|
["Cancelled", "eval:self.docstatus==2"],
|
||||||
["Closed", "eval:self.status=='Closed'"],
|
["Closed", "eval:self.status=='Closed'"],
|
||||||
],
|
],
|
||||||
"Purchase Invoice": [
|
"Purchase Invoice": [
|
||||||
["Draft", None],
|
["Draft", None],
|
||||||
["Submitted", "eval:self.docstatus==1"],
|
["Submitted", "eval:self.docstatus==1"],
|
||||||
["Paid", "eval:self.outstanding_amount==0 and self.docstatus==1"],
|
["Paid", "eval:self.outstanding_amount==0 and self.docstatus==1"],
|
||||||
["Return", "eval:self.is_return==1 and self.docstatus==1"],
|
["Return", "eval:self.is_return==1 and self.docstatus==1"],
|
||||||
["Debit Note Issued",
|
["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})"],
|
"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"],
|
["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"],
|
["Overdue", "eval:self.outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()) and self.docstatus==1"],
|
||||||
["Cancelled", "eval:self.docstatus==2"],
|
["Cancelled", "eval:self.docstatus==2"],
|
||||||
],
|
],
|
||||||
"Material Request": [
|
"Material Request": [
|
||||||
["Draft", None],
|
["Draft", None],
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe, erpnext
|
import frappe, erpnext
|
||||||
from frappe.utils import cint, flt, cstr
|
from frappe.utils import cint, flt, cstr, get_link_to_form, today, getdate
|
||||||
from frappe import _
|
from frappe import _
|
||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
from erpnext.accounts.utils import get_fiscal_year
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
@@ -21,6 +21,7 @@ class StockController(AccountsController):
|
|||||||
super(StockController, self).validate()
|
super(StockController, self).validate()
|
||||||
self.validate_inspection()
|
self.validate_inspection()
|
||||||
self.validate_serialized_batch()
|
self.validate_serialized_batch()
|
||||||
|
self.validate_customer_provided_item()
|
||||||
|
|
||||||
def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False):
|
def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False):
|
||||||
if self.docstatus == 2:
|
if self.docstatus == 2:
|
||||||
@@ -54,6 +55,13 @@ class StockController(AccountsController):
|
|||||||
frappe.throw(_("Row #{0}: Serial No {1} does not belong to Batch {2}")
|
frappe.throw(_("Row #{0}: Serial No {1} does not belong to Batch {2}")
|
||||||
.format(d.idx, serial_no_data.name, d.batch_no))
|
.format(d.idx, serial_no_data.name, d.batch_no))
|
||||||
|
|
||||||
|
if d.qty > 0 and d.get("batch_no") and self.get("posting_date") and self.docstatus < 2:
|
||||||
|
expiry_date = frappe.get_cached_value("Batch", d.get("batch_no"), "expiry_date")
|
||||||
|
|
||||||
|
if expiry_date and getdate(expiry_date) < getdate(self.posting_date):
|
||||||
|
frappe.throw(_("Row #{0}: The batch {1} has already expired.")
|
||||||
|
.format(d.idx, get_link_to_form("Batch", d.get("batch_no"))))
|
||||||
|
|
||||||
def get_gl_entries(self, warehouse_account=None, default_expense_account=None,
|
def get_gl_entries(self, warehouse_account=None, default_expense_account=None,
|
||||||
default_cost_center=None):
|
default_cost_center=None):
|
||||||
|
|
||||||
@@ -377,6 +385,12 @@ class StockController(AccountsController):
|
|||||||
for blanket_order in blanket_orders:
|
for blanket_order in blanket_orders:
|
||||||
frappe.get_doc("Blanket Order", blanket_order).update_ordered_qty()
|
frappe.get_doc("Blanket Order", blanket_order).update_ordered_qty()
|
||||||
|
|
||||||
|
def validate_customer_provided_item(self):
|
||||||
|
for d in self.get('items'):
|
||||||
|
# Customer Provided parts will have zero valuation rate
|
||||||
|
if frappe.db.get_value('Item', d.item_code, 'is_customer_provided_item'):
|
||||||
|
d.allow_zero_valuation_rate = 1
|
||||||
|
|
||||||
def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None,
|
def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None,
|
||||||
warehouse_account=None, company=None):
|
warehouse_account=None, company=None):
|
||||||
def _delete_gl_entries(voucher_type, voucher_no):
|
def _delete_gl_entries(voucher_type, voucher_no):
|
||||||
|
|||||||
@@ -667,8 +667,7 @@ def get_itemised_tax_breakup_html(doc):
|
|||||||
itemised_tax=itemised_tax,
|
itemised_tax=itemised_tax,
|
||||||
itemised_taxable_amount=itemised_taxable_amount,
|
itemised_taxable_amount=itemised_taxable_amount,
|
||||||
tax_accounts=tax_accounts,
|
tax_accounts=tax_accounts,
|
||||||
conversion_rate=doc.conversion_rate,
|
doc=doc
|
||||||
currency=doc.currency
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class TestMapper(unittest.TestCase):
|
|||||||
'''Test mapping of multiple source docs on a single target doc'''
|
'''Test mapping of multiple source docs on a single target doc'''
|
||||||
|
|
||||||
make_test_records("Item")
|
make_test_records("Item")
|
||||||
items = frappe.get_all("Item", fields = ["name", "item_code"], filters = {'is_sales_item': 1, 'has_variants': 0})
|
items = frappe.get_all("Item", fields = ["name", "item_code"], filters = {'is_sales_item': 1, 'has_variants': 0, 'disabled': 0})
|
||||||
customers = frappe.get_all("Customer")
|
customers = frappe.get_all("Customer")
|
||||||
if items and customers:
|
if items and customers:
|
||||||
# Make source docs (quotations) and a target doc (sales order)
|
# Make source docs (quotations) and a target doc (sales order)
|
||||||
|
|||||||
@@ -1,24 +1,29 @@
|
|||||||
{
|
{
|
||||||
"cards": [
|
"cards": [
|
||||||
{
|
{
|
||||||
"icon": "fa fa-star",
|
"hidden": 0,
|
||||||
"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]",
|
"label": "Sales Pipeline",
|
||||||
"title": "Sales Pipeline"
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"icon": "fa fa-list",
|
"hidden": 0,
|
||||||
"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]",
|
"label": "Reports",
|
||||||
"title": "Reports"
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"icon": "fa fa-cog",
|
"hidden": 0,
|
||||||
"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]",
|
"label": "Maintenance",
|
||||||
"title": "Settings"
|
"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]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"icon": "fa fa-star",
|
"hidden": 0,
|
||||||
"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]",
|
"label": "Campaign",
|
||||||
"title": "Maintenance"
|
"links": "[\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\": \"Create and Schedule social media posts\",\n \"label\": \"Social Media Post\",\n \"name\": \"Social Media Post\",\n \"type\": \"doctype\"\n }\n]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hidden": 0,
|
||||||
|
"label": "Settings",
|
||||||
|
"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\": \"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 {\n \"label\": \"Twitter Settings\",\n \"name\": \"Twitter Settings\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"LinkedIn Settings\",\n \"name\": \"LinkedIn Settings\",\n \"type\": \"doctype\"\n }\n]"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"category": "Modules",
|
"category": "Modules",
|
||||||
@@ -33,7 +38,7 @@
|
|||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"label": "CRM",
|
"label": "CRM",
|
||||||
"modified": "2020-03-12 16:30:41.142037",
|
"modified": "2020-04-27 22:32:26.682911",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "CRM",
|
"name": "CRM",
|
||||||
@@ -42,26 +47,26 @@
|
|||||||
"pin_to_top": 0,
|
"pin_to_top": 0,
|
||||||
"shortcuts": [
|
"shortcuts": [
|
||||||
{
|
{
|
||||||
"format": "Open",
|
"format": "{} Open",
|
||||||
"is_query_report": 0,
|
"label": "Lead",
|
||||||
"link_to": "Lead",
|
"link_to": "Lead",
|
||||||
"stats_filter": "{\"status\":\"Open\"}",
|
"stats_filter": "{\"status\":\"Open\"}",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"format": "{} Assigned",
|
"format": "{} Assigned",
|
||||||
"is_query_report": 0,
|
"label": "Opportunity",
|
||||||
"link_to": "Opportunity",
|
"link_to": "Opportunity",
|
||||||
"stats_filter": "{\"_assign\": [\"like\", '%' + frappe.session.user + '%']}",
|
"stats_filter": "{\"_assign\": [\"like\", '%' + frappe.session.user + '%']}",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"is_query_report": 0,
|
"label": "Customer",
|
||||||
"link_to": "Customer",
|
"link_to": "Customer",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"is_query_report": 0,
|
"label": "Sales Analytics",
|
||||||
"link_to": "Sales Analytics",
|
"link_to": "Sales Analytics",
|
||||||
"type": "Report"
|
"type": "Report"
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user