diff --git a/.travis.yml b/.travis.yml index ad9822d187b..70df757fa3f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,7 @@ before_script: - bench reinstall --yes - bench build - bench scheduler disable + - sed -i 's/9000/9001/g' sites/common_site_config.json - bench start & - sleep 10 diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 540e2233761..ea1a4023e55 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.28' +__version__ = '10.1.29' def get_default_company(user=None): '''Get default company for user''' diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index a3ad049abfb..4b497d00dfd 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -346,8 +346,8 @@ class SalesInvoice(SellingController): self.terms = frappe.db.get_value("Terms and Conditions", self.tc_name, "terms") # fetch charges - if self.taxes_and_charges and not len(self.get("taxes")): - self.set_taxes() + if self.taxes_and_charges: + self.set_other_charges() return pos diff --git a/erpnext/healthcare/doctype/consultation/consultation.py b/erpnext/healthcare/doctype/consultation/consultation.py index 451c4914b09..472a2f2946f 100755 --- a/erpnext/healthcare/doctype/consultation/consultation.py +++ b/erpnext/healthcare/doctype/consultation/consultation.py @@ -108,9 +108,11 @@ def insert_consultation_to_medical_record(doc): def update_consultation_to_medical_record(consultation): medical_record_id = frappe.db.sql("select name from `tabPatient Medical Record` where reference_name=%s", (consultation.name)) - if(medical_record_id[0][0]): + if medical_record_id and medical_record_id[0][0]: subject = set_subject_field(consultation) frappe.db.set_value("Patient Medical Record", medical_record_id[0][0], "subject", subject) + else: + insert_consultation_to_medical_record(consultation) def delete_medical_record(consultation): frappe.db.sql("""delete from `tabPatient Medical Record` where reference_name = %s""", (consultation.name)) diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.py b/erpnext/healthcare/doctype/lab_test/lab_test.py index 766491d3189..c910d7cc884 100644 --- a/erpnext/healthcare/doctype/lab_test/lab_test.py +++ b/erpnext/healthcare/doctype/lab_test/lab_test.py @@ -244,7 +244,7 @@ def insert_lab_test_to_medical_record(doc): def delete_lab_test_from_medical_record(self): medical_record_id = frappe.db.sql("select name from `tabPatient Medical Record` where reference_name=%s",(self.name)) - if(medical_record_id[0][0]): + if medical_record_id and medical_record_id[0][0]: frappe.delete_doc("Patient Medical Record", medical_record_id[0][0]) def create_item_line(test_code, sales_invoice): diff --git a/erpnext/healthcare/doctype/vital_signs/vital_signs.py b/erpnext/healthcare/doctype/vital_signs/vital_signs.py index a42ff02ea20..41d9258a760 100644 --- a/erpnext/healthcare/doctype/vital_signs/vital_signs.py +++ b/erpnext/healthcare/doctype/vital_signs/vital_signs.py @@ -27,7 +27,7 @@ def insert_vital_signs_to_medical_record(doc): def delete_vital_signs_from_medical_record(doc): medical_record_id = frappe.db.sql("select name from `tabPatient Medical Record` where reference_name=%s",(doc.name)) - if(medical_record_id[0][0]): + if medical_record_id and medical_record_id[0][0]: frappe.delete_doc("Patient Medical Record", medical_record_id[0][0]) def set_subject_field(doc): diff --git a/erpnext/hr/doctype/hr_settings/hr_settings.json b/erpnext/hr/doctype/hr_settings/hr_settings.json index d1e02be1c6a..225785d305d 100644 --- a/erpnext/hr/doctype/hr_settings/hr_settings.json +++ b/erpnext/hr/doctype/hr_settings/hr_settings.json @@ -452,6 +452,66 @@ "set_only_once": 0, "translatable": 0, "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "leave_settings", + "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": "Leave 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": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "show_leaves_of_all_department_members_in_calendar", + "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 Leaves Of All Department Members In Calendar", + "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, @@ -465,7 +525,7 @@ "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2018-04-14 17:09:15.904645", + "modified": "2018-05-03 15:36:13.015466", "modified_by": "Administrator", "module": "HR", "name": "HR Settings", diff --git a/erpnext/hr/doctype/hr_settings/test_hr_settings.py b/erpnext/hr/doctype/hr_settings/test_hr_settings.py index 00f183e60a5..2d5b18b6fbb 100644 --- a/erpnext/hr/doctype/hr_settings/test_hr_settings.py +++ b/erpnext/hr/doctype/hr_settings/test_hr_settings.py @@ -3,6 +3,7 @@ # See license.txt from __future__ import unicode_literals +import frappe import unittest class TestHRSettings(unittest.TestCase): diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py index d225463b6f8..069e6eebab4 100755 --- a/erpnext/hr/doctype/leave_application/leave_application.py +++ b/erpnext/hr/doctype/leave_application/leave_application.py @@ -404,16 +404,29 @@ def add_department_leaves(events, start, end, employee, company): and company=%s""", (department, company)) match_conditions = "and employee in (\"%s\")" % '", "'.join(department_employees) - add_leaves(events, start, end, match_conditions=match_conditions) + add_leaves(events, start, end, filter_conditions=match_conditions) -def add_leaves(events, start, end, match_conditions=None): - query = """select name, from_date, to_date, employee_name, color, half_day, - employee, docstatus +def add_leaves(events, start, end, filter_conditions=None): + conditions = [] + + if filter_conditions: + conditions.append(filter_conditions) + + if not cint(frappe.db.get_value("HR Settings", None, "show_leaves_of_all_department_members_in_calendar")): + from frappe.desk.reportview import build_match_conditions + match_conditions = build_match_conditions("Leave Application") + + if match_conditions: + conditions.append(match_conditions) + + query = """select name, from_date, to_date, employee_name, half_day, + status, employee, docstatus from `tabLeave Application` where from_date <= %(end)s and to_date >= %(start)s <= to_date and docstatus < 2""" - if match_conditions: - query += match_conditions + + if conditions: + query += ' and '.join(conditions) for d in frappe.db.sql(query, {"start":start, "end": end}, as_dict=True): e = { diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 17d68ef93e2..d138587e22d 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -527,3 +527,6 @@ erpnext.patches.v10_1.transfer_subscription_to_auto_repeat erpnext.patches.v10_1.drop_old_subscription_records erpnext.patches.v11_0.update_brand_in_item_price erpnext.patches.v11_0.create_default_success_action +erpnext.patches.v10_0.taxes_issue_with_pos +erpnext.patches.v10_0.set_qty_in_transactions_based_on_serial_no_input +erpnext.patches.v10_0.show_leaves_of_all_department_members_in_calendar diff --git a/erpnext/patches/v10_0/set_qty_in_transactions_based_on_serial_no_input.py b/erpnext/patches/v10_0/set_qty_in_transactions_based_on_serial_no_input.py new file mode 100644 index 00000000000..5dbcb1d38fa --- /dev/null +++ b/erpnext/patches/v10_0/set_qty_in_transactions_based_on_serial_no_input.py @@ -0,0 +1,12 @@ +# Copyright (c) 2017, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe + +def execute(): + frappe.reload_doc("stock", "doctype", "stock_settings") + + ss = frappe.get_doc("Stock Settings") + ss.set_qty_in_transactions_based_on_serial_no_input = 1 + ss.save() \ No newline at end of file diff --git a/erpnext/patches/v10_0/show_leaves_of_all_department_members_in_calendar.py b/erpnext/patches/v10_0/show_leaves_of_all_department_members_in_calendar.py new file mode 100644 index 00000000000..1ae8b4a54e3 --- /dev/null +++ b/erpnext/patches/v10_0/show_leaves_of_all_department_members_in_calendar.py @@ -0,0 +1,5 @@ +import frappe + +def execute(): + frappe.reload_doc("hr", "doctype", "hr_settings") + frappe.db.set_value("HR Settings", None, "show_leaves_of_all_department_members_in_calendar", 1) \ No newline at end of file diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 102090b812d..05bc104ca53 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -400,7 +400,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ item.serial_no = valid_serial_nos.join('\n'); refresh_field("serial_no", item.name, item.parentfield); - if(!doc.is_return) { + if(!doc.is_return && cint(user_defaults.set_qty_in_transactions_based_on_serial_no_input)) { frappe.model.set_value(item.doctype, item.name, "qty", valid_serial_nos.length / item.conversion_factor); frappe.model.set_value(item.doctype, item.name, "stock_qty", valid_serial_nos.length); diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py index 50a2e0de8fd..f9e01561f8c 100644 --- a/erpnext/regional/report/gstr_1/gstr_1.py +++ b/erpnext/regional/report/gstr_1/gstr_1.py @@ -143,7 +143,17 @@ class Gstr1Report(object): """ % (self.doctype, ', '.join(['%s']*len(self.invoices))), tuple(self.invoices), as_dict=1) for d in items: - self.invoice_items.setdefault(d.parent, {}).setdefault(d.item_code, d.base_net_amount) + item_details = {} + item_details[d.item_code] = d.base_net_amount + + if d.parent in self.invoice_items: + parent_dict = self.invoice_items[d.parent] + if d.item_code in parent_dict: + item_details[d.item_code] += parent_dict[d.item_code] + else: + item_details.update(parent_dict) + + self.invoice_items[d.parent] = item_details def get_items_based_on_tax_rate(self): self.tax_details = frappe.db.sql(""" diff --git a/erpnext/setup/setup_wizard/operations/defaults_setup.py b/erpnext/setup/setup_wizard/operations/defaults_setup.py index f5b1e984f7e..086b60e3066 100644 --- a/erpnext/setup/setup_wizard/operations/defaults_setup.py +++ b/erpnext/setup/setup_wizard/operations/defaults_setup.py @@ -36,6 +36,7 @@ def set_default_settings(args): stock_settings.auto_indent = 1 stock_settings.auto_insert_price_list_rate_if_missing = 1 stock_settings.automatically_set_serial_nos_based_on_fifo = 1 + stock_settings.set_qty_in_transactions_based_on_serial_no_input = 1 stock_settings.save() selling_settings = frappe.get_doc("Selling Settings") diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index 611b3fd94c1..31cb828f5a9 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -631,19 +631,20 @@ class Item(WebsiteGenerator): def update_template_item(self): """Set Show in Website for Template Item if True for its Variant""" - if self.variant_of and self.show_in_website: - self.show_variant_in_website = 1 - self.show_in_website = 0 + if self.variant_of: + if self.show_in_website: + self.show_variant_in_website = 1 + self.show_in_website = 0 - if self.show_variant_in_website: - # show template - template_item = frappe.get_doc("Item", self.variant_of) + if self.show_variant_in_website: + # show template + template_item = frappe.get_doc("Item", self.variant_of) - if not template_item.show_in_website: - template_item.show_in_website = 1 - template_item.flags.dont_update_variants = True - template_item.flags.ignore_permissions = True - template_item.save() + if not template_item.show_in_website: + template_item.show_in_website = 1 + template_item.flags.dont_update_variants = True + template_item.flags.ignore_permissions = True + template_item.save() def update_variants(self): if self.flags.dont_update_variants or \ @@ -667,10 +668,10 @@ class Item(WebsiteGenerator): def validate_stock_exists_for_template_item(self): if self.stock_ledger_created() and self._doc_before_save: - if (self._doc_before_save.has_variants != self.has_variants - or self._doc_before_save.variant_of != self.variant_of): - frappe.throw(_("Cannot change Variant properties after stock transction. You will have to make a new Item to do this.").format(self.name), - StockExistsForTemplate) + if (cint(self._doc_before_save.has_variants) != cint(self.has_variants) + or self._doc_before_save.variant_of != self.variant_of): + frappe.throw(_("Cannot change Variant properties after stock transaction. You will have to make a new Item to do this.").format(self.name), + StockExistsForTemplate) if self.has_variants or self.variant_of: if not self.is_child_table_same('attributes'): diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py index a6d2a0b06fe..020a8bc1f7c 100644 --- a/erpnext/stock/doctype/serial_no/serial_no.py +++ b/erpnext/stock/doctype/serial_no/serial_no.py @@ -200,7 +200,7 @@ def validate_serial_no(sle, item_det): frappe.throw(_("Serial No {0} quantity {1} cannot be a fraction").format(sle.item_code, sle.actual_qty)) if len(serial_nos) and len(serial_nos) != abs(cint(sle.actual_qty)): - frappe.throw(_("{0} Serial Numbers required for Item {1}. You have provided {2}.").format(sle.actual_qty, sle.item_code, len(serial_nos)), + frappe.throw(_("{0} Serial Numbers required for Item {1}. You have provided {2}.").format(abs(sle.actual_qty), sle.item_code, len(serial_nos)), SerialNoQtyError) if len(serial_nos) != len(set(serial_nos)): diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.json b/erpnext/stock/doctype/stock_settings/stock_settings.json index 48f89ec20fd..4d5423e5476 100644 --- a/erpnext/stock/doctype/stock_settings/stock_settings.json +++ b/erpnext/stock/doctype/stock_settings/stock_settings.json @@ -464,6 +464,37 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "1", + "fieldname": "set_qty_in_transactions_based_on_serial_no_input", + "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": "Set Qty in Transactions based on Serial No Input", + "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, @@ -773,7 +804,7 @@ "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2018-01-12 09:38:58.200950", + "modified": "2018-05-03 12:38:12.905394", "modified_by": "Administrator", "module": "Stock", "name": "Stock Settings", diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.py b/erpnext/stock/doctype/stock_settings/stock_settings.py index 23a18f4e31c..97d24c6c94c 100644 --- a/erpnext/stock/doctype/stock_settings/stock_settings.py +++ b/erpnext/stock/doctype/stock_settings/stock_settings.py @@ -11,8 +11,9 @@ from frappe.utils.html_utils import clean_html class StockSettings(Document): def validate(self): - for key in ["item_naming_by", "item_group", "stock_uom", "allow_negative_stock", "default_warehouse"]: - frappe.db.set_default(key, self.get(key, "")) + for key in ["item_naming_by", "item_group", "stock_uom", + "allow_negative_stock", "default_warehouse", "set_qty_in_transactions_based_on_serial_no_input"]: + frappe.db.set_default(key, self.get(key, "")) from erpnext.setup.doctype.naming_series.naming_series import set_by_naming_series set_by_naming_series("Item", "item_code",