diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 0c7daad89f..1ebff9ac24 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from erpnext.hooks import regional_overrides -__version__ = '9.1.7' +__version__ = '9.1.8' def get_default_company(user=None): '''Get default company for user''' diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index face5ede25..790003c301 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -54,7 +54,7 @@ class JournalEntry(AccountsController): def update_advance_paid(self): advance_paid = frappe._dict() for d in self.get("accounts"): - if d.is_advance: + if d.is_advance == "Yes": if d.reference_type in ("Sales Order", "Purchase Order"): advance_paid.setdefault(d.reference_type, []).append(d.reference_name) @@ -76,7 +76,7 @@ class JournalEntry(AccountsController): def unlink_advance_entry_reference(self): for d in self.get("accounts"): - if d.is_advance and d.reference_type in ("Sales Invoice", "Purchase Invoice"): + if d.is_advance == "Yes" and d.reference_type in ("Sales Invoice", "Purchase Invoice"): doc = frappe.get_doc(d.reference_type, d.reference_name) doc.delink_advance_entries(self.name) d.reference_type = '' diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index 04db9e28ae..17ac1f7056 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -405,11 +405,7 @@ frappe.ui.form.on('Payment Entry', { } // Make read only if Accounts Settings doesn't allow stale rates - frappe.model.get_value("Accounts Settings", null, "allow_stale", - function(d){ - frm.set_df_property("source_exchange_rate", "read_only", cint(d.allow_stale) ? 0 : 1); - } - ); + frm.set_df_property("source_exchange_rate", "read_only", erpnext.stale_rate_allowed()); }, target_exchange_rate: function(frm) { @@ -430,11 +426,7 @@ frappe.ui.form.on('Payment Entry', { frm.set_paid_amount_based_on_received_amount = false; // Make read only if Accounts Settings doesn't allow stale rates - frappe.model.get_value("Accounts Settings", null, "allow_stale", - function(d){ - frm.set_df_property("target_exchange_rate", "read_only", cint(d.allow_stale) ? 0 : 1); - } - ); + frm.set_df_property("target_exchange_rate", "read_only", erpnext.stale_rate_allowed()); }, paid_amount: function(frm) { @@ -660,8 +652,15 @@ frappe.ui.form.on('Payment Entry', { var party_amount = frm.doc.payment_type=="Receive" ? frm.doc.paid_amount : frm.doc.received_amount; + var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [], + function(d) { return flt(d.amount) })); + if(frm.doc.total_allocated_amount < party_amount) { - unallocated_amount = party_amount - frm.doc.total_allocated_amount; + if(frm.doc.payment_type == "Receive") { + unallocated_amount = party_amount - (frm.doc.total_allocated_amount - total_deductions); + } else { + unallocated_amount = party_amount - (frm.doc.total_allocated_amount + total_deductions); + } } } frm.set_value("unallocated_amount", unallocated_amount); @@ -680,9 +679,6 @@ frappe.ui.form.on('Payment Entry', { difference_amount = flt(frm.doc.base_paid_amount) - flt(frm.doc.base_received_amount); } - var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [], - function(d) { return flt(d.amount) })); - frm.set_value("difference_amount", difference_amount - total_deductions); frm.events.hide_unhide_fields(frm); diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 9d24261038..56bdfbaf4b 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -285,8 +285,13 @@ class PaymentEntry(AccountsController): if self.party: party_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount + total_deductions = sum([flt(d.amount) for d in self.get("deductions")]) + if self.total_allocated_amount < party_amount: - self.unallocated_amount = party_amount - self.total_allocated_amount + if self.payment_type == "Receive": + self.unallocated_amount = party_amount - (self.total_allocated_amount - total_deductions) + else: + self.unallocated_amount = party_amount - (self.total_allocated_amount + total_deductions) def set_difference_amount(self): base_unallocated_amount = flt(self.unallocated_amount) * (flt(self.source_exchange_rate) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json index e3c5fb4942..3d70b3b0b9 100755 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json @@ -3440,139 +3440,13 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "subscription", - "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": "Subscription", - "length": 0, - "no_copy": 1, - "options": "Subscription", - "permlevel": 0, - "precision": "", - "print_hide": 1, - "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, - "bold": 0, - "collapsible": 1, - "collapsible_depends_on": "is_recurring", - "columns": 0, - "depends_on": "eval:doc.docstatus<2 && !doc.__islocal", - "fieldname": "recurring_invoice", - "fieldtype": "Section Break", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Recurring Invoice", - "length": 0, - "no_copy": 0, - "options": "fa fa-time", - "permlevel": 0, - "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, - "unique": 0 - }, { "allow_bulk_edit": 0, "allow_on_submit": 1, "bold": 0, "collapsible": 0, "columns": 0, - "depends_on": "eval:doc.docstatus<2", - "description": "", - "fieldname": "is_recurring", - "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": "Is Recurring", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring==1", - "description": "Select the period when the invoice will be generated automatically", - "fieldname": "recurring_type", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Recurring Type", - "length": 0, - "no_copy": 1, - "options": "Monthly\nQuarterly\nHalf-yearly\nYearly", - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring==1", + "depends_on": "", "description": "Start date of current invoice's period", "fieldname": "from_date", "fieldtype": "Date", @@ -3603,7 +3477,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "depends_on": "eval:doc.is_recurring==1", + "depends_on": "", "description": "End date of current invoice's period", "fieldname": "to_date", "fieldtype": "Date", @@ -3628,138 +3502,13 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", - "fieldname": "submit_on_creation", - "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": "Submit on creation", - "length": 0, - "no_copy": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", - "description": "", - "fieldname": "notify_by_email", - "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": "Notify by email", - "length": 0, - "no_copy": 1, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring==1", - "description": "The day of the month on which auto invoice will be generated e.g. 05, 28 etc", - "fieldname": "repeat_on_day_of_month", - "fieldtype": "Int", - "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": "Repeat on Day of Month", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring==1", - "description": "The date on which recurring invoice will be stop", - "fieldname": "end_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": "End Date", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "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, - "unique": 0 - }, { "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "column_break_82", + "fieldname": "column_break_114", "fieldtype": "Column Break", "hidden": 0, "ignore_user_permissions": 0, @@ -3771,101 +3520,8 @@ "length": 0, "no_copy": 0, "permlevel": 0, - "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, - "unique": 0, - "width": "50%" - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring==1", - "description": "The date on which next invoice will be generated. It is generated on submit.", - "fieldname": "next_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": "Next Date", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "print_hide": 1, - "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, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring==1", - "description": "The unique id for tracking all recurring invoices. It is generated on submit.", - "fieldname": "recurring_id", - "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": "Recurring Id", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "print_hide": 1, - "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": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring==1", - "description": "Enter Email Address separated by commas, invoice will be mailed automatically on particular date", - "fieldname": "notification_email_address", - "fieldtype": "Small Text", - "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": "Notification Email Address", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "print_hide": 1, + "precision": "", + "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, "remember_last_selected_value": 0, @@ -3881,8 +3537,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "depends_on": "eval:doc.is_recurring==1", - "fieldname": "recurring_print_format", + "fieldname": "subscription", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, @@ -3891,15 +3546,15 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Recurring Print Format", + "label": "Subscription", "length": 0, - "no_copy": 0, - "options": "Print Format", + "no_copy": 1, + "options": "Subscription", "permlevel": 0, "precision": "", - "print_hide": 0, + "print_hide": 1, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, @@ -3920,7 +3575,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2017-09-19 11:22:47.074420", + "modified": "2017-10-24 12:51:51.199594", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice", diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 9aa0e6b6a2..ecd7cf9069 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -4273,414 +4273,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "subscription", - "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": "Subscription", - "length": 0, - "no_copy": 1, - "options": "Subscription", - "permlevel": 0, - "precision": "", - "print_hide": 1, - "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, - "bold": 0, - "collapsible": 1, - "collapsible_depends_on": "is_recurring", - "columns": 0, - "depends_on": "eval:doc.docstatus<2 && !doc.__islocal", - "fieldname": "recurring_invoice", - "fieldtype": "Section Break", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Recurring Invoice", - "length": 0, - "no_copy": 0, - "options": "fa fa-time", - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break11", - "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, - "label": "Settings", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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, - "unique": 0, - "width": "50%" - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.docstatus<2", - "description": "", - "fieldname": "is_recurring", - "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": "Is Recurring", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "is_recurring", - "description": "", - "fieldname": "recurring_id", - "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": "Reference Document", - "length": 0, - "no_copy": 1, - "options": "Sales Invoice", - "permlevel": 0, - "print_hide": 1, - "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": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", - "description": "", - "fieldname": "recurring_type", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Frequency", - "length": 0, - "no_copy": 1, - "options": "\nMonthly\nQuarterly\nHalf-yearly\nYearly", - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", - "description": "", - "fieldname": "repeat_on_day_of_month", - "fieldtype": "Int", - "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": "Repeat on Day of Month", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", - "description": "", - "fieldname": "end_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": "End Date", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", - "fieldname": "submit_on_creation", - "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": "Submit on creation", - "length": 0, - "no_copy": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", - "description": "", - "fieldname": "notify_by_email", - "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": "Notify by email", - "length": 0, - "no_copy": 1, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.notify_by_email && doc.recurring_id === doc.name", - "description": "", - "fieldname": "notification_email_address", - "fieldtype": "Code", - "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": "Notification Email Address", - "length": 0, - "no_copy": 1, - "options": "Email", - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.notify_by_email && doc.recurring_id === doc.name", - "fieldname": "recurring_print_format", - "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": "Recurring Print Format", - "length": 0, - "no_copy": 0, - "options": "Print Format", - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break12", - "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, - "label": "This Document", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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, - "unique": 0, - "width": "50%" - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "is_recurring", + "depends_on": "", "description": "", "fieldname": "from_date", "fieldtype": "Date", @@ -4711,7 +4304,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "depends_on": "is_recurring", + "depends_on": "", "description": "", "fieldname": "to_date", "fieldtype": "Date", @@ -4742,10 +4335,8 @@ "bold": 0, "collapsible": 0, "columns": 0, - "depends_on": "is_recurring", - "description": "", - "fieldname": "next_date", - "fieldtype": "Date", + "fieldname": "column_break_140", + "fieldtype": "Column Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -4753,11 +4344,11 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Next Date", "length": 0, - "no_copy": 1, + "no_copy": 0, "permlevel": 0, - "print_hide": 1, + "precision": "", + "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, "remember_last_selected_value": 0, @@ -4767,6 +4358,37 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 1, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "subscription", + "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": "Subscription", + "length": 0, + "no_copy": 1, + "options": "Subscription", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "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, @@ -4811,7 +4433,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2017-09-19 11:23:08.675028", + "modified": "2017-10-24 12:46:48.331723", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 6ab614863b..1c4fe3d084 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -70,6 +70,7 @@ class SalesInvoice(SellingController): self.clear_unallocated_advances("Sales Invoice Advance", "advances") self.add_remarks() self.validate_write_off_account() + self.validate_duplicate_offline_pos_entry() self.validate_account_for_change_amount() self.validate_fixed_asset() self.set_income_account_for_fixed_assets() @@ -462,6 +463,12 @@ class SalesInvoice(SellingController): if flt(self.write_off_amount) and not self.write_off_account: msgprint(_("Please enter Write Off Account"), raise_exception=1) + def validate_duplicate_offline_pos_entry(self): + if self.is_pos and self.offline_pos_name \ + and frappe.db.get_value('Sales Invoice', + {'offline_pos_name': self.offline_pos_name, 'docstatus': 1}): + frappe.throw(_("Duplicate offline pos sales invoice {0}").format(self.offline_pos_name)) + def validate_account_for_change_amount(self): if flt(self.change_amount) and not self.account_for_change_amount: msgprint(_("Please enter Account for Change Amount"), raise_exception=1) diff --git a/erpnext/accounts/doctype/subscription/subscription.js b/erpnext/accounts/doctype/subscription/subscription.js index 15927d5961..8db5be8772 100644 --- a/erpnext/accounts/doctype/subscription/subscription.js +++ b/erpnext/accounts/doctype/subscription/subscription.js @@ -12,7 +12,8 @@ frappe.ui.form.on('Subscription', { frm.fields_dict['reference_document'].get_query = function() { return { filters: { - "docstatus": 1 + "docstatus": 1, + "subscription": '' } }; }; diff --git a/erpnext/accounts/doctype/subscription/subscription.json b/erpnext/accounts/doctype/subscription/subscription.json index 167a92f502..7ff2e4b632 100644 --- a/erpnext/accounts/doctype/subscription/subscription.json +++ b/erpnext/accounts/doctype/subscription/subscription.json @@ -315,22 +315,23 @@ }, { "allow_bulk_edit": 0, - "allow_on_submit": 1, + "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "from_date", - "fieldtype": "Date", + "fieldname": "frequency", + "fieldtype": "Select", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 0, - "label": "From Date", + "label": "Frequency", "length": 0, "no_copy": 0, + "options": "\nDaily\nWeekly\nMonthly\nQuarterly\nHalf-yearly\nYearly", "permlevel": 0, "precision": "", "print_hide": 0, @@ -338,37 +339,7 @@ "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": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "to_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": "To Date", - "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, + "reqd": 1, "search_index": 0, "set_only_once": 0, "unique": 0 @@ -402,37 +373,6 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "frequency", - "fieldtype": "Select", - "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": "Frequency", - "length": 0, - "no_copy": 0, - "options": "\nDaily\nWeekly\nMonthly\nQuarterly\nHalf-yearly\nYearly", - "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": 1, @@ -844,7 +784,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-10-10 17:28:10.105561", + "modified": "2017-10-23 18:28:08.966403", "modified_by": "Administrator", "module": "Accounts", "name": "Subscription", diff --git a/erpnext/accounts/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py index 20cf031503..fb01efe13b 100644 --- a/erpnext/accounts/doctype/subscription/subscription.py +++ b/erpnext/accounts/doctype/subscription/subscription.py @@ -17,6 +17,7 @@ month_map = {'Monthly': 1, 'Quarterly': 3, 'Half-yearly': 6, 'Yearly': 12} class Subscription(Document): def validate(self): self.update_status() + self.validate_reference_doctype() self.validate_dates() self.validate_next_schedule_date() self.validate_email_id() @@ -25,25 +26,28 @@ class Subscription(Document): validate_template(self.message or "") def before_submit(self): - self.set_next_schedule_date() + if not self.next_schedule_date: + self.next_schedule_date = get_next_schedule_date(self.start_date, + self.frequency, self.repeat_on_day) def on_submit(self): - # self.update_subscription_id() - self.update_subscription_data() + self.update_subscription_id() def on_update_after_submit(self): - self.update_subscription_data() self.validate_dates() self.set_next_schedule_date() def before_cancel(self): self.unlink_subscription_id() + self.next_schedule_date = None def unlink_subscription_id(self): - doc = frappe.get_doc(self.reference_doctype, self.reference_document) - if doc.meta.get_field('subscription'): - doc.subscription = None - doc.db_update() + frappe.db.sql("update `tab{0}` set subscription = null where subscription=%s" + .format(self.reference_doctype), self.name) + + def validate_reference_doctype(self): + if not frappe.get_meta(self.reference_doctype).has_field('subscription'): + frappe.throw(_("Add custom field Subscription in the doctype {0}").format(self.reference_doctype)) def validate_dates(self): if self.end_date and getdate(self.start_date) > getdate(self.end_date): @@ -76,30 +80,11 @@ class Subscription(Document): frappe.throw(_("'Recipients' not specified")) def set_next_schedule_date(self): - self.next_schedule_date = get_next_schedule_date(self.start_date, - self.frequency, self.repeat_on_day) - - def update_subscription_data(self): - update_doc = False - doc = frappe.get_doc(self.reference_doctype, self.reference_document) - if frappe.get_meta(self.reference_doctype).get_field("from_date"): - doc.from_date = self.from_date - doc.to_date = self.to_date - update_doc = True - - if not doc.subscription: - doc.subscription = self.name - update_doc = True - - if update_doc: - doc.db_update() + if self.repeat_on_day: + self.next_schedule_date = get_next_date(self.next_schedule_date, 0, self.repeat_on_day) def update_subscription_id(self): - doc = frappe.get_doc(self.reference_doctype, self.reference_document) - if not doc.meta.get_field('subscription'): - frappe.throw(_("Add custom field Subscription Id in the doctype {0}").format(self.reference_doctype)) - - doc.db_set('subscription', self.name) + frappe.db.set_value(self.reference_doctype, self.reference_document, "subscription", self.name) def update_status(self, status=None): self.status = { @@ -142,9 +127,6 @@ def get_subscription_entries(date): def create_documents(data, schedule_date): try: doc = make_new_document(data, schedule_date) - if getattr(doc, "from_date", None): - update_subscription_period(data, doc) - if data.notify_by_email and data.recipients: print_format = data.print_format or "Standard" send_notification(doc, data, print_format=print_format) @@ -159,13 +141,6 @@ def create_documents(data, schedule_date): if data.reference_document and not frappe.flags.in_test: notify_error_to_user(data) -def update_subscription_period(data, doc): - from_date = doc.from_date - to_date = doc.to_date - - frappe.db.set_value('Subscription', data.name, 'from_date', from_date) - frappe.db.set_value('Subscription', data.name, 'to_date', to_date) - def disable_subscription(data): subscription = frappe.get_doc('Subscription', data.name) subscription.db_set('disabled', 1) @@ -216,24 +191,38 @@ def update_doc(new_document, reference_doc, args, schedule_date): for fieldname in ("page_break",): item.set(fieldname, reference_doc.items[i].get(fieldname)) - if args.from_date and args.to_date: - from_date = get_next_date(args.from_date, mcount) - - if (cstr(get_first_day(args.from_date)) == cstr(args.from_date)) and \ - (cstr(get_last_day(args.to_date)) == cstr(args.to_date)): - to_date = get_last_day(get_next_date(args.to_date, mcount)) - else: - to_date = get_next_date(args.to_date, mcount) - - if new_document.meta.get_field('from_date'): - new_document.set('from_date', from_date) - new_document.set('to_date', to_date) - - new_document.run_method("on_recurring", reference_doc=reference_doc, subscription_doc=args) for data in new_document.meta.fields: if data.fieldtype == 'Date' and data.reqd: new_document.set(data.fieldname, schedule_date) + set_subscription_period(args, mcount, new_document) + + new_document.run_method("on_recurring", reference_doc=reference_doc, subscription_doc=args) + +def set_subscription_period(args, mcount, new_document): + if new_document.meta.get_field('from_date') and new_document.meta.get_field('to_date'): + last_ref_doc = frappe.db.sql(""" + select name, from_date, to_date + from `tab{0}` + where subscription=%s and docstatus < 2 + order by creation desc + limit 1 + """.format(args.reference_doctype), args.name, as_dict=1) + + if not last_ref_doc: + return + + from_date = get_next_date(last_ref_doc[0].from_date, mcount) + + if (cstr(get_first_day(last_ref_doc[0].from_date)) == cstr(last_ref_doc[0].from_date)) and \ + (cstr(get_last_day(last_ref_doc[0].to_date)) == cstr(last_ref_doc[0].to_date)): + to_date = get_last_day(get_next_date(last_ref_doc[0].to_date, mcount)) + else: + to_date = get_next_date(last_ref_doc[0].to_date, mcount) + + new_document.set('from_date', from_date) + new_document.set('to_date', to_date) + def get_next_date(dt, mcount, day=None): dt = getdate(dt) dt += relativedelta(months=mcount, day=day) @@ -287,8 +276,11 @@ def assign_task_to_owner(name, msg, users): @frappe.whitelist() def make_subscription(doctype, docname): doc = frappe.new_doc('Subscription') + + reference_doc = frappe.get_doc(doctype, docname) doc.reference_doctype = doctype doc.reference_document = docname + doc.start_date = reference_doc.get('posting_date') or reference_doc.get('transaction_date') return doc @frappe.whitelist() diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py index bcec0a29c9..ce049f5d87 100644 --- a/erpnext/accounts/party.py +++ b/erpnext/accounts/party.py @@ -76,7 +76,7 @@ def set_address_details(out, party, party_type, doctype=None, company=None): # shipping address if party_type in ["Customer", "Lead"]: - out.shipping_address_name = get_default_address(party_type, party.name, 'is_shipping_address') + out.shipping_address_name = get_party_shipping_address(party_type, party.name) out.shipping_address = get_address_display(out["shipping_address_name"]) if doctype: out.update(get_fetch_values(doctype, 'shipping_address_name', out.shipping_address_name)) @@ -418,3 +418,32 @@ def get_dashboard_info(party_type, party): info["total_unpaid"] = -1 * info["total_unpaid"] return info + + +def get_party_shipping_address(doctype, name): + """ + Returns an Address name (best guess) for the given doctype and name for which `address_type == 'Shipping'` is true. + and/or `is_shipping_address = 1`. + + It returns an empty string if there is no matching record. + + :param doctype: Party Doctype + :param name: Party name + :return: String + """ + out = frappe.db.sql( + 'SELECT dl.parent ' + 'from `tabDynamic Link` dl join `tabAddress` ta on dl.parent=ta.name ' + 'where ' + 'dl.link_doctype=%s ' + 'and dl.link_name=%s ' + 'and dl.parenttype="Address" ' + 'and ' + '(ta.address_type="Shipping" or ta.is_shipping_address=1) ' + 'order by ta.is_shipping_address desc, ta.address_type desc limit 1', + (doctype, name) + ) + if out: + return out[0][0] + else: + return '' diff --git a/erpnext/accounts/test/__init__.py b/erpnext/accounts/test/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/accounts/test/test_utils.py b/erpnext/accounts/test/test_utils.py new file mode 100644 index 0000000000..0fca470fe5 --- /dev/null +++ b/erpnext/accounts/test/test_utils.py @@ -0,0 +1,84 @@ +import unittest +from erpnext.accounts.party import get_party_shipping_address +from frappe.test_runner import make_test_objects + + +class TestUtils(unittest.TestCase): + @classmethod + def setUpClass(cls): + super(TestUtils, cls).setUpClass() + make_test_objects('Address', ADDRESS_RECORDS) + + def test_get_party_shipping_address(self): + address = get_party_shipping_address('Customer', '_Test Customer 1') + self.assertEqual(address, '_Test Billing Address 2 Title-Billing') + + def test_get_party_shipping_address2(self): + address = get_party_shipping_address('Customer', '_Test Customer 2') + self.assertEqual(address, '_Test Shipping Address 2 Title-Shipping') + + +ADDRESS_RECORDS = [ + { + "doctype": "Address", + "address_type": "Billing", + "address_line1": "Address line 1", + "address_title": "_Test Billing Address Title", + "city": "Lagos", + "country": "Nigeria", + "links": [ + { + "link_doctype": "Customer", + "link_name": "_Test Customer 2", + "doctype": "Dynamic Link" + } + ] + }, + { + "doctype": "Address", + "address_type": "Shipping", + "address_line1": "Address line 2", + "address_title": "_Test Shipping Address 1 Title", + "city": "Lagos", + "country": "Nigeria", + "links": [ + { + "link_doctype": "Customer", + "link_name": "_Test Customer 2", + "doctype": "Dynamic Link" + } + ] + }, + { + "doctype": "Address", + "address_type": "Shipping", + "address_line1": "Address line 3", + "address_title": "_Test Shipping Address 2 Title", + "city": "Lagos", + "country": "Nigeria", + "is_shipping_address": "1", + "links": [ + { + "link_doctype": "Customer", + "link_name": "_Test Customer 2", + "doctype": "Dynamic Link" + } + ] + }, + { + "doctype": "Address", + "address_type": "Billing", + "address_line1": "Address line 4", + "address_title": "_Test Billing Address 2 Title", + "city": "Lagos", + "country": "Nigeria", + "is_shipping_address": "1", + "links": [ + { + "link_doctype": "Customer", + "link_name": "_Test Customer 1", + "doctype": "Dynamic Link" + } + ] + } +] diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index 28b8b475c2..534af8bfc5 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -2948,418 +2948,13 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "subscription", - "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": "Subscription", - "length": 0, - "no_copy": 1, - "options": "Subscription", - "permlevel": 0, - "precision": "", - "print_hide": 1, - "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, - "bold": 0, - "collapsible": 1, - "collapsible_depends_on": "is_recurring", - "columns": 0, - "depends_on": "eval:doc.docstatus<2 && !doc.__islocal", - "fieldname": "recurring_order", - "fieldtype": "Section Break", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Recurring Order", - "length": 0, - "no_copy": 0, - "options": "fa fa-time", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "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, - "label": "Settings", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, { "allow_bulk_edit": 0, "allow_on_submit": 1, "bold": 0, "collapsible": 0, "columns": 0, - "depends_on": "eval:doc.docstatus<2", - "description": "", - "fieldname": "is_recurring", - "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": "Is Recurring", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "is_recurring", - "description": "", - "fieldname": "recurring_id", - "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": "Reference Document", - "length": 0, - "no_copy": 1, - "options": "Purchase Order", - "permlevel": 0, - "print_hide": 1, - "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": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", - "description": "", - "fieldname": "recurring_type", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Frequency", - "length": 0, - "no_copy": 1, - "options": "Monthly\nQuarterly\nHalf-yearly\nYearly", - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", - "description": "", - "fieldname": "repeat_on_day_of_month", - "fieldtype": "Int", - "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": "Repeat on Day of Month", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", - "description": "", - "fieldname": "end_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": "End Date", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", - "fieldname": "submit_on_creation", - "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": "Submit on creation", - "length": 0, - "no_copy": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", - "description": "", - "fieldname": "notify_by_email", - "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": "Notify by email", - "length": 0, - "no_copy": 1, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.notify_by_email && doc.recurring_id === doc.name", - "description": "", - "fieldname": "notification_email_address", - "fieldtype": "Code", - "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": "Notification Email Address", - "length": 0, - "no_copy": 1, - "options": "Email", - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.notify_by_email && doc.recurring_id === doc.name", - "fieldname": "recurring_print_format", - "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": "Recurring Print Format", - "length": 0, - "no_copy": 0, - "options": "Print Format", - "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_break83", - "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, - "label": "This Document", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "is_recurring", + "depends_on": "", "description": "", "fieldname": "from_date", "fieldtype": "Date", @@ -3390,7 +2985,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "depends_on": "is_recurring", + "depends_on": "", "description": "", "fieldname": "to_date", "fieldtype": "Date", @@ -3421,10 +3016,8 @@ "bold": 0, "collapsible": 0, "columns": 0, - "depends_on": "is_recurring", - "description": "", - "fieldname": "next_date", - "fieldtype": "Date", + "fieldname": "column_break_97", + "fieldtype": "Column Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -3432,11 +3025,11 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Next Date", "length": 0, - "no_copy": 1, + "no_copy": 0, "permlevel": 0, - "print_hide": 1, + "precision": "", + "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, "remember_last_selected_value": 0, @@ -3445,6 +3038,37 @@ "search_index": 0, "set_only_once": 0, "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "subscription", + "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": "Subscription", + "length": 0, + "no_copy": 1, + "options": "Subscription", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "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 } ], "has_web_view": 0, @@ -3458,7 +3082,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-10-05 14:19:04.102534", + "modified": "2017-10-24 12:52:11.272306", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order", diff --git a/erpnext/controllers/item_variant.py b/erpnext/controllers/item_variant.py index 8ca4f7096c..f40d519b92 100644 --- a/erpnext/controllers/item_variant.py +++ b/erpnext/controllers/item_variant.py @@ -201,14 +201,16 @@ def copy_attributes_to_variant(item, variant): variant.variant_of = item.name variant.has_variants = 0 if not variant.description: - variant.description = '' + variant.description = "" if item.variant_based_on=='Item Attribute': if variant.attributes: - if not variant.description: - variant.description += "\n" - for d in variant.attributes: - variant.description += "
" + d.attribute + ": " + cstr(d.attribute_value) + "
" + attributes_description = "" + for d in variant.attributes: + attributes_description += "
" + d.attribute + ": " + cstr(d.attribute_value) + "
" + + if attributes_description not in variant.description: + variant.description += attributes_description def make_variant_item_code(template_item_code, template_item_name, variant): """Uses template's item code and abbreviations to make variant's item code""" diff --git a/erpnext/manufacturing/doctype/bom/bom.json b/erpnext/manufacturing/doctype/bom/bom.json index 2558df35ea..85a3f7e9b1 100644 --- a/erpnext/manufacturing/doctype/bom/bom.json +++ b/erpnext/manufacturing/doctype/bom/bom.json @@ -322,6 +322,36 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "currency_detail", + "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": "", + "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, @@ -359,8 +389,8 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "currency_detail", - "fieldtype": "Section Break", + "fieldname": "column_break_12", + "fieldtype": "Column Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -368,7 +398,6 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "", "length": 0, "no_copy": 0, "permlevel": 0, @@ -414,35 +443,6 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_12", - "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, @@ -1322,7 +1322,7 @@ "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, - "collapsible": 1, + "collapsible": 0, "columns": 0, "depends_on": "eval:!doc.__islocal", "fieldname": "section_break0", @@ -1671,7 +1671,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-08-23 14:09:30.492628", + "modified": "2017-10-23 14:56:21.991160", "modified_by": "Administrator", "module": "Manufacturing", "name": "BOM", diff --git a/erpnext/patches.txt b/erpnext/patches.txt index ef341899ee..fd7a1b4da6 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -448,8 +448,10 @@ erpnext.patches.v8_9.remove_employee_from_salary_structure_parent erpnext.patches.v8_9.delete_gst_doctypes_for_outside_india_accounts erpnext.patches.v8_9.set_default_fields_in_variant_settings erpnext.patches.v8_9.update_billing_gstin_for_indian_account -erpnext.patches.v9_0.fix_subscription_next_date erpnext.patches.v9_0.set_schedule_date_for_material_request_and_purchase_order erpnext.patches.v9_0.student_admission_childtable_migrate +erpnext.patches.v9_0.fix_subscription_next_date #2017-10-23 erpnext.patches.v9_0.add_healthcare_domain erpnext.patches.v9_0.set_variant_item_description +erpnext.patches.v9_0.set_uoms_in_variant_field +erpnext.patches.v9_0.copy_old_fees_field_data diff --git a/erpnext/patches/v8_7/make_subscription_from_recurring_data.py b/erpnext/patches/v8_7/make_subscription_from_recurring_data.py index c5d7d7279a..2932749116 100644 --- a/erpnext/patches/v8_7/make_subscription_from_recurring_data.py +++ b/erpnext/patches/v8_7/make_subscription_from_recurring_data.py @@ -18,24 +18,33 @@ def execute(): frappe.reload_doc('accounts', 'doctype', 'journal_entry') frappe.reload_doc('accounts', 'doctype', 'payment_entry') - for doctype in ['Sales Order', 'Sales Invoice', - 'Purchase Invoice', 'Purchase Invoice']: - for data in get_data(doctype): - make_subscription(doctype, data) + for doctype in ['Sales Order', 'Sales Invoice', 'Purchase Order', 'Purchase Invoice']: + date_field = "transaction_date" + if doctype in ("Sales Invoice", "Purchase Invoice"): + date_field = "posting_date" -def get_data(doctype): - return frappe.db.sql(""" select name, from_date, end_date, recurring_type,recurring_id, + for data in get_data(doctype, date_field): + make_subscription(doctype, data, date_field) + +def get_data(doctype, date_field): + return frappe.db.sql(""" select name, from_date, end_date, recurring_type, recurring_id, next_date, notify_by_email, notification_email_address, recurring_print_format, - repeat_on_day_of_month, submit_on_creation, docstatus - from `tab{0}` where is_recurring = 1 and next_date >= %s and docstatus < 2 - """.format(doctype), today(), as_dict=1) + repeat_on_day_of_month, submit_on_creation, docstatus, {0} + from `tab{1}` where is_recurring = 1 and next_date >= %s and docstatus < 2 + order by next_date desc + """.format(date_field, doctype), today(), as_dict=1) + +def make_subscription(doctype, data, date_field): + if data.name == data.recurring_id: + start_date = data.get(date_field) + else: + start_date = frappe.db.get_value(doctype, data.recurring_id, date_field) -def make_subscription(doctype, data): doc = frappe.get_doc({ 'doctype': 'Subscription', 'reference_doctype': doctype, - 'reference_document': data.name, - 'start_date': data.from_date, + 'reference_document': data.recurring_id, + 'start_date': start_date, 'end_date': data.end_date, 'frequency': data.recurring_type, 'repeat_on_day': data.repeat_on_day_of_month, diff --git a/erpnext/patches/v9_0/copy_old_fees_field_data.py b/erpnext/patches/v9_0/copy_old_fees_field_data.py new file mode 100644 index 0000000000..fb11ee5a56 --- /dev/null +++ b/erpnext/patches/v9_0/copy_old_fees_field_data.py @@ -0,0 +1,11 @@ +# Copyright (c) 2017, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe + +def execute(): + if "total_amount" not in frappe.db.get_table_columns("Fees"): + return + + frappe.db.sql("""update tabFees set grand_total=total_amount where grand_total = 0.0""") \ No newline at end of file diff --git a/erpnext/patches/v9_0/fix_subscription_next_date.py b/erpnext/patches/v9_0/fix_subscription_next_date.py index a36e60ccaa..07af7129f6 100644 --- a/erpnext/patches/v9_0/fix_subscription_next_date.py +++ b/erpnext/patches/v9_0/fix_subscription_next_date.py @@ -3,25 +3,41 @@ from __future__ import unicode_literals import frappe +from frappe.utils import getdate +from erpnext.accounts.doctype.subscription.subscription import get_next_schedule_date def execute(): frappe.reload_doctype('Subscription') doctypes = ('Purchase Order', 'Sales Order', 'Purchase Invoice', 'Sales Invoice') - for data in frappe.get_all('Subscription', fields = ["name", "reference_doctype", "reference_document"], - filters = {'reference_doctype': ('in', doctypes)}): - doc = frappe.get_doc('Subscription', data.name) - fields = ['transaction_date'] - if doc.reference_doctype in ['Sales Invoice', 'Purchase Invoice']: - fields = ['posting_date'] + for data in frappe.get_all('Subscription', + fields = ["name", "reference_doctype", "reference_document", + "start_date", "frequency", "repeat_on_day"], + filters = {'reference_doctype': ('in', doctypes), 'docstatus': 1}): - fields.extend(['from_date', 'to_date']) - reference_data = frappe.db.get_value(data.reference_doctype, - data.reference_document, fields, as_dict=1) + recurring_id = frappe.db.get_value(data.reference_doctype, data.reference_document, "recurring_id") + if recurring_id: + frappe.db.sql("update `tab{0}` set subscription=%s where recurring_id=%s" + .format(data.reference_doctype), (data.name, recurring_id)) - if reference_data: - doc.start_date = reference_data.get('posting_date') or reference_data.get('transaction_date') - doc.from_date = reference_data.get('from_date') - doc.to_date = reference_data.get('to_date') - doc.set_next_schedule_date() - doc.db_update() \ No newline at end of file + date_field = 'transaction_date' + if data.reference_doctype in ['Sales Invoice', 'Purchase Invoice']: + date_field = 'posting_date' + + start_date = frappe.db.get_value(data.reference_doctype, data.reference_document, date_field) + + if start_date and getdate(start_date) != getdate(data.start_date): + last_ref_date = frappe.db.sql(""" + select {0} + from `tab{1}` + where subscription=%s and docstatus < 2 + order by creation desc + limit 1 + """.format(date_field, data.reference_doctype), data.name)[0][0] + + next_schedule_date = get_next_schedule_date(last_ref_date, data.frequency, data.repeat_on_day) + + frappe.db.set_value("Subscription", data.name, { + "start_date": start_date, + "next_schedule_date": next_schedule_date + }, None) \ No newline at end of file diff --git a/erpnext/patches/v9_0/set_uoms_in_variant_field.py b/erpnext/patches/v9_0/set_uoms_in_variant_field.py new file mode 100644 index 0000000000..9e783d99be --- /dev/null +++ b/erpnext/patches/v9_0/set_uoms_in_variant_field.py @@ -0,0 +1,14 @@ +from __future__ import unicode_literals +import frappe + + +def execute(): + doc = frappe.get_doc('Item Variant Settings') + variant_field_names = [vf.field_name for vf in doc.fields] + if 'uoms' not in variant_field_names: + doc.append( + 'fields', { + 'field_name': 'uoms' + } + ) + doc.save() diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 5b647f80d2..41fdc6e646 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -542,11 +542,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ } // Make read only if Accounts Settings doesn't allow stale rates - frappe.model.get_value("Accounts Settings", null, "allow_stale", - function(d){ - me.set_df_property("conversion_rate", "read_only", cint(d.allow_stale) ? 0 : 1); - } - ); + this.frm.set_df_property("conversion_rate", "read_only", erpnext.stale_rate_allowed()); }, set_actual_charges_based_on_currency: function() { diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index 721f216888..efb04d1c09 100644 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -37,6 +37,10 @@ $.extend(erpnext, { } }, + stale_rate_allowed: () => { + return cint(frappe.boot.sysdefaults.allow_stale) || 1; + }, + setup_serial_no: function() { var grid_row = cur_frm.open_grid_row(); if(!grid_row || !grid_row.grid_form.fields_dict.serial_no || diff --git a/erpnext/schools/doctype/fees/fees.py b/erpnext/schools/doctype/fees/fees.py index 42b329e4b7..bfe6af4bdb 100644 --- a/erpnext/schools/doctype/fees/fees.py +++ b/erpnext/schools/doctype/fees/fees.py @@ -112,7 +112,7 @@ def get_fee_list(doctype, txt, filters, limit_start, limit_page_length=20, order user = frappe.session.user student = frappe.db.sql("select name from `tabStudent` where student_email_id= %s", user) if student: - return frappe. db.sql('''select name, program, due_date, paid_amount, outstanding_amount, total_amount from `tabFees` + return frappe. db.sql('''select name, program, due_date, paid_amount, outstanding_amount, grand_total from `tabFees` where student= %s and docstatus=1 order by due_date asc limit {0} , {1}''' .format(limit_start, limit_page_length), student, as_dict = True) diff --git a/erpnext/schools/report/student_fee_collection/student_fee_collection.json b/erpnext/schools/report/student_fee_collection/student_fee_collection.json index 264638f821..5c63765cf8 100644 --- a/erpnext/schools/report/student_fee_collection/student_fee_collection.json +++ b/erpnext/schools/report/student_fee_collection/student_fee_collection.json @@ -5,14 +5,14 @@ "disabled": 0, "docstatus": 0, "doctype": "Report", - "idx": 2, + "idx": 3, "is_standard": "Yes", - "modified": "2017-02-24 20:05:08.514320", + "modified": "2017-10-25 11:59:26.003899", "modified_by": "Administrator", "module": "Schools", "name": "Student Fee Collection", "owner": "Administrator", - "query": "SELECT\n student as \"Student:Link/Student:200\",\n student_name as \"Student Name::200\",\n sum(paid_amount) as \"Paid Amount:Currency:150\",\n sum(outstanding_amount) as \"Outstanding Amount:Currency:150\",\n sum(total_amount) as \"Total Amount:Currency:150\"\nFROM\n `tabFees` \nGROUP BY\n student", + "query": "SELECT\n student as \"Student:Link/Student:200\",\n student_name as \"Student Name::200\",\n sum(paid_amount) as \"Paid Amount:Currency:150\",\n sum(outstanding_amount) as \"Outstanding Amount:Currency:150\",\n sum(grand_total) as \"Grand Total:Currency:150\"\nFROM\n `tabFees` \nGROUP BY\n student", "ref_doctype": "Fees", "report_name": "Student Fee Collection", "report_type": "Query Report", diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json index b57895ad7c..36f1284c43 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.json +++ b/erpnext/selling/doctype/sales_order/sales_order.json @@ -3272,419 +3272,13 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "subscription", - "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": "Subscription", - "length": 0, - "no_copy": 0, - "options": "Subscription", - "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": 1, - "collapsible_depends_on": "is_recurring", - "columns": 0, - "depends_on": "eval:doc.docstatus<2 && !doc.__islocal", - "fieldname": "recurring_order", - "fieldtype": "Section Break", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Recurring Order", - "length": 0, - "no_copy": 0, - "options": "fa fa-time", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "settings", - "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, - "label": "Settings", - "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": 1, "bold": 0, "collapsible": 0, "columns": 0, - "depends_on": "eval:doc.docstatus<2", - "description": "", - "fieldname": "is_recurring", - "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": "Is Recurring", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "is_recurring", - "description": "", - "fieldname": "recurring_id", - "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": "Reference Document", - "length": 0, - "no_copy": 1, - "options": "Sales Order", - "permlevel": 0, - "print_hide": 1, - "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": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", - "description": "", - "fieldname": "recurring_type", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Frequency", - "length": 0, - "no_copy": 1, - "options": "\nMonthly\nQuarterly\nHalf-yearly\nYearly", - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", - "description": "", - "fieldname": "repeat_on_day_of_month", - "fieldtype": "Int", - "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": "Repeat on Day of Month", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", - "description": "", - "fieldname": "end_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": "Recurring Upto", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", - "fieldname": "submit_on_creation", - "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": "Submit on creation", - "length": 0, - "no_copy": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name", - "description": "", - "fieldname": "notify_by_email", - "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": "Notify by email", - "length": 0, - "no_copy": 1, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.notify_by_email && doc.recurring_id === doc.name", - "description": "", - "fieldname": "notification_email_address", - "fieldtype": "Code", - "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": "Notification Email Address", - "length": 0, - "no_copy": 1, - "options": "Email", - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_recurring && doc.notify_by_email && doc.recurring_id === doc.name", - "fieldname": "recurring_print_format", - "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": "Recurring Print Format", - "length": 0, - "no_copy": 0, - "options": "Print Format", - "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_break83", - "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, - "label": "This Document", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "is_recurring", + "depends_on": "", "description": "", "fieldname": "from_date", "fieldtype": "Date", @@ -3715,7 +3309,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "depends_on": "is_recurring", + "depends_on": "", "description": "", "fieldname": "to_date", "fieldtype": "Date", @@ -3746,10 +3340,8 @@ "bold": 0, "collapsible": 0, "columns": 0, - "depends_on": "is_recurring", - "description": "", - "fieldname": "next_date", - "fieldtype": "Date", + "fieldname": "column_break_108", + "fieldtype": "Column Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -3757,11 +3349,42 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Next Date", "length": 0, - "no_copy": 1, + "no_copy": 0, "permlevel": 0, - "print_hide": 1, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "subscription", + "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": "Subscription", + "length": 0, + "no_copy": 0, + "options": "Subscription", + "permlevel": 0, + "precision": "", + "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, "remember_last_selected_value": 0, @@ -3783,7 +3406,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-09-19 11:21:36.332326", + "modified": "2017-10-24 12:52:28.115742", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order", diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index c3e28d21c7..fa21a3d7ee 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -347,15 +347,15 @@ class SalesOrder(SellingController): return items def on_recurring(self, reference_doc, subscription_doc): - self.set("delivery_date", get_next_schedule_date(reference_doc.delivery_date, subscription_doc.frequency, - cint(subscription_doc.repeat_on_day))) + self.set("delivery_date", get_next_schedule_date(reference_doc.delivery_date, + subscription_doc.frequency, cint(subscription_doc.repeat_on_day))) for d in self.get("items"): reference_delivery_date = frappe.db.get_value("Sales Order Item", {"parent": reference_doc.name, "item_code": d.item_code, "idx": d.idx}, "delivery_date") - d.set("delivery_date", - get_next_schedule_date(reference_delivery_date, subscription_doc.frequency, cint(subscription_doc.repeat_on_day))) + d.set("delivery_date", get_next_schedule_date(reference_delivery_date, + subscription_doc.frequency, cint(subscription_doc.repeat_on_day))) def get_list_context(context=None): from erpnext.controllers.website_list_for_contact import get_list_context diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js index 5feae9c28a..e23dcdbc95 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.js +++ b/erpnext/selling/page/point_of_sale/point_of_sale.js @@ -113,6 +113,9 @@ erpnext.pos.PointOfSale = class PointOfSale { }, on_select_change: () => { this.cart.numpad.set_inactive(); + }, + get_item_details: (item_code) => { + return this.items.get(item_code); } } }); @@ -408,6 +411,7 @@ erpnext.pos.PointOfSale = class PointOfSale { class POSCart { constructor({frm, wrapper, pos_profile, events}) { this.frm = frm; + this.item_data = {}; this.wrapper = wrapper; this.events = events; this.pos_profile = pos_profile; @@ -667,7 +671,8 @@ class POSCart { const $item = this.$cart_items.find(`[data-item-code="${item.item_code}"]`); if(item.qty > 0) { - const indicator_class = item.actual_qty >= item.qty ? 'green' : 'red'; + const is_stock_item = this.get_item_details(item.item_code).is_stock_item; + const indicator_class = (!is_stock_item || item.actual_qty >= item.qty) ? 'green' : 'red'; const remove_class = indicator_class == 'green' ? 'red' : 'green'; $item.find('.quantity input').val(item.qty); @@ -681,8 +686,9 @@ class POSCart { } get_item_html(item) { + const is_stock_item = this.get_item_details(item.item_code).is_stock_item; const rate = format_currency(item.rate, this.frm.doc.currency); - const indicator_class = item.actual_qty >= item.qty ? 'green' : 'red'; + const indicator_class = (!is_stock_item || item.actual_qty >= item.qty) ? 'green' : 'red'; return `
@@ -717,6 +723,14 @@ class POSCart { } } + get_item_details(item_code) { + if (!this.item_data[item_code]) { + this.item_data[item_code] = this.events.get_item_details(item_code); + } + + return this.item_data[item_code]; + } + exists(item_code) { let $item = this.$cart_items.find(`[data-item-code="${item_code}"]`); return $item.length > 0; @@ -965,11 +979,13 @@ class POSItems { this.search_index = this.search_index || {}; if (this.search_index[search_term]) { const items = this.search_index[search_term]; + this.items = items; this.render_items(items); this.set_item_in_the_cart(items); return; } } else if (item_group == "All Item Groups") { + this.items = this.all_items; return this.render_items(this.all_items); } @@ -979,6 +995,7 @@ class POSItems { this.search_index[search_term] = items; } + this.items = items; this.render_items(items); this.set_item_in_the_cart(items, serial_no, batch_no); }); @@ -1021,7 +1038,14 @@ class POSItems { } get(item_code) { - return this.items[item_code]; + let item = {}; + this.items.map(data => { + if (data.item_code === item_code) { + item = data; + } + }) + + return item } get_all() { diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.py b/erpnext/selling/page/point_of_sale/point_of_sale.py index b92c653030..7400e432ae 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.py +++ b/erpnext/selling/page/point_of_sale/point_of_sale.py @@ -36,7 +36,7 @@ def get_items(start, page_length, price_list, item_group, search_value=""): lft, rgt = frappe.db.get_value('Item Group', item_group, ['lft', 'rgt']) # locate function is used to sort by closest match from the beginning of the value res = frappe.db.sql("""select i.name as item_code, i.item_name, i.image as item_image, - item_det.price_list_rate, item_det.currency + i.is_stock_item, item_det.price_list_rate, item_det.currency from `tabItem` i LEFT JOIN (select item_code, price_list_rate, currency from `tabItem Price` where price_list=%(price_list)s) item_det diff --git a/erpnext/startup/boot.py b/erpnext/startup/boot.py index 3164306109..2080224a70 100644 --- a/erpnext/startup/boot.py +++ b/erpnext/startup/boot.py @@ -19,6 +19,8 @@ def boot_session(bootinfo): 'territory') bootinfo.sysdefaults.customer_group = frappe.db.get_single_value('Selling Settings', 'customer_group') + bootinfo.sysdefaults.allow_stale = frappe.db.get_single_value('Accounts Settings', + 'allow_stale') or 1 bootinfo.notification_settings = frappe.get_doc("Notification Control", "Notification Control") diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index baa59bf14f..6f3fce5ba2 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -103,6 +103,11 @@ frappe.ui.form.on("Item", { frappe.set_route("Form", "Item Variant Settings"); }, __("View")); } + + if(frm.doc.__onload && frm.doc.__onload.stock_exists) { + // Hide variants section if stock exists + frm.toggle_display("variants_section", 0); + } }, validate: function(frm){ diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json index 05525ab54f..fd85a50d40 100644 --- a/erpnext/stock/doctype/item/item.json +++ b/erpnext/stock/doctype/item/item.json @@ -1102,7 +1102,7 @@ "in_standard_filter": 0, "label": "UOMs", "length": 0, - "no_copy": 1, + "no_copy": 0, "oldfieldname": "uom_conversion_details", "oldfieldtype": "Table", "options": "UOM Conversion Detail", @@ -3329,7 +3329,7 @@ "issingle": 0, "istable": 0, "max_attachments": 1, - "modified": "2017-10-03 14:08:02.948326", + "modified": "2017-10-25 14:08:02.948326", "modified_by": "Administrator", "module": "Stock", "name": "Item", diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index e7ed5d0076..4b4f15bf41 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -17,6 +17,7 @@ from erpnext.controllers.item_variant import (get_variant, copy_attributes_to_va make_variant_item_code, validate_item_variant_attributes, ItemVariantExistsError) class DuplicateReorderRows(frappe.ValidationError): pass +class StockExistsForTemplate(frappe.ValidationError): pass class Item(WebsiteGenerator): website = frappe._dict( @@ -28,11 +29,15 @@ class Item(WebsiteGenerator): def onload(self): super(Item, self).onload() + self.set_onload('sle_exists', self.check_if_sle_exists()) if self.is_fixed_asset: asset = frappe.db.get_all("Asset", filters={"item_code": self.name, "docstatus": 1}, limit=1) self.set_onload("asset_exists", True if asset else False) + if frappe.db.get_value('Stock Ledger Entry', {'item_code': self.name}): + self.set_onload('stock_exists', True) + def autoname(self): if frappe.db.get_default("item_naming_by")=="Naming Series": if self.variant_of: @@ -90,6 +95,7 @@ class Item(WebsiteGenerator): self.synced_with_hub = 0 self.validate_has_variants() + self.validate_stock_exists_for_template_item() self.validate_attributes() self.validate_variant_attributes() self.validate_website_image() @@ -636,6 +642,12 @@ class Item(WebsiteGenerator): if frappe.db.exists("Item", {"variant_of": self.name}): frappe.throw(_("Item has variants.")) + def validate_stock_exists_for_template_item(self): + if self.has_variants and \ + frappe.db.get_value('Stock Ledger Entry', {'item_code': self.name}): + frappe.throw(_("As stock exists against an item {0}, you can not enable has variants property") + .format(self.name), StockExistsForTemplate) + def validate_uom(self): if not self.get("__islocal"): check_stock_uom_with_bin(self.name, self.stock_uom) diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py index 5cf98a1a4d..8693414360 100644 --- a/erpnext/stock/doctype/item/test_item.py +++ b/erpnext/stock/doctype/item/test_item.py @@ -8,6 +8,7 @@ import frappe from frappe.test_runner import make_test_records from erpnext.controllers.item_variant import (create_variant, ItemVariantExistsError, InvalidItemAttributeValueError, get_variant) +from erpnext.stock.doctype.item.item import StockExistsForTemplate from frappe.model.rename_doc import rename_doc from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry @@ -264,6 +265,15 @@ class TestItem(unittest.TestCase): self.assertEquals(variant.manufacturer, 'MSG1') self.assertEquals(variant.manufacturer_part_no, '007') + def test_stock_exists_against_template_item(self): + stock_item = frappe.get_all('Stock Ledger Entry', fields = ["item_code"], limit=1) + if stock_item: + item_code = stock_item[0].item_code + + item_doc = frappe.get_doc('Item', item_code) + item_doc.has_variants = 1 + self.assertRaises(StockExistsForTemplate, item_doc.save) + def set_item_variant_settings(fields): doc = frappe.get_doc('Item Variant Settings') doc.set('fields', fields) diff --git a/erpnext/templates/emails/recurring_document_failed.html b/erpnext/templates/emails/recurring_document_failed.html index 27c43bc0fc..f9e8c2dafc 100644 --- a/erpnext/templates/emails/recurring_document_failed.html +++ b/erpnext/templates/emails/recurring_document_failed.html @@ -2,8 +2,8 @@

{{_("An error occured while creating recurring")}} {{ type }} {{ name }} {{_("for")}} {{ party }}.

{{_("This could be because of some invalid Email Addresses in the")}} {{ type }}.

-

{{_("To stop sending repetitive error notifications from the system, we have checked "Disabled" field in the subscription")}} {{ subscription}} {{_("for the")}} {{ type }} {{ name }}.

-

{{_("Please correct the")}} {{ type }} {{_('and unchcked "Disabled" in the')}} {{ subscription }} {{_("for making recurring again.")}}

+

{{_("To stop sending repetitive error notifications from the system, we have checked Disabled field in the subscription")}} {{ subscription}} {{_("for the")}} {{ type }} {{ name }}.

+

{{_("Please correct the")}} {{ type }} {{_('and unchcked Disabled in the')}} {{ subscription }} {{_("for making recurring again.")}}


{{_("It is necessary to take this action today itself for the above mentioned recurring")}} {{ type }} {{_('to be generated. If delayed, you will have to manually change the "Repeat on Day of Month" field