diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 416aaf4454..a2dc172767 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '10.1.13' +__version__ = '10.1.14' def get_default_company(user=None): '''Get default company for user''' diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py index 21ddb10b4d..ee20a43d8d 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -78,6 +78,9 @@ class PaymentRequest(Document): controller = get_payment_gateway_controller(self.payment_gateway) controller.validate_transaction_currency(self.currency) + if hasattr(controller, 'validate_minimum_transaction_amount'): + controller.validate_minimum_transaction_amount(self.currency, self.grand_total) + return controller.get_payment_url(**{ "amount": flt(self.grand_total, self.precision("grand_total")), "title": data.company.encode("utf-8"), diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py index 83045eae4e..d6b12f1b47 100644 --- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py +++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py @@ -131,7 +131,7 @@ def get_serial_no_for_item(args): "name": args.name, "serial_no": args.serial_no }) - if args.get("parenttype") in ("Sales Invoice", "Delivery Note") and args.stock_qty > 0: + if args.get("parenttype") in ("Sales Invoice", "Delivery Note") and flt(args.stock_qty) > 0: item_details.serial_no = get_serial_no(args) return item_details diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 2bd14472f3..5b52bbba90 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -751,7 +751,7 @@ "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 1, + "read_only": 0, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, @@ -4683,7 +4683,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2018-03-13 15:19:54.711885", + "modified": "2018-03-16 15:19:54.711885", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", diff --git a/erpnext/accounts/print_format/gst_pos_invoice/gst_pos_invoice.json b/erpnext/accounts/print_format/gst_pos_invoice/gst_pos_invoice.json index 8d6cf3e2b6..2342f31976 100644 --- a/erpnext/accounts/print_format/gst_pos_invoice/gst_pos_invoice.json +++ b/erpnext/accounts/print_format/gst_pos_invoice/gst_pos_invoice.json @@ -7,10 +7,10 @@ "docstatus": 0, "doctype": "Print Format", "font": "Default", - "html": "\n\n

\n\t{{ doc.company }}
\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"
\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t{{ _(\"GSTIN\") }}:{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"
GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t
\n\t{{ doc.select_print_heading or _(\"Invoice\") }}
\n

\n

\n\t{{ _(\"Receipt No\") }}: {{ doc.name }}
\n\t{{ _(\"Date\") }}: {{ doc.get_formatted(\"posting_date\") }}
\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"
\", \" \") %}\n\t\t{{ _(\"Customer\") }}:
\n\t\t{{ doc.customer_name }}
\n\t\t{{ customer_address }}\n\t{% endif %}\n

\n\n
\n\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n\t\n\t\t{%- for item in doc.items -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endfor -%}\n\t\n
{{ _(\"Item\") }}{{ _(\"Qty\") }}{{ _(\"Amount\") }}
\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t
{{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t
{{ _(\"HSN/SAC\") }}: {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t
{{ _(\"Serial No\") }}: {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t
{{ item.qty }}
@ {{ item.rate }}
{{ item.get_formatted(\"amount\") }}
\n\n\t\n\t\t\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t\n\t\t\t\t\n\t\t\t{% else %}\n\t\t\t\t\n\t\t\t\t\n\t\t\t{% endif %}\n\t\t\n\t\t{%- for row in doc.taxes -%}\n\t\t {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t {%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endif -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- if doc.rounded_total -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endif -%}\n\t\n
\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t
\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t
\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t
\n\t\t\t\t{{ _(\"Grand Total\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t
\n\t\t\t\t{{ _(\"Rounded Total\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t
\n

Tax Breakup:

\n
\n\t{{ doc.other_charges_calculation }}\n
\n

{{ doc.terms or \"\" }}

\n

{{ _(\"Thank you, please visit again.\") }}

", + "html": "\n\n

\n\t{{ doc.company }}
\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"
\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t{{ _(\"GSTIN\") }}:{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"
GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t
\n\t{{ doc.select_print_heading or _(\"Invoice\") }}
\n

\n

\n\t{{ _(\"Receipt No\") }}: {{ doc.name }}
\n\t{{ _(\"Date\") }}: {{ doc.get_formatted(\"posting_date\") }}
\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"
\", \" \") %}\n\t\t{{ _(\"Customer\") }}:
\n\t\t{{ doc.customer_name }}
\n\t\t{{ customer_address }}\n\t{% endif %}\n

\n\n
\n\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n\t\n\t\t{%- for item in doc.items -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endfor -%}\n\t\n
{{ _(\"Item\") }}{{ _(\"Qty\") }}{{ _(\"Amount\") }}
\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t
{{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t
{{ _(\"HSN/SAC\") }}: {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t
{{ _(\"Serial No\") }}: {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t
{{ item.qty }}
@ {{ item.rate }}
{{ item.get_formatted(\"amount\") }}
\n\n\t\n\t\t\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t\n\t\t\t\t\n\t\t\t{% else %}\n\t\t\t\t\n\t\t\t\t\n\t\t\t{% endif %}\n\t\t\n\t\t{%- for row in doc.taxes -%}\n\t\t {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t {%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endif -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- if doc.rounded_total -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endif -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t{%- if doc.change_amount -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t{%- endif -%}\n\t\n
\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t
\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t
\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t
\n\t\t\t\t{{ _(\"Grand Total\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t
\n\t\t\t\t{{ _(\"Rounded Total\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t
\n\t\t\t\t{{ _(\"Paid Amount\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"paid_amount\") }}\n\t\t\t
\n\t\t\t\t{{ _(\"Change Amount\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"change_amount\") }}\n\t\t\t
\n

Tax Breakup:

\n
\n\t{{ doc.other_charges_calculation }}\n
\n

{{ doc.terms or \"\" }}

\n

{{ _(\"Thank you, please visit again.\") }}

", "idx": 0, "line_breaks": 0, - "modified": "2018-01-12 11:19:17.432600", + "modified": "2018-03-20 14:24:08.167930", "modified_by": "Administrator", "module": "Accounts", "name": "GST POS Invoice", diff --git a/erpnext/accounts/print_format/pos_invoice/pos_invoice.json b/erpnext/accounts/print_format/pos_invoice/pos_invoice.json index 1613462a49..0b15423bff 100644 --- a/erpnext/accounts/print_format/pos_invoice/pos_invoice.json +++ b/erpnext/accounts/print_format/pos_invoice/pos_invoice.json @@ -6,10 +6,10 @@ "doc_type": "Sales Invoice", "docstatus": 0, "doctype": "Print Format", - "html": "\n\n

\n\t{{ doc.company }}
\n\t{{ doc.select_print_heading or _(\"Invoice\") }}
\n

\n

\n\t{{ _(\"Receipt No\") }}: {{ doc.name }}
\n\t{{ _(\"Date\") }}: {{ doc.get_formatted(\"posting_date\") }}
\n\t{{ _(\"Customer\") }}: {{ doc.customer_name }}\n

\n\n
\n\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n\t\n\t\t{%- for item in doc.items -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endfor -%}\n\t\n
{{ _(\"Item\") }}{{ _(\"Qty\") }}{{ _(\"Amount\") }}
\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t
{{ item.item_name }}{%- endif -%}\n\t\t\t
{{ item.qty }}
@ {{ item.get_formatted(\"rate\") }}
{{ item.get_formatted(\"amount\") }}
\n\n\t\n\t\t\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t\n\t\t\t\t\n\t\t\t{% else %}\n\t\t\t\t\n\t\t\t\t\n\t\t\t{% endif %}\n\t\t\n\t\t{%- for row in doc.taxes -%}\n\t\t {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t {%- endif -%}\n\t\t{%- endfor -%}\n\n\t\t{%- if doc.discount_amount -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endif -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- if doc.rounded_total -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endif -%}\n\t\n
\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t
\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t
\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t
\n\t\t\t\t{{ _(\"Grand Total\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t
\n\t\t\t\t{{ _(\"Rounded Total\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t
\n
\n

{{ doc.terms or \"\" }}

\n

{{ _(\"Thank you, please visit again.\") }}

", + "html": "\n\n

\n\t{{ doc.company }}
\n\t{{ doc.select_print_heading or _(\"Invoice\") }}
\n

\n

\n\t{{ _(\"Receipt No\") }}: {{ doc.name }}
\n\t{{ _(\"Date\") }}: {{ doc.get_formatted(\"posting_date\") }}
\n\t{{ _(\"Customer\") }}: {{ doc.customer_name }}\n

\n\n
\n\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n\t\n\t\t{%- for item in doc.items -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endfor -%}\n\t\n
{{ _(\"Item\") }}{{ _(\"Qty\") }}{{ _(\"Amount\") }}
\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t
{{ item.item_name }}{%- endif -%}\n\t\t\t
{{ item.qty }}
@ {{ item.get_formatted(\"rate\") }}
{{ item.get_formatted(\"amount\") }}
\n\n\t\n\t\t\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t\n\t\t\t\t\n\t\t\t{% else %}\n\t\t\t\t\n\t\t\t\t\n\t\t\t{% endif %}\n\t\t\n\t\t{%- for row in doc.taxes -%}\n\t\t {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t {%- endif -%}\n\t\t{%- endfor -%}\n\n\t\t{%- if doc.discount_amount -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endif -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- if doc.rounded_total -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endif -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- if doc.change_amount -%}\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t{%- endif -%}\n\t\n
\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t
\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t
\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t
\n\t\t\t\t{{ _(\"Grand Total\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t
\n\t\t\t\t{{ _(\"Rounded Total\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t
\n\t\t\t\t{{ _(\"Paid Amount\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"paid_amount\") }}\n\t\t\t
\n\t\t\t\t\t{{ _(\"Change Amount\") }}\n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"change_amount\") }}\n\t\t\t\t
\n
\n

{{ doc.terms or \"\" }}

\n

{{ _(\"Thank you, please visit again.\") }}

", "idx": 1, "line_breaks": 0, - "modified": "2018-01-12 11:18:54.229254", + "modified": "2018-03-20 14:24:12.394354", "modified_by": "Administrator", "module": "Accounts", "name": "POS Invoice", diff --git a/erpnext/accounts/report/accounts_payable/accounts_payable.js b/erpnext/accounts/report/accounts_payable/accounts_payable.js index 0c24feb96d..63ef83263c 100644 --- a/erpnext/accounts/report/accounts_payable/accounts_payable.js +++ b/erpnext/accounts/report/accounts_payable/accounts_payable.js @@ -14,7 +14,13 @@ frappe.query_reports["Accounts Payable"] = { "fieldname":"supplier", "label": __("Supplier"), "fieldtype": "Link", - "options": "Supplier" + "options": "Supplier", + on_change: () => { + var supplier = frappe.query_report_filters_by_name.supplier.get_value(); + frappe.db.get_value('Supplier', supplier, "tax_id", function(value) { + frappe.query_report_filters_by_name.tax_id.set_value(value["tax_id"]); + }); + } }, { "fieldname":"report_date", @@ -52,6 +58,12 @@ frappe.query_reports["Accounts Payable"] = { "fieldtype": "Int", "default": "90", "reqd": 1 + }, + { + "fieldname":"tax_id", + "label": __("Tax Id"), + "fieldtype": "Data", + "hidden": 1 } ], onload: function(report) { diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html index d96fc996bc..10f326242b 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html @@ -13,6 +13,11 @@

{%= __(report.report_name) %}

{%= filters.customer || filters.supplier %}

+
+ {% if (filters.tax_id) { %} + {%= __("Tax Id: ")%} {%= filters.tax_id %} + {% } %} +
{%= __(filters.ageing_based_on) %} {%= __("Until") %} diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js index 67483984b9..f44ea448e7 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js @@ -14,7 +14,13 @@ frappe.query_reports["Accounts Receivable"] = { "fieldname":"customer", "label": __("Customer"), "fieldtype": "Link", - "options": "Customer" + "options": "Customer", + on_change: () => { + var customer = frappe.query_report_filters_by_name.customer.get_value(); + frappe.db.get_value('Customer', customer, "tax_id", function(value) { + frappe.query_report_filters_by_name.tax_id.set_value(value["tax_id"]); + }); + } }, { "fieldname":"customer_group", @@ -69,6 +75,12 @@ frappe.query_reports["Accounts Receivable"] = { "fieldname":"show_pdc_in_print", "label": __("Show PDC in Print"), "fieldtype": "Check", + }, + { + "fieldname":"tax_id", + "label": __("Tax Id"), + "fieldtype": "Data", + "hidden": 1 } ], diff --git a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py index 845a2c5362..08b24fb147 100644 --- a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py +++ b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals import frappe from frappe import _ +from frappe.utils import flt from erpnext.accounts.report.accounts_receivable.accounts_receivable import ReceivablePayableReport class AccountsReceivableSummary(ReceivablePayableReport): @@ -88,7 +89,8 @@ class AccountsReceivableSummary(ReceivablePayableReport): }) ) for k in party_total[d.party].keys(): - party_total[d.party][k] += d.get(k, 0) + if k != "currency": + party_total[d.party][k] += flt(d.get(k, 0)) party_total[d.party].currency = d.currency diff --git a/erpnext/accounts/report/general_ledger/general_ledger.html b/erpnext/accounts/report/general_ledger/general_ledger.html index 9e1b884e1a..880ac1d785 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.html +++ b/erpnext/accounts/report/general_ledger/general_ledger.html @@ -8,6 +8,13 @@ {%= filters.account %} {% } %}
+ +
+ {% if (filters.tax_id) { %} + {%= __("Tax Id: ")%} {%= filters.tax_id %} + {% } %} +
+
{%= dateutil.str_to_user(filters.from_date) %} {%= __("to") %} diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js index adefadd2db..631f8263fe 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.js +++ b/erpnext/accounts/report/general_ledger/general_ledger.js @@ -87,6 +87,12 @@ frappe.query_reports["General Ledger"] = { frappe.db.get_value(party_type, party, fieldname, function(value) { frappe.query_report_filters_by_name.party_name.set_value(value[fieldname]); }); + + if (party_type === "Customer" || party_type === "Supplier") { + frappe.db.get_value(party_type, party, "tax_id", function(value) { + frappe.query_report_filters_by_name.tax_id.set_value(value["tax_id"]); + }); + } } }, { @@ -95,6 +101,12 @@ frappe.query_reports["General Ledger"] = { "fieldtype": "Data", "hidden": 1 }, + { + "fieldname":"tax_id", + "label": __("Tax Id"), + "fieldtype": "Data", + "hidden": 1 + }, { "fieldname":"group_by_voucher", "label": __("Group by Voucher"), diff --git a/erpnext/accounts/report/purchase_register/purchase_register.py b/erpnext/accounts/report/purchase_register/purchase_register.py index 610475acfc..d300980cc5 100644 --- a/erpnext/accounts/report/purchase_register/purchase_register.py +++ b/erpnext/accounts/report/purchase_register/purchase_register.py @@ -43,7 +43,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum row += [ supplier_details.get(inv.supplier), # supplier_type - inv.credit_to, inv.mode_of_payment, ", ".join(project), + inv.tax_id, inv.credit_to, inv.mode_of_payment, ", ".join(project), inv.bill_no, inv.bill_date, inv.remarks, ", ".join(purchase_order), ", ".join(purchase_receipt), company_currency ] @@ -83,7 +83,7 @@ def get_columns(invoice_list, additional_table_columns): columns += additional_table_columns columns += [ - _("Supplier Type") + ":Link/Supplier Type:120", _("Payable Account") + ":Link/Account:120", + _("Supplier Type") + ":Link/Supplier Type:120", _("Tax Id") + "::80", _("Payable Account") + ":Link/Account:120", _("Mode of Payment") + ":Link/Mode of Payment:80", _("Project") + ":Link/Project:80", _("Bill No") + "::120", _("Bill Date") + ":Date:80", _("Remarks") + "::150", _("Purchase Order") + ":Link/Purchase Order:100", @@ -143,7 +143,7 @@ def get_invoices(filters, additional_query_columns): conditions = get_conditions(filters) return frappe.db.sql(""" select - name, posting_date, credit_to, supplier, supplier_name, bill_no, bill_date, + name, posting_date, credit_to, supplier, supplier_name, tax_id, bill_no, bill_date, remarks, base_net_total, base_grand_total, outstanding_amount, mode_of_payment {0} from `tabPurchase Invoice` diff --git a/erpnext/accounts/report/sales_register/sales_register.py b/erpnext/accounts/report/sales_register/sales_register.py index f74ccc7cd8..476551e0d6 100644 --- a/erpnext/accounts/report/sales_register/sales_register.py +++ b/erpnext/accounts/report/sales_register/sales_register.py @@ -47,6 +47,7 @@ def _execute(filters, additional_table_columns=None, additional_query_columns=No row +=[ inv.get("customer_group"), inv.get("territory"), + inv.get("tax_id"), inv.debit_to, ", ".join(mode_of_payments.get(inv.name, [])), inv.project, inv.owner, inv.remarks, ", ".join(sales_order), ", ".join(delivery_note),", ".join(cost_center), @@ -89,7 +90,7 @@ def get_columns(invoice_list, additional_table_columns): columns +=[ _("Customer Group") + ":Link/Customer Group:120", _("Territory") + ":Link/Territory:80", - _("Receivable Account") + ":Link/Account:120", _("Mode of Payment") + "::120", + _("Tax Id") + "::80", _("Receivable Account") + ":Link/Account:120", _("Mode of Payment") + "::120", _("Project") +":Link/Project:80", _("Owner") + "::150", _("Remarks") + "::150", _("Sales Order") + ":Link/Sales Order:100", _("Delivery Note") + ":Link/Delivery Note:100", _("Cost Center") + ":Link/Cost Center:100", _("Warehouse") + ":Link/Warehouse:100", @@ -161,7 +162,7 @@ def get_invoices(filters, additional_query_columns): conditions = get_conditions(filters) return frappe.db.sql(""" select name, posting_date, debit_to, project, customer, - customer_name, owner, remarks, territory, customer_group, + customer_name, owner, remarks, territory, tax_id, customer_group, base_net_total, base_grand_total, base_rounded_total, outstanding_amount {0} from `tabSales Invoice` where docstatus = 1 %s order by posting_date desc, name desc""".format(additional_query_columns or '') % diff --git a/erpnext/config/education.py b/erpnext/config/education.py index e4e77f36d6..5a05a258b2 100644 --- a/erpnext/config/education.py +++ b/erpnext/config/education.py @@ -135,6 +135,10 @@ def get_data(): "name": "Assessment Plan Status", "doctype": "Assessment Plan" }, + { + "type": "doctype", + "name": "Student Report Generation Tool" + } ] }, { diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index 606cc90866..2a22b32637 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -330,7 +330,7 @@ class SellingController(StockController): self.make_sl_entries(sl_entries) def set_po_nos(self): - if self.doctype in ("Delivery Note", "Sales Invoice"): + if self.doctype in ("Delivery Note", "Sales Invoice") and hasattr(self, "items"): ref_fieldname = "against_sales_order" if self.doctype == "Delivery Note" else "sales_order" sales_orders = list(set([d.get(ref_fieldname) for d in self.items if d.get(ref_fieldname)])) if sales_orders: diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py index df0fec833d..e8e851d513 100644 --- a/erpnext/controllers/status_updater.py +++ b/erpnext/controllers/status_updater.py @@ -285,7 +285,7 @@ class StatusUpdater(Document): ifnull((select ifnull(sum(if(%(target_ref_field)s > %(target_field)s, abs(%(target_field)s), abs(%(target_ref_field)s))), 0) / sum(abs(%(target_ref_field)s)) * 100 - from `tab%(target_dt)s` where parent="%(name)s"), 0), 2) + from `tab%(target_dt)s` where parent="%(name)s" having sum(abs(%(target_ref_field)s)) > 0), 0), 2) %(update_modified)s where name='%(name)s'""" % args) diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 605881c839..798d8e305d 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -252,7 +252,7 @@ class StockController(AccountsController): "company": self.company, "batch_no": cstr(d.get("batch_no")).strip(), "serial_no": d.get("serial_no"), - "project": d.get("project"), + "project": d.get("project") or self.get('project'), "is_cancelled": self.docstatus==2 and "Yes" or "No" }) diff --git a/erpnext/education/doctype/student/student.py b/erpnext/education/doctype/student/student.py index a830e5bdc0..841c2e88c4 100644 --- a/erpnext/education/doctype/student/student.py +++ b/erpnext/education/doctype/student/student.py @@ -22,14 +22,16 @@ class Student(Document): def update_student_name_in_linked_doctype(self): linked_doctypes = get_linked_doctypes("Student") for d in linked_doctypes: - if "student_name" in [f.fieldname for f in frappe.get_meta(d).fields]: - frappe.db.sql("""UPDATE `tab{0}` set student_name = %s where {1} = %s""" - .format(d, linked_doctypes[d]["fieldname"]),(self.title, self.name)) + meta = frappe.get_meta(d) + if not meta.issingle: + if "student_name" in [f.fieldname for f in meta.fields]: + frappe.db.sql("""UPDATE `tab{0}` set student_name = %s where {1} = %s""" + .format(d, linked_doctypes[d]["fieldname"]),(self.title, self.name)) - if "child_doctype" in linked_doctypes[d].keys() and "student_name" in \ - [f.fieldname for f in frappe.get_meta(linked_doctypes[d]["child_doctype"]).fields]: - frappe.db.sql("""UPDATE `tab{0}` set student_name = %s where {1} = %s""" - .format(linked_doctypes[d]["child_doctype"], linked_doctypes[d]["fieldname"]),(self.title, self.name)) + if "child_doctype" in linked_doctypes[d].keys() and "student_name" in \ + [f.fieldname for f in frappe.get_meta(linked_doctypes[d]["child_doctype"]).fields]: + frappe.db.sql("""UPDATE `tab{0}` set student_name = %s where {1} = %s""" + .format(linked_doctypes[d]["child_doctype"], linked_doctypes[d]["fieldname"]),(self.title, self.name)) def check_unique(self): """Validates if the Student Applicant is Unique""" diff --git a/erpnext/education/doctype/student_report_generation_tool/__init__.py b/erpnext/education/doctype/student_report_generation_tool/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.html b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.html new file mode 100644 index 0000000000..72772b7b32 --- /dev/null +++ b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.html @@ -0,0 +1,371 @@ + + + + +
+ +
+ + {% if letterhead and add_letterhead %} +
{{ letterhead }}
+ {% endif %} + +
+ +
+
+
+
+ +
+
+ {{ doc.students[0] }} +
+
+ +
+
+ +
+
+ {{ doc.student_name }} +
+
+ +
+
+ +
+
+ {{ doc.program }} +
+
+ +
+
+ +
+
+ {{ doc.student_batch }} +
+
+
+ +
+
+
+ +
+
+ {{ doc.academic_year }} +
+
+ + {% if doc.academic_term %} +
+
+ +
+
+ {{ doc.academic_term }} +
+
+ {% endif %} + +
+
+ +
+
+ {{ doc.assessment_group }} +
+
+
+
+ + +{% if doc.show_marks | int %} + {% set result_data = 'score' %} +{% else %} + {% set result_data = 'grade' %} +{% endif %} + + +{% for course in courses %} + +
+
+ +
+ + + + + + {% for assessment_group in assessment_groups %} + + {% endfor %} + + + + + {% for criteria in course_criteria[course] %} + + + {% for assessment_group in assessment_groups %} + {% if (assessment_result.get(course) and assessment_result.get(course).get(assessment_group) and assessment_result.get(course).get(assessment_group).get(criteria)) %} + + {% else %} + + {% endif %} + {% endfor %} + + {% endfor %} + + +
+
+
+ +
+
+ {{ course }} ({{ frappe.db.get_value("Course", course, "course_name") }}) +
+
+
{{ _("Assessment Criteria") }} {{ assessment_group }}
{{ criteria }} + {{ assessment_result.get(course).get(assessment_group).get(criteria).get(result_data) }} + {% if result_data == 'score' %} + ({{ assessment_result.get(course).get(assessment_group).get(criteria).get('maximum_score') }}) + {% endif %} +
+
+
+
+ +{% endfor %} + +
+ +
+
+

{{ _("Student Attendance")}}


+
+ Present {{ doc.attendance.get("Present") if doc.attendance.get("Present") != None else '0' }} days + out of {{ doc.attendance.get("Present") + doc.attendance.get("Absent") }} +
+
+ +
+

{{ _("Parents Teacher Meeting Attendance")}}


+
+ Present {{ doc.parents_attendance if doc.parents_attendance != None else '0' }} + out of {{ doc.parents_meeting if doc.parents_meeting != None else '0' }} +
+
+
+ +{% if doc.assessment_terms %} +
+
+

{{ doc.assessment_terms }}

+
+
+{% endif %} +
diff --git a/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.js b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.js new file mode 100644 index 0000000000..d5103ca2ad --- /dev/null +++ b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.js @@ -0,0 +1,66 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Student Report Generation Tool', { + onload: function(frm) { + frm.set_query("academic_term",function(){ + return{ + "filters":{ + "academic_year": frm.doc.academic_year + } + }; + }); + frm.set_query("assessment_group", function() { + return{ + filters: { + "is_group": 1 + } + }; + }); + }, + + refresh: function(frm) { + frm.disable_save(); + frm.page.clear_indicator(); + frm.page.set_primary_action(__('Print Report Card'), () => { + let url = "/api/method/erpnext.education.doctype.student_report_generation_tool.student_report_generation_tool.preview_report_card"; + open_url_post(url, frm.doc, true); + }); + }, + + student: function(frm) { + if (frm.doc.student) { + frappe.call({ + method:"erpnext.education.api.get_current_enrollment", + args: { + "student": frm.doc.student, + "academic_year": frm.doc.academic_year + }, + callback: function(r) { + if(r){ + $.each(r.message, function(i, d) { + if (frm.fields_dict.hasOwnProperty(i)) { + frm.set_value(i, d); + } + }); + } + } + }); + } + }, + + terms: function(frm) { + if(frm.doc.terms) { + return frappe.call({ + method: 'erpnext.setup.doctype.terms_and_conditions.terms_and_conditions.get_terms_and_conditions', + args: { + template_name: frm.doc.terms, + doc: frm.doc + }, + callback: function(r) { + frm.set_value("assessment_terms", r.message); + } + }); + } + } +}); diff --git a/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.json b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.json new file mode 100644 index 0000000000..88c59c2bdb --- /dev/null +++ b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.json @@ -0,0 +1,582 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2018-01-15 15:36:32.830069", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "student", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Student", + "length": 0, + "no_copy": 0, + "options": "Student", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "student_name", + "fieldtype": "Read Only", + "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": "Student 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, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "program", + "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": "Program", + "length": 0, + "no_copy": 0, + "options": "Program", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "student_batch", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Batch", + "length": 0, + "no_copy": 0, + "options": "Student Batch Name", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "include_all_assessment", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Include All Assessment Group", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "show_marks", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Show Marks", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "1", + "fieldname": "add_letterhead", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Add letterhead", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "column_break_3", + "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, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "assessment_group", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Assessment Group", + "length": 0, + "no_copy": 0, + "options": "Assessment Group", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "academic_year", + "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": "Academic Year", + "length": 0, + "no_copy": 0, + "options": "Academic Year", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "academic_term", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Academic Term", + "length": 0, + "no_copy": 0, + "options": "Academic Term", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "add_letterhead", + "fieldname": "letter_head", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Letter Head", + "length": 0, + "no_copy": 0, + "options": "Letter Head", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "section_break_5", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Print Section", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "parents_meeting", + "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": "Total Parents Teacher Meeting", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "parents_attendance", + "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": "Attended by Parents", + "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, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "terms", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Terms", + "length": 0, + "no_copy": 0, + "options": "Terms and Conditions", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "assessment_terms", + "fieldtype": "Text Editor", + "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": "Assessment Terms", + "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 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 1, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 1, + "istable": 0, + "max_attachments": 0, + "modified": "2018-03-20 17:57:53.936119", + "modified_by": "Administrator", + "module": "Education", + "name": "Student Report Generation Tool", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 0, + "email": 0, + "export": 0, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 0, + "read": 1, + "report": 0, + "role": "System Manager", + "set_user_permissions": 0, + "share": 0, + "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": 1, + "track_seen": 0 +} \ No newline at end of file diff --git a/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.py b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.py new file mode 100644 index 0000000000..7b2e00713a --- /dev/null +++ b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, 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 +from erpnext.education.api import get_grade +from frappe.utils.pdf import get_pdf +from erpnext.education.report.course_wise_assessment_report.course_wise_assessment_report import get_formatted_result +from erpnext.education.report.course_wise_assessment_report.course_wise_assessment_report import get_child_assessment_groups + + +class StudentReportGenerationTool(Document): + pass + + +@frappe.whitelist() +def preview_report_card(**kwargs): + doc = frappe._dict(**kwargs) + doc.students = [doc.student] + if not (doc.student_name and doc.student_batch): + program_enrollment = frappe.get_all("Program Enrollment", fields=["student_batch_name", "student_name"], + filters={"student": doc.student, "docstatus": ('!=', 2), "academic_year": doc.academic_year}) + if program_enrollment: + doc.batch = program_enrollment[0].student_batch_name + doc.student_name = program_enrollment[0].student_name + + # get the assessment result of the selected student + values = get_formatted_result(doc, get_course=True, get_all_assessment_groups=doc.include_all_assessment) + assessment_result = values.get("assessment_result").get(doc.student) + courses = values.get("course_dict") + course_criteria = get_courses_criteria(courses) + + # get the assessment group as per the user selection + if int(doc.include_all_assessment): + assessment_groups = get_child_assessment_groups(doc.assessment_group) + else: + assessment_groups = [doc.assessment_group] + + # get the attendance of the student for that peroid of time. + doc.attendance = get_attendance_count(doc.students[0], doc.academic_year, doc.academic_term) + + template = "erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.html" + base_template_path = "frappe/www/printview.html" + + from frappe.www.printview import get_letter_head + letterhead = get_letter_head(frappe._dict({"letter_head": doc.letterhead}), not doc.add_letterhead) + + html = frappe.render_template(template, + { + "doc": doc, + "assessment_result": assessment_result, + "courses": courses, + "assessment_groups": assessment_groups, + "course_criteria": course_criteria, + "letterhead": letterhead.content, + "add_letterhead": int(doc.add_letterhead) if int(doc.add_letterhead) else 0 + }) + final_template = frappe.render_template(base_template_path, {"body": html, "title": "Report Card"}) + + frappe.response.filename = "Report Card " + doc.students[0] + ".pdf" + frappe.response.filecontent = get_pdf(final_template) + frappe.response.type = "download" + + +def get_courses_criteria(courses): + course_criteria = frappe._dict() + for course in courses: + course_criteria[course] = [d.assessment_criteria for d in frappe.get_all("Course Assessment Criteria", + fields=["assessment_criteria"], filters={"parent": course})] + return course_criteria + + +def get_attendance_count(student, academic_year, academic_term=None): + if academic_year: + from_date, to_date = frappe.db.get_value("Academic Year", academic_year, ["year_start_date", "year_end_date"]) + elif academic_term: + from_date, to_date = frappe.db.get_value("Academic Term", academic_term, ["term_start_date", "term_end_date"]) + if from_date and to_date: + attendance = dict(frappe.db.sql('''select status, count(student) as no_of_days + from `tabStudent Attendance` where student = %s + and date between %s and %s group by status''', + (student, from_date, to_date))) + if "Absent" not in attendance.keys(): + attendance["Absent"] = 0 + if "Present" not in attendance.keys(): + attendance["Present"] = 0 + return attendance + else: + frappe.throw("Provide the academic year and set the starting and ending date.") \ No newline at end of file diff --git a/erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.js b/erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.js new file mode 100644 index 0000000000..10be092bb9 --- /dev/null +++ b/erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Student Report Generation Tool", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Student Report Generation Tool + () => frappe.tests.make('Student Report Generation Tool', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.py b/erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.py new file mode 100644 index 0000000000..417816642e --- /dev/null +++ b/erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +class TestStudentReportGenerationTool(unittest.TestCase): + pass diff --git a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py index a50ad7b91e..ce581486ec 100644 --- a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py +++ b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py @@ -60,7 +60,7 @@ def execute(filters=None): return columns, data, None, chart -def get_formatted_result(args, get_assessment_criteria=False, get_course=False): +def get_formatted_result(args, get_assessment_criteria=False, get_course=False, get_all_assessment_groups=False): cond, cond1, cond2, cond3, cond4 = " ", " ", " ", " ", " " args_list = [args.academic_year] @@ -77,15 +77,9 @@ def get_formatted_result(args, get_assessment_criteria=False, get_course=False): args_list.append(args.student_group) create_total_dict = False - group_type = frappe.get_value("Assessment Group", args.assessment_group, "is_group") - if group_type: - from frappe.desk.treeview import get_children - assessment_groups = [d.get("value") for d in get_children("Assessment Group", - args.assessment_group) if d.get("value") and not d.get("expandable")] - cond3 = " and ar.assessment_group in (%s)"%(', '.join(['%s']*len(assessment_groups))) - else: - assessment_groups = [args.assessment_group] - cond3 = " and ar.assessment_group=%s" + + assessment_groups = get_child_assessment_groups(args.assessment_group) + cond3 = " and ar.assessment_group in (%s)"%(', '.join(['%s']*len(assessment_groups))) args_list += assessment_groups if args.students: @@ -156,6 +150,9 @@ def get_formatted_result(args, get_assessment_criteria=False, get_course=False): # create the total of all the assessment groups criteria-wise elif create_total_dict: + if get_all_assessment_groups: + formatted_assessment_result[result.student][result.course][result.assessment_group]\ + [result.assessment_criteria] = assessment_criteria_details if not formatted_assessment_result[result.student][result.course][args.assessment_group]: formatted_assessment_result[result.student][result.course][args.assessment_group] = defaultdict(dict) formatted_assessment_result[result.student][result.course][args.assessment_group]\ @@ -238,3 +235,15 @@ def get_chart_data(grades, criteria_list, kounter): }, "type": 'bar', } + + +def get_child_assessment_groups(assessment_group): + assessment_groups = [] + group_type = frappe.get_value("Assessment Group", assessment_group, "is_group") + if group_type: + from frappe.desk.treeview import get_children + assessment_groups = [d.get("value") for d in get_children("Assessment Group", + assessment_group) if d.get("value") and not d.get("expandable")] + else: + assessment_groups = [assessment_group] + return assessment_groups diff --git a/erpnext/patches.txt b/erpnext/patches.txt index d06b405821..36e68ca078 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -495,3 +495,6 @@ erpnext.patches.v10_0.set_auto_created_serial_no_in_stock_entry erpnext.patches.v10_0.update_territory_and_customer_group erpnext.patches.v10_0.update_warehouse_address_details erpnext.patches.v10_0.update_reserved_qty_for_purchase_order +erpnext.patches.v10_0.update_hub_connector_domain +erpnext.patches.v10_0.set_student_party_type +erpnext.patches.v10_0.update_project_in_sle \ No newline at end of file diff --git a/erpnext/patches/v10_0/set_student_party_type.py b/erpnext/patches/v10_0/set_student_party_type.py new file mode 100644 index 0000000000..6ac1451623 --- /dev/null +++ b/erpnext/patches/v10_0/set_student_party_type.py @@ -0,0 +1,7 @@ +import frappe + +def execute(): + if not frappe.db.exists("Party Type", "Student"): + party = frappe.new_doc("Party Type") + party.party_type = "Student" + party.save() diff --git a/erpnext/patches/v10_0/update_hub_connector_domain.py b/erpnext/patches/v10_0/update_hub_connector_domain.py new file mode 100644 index 0000000000..808ae77129 --- /dev/null +++ b/erpnext/patches/v10_0/update_hub_connector_domain.py @@ -0,0 +1,9 @@ +import frappe + +def execute(): + if frappe.db.table_exists("Data Migration Connector"): + frappe.db.sql(""" + UPDATE `tabData Migration Connector` + SET hostname = 'https://hubmarket.org' + WHERE connector_name = 'Hub Connector' + """) \ No newline at end of file diff --git a/erpnext/patches/v10_0/update_project_in_sle.py b/erpnext/patches/v10_0/update_project_in_sle.py new file mode 100644 index 0000000000..08c64f18d8 --- /dev/null +++ b/erpnext/patches/v10_0/update_project_in_sle.py @@ -0,0 +1,15 @@ +# Copyright (c) 2017, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe + +def execute(): + for doctype in ['Sales Invoice', 'Delivery Note', 'Stock Entry']: + frappe.db.sql(""" update + `tabStock Ledger Entry` sle, `tab{0}` parent_doc + set + sle.project = parent_doc.project + where + sle.voucher_no = parent_doc.name and sle.voucher_type = %s and sle.project is null + and parent_doc.project is not null and parent_doc.project != ''""".format(doctype), doctype) diff --git a/erpnext/projects/doctype/project/project.json b/erpnext/projects/doctype/project/project.json index 5d95bd3904..bec7b377fd 100644 --- a/erpnext/projects/doctype/project/project.json +++ b/erpnext/projects/doctype/project/project.json @@ -1119,6 +1119,36 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "total_consumed_material_cost", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Total Consumed Material Cost (via Stock Entry)", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_on_submit": 0, @@ -1285,7 +1315,7 @@ "issingle": 0, "istable": 0, "max_attachments": 4, - "modified": "2017-12-10 08:40:46.843201", + "modified": "2018-03-22 11:44:38.723507", "modified_by": "Administrator", "module": "Projects", "name": "Project", diff --git a/erpnext/setup/doctype/naming_series/naming_series.py b/erpnext/setup/doctype/naming_series/naming_series.py index 45345846bc..c90a75f395 100644 --- a/erpnext/setup/doctype/naming_series/naming_series.py +++ b/erpnext/setup/doctype/naming_series/naming_series.py @@ -20,7 +20,7 @@ class NamingSeries(Document): + frappe.db.sql_list("""select dt from `tabCustom Field` where fieldname='naming_series'"""))) - doctypes = list(set(get_doctypes_with_read()) | set(doctypes)) + doctypes = list(set(get_doctypes_with_read()).intersection(set(doctypes))) prefixes = "" for d in doctypes: options = "" @@ -47,6 +47,7 @@ class NamingSeries(Document): def update_series(self, arg=None): """update series list""" + self.validate_series_set() self.check_duplicate() series_list = self.set_options.split("\n") @@ -60,6 +61,10 @@ class NamingSeries(Document): return self.get_transactions() + def validate_series_set(self): + if self.select_doc_for_series and not self.set_options: + frappe.throw(_("Please set the series to be used.")) + def set_series_for(self, doctype, ol): options = self.scrub_options_list(ol) diff --git a/erpnext/setup/setup_wizard/operations/install_fixtures.py b/erpnext/setup/setup_wizard/operations/install_fixtures.py index dce3c288b8..376ef29889 100644 --- a/erpnext/setup/setup_wizard/operations/install_fixtures.py +++ b/erpnext/setup/setup_wizard/operations/install_fixtures.py @@ -216,6 +216,7 @@ def install(country=None): {'doctype': "Party Type", "party_type": "Supplier"}, {'doctype': "Party Type", "party_type": "Employee"}, {'doctype': "Party Type", "party_type": "Member"}, + {'doctype': "Party Type", "party_type": "Student"}, {'doctype': "Opportunity Type", "name": "Hub"}, {'doctype': "Opportunity Type", "name": _("Sales")}, diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js index 2748436fd8..dff65afca3 100644 --- a/erpnext/stock/dashboard/item_dashboard.js +++ b/erpnext/stock/dashboard/item_dashboard.js @@ -18,12 +18,12 @@ erpnext.stock.ItemDashboard = Class.extend({ // move this.content.on('click', '.btn-move', function() { - erpnext.stock.move_item($(this).attr('data-item'), $(this).attr('data-warehouse'), + erpnext.stock.move_item(unescape($(this).attr('data-item')), $(this).attr('data-warehouse'), null, $(this).attr('data-actual_qty'), null, function() { me.refresh(); }); }); this.content.on('click', '.btn-add', function() { - erpnext.stock.move_item($(this).attr('data-item'), null, $(this).attr('data-warehouse'), + erpnext.stock.move_item(unescape($(this).attr('data-item')), null, $(this).attr('data-warehouse'), $(this).attr('data-actual_qty'), $(this).attr('data-rate'), function() { me.refresh(); }); }); diff --git a/erpnext/stock/dashboard/item_dashboard_list.html b/erpnext/stock/dashboard/item_dashboard_list.html index e0b3431839..5a3fa2ed48 100644 --- a/erpnext/stock/dashboard/item_dashboard_list.html +++ b/erpnext/stock/dashboard/item_dashboard_list.html @@ -45,12 +45,12 @@