diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5a46002820c..37bb37e1d24 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,10 +13,10 @@ jobs: with: fetch-depth: 0 persist-credentials: false - - name: Setup Node.js v14 + - name: Setup Node.js uses: actions/setup-node@v2 with: - node-version: 14 + node-version: 18 - name: Setup dependencies run: | npm install @semantic-release/git @semantic-release/exec --no-save @@ -28,4 +28,4 @@ jobs: GIT_AUTHOR_EMAIL: "developers@frappe.io" GIT_COMMITTER_NAME: "Frappe PR Bot" GIT_COMMITTER_EMAIL: "developers@frappe.io" - run: npx semantic-release \ No newline at end of file + run: npx semantic-release diff --git a/erpnext/crm/doctype/appointment/appointment.json b/erpnext/crm/doctype/appointment/appointment.json index 306be7faa74..c4c26d0c27e 100644 --- a/erpnext/crm/doctype/appointment/appointment.json +++ b/erpnext/crm/doctype/appointment/appointment.json @@ -102,7 +102,7 @@ } ], "links": [], - "modified": "2021-06-29 18:27:02.832979", + "modified": "2022-12-28 16:35:34.377575", "modified_by": "Administrator", "module": "CRM", "name": "Appointment", @@ -121,16 +121,6 @@ "share": 1, "write": 1 }, - { - "create": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Guest", - "share": 1 - }, { "create": 1, "delete": 1, diff --git a/erpnext/crm/doctype/appointment/appointment.py b/erpnext/crm/doctype/appointment/appointment.py index 69b8c324e00..65360542324 100644 --- a/erpnext/crm/doctype/appointment/appointment.py +++ b/erpnext/crm/doctype/appointment/appointment.py @@ -5,7 +5,9 @@ from collections import Counter import frappe +import frappe.share from frappe import _ +from frappe.desk.form.assign_to import add as add_assignment from frappe.model.document import Document from frappe.utils import get_url, getdate from frappe.utils.verified_command import get_signed_params @@ -118,21 +120,18 @@ class Appointment(Document): self.party = lead.name def auto_assign(self): - from frappe.desk.form.assign_to import add as add_assignemnt - existing_assignee = self.get_assignee_from_latest_opportunity() if existing_assignee: # If the latest opportunity is assigned to someone # Assign the appointment to the same - add_assignemnt({"doctype": self.doctype, "name": self.name, "assign_to": [existing_assignee]}) + self.assign_agent(existing_assignee) return if self._assign: return available_agents = _get_agents_sorted_by_asc_workload(getdate(self.scheduled_time)) for agent in available_agents: if _check_agent_availability(agent, self.scheduled_time): - agent = agent[0] - add_assignemnt({"doctype": self.doctype, "name": self.name, "assign_to": [agent]}) + self.assign_agent(agent[0]) break def get_assignee_from_latest_opportunity(self): @@ -187,9 +186,15 @@ class Appointment(Document): params = {"email": self.customer_email, "appointment": self.name} return get_url(verify_route + "?" + get_signed_params(params)) + def assign_agent(self, agent): + if not frappe.has_permission(doc=self, user=agent): + frappe.share.add(self.doctype, self.name, agent, flags={"ignore_share_permission": True}) + + add_assignment({"doctype": self.doctype, "name": self.name, "assign_to": [agent]}) + def _get_agents_sorted_by_asc_workload(date): - appointments = frappe.db.get_list("Appointment", fields="*") + appointments = frappe.get_all("Appointment", fields="*") agent_list = _get_agent_list_as_strings() if not appointments: return agent_list @@ -214,7 +219,7 @@ def _get_agent_list_as_strings(): def _check_agent_availability(agent_email, scheduled_time): - appointemnts_at_scheduled_time = frappe.get_list( + appointemnts_at_scheduled_time = frappe.get_all( "Appointment", filters={"scheduled_time": scheduled_time} ) for appointment in appointemnts_at_scheduled_time: diff --git a/erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.json b/erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.json index 4b26e4901bd..ac58e386fe3 100644 --- a/erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.json +++ b/erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.json @@ -1,4 +1,5 @@ { + "actions": [], "creation": "2019-08-27 10:56:48.309824", "doctype": "DocType", "editable_grid": 1, @@ -101,7 +102,8 @@ } ], "issingle": 1, - "modified": "2019-11-26 12:14:17.669366", + "links": [], + "modified": "2022-12-28 16:41:28.773090", "modified_by": "Administrator", "module": "CRM", "name": "Appointment Booking Settings", @@ -117,13 +119,6 @@ "share": 1, "write": 1 }, - { - "email": 1, - "print": 1, - "read": 1, - "role": "Guest", - "share": 1 - }, { "create": 1, "email": 1, diff --git a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py index 1f7ade23f4c..fccf722939e 100644 --- a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py +++ b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py @@ -111,34 +111,30 @@ def get_data(filters: Filters) -> List: employee.leave_approver ) - if ( - (leave_approvers and len(leave_approvers) and user in leave_approvers) - or (user in ["Administrator", employee.user_id]) - or ("HR Manager" in frappe.get_roles(user)) - ): - if len(active_employees) > 1: - row = frappe._dict() - row.employee = employee.name - row.employee_name = employee.employee_name + if len(active_employees) > 1: + row = frappe._dict() - leaves_taken = ( - get_leaves_for_period(employee.name, leave_type, filters.from_date, filters.to_date) * -1 - ) + row.employee = employee.name + row.employee_name = employee.employee_name - new_allocation, expired_leaves, carry_forwarded_leaves = get_allocated_and_expired_leaves( - filters.from_date, filters.to_date, employee.name, leave_type - ) - opening = get_opening_balance(employee.name, leave_type, filters, carry_forwarded_leaves) + leaves_taken = ( + get_leaves_for_period(employee.name, leave_type, filters.from_date, filters.to_date) * -1 + ) - row.leaves_allocated = new_allocation - row.leaves_expired = expired_leaves - row.opening_balance = opening - row.leaves_taken = leaves_taken + new_allocation, expired_leaves, carry_forwarded_leaves = get_allocated_and_expired_leaves( + filters.from_date, filters.to_date, employee.name, leave_type + ) + opening = get_opening_balance(employee.name, leave_type, filters, carry_forwarded_leaves) - # not be shown on the basis of days left it create in user mind for carry_forward leave - row.closing_balance = new_allocation + opening - (row.leaves_expired + leaves_taken) - row.indent = 1 - data.append(row) + row.leaves_allocated = new_allocation + row.leaves_expired = expired_leaves + row.opening_balance = opening + row.leaves_taken = leaves_taken + + # not be shown on the basis of days left it create in user mind for carry_forward leave + row.closing_balance = new_allocation + opening - (row.leaves_expired + leaves_taken) + row.indent = 1 + data.append(row) return data diff --git a/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py b/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py index 35ba16c74a7..9750ad4e880 100644 --- a/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py +++ b/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py @@ -65,21 +65,16 @@ def get_data(filters, leave_types): if employee.leave_approver: leave_approvers.append(employee.leave_approver) - if ( - (len(leave_approvers) and user in leave_approvers) - or (user in ["Administrator", employee.user_id]) - or ("HR Manager" in frappe.get_roles(user)) - ): - row = [employee.name, employee.employee_name, employee.department] - available_leave = get_leave_details(employee.name, filters.date) - for leave_type in leave_types: - remaining = 0 - if leave_type in available_leave["leave_allocation"]: - # opening balance - remaining = available_leave["leave_allocation"][leave_type]["remaining_leaves"] + row = [employee.name, employee.employee_name, employee.department] + available_leave = get_leave_details(employee.name, filters.date) + for leave_type in leave_types: + remaining = 0 + if leave_type in available_leave["leave_allocation"]: + # opening balance + remaining = available_leave["leave_allocation"][leave_type]["remaining_leaves"] - row += [remaining] + row += [remaining] - data.append(row) + data.append(row) return data diff --git a/erpnext/setup/doctype/item_group/item_group.json b/erpnext/setup/doctype/item_group/item_group.json index 50f923d87e0..2986087277c 100644 --- a/erpnext/setup/doctype/item_group/item_group.json +++ b/erpnext/setup/doctype/item_group/item_group.json @@ -123,6 +123,7 @@ "fieldname": "route", "fieldtype": "Data", "label": "Route", + "no_copy": 1, "unique": 1 }, { @@ -232,11 +233,10 @@ "is_tree": 1, "links": [], "max_attachments": 3, - "modified": "2022-03-09 12:27:11.055782", + "modified": "2023-01-05 12:21:30.458628", "modified_by": "Administrator", "module": "Setup", "name": "Item Group", - "name_case": "Title Case", "naming_rule": "By fieldname", "nsm_parent_field": "parent_item_group", "owner": "Administrator", diff --git a/erpnext/stock/doctype/packed_item/packed_item.py b/erpnext/stock/doctype/packed_item/packed_item.py index 4d05d7a345c..5412d4c0020 100644 --- a/erpnext/stock/doctype/packed_item/packed_item.py +++ b/erpnext/stock/doctype/packed_item/packed_item.py @@ -83,8 +83,8 @@ def reset_packing_list(doc): # 1. items were deleted # 2. if bundle item replaced by another item (same no. of items but different items) # we maintain list to track recurring item rows as well - items_before_save = [item.item_code for item in doc_before_save.get("items")] - items_after_save = [item.item_code for item in doc.get("items")] + items_before_save = [(item.name, item.item_code) for item in doc_before_save.get("items")] + items_after_save = [(item.name, item.item_code) for item in doc.get("items")] reset_table = items_before_save != items_after_save else: # reset: if via Update Items OR diff --git a/erpnext/www/book-appointment/__init__.py b/erpnext/www/book-appointment/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/erpnext/www/book-appointment/verify/__init__.py b/erpnext/www/book-appointment/verify/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/erpnext/www/book_appointment/index.js b/erpnext/www/book_appointment/index.js index 5562cbd4710..7da493a9341 100644 --- a/erpnext/www/book_appointment/index.js +++ b/erpnext/www/book_appointment/index.js @@ -2,7 +2,6 @@ frappe.ready(async () => { initialise_select_date(); }) -window.holiday_list = []; async function initialise_select_date() { navigate_to_page(1); @@ -20,7 +19,6 @@ async function get_global_variables() { window.timezones = (await frappe.call({ method:'erpnext.www.book_appointment.index.get_timezones' })).message; - window.holiday_list = window.appointment_settings.holiday_list; } function setup_timezone_selector() { diff --git a/erpnext/www/book_appointment/index.py b/erpnext/www/book_appointment/index.py index 06e99da3f94..dfca9465ed1 100644 --- a/erpnext/www/book_appointment/index.py +++ b/erpnext/www/book_appointment/index.py @@ -26,8 +26,12 @@ def get_context(context): @frappe.whitelist(allow_guest=True) def get_appointment_settings(): - settings = frappe.get_doc("Appointment Booking Settings") - settings.holiday_list = frappe.get_doc("Holiday List", settings.holiday_list) + settings = frappe.get_cached_value( + "Appointment Booking Settings", + None, + ["advance_booking_days", "appointment_duration", "success_redirect_url"], + as_dict=True, + ) return settings @@ -106,7 +110,7 @@ def create_appointment(date, time, tz, contact): appointment.customer_details = contact.get("notes", None) appointment.customer_email = contact.get("email", None) appointment.status = "Open" - appointment.insert() + appointment.insert(ignore_permissions=True) return appointment diff --git a/erpnext/www/book_appointment/verify/index.py b/erpnext/www/book_appointment/verify/index.py index 1a5ba9de7e5..3beb8667ae7 100644 --- a/erpnext/www/book_appointment/verify/index.py +++ b/erpnext/www/book_appointment/verify/index.py @@ -2,7 +2,6 @@ import frappe from frappe.utils.verified_command import verify_request -@frappe.whitelist(allow_guest=True) def get_context(context): if not verify_request(): context.success = False