diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 97ab9343d2a3..e88e00d9fc97 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals import frappe -__version__ = '7.1.23' +__version__ = '7.1.24' def get_default_company(user=None): '''Get default company for user''' diff --git a/erpnext/accounts/doctype/account/account_tree.js b/erpnext/accounts/doctype/account/account_tree.js index 4cf9a678f803..8b2f14db5862 100644 --- a/erpnext/accounts/doctype/account/account_tree.js +++ b/erpnext/accounts/doctype/account/account_tree.js @@ -34,7 +34,7 @@ frappe.treeview_settings["Account"] = { description: __("Optional. This setting will be used to filter in various transactions.") }, {fieldtype:'Float', fieldname:'tax_rate', label:__('Tax Rate'), - depends_on: 'eval:doc.is_group==1&&doc.account_type=="Tax"'}, + depends_on: 'eval:doc.is_group==0&&doc.account_type=="Tax"'}, {fieldtype:'Link', fieldname:'warehouse', label:__('Warehouse'), options:"Warehouse", depends_on: 'eval:(!doc.is_group&&doc.account_type=="Stock")', get_query: function() { diff --git a/erpnext/accounts/doctype/payment_request/payment_request.json b/erpnext/accounts/doctype/payment_request/payment_request.json index 50946c374226..3619ccb7137c 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.json +++ b/erpnext/accounts/doctype/payment_request/payment_request.json @@ -32,6 +32,7 @@ "print_hide": 1, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, "search_index": 0, @@ -58,6 +59,7 @@ "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, @@ -86,6 +88,7 @@ "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, @@ -112,6 +115,7 @@ "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, @@ -138,6 +142,7 @@ "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, @@ -163,6 +168,7 @@ "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, @@ -190,6 +196,7 @@ "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, @@ -217,6 +224,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -245,6 +253,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -273,6 +282,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -300,6 +310,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -325,6 +336,7 @@ "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, @@ -351,6 +363,7 @@ "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, @@ -378,6 +391,7 @@ "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, @@ -404,6 +418,7 @@ "print_hide": 1, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 1, "reqd": 0, "search_index": 0, @@ -416,7 +431,7 @@ "collapsible": 0, "columns": 0, "fieldname": "payment_url", - "fieldtype": "Data", + "fieldtype": "Small Text", "hidden": 1, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -430,6 +445,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -457,6 +473,7 @@ "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, @@ -484,6 +501,7 @@ "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, @@ -511,6 +529,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -537,6 +556,7 @@ "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, @@ -564,6 +584,7 @@ "print_hide": 1, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 1, "reqd": 0, "search_index": 0, @@ -591,6 +612,7 @@ "print_hide": 1, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 1, "reqd": 0, "search_index": 0, @@ -617,6 +639,7 @@ "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, @@ -634,7 +657,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2016-09-02 04:07:15.279949", + "modified": "2016-12-12 13:30:42.858205", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Request", @@ -651,6 +674,7 @@ "export": 1, "if_owner": 0, "import": 0, + "is_custom": 0, "permlevel": 0, "print": 1, "read": 1, @@ -671,6 +695,7 @@ "export": 1, "if_owner": 0, "import": 0, + "is_custom": 0, "permlevel": 0, "print": 1, "read": 1, diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.js b/erpnext/accounts/doctype/pos_profile/pos_profile.js index bbbab73e1c2a..c1aa0c3cb52b 100755 --- a/erpnext/accounts/doctype/pos_profile/pos_profile.js +++ b/erpnext/accounts/doctype/pos_profile/pos_profile.js @@ -26,30 +26,6 @@ frappe.ui.form.on("POS Profile", "onload", function(frm) { }); }); -frappe.ui.form.on("POS Profile", { - setup: function(frm) { - frm.trigger("get_query_for_groups") - }, - - get_query_for_groups: function(frm) { - frm.fields_dict['item_groups'].grid.get_field('item_group').get_query = function(frm, cdt, cdn) { - return{ - filters: { - 'is_group': 0 - } - } - } - - frm.fields_dict['customer_groups'].grid.get_field('customer_group').get_query = function(frm, cdt, cdn) { - return{ - filters: { - 'is_group': 0 - } - } - } - } -}) - // Income Account // -------------------------------- cur_frm.fields_dict['income_account'].get_query = function(doc,cdt,cdn) { diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py index f298bc88f91f..b36898a8078f 100644 --- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py +++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py @@ -126,6 +126,8 @@ def get_pricing_rule_for_item(args): }) if args.ignore_pricing_rule or not args.item_code: + if args.name and args.get("pricing_rule"): + item_details = remove_pricing_rule(args, item_details) return item_details if not (args.item_group and args.brand): @@ -166,9 +168,16 @@ def get_pricing_rule_for_item(args): else: item_details.discount_percentage = pricing_rule.discount_percentage elif args.get('pricing_rule'): - if frappe.db.get_value('Pricing Rule', args.get('pricing_rule'), 'price_or_discount') == 'Discount Percentage': - item_details.discount_percentage = 0.0 + item_details = remove_pricing_rule(args, item_details) + return item_details + +def remove_pricing_rule(args, item_details): + pricing_rule = frappe.db.get_value('Pricing Rule', args.get('pricing_rule'), ['price_or_discount', 'margin_type'], as_dict=1) + if pricing_rule and pricing_rule.price_or_discount == 'Discount Percentage': + item_details.discount_percentage = 0.0 + + if pricing_rule and pricing_rule.margin_type in ['Percentage', 'Amount']: item_details.margin_rate_or_amount = 0.0 item_details.margin_type = None diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py index 4e4ad780ed61..75d98c5ae7d4 100644 --- a/erpnext/accounts/doctype/sales_invoice/pos.py +++ b/erpnext/accounts/doctype/sales_invoice/pos.py @@ -115,9 +115,9 @@ def get_items_list(pos_profile): item_groups = [] if pos_profile.get('item_groups'): # Get items based on the item groups defined in the POS profile - - cond = "item_group in (%s)"%(', '.join(['%s']*len(pos_profile.get('item_groups')))) - item_groups = [d.item_group for d in pos_profile.get('item_groups')] + for d in pos_profile.get('item_groups'): + item_groups.extend(get_child_nodes('Item Group', d.item_group)) + cond = "item_group in (%s)"%(', '.join(['%s']*len(item_groups))) return frappe.db.sql(""" select @@ -135,14 +135,19 @@ def get_customers_list(pos_profile): customer_groups = [] if pos_profile.get('customer_groups'): # Get customers based on the customer groups defined in the POS profile - - cond = "customer_group in (%s)"%(', '.join(['%s']*len(pos_profile.get('customer_groups')))) - customer_groups = [d.customer_group for d in pos_profile.get('customer_groups')] + for d in pos_profile.get('customer_groups'): + customer_groups.extend(get_child_nodes('Customer Group', d.customer_group)) + cond = "customer_group in (%s)"%(', '.join(['%s']*len(customer_groups))) return frappe.db.sql(""" select name, customer_name, customer_group, territory from tabCustomer where disabled = 0 and {cond}""".format(cond=cond), tuple(customer_groups), as_dict=1) or {} +def get_child_nodes(group_type, root): + lft, rgt = frappe.db.get_value(group_type, root, ["lft", "rgt"]) + return frappe.db.sql_list(""" Select name from `tab{tab}` where + lft >= {lft} and rgt <= {rgt}""".format(tab=group_type, lft=lft, rgt=rgt)) + def get_serial_no_data(pos_profile, company): # get itemwise serial no data # example {'Nokia Lumia 1020': {'SN0001': 'Pune'}} @@ -240,8 +245,7 @@ def make_invoice(doc_list): for docs in doc_list: for name, doc in docs.items(): - if not frappe.db.exists('Sales Invoice', - {'offline_pos_name': name, 'docstatus': ("<", "2")}): + if not frappe.db.exists('Sales Invoice', {'offline_pos_name': name}): validate_records(doc) si_doc = frappe.new_doc('Sales Invoice') si_doc.offline_pos_name = name @@ -286,6 +290,7 @@ def submit_invoice(si_doc, name): try: si_doc.insert() si_doc.submit() + frappe.db.commit() except Exception, e: if frappe.message_log: frappe.message_log.pop() frappe.db.rollback() diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py index 34022bd713f1..06028e2cfd18 100644 --- a/erpnext/hr/doctype/salary_slip/salary_slip.py +++ b/erpnext/hr/doctype/salary_slip/salary_slip.py @@ -223,7 +223,6 @@ def get_leave_details(self, joining_date=None, relieving_date=None, lwp=None): ["date_of_joining", "relieving_date"]) holidays = self.get_holidays_for_employee(self.start_date, self.end_date) - working_days = date_diff(self.end_date, self.start_date) + 1 if not cint(frappe.db.get_value("HR Settings", None, "include_holidays_in_total_working_days")): working_days -= len(holidays) diff --git a/erpnext/hr/doctype/salary_slip/test_records.json b/erpnext/hr/doctype/salary_slip/test_records.json deleted file mode 100644 index 20cef3db1852..000000000000 --- a/erpnext/hr/doctype/salary_slip/test_records.json +++ /dev/null @@ -1,45 +0,0 @@ -[ - { - "company": "_Test Company", - "doctype": "Salary Slip", - "deductions": [ - { - "doctype": "Salary Detail", - "amount": 100, - "depends_on_lwp": 0, - "salary_component": "_Test Professional Tax", - "parentfield": "deductions" - }, - { - "doctype": "Salary Detail", - "amount": 48.39, - "depends_on_lwp": 0, - "salary_component": "_Test TDS", - "parentfield": "deductions" - } - ], - "earnings": [ - { - "doctype": "Salary Detail", - "amount": 14516.13, - "depends_on_lwp": 0, - "salary_component": "_Test Basic Salary", - "parentfield": "earnings" - }, - { - "doctype": "Salary Detail", - "amount": 500, - "depends_on_lwp": 0, - "salary_component": "_Test Allowance", - "parentfield": "earnings" - } - ], - "employee": "_T-Employee-0001", - "employee_name": "_Test Employee", - "posting_date": "2013-02-01", - "fiscal_year": "_Test Fiscal Year 2013", - "month": "01", - "payment_days": 31, - "total_days_in_month": 31 - } -] \ No newline at end of file diff --git a/erpnext/hr/doctype/salary_slip/test_salary_slip.py b/erpnext/hr/doctype/salary_slip/test_salary_slip.py index 57a3711fc0b4..fafc2273c92e 100644 --- a/erpnext/hr/doctype/salary_slip/test_salary_slip.py +++ b/erpnext/hr/doctype/salary_slip/test_salary_slip.py @@ -5,32 +5,31 @@ import unittest import frappe import erpnext -from frappe.utils.make_random import get_random -from frappe.utils import today, now_datetime, getdate, cstr, add_years, nowdate +import calendar +from erpnext.accounts.utils import get_fiscal_year +from frappe.utils import getdate, nowdate, add_days from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip from erpnext.hr.doctype.process_payroll.test_process_payroll import get_salary_component_account class TestSalarySlip(unittest.TestCase): def setUp(self): - make_salary_component(["Basic Salary", "Allowance", "HRA", "Professional Tax", "TDS"]) + make_earning_salary_component(["Basic Salary", "Allowance", "HRA"]) + make_deduction_salary_component(["Professional Tax", "TDS"]) for dt in ["Leave Application", "Leave Allocation", "Salary Slip"]: frappe.db.sql("delete from `tab%s`" % dt) self.make_holiday_list() + frappe.db.set_value("Company", erpnext.get_default_company(), "default_holiday_list", "Salary Slip Test Holiday List") - from erpnext.hr.doctype.leave_application.test_leave_application import _test_records as leave_applications - la = frappe.copy_doc(leave_applications[2]) - la.insert() - la.status = "Approved" - la.submit() def tearDown(self): frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0) frappe.set_user("Administrator") def test_salary_slip_with_holidays_included(self): + no_of_days = self.get_no_of_days() frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 1) self.make_employee("test_employee@salary.com") frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None) @@ -38,8 +37,8 @@ def test_salary_slip_with_holidays_included(self): ss = frappe.get_doc("Salary Slip", self.make_employee_salary_slip("test_employee@salary.com")) - self.assertEquals(ss.total_days_in_month, 31) - self.assertEquals(ss.payment_days, 31) + self.assertEquals(ss.total_days_in_month, no_of_days[0]) + self.assertEquals(ss.payment_days, no_of_days[0]) self.assertEquals(ss.earnings[0].amount, 5000) self.assertEquals(ss.earnings[1].amount, 3000) self.assertEquals(ss.deductions[0].amount, 5000) @@ -48,6 +47,7 @@ def test_salary_slip_with_holidays_included(self): self.assertEquals(ss.net_pay, 3000) def test_salary_slip_with_holidays_excluded(self): + no_of_days = self.get_no_of_days() frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0) self.make_employee("test_employee@salary.com") frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None) @@ -55,8 +55,8 @@ def test_salary_slip_with_holidays_excluded(self): ss = frappe.get_doc("Salary Slip", self.make_employee_salary_slip("test_employee@salary.com")) - self.assertEquals(ss.total_days_in_month, 28) - self.assertEquals(ss.payment_days, 28) + self.assertEquals(ss.total_days_in_month, no_of_days[0] - no_of_days[1]) + self.assertEquals(ss.payment_days, no_of_days[0] - no_of_days[1]) self.assertEquals(ss.earnings[0].amount, 5000) self.assertEquals(ss.earnings[0].default_amount, 5000) self.assertEquals(ss.earnings[1].amount, 3000) @@ -66,37 +66,46 @@ def test_salary_slip_with_holidays_excluded(self): self.assertEquals(ss.net_pay, 3000) def test_payment_days(self): + no_of_days = self.get_no_of_days() # Holidays not included in working days - frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0) + frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 1) # set joinng date in the same month self.make_employee("test_employee@salary.com") - frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", "2013-01-11") + if getdate(nowdate()).day > 15: + date_of_joining = getdate(add_days(nowdate(),-10)) + relieving_date = getdate(add_days(nowdate(),-10)) + elif getdate(nowdate()).day < 15 and getdate(nowdate()).day > 5: + date_of_joining = getdate(add_days(nowdate(),-3)) + relieving_date = getdate(add_days(nowdate(),-3)) + elif getdate(nowdate()).day < 5 and not getdate(nowdate()).day == 1: + date_of_joining = getdate(add_days(nowdate(),-1)) + relieving_date = getdate(add_days(nowdate(),-1)) + elif getdate(nowdate()).day == 1: + date_of_joining = getdate(nowdate()) + relieving_date = getdate(nowdate()) + + frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", date_of_joining) + frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None) + frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active") ss = frappe.get_doc("Salary Slip", self.make_employee_salary_slip("test_employee@salary.com")) - self.assertEquals(ss.total_days_in_month, 28) - self.assertEquals(ss.payment_days, 28) + self.assertEquals(ss.total_days_in_month, no_of_days[0]) + self.assertEquals(ss.payment_days, (no_of_days[0] - getdate(date_of_joining).day + 1)) # set relieving date in the same month - frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", "12-12-2016") + frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", (add_days(nowdate(),-60))) + frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", relieving_date) frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Left") - - self.assertEquals(ss.total_days_in_month, 28) - self.assertEquals(ss.payment_days, 28) ss.save() + self.assertEquals(ss.total_days_in_month, no_of_days[0]) + self.assertEquals(ss.payment_days, getdate(relieving_date).day) + frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None) frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active") - # Holidays included in working days - frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 1) - self.assertEquals(ss.total_days_in_month, 28) - self.assertEquals(ss.payment_days, 28) - ss.save() - # - # frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", "2001-01-11") - # frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None) def test_employee_salary_slip_read_permission(self): self.make_employee("test_employee@salary.com") @@ -120,7 +129,6 @@ def test_email_salary_slip(self): email_queue = frappe.db.sql("""select name from `tabEmail Queue`""") self.assertTrue(email_queue) - def make_employee(self, user): if not frappe.db.get_value("User", user): frappe.get_doc({ @@ -148,29 +156,30 @@ def make_employee(self, user): "status": "Active", "employment_type": "Intern" }).insert() - + def make_holiday_list(self): + fiscal_year = get_fiscal_year(nowdate()) if not frappe.db.get_value("Holiday List", "Salary Slip Test Holiday List"): holiday_list = frappe.get_doc({ "doctype": "Holiday List", "holiday_list_name": "Salary Slip Test Holiday List", - "from_date": nowdate(), - "to_date": add_years(nowdate(), 1), + "from_date": fiscal_year[1], + "to_date": fiscal_year[2], "weekly_off": "Sunday" }).insert() holiday_list.get_weekly_off_dates() holiday_list.save() - + def make_employee_salary_slip(self, user): employee = frappe.db.get_value("Employee", {"user_id": user}) - salary_structure = make_salary_structure("Salary Structure Test for Salary Slip") + salary_structure = make_salary_structure("Salary Structure Test for Salary Slip", employee) salary_slip = frappe.db.get_value("Salary Slip", {"employee": frappe.db.get_value("Employee", {"user_id": user})}) if not salary_slip: salary_slip = make_salary_slip(salary_structure, employee = employee) salary_slip.employee_name = frappe.get_value("Employee", {"name":frappe.db.get_value("Employee", {"user_id": user})}, "employee_name") - salary_slip.month = "12" salary_slip.fiscal_year = "_Test Fiscal Year 2016" + salary_slip.month = getdate(nowdate()).month salary_slip.posting_date = nowdate() salary_slip.insert() # salary_slip.submit() @@ -185,38 +194,67 @@ def make_activity_for_employee(self): activity_type.wage_rate = 25 activity_type.save() -def make_salary_component(salary_components): + def get_no_of_days(self): + no_of_days_in_month = calendar.monthrange(getdate(nowdate()).year, + getdate(nowdate()).month) + no_of_holidays_in_month = len([1 for i in calendar.monthcalendar(getdate(nowdate()).year, + getdate(nowdate()).month) if i[6] != 0]) + return [no_of_days_in_month[1], no_of_holidays_in_month] + + +def make_earning_salary_component(salary_components): for salary_component in salary_components: if not frappe.db.exists('Salary Component', salary_component): sal_comp = frappe.get_doc({ "doctype": "Salary Component", - "salary_component": salary_component + "salary_component": salary_component, + "type": "Earning" }) sal_comp.insert() get_salary_component_account(salary_component) -def make_salary_structure(sal_struct): +def make_deduction_salary_component(salary_components): + for salary_component in salary_components: + if not frappe.db.exists('Salary Component', salary_component): + sal_comp = frappe.get_doc({ + "doctype": "Salary Component", + "salary_component": salary_component, + "type": "Deduction" + }) + sal_comp.insert() + get_salary_component_account(salary_component) + +def make_salary_structure(sal_struct, employee): if not frappe.db.exists('Salary Structure', sal_struct): frappe.get_doc({ "doctype": "Salary Structure", "name": sal_struct, "company": erpnext.get_default_company(), "from_date": nowdate(), - "employees": get_employee_details(), + "employees": get_employee_details(employee), "earnings": get_earnings_component(), "deductions": get_deductions_component(), "payment_account": frappe.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name") }).insert() + + elif not frappe.db.get_value("Salary Structure Employee",{'parent':sal_struct, 'employee':employee},'name'): + sal_struct = frappe.get_doc("Salary Structure", sal_struct) + sal_struct.append("employees", {"employee": employee, + "employee_name": employee, + "base": 32000, + "variable": 3200 + }) + sal_struct.save() + sal_struct = sal_struct.name return sal_struct - - -def get_employee_details(): - return [{"employee": frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), + +def get_employee_details(employee): + return [{"employee": employee, "base": 25000, "variable": 5000 } ] - + def get_earnings_component(): return [ { @@ -270,7 +308,4 @@ def get_deductions_component(): "formula": 'base*.1', "idx": 3 } - ] - -test_dependencies = ["Leave Application", "Holiday List"] - \ No newline at end of file + ] \ No newline at end of file diff --git a/erpnext/hr/doctype/salary_structure/test_salary_structure.py b/erpnext/hr/doctype/salary_structure/test_salary_structure.py index 81f674391d64..8eb9daaefd99 100644 --- a/erpnext/hr/doctype/salary_structure/test_salary_structure.py +++ b/erpnext/hr/doctype/salary_structure/test_salary_structure.py @@ -6,25 +6,19 @@ import unittest import erpnext from frappe.utils.make_random import get_random -from frappe.utils import nowdate, add_days, add_years +from frappe.utils import nowdate, add_days, add_years, getdate from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip -from erpnext.hr.doctype.salary_slip.test_salary_slip import make_salary_component +from erpnext.hr.doctype.salary_slip.test_salary_slip import make_earning_salary_component, make_deduction_salary_component # test_records = frappe.get_test_records('Salary Structure') +test_dependencies = ["Fiscal Year"] + class TestSalaryStructure(unittest.TestCase): - def test_setup(self): - if not frappe.db.exists("Fiscal Year", "_Test Fiscal Year 2016"): - fy = frappe.get_doc({ - "doctype": "Fiscal Year", - "year": "_Test Fiscal Year 2016", - "year_end_date": "2016-12-31", - "year_start_date": "2016-01-01" - }) - fy.insert() - + def setUp(self): self.make_holiday_list() frappe.db.set_value("Company", erpnext.get_default_company(), "default_holiday_list", "Salary Structure Test Holiday List") - make_salary_component(["Basic Salary", "Allowance", "HRA", "Professional Tax", "TDS"]) + make_earning_salary_component(["Basic Salary", "Allowance", "HRA"]) + make_deduction_salary_component(["Professional Tax", "TDS"]) employee1 = self.make_employee("test_employee@salary.com") employee2 = self.make_employee("test_employee_2@salary.com") @@ -87,8 +81,8 @@ def make_salary_slip_from_salary_structure(employee): sal_struct = make_salary_structure('Salary Structure Sample') sal_slip = make_salary_slip(sal_struct, employee = employee) sal_slip.employee_name = frappe.get_value("Employee", {"name":employee}, "employee_name") - sal_slip.month = "11" sal_slip.fiscal_year = "_Test Fiscal Year 2016" + sal_slip.month = getdate(nowdate()).month sal_slip.posting_date = nowdate() sal_slip.insert() sal_slip.submit() diff --git a/erpnext/patches.txt b/erpnext/patches.txt index b578ac2ccab8..b9f8efb30302 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -350,4 +350,5 @@ erpnext.patches.v7_1.update_invoice_status erpnext.patches.v7_0.po_status_issue_for_pr_return erpnext.patches.v7_1.update_missing_salary_component_type erpnext.patches.v7_0.update_autoname_field -erpnext.patches.v7_0.update_status_of_po_so \ No newline at end of file +erpnext.patches.v7_0.update_status_of_po_so +erpnext.patches.v7_1.repost_stock_for_deleted_bins_for_merging_items \ No newline at end of file diff --git a/erpnext/patches/v7_1/repost_stock_for_deleted_bins_for_merging_items.py b/erpnext/patches/v7_1/repost_stock_for_deleted_bins_for_merging_items.py new file mode 100644 index 000000000000..5c63c007adfe --- /dev/null +++ b/erpnext/patches/v7_1/repost_stock_for_deleted_bins_for_merging_items.py @@ -0,0 +1,41 @@ +from __future__ import unicode_literals +import frappe +from erpnext.stock.stock_balance import repost_stock + +def execute(): + modified_items = frappe.db.sql_list(""" + select name from `tabItem` + where is_stock_item=1 and modified >= '2016-10-31' + """) + + if not modified_items: + return + + item_warehouses_with_transactions = [] + transactions = ("Sales Order Item", "Material Request Item", "Purchase Order Item", + "Stock Ledger Entry", "Packed Item") + + for doctype in transactions: + item_warehouses_with_transactions += list(frappe.db.sql(""" + select distinct item_code, warehouse + from `tab{0}` where docstatus=1 and item_code in ({1})""" + .format(doctype, ', '.join(['%s']*len(modified_items))), tuple(modified_items))) + + item_warehouses_with_transactions += list(frappe.db.sql(""" + select distinct production_item, fg_warehouse + from `tabProduction Order` where docstatus=1 and production_item in ({0})""" + .format(', '.join(['%s']*len(modified_items))), tuple(modified_items))) + + item_warehouses_with_transactions += list(frappe.db.sql(""" + select distinct pr_item.item_code, pr.source_warehouse + from `tabProduction Order` pr, `tabProduction Order Item` pr_item + where pr_item.parent and pr.name and pr.docstatus=1 and pr_item.item_code in ({0})""" + .format(', '.join(['%s']*len(modified_items))), tuple(modified_items))) + + item_warehouses_with_bin = list(frappe.db.sql("select distinct item_code, warehouse from `tabBin`")) + + item_warehouses_with_missing_bin = list( + set(item_warehouses_with_transactions) - set(item_warehouses_with_bin)) + + for item_code, warehouse in item_warehouses_with_missing_bin: + repost_stock(item_code, warehouse) diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json index 18fdad7c8c19..42b50e3fe085 100644 --- a/erpnext/stock/doctype/item/item.json +++ b/erpnext/stock/doctype/item/item.json @@ -12,11 +12,13 @@ "doctype": "DocType", "document_type": "Setup", "editable_grid": 1, + "engine": "InnoDB", "fields": [ { "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "name_and_description_section", "fieldtype": "Section Break", "hidden": 0, @@ -33,6 +35,7 @@ "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, @@ -43,6 +46,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "naming_series", "fieldtype": "Select", "hidden": 0, @@ -58,6 +62,7 @@ "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, @@ -68,6 +73,7 @@ "allow_on_submit": 0, "bold": 1, "collapsible": 0, + "columns": 0, "description": "", "fieldname": "item_code", "fieldtype": "Data", @@ -85,6 +91,7 @@ "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, @@ -95,6 +102,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "variant_of", "description": "If item is a variant of another item then description, image, pricing, taxes etc will be set from the template unless explicitly specified", "fieldname": "variant_of", @@ -113,6 +121,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -123,6 +132,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "item_name", "fieldtype": "Data", "hidden": 0, @@ -139,6 +149,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, "search_index": 1, @@ -149,6 +160,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "barcode", "fieldtype": "Data", "hidden": 0, @@ -163,6 +175,7 @@ "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, @@ -173,6 +186,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "description": "", "fieldname": "item_group", "fieldtype": "Link", @@ -191,6 +205,7 @@ "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, @@ -201,6 +216,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "description": "", "fieldname": "stock_uom", "fieldtype": "Link", @@ -219,6 +235,7 @@ "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, @@ -229,6 +246,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "column_break0", "fieldtype": "Column Break", "hidden": 0, @@ -242,6 +260,7 @@ "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, @@ -252,6 +271,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "disabled", "fieldtype": "Check", "hidden": 0, @@ -267,6 +287,7 @@ "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, @@ -277,6 +298,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "default": "1", "description": "", "fieldname": "is_stock_item", @@ -296,6 +318,7 @@ "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, @@ -306,9 +329,10 @@ "allow_on_submit": 0, "bold": 1, "collapsible": 0, + "columns": 0, "depends_on": "eval:(doc.__islocal&&doc.is_stock_item && !doc.has_serial_no && !doc.has_batch_no)", "fieldname": "opening_stock", - "fieldtype": "Int", + "fieldtype": "Float", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -322,6 +346,7 @@ "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, @@ -332,6 +357,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "eval:(doc.__islocal && doc.is_stock_item && !doc.has_serial_no && !doc.has_batch_no && doc.opening_stock)", "fieldname": "valuation_rate", "fieldtype": "Currency", @@ -348,6 +374,7 @@ "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, @@ -358,6 +385,7 @@ "allow_on_submit": 0, "bold": 1, "collapsible": 0, + "columns": 0, "fieldname": "standard_rate", "fieldtype": "Currency", "hidden": 0, @@ -373,6 +401,7 @@ "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, @@ -383,6 +412,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "is_fixed_asset", "fieldtype": "Check", "hidden": 0, @@ -398,6 +428,7 @@ "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, @@ -408,6 +439,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "is_fixed_asset", "fieldname": "asset_category", "fieldtype": "Link", @@ -425,6 +457,7 @@ "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, @@ -435,6 +468,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "image", "fieldtype": "Attach Image", "hidden": 1, @@ -451,6 +485,7 @@ "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, @@ -461,6 +496,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 1, + "columns": 0, "fieldname": "section_break_11", "fieldtype": "Section Break", "hidden": 0, @@ -476,6 +512,7 @@ "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, @@ -486,6 +523,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "brand", "fieldtype": "Link", "hidden": 0, @@ -503,6 +541,7 @@ "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, @@ -513,6 +552,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "description", "fieldtype": "Text Editor", "hidden": 0, @@ -529,6 +569,7 @@ "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, @@ -540,6 +581,7 @@ "bold": 0, "collapsible": 1, "collapsible_depends_on": "is_stock_item", + "columns": 0, "depends_on": "is_stock_item", "fieldname": "inventory", "fieldtype": "Section Break", @@ -557,6 +599,7 @@ "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, @@ -567,6 +610,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "is_stock_item", "description": "", "fieldname": "default_warehouse", @@ -586,6 +630,7 @@ "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, @@ -596,6 +641,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "default": "2099-12-31", "depends_on": "is_stock_item", "fieldname": "end_of_life", @@ -614,6 +660,7 @@ "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, @@ -624,6 +671,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "default": "", "depends_on": "eval:doc.is_stock_item", "fieldname": "has_batch_no", @@ -643,6 +691,7 @@ "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, @@ -653,6 +702,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "default": "", "depends_on": "eval:doc.is_stock_item", "description": "Selecting \"Yes\" will give a unique identity to each entity of this item which can be viewed in the Serial No master.", @@ -673,6 +723,7 @@ "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, @@ -683,6 +734,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "has_serial_no", "description": "Example: ABCD.#####\nIf series is set and Serial No is not mentioned in transactions, then automatic serial number will be created based on this series. If you always want to explicitly mention Serial Nos for this item. leave this blank.", "fieldname": "serial_no_series", @@ -699,6 +751,7 @@ "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, @@ -709,6 +762,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "default": "Purchase", "fieldname": "default_material_request_type", "fieldtype": "Select", @@ -726,6 +780,7 @@ "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, @@ -736,6 +791,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "is_stock_item", "fieldname": "column_break1", "fieldtype": "Column Break", @@ -751,6 +807,7 @@ "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, @@ -762,6 +819,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "is_stock_item", "description": "", "fieldname": "tolerance", @@ -780,6 +838,7 @@ "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, @@ -790,6 +849,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "is_stock_item", "fieldname": "valuation_method", "fieldtype": "Select", @@ -806,6 +866,7 @@ "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, @@ -816,6 +877,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "eval:doc.is_stock_item", "fieldname": "warranty_period", "fieldtype": "Data", @@ -833,6 +895,7 @@ "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, @@ -843,6 +906,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "is_stock_item", "description": "", "fieldname": "net_weight", @@ -859,6 +923,7 @@ "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, @@ -869,6 +934,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "eval:doc.is_stock_item", "fieldname": "weight_uom", "fieldtype": "Link", @@ -885,6 +951,7 @@ "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, @@ -895,6 +962,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 1, + "columns": 0, "depends_on": "is_stock_item", "description": "", "fieldname": "reorder_section", @@ -912,6 +980,7 @@ "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, @@ -922,6 +991,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "description": "Will also apply for variants unless overrridden", "fieldname": "reorder_levels", @@ -939,6 +1009,7 @@ "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, @@ -950,6 +1021,7 @@ "bold": 0, "collapsible": 1, "collapsible_depends_on": "attributes", + "columns": 0, "depends_on": "", "fieldname": "variants_section", "fieldtype": "Section Break", @@ -966,6 +1038,7 @@ "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, @@ -976,6 +1049,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "default": "0", "depends_on": "eval:!doc.variant_of", "description": "If this item has variants, then it cannot be selected in sales orders etc.", @@ -995,6 +1069,7 @@ "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, @@ -1005,6 +1080,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "fieldname": "attributes", "fieldtype": "Table", @@ -1022,6 +1098,7 @@ "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, @@ -1032,6 +1109,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 1, + "columns": 0, "fieldname": "purchase_details", "fieldtype": "Section Break", "hidden": 0, @@ -1048,6 +1126,7 @@ "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, @@ -1058,6 +1137,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "default": "1", "fieldname": "is_purchase_item", "fieldtype": "Check", @@ -1074,6 +1154,7 @@ "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, @@ -1084,6 +1165,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "default": "0.00", "depends_on": "is_stock_item", "description": "", @@ -1103,6 +1185,7 @@ "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, @@ -1113,6 +1196,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "safety_stock", "fieldtype": "Float", "hidden": 0, @@ -1128,6 +1212,7 @@ "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, @@ -1138,6 +1223,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "description": "Average time taken by the supplier to deliver", "fieldname": "lead_time_days", @@ -1156,6 +1242,7 @@ "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, @@ -1166,6 +1253,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "description": "", "fieldname": "buying_cost_center", @@ -1185,6 +1273,7 @@ "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, @@ -1195,6 +1284,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "description": "", "fieldname": "expense_account", @@ -1214,6 +1304,7 @@ "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, @@ -1224,6 +1315,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "fieldname": "unit_of_measure_conversion", "fieldtype": "Column Break", @@ -1240,6 +1332,7 @@ "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, @@ -1250,6 +1343,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "description": "Will also apply for variants", "fieldname": "uoms", @@ -1269,6 +1363,7 @@ "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, @@ -1279,6 +1374,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "fieldname": "last_purchase_rate", "fieldtype": "Float", @@ -1296,6 +1392,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -1306,6 +1403,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 1, + "columns": 0, "depends_on": "", "fieldname": "supplier_details", "fieldtype": "Section Break", @@ -1322,6 +1420,7 @@ "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, @@ -1332,6 +1431,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "fieldname": "default_supplier", "fieldtype": "Link", @@ -1348,6 +1448,7 @@ "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, @@ -1358,6 +1459,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "delivered_by_supplier", "fieldtype": "Check", "hidden": 0, @@ -1373,6 +1475,7 @@ "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, @@ -1383,6 +1486,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "fieldname": "manufacturer", "fieldtype": "Link", @@ -1399,6 +1503,7 @@ "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, @@ -1409,6 +1514,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "fieldname": "manufacturer_part_no", "fieldtype": "Data", @@ -1424,6 +1530,7 @@ "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, @@ -1434,6 +1541,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "fieldname": "column_break2", "fieldtype": "Column Break", @@ -1450,6 +1558,7 @@ "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, @@ -1461,6 +1570,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "fieldname": "supplier_items", "fieldtype": "Table", @@ -1477,6 +1587,7 @@ "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, @@ -1487,6 +1598,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 1, + "columns": 0, "fieldname": "sales_details", "fieldtype": "Section Break", "hidden": 0, @@ -1503,6 +1615,7 @@ "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, @@ -1513,6 +1626,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "default": "1", "fieldname": "is_sales_item", "fieldtype": "Check", @@ -1529,6 +1643,7 @@ "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, @@ -1539,6 +1654,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "default": "0", "description": "Publish Item to hub.erpnext.com", "fieldname": "publish_in_hub", @@ -1556,6 +1672,7 @@ "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, @@ -1566,6 +1683,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "default": "0", "fieldname": "synced_with_hub", "fieldtype": "Check", @@ -1582,6 +1700,7 @@ "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, @@ -1592,6 +1711,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "fieldname": "income_account", "fieldtype": "Link", @@ -1608,6 +1728,7 @@ "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, @@ -1618,6 +1739,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "fieldname": "selling_cost_center", "fieldtype": "Link", @@ -1634,6 +1756,7 @@ "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, @@ -1644,6 +1767,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "fieldname": "column_break3", "fieldtype": "Column Break", @@ -1660,6 +1784,7 @@ "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, @@ -1671,6 +1796,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "description": "", "fieldname": "customer_items", @@ -1688,6 +1814,7 @@ "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, @@ -1698,6 +1825,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "fieldname": "max_discount", "fieldtype": "Float", @@ -1715,6 +1843,7 @@ "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, @@ -1725,6 +1854,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 1, + "columns": 0, "fieldname": "item_tax_section_break", "fieldtype": "Section Break", "hidden": 0, @@ -1741,6 +1871,7 @@ "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, @@ -1751,6 +1882,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "description": "Will also apply for variants", "fieldname": "taxes", "fieldtype": "Table", @@ -1769,6 +1901,7 @@ "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, @@ -1779,6 +1912,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 1, + "columns": 0, "fieldname": "inspection_criteria", "fieldtype": "Section Break", "hidden": 0, @@ -1795,6 +1929,7 @@ "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, @@ -1805,6 +1940,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "default": "", "fieldname": "inspection_required", "fieldtype": "Check", @@ -1823,6 +1959,7 @@ "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, @@ -1833,6 +1970,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "inspection_required", "description": "Will also apply to variants", "fieldname": "quality_parameters", @@ -1852,6 +1990,7 @@ "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, @@ -1862,6 +2001,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 1, + "columns": 0, "depends_on": "is_stock_item", "fieldname": "manufacturing", "fieldtype": "Section Break", @@ -1879,6 +2019,7 @@ "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, @@ -1889,6 +2030,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "", "fieldname": "default_bom", "fieldtype": "Link", @@ -1907,6 +2049,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -1917,6 +2060,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "default": "", "description": "If subcontracted to a vendor", "fieldname": "is_sub_contracted_item", @@ -1936,6 +2080,7 @@ "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, @@ -1946,6 +2091,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "column_break_74", "fieldtype": "Column Break", "hidden": 0, @@ -1960,6 +2106,7 @@ "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, @@ -1970,6 +2117,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "customer_code", "fieldtype": "Data", "hidden": 1, @@ -1984,6 +2132,7 @@ "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, @@ -1994,6 +2143,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 1, + "columns": 0, "fieldname": "website_section", "fieldtype": "Section Break", "hidden": 0, @@ -2009,6 +2159,7 @@ "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, @@ -2019,6 +2170,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "show_in_website", "fieldtype": "Check", "hidden": 0, @@ -2033,6 +2185,7 @@ "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, @@ -2043,6 +2196,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "show_in_website", "fieldname": "route", "fieldtype": "Small Text", @@ -2059,6 +2213,7 @@ "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, @@ -2069,6 +2224,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "show_in_website", "description": "Items with higher weightage will be shown higher", "fieldname": "weightage", @@ -2085,6 +2241,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 1, @@ -2095,6 +2252,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "show_in_website", "description": "Show a slideshow at the top of the page", "fieldname": "slideshow", @@ -2112,6 +2270,7 @@ "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, @@ -2122,6 +2281,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "show_in_website", "description": "Item Image (if not slideshow)", "fieldname": "website_image", @@ -2139,6 +2299,7 @@ "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, @@ -2149,6 +2310,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "thumbnail", "fieldtype": "Data", "hidden": 0, @@ -2164,6 +2326,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -2174,6 +2337,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "cb72", "fieldtype": "Column Break", "hidden": 0, @@ -2187,6 +2351,7 @@ "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, @@ -2197,6 +2362,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "show_in_website", "description": "Show \"In Stock\" or \"Not in Stock\" based on stock available in this warehouse.", "fieldname": "website_warehouse", @@ -2214,6 +2380,7 @@ "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, @@ -2224,6 +2391,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "show_in_website", "description": "List this Item in multiple groups on the website.", "fieldname": "website_item_groups", @@ -2241,6 +2409,7 @@ "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, @@ -2252,6 +2421,7 @@ "bold": 0, "collapsible": 1, "collapsible_depends_on": "website_specifications", + "columns": 0, "depends_on": "show_in_website", "fieldname": "sb72", "fieldtype": "Section Break", @@ -2267,6 +2437,7 @@ "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, @@ -2277,6 +2448,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "show_in_website", "fieldname": "copy_from_item_group", "fieldtype": "Button", @@ -2292,6 +2464,7 @@ "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, @@ -2302,6 +2475,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "show_in_website", "fieldname": "website_specifications", "fieldtype": "Table", @@ -2318,6 +2492,7 @@ "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, @@ -2328,6 +2503,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "depends_on": "show_in_website", "fieldname": "web_long_description", "fieldtype": "Text Editor", @@ -2343,6 +2519,7 @@ "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, @@ -2353,6 +2530,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "total_projected_qty", "fieldtype": "Float", "hidden": 1, @@ -2368,6 +2546,7 @@ "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, @@ -2387,7 +2566,7 @@ "issingle": 0, "istable": 0, "max_attachments": 1, - "modified": "2016-08-17 17:30:51.323382", + "modified": "2016-12-12 18:19:27.154509", "modified_by": "Administrator", "module": "Stock", "name": "Item", @@ -2403,6 +2582,7 @@ "export": 0, "if_owner": 0, "import": 1, + "is_custom": 0, "permlevel": 0, "print": 1, "read": 1, @@ -2423,6 +2603,7 @@ "export": 0, "if_owner": 0, "import": 0, + "is_custom": 0, "permlevel": 0, "print": 1, "read": 1, @@ -2443,6 +2624,7 @@ "export": 0, "if_owner": 0, "import": 0, + "is_custom": 0, "permlevel": 0, "print": 1, "read": 1, @@ -2463,6 +2645,7 @@ "export": 0, "if_owner": 0, "import": 0, + "is_custom": 0, "permlevel": 0, "print": 0, "read": 1, @@ -2483,6 +2666,7 @@ "export": 0, "if_owner": 0, "import": 0, + "is_custom": 0, "permlevel": 0, "print": 0, "read": 1, @@ -2503,6 +2687,7 @@ "export": 0, "if_owner": 0, "import": 0, + "is_custom": 0, "permlevel": 0, "print": 0, "read": 1, @@ -2523,6 +2708,7 @@ "export": 0, "if_owner": 0, "import": 0, + "is_custom": 0, "permlevel": 0, "print": 0, "read": 1, @@ -2543,6 +2729,7 @@ "export": 0, "if_owner": 0, "import": 0, + "is_custom": 0, "permlevel": 0, "print": 0, "read": 1, diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index 3d248d1c280a..98d0ebcfac23 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -532,8 +532,6 @@ def before_rename(self, old_name, new_name, merge=False): frappe.throw(_("To merge, following properties must be same for both items") + ": \n" + ", ".join([self.meta.get_label(fld) for fld in field_list])) - frappe.db.sql("delete from `tabBin` where item_code=%s", old_name) - def after_rename(self, old_name, new_name, merge): if self.route: invalidate_cache_for_item(self) @@ -567,8 +565,14 @@ def recalculate_bin_qty(self, new_name): existing_allow_negative_stock = frappe.db.get_value("Stock Settings", None, "allow_negative_stock") frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1) - for warehouse in frappe.db.sql("select warehouse from `tabBin` where item_code=%s", new_name): - repost_stock(new_name, warehouse[0]) + repost_stock_for_warehouses = frappe.db.sql_list("""select distinct warehouse + from tabBin where item_code=%s""", new_name) + + # Delete all existing bins to avoid duplicate bins for the same item and warehouse + frappe.db.sql("delete from `tabBin` where item_code=%s", new_name) + + for warehouse in repost_stock_for_warehouses: + repost_stock(new_name, warehouse) frappe.db.set_value("Stock Settings", None, "allow_negative_stock", existing_allow_negative_stock) frappe.db.auto_commit_on_many_writes = 0 diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py index aceefc0ce5f7..706fd5a1f46c 100644 --- a/erpnext/stock/doctype/item/test_item.py +++ b/erpnext/stock/doctype/item/test_item.py @@ -9,6 +9,9 @@ from erpnext.controllers.item_variant import (create_variant, ItemVariantExistsError, InvalidItemAttributeValueError) +from frappe.model.rename_doc import rename_doc +from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry + test_ignore = ["BOM"] test_dependencies = ["Warehouse"] @@ -164,11 +167,31 @@ def test_make_item_variant_with_numeric_values(self): variant.item_name = "_Test Numeric Variant Large 1.1m" self.assertRaises(InvalidItemAttributeValueError, variant.save) - variant = create_variant("_Test Numeric Template Item", {"Test Size": "Large", "Test Item Length": 1.5}) + variant = create_variant("_Test Numeric Template Item", + {"Test Size": "Large", "Test Item Length": 1.5}) self.assertEquals(variant.item_code, None) variant.item_code = "_Test Numeric Variant-L-1.5" variant.item_name = "_Test Numeric Variant Large 1.5m" variant.save() + + def test_item_merging(self): + create_item("Test Item for Merging 1") + create_item("Test Item for Merging 2") + + make_stock_entry(item_code="Test Item for Merging 1", target="_Test Warehouse - _TC", + qty=1, rate=100) + make_stock_entry(item_code="Test Item for Merging 2", target="_Test Warehouse 1 - _TC", + qty=1, rate=100) + + rename_doc("Item", "Test Item for Merging 1", "Test Item for Merging 2", merge=True) + + self.assertFalse(frappe.db.exists("Item", "Test Item for Merging 1")) + + self.assertTrue(frappe.db.get_value("Bin", + {"item_code": "Test Item for Merging 2", "warehouse": "_Test Warehouse - _TC"})) + + self.assertTrue(frappe.db.get_value("Bin", + {"item_code": "Test Item for Merging 2", "warehouse": "_Test Warehouse 1 - _TC"})) def make_item_variant(): if not frappe.db.exists("Item", "_Test Variant Item-S"): @@ -184,3 +207,14 @@ def get_total_projected_qty(item): return total_qty[0].projected_qty if total_qty else 0.0 test_records = frappe.get_test_records('Item') + +def create_item(item_code, is_stock_item=None): + if not frappe.db.exists("Item", item_code): + item = frappe.new_doc("Item") + item.item_code = item_code + item.item_name = item_code + item.description = item_code + item.item_group = "All Item Groups" + item.is_stock_item = is_stock_item or 1 + item.save() + \ No newline at end of file diff --git a/erpnext/stock/doctype/warehouse/test_warehouse.py b/erpnext/stock/doctype/warehouse/test_warehouse.py index 223258430f4d..edc540054795 100644 --- a/erpnext/stock/doctype/warehouse/test_warehouse.py +++ b/erpnext/stock/doctype/warehouse/test_warehouse.py @@ -1,7 +1,10 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: GNU General Public License v3. See license.txt from __future__ import unicode_literals - +from frappe.model.rename_doc import rename_doc +from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry +from frappe.utils import cint +from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory import frappe import unittest @@ -21,5 +24,77 @@ def test_warehouse_hierarchy(self): for child_warehouse in child_warehouses: self.assertEquals(p_warehouse.name, child_warehouse.parent_warehouse) self.assertEquals(child_warehouse.is_group, 0) + + def test_warehouse_renaming(self): + set_perpetual_inventory(1) + create_warehouse("Test Warehouse for Renaming 1") + + self.assertTrue(frappe.db.exists("Account", "Test Warehouse for Renaming 1 - _TC")) + self.assertTrue(frappe.db.get_value("Account", + filters={"warehouse": "Test Warehouse for Renaming 1 - _TC"})) + + # Rename with abbr + if frappe.db.exists("Warehouse", "Test Warehouse for Renaming 2 - _TC"): + frappe.delete_doc("Warehouse", "Test Warehouse for Renaming 2 - _TC") + rename_doc("Warehouse", "Test Warehouse for Renaming 1 - _TC", "Test Warehouse for Renaming 2 - _TC") + + self.assertTrue(frappe.db.exists("Account", "Test Warehouse for Renaming 2 - _TC")) + self.assertTrue(frappe.db.get_value("Account", + filters={"warehouse": "Test Warehouse for Renaming 2 - _TC"})) + + # Rename without abbr + if frappe.db.exists("Warehouse", "Test Warehouse for Renaming 3 - _TC"): + frappe.delete_doc("Warehouse", "Test Warehouse for Renaming 3 - _TC") + + rename_doc("Warehouse", "Test Warehouse for Renaming 2 - _TC", "Test Warehouse for Renaming 3") + + self.assertTrue(frappe.db.exists("Account", "Test Warehouse for Renaming 3 - _TC")) + self.assertTrue(frappe.db.get_value("Account", + filters={"warehouse": "Test Warehouse for Renaming 3 - _TC"})) + + set_perpetual_inventory(0) + + def test_warehouse_merging(self): + set_perpetual_inventory(1) + + create_warehouse("Test Warehouse for Merging 1") + create_warehouse("Test Warehouse for Merging 2") + + make_stock_entry(item_code="_Test Item", target="Test Warehouse for Merging 1 - _TC", + qty=1, rate=100) + make_stock_entry(item_code="_Test Item", target="Test Warehouse for Merging 2 - _TC", + qty=1, rate=100) + + existing_bin_qty = ( + cint(frappe.db.get_value("Bin", + {"item_code": "_Test Item", "warehouse": "Test Warehouse for Merging 1 - _TC"}, "actual_qty")) + + cint(frappe.db.get_value("Bin", + {"item_code": "_Test Item", "warehouse": "Test Warehouse for Merging 2 - _TC"}, "actual_qty")) + ) + + rename_doc("Warehouse", "Test Warehouse for Merging 1 - _TC", + "Test Warehouse for Merging 2 - _TC", merge=True) + + self.assertFalse(frappe.db.exists("Warehouse", "Test Warehouse for Merging 1 - _TC")) + + bin_qty = frappe.db.get_value("Bin", + {"item_code": "_Test Item", "warehouse": "Test Warehouse for Merging 2 - _TC"}, "actual_qty") + + self.assertEqual(bin_qty, existing_bin_qty) + self.assertFalse(frappe.db.exists("Account", "Test Warehouse for Merging 1 - _TC")) + self.assertTrue(frappe.db.exists("Account", "Test Warehouse for Merging 2 - _TC")) + self.assertTrue(frappe.db.get_value("Account", + filters={"warehouse": "Test Warehouse for Merging 2 - _TC"})) + + set_perpetual_inventory(0) +def create_warehouse(warehouse_name): + if not frappe.db.exists("Warehouse", warehouse_name + " - _TC"): + w = frappe.new_doc("Warehouse") + w.warehouse_name = warehouse_name + w.parent_warehouse = "_Test Warehouse Group - _TC" + w.company = "_Test Company" + w.save() + + \ No newline at end of file diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py index 8e7941cdea08..e01cc0b6fe2d 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.py +++ b/erpnext/stock/doctype/warehouse/warehouse.py @@ -143,9 +143,7 @@ def before_rename(self, olddn, newdn, merge=False): if self.company != frappe.db.get_value("Warehouse", new_warehouse, "company"): frappe.throw(_("Both Warehouse must belong to same Company")) - frappe.db.sql("delete from `tabBin` where warehouse=%s", olddn) - - self.rename_account_for(olddn, newdn, merge) + self.rename_account_for(olddn, new_warehouse, merge) return new_warehouse @@ -195,11 +193,14 @@ def recalculate_bin_qty(self, newdn): existing_allow_negative_stock = frappe.db.get_value("Stock Settings", None, "allow_negative_stock") frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1) - for item in frappe.db.sql("""select distinct item_code from ( - select name as item_code from `tabItem` where is_stock_item=1 - union - select distinct item_code from tabBin) a"""): - repost_stock(item[0], newdn) + repost_stock_for_items = frappe.db.sql_list("""select distinct item_code + from tabBin where warehouse=%s""", newdn) + + # Delete all existing bins to avoid duplicate bins for the same item and warehouse + frappe.db.sql("delete from `tabBin` where warehouse=%s", newdn) + + for item_code in repost_stock_for_items: + repost_stock(item_code, newdn) frappe.db.set_value("Stock Settings", None, "allow_negative_stock", existing_allow_negative_stock) frappe.db.auto_commit_on_many_writes = 0 diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index f8410afef9c2..98102e666024 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -173,7 +173,7 @@ def get_basic_details(args, item): "net_amount": 0.0, "discount_percentage": 0.0, "supplier": item.default_supplier, - "delivered_by_supplier": item.delivered_by_supplier, + "delivered_by_supplier": item.delivered_by_supplier if args.get("doctype") in ["Sales Order", "Sales Invoice"] else 0, "is_fixed_asset": item.is_fixed_asset }) diff --git a/erpnext/support/doctype/warranty_claim/warranty_claim.json b/erpnext/support/doctype/warranty_claim/warranty_claim.json index 81b06e2e782f..08a91c1a4504 100644 --- a/erpnext/support/doctype/warranty_claim/warranty_claim.json +++ b/erpnext/support/doctype/warranty_claim/warranty_claim.json @@ -1086,7 +1086,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2016-11-03 16:16:32.681068", + "modified": "2016-12-13 11:17:40.538428", "modified_by": "Administrator", "module": "Support", "name": "Warranty Claim",