diff --git a/.github/workflows/docker-release.yml b/.github/workflows/docker-release.yml index 8f67858306..4b1147e79f 100644 --- a/.github/workflows/docker-release.yml +++ b/.github/workflows/docker-release.yml @@ -1,7 +1,7 @@ name: Trigger Docker build on release on: release: - types: [created] + types: [released] jobs: curl: runs-on: ubuntu-latest diff --git a/erpnext/accounts/desk_page/accounting/accounting.json b/erpnext/accounts/desk_page/accounting/accounting.json index 42fb9f4f37..31315e4c71 100644 --- a/erpnext/accounts/desk_page/accounting/accounting.json +++ b/erpnext/accounts/desk_page/accounting/accounting.json @@ -13,7 +13,7 @@ { "hidden": 0, "label": "Accounts Receivable", - "links": "[\n {\n \"description\": \"Bills raised to Customers.\",\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bank/Cash transactions against party or for internal transfer\",\n \"label\": \"Payment Entry\",\n \"name\": \"Payment Entry\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Payment Request\",\n \"label\": \"Payment Request\",\n \"name\": \"Payment Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable\",\n \"name\": \"Accounts Receivable\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable Summary\",\n \"name\": \"Accounts Receivable Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Register\",\n \"name\": \"Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales Register\",\n \"name\": \"Item-wise Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Ordered Items To Be Billed\",\n \"name\": \"Ordered Items To Be Billed\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Delivered Items To Be Billed\",\n \"name\": \"Delivered Items To Be Billed\",\n \"type\": \"report\"\n }\n]" + "links": "[\n {\n \"description\": \"Bills raised to Customers.\",\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bank/Cash transactions against party or for internal transfer\",\n \"label\": \"Payment Entry\",\n \"name\": \"Payment Entry\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Payment Request\",\n \"label\": \"Payment Request\",\n \"name\": \"Payment Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable\",\n \"name\": \"Accounts Receivable\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable Summary\",\n \"name\": \"Accounts Receivable Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Register\",\n \"name\": \"Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales Register\",\n \"name\": \"Item-wise Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Analysis\",\n \"name\": \"Sales Order Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Delivered Items To Be Billed\",\n \"name\": \"Delivered Items To Be Billed\",\n \"type\": \"report\"\n }\n]" }, { "hidden": 0, @@ -98,7 +98,7 @@ "idx": 0, "is_standard": 1, "label": "Accounting", - "modified": "2020-05-27 20:34:50.949772", + "modified": "2020-06-19 12:42:44.054598", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting", @@ -122,11 +122,6 @@ "link_to": "Purchase Invoice", "type": "DocType" }, - { - "label": "Dashboard", - "link_to": "Accounts", - "type": "Dashboard" - }, { "label": "Journal Entry", "link_to": "Journal Entry", @@ -151,6 +146,11 @@ "label": "Trial Balance", "link_to": "Trial Balance", "type": "Report" + }, + { + "label": "Dashboard", + "link_to": "Accounts", + "type": "Dashboard" } ] } \ No newline at end of file diff --git a/erpnext/accounts/doctype/cost_center/cost_center.js b/erpnext/accounts/doctype/cost_center/cost_center.js index f341f78207..ee23b1be5c 100644 --- a/erpnext/accounts/doctype/cost_center/cost_center.js +++ b/erpnext/accounts/doctype/cost_center/cost_center.js @@ -71,8 +71,13 @@ frappe.ui.form.on('Cost Center', { "label": "Cost Center Number", "fieldname": "cost_center_number", "fieldtype": "Data", - "reqd": 1, "default": frm.doc.cost_center_number + }, + { + "label": __("Merge with existing"), + "fieldname": "merge", + "fieldtype": "Check", + "default": 0 } ], primary_action: function() { @@ -87,8 +92,9 @@ frappe.ui.form.on('Cost Center', { args: { docname: frm.doc.name, cost_center_name: data.cost_center_name, - cost_center_number: data.cost_center_number, - company: frm.doc.company + cost_center_number: cstr(data.cost_center_number), + company: frm.doc.company, + merge: data.merge }, callback: function(r) { frappe.dom.unfreeze(); diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py index 291aff3f5a..645da341a3 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.py +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import frappe, erpnext from frappe import _ -from frappe.utils import flt, fmt_money, getdate, formatdate +from frappe.utils import flt, fmt_money, getdate, formatdate, cint from frappe.model.document import Document from frappe.model.naming import set_name_from_naming_options from frappe.model.meta import get_field_precision @@ -134,10 +134,17 @@ class GLEntry(Document): return self.cost_center_company[self.cost_center] + def _check_is_group(): + return cint(frappe.get_cached_value('Cost Center', self.cost_center, 'is_group')) + if self.cost_center and _get_cost_center_company() != self.company: frappe.throw(_("{0} {1}: Cost Center {2} does not belong to Company {3}") .format(self.voucher_type, self.voucher_no, self.cost_center, self.company)) + if self.cost_center and _check_is_group(): + frappe.throw(_("""{0} {1}: Cost Center {2} is a group cost center and group cost centers cannot + be used in transactions""").format(self.voucher_type, self.voucher_no, frappe.bold(self.cost_center))) + def validate_party(self): validate_party_frozen_disabled(self.party_type, self.party) diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js index 9a832e3c1f..5685f839fe 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.js +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js @@ -278,7 +278,7 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({ // payroll entry if(jvd.reference_type==="Payroll Entry") { return { - query: "erpnext.hr.doctype.payroll_entry.payroll_entry.get_payroll_entries_for_jv", + query: "erpnext.payroll.doctype.payroll_entry.payroll_entry.get_payroll_entries_for_jv", }; } diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index 41922a2a69..caaf30f11f 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -54,7 +54,7 @@ class JournalEntry(AccountsController): def on_cancel(self): from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries - from erpnext.hr.doctype.salary_slip.salary_slip import unlink_ref_doc_from_salary_slip + from erpnext.payroll.doctype.salary_slip.salary_slip import unlink_ref_doc_from_salary_slip unlink_ref_doc_from_payment_entries(self) unlink_ref_doc_from_salary_slip(self.name) self.ignore_linked_doctypes = ('GL Entry', 'Stock Ledger Entry') diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 15e51bbd99..59611bc74c 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -453,6 +453,8 @@ class PaymentEntry(AccountsController): frappe.throw(_("Reference No and Reference Date is mandatory for Bank transaction")) def set_remarks(self): + if self.remarks: return + if self.payment_type=="Internal Transfer": remarks = [_("Amount {0} {1} transferred from {2} to {3}") .format(self.paid_from_account_currency, self.paid_amount, self.paid_from, self.paid_to)] diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index aa1d5b526c..870718c22d 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -238,6 +238,12 @@ class PurchaseInvoice(BuyingController): not frappe.db.get_value("Purchase Order Item", item.po_detail, "delivered_by_supplier")): if self.update_stock and (not item.from_warehouse): + if for_validate and item.expense_account and item.expense_account != warehouse_account[item.warehouse]["account"]: + frappe.msgprint(_('''Row {0}: Expense Head changed to {1} because account {2} + is not linked to warehouse {3} or it is not the default inventory account'''.format( + item.idx, frappe.bold(warehouse_account[item.warehouse]["account"]), + frappe.bold(item.expense_account), frappe.bold(item.warehouse)))) + item.expense_account = warehouse_account[item.warehouse]["account"] else: # check if 'Stock Received But Not Billed' account is credited in Purchase receipt or not @@ -247,10 +253,21 @@ class PurchaseInvoice(BuyingController): (item.purchase_receipt, stock_not_billed_account)) if negative_expense_booked_in_pr: + if for_validate and item.expense_account and item.expense_account != stock_not_billed_account: + frappe.msgprint(_('''Row {0}: Expense Head changed to {1} because + expense is booked against this account in Purchase Receipt {2}'''.format( + item.idx, frappe.bold(stock_not_billed_account), frappe.bold(item.purchase_receipt)))) + item.expense_account = stock_not_billed_account else: # If no purchase receipt present then book expense in 'Stock Received But Not Billed' # This is done in cases when Purchase Invoice is created before Purchase Receipt + if for_validate and item.expense_account and item.expense_account != stock_not_billed_account: + frappe.msgprint(_('''Row {0}: Expense Head changed to {1} as no Purchase + Receipt is created against Item {2}. This is done to handle accounting for cases + when Purchase Receipt is created after Purchase Invoice'''.format( + item.idx, frappe.bold(stock_not_billed_account), frappe.bold(item.item_code)))) + item.expense_account = stock_not_billed_account elif item.is_fixed_asset and not is_cwip_accounting_enabled(asset_category): @@ -1020,7 +1037,7 @@ class PurchaseInvoice(BuyingController): # calculate totals again after applying TDS self.calculate_taxes_and_totals() - + def set_status(self, update=False, status=None, update_modified=True): if self.is_new(): if self.get('amended_from'): diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js index 800ed921bd..86c2e408c0 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js @@ -16,7 +16,7 @@ frappe.listview_settings['Purchase Invoice'] = { } else if(frappe.datetime.get_diff(doc.due_date) < 0) { return [__("Overdue"), "red", "outstanding_amount,>,0|due_date,<,Today"]; } else { - return [__("Unpaid"), "orange", "outstanding_amount,>,0|due,>=,Today"]; + return [__("Unpaid"), "orange", "outstanding_amount,>,0|due_date,>=,Today"]; } } else if(cint(doc.is_return)) { return [__("Return"), "darkgrey", "is_return,=,Yes"]; @@ -24,4 +24,4 @@ frappe.listview_settings['Purchase Invoice'] = { return [__("Paid"), "green", "outstanding_amount,=,0"]; } } -}; +}; \ No newline at end of file diff --git a/erpnext/accounts/report/account_balance/test_account_balance.py b/erpnext/accounts/report/account_balance/test_account_balance.py index 5544fc4673..b6ced312d0 100644 --- a/erpnext/accounts/report/account_balance/test_account_balance.py +++ b/erpnext/accounts/report/account_balance/test_account_balance.py @@ -61,7 +61,7 @@ def make_sales_invoice(): debit_to = 'Debtors - _TC2', income_account = 'Sales - _TC2', expense_account = 'Cost of Goods Sold - _TC2', - cost_center = '_Test Company 2 - _TC2') + cost_center = 'Main - _TC2') diff --git a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py index f0274b4472..2ff5b531c5 100644 --- a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py @@ -63,7 +63,7 @@ def make_sales_invoice(): debit_to = 'Debtors - _TC2', income_account = 'Sales - _TC2', expense_account = 'Cost of Goods Sold - _TC2', - cost_center = '_Test Company 2 - _TC2', + cost_center = 'Main - _TC2', do_not_save=1) si.append('payment_schedule', dict(due_date=getdate(add_days(today(), 30)), invoice_portion=30.00, payment_amount=30)) @@ -83,14 +83,14 @@ def make_payment(docname): def make_credit_note(docname): create_sales_invoice(company="_Test Company 2", - customer = '_Test Customer 2', - currency = 'EUR', - qty = -1, - warehouse = 'Finished Goods - _TC2', - debit_to = 'Debtors - _TC2', - income_account = 'Sales - _TC2', - expense_account = 'Cost of Goods Sold - _TC2', - cost_center = '_Test Company 2 - _TC2', - is_return = 1, - return_against = docname) + customer = '_Test Customer 2', + currency = 'EUR', + qty = -1, + warehouse = 'Finished Goods - _TC2', + debit_to = 'Debtors - _TC2', + income_account = 'Sales - _TC2', + expense_account = 'Cost of Goods Sold - _TC2', + cost_center = 'Main - _TC2', + is_return = 1, + return_against = docname) diff --git a/erpnext/accounts/report/ordered_items_to_be_billed/ordered_items_to_be_billed.js b/erpnext/accounts/report/ordered_items_to_be_billed/ordered_items_to_be_billed.js deleted file mode 100644 index 6e13d67766..0000000000 --- a/erpnext/accounts/report/ordered_items_to_be_billed/ordered_items_to_be_billed.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.query_reports["Ordered Items To Be Billed"] = { - "filters": [ - - ] -} diff --git a/erpnext/accounts/report/ordered_items_to_be_billed/ordered_items_to_be_billed.json b/erpnext/accounts/report/ordered_items_to_be_billed/ordered_items_to_be_billed.json deleted file mode 100644 index c983dc9629..0000000000 --- a/erpnext/accounts/report/ordered_items_to_be_billed/ordered_items_to_be_billed.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "add_total_row": 1, - "apply_user_permissions": 1, - "creation": "2013-02-21 14:26:44", - "disabled": 0, - "docstatus": 0, - "doctype": "Report", - "idx": 3, - "is_standard": "Yes", - "modified": "2017-11-06 13:04:51.559061", - "modified_by": "Administrator", - "module": "Accounts", - "name": "Ordered Items To Be Billed", - "owner": "Administrator", - "query": "select \n `tabSales Order`.`name` as \"Sales Order:Link/Sales Order:120\",\n `tabSales Order`.`customer` as \"Customer:Link/Customer:120\",\n `tabSales Order`.`customer_name` as \"Customer Name:150\",\n`tabSales Order`.`status` as \"Status\",\n `tabSales Order`.`transaction_date` as \"Date:Date\",\n `tabSales Order`.`project` as \"Project\",\n `tabSales Order Item`.item_code as \"Item:Link/Item:120\",\n `tabSales Order Item`.base_amount as \"Amount:Currency:110\",\n (`tabSales Order Item`.billed_amt * ifnull(`tabSales Order`.conversion_rate, 1)) as \"Billed Amount:Currency:110\",\n (`tabSales Order Item`.base_amount - (`tabSales Order Item`.billed_amt * ifnull(`tabSales Order`.conversion_rate, 1))) as \"Pending Amount:Currency:120\",\n `tabSales Order Item`.item_name as \"Item Name::150\",\n `tabSales Order Item`.description as \"Description::200\",\n `tabSales Order`.`company` as \"Company:Link/Company:\"\nfrom\n `tabSales Order`, `tabSales Order Item`\nwhere\n `tabSales Order Item`.`parent` = `tabSales Order`.`name`\n and `tabSales Order`.docstatus = 1\n and `tabSales Order`.status != \"Closed\"\n and `tabSales Order Item`.amount > 0\n and `tabSales Order Item`.billed_amt < `tabSales Order Item`.amount\norder by `tabSales Order`.transaction_date asc", - "ref_doctype": "Sales Invoice", - "report_name": "Ordered Items To Be Billed", - "report_type": "Script Report", - "roles": [ - { - "role": "Accounts Manager" - }, - { - "role": "Accounts User" - } - ] -} \ No newline at end of file diff --git a/erpnext/accounts/report/ordered_items_to_be_billed/ordered_items_to_be_billed.py b/erpnext/accounts/report/ordered_items_to_be_billed/ordered_items_to_be_billed.py deleted file mode 100644 index ec0d2f39f3..0000000000 --- a/erpnext/accounts/report/ordered_items_to_be_billed/ordered_items_to_be_billed.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - -from __future__ import unicode_literals -import frappe -from frappe import _ -from erpnext.accounts.report.non_billed_report import get_ordered_to_be_billed_data - -def execute(filters=None): - columns = get_column() - args = get_args() - data = get_ordered_to_be_billed_data(args) - return columns, data - -def get_column(): - return [ - _("Sales Order") + ":Link/Sales Order:120", _("Status") + "::120", _("Date") + ":Date:100", - _("Suplier") + ":Link/Customer:120", _("Customer Name") + "::120", - _("Project") + ":Link/Project:120", _("Item Code") + ":Link/Item:120", - _("Amount") + ":Currency:100", _("Billed Amount") + ":Currency:100", _("Pending Amount") + ":Currency:100", - _("Item Name") + "::120", _("Description") + "::120", _("Company") + ":Link/Company:120", - ] - -def get_args(): - return {'doctype': 'Sales Order', 'party': 'customer', - 'date': 'transaction_date', 'order': 'transaction_date', 'order_by': 'asc'} \ No newline at end of file diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index f6cd606757..16146f4480 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -837,7 +837,7 @@ def create_payment_gateway_account(gateway): pass @frappe.whitelist() -def update_cost_center(docname, cost_center_name, cost_center_number, company): +def update_cost_center(docname, cost_center_name, cost_center_number, company, merge): ''' Renames the document by adding the number as a prefix to the current name and updates all transaction where it was present. @@ -853,7 +853,7 @@ def update_cost_center(docname, cost_center_name, cost_center_number, company): new_name = get_autoname_with_number(cost_center_number, cost_center_name, docname, company) if docname != new_name: - frappe.rename_doc("Cost Center", docname, new_name, force=1) + frappe.rename_doc("Cost Center", docname, new_name, force=1, merge=merge) return new_name def validate_field_number(doctype_name, docname, number_value, company, field_name): diff --git a/erpnext/buying/dashboard_fixtures.py b/erpnext/buying/dashboard_fixtures.py index 172c936bd2..c6e2ffa634 100644 --- a/erpnext/buying/dashboard_fixtures.py +++ b/erpnext/buying/dashboard_fixtures.py @@ -155,8 +155,7 @@ def get_number_cards(company, fiscal_year_name, start_date, end_date): ["Purchase Order", "transaction_date", "Between", [start_date, end_date], False], ["Purchase Order", "status", "not in", ["Draft", "Cancelled", "Closed", None], False], ["Purchase Order", "docstatus", "=", 1, False], - ["Purchase Order", "company", "=", company.name, False], - ["Purchase Order", "transaction_date", "Between", [start_date,end_date], False] + ["Purchase Order", "company", "=", company.name, False] ]), "function": "Sum", "is_public": 1, diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.js b/erpnext/buying/doctype/buying_settings/buying_settings.js index 01b40cd26f..e496e9628d 100644 --- a/erpnext/buying/doctype/buying_settings/buying_settings.js +++ b/erpnext/buying/doctype/buying_settings/buying_settings.js @@ -11,21 +11,21 @@ frappe.tour['Buying Settings'] = [ { fieldname: "supp_master_name", title: "Supplier Naming By", - description: __("By default, the Item Name is set as per the Item Code entered. If you want Items to be named by a set ") + "Naming Series" + __(" choose the 'Naming Series' option."), + description: __("By default, the Supplier Name is set as per the Supplier Name entered. If you want Suppliers to be named by a ") + "Naming Series" + __(" choose the 'Naming Series' option."), }, { fieldname: "buying_price_list", title: "Default Buying Price List", - description: __("Configure the default Price List when creating a new Buying transaction, the default is set as 'Standard Buying'. Item prices will be fetched from this Price List.") + description: __("Configure the default Price List when creating a new Purchase transaction. Item prices will be fetched from this Price List.") }, { fieldname: "po_required", title: "Purchase Order Required for Purchase Invoice & Receipt Creation", - description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Purchase Invoice or Receipt without creating a Purchase Order first. This configuration can be overridden for a particular supplier by enabling the 'Allow Purchase Invoice Creation Without Purchase Order' checkbox in supplier master.") + description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Purchase Invoice or Receipt without creating a Purchase Order first. This configuration can be overridden for a particular supplier by enabling the 'Allow Purchase Invoice Creation Without Purchase Order' checkbox in the Supplier master.") }, { fieldname: "pr_required", title: "Purchase Receipt Required for Purchase Invoice Creation", - description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Purchase Invoice without creating a Purchase Receipt first. This configuration can be overridden for a particular supplier by enabling the 'Allow Purchase Invoice Creation Without Purchase Receipt' checkbox in supplier master.") + description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Purchase Invoice without creating a Purchase Receipt first. This configuration can be overridden for a particular supplier by enabling the 'Allow Purchase Invoice Creation Without Purchase Receipt' checkbox in the Supplier master.") } ]; \ No newline at end of file diff --git a/erpnext/buying/module_onboarding/buying/buying.json b/erpnext/buying/module_onboarding/buying/buying.json index 8fe2f388b0..6e4bbc95a2 100644 --- a/erpnext/buying/module_onboarding/buying/buying.json +++ b/erpnext/buying/module_onboarding/buying/buying.json @@ -19,7 +19,7 @@ "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/buying", "idx": 0, "is_complete": 0, - "modified": "2020-05-27 17:17:52.075947", + "modified": "2020-06-01 12:55:09.234944", "modified_by": "Administrator", "module": "Buying", "name": "Buying", diff --git a/erpnext/buying/onboarding_step/buying_settings/buying_settings.json b/erpnext/buying/onboarding_step/buying_settings/buying_settings.json index a788ccd4cc..6d765af137 100644 --- a/erpnext/buying/onboarding_step/buying_settings/buying_settings.json +++ b/erpnext/buying/onboarding_step/buying_settings/buying_settings.json @@ -1,19 +1,19 @@ { - "action": "Update Settings", + "action": "Show Form Tour", "creation": "2020-05-06 15:53:44.667414", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, "is_complete": 0, - "is_mandatory": 0, - "is_single": 0, + "is_mandatory": 1, + "is_single": 1, "is_skipped": 0, - "modified": "2020-05-12 18:30:06.323797", + "modified": "2020-06-01 12:52:57.668870", "modified_by": "Administrator", "name": "Buying Settings", "owner": "Administrator", "reference_document": "Buying Settings", "show_full_form": 0, "title": "Configure Buying Settings.", - "validate_action": 1 + "validate_action": 0 } \ No newline at end of file diff --git a/erpnext/crm/doctype/opportunity/opportunity.js b/erpnext/crm/doctype/opportunity/opportunity.js index 0c9ba495c7..f1b8171349 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.js +++ b/erpnext/crm/doctype/opportunity/opportunity.js @@ -96,6 +96,7 @@ frappe.ui.form.on("Opportunity", { }); } else { frm.add_custom_button(__("Reopen"), function() { + frm.set_value("lost_reasons",[]) frm.set_value("status", "Open"); frm.save(); }); diff --git a/erpnext/hr/dashboard_fixtures.py b/erpnext/hr/dashboard_fixtures.py index 6e042ac78d..6d8091be64 100644 --- a/erpnext/hr/dashboard_fixtures.py +++ b/erpnext/hr/dashboard_fixtures.py @@ -24,24 +24,19 @@ def get_human_resource_dashboard(): "dashboard_name": "Human Resource", "is_default": 1, "charts": [ - { "chart": "Outgoing Salary", "width": "Full"}, + { "chart": "Attendance Count", "width": "Full"}, { "chart": "Gender Diversity Ratio", "width": "Half"}, { "chart": "Job Application Status", "width": "Half"}, { "chart": 'Designation Wise Employee Count', "width": "Half"}, { "chart": 'Department Wise Employee Count', "width": "Half"}, { "chart": 'Designation Wise Openings', "width": "Half"}, - { "chart": 'Department Wise Openings', "width": "Half"}, - { "chart": "Attendance Count", "width": "Full"} + { "chart": 'Department Wise Openings', "width": "Half"} ], "cards": [ {"card": "Total Employees"}, {"card": "New Joinees (Last year)"}, {'card': "Employees Left (Last year)"}, - {'card': "Total Job Openings (Last month)"}, {'card': "Total Applicants (Last month)"}, - {'card': "Shortlisted Candidates (Last month)"}, - {'card': "Rejected Candidates (Last month)"}, - {'card': "Total Job Offered (Last month)"}, ] } @@ -71,13 +66,6 @@ def get_charts(): filters_json = json.dumps([["Job Applicant", "creation", "Previous", "1 month"]])) ) - dashboard_charts.append( - get_dashboards_chart_doc('Outgoing Salary', "Sum", "Line", - document_type = "Salary Slip", based_on="end_date", - value_based_on = "rounded_total", time_interval = "Monthly", timeseries = 1, - filters_json = json.dumps([["Salary Slip", "docstatus", "=", 1]])) - ) - custom_options = '''{ "type": "line", "axisOptions": { @@ -156,32 +144,6 @@ def get_number_cards(): ) ) - number_cards.append( - get_number_cards_doc("Job Opening", "Total Job Openings (Last month)", func = "Sum", - aggregate_function_based_on = "planned_vacancies", - filters_json = json.dumps([["Job Opening", "creation", "Previous", "1 month"]]) - ) - ) - number_cards.append( - get_number_cards_doc("Job Applicant", "Shortlisted Candidates (Last month)", filters_json = json.dumps([ - ["Job Applicant", "status", "=", "Accepted"], - ["Job Applicant", "creation", "Previous", "1 month"] - ]) - ) - ) - number_cards.append( - get_number_cards_doc("Job Applicant", "Rejected Candidates (Last month)", filters_json = json.dumps([ - ["Job Applicant", "status", "=", "Rejected"], - ["Job Applicant", "creation", "Previous", "1 month"] - ]) - ) - ) - number_cards.append( - get_number_cards_doc("Job Offer", "Total Job Offered (Last month)", - filters_json = json.dumps([["Job Offer", "creation", "Previous", "1 month"]]) - ) - ) - return number_cards diff --git a/erpnext/hr/desk_page/hr/hr.json b/erpnext/hr/desk_page/hr/hr.json index 12548d48a7..0fed8d322f 100644 --- a/erpnext/hr/desk_page/hr/hr.json +++ b/erpnext/hr/desk_page/hr/hr.json @@ -20,11 +20,6 @@ "label": "Leaves", "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Application\",\n \"name\": \"Leave Application\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Allocation\",\n \"name\": \"Leave Allocation\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Leave Type\"\n ],\n \"label\": \"Leave Policy\",\n \"name\": \"Leave Policy\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Leave Period\",\n \"name\": \"Leave Period\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Leave Type\",\n \"name\": \"Leave Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Holiday List\",\n \"name\": \"Holiday List\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Compensatory Leave Request\",\n \"name\": \"Compensatory Leave Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Encashment\",\n \"name\": \"Leave Encashment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Leave Block List\",\n \"name\": \"Leave Block List\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Leave Application\"\n ],\n \"doctype\": \"Leave Application\",\n \"is_query_report\": true,\n \"label\": \"Employee Leave Balance\",\n \"name\": \"Employee Leave Balance\",\n \"type\": \"report\"\n }\n]" }, - { - "hidden": 0, - "label": "Payroll", - "links": "[\n {\n \"label\": \"Salary Structure\",\n \"name\": \"Salary Structure\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Salary Structure\",\n \"Employee\"\n ],\n \"label\": \"Salary Structure Assignment\",\n \"name\": \"Salary Structure Assignment\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Payroll Entry\",\n \"name\": \"Payroll Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Slip\",\n \"name\": \"Salary Slip\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Payroll Period\",\n \"name\": \"Payroll Period\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Income Tax Slab\",\n \"name\": \"Income Tax Slab\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Component\",\n \"name\": \"Salary Component\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Additional Salary\",\n \"name\": \"Additional Salary\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Retention Bonus\",\n \"name\": \"Retention Bonus\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Incentive\",\n \"name\": \"Employee Incentive\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"is_query_report\": true,\n \"label\": \"Salary Register\",\n \"name\": \"Salary Register\",\n \"type\": \"report\"\n }\n]" - }, { "hidden": 0, "label": "Attendance", @@ -50,11 +45,6 @@ "label": "Recruitment", "links": "[\n {\n \"label\": \"Job Opening\",\n \"name\": \"Job Opening\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Job Applicant\",\n \"name\": \"Job Applicant\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Job Offer\",\n \"name\": \"Job Offer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Staffing Plan\",\n \"name\": \"Staffing Plan\",\n \"type\": \"doctype\"\n }\n]" }, - { - "hidden": 0, - "label": "Loans", - "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Loan Application\",\n \"name\": \"Loan Application\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan\",\n \"name\": \"Loan\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Type\",\n \"name\": \"Loan Type\",\n \"type\": \"doctype\"\n }\n]" - }, { "hidden": 0, "label": "Training", @@ -69,18 +59,13 @@ "hidden": 0, "label": "Performance", "links": "[\n {\n \"label\": \"Appraisal\",\n \"name\": \"Appraisal\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Appraisal Template\",\n \"name\": \"Appraisal Template\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Energy Point Rule\",\n \"name\": \"Energy Point Rule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Energy Point Log\",\n \"name\": \"Energy Point Log\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Employee Tax and Benefits", - "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Declaration\",\n \"name\": \"Employee Tax Exemption Declaration\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Proof Submission\",\n \"name\": \"Employee Tax Exemption Proof Submission\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\",\n \"Payroll Period\"\n ],\n \"label\": \"Employee Other Income\",\n \"name\": \"Employee Other Income\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Benefit Application\",\n \"name\": \"Employee Benefit Application\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Benefit Claim\",\n \"name\": \"Employee Benefit Claim\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Category\",\n \"name\": \"Employee Tax Exemption Category\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Sub Category\",\n \"name\": \"Employee Tax Exemption Sub Category\",\n \"type\": \"doctype\"\n }\n]" } ], "category": "Modules", "charts": [ { - "chart_name": "Outgoing Salary", - "label": "Outgoing Salary" + "chart_name": "Attendance Count", + "label": "Attendance Count" } ], "creation": "2020-03-02 15:48:58.322521", @@ -103,21 +88,13 @@ "pin_to_top": 0, "shortcuts": [ { - "color": "#cef6d1", + "color": "#9deca2", "format": "{} Active", "label": "Employee", "link_to": "Employee", "stats_filter": "{\"status\":\"Active\"}", "type": "DocType" }, - { - "color": "#ffe8cd", - "format": "{} Open", - "label": "Leave Application", - "link_to": "Leave Application", - "stats_filter": "{\"status\":\"Open\"}", - "type": "DocType" - }, { "label": "Attendance", "link_to": "Attendance", @@ -125,8 +102,15 @@ "type": "DocType" }, { - "label": "Salary Structure", - "link_to": "Salary Structure", + "format": "{} Open", + "label": "Leave Application", + "link_to": "Leave Application", + "stats_filter": "{\"status\":\"Open\"}", + "type": "DocType" + }, + { + "label": "Job Applicant", + "link_to": "Job Applicant", "type": "DocType" }, { diff --git a/erpnext/hr/doctype/employee_advance/employee_advance.py b/erpnext/hr/doctype/employee_advance/employee_advance.py index a49dfcfc2a..76195812c8 100644 --- a/erpnext/hr/doctype/employee_advance/employee_advance.py +++ b/erpnext/hr/doctype/employee_advance/employee_advance.py @@ -22,6 +22,7 @@ class EmployeeAdvance(Document): self.validate_employee_advance_account() def on_cancel(self): + self.ignore_linked_doctypes = ('GL Entry') self.set_status() def set_status(self): diff --git a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.json b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.json deleted file mode 100644 index cf624195b7..0000000000 --- a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.json +++ /dev/null @@ -1,576 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 1, - "autoname": "HR-BEN-APP-.YY.-.MM.-.#####", - "beta": 0, - "creation": "2018-04-13 16:31:39.190787", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "employee", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Employee", - "length": 0, - "no_copy": 0, - "options": "Employee", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "employee.employee_name", - "fieldname": "employee_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Employee Name", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "max_benefits", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Max Benefits (Yearly)", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "remaining_benefit", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Remaining Benefits (Yearly)", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_2", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "Today", - "fieldname": "date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "payroll_period", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Payroll Period", - "length": 0, - "no_copy": 0, - "options": "Payroll Period", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "employee.department", - "fieldname": "department", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Department", - "length": 0, - "no_copy": 0, - "options": "Department", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "amended_from", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Amended From", - "length": 0, - "no_copy": 1, - "options": "Employee Benefit Application", - "permlevel": 0, - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_4", - "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": "Benefits Applied", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "employee_benefits", - "fieldtype": "Table", - "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": "Employee Benefits", - "length": 0, - "no_copy": 0, - "options": "Employee Benefit Application Detail", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "totals", - "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": "Totals", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "total_amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Total Amount", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "pro_rata_dispensed_amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Dispensed Amount (Pro-rated)", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 1, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-08-21 16:15:39.714081", - "modified_by": "Administrator", - "module": "HR", - "name": "Employee Benefit Application", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 1, - "write": 1 - }, - { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "HR Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 1, - "write": 1 - }, - { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "HR User", - "set_user_permissions": 0, - "share": 1, - "submit": 1, - "write": 1 - }, - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Employee", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "employee_name", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/hr/doctype/employee_benefit_application_detail/employee_benefit_application_detail.json b/erpnext/hr/doctype/employee_benefit_application_detail/employee_benefit_application_detail.json deleted file mode 100644 index 56421db8c3..0000000000 --- a/erpnext/hr/doctype/employee_benefit_application_detail/employee_benefit_application_detail.json +++ /dev/null @@ -1,177 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "", - "beta": 0, - "creation": "2018-04-13 16:36:18.389786", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "earning_component", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Earning Component", - "length": 0, - "no_copy": 0, - "options": "Salary Component", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "earning_component.pay_against_benefit_claim", - "fieldname": "pay_against_benefit_claim", - "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": "Pay Against Benefit Claim", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "earning_component.max_benefit_amount", - "fieldname": "max_benefit_amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Max Benefit Amount", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Amount", - "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": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-08-21 16:15:42.111118", - "modified_by": "Administrator", - "module": "HR", - "name": "Employee Benefit Application Detail", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "search_fields": "", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/hr/doctype/employee_benefit_claim/employee_benefit_claim.json b/erpnext/hr/doctype/employee_benefit_claim/employee_benefit_claim.json deleted file mode 100644 index 1aa69d02a5..0000000000 --- a/erpnext/hr/doctype/employee_benefit_claim/employee_benefit_claim.json +++ /dev/null @@ -1,580 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 0, - "autoname": "HR-BEN-CLM-.YY.-.MM.-.#####", - "beta": 0, - "creation": "2018-04-13 16:43:10.386409", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "employee", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Employee", - "length": 0, - "no_copy": 0, - "options": "Employee", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "employee.employee_name", - "fieldname": "employee_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Employee Name", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "employee.department", - "fieldname": "department", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Department", - "length": 0, - "no_copy": 0, - "options": "Department", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_3", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "Today", - "fieldname": "claim_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Claim Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "benefit_type_and_amount", - "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": "Benefit Type and Amount", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "earning_component", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Claim Benefit For", - "length": 0, - "no_copy": 0, - "options": "Salary Component", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "earning_component.max_benefit_amount", - "fieldname": "max_amount_eligible", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Max Amount Eligible", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "earning_component.pay_against_benefit_claim", - "fieldname": "pay_against_benefit_claim", - "fieldtype": "Check", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Pay Against Benefit Claim", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "claimed_amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Claimed Amount", - "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": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "salary_slip", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Salary Slip", - "length": 0, - "no_copy": 0, - "options": "Salary Slip", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "amended_from", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Amended From", - "length": 0, - "no_copy": 1, - "options": "Employee Benefit Claim", - "permlevel": 0, - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_9", - "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": "Expense Proof", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "attachments", - "fieldtype": "Attach", - "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": "Attachments", - "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, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 1, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-08-21 16:15:35.942067", - "modified_by": "Administrator", - "module": "HR", - "name": "Employee Benefit Claim", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 1, - "write": 1 - }, - { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "HR Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 1, - "write": 1 - }, - { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "HR User", - "set_user_permissions": 0, - "share": 1, - "submit": 1, - "write": 1 - }, - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Employee", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "employee_name", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/hr/doctype/employee_promotion/test_employee_promotion.py b/erpnext/hr/doctype/employee_promotion/test_employee_promotion.py index 420bbe6b1a..9e7d3186b8 100644 --- a/erpnext/hr/doctype/employee_promotion/test_employee_promotion.py +++ b/erpnext/hr/doctype/employee_promotion/test_employee_promotion.py @@ -6,7 +6,7 @@ from __future__ import unicode_literals import frappe import unittest from frappe.utils import getdate, add_days -from erpnext.hr.doctype.salary_structure.test_salary_structure import make_employee +from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_employee class TestEmployeePromotion(unittest.TestCase): def setUp(self): diff --git a/erpnext/hr/doctype/employee_tax_exemption_category/employee_tax_exemption_category.json b/erpnext/hr/doctype/employee_tax_exemption_category/employee_tax_exemption_category.json deleted file mode 100644 index 66fac5bee5..0000000000 --- a/erpnext/hr/doctype/employee_tax_exemption_category/employee_tax_exemption_category.json +++ /dev/null @@ -1,169 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 1, - "autoname": "Prompt", - "beta": 0, - "creation": "2018-04-13 16:51:36.971140", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "max_amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Max Exemption Amount", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "1", - "fetch_if_empty": 0, - "fieldname": "is_active", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Is Active", - "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, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2019-04-25 13:20:31.367158", - "modified_by": "Administrator", - "module": "HR", - "name": "Employee Tax Exemption Category", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - }, - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "HR Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - }, - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "HR User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.json b/erpnext/hr/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.json deleted file mode 100644 index 7b3b8f5caa..0000000000 --- a/erpnext/hr/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.json +++ /dev/null @@ -1,179 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2018-04-13 16:56:23.333041", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "exemption_sub_category", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Exemption Sub Category", - "length": 0, - "no_copy": 0, - "options": "Employee Tax Exemption Sub Category", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "exemption_sub_category.exemption_category", - "fetch_if_empty": 0, - "fieldname": "exemption_category", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Exemption Category", - "length": 0, - "no_copy": 0, - "options": "Employee Tax Exemption Category", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "exemption_sub_category.max_amount", - "fetch_if_empty": 0, - "fieldname": "max_amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Maximum Exempted Amount", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Declared Amount", - "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": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2019-04-26 11:28:14.023086", - "modified_by": "Administrator", - "module": "HR", - "name": "Employee Tax Exemption Declaration Category", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/test_employee_tax_exemption_proof_submission.py b/erpnext/hr/doctype/employee_tax_exemption_proof_submission/test_employee_tax_exemption_proof_submission.py deleted file mode 100644 index e54d9193ba..0000000000 --- a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/test_employee_tax_exemption_proof_submission.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt -from __future__ import unicode_literals - -import frappe -import unittest -# from erpnext.hr.doctype.employee_tax_exemption_declaration.test_employee_tax_exemption_declaration import create_exemption_category, create_payroll_period -# -# class TestEmployeeTaxExemptionProofSubmission(unittest.TestCase): -# def setup(self): -# make_employee("employee@proofsubmission.com") -# create_payroll_period() -# create_exemption_category() -# frappe.db.sql("""delete from `tabEmployee Tax Exemption Proof Submission`""") -# -# def test_exemption_amount_lesser_than_category_max(self): -# declaration = frappe.get_doc({ -# "doctype": "Employee Tax Exemption Proof Submission", -# "employee": frappe.get_value("Employee", {"user_id":"employee@proofsubmission.com"}, "name"), -# "payroll_period": "Test Payroll Period", -# "tax_exemption_proofs": [dict(exemption_sub_category = "_Test Sub Category", -# type_of_proof = "Test Proof", -# exemption_category = "_Test Category", -# amount = 150000)] -# }) -# self.assertRaises(frappe.ValidationError, declaration.save) -# declaration = frappe.get_doc({ -# "doctype": "Employee Tax Exemption Proof Submission", -# "payroll_period": "Test Payroll Period", -# "employee": frappe.get_value("Employee", {"user_id":"employee@proofsubmission.com"}, "name"), -# "tax_exemption_proofs": [dict(exemption_sub_category = "_Test Sub Category", -# type_of_proof = "Test Proof", -# exemption_category = "_Test Category", -# amount = 100000)] -# }) -# self.assertTrue(declaration.save) -# self.assertTrue(declaration.submit) -# -# def test_duplicate_category_in_proof_submission(self): -# declaration = frappe.get_doc({ -# "doctype": "Employee Tax Exemption Proof Submission", -# "employee": frappe.get_value("Employee", {"user_id":"employee@proofsubmission.com"}, "name"), -# "payroll_period": "Test Payroll Period", -# "tax_exemption_proofs": [dict(exemption_sub_category = "_Test Sub Category", -# exemption_category = "_Test Category", -# type_of_proof = "Test Proof", -# amount = 100000), -# dict(exemption_sub_category = "_Test Sub Category", -# exemption_category = "_Test Category", -# amount = 50000), -# ] -# }) -# self.assertRaises(frappe.ValidationError, declaration.save) diff --git a/erpnext/hr/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.json b/erpnext/hr/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.json deleted file mode 100644 index b9254afad0..0000000000 --- a/erpnext/hr/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.json +++ /dev/null @@ -1,213 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2018-04-13 17:19:03.006149", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "exemption_sub_category", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Exemption Sub Category", - "length": 0, - "no_copy": 0, - "options": "Employee Tax Exemption Sub Category", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "exemption_sub_category.exemption_category", - "fetch_if_empty": 0, - "fieldname": "exemption_category", - "fieldtype": "Read Only", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Exemption Category", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "exemption_sub_category.max_amount", - "fetch_if_empty": 0, - "fieldname": "max_amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Maximum Exemption Amount", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "type_of_proof", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Type of Proof", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Actual Amount", - "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, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2019-04-25 15:45:03.154904", - "modified_by": "Administrator", - "module": "HR", - "name": "Employee Tax Exemption Proof Submission Detail", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.json b/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.json deleted file mode 100644 index b0e492e7ca..0000000000 --- a/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.json +++ /dev/null @@ -1,204 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 1, - "autoname": "Prompt", - "beta": 0, - "creation": "2018-05-09 12:47:26.983095", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "exemption_category", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Tax Exemption Category", - "length": 0, - "no_copy": 0, - "options": "Employee Tax Exemption Category", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "exemption_category.max_amount", - "fetch_if_empty": 1, - "fieldname": "max_amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Max Exemption Amount", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "1", - "fetch_if_empty": 0, - "fieldname": "is_active", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Is Active", - "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, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2019-04-25 13:24:05.164877", - "modified_by": "Administrator", - "module": "HR", - "name": "Employee Tax Exemption Sub Category", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - }, - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "HR Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - }, - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "HR User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/hr/doctype/hr_settings/hr_settings.js b/erpnext/hr/doctype/hr_settings/hr_settings.js index b629b42f9b..fd082fda09 100644 --- a/erpnext/hr/doctype/hr_settings/hr_settings.js +++ b/erpnext/hr/doctype/hr_settings/hr_settings.js @@ -2,21 +2,6 @@ // For license information, please see license.txt frappe.ui.form.on('HR Settings', { - encrypt_salary_slips_in_emails: function(frm) { - let encrypt_state = frm.doc.encrypt_salary_slips_in_emails; - frm.set_df_property('password_policy', 'reqd', encrypt_state); - }, - - validate: function(frm) { - let policy = frm.doc.password_policy; - if (policy) { - if (policy.includes(' ') || policy.includes('--')) { - frappe.msgprint(__("Password policy cannot contain spaces or simultaneous hyphens. The format will be restructured automatically")); - } - frm.set_value('password_policy', policy.split(new RegExp(" |-", 'g')).filter((token) => token).join('-')); - } - }, - restrict_backdated_leave_application: function(frm) { frm.toggle_reqd("role_allowed_to_create_backdated_leave_application", frm.doc.restrict_backdated_leave_application); } diff --git a/erpnext/hr/doctype/hr_settings/hr_settings.json b/erpnext/hr/doctype/hr_settings/hr_settings.json index ebf8723be6..c42e1d72fc 100644 --- a/erpnext/hr/doctype/hr_settings/hr_settings.json +++ b/erpnext/hr/doctype/hr_settings/hr_settings.json @@ -12,16 +12,6 @@ "column_break_4", "stop_birthday_reminders", "expense_approver_mandatory_in_expense_claim", - "payroll_settings", - "payroll_based_on", - "max_working_hours_against_timesheet", - "include_holidays_in_total_working_days", - "disable_rounded_total", - "column_break_11", - "daily_wages_fraction_for_half_day", - "email_salary_slip_to_employee", - "encrypt_salary_slips_in_emails", - "password_policy", "leave_settings", "leave_approval_notification_template", "leave_status_notification_template", @@ -38,13 +28,17 @@ { "fieldname": "employee_settings", "fieldtype": "Section Break", - "label": "Employee Settings" + "label": "Employee Settings", + "show_days": 1, + "show_seconds": 1 }, { "description": "Enter retirement age in years", "fieldname": "retirement_age", "fieldtype": "Data", - "label": "Retirement Age" + "label": "Retirement Age", + "show_days": 1, + "show_seconds": 1 }, { "default": "Naming Series", @@ -52,161 +46,126 @@ "fieldname": "emp_created_by", "fieldtype": "Select", "label": "Employee Records to be created by", - "options": "Naming Series\nEmployee Number\nFull Name" + "options": "Naming Series\nEmployee Number\nFull Name", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "column_break_4", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 }, { "default": "0", "description": "Don't send Employee Birthday Reminders", "fieldname": "stop_birthday_reminders", "fieldtype": "Check", - "label": "Stop Birthday Reminders" + "label": "Stop Birthday Reminders", + "show_days": 1, + "show_seconds": 1 }, { "default": "1", "fieldname": "expense_approver_mandatory_in_expense_claim", "fieldtype": "Check", - "label": "Expense Approver Mandatory In Expense Claim" - }, - { - "fieldname": "payroll_settings", - "fieldtype": "Section Break", - "label": "Payroll Settings" - }, - { - "default": "0", - "description": "If checked, Total no. of Working Days will include holidays, and this will reduce the value of Salary Per Day", - "fieldname": "include_holidays_in_total_working_days", - "fieldtype": "Check", - "label": "Include holidays in Total no. of Working Days" - }, - { - "fieldname": "max_working_hours_against_timesheet", - "fieldtype": "Float", - "label": "Max working hours against Timesheet" - }, - { - "fieldname": "column_break_11", - "fieldtype": "Column Break" - }, - { - "default": "1", - "description": "Emails salary slip to employee based on preferred email selected in Employee", - "fieldname": "email_salary_slip_to_employee", - "fieldtype": "Check", - "label": "Email Salary Slip to Employee" - }, - { - "default": "0", - "depends_on": "eval: doc.email_salary_slip_to_employee == 1;", - "description": "The salary slip emailed to the employee will be password protected, the password will be generated based on the password policy.", - "fieldname": "encrypt_salary_slips_in_emails", - "fieldtype": "Check", - "label": "Encrypt Salary Slips in Emails" - }, - { - "depends_on": "eval: doc.encrypt_salary_slips_in_emails == 1", - "description": "Example: SAL-{first_name}-{date_of_birth.year}
This will generate a password like SAL-Jane-1972", - "fieldname": "password_policy", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Password Policy" + "label": "Expense Approver Mandatory In Expense Claim", + "show_days": 1, + "show_seconds": 1 }, { "collapsible": 1, "fieldname": "leave_settings", "fieldtype": "Section Break", - "label": "Leave Settings" + "label": "Leave Settings", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "leave_approval_notification_template", "fieldtype": "Link", "label": "Leave Approval Notification Template", - "options": "Email Template" + "options": "Email Template", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "leave_status_notification_template", "fieldtype": "Link", "label": "Leave Status Notification Template", - "options": "Email Template" + "options": "Email Template", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "column_break_18", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 }, { "default": "1", "fieldname": "leave_approver_mandatory_in_leave_application", "fieldtype": "Check", - "label": "Leave Approver Mandatory In Leave Application" + "label": "Leave Approver Mandatory In Leave Application", + "show_days": 1, + "show_seconds": 1 }, { "default": "0", "fieldname": "show_leaves_of_all_department_members_in_calendar", "fieldtype": "Check", - "label": "Show Leaves Of All Department Members In Calendar" + "label": "Show Leaves Of All Department Members In Calendar", + "show_days": 1, + "show_seconds": 1 }, { "collapsible": 1, "fieldname": "hiring_settings", "fieldtype": "Section Break", - "label": "Hiring Settings" + "label": "Hiring Settings", + "show_days": 1, + "show_seconds": 1 }, { "default": "0", "fieldname": "check_vacancies", "fieldtype": "Check", - "label": "Check Vacancies On Job Offer Creation" + "label": "Check Vacancies On Job Offer Creation", + "show_days": 1, + "show_seconds": 1 }, { "default": "0", "fieldname": "auto_leave_encashment", "fieldtype": "Check", - "label": "Auto Leave Encashment" - }, - { - "default": "0", - "description": "If checked, hides and disables Rounded Total field in Salary Slips", - "fieldname": "disable_rounded_total", - "fieldtype": "Check", - "label": "Disable Rounded Total" + "label": "Auto Leave Encashment", + "show_days": 1, + "show_seconds": 1 }, { "default": "0", "fieldname": "restrict_backdated_leave_application", "fieldtype": "Check", - "label": "Restrict Backdated Leave Application" + "label": "Restrict Backdated Leave Application", + "show_days": 1, + "show_seconds": 1 }, { "depends_on": "eval:doc.restrict_backdated_leave_application == 1", "fieldname": "role_allowed_to_create_backdated_leave_application", "fieldtype": "Link", "label": "Role Allowed to Create Backdated Leave Application", - "options": "Role" - }, - { - "default": "Leave", - "fieldname": "payroll_based_on", - "fieldtype": "Select", - "label": "Calculate Payroll Working Days Based On", - "options": "Leave\nAttendance" - }, - { - "default": "0.5", - "description": "The fraction of daily wages to be paid for half-day attendance", - "fieldname": "daily_wages_fraction_for_half_day", - "fieldtype": "Float", - "label": "Daily Wages Fraction for Half Day" + "options": "Role", + "show_days": 1, + "show_seconds": 1 } ], "icon": "fa fa-cog", "idx": 1, "issingle": 1, "links": [], - "modified": "2020-05-11 13:02:51.274347", + "modified": "2020-06-04 15:15:09.865476", "modified_by": "Administrator", "module": "HR", "name": "HR Settings", diff --git a/erpnext/hr/doctype/hr_settings/hr_settings.py b/erpnext/hr/doctype/hr_settings/hr_settings.py index 5ed4c87c62..ced98fb9a5 100644 --- a/erpnext/hr/doctype/hr_settings/hr_settings.py +++ b/erpnext/hr/doctype/hr_settings/hr_settings.py @@ -5,34 +5,14 @@ from __future__ import unicode_literals import frappe -from frappe import _ from frappe.model.document import Document -from frappe.utils import cint -from frappe.custom.doctype.property_setter.property_setter import make_property_setter class HRSettings(Document): def validate(self): self.set_naming_series() - self.validate_password_policy() - - if not self.daily_wages_fraction_for_half_day: - self.daily_wages_fraction_for_half_day = 0.5 def set_naming_series(self): from erpnext.setup.doctype.naming_series.naming_series import set_by_naming_series set_by_naming_series("Employee", "employee_number", self.get("emp_created_by")=="Naming Series", hide_name_field=True) - def validate_password_policy(self): - if self.email_salary_slip_to_employee and self.encrypt_salary_slips_in_emails: - if not self.password_policy: - frappe.throw(_("Password policy for Salary Slips is not set")) - - def on_update(self): - self.toggle_rounded_total() - frappe.clear_cache() - - def toggle_rounded_total(self): - self.disable_rounded_total = cint(self.disable_rounded_total) - make_property_setter("Salary Slip", "rounded_total", "hidden", self.disable_rounded_total, "Check") - make_property_setter("Salary Slip", "rounded_total", "print_hide", self.disable_rounded_total, "Check") diff --git a/erpnext/hr/doctype/leave_encashment/leave_encashment.py b/erpnext/hr/doctype/leave_encashment/leave_encashment.py index 50a08b12bc..8913c648c5 100644 --- a/erpnext/hr/doctype/leave_encashment/leave_encashment.py +++ b/erpnext/hr/doctype/leave_encashment/leave_encashment.py @@ -8,7 +8,7 @@ from frappe import _ from frappe.model.document import Document from frappe.utils import getdate, nowdate, flt from erpnext.hr.utils import set_employee_name -from erpnext.hr.doctype.salary_structure_assignment.salary_structure_assignment import get_assigned_salary_structure +from erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment import get_assigned_salary_structure from erpnext.hr.doctype.leave_ledger_entry.leave_ledger_entry import create_leave_ledger_entry from erpnext.hr.doctype.leave_allocation.leave_allocation import get_unused_leaves diff --git a/erpnext/hr/doctype/leave_encashment/test_leave_encashment.py b/erpnext/hr/doctype/leave_encashment/test_leave_encashment.py index ac7755b23a..99f6463416 100644 --- a/erpnext/hr/doctype/leave_encashment/test_leave_encashment.py +++ b/erpnext/hr/doctype/leave_encashment/test_leave_encashment.py @@ -7,7 +7,7 @@ import frappe import unittest from frappe.utils import today, add_months from erpnext.hr.doctype.employee.test_employee import make_employee -from erpnext.hr.doctype.salary_structure.test_salary_structure import make_salary_structure +from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure from erpnext.hr.doctype.leave_period.test_leave_period import create_leave_period from erpnext.hr.doctype.leave_policy.test_leave_policy import create_leave_policy\ diff --git a/erpnext/hr/doctype/payroll_employee_detail/payroll_employee_detail.json b/erpnext/hr/doctype/payroll_employee_detail/payroll_employee_detail.json deleted file mode 100644 index 0dd3403d66..0000000000 --- a/erpnext/hr/doctype/payroll_employee_detail/payroll_employee_detail.json +++ /dev/null @@ -1,209 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2017-11-30 06:07:33.477781", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "employee", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Employee", - "length": 0, - "no_copy": 0, - "options": "Employee", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "employee.employee_name", - "fieldname": "employee_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Employee Name", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_3", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "employee.department", - "fieldname": "department", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Department", - "length": 0, - "no_copy": 0, - "options": "Department", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "employee.designation", - "fieldname": "designation", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Designation", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2019-01-30 11:28:16.544471", - "modified_by": "Administrator", - "module": "HR", - "name": "Payroll Employee Detail", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 1, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/hr/doctype/payroll_period_date/payroll_period_date.json b/erpnext/hr/doctype/payroll_period_date/payroll_period_date.json deleted file mode 100644 index 29bd2a3322..0000000000 --- a/erpnext/hr/doctype/payroll_period_date/payroll_period_date.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2018-04-13 15:17:30.513630", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "start_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Start Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "end_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "End Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-04-13 19:39:37.473294", - "modified_by": "Administrator", - "module": "HR", - "name": "Payroll Period Date", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/hr/doctype/salary_slip_timesheet/salary_slip_timesheet.json b/erpnext/hr/doctype/salary_slip_timesheet/salary_slip_timesheet.json deleted file mode 100644 index 797f8f7c02..0000000000 --- a/erpnext/hr/doctype/salary_slip_timesheet/salary_slip_timesheet.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2016-06-14 19:22:29.811658", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "time_sheet", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Time Sheet", - "length": 0, - "no_copy": 0, - "options": "Timesheet", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "working_hours", - "fieldtype": "Float", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Working Hours", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2019-02-19 08:33:41.762144", - "modified_by": "Administrator", - "module": "HR", - "name": "Salary Slip Timesheet", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/hr/doctype/taxable_salary_slab/taxable_salary_slab.json b/erpnext/hr/doctype/taxable_salary_slab/taxable_salary_slab.json deleted file mode 100644 index a094f8a197..0000000000 --- a/erpnext/hr/doctype/taxable_salary_slab/taxable_salary_slab.json +++ /dev/null @@ -1,232 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2018-04-13 17:42:13.516032", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "from_amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "From Amount", - "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": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "to_amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "To Amount", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "percent_deduction", - "fieldtype": "Percent", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Percent Deduction", - "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": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "condition", - "fieldtype": "Code", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Condition", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_5", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "html_6", - "fieldtype": "HTML", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "options": "

Condition Examples

\n
    \n
  1. Applying tax if employee born between 31-12-1937 and 01-01-1958 (Employees aged 60 to 80)
    \nCondition: date_of_birth>date(1937, 12, 31) and date_of_birth<date(1958, 01, 01)

  2. Applying tax by employee gender
    \nCondition: gender==\"Male\"

  3. \n
  4. Applying tax by Salary Component
    \nCondition: base > 10000
", - "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, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2018-06-19 10:10:23.732132", - "modified_by": "Administrator", - "module": "HR", - "name": "Taxable Salary Slab", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0 -} diff --git a/erpnext/hr/doctype/training_event/test_training_event.py b/erpnext/hr/doctype/training_event/test_training_event.py index 57123e304f..313f90eba8 100644 --- a/erpnext/hr/doctype/training_event/test_training_event.py +++ b/erpnext/hr/doctype/training_event/test_training_event.py @@ -6,7 +6,7 @@ from __future__ import unicode_literals import frappe import unittest from frappe.utils import today, add_days -from erpnext.hr.doctype.salary_structure.test_salary_structure import make_employee +from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_employee class TestTrainingEvent(unittest.TestCase): def setUp(self): diff --git a/erpnext/hr/report/salary_register/salary_register.json b/erpnext/hr/report/salary_register/salary_register.json deleted file mode 100644 index 89a7ba2910..0000000000 --- a/erpnext/hr/report/salary_register/salary_register.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "add_total_row": 1, - "apply_user_permissions": 1, - "creation": "2017-01-10 17:36:58.153863", - "disabled": 0, - "docstatus": 0, - "doctype": "Report", - "idx": 2, - "is_standard": "Yes", - "modified": "2017-02-24 19:58:33.143974", - "modified_by": "Administrator", - "module": "HR", - "name": "Salary Register", - "owner": "Administrator", - "ref_doctype": "Salary Slip", - "report_name": "Salary Register", - "report_type": "Script Report", - "roles": [ - { - "role": "HR User" - }, - { - "role": "HR Manager" - } - ] -} \ No newline at end of file diff --git a/erpnext/loan_management/doctype/loan/test_loan.py b/erpnext/loan_management/doctype/loan/test_loan.py index 364e2ffecf..3f37a26418 100644 --- a/erpnext/loan_management/doctype/loan/test_loan.py +++ b/erpnext/loan_management/doctype/loan/test_loan.py @@ -9,7 +9,7 @@ import unittest from frappe.utils import (nowdate, add_days, getdate, now_datetime, add_to_date, get_datetime, add_months, get_first_day, get_last_day, flt, date_diff) from erpnext.selling.doctype.customer.test_customer import get_customer_dict -from erpnext.hr.doctype.salary_structure.test_salary_structure import make_employee +from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_employee from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import (process_loan_interest_accrual_for_demand_loans, process_loan_interest_accrual_for_term_loans) from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import days_in_year diff --git a/erpnext/loan_management/doctype/loan_application/test_loan_application.py b/erpnext/loan_management/doctype/loan_application/test_loan_application.py index 99c807b2cd..687c58000e 100644 --- a/erpnext/loan_management/doctype/loan_application/test_loan_application.py +++ b/erpnext/loan_management/doctype/loan_application/test_loan_application.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals import frappe import unittest -from erpnext.hr.doctype.salary_structure.test_salary_structure import make_employee +from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_employee from erpnext.loan_management.doctype.loan.test_loan import create_loan_type, create_loan_accounts class TestLoanApplication(unittest.TestCase): diff --git a/erpnext/modules.txt b/erpnext/modules.txt index 3b347582c3..1e2aeea36a 100644 --- a/erpnext/modules.txt +++ b/erpnext/modules.txt @@ -24,4 +24,5 @@ Hotels Hub Node Quality Management Communication -Loan Management \ No newline at end of file +Loan Management +Payroll \ No newline at end of file diff --git a/erpnext/patches.txt b/erpnext/patches.txt index b3a38b6194..928c0ab9d8 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -333,7 +333,7 @@ erpnext.patches.v7_0.update_mode_of_payment_type execute:frappe.reload_doctype('Employee') #2016-10-18 execute:frappe.db.sql("update `tabEmployee` set prefered_contact_email = IFNULL(prefered_contact_email,'') ") -execute:frappe.reload_doctype("Salary Slip") +execute:frappe.reload_doc("Payroll", "doctype", "salary_slip") execute:frappe.db.sql("update `tabSalary Slip` set posting_date=creation") execute:frappe.reload_doc("stock", "doctype", "stock_settings") erpnext.patches.v8_0.create_domain_docs #16-05-2017 @@ -700,3 +700,8 @@ erpnext.patches.v12_0.set_italian_import_supplier_invoice_permissions erpnext.patches.v13_0.update_sla_enhancements erpnext.patches.v12_0.update_address_template_for_india erpnext.patches.v12_0.set_multi_uom_in_rfq +erpnext.patches.v13_0.delete_old_sales_reports +execute:frappe.delete_doc_if_exists("DocType", "Bank Reconciliation") +erpnext.patches.v13_0.move_doctype_reports_and_notification_from_hr_to_payroll #22-06-2020 +erpnext.patches.v13_0.move_payroll_setting_separately_from_hr_settings #22-06-2020 +erpnext.patches.v13_0.check_is_income_tax_component #22-06-2020 diff --git a/erpnext/patches/v11_0/create_department_records_for_each_company.py b/erpnext/patches/v11_0/create_department_records_for_each_company.py index f09c5b2c5d..e9b5950a13 100644 --- a/erpnext/patches/v11_0/create_department_records_for_each_company.py +++ b/erpnext/patches/v11_0/create_department_records_for_each_company.py @@ -6,8 +6,9 @@ from frappe.utils.nestedset import rebuild_tree def execute(): frappe.local.lang = frappe.db.get_default("lang") or 'en' - for doctype in ['department', 'leave_period', 'staffing_plan', 'job_opening', 'payroll_entry']: + for doctype in ['department', 'leave_period', 'staffing_plan', 'job_opening']: frappe.reload_doc("hr", "doctype", doctype) + frappe.reload_doc("Payroll", "doctype", 'payroll_entry') companies = frappe.db.get_all("Company", fields=["name", "abbr"]) departments = frappe.db.get_all("Department") diff --git a/erpnext/patches/v11_0/create_salary_structure_assignments.py b/erpnext/patches/v11_0/create_salary_structure_assignments.py index 610fa85172..c51c38182c 100644 --- a/erpnext/patches/v11_0/create_salary_structure_assignments.py +++ b/erpnext/patches/v11_0/create_salary_structure_assignments.py @@ -5,11 +5,11 @@ from __future__ import unicode_literals import frappe from datetime import datetime from frappe.utils import getdate -from erpnext.hr.doctype.salary_structure_assignment.salary_structure_assignment import DuplicateAssignment +from erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment import DuplicateAssignment def execute(): - frappe.reload_doc('hr', 'doctype', 'salary_structure') - frappe.reload_doc("hr", "doctype", "salary_structure_assignment") + frappe.reload_doc('Payroll', 'doctype', 'salary_structure') + frappe.reload_doc("Payroll", "doctype", "salary_structure_assignment") frappe.db.sql(""" delete from `tabSalary Structure Assignment` where salary_structure in (select name from `tabSalary Structure` where is_active='No' or docstatus!=1) diff --git a/erpnext/patches/v11_0/inter_state_field_for_gst.py b/erpnext/patches/v11_0/inter_state_field_for_gst.py index 48249c9bbf..730eebc01c 100644 --- a/erpnext/patches/v11_0/inter_state_field_for_gst.py +++ b/erpnext/patches/v11_0/inter_state_field_for_gst.py @@ -6,8 +6,8 @@ def execute(): company = frappe.get_all('Company', filters = {'country': 'India'}) if not company: return - frappe.reload_doc("hr", "doctype", "Employee Tax Exemption Declaration") - frappe.reload_doc("hr", "doctype", "Employee Tax Exemption Proof Submission") + frappe.reload_doc("Payroll", "doctype", "Employee Tax Exemption Declaration") + frappe.reload_doc("Payroll", "doctype", "Employee Tax Exemption Proof Submission") frappe.reload_doc("hr", "doctype", "Employee Grade") frappe.reload_doc("hr", "doctype", "Leave Policy") diff --git a/erpnext/patches/v11_0/set_salary_component_properties.py b/erpnext/patches/v11_0/set_salary_component_properties.py index 83fb53d2a7..2498888273 100644 --- a/erpnext/patches/v11_0/set_salary_component_properties.py +++ b/erpnext/patches/v11_0/set_salary_component_properties.py @@ -2,8 +2,8 @@ from __future__ import unicode_literals import frappe def execute(): - frappe.reload_doc('hr', 'doctype', 'salary_detail') - frappe.reload_doc('hr', 'doctype', 'salary_component') + frappe.reload_doc('Payroll', 'doctype', 'salary_detail') + frappe.reload_doc('Payroll', 'doctype', 'salary_component') frappe.db.sql("update `tabSalary Component` set is_tax_applicable=1 where type='Earning'") diff --git a/erpnext/patches/v11_1/rename_depends_on_lwp.py b/erpnext/patches/v11_1/rename_depends_on_lwp.py index 20d8867e1d..a0f2536f7d 100644 --- a/erpnext/patches/v11_1/rename_depends_on_lwp.py +++ b/erpnext/patches/v11_1/rename_depends_on_lwp.py @@ -9,5 +9,5 @@ from frappe.model.utils.rename_field import rename_field def execute(): for doctype in ("Salary Component", "Salary Detail"): if "depends_on_lwp" in frappe.db.get_table_columns(doctype): - frappe.reload_doc("hr", "doctype", scrub(doctype)) + frappe.reload_doc("Payroll", "doctype", scrub(doctype)) rename_field(doctype, "depends_on_lwp", "depends_on_payment_days") \ No newline at end of file diff --git a/erpnext/patches/v13_0/check_is_income_tax_component.py b/erpnext/patches/v13_0/check_is_income_tax_component.py new file mode 100644 index 0000000000..9ad48e23b7 --- /dev/null +++ b/erpnext/patches/v13_0/check_is_income_tax_component.py @@ -0,0 +1,43 @@ +# Copyright (c) 2019, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals + +import frappe, erpnext +from erpnext.regional.india.setup import setup + +def execute(): + + doctypes = ['salary_component', + 'Employee Tax Exemption Declaration', + 'Employee Tax Exemption Proof Submission', + 'Employee Tax Exemption Declaration Category', + 'Employee Tax Exemption Proof Submission Detail' + ] + + for doctype in doctypes: + frappe.reload_doc('Payroll', 'doctype', doctype) + + + reports = ['Professional Tax Deductions', 'Provident Fund Deductions'] + for report in reports: + frappe.reload_doc('Regional', 'Report', report) + frappe.reload_doc('Regional', 'Report', report) + + if erpnext.get_region() == "India": + setup(patch=True) + + if frappe.db.exists("Salary Component", "Income Tax"): + frappe.db.set_value("Salary Component", "Income Tax", "is_income_tax_component", 1) + if frappe.db.exists("Salary Component", "TDS"): + frappe.db.set_value("Salary Component", "TDS", "is_income_tax_component", 1) + + components = frappe.db.sql("select name from `tabSalary Component` where variable_based_on_taxable_salary = 1", as_dict=1) + for component in components: + frappe.db.set_value("Salary Component", component.name, "is_income_tax_component", 1) + + if erpnext.get_region() == "India": + if frappe.db.exists("Salary Component", "Provident Fund"): + frappe.db.set_value("Salary Component", "Provident Fund", "component_type", "Provident Fund") + if frappe.db.exists("Salary Component", "Professional Tax"): + frappe.db.set_value("Salary Component", "Professional Tax", "component_type", "Professional Tax") \ No newline at end of file diff --git a/erpnext/patches/v13_0/delete_old_sales_reports.py b/erpnext/patches/v13_0/delete_old_sales_reports.py new file mode 100644 index 0000000000..0f44865808 --- /dev/null +++ b/erpnext/patches/v13_0/delete_old_sales_reports.py @@ -0,0 +1,21 @@ +# Copyright (c) 2019, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals + +import frappe + +def execute(): + reports_to_delete = ["Ordered Items To Be Delivered", "Ordered Items To Be Billed"] + + for report in reports_to_delete: + if frappe.db.exists("Report", report): + delete_auto_email_reports(report) + + frappe.delete_doc("Report", report) + +def delete_auto_email_reports(report): + """ Check for one or multiple Auto Email Reports and delete """ + auto_email_reports = frappe.db.get_values("Auto Email Report", {"report": report}, ["name"]) + for auto_email_report in auto_email_reports: + frappe.delete_doc("Auto Email Report", auto_email_report[0]) \ No newline at end of file diff --git a/erpnext/patches/v13_0/move_doctype_reports_and_notification_from_hr_to_payroll.py b/erpnext/patches/v13_0/move_doctype_reports_and_notification_from_hr_to_payroll.py new file mode 100644 index 0000000000..4d7c85ce2d --- /dev/null +++ b/erpnext/patches/v13_0/move_doctype_reports_and_notification_from_hr_to_payroll.py @@ -0,0 +1,52 @@ +# Copyright (c) 2019, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals + +import frappe + +def execute(): + frappe.db.sql("""UPDATE `tabPrint Format` + SET module = 'Payroll' + WHERE name IN ('Salary Slip Based On Timesheet', 'Salary Slip Standard')""" + ) + + frappe.db.sql("""UPDATE `tabNotification` SET module='Payroll' WHERE name='Retention Bonus';""" + ) + + doctypes_moved = [ + 'Employee Benefit Application Detail', + 'Employee Tax Exemption Declaration Category', + 'Salary Component', + 'Employee Tax Exemption Proof Submission Detail', + 'Income Tax Slab Other Charges', + 'Taxable Salary Slab', + 'Payroll Period Date', + 'Salary Slip Timesheet', + 'Payroll Employee Detail', + 'Salary Detail', + 'Employee Tax Exemption Sub Category', + 'Employee Tax Exemption Category', + 'Employee Benefit Claim', + 'Employee Benefit Application', + 'Employee Other Income', + 'Employee Tax Exemption Proof Submission', + 'Employee Tax Exemption Declaration', + 'Employee Incentive', + 'Retention Bonus', + 'Additional Salary', + 'Income Tax Slab', + 'Payroll Period', + 'Salary Slip', + 'Payroll Entry', + 'Salary Structure Assignment', + 'Salary Structure' + ] + + for doctype in doctypes_moved: + frappe.delete_doc_if_exists("DocType", doctype) + + reports = ["Salary Register", "Bank Remittance"] + + for report in reports: + frappe.delete_doc_if_exists("Report", report) diff --git a/erpnext/patches/v13_0/move_payroll_setting_separately_from_hr_settings.py b/erpnext/patches/v13_0/move_payroll_setting_separately_from_hr_settings.py new file mode 100644 index 0000000000..a901064b88 --- /dev/null +++ b/erpnext/patches/v13_0/move_payroll_setting_separately_from_hr_settings.py @@ -0,0 +1,27 @@ +# Copyright (c) 2019, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals + +import frappe + +def execute(): + data = frappe.db.sql('''SELECT * + FROM `tabSingles` + WHERE + doctype = "HR Settings" + AND + field in ( + "encrypt_salary_slips_in_emails", + "email_salary_slip_to_employee", + "daily_wages_fraction_for_half_day", + "disable_rounded_total", + "include_holidays_in_total_working_days", + "max_working_hours_against_timesheet", + "payroll_based_on", + "password_policy" + ) + ''', as_dict=1) + + for d in data: + frappe.db.set_value("Payroll Settings", None, d.field, d.value) diff --git a/erpnext/patches/v13_0/move_tax_slabs_from_payroll_period_to_income_tax_slab.py b/erpnext/patches/v13_0/move_tax_slabs_from_payroll_period_to_income_tax_slab.py index 5ade8ca0f4..1a91d218ba 100644 --- a/erpnext/patches/v13_0/move_tax_slabs_from_payroll_period_to_income_tax_slab.py +++ b/erpnext/patches/v13_0/move_tax_slabs_from_payroll_period_to_income_tax_slab.py @@ -11,7 +11,7 @@ def execute(): return for doctype in ("income_tax_slab", "salary_structure_assignment", "employee_other_income", "income_tax_slab_other_charges"): - frappe.reload_doc("hr", "doctype", doctype) + frappe.reload_doc("Payroll", "doctype", doctype) standard_tax_exemption_amount_exists = frappe.db.has_column("Payroll Period", "standard_tax_exemption_amount") @@ -29,7 +29,7 @@ def execute(): WHERE company=%s ORDER BY start_date DESC """.format(select_fields), company.name, as_dict = 1) - + for i, period in enumerate(payroll_periods): income_tax_slab = frappe.new_doc("Income Tax Slab") income_tax_slab.name = "Tax Slab:" + period.name diff --git a/erpnext/patches/v13_0/patch_to_fix_reverse_linking_in_additional_salary_encashment_and_incentive.py b/erpnext/patches/v13_0/patch_to_fix_reverse_linking_in_additional_salary_encashment_and_incentive.py index ddcadcb4de..fde8f86470 100644 --- a/erpnext/patches/v13_0/patch_to_fix_reverse_linking_in_additional_salary_encashment_and_incentive.py +++ b/erpnext/patches/v13_0/patch_to_fix_reverse_linking_in_additional_salary_encashment_and_incentive.py @@ -6,8 +6,10 @@ def execute(): if not frappe.db.table_exists("Additional Salary"): return - for doctype in ("Additional Salary", "Leave Encashment", "Employee Incentive", "Salary Detail"): - frappe.reload_doc("hr", "doctype", doctype) + for doctype in ("Additional Salary", "Employee Incentive", "Salary Detail"): + frappe.reload_doc("Payroll", "doctype", doctype) + + frappe.reload_doc("hr", "doctype", "Leave Encashment") additional_salaries = frappe.get_all("Additional Salary", fields = ['name', "salary_slip", "type", "salary_component"], diff --git a/erpnext/patches/v4_0/create_custom_fields_for_india_specific_fields.py b/erpnext/patches/v4_0/create_custom_fields_for_india_specific_fields.py index 9c602a3f78..fe50e444b5 100644 --- a/erpnext/patches/v4_0/create_custom_fields_for_india_specific_fields.py +++ b/erpnext/patches/v4_0/create_custom_fields_for_india_specific_fields.py @@ -8,7 +8,7 @@ from frappe.custom.doctype.custom_field.custom_field import create_custom_field_ def execute(): frappe.reload_doc("stock", "doctype", "purchase_receipt") frappe.reload_doc("hr", "doctype", "employee") - frappe.reload_doc("hr", "doctype", "salary_slip") + frappe.reload_doc("Payroll", "doctype", "salary_slip") india_specific_fields = { "Purchase Receipt": [{ diff --git a/erpnext/patches/v5_0/rename_table_fieldnames.py b/erpnext/patches/v5_0/rename_table_fieldnames.py index 59f534303f..aefb0a2037 100644 --- a/erpnext/patches/v5_0/rename_table_fieldnames.py +++ b/erpnext/patches/v5_0/rename_table_fieldnames.py @@ -220,7 +220,7 @@ def execute(): frappe.reload_doc("manufacturing", "doctype", "work_order_operation") frappe.reload_doc("manufacturing", "doctype", "workstation_working_hour") frappe.reload_doc("stock", "doctype", "item_variant") - frappe.reload_doc("hr", "doctype", "salary_detail") + frappe.reload_doc("Payroll", "doctype", "salary_detail") frappe.reload_doc("accounts", "doctype", "party_account") frappe.reload_doc("accounts", "doctype", "fiscal_year_company") diff --git a/erpnext/patches/v7_0/rename_salary_components.py b/erpnext/patches/v7_0/rename_salary_components.py index bc48e34317..1693f3bdf1 100644 --- a/erpnext/patches/v7_0/rename_salary_components.py +++ b/erpnext/patches/v7_0/rename_salary_components.py @@ -6,8 +6,8 @@ def execute(): if not frappe.db.exists("DocType", "Salary Structure Earning"): return - frappe.reload_doc("hr", "doctype", "salary_detail") - frappe.reload_doc("hr", "doctype", "salary_component") + frappe.reload_doc("Payroll", "doctype", "salary_detail") + frappe.reload_doc("Payroll", "doctype", "salary_component") standard_cols = ["name", "creation", "modified", "owner", "modified_by", "parent", "parenttype", "parentfield", "idx"] diff --git a/erpnext/patches/v7_1/update_component_type.py b/erpnext/patches/v7_1/update_component_type.py index 552fc89467..24ca0570e0 100644 --- a/erpnext/patches/v7_1/update_component_type.py +++ b/erpnext/patches/v7_1/update_component_type.py @@ -3,7 +3,7 @@ import frappe from frappe.utils import flt def execute(): - frappe.reload_doc('hr', 'doctype', 'salary_component') + frappe.reload_doc('Payroll', 'doctype', 'salary_component') sal_components = frappe.db.sql(""" select DISTINCT salary_component, parentfield from `tabSalary Detail`""", as_dict=True) diff --git a/erpnext/patches/v7_1/update_missing_salary_component_type.py b/erpnext/patches/v7_1/update_missing_salary_component_type.py index 7d50ee4dff..824f2b881f 100644 --- a/erpnext/patches/v7_1/update_missing_salary_component_type.py +++ b/erpnext/patches/v7_1/update_missing_salary_component_type.py @@ -10,12 +10,12 @@ earnings or deductions in existing salary slips def execute(): frappe.reload_doc("accounts", "doctype", "salary_component_account") - frappe.reload_doc("hr", "doctype", "salary_component") - frappe.reload_doc("hr", "doctype", "taxable_salary_slab") - - for s in frappe.db.sql('''select name, type, salary_component_abbr from `tabSalary Component` + frappe.reload_doc("Payroll", "doctype", "salary_component") + frappe.reload_doc("Payroll", "doctype", "taxable_salary_slab") + + for s in frappe.db.sql('''select name, type, salary_component_abbr from `tabSalary Component` where ifnull(type, "")="" or ifnull(salary_component_abbr, "") = ""''', as_dict=1): - + component = frappe.get_doc('Salary Component', s.name) # guess @@ -29,22 +29,22 @@ def execute(): else: component.type = 'Deduction' - + if not s.salary_component_abbr: abbr = ''.join([c[0] for c in component.salary_component.split()]).upper() - + abbr_count = frappe.db.sql(""" - select - count(name) - from - `tabSalary Component` - where + select + count(name) + from + `tabSalary Component` + where salary_component_abbr = %s or salary_component_abbr like %s """, (abbr, abbr + "-%%")) - + if abbr_count and abbr_count[0][0] > 0: abbr = abbr + "-" + cstr(abbr_count[0][0]) - + component.salary_component_abbr = abbr - + component.save() diff --git a/erpnext/patches/v7_2/arrear_leave_encashment_as_salary_component.py b/erpnext/patches/v7_2/arrear_leave_encashment_as_salary_component.py index 3b9642dd3b..d2583b9422 100644 --- a/erpnext/patches/v7_2/arrear_leave_encashment_as_salary_component.py +++ b/erpnext/patches/v7_2/arrear_leave_encashment_as_salary_component.py @@ -2,7 +2,9 @@ from __future__ import unicode_literals import frappe def execute(): - frappe.reload_doctype('Salary Slip', 'Salary Component') + # frappe.reload_doctype('Salary Slip', 'Salary Component') + frappe.reload_doc("Payroll", "doctype", "Salary Slip") + frappe.reload_doc("Payroll", "doctype", "Salary Component") salary_components = [['Arrear', "ARR"], ['Leave Encashment', 'LENC']] for salary_component, salary_abbr in salary_components: if not frappe.db.exists('Salary Component', salary_component): diff --git a/erpnext/patches/v7_2/update_abbr_in_salary_slips.py b/erpnext/patches/v7_2/update_abbr_in_salary_slips.py index 19dcb5e3b2..57432fe986 100644 --- a/erpnext/patches/v7_2/update_abbr_in_salary_slips.py +++ b/erpnext/patches/v7_2/update_abbr_in_salary_slips.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals import frappe def execute(): - frappe.reload_doctype('Salary Slip') + frappe.reload_doc('Payroll', 'doctype', 'Salary Slip') if not frappe.db.has_column('Salary Detail', 'abbr'): return diff --git a/erpnext/patches/v7_2/update_salary_slips.py b/erpnext/patches/v7_2/update_salary_slips.py index 11a52f9587..9fcce62d8f 100644 --- a/erpnext/patches/v7_2/update_salary_slips.py +++ b/erpnext/patches/v7_2/update_salary_slips.py @@ -1,10 +1,10 @@ from __future__ import unicode_literals import frappe -from erpnext.hr.doctype.payroll_entry.payroll_entry import get_month_details +from erpnext.payroll.doctype.payroll_entry.payroll_entry import get_month_details from frappe.utils import cint def execute(): - frappe.reload_doctype('Salary Slip') + frappe.reload_doc("Payroll", "doctype", "Salary Slip") if not frappe.db.has_column('Salary Slip', 'fiscal_year'): return diff --git a/erpnext/patches/v8_7/sync_india_custom_fields.py b/erpnext/patches/v8_7/sync_india_custom_fields.py index 73e1b182e8..eb24a90f01 100644 --- a/erpnext/patches/v8_7/sync_india_custom_fields.py +++ b/erpnext/patches/v8_7/sync_india_custom_fields.py @@ -7,11 +7,11 @@ def execute(): if not company: return - frappe.reload_doc('hr', 'doctype', 'payroll_period') - frappe.reload_doc('hr', 'doctype', 'employee_tax_exemption_declaration') - frappe.reload_doc('hr', 'doctype', 'employee_tax_exemption_proof_submission') - frappe.reload_doc('hr', 'doctype', 'employee_tax_exemption_declaration_category') - frappe.reload_doc('hr', 'doctype', 'employee_tax_exemption_proof_submission_detail') + frappe.reload_doc('Payroll', 'doctype', 'payroll_period') + frappe.reload_doc('Payroll', 'doctype', 'employee_tax_exemption_declaration') + frappe.reload_doc('Payroll', 'doctype', 'employee_tax_exemption_proof_submission') + frappe.reload_doc('Payroll', 'doctype', 'employee_tax_exemption_declaration_category') + frappe.reload_doc('Payroll', 'doctype', 'employee_tax_exemption_proof_submission_detail') frappe.reload_doc('accounts', 'doctype', 'tax_category') diff --git a/erpnext/patches/v9_0/update_employee_loan_details.py b/erpnext/patches/v9_0/update_employee_loan_details.py index 86690fc1f8..ef8d32855f 100644 --- a/erpnext/patches/v9_0/update_employee_loan_details.py +++ b/erpnext/patches/v9_0/update_employee_loan_details.py @@ -5,8 +5,8 @@ from __future__ import unicode_literals import frappe def execute(): - frappe.reload_doc('hr', 'doctype', 'salary_slip_loan') - frappe.reload_doc('hr', 'doctype', 'salary_slip') + frappe.reload_doc('Payroll', 'doctype', 'salary_slip_loan') + frappe.reload_doc('Payroll', 'doctype', 'salary_slip') for data in frappe.db.sql(""" select name, start_date, end_date, total_loan_repayment diff --git a/erpnext/accounts/report/ordered_items_to_be_billed/__init__.py b/erpnext/payroll/__init__.py similarity index 100% rename from erpnext/accounts/report/ordered_items_to_be_billed/__init__.py rename to erpnext/payroll/__init__.py diff --git a/erpnext/payroll/dashboard_fixtures.py b/erpnext/payroll/dashboard_fixtures.py new file mode 100644 index 0000000000..ae7a9ff51a --- /dev/null +++ b/erpnext/payroll/dashboard_fixtures.py @@ -0,0 +1,100 @@ +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +import frappe +import erpnext +from erpnext.hr.dashboard_fixtures import get_dashboards_chart_doc, get_number_cards_doc +import json +from frappe import _ + +def get_data(): + return frappe._dict({ + "dashboards": get_dashboards(), + "charts": get_charts(), + "number_cards": get_number_cards(), + }) + +def get_dashboards(): + dashboards = [] + dashboards.append(get_payroll_dashboard()) + return dashboards + +def get_payroll_dashboard(): + return { + "name": "Payroll", + "dashboard_name": "Payroll", + "is_default": 1, + "charts": [ + { "chart": "Outgoing Salary", "width": "Full"}, + { "chart": "Designation Wise Salary(Last Month)", "width": "Half"}, + { "chart": "Department Wise Salary(Last Month)", "width": "Half"}, + ], + "cards": [ + {"card": "Total Declaration Submitted"}, + {"card": "Total Salary Structure"}, + {"card": "Total Incentive Given(Last month)"}, + {"card": "Total Outgoing Salary(Last month)"}, + ] + } + +def get_charts(): + dashboard_charts= [ + get_dashboards_chart_doc('Outgoing Salary', "Sum", "Line", + document_type = "Salary Slip", based_on="end_date", + value_based_on = "rounded_total", time_interval = "Monthly", timeseries = 1, + filters_json = json.dumps([["Salary Slip", "docstatus", "=", 1]])) + ] + + dashboard_charts.append( + get_dashboards_chart_doc('Department Wise Salary(Last Month)', "Group By", "Bar", + document_type = "Salary Slip", group_by_type="Sum", group_by_based_on="department", + time_interval = "Monthly", aggregate_function_based_on = "rounded_total", + filters_json = json.dumps([ + ["Salary Slip", "docstatus", "=", 1], + ["Salary Slip", "start_date", "Previous","1 month"] + ]) + ) + ) + + dashboard_charts.append( + get_dashboards_chart_doc('Designation Wise Salary(Last Month)', "Group By", "Bar", + document_type = "Salary Slip", group_by_type="Sum", group_by_based_on="designation", + time_interval = "Monthly", aggregate_function_based_on = "rounded_total", + filters_json = json.dumps([ + ["Salary Slip", "docstatus", "=", 1], + ["Salary Slip", "start_date", "Previous","1 month"] + ]) + ) + ) + + return dashboard_charts + +def get_number_cards(): + number_cards = [get_number_cards_doc("Employee Tax Exemption Declaration", "Total Declaration Submitted", filters_json = json.dumps([ + ["Employee Tax Exemption Declaration", "docstatus", "=","1"], + ["Employee Tax Exemption Declaration","creation","Previous","1 year"] + ]) + )] + + number_cards.append(get_number_cards_doc("Employee Incentive", "Total Incentive Given(Last month)", + time_interval = "Monthly", func = "Sum", aggregate_function_based_on = "incentive_amount", + filters_json = json.dumps([ + ["Employee Incentive", "docstatus", "=", 1], + ["Employee Incentive","payroll_date","Previous","1 year"] + ])) + ) + + number_cards.append(get_number_cards_doc("Salary Slip", "Total Outgoing Salary(Last month)", + time_interval = "Monthly", time_span= "Monthly", func = "Sum", aggregate_function_based_on = "rounded_total", + filters_json = json.dumps([ + ["Salary Slip", "docstatus", "=", 1], + ["Salary Slip", "start_date","Previous","1 month"] + ])) + ) + number_cards.append(get_number_cards_doc("Salary Structure", "Total Salary Structure", + filters_json = json.dumps([ + ["Salary Structure", "docstatus", "=", 1] + ])) + ) + + return number_cards \ No newline at end of file diff --git a/erpnext/payroll/desk_page/payroll/payroll.json b/erpnext/payroll/desk_page/payroll/payroll.json new file mode 100644 index 0000000000..b5eac465c8 --- /dev/null +++ b/erpnext/payroll/desk_page/payroll/payroll.json @@ -0,0 +1,84 @@ +{ + "cards": [ + { + "hidden": 0, + "label": "Payroll", + "links": "[\n {\n \"label\": \"Salary Component\",\n \"name\": \"Salary Component\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Salary Structure\",\n \"name\": \"Salary Structure\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Structure Assignment\",\n \"name\": \"Salary Structure Assignment\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Payroll Entry\",\n \"name\": \"Payroll Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Slip\",\n \"name\": \"Salary Slip\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]" + }, + { + "hidden": 0, + "label": "Taxation", + "links": "[\n {\n \"label\": \"Payroll Period\",\n \"name\": \"Payroll Period\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Income Tax Slab\",\n \"name\": \"Income Tax Slab\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Employee Tax Exemption Declaration\",\n \"name\": \"Employee Tax Exemption Declaration\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Employee Tax Exemption Proof Submission\",\n \"name\": \"Employee Tax Exemption Proof Submission\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Employee Tax Exemption Category\",\n \"name\": \"Employee Tax Exemption Category\",\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Employee Tax Exemption Sub Category\",\n \"name\": \"Employee Tax Exemption Sub Category\",\n \"type\": \"doctype\"\n \n }\n]" + }, + { + "hidden": 0, + "label": "Compensations", + "links": "[\n {\n \"label\": \"Additional Salary\",\n \"name\": \"Additional Salary\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Retention Bonus\",\n \"name\": \"Retention Bonus\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Employee Incentive\",\n \"name\": \"Employee Incentive\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Employee Benefit Application\",\n \"name\": \"Employee Benefit Application\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Employee Benefit Claim\",\n \"name\": \"Employee Benefit Claim\",\n \"type\": \"doctype\"\n }\n]" + }, + { + "hidden": 0, + "label": "Reports", + "links": "[\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"is_query_report\": true,\n \"label\": \"Salary Register\",\n \"name\": \"Salary Register\",\n \"type\": \"report\"\n \n },\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"label\": \"Salary Payments Based On Payment Mode\",\n \"is_query_report\": true,\n \"name\": \"Salary Payments Based On Payment Mode\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"label\": \"Salary Payments via ECS\",\n \"is_query_report\": true,\n \"name\": \"Salary Payments via ECS\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"label\": \"Income Tax Deductions\",\n \"is_query_report\": true,\n \"name\": \"Income Tax Deductions\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"label\": \"Professional Tax Deductions\",\n \"is_query_report\": true,\n \"name\": \"Professional Tax Deductions\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"label\": \"Provident Fund Deductions\",\n \"is_query_report\": true,\n \"name\": \"Provident Fund Deductions\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Payroll Entry\"\n ],\n \"doctype\": \"Payroll Entry\",\n \"is_query_report\": true,\n \"label\": \"Bank Remittance\",\n \"name\": \"Bank Remittance\",\n \"type\": \"report\"\n \n }\n]" + } + ], + "category": "Modules", + "charts": [ + { + "chart_name": "Outgoing Salary", + "label": "Outgoing Salary" + } + ], + "creation": "2020-05-27 19:54:23.405607", + "developer_mode_only": 0, + "disable_user_customization": 0, + "docstatus": 0, + "doctype": "Desk Page", + "extends_another_page": 0, + "hide_custom": 0, + "idx": 0, + "is_standard": 1, + "label": "Payroll", + "modified": "2020-06-19 12:23:06.034046", + "modified_by": "Administrator", + "module": "Payroll", + "name": "Payroll", + "onboarding": "Payroll", + "owner": "Administrator", + "pin_to_bottom": 0, + "pin_to_top": 0, + "shortcuts": [ + { + "label": "Salary Structure", + "link_to": "Salary Structure", + "type": "DocType" + }, + { + "label": "Payroll Entry", + "link_to": "Payroll Entry", + "type": "DocType" + }, + { + "color": "", + "format": "{} Pending", + "label": "Salary Slip", + "link_to": "Salary Slip", + "stats_filter": "{\"status\": \"Draft\"}", + "type": "DocType" + }, + { + "label": "Income Tax Slab", + "link_to": "Income Tax Slab", + "type": "DocType" + }, + { + "label": "Salary Register", + "link_to": "Salary Register", + "type": "Report" + }, + { + "label": "Dashboard", + "link_to": "Payroll", + "type": "Dashboard" + } + ] +} \ No newline at end of file diff --git a/erpnext/hr/doctype/additional_salary/__init__.py b/erpnext/payroll/doctype/__init__.py similarity index 100% rename from erpnext/hr/doctype/additional_salary/__init__.py rename to erpnext/payroll/doctype/__init__.py diff --git a/erpnext/hr/doctype/employee_benefit_application/__init__.py b/erpnext/payroll/doctype/additional_salary/__init__.py similarity index 100% rename from erpnext/hr/doctype/employee_benefit_application/__init__.py rename to erpnext/payroll/doctype/additional_salary/__init__.py diff --git a/erpnext/hr/doctype/additional_salary/additional_salary.js b/erpnext/payroll/doctype/additional_salary/additional_salary.js similarity index 100% rename from erpnext/hr/doctype/additional_salary/additional_salary.js rename to erpnext/payroll/doctype/additional_salary/additional_salary.js diff --git a/erpnext/hr/doctype/additional_salary/additional_salary.json b/erpnext/payroll/doctype/additional_salary/additional_salary.json similarity index 98% rename from erpnext/hr/doctype/additional_salary/additional_salary.json rename to erpnext/payroll/doctype/additional_salary/additional_salary.json index bfb543f49a..69cb5da893 100644 --- a/erpnext/hr/doctype/additional_salary/additional_salary.json +++ b/erpnext/payroll/doctype/additional_salary/additional_salary.json @@ -146,7 +146,7 @@ "label": "To Date", "mandatory_depends_on": "eval:(doc.is_recurring==1)" }, - { + { "fieldname": "ref_doctype", "fieldtype": "Link", "label": "Reference Document Type", @@ -163,9 +163,9 @@ ], "is_submittable": 1, "links": [], - "modified": "2020-04-04 18:06:29.170878", + "modified": "2020-06-22 21:10:50.374063", "modified_by": "Administrator", - "module": "HR", + "module": "Payroll", "name": "Additional Salary", "owner": "Administrator", "permissions": [ diff --git a/erpnext/hr/doctype/additional_salary/additional_salary.py b/erpnext/payroll/doctype/additional_salary/additional_salary.py similarity index 100% rename from erpnext/hr/doctype/additional_salary/additional_salary.py rename to erpnext/payroll/doctype/additional_salary/additional_salary.py diff --git a/erpnext/hr/doctype/additional_salary/test_additional_salary.js b/erpnext/payroll/doctype/additional_salary/test_additional_salary.js similarity index 100% rename from erpnext/hr/doctype/additional_salary/test_additional_salary.js rename to erpnext/payroll/doctype/additional_salary/test_additional_salary.js diff --git a/erpnext/hr/doctype/additional_salary/test_additional_salary.py b/erpnext/payroll/doctype/additional_salary/test_additional_salary.py similarity index 87% rename from erpnext/hr/doctype/additional_salary/test_additional_salary.py rename to erpnext/payroll/doctype/additional_salary/test_additional_salary.py index 6f93fb5df8..de26543b57 100644 --- a/erpnext/hr/doctype/additional_salary/test_additional_salary.py +++ b/erpnext/payroll/doctype/additional_salary/test_additional_salary.py @@ -6,8 +6,8 @@ import unittest import frappe, erpnext from frappe.utils import nowdate, add_days from erpnext.hr.doctype.employee.test_employee import make_employee -from erpnext.hr.doctype.salary_component.test_salary_component import create_salary_component -from erpnext.hr.doctype.salary_slip.test_salary_slip import make_employee_salary_slip, setup_test +from erpnext.payroll.doctype.salary_component.test_salary_component import create_salary_component +from erpnext.payroll.doctype.salary_slip.test_salary_slip import make_employee_salary_slip, setup_test class TestAdditionalSalary(unittest.TestCase): diff --git a/erpnext/hr/doctype/employee_benefit_application_detail/__init__.py b/erpnext/payroll/doctype/employee_benefit_application/__init__.py similarity index 100% rename from erpnext/hr/doctype/employee_benefit_application_detail/__init__.py rename to erpnext/payroll/doctype/employee_benefit_application/__init__.py diff --git a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js b/erpnext/payroll/doctype/employee_benefit_application/employee_benefit_application.js similarity index 83% rename from erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js rename to erpnext/payroll/doctype/employee_benefit_application/employee_benefit_application.js index b73dcf8ac3..f509df31e8 100644 --- a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js +++ b/erpnext/payroll/doctype/employee_benefit_application/employee_benefit_application.js @@ -6,7 +6,7 @@ frappe.ui.form.on('Employee Benefit Application', { frm.trigger('set_earning_component'); var method, args; if(frm.doc.employee && frm.doc.date && frm.doc.payroll_period){ - method = "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_max_benefits_remaining"; + method = "erpnext.payroll.doctype.employee_benefit_application.employee_benefit_application.get_max_benefits_remaining"; args = { employee: frm.doc.employee, on_date: frm.doc.date, @@ -15,7 +15,7 @@ frappe.ui.form.on('Employee Benefit Application', { get_max_benefits(frm, method, args); } else if(frm.doc.employee && frm.doc.date){ - method = "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_max_benefits"; + method = "erpnext.payroll.doctype.employee_benefit_application.employee_benefit_application.get_max_benefits"; args = { employee: frm.doc.employee, on_date: frm.doc.date @@ -32,7 +32,7 @@ frappe.ui.form.on('Employee Benefit Application', { if(!frm.doc.employee && !frm.doc.date) return; frm.set_query("earning_component", "employee_benefits", function() { return { - query : "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_earning_components", + query : "erpnext.payroll.doctype.employee_benefit_application.employee_benefit_application.get_earning_components", filters: {date: frm.doc.date, employee: frm.doc.employee} }; }); @@ -41,7 +41,7 @@ frappe.ui.form.on('Employee Benefit Application', { payroll_period: function(frm) { var method, args; if(frm.doc.employee && frm.doc.date && frm.doc.payroll_period){ - method = "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_max_benefits_remaining"; + method = "erpnext.payroll.doctype.employee_benefit_application.employee_benefit_application.get_max_benefits_remaining"; args = { employee: frm.doc.employee, on_date: frm.doc.date, diff --git a/erpnext/payroll/doctype/employee_benefit_application/employee_benefit_application.json b/erpnext/payroll/doctype/employee_benefit_application/employee_benefit_application.json new file mode 100644 index 0000000000..b0c1bd6c3e --- /dev/null +++ b/erpnext/payroll/doctype/employee_benefit_application/employee_benefit_application.json @@ -0,0 +1,191 @@ +{ + "actions": [], + "allow_import": 1, + "allow_rename": 1, + "autoname": "HR-BEN-APP-.YY.-.MM.-.#####", + "creation": "2018-04-13 16:31:39.190787", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "employee", + "employee_name", + "max_benefits", + "remaining_benefit", + "column_break_2", + "date", + "payroll_period", + "department", + "amended_from", + "section_break_4", + "employee_benefits", + "totals", + "total_amount", + "pro_rata_dispensed_amount" + ], + "fields": [ + { + "fieldname": "employee", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Employee", + "options": "Employee", + "reqd": 1 + }, + { + "fetch_from": "employee.employee_name", + "fieldname": "employee_name", + "fieldtype": "Data", + "label": "Employee Name", + "read_only": 1 + }, + { + "fieldname": "max_benefits", + "fieldtype": "Currency", + "label": "Max Benefits (Yearly)", + "read_only": 1 + }, + { + "fieldname": "remaining_benefit", + "fieldtype": "Currency", + "label": "Remaining Benefits (Yearly)", + "read_only": 1 + }, + { + "fieldname": "column_break_2", + "fieldtype": "Column Break" + }, + { + "default": "Today", + "fieldname": "date", + "fieldtype": "Date", + "label": "Date", + "reqd": 1 + }, + { + "fieldname": "payroll_period", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Payroll Period", + "options": "Payroll Period", + "reqd": 1 + }, + { + "fetch_from": "employee.department", + "fieldname": "department", + "fieldtype": "Link", + "label": "Department", + "options": "Department", + "read_only": 1 + }, + { + "fieldname": "amended_from", + "fieldtype": "Link", + "label": "Amended From", + "no_copy": 1, + "options": "Employee Benefit Application", + "print_hide": 1, + "read_only": 1 + }, + { + "fieldname": "section_break_4", + "fieldtype": "Section Break", + "label": "Benefits Applied" + }, + { + "fieldname": "employee_benefits", + "fieldtype": "Table", + "label": "Employee Benefits", + "options": "Employee Benefit Application Detail", + "reqd": 1 + }, + { + "fieldname": "totals", + "fieldtype": "Section Break", + "label": "Totals" + }, + { + "fieldname": "total_amount", + "fieldtype": "Currency", + "label": "Total Amount", + "read_only": 1 + }, + { + "fieldname": "pro_rata_dispensed_amount", + "fieldtype": "Currency", + "label": "Dispensed Amount (Pro-rated)", + "read_only": 1 + } + ], + "is_submittable": 1, + "links": [], + "modified": "2020-06-22 22:58:31.271922", + "modified_by": "Administrator", + "module": "Payroll", + "name": "Employee Benefit Application", + "owner": "Administrator", + "permissions": [ + { + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "submit": 1, + "write": 1 + }, + { + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "HR Manager", + "share": 1, + "submit": 1, + "write": 1 + }, + { + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "HR User", + "share": 1, + "submit": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Employee", + "share": 1, + "write": 1 + } + ], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "title_field": "employee_name", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py b/erpnext/payroll/doctype/employee_benefit_application/employee_benefit_application.py similarity index 97% rename from erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py rename to erpnext/payroll/doctype/employee_benefit_application/employee_benefit_application.py index feaa92590a..e166a704d6 100644 --- a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py +++ b/erpnext/payroll/doctype/employee_benefit_application/employee_benefit_application.py @@ -7,8 +7,8 @@ import frappe from frappe import _ from frappe.utils import date_diff, getdate, rounded, add_days, cstr, cint, flt from frappe.model.document import Document -from erpnext.hr.doctype.payroll_period.payroll_period import get_payroll_period_days, get_period_factor -from erpnext.hr.doctype.salary_structure_assignment.salary_structure_assignment import get_assigned_salary_structure +from erpnext.payroll.doctype.payroll_period.payroll_period import get_payroll_period_days, get_period_factor +from erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment import get_assigned_salary_structure from erpnext.hr.utils import get_sal_slip_total_benefit_given, get_holidays_for_employee, get_previous_claimed_amount class EmployeeBenefitApplication(Document): diff --git a/erpnext/hr/doctype/employee_benefit_application/test_employee_benefit_application.js b/erpnext/payroll/doctype/employee_benefit_application/test_employee_benefit_application.js similarity index 100% rename from erpnext/hr/doctype/employee_benefit_application/test_employee_benefit_application.js rename to erpnext/payroll/doctype/employee_benefit_application/test_employee_benefit_application.js diff --git a/erpnext/hr/doctype/employee_benefit_application/test_employee_benefit_application.py b/erpnext/payroll/doctype/employee_benefit_application/test_employee_benefit_application.py similarity index 100% rename from erpnext/hr/doctype/employee_benefit_application/test_employee_benefit_application.py rename to erpnext/payroll/doctype/employee_benefit_application/test_employee_benefit_application.py diff --git a/erpnext/hr/doctype/employee_benefit_claim/__init__.py b/erpnext/payroll/doctype/employee_benefit_application_detail/__init__.py similarity index 100% rename from erpnext/hr/doctype/employee_benefit_claim/__init__.py rename to erpnext/payroll/doctype/employee_benefit_application_detail/__init__.py diff --git a/erpnext/payroll/doctype/employee_benefit_application_detail/employee_benefit_application_detail.json b/erpnext/payroll/doctype/employee_benefit_application_detail/employee_benefit_application_detail.json new file mode 100644 index 0000000000..fa6b4da2af --- /dev/null +++ b/erpnext/payroll/doctype/employee_benefit_application_detail/employee_benefit_application_detail.json @@ -0,0 +1,58 @@ +{ + "actions": [], + "creation": "2018-04-13 16:36:18.389786", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "earning_component", + "pay_against_benefit_claim", + "max_benefit_amount", + "amount" + ], + "fields": [ + { + "fieldname": "earning_component", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Earning Component", + "options": "Salary Component", + "reqd": 1 + }, + { + "default": "0", + "fetch_from": "earning_component.pay_against_benefit_claim", + "fieldname": "pay_against_benefit_claim", + "fieldtype": "Check", + "label": "Pay Against Benefit Claim", + "read_only": 1 + }, + { + "fetch_from": "earning_component.max_benefit_amount", + "fieldname": "max_benefit_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Max Benefit Amount", + "read_only": 1 + }, + { + "fieldname": "amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Amount", + "reqd": 1 + } + ], + "istable": 1, + "links": [], + "modified": "2020-06-22 23:45:00.519134", + "modified_by": "Administrator", + "module": "Payroll", + "name": "Employee Benefit Application Detail", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/hr/doctype/employee_benefit_application_detail/employee_benefit_application_detail.py b/erpnext/payroll/doctype/employee_benefit_application_detail/employee_benefit_application_detail.py similarity index 73% rename from erpnext/hr/doctype/employee_benefit_application_detail/employee_benefit_application_detail.py rename to erpnext/payroll/doctype/employee_benefit_application_detail/employee_benefit_application_detail.py index 3a502fe524..65405feaf1 100644 --- a/erpnext/hr/doctype/employee_benefit_application_detail/employee_benefit_application_detail.py +++ b/erpnext/payroll/doctype/employee_benefit_application_detail/employee_benefit_application_detail.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors # For license information, please see license.txt from __future__ import unicode_literals -import frappe +# import frappe from frappe.model.document import Document class EmployeeBenefitApplicationDetail(Document): diff --git a/erpnext/hr/doctype/employee_incentive/__init__.py b/erpnext/payroll/doctype/employee_benefit_claim/__init__.py similarity index 100% rename from erpnext/hr/doctype/employee_incentive/__init__.py rename to erpnext/payroll/doctype/employee_benefit_claim/__init__.py diff --git a/erpnext/hr/doctype/employee_benefit_claim/employee_benefit_claim.js b/erpnext/payroll/doctype/employee_benefit_claim/employee_benefit_claim.js similarity index 77% rename from erpnext/hr/doctype/employee_benefit_claim/employee_benefit_claim.js rename to erpnext/payroll/doctype/employee_benefit_claim/employee_benefit_claim.js index 5e12828ba4..6db6cb86b3 100644 --- a/erpnext/hr/doctype/employee_benefit_claim/employee_benefit_claim.js +++ b/erpnext/payroll/doctype/employee_benefit_claim/employee_benefit_claim.js @@ -5,7 +5,7 @@ frappe.ui.form.on('Employee Benefit Claim', { setup: function(frm) { frm.set_query("earning_component", function() { return { - query : "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_earning_components", + query : "erpnext.payroll.doctype.employee_benefit_application.employee_benefit_application.get_earning_components", filters: {date: frm.doc.claim_date, employee: frm.doc.employee} }; }); diff --git a/erpnext/payroll/doctype/employee_benefit_claim/employee_benefit_claim.json b/erpnext/payroll/doctype/employee_benefit_claim/employee_benefit_claim.json new file mode 100644 index 0000000000..ae4c218615 --- /dev/null +++ b/erpnext/payroll/doctype/employee_benefit_claim/employee_benefit_claim.json @@ -0,0 +1,194 @@ +{ + "actions": [], + "allow_import": 1, + "autoname": "HR-BEN-CLM-.YY.-.MM.-.#####", + "creation": "2018-04-13 16:43:10.386409", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "employee", + "employee_name", + "department", + "column_break_3", + "claim_date", + "benefit_type_and_amount", + "earning_component", + "max_amount_eligible", + "pay_against_benefit_claim", + "claimed_amount", + "salary_slip", + "amended_from", + "section_break_9", + "attachments" + ], + "fields": [ + { + "fieldname": "employee", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Employee", + "options": "Employee", + "reqd": 1 + }, + { + "fetch_from": "employee.employee_name", + "fieldname": "employee_name", + "fieldtype": "Data", + "label": "Employee Name", + "read_only": 1 + }, + { + "fetch_from": "employee.department", + "fieldname": "department", + "fieldtype": "Link", + "label": "Department", + "options": "Department", + "read_only": 1 + }, + { + "fieldname": "column_break_3", + "fieldtype": "Column Break" + }, + { + "default": "Today", + "fieldname": "claim_date", + "fieldtype": "Date", + "in_list_view": 1, + "label": "Claim Date", + "reqd": 1 + }, + { + "fieldname": "benefit_type_and_amount", + "fieldtype": "Section Break", + "label": "Benefit Type and Amount" + }, + { + "fieldname": "earning_component", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Claim Benefit For", + "options": "Salary Component", + "reqd": 1 + }, + { + "fetch_from": "earning_component.max_benefit_amount", + "fieldname": "max_amount_eligible", + "fieldtype": "Currency", + "label": "Max Amount Eligible", + "read_only": 1 + }, + { + "default": "0", + "fetch_from": "earning_component.pay_against_benefit_claim", + "fieldname": "pay_against_benefit_claim", + "fieldtype": "Check", + "hidden": 1, + "label": "Pay Against Benefit Claim", + "read_only": 1 + }, + { + "fieldname": "claimed_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Claimed Amount", + "reqd": 1 + }, + { + "fieldname": "salary_slip", + "fieldtype": "Link", + "label": "Salary Slip", + "options": "Salary Slip", + "read_only": 1 + }, + { + "fieldname": "amended_from", + "fieldtype": "Link", + "label": "Amended From", + "no_copy": 1, + "options": "Employee Benefit Claim", + "print_hide": 1, + "read_only": 1 + }, + { + "fieldname": "section_break_9", + "fieldtype": "Section Break", + "label": "Expense Proof" + }, + { + "fieldname": "attachments", + "fieldtype": "Attach", + "label": "Attachments" + } + ], + "is_submittable": 1, + "links": [], + "modified": "2020-06-22 23:01:50.791676", + "modified_by": "Administrator", + "module": "Payroll", + "name": "Employee Benefit Claim", + "owner": "Administrator", + "permissions": [ + { + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "submit": 1, + "write": 1 + }, + { + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "HR Manager", + "share": 1, + "submit": 1, + "write": 1 + }, + { + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "HR User", + "share": 1, + "submit": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Employee", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "title_field": "employee_name", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/hr/doctype/employee_benefit_claim/employee_benefit_claim.py b/erpnext/payroll/doctype/employee_benefit_claim/employee_benefit_claim.py similarity index 96% rename from erpnext/hr/doctype/employee_benefit_claim/employee_benefit_claim.py rename to erpnext/payroll/doctype/employee_benefit_claim/employee_benefit_claim.py index 3a12c9c9f9..d9937a7bb9 100644 --- a/erpnext/hr/doctype/employee_benefit_claim/employee_benefit_claim.py +++ b/erpnext/payroll/doctype/employee_benefit_claim/employee_benefit_claim.py @@ -7,10 +7,10 @@ import frappe from frappe import _ from frappe.utils import flt from frappe.model.document import Document -from erpnext.hr.doctype.employee_benefit_application.employee_benefit_application import get_max_benefits +from erpnext.payroll.doctype.employee_benefit_application.employee_benefit_application import get_max_benefits from erpnext.hr.utils import get_previous_claimed_amount -from erpnext.hr.doctype.payroll_period.payroll_period import get_payroll_period -from erpnext.hr.doctype.salary_structure_assignment.salary_structure_assignment import get_assigned_salary_structure +from erpnext.payroll.doctype.payroll_period.payroll_period import get_payroll_period +from erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment import get_assigned_salary_structure class EmployeeBenefitClaim(Document): def validate(self): diff --git a/erpnext/hr/doctype/employee_benefit_claim/test_employee_benefit_claim.js b/erpnext/payroll/doctype/employee_benefit_claim/test_employee_benefit_claim.js similarity index 100% rename from erpnext/hr/doctype/employee_benefit_claim/test_employee_benefit_claim.js rename to erpnext/payroll/doctype/employee_benefit_claim/test_employee_benefit_claim.js diff --git a/erpnext/hr/doctype/employee_benefit_claim/test_employee_benefit_claim.py b/erpnext/payroll/doctype/employee_benefit_claim/test_employee_benefit_claim.py similarity index 100% rename from erpnext/hr/doctype/employee_benefit_claim/test_employee_benefit_claim.py rename to erpnext/payroll/doctype/employee_benefit_claim/test_employee_benefit_claim.py diff --git a/erpnext/hr/doctype/employee_other_income/__init__.py b/erpnext/payroll/doctype/employee_incentive/__init__.py similarity index 100% rename from erpnext/hr/doctype/employee_other_income/__init__.py rename to erpnext/payroll/doctype/employee_incentive/__init__.py diff --git a/erpnext/hr/doctype/employee_incentive/employee_incentive.js b/erpnext/payroll/doctype/employee_incentive/employee_incentive.js similarity index 100% rename from erpnext/hr/doctype/employee_incentive/employee_incentive.js rename to erpnext/payroll/doctype/employee_incentive/employee_incentive.js diff --git a/erpnext/hr/doctype/employee_incentive/employee_incentive.json b/erpnext/payroll/doctype/employee_incentive/employee_incentive.json similarity index 97% rename from erpnext/hr/doctype/employee_incentive/employee_incentive.json rename to erpnext/payroll/doctype/employee_incentive/employee_incentive.json index e2d8a11f47..204c9a40b1 100644 --- a/erpnext/hr/doctype/employee_incentive/employee_incentive.json +++ b/erpnext/payroll/doctype/employee_incentive/employee_incentive.json @@ -74,9 +74,9 @@ ], "is_submittable": 1, "links": [], - "modified": "2020-03-05 18:59:40.526014", + "modified": "2020-06-22 22:42:51.209630", "modified_by": "Administrator", - "module": "HR", + "module": "Payroll", "name": "Employee Incentive", "owner": "Administrator", "permissions": [ diff --git a/erpnext/hr/doctype/employee_incentive/employee_incentive.py b/erpnext/payroll/doctype/employee_incentive/employee_incentive.py similarity index 100% rename from erpnext/hr/doctype/employee_incentive/employee_incentive.py rename to erpnext/payroll/doctype/employee_incentive/employee_incentive.py diff --git a/erpnext/hr/doctype/employee_incentive/test_employee_incentive.js b/erpnext/payroll/doctype/employee_incentive/test_employee_incentive.js similarity index 100% rename from erpnext/hr/doctype/employee_incentive/test_employee_incentive.js rename to erpnext/payroll/doctype/employee_incentive/test_employee_incentive.js diff --git a/erpnext/hr/doctype/employee_incentive/test_employee_incentive.py b/erpnext/payroll/doctype/employee_incentive/test_employee_incentive.py similarity index 100% rename from erpnext/hr/doctype/employee_incentive/test_employee_incentive.py rename to erpnext/payroll/doctype/employee_incentive/test_employee_incentive.py diff --git a/erpnext/hr/doctype/employee_tax_exemption_category/__init__.py b/erpnext/payroll/doctype/employee_other_income/__init__.py similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_category/__init__.py rename to erpnext/payroll/doctype/employee_other_income/__init__.py diff --git a/erpnext/hr/doctype/employee_other_income/employee_other_income.js b/erpnext/payroll/doctype/employee_other_income/employee_other_income.js similarity index 100% rename from erpnext/hr/doctype/employee_other_income/employee_other_income.js rename to erpnext/payroll/doctype/employee_other_income/employee_other_income.js diff --git a/erpnext/hr/doctype/employee_other_income/employee_other_income.json b/erpnext/payroll/doctype/employee_other_income/employee_other_income.json similarity index 97% rename from erpnext/hr/doctype/employee_other_income/employee_other_income.json rename to erpnext/payroll/doctype/employee_other_income/employee_other_income.json index 8abfe1e93a..14f63e4fdd 100644 --- a/erpnext/hr/doctype/employee_other_income/employee_other_income.json +++ b/erpnext/payroll/doctype/employee_other_income/employee_other_income.json @@ -76,9 +76,9 @@ ], "is_submittable": 1, "links": [], - "modified": "2020-05-14 17:17:38.883126", + "modified": "2020-06-22 22:55:17.604688", "modified_by": "Administrator", - "module": "HR", + "module": "Payroll", "name": "Employee Other Income", "owner": "Administrator", "permissions": [ diff --git a/erpnext/hr/doctype/employee_other_income/employee_other_income.py b/erpnext/payroll/doctype/employee_other_income/employee_other_income.py similarity index 100% rename from erpnext/hr/doctype/employee_other_income/employee_other_income.py rename to erpnext/payroll/doctype/employee_other_income/employee_other_income.py diff --git a/erpnext/hr/doctype/employee_other_income/test_employee_other_income.py b/erpnext/payroll/doctype/employee_other_income/test_employee_other_income.py similarity index 100% rename from erpnext/hr/doctype/employee_other_income/test_employee_other_income.py rename to erpnext/payroll/doctype/employee_other_income/test_employee_other_income.py diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration/__init__.py b/erpnext/payroll/doctype/employee_tax_exemption_category/__init__.py similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_declaration/__init__.py rename to erpnext/payroll/doctype/employee_tax_exemption_category/__init__.py diff --git a/erpnext/hr/doctype/employee_tax_exemption_category/employee_tax_exemption_category.js b/erpnext/payroll/doctype/employee_tax_exemption_category/employee_tax_exemption_category.js similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_category/employee_tax_exemption_category.js rename to erpnext/payroll/doctype/employee_tax_exemption_category/employee_tax_exemption_category.js diff --git a/erpnext/payroll/doctype/employee_tax_exemption_category/employee_tax_exemption_category.json b/erpnext/payroll/doctype/employee_tax_exemption_category/employee_tax_exemption_category.json new file mode 100644 index 0000000000..f2556d7d96 --- /dev/null +++ b/erpnext/payroll/doctype/employee_tax_exemption_category/employee_tax_exemption_category.json @@ -0,0 +1,74 @@ +{ + "actions": [], + "allow_import": 1, + "allow_rename": 1, + "autoname": "Prompt", + "creation": "2018-04-13 16:51:36.971140", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "max_amount", + "is_active" + ], + "fields": [ + { + "fieldname": "max_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Max Exemption Amount" + }, + { + "default": "1", + "fieldname": "is_active", + "fieldtype": "Check", + "label": "Is Active" + } + ], + "links": [], + "modified": "2020-06-22 23:16:47.472910", + "modified_by": "Administrator", + "module": "Payroll", + "name": "Employee Tax Exemption Category", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "HR Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "HR User", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC" +} \ No newline at end of file diff --git a/erpnext/hr/doctype/employee_tax_exemption_category/employee_tax_exemption_category.py b/erpnext/payroll/doctype/employee_tax_exemption_category/employee_tax_exemption_category.py similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_category/employee_tax_exemption_category.py rename to erpnext/payroll/doctype/employee_tax_exemption_category/employee_tax_exemption_category.py diff --git a/erpnext/hr/doctype/employee_tax_exemption_category/test_employee_tax_exemption_category.js b/erpnext/payroll/doctype/employee_tax_exemption_category/test_employee_tax_exemption_category.js similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_category/test_employee_tax_exemption_category.js rename to erpnext/payroll/doctype/employee_tax_exemption_category/test_employee_tax_exemption_category.js diff --git a/erpnext/hr/doctype/employee_tax_exemption_category/test_employee_tax_exemption_category.py b/erpnext/payroll/doctype/employee_tax_exemption_category/test_employee_tax_exemption_category.py similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_category/test_employee_tax_exemption_category.py rename to erpnext/payroll/doctype/employee_tax_exemption_category/test_employee_tax_exemption_category.py diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration_category/__init__.py b/erpnext/payroll/doctype/employee_tax_exemption_declaration/__init__.py similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_declaration_category/__init__.py rename to erpnext/payroll/doctype/employee_tax_exemption_declaration/__init__.py diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.js b/erpnext/payroll/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.js similarity index 88% rename from erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.js rename to erpnext/payroll/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.js index a827eca1c4..0e0c9b5a1a 100644 --- a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.js +++ b/erpnext/payroll/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.js @@ -42,7 +42,7 @@ frappe.ui.form.on('Employee Tax Exemption Declaration', { if(frm.doc.docstatus==1) { frm.add_custom_button(__('Submit Proof'), function() { frappe.model.open_mapped_doc({ - method: "erpnext.hr.doctype.employee_tax_exemption_declaration.employee_tax_exemption_declaration.make_proof_submission", + method: "erpnext.payroll.doctype.employee_tax_exemption_declaration.employee_tax_exemption_declaration.make_proof_submission", frm: frm }); }).addClass("btn-primary"); diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.json b/erpnext/payroll/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.json similarity index 98% rename from erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.json rename to erpnext/payroll/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.json index 18fad85c4b..de7c348bb2 100644 --- a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.json +++ b/erpnext/payroll/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.json @@ -107,9 +107,9 @@ ], "is_submittable": 1, "links": [], - "modified": "2020-03-18 14:56:25.625717", + "modified": "2020-06-22 22:49:43.829892", "modified_by": "Administrator", - "module": "HR", + "module": "Payroll", "name": "Employee Tax Exemption Declaration", "owner": "Administrator", "permissions": [ diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.py b/erpnext/payroll/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.py similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.py rename to erpnext/payroll/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.py diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.js b/erpnext/payroll/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.js similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.js rename to erpnext/payroll/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.js diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.py b/erpnext/payroll/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.py similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.py rename to erpnext/payroll/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.py diff --git a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/__init__.py b/erpnext/payroll/doctype/employee_tax_exemption_declaration_category/__init__.py similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_proof_submission/__init__.py rename to erpnext/payroll/doctype/employee_tax_exemption_declaration_category/__init__.py diff --git a/erpnext/payroll/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.json b/erpnext/payroll/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.json new file mode 100644 index 0000000000..8c2f9aa370 --- /dev/null +++ b/erpnext/payroll/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.json @@ -0,0 +1,61 @@ +{ + "actions": [], + "creation": "2018-04-13 16:56:23.333041", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "exemption_sub_category", + "exemption_category", + "max_amount", + "amount" + ], + "fields": [ + { + "fieldname": "exemption_sub_category", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Exemption Sub Category", + "options": "Employee Tax Exemption Sub Category", + "reqd": 1 + }, + { + "fetch_from": "exemption_sub_category.exemption_category", + "fieldname": "exemption_category", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Exemption Category", + "options": "Employee Tax Exemption Category", + "read_only": 1, + "reqd": 1 + }, + { + "fetch_from": "exemption_sub_category.max_amount", + "fieldname": "max_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Maximum Exempted Amount", + "read_only": 1, + "reqd": 1 + }, + { + "fieldname": "amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Declared Amount", + "reqd": 1 + } + ], + "istable": 1, + "links": [], + "modified": "2020-06-22 23:41:03.638739", + "modified_by": "Administrator", + "module": "Payroll", + "name": "Employee Tax Exemption Declaration Category", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.py b/erpnext/payroll/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.py similarity index 73% rename from erpnext/hr/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.py rename to erpnext/payroll/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.py index 362677e887..bff747f90d 100644 --- a/erpnext/hr/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.py +++ b/erpnext/payroll/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors # For license information, please see license.txt from __future__ import unicode_literals -import frappe +# import frappe from frappe.model.document import Document class EmployeeTaxExemptionDeclarationCategory(Document): diff --git a/erpnext/hr/doctype/employee_tax_exemption_proof_submission_detail/__init__.py b/erpnext/payroll/doctype/employee_tax_exemption_proof_submission/__init__.py similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_proof_submission_detail/__init__.py rename to erpnext/payroll/doctype/employee_tax_exemption_proof_submission/__init__.py diff --git a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.js b/erpnext/payroll/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.js similarity index 90% rename from erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.js rename to erpnext/payroll/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.js index 66118c0811..715d7553b0 100644 --- a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.js +++ b/erpnext/payroll/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.js @@ -43,7 +43,7 @@ frappe.ui.form.on('Employee Tax Exemption Proof Submission', { frm.add_custom_button(__('Get Details From Declaration'), function() { erpnext.utils.map_current_doc({ - method: "erpnext.hr.doctype.employee_tax_exemption_declaration.employee_tax_exemption_declaration.make_proof_submission", + method: "erpnext.payroll.doctype.employee_tax_exemption_declaration.employee_tax_exemption_declaration.make_proof_submission", source_doctype: "Employee Tax Exemption Declaration", target: frm, date_field: "creation", diff --git a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.json b/erpnext/payroll/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.json similarity index 98% rename from erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.json rename to erpnext/payroll/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.json index 8b117a25b5..b62b5aab0b 100644 --- a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.json +++ b/erpnext/payroll/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.json @@ -130,9 +130,9 @@ ], "is_submittable": 1, "links": [], - "modified": "2020-03-18 14:55:51.420016", + "modified": "2020-06-22 22:53:10.412321", "modified_by": "Administrator", - "module": "HR", + "module": "Payroll", "name": "Employee Tax Exemption Proof Submission", "owner": "Administrator", "permissions": [ diff --git a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.py b/erpnext/payroll/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.py similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.py rename to erpnext/payroll/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.py diff --git a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/test_employee_tax_exemption_proof_submission.js b/erpnext/payroll/doctype/employee_tax_exemption_proof_submission/test_employee_tax_exemption_proof_submission.js similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_proof_submission/test_employee_tax_exemption_proof_submission.js rename to erpnext/payroll/doctype/employee_tax_exemption_proof_submission/test_employee_tax_exemption_proof_submission.js diff --git a/erpnext/payroll/doctype/employee_tax_exemption_proof_submission/test_employee_tax_exemption_proof_submission.py b/erpnext/payroll/doctype/employee_tax_exemption_proof_submission/test_employee_tax_exemption_proof_submission.py new file mode 100644 index 0000000000..cb9ed5f971 --- /dev/null +++ b/erpnext/payroll/doctype/employee_tax_exemption_proof_submission/test_employee_tax_exemption_proof_submission.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest +from erpnext.payroll.doctype.employee_tax_exemption_declaration.test_employee_tax_exemption_declaration import create_exemption_category, create_payroll_period + +class TestEmployeeTaxExemptionProofSubmission(unittest.TestCase): + def setup(self): + make_employee("employee@proofsubmission.com") + create_payroll_period() + create_exemption_category() + frappe.db.sql("""delete from `tabEmployee Tax Exemption Proof Submission`""") + + def test_exemption_amount_lesser_than_category_max(self): + declaration = frappe.get_doc({ + "doctype": "Employee Tax Exemption Proof Submission", + "employee": frappe.get_value("Employee", {"user_id":"employee@proofsubmission.com"}, "name"), + "payroll_period": "Test Payroll Period", + "tax_exemption_proofs": [dict(exemption_sub_category = "_Test Sub Category", + type_of_proof = "Test Proof", + exemption_category = "_Test Category", + amount = 150000)] + }) + self.assertRaises(frappe.ValidationError, declaration.save) + declaration = frappe.get_doc({ + "doctype": "Employee Tax Exemption Proof Submission", + "payroll_period": "Test Payroll Period", + "employee": frappe.get_value("Employee", {"user_id":"employee@proofsubmission.com"}, "name"), + "tax_exemption_proofs": [dict(exemption_sub_category = "_Test Sub Category", + type_of_proof = "Test Proof", + exemption_category = "_Test Category", + amount = 100000)] + }) + self.assertTrue(declaration.save) + self.assertTrue(declaration.submit) + + def test_duplicate_category_in_proof_submission(self): + declaration = frappe.get_doc({ + "doctype": "Employee Tax Exemption Proof Submission", + "employee": frappe.get_value("Employee", {"user_id":"employee@proofsubmission.com"}, "name"), + "payroll_period": "Test Payroll Period", + "tax_exemption_proofs": [dict(exemption_sub_category = "_Test Sub Category", + exemption_category = "_Test Category", + type_of_proof = "Test Proof", + amount = 100000), + dict(exemption_sub_category = "_Test Sub Category", + exemption_category = "_Test Category", + amount = 50000), + ] + }) + self.assertRaises(frappe.ValidationError, declaration.save) diff --git a/erpnext/hr/doctype/employee_tax_exemption_sub_category/__init__.py b/erpnext/payroll/doctype/employee_tax_exemption_proof_submission_detail/__init__.py similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_sub_category/__init__.py rename to erpnext/payroll/doctype/employee_tax_exemption_proof_submission_detail/__init__.py diff --git a/erpnext/payroll/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.json b/erpnext/payroll/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.json new file mode 100644 index 0000000000..c1f532050a --- /dev/null +++ b/erpnext/payroll/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.json @@ -0,0 +1,66 @@ +{ + "actions": [], + "creation": "2018-04-13 17:19:03.006149", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "exemption_sub_category", + "exemption_category", + "max_amount", + "type_of_proof", + "amount" + ], + "fields": [ + { + "fieldname": "exemption_sub_category", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Exemption Sub Category", + "options": "Employee Tax Exemption Sub Category", + "reqd": 1 + }, + { + "fetch_from": "exemption_sub_category.exemption_category", + "fieldname": "exemption_category", + "fieldtype": "Read Only", + "in_list_view": 1, + "label": "Exemption Category", + "reqd": 1 + }, + { + "fetch_from": "exemption_sub_category.max_amount", + "fieldname": "max_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Maximum Exemption Amount", + "read_only": 1, + "reqd": 1 + }, + { + "fieldname": "type_of_proof", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Type of Proof", + "reqd": 1 + }, + { + "fieldname": "amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Actual Amount" + } + ], + "istable": 1, + "links": [], + "modified": "2020-06-22 23:37:08.265600", + "modified_by": "Administrator", + "module": "Payroll", + "name": "Employee Tax Exemption Proof Submission Detail", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/hr/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.py b/erpnext/payroll/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.py similarity index 74% rename from erpnext/hr/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.py rename to erpnext/payroll/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.py index c5d1a8fe5d..0244ae6646 100644 --- a/erpnext/hr/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.py +++ b/erpnext/payroll/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors # For license information, please see license.txt from __future__ import unicode_literals -import frappe +# import frappe from frappe.model.document import Document class EmployeeTaxExemptionProofSubmissionDetail(Document): diff --git a/erpnext/hr/doctype/income_tax_slab/__init__.py b/erpnext/payroll/doctype/employee_tax_exemption_sub_category/__init__.py similarity index 100% rename from erpnext/hr/doctype/income_tax_slab/__init__.py rename to erpnext/payroll/doctype/employee_tax_exemption_sub_category/__init__.py diff --git a/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.js b/erpnext/payroll/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.js similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.js rename to erpnext/payroll/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.js diff --git a/erpnext/payroll/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.json b/erpnext/payroll/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.json new file mode 100644 index 0000000000..f8c4b8bcb0 --- /dev/null +++ b/erpnext/payroll/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.json @@ -0,0 +1,86 @@ +{ + "actions": [], + "allow_import": 1, + "allow_rename": 1, + "autoname": "Prompt", + "creation": "2018-05-09 12:47:26.983095", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "exemption_category", + "max_amount", + "is_active" + ], + "fields": [ + { + "fieldname": "exemption_category", + "fieldtype": "Link", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Tax Exemption Category", + "options": "Employee Tax Exemption Category", + "reqd": 1 + }, + { + "fetch_from": "exemption_category.max_amount", + "fetch_if_empty": 1, + "fieldname": "max_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Max Exemption Amount" + }, + { + "default": "1", + "fieldname": "is_active", + "fieldtype": "Check", + "label": "Is Active" + } + ], + "links": [], + "modified": "2020-06-22 23:18:08.254645", + "modified_by": "Administrator", + "module": "Payroll", + "name": "Employee Tax Exemption Sub Category", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "HR Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "HR User", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC" +} \ No newline at end of file diff --git a/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.py b/erpnext/payroll/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.py similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.py rename to erpnext/payroll/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.py diff --git a/erpnext/hr/doctype/employee_tax_exemption_sub_category/test_employee_tax_exemption_sub_category.js b/erpnext/payroll/doctype/employee_tax_exemption_sub_category/test_employee_tax_exemption_sub_category.js similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_sub_category/test_employee_tax_exemption_sub_category.js rename to erpnext/payroll/doctype/employee_tax_exemption_sub_category/test_employee_tax_exemption_sub_category.js diff --git a/erpnext/hr/doctype/employee_tax_exemption_sub_category/test_employee_tax_exemption_sub_category.py b/erpnext/payroll/doctype/employee_tax_exemption_sub_category/test_employee_tax_exemption_sub_category.py similarity index 100% rename from erpnext/hr/doctype/employee_tax_exemption_sub_category/test_employee_tax_exemption_sub_category.py rename to erpnext/payroll/doctype/employee_tax_exemption_sub_category/test_employee_tax_exemption_sub_category.py diff --git a/erpnext/hr/doctype/income_tax_slab_other_charges/__init__.py b/erpnext/payroll/doctype/income_tax_slab/__init__.py similarity index 100% rename from erpnext/hr/doctype/income_tax_slab_other_charges/__init__.py rename to erpnext/payroll/doctype/income_tax_slab/__init__.py diff --git a/erpnext/hr/doctype/income_tax_slab/income_tax_slab.js b/erpnext/payroll/doctype/income_tax_slab/income_tax_slab.js similarity index 100% rename from erpnext/hr/doctype/income_tax_slab/income_tax_slab.js rename to erpnext/payroll/doctype/income_tax_slab/income_tax_slab.js diff --git a/erpnext/hr/doctype/income_tax_slab/income_tax_slab.json b/erpnext/payroll/doctype/income_tax_slab/income_tax_slab.json similarity index 97% rename from erpnext/hr/doctype/income_tax_slab/income_tax_slab.json rename to erpnext/payroll/doctype/income_tax_slab/income_tax_slab.json index f74315f32e..6337d5a6d3 100644 --- a/erpnext/hr/doctype/income_tax_slab/income_tax_slab.json +++ b/erpnext/payroll/doctype/income_tax_slab/income_tax_slab.json @@ -94,9 +94,9 @@ ], "is_submittable": 1, "links": [], - "modified": "2020-04-29 15:08:21.436120", + "modified": "2020-06-22 20:27:13.425084", "modified_by": "Administrator", - "module": "HR", + "module": "Payroll", "name": "Income Tax Slab", "owner": "Administrator", "permissions": [ diff --git a/erpnext/hr/doctype/income_tax_slab/income_tax_slab.py b/erpnext/payroll/doctype/income_tax_slab/income_tax_slab.py similarity index 100% rename from erpnext/hr/doctype/income_tax_slab/income_tax_slab.py rename to erpnext/payroll/doctype/income_tax_slab/income_tax_slab.py diff --git a/erpnext/hr/doctype/income_tax_slab/test_income_tax_slab.py b/erpnext/payroll/doctype/income_tax_slab/test_income_tax_slab.py similarity index 100% rename from erpnext/hr/doctype/income_tax_slab/test_income_tax_slab.py rename to erpnext/payroll/doctype/income_tax_slab/test_income_tax_slab.py diff --git a/erpnext/hr/doctype/payroll_employee_detail/__init__.py b/erpnext/payroll/doctype/income_tax_slab_other_charges/__init__.py similarity index 100% rename from erpnext/hr/doctype/payroll_employee_detail/__init__.py rename to erpnext/payroll/doctype/income_tax_slab_other_charges/__init__.py diff --git a/erpnext/hr/doctype/income_tax_slab_other_charges/income_tax_slab_other_charges.json b/erpnext/payroll/doctype/income_tax_slab_other_charges/income_tax_slab_other_charges.json similarity index 95% rename from erpnext/hr/doctype/income_tax_slab_other_charges/income_tax_slab_other_charges.json rename to erpnext/payroll/doctype/income_tax_slab_other_charges/income_tax_slab_other_charges.json index b23fb3dc31..7f21204591 100644 --- a/erpnext/hr/doctype/income_tax_slab_other_charges/income_tax_slab_other_charges.json +++ b/erpnext/payroll/doctype/income_tax_slab_other_charges/income_tax_slab_other_charges.json @@ -14,18 +14,6 @@ "max_taxable_income" ], "fields": [ - { - "fieldname": "column_break_2", - "fieldtype": "Column Break" - }, - { - "columns": 2, - "fieldname": "min_taxable_income", - "fieldtype": "Currency", - "in_list_view": 1, - "label": "Min Taxable Income", - "options": "Company:company:default_currency" - }, { "columns": 4, "fieldname": "description", @@ -34,6 +22,10 @@ "label": "Description", "reqd": 1 }, + { + "fieldname": "column_break_2", + "fieldtype": "Column Break" + }, { "columns": 2, "fieldname": "percent", @@ -47,6 +39,14 @@ "fieldtype": "Section Break", "label": "Conditions" }, + { + "columns": 2, + "fieldname": "min_taxable_income", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Min Taxable Income", + "options": "Company:company:default_currency" + }, { "fieldname": "column_break_7", "fieldtype": "Column Break" @@ -62,9 +62,9 @@ ], "istable": 1, "links": [], - "modified": "2020-04-24 13:27:43.598967", + "modified": "2020-06-22 23:33:17.931912", "modified_by": "Administrator", - "module": "HR", + "module": "Payroll", "name": "Income Tax Slab Other Charges", "owner": "Administrator", "permissions": [], diff --git a/erpnext/hr/doctype/income_tax_slab_other_charges/income_tax_slab_other_charges.py b/erpnext/payroll/doctype/income_tax_slab_other_charges/income_tax_slab_other_charges.py similarity index 100% rename from erpnext/hr/doctype/income_tax_slab_other_charges/income_tax_slab_other_charges.py rename to erpnext/payroll/doctype/income_tax_slab_other_charges/income_tax_slab_other_charges.py diff --git a/erpnext/hr/doctype/payroll_entry/__init__.py b/erpnext/payroll/doctype/payroll_employee_detail/__init__.py similarity index 100% rename from erpnext/hr/doctype/payroll_entry/__init__.py rename to erpnext/payroll/doctype/payroll_employee_detail/__init__.py diff --git a/erpnext/payroll/doctype/payroll_employee_detail/payroll_employee_detail.json b/erpnext/payroll/doctype/payroll_employee_detail/payroll_employee_detail.json new file mode 100644 index 0000000000..bb68e1814a --- /dev/null +++ b/erpnext/payroll/doctype/payroll_employee_detail/payroll_employee_detail.json @@ -0,0 +1,66 @@ +{ + "actions": [], + "creation": "2017-11-30 06:07:33.477781", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "employee", + "employee_name", + "column_break_3", + "department", + "designation" + ], + "fields": [ + { + "fieldname": "employee", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Employee", + "options": "Employee", + "read_only": 1 + }, + { + "fetch_from": "employee.employee_name", + "fieldname": "employee_name", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Employee Name", + "read_only": 1 + }, + { + "fieldname": "column_break_3", + "fieldtype": "Column Break" + }, + { + "fetch_from": "employee.department", + "fieldname": "department", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Department", + "options": "Department", + "read_only": 1 + }, + { + "fetch_from": "employee.designation", + "fieldname": "designation", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Designation", + "read_only": 1 + } + ], + "istable": 1, + "links": [], + "modified": "2020-06-22 23:25:13.779032", + "modified_by": "Administrator", + "module": "Payroll", + "name": "Payroll Employee Detail", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "read_only": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/hr/doctype/payroll_employee_detail/payroll_employee_detail.py b/erpnext/payroll/doctype/payroll_employee_detail/payroll_employee_detail.py similarity index 100% rename from erpnext/hr/doctype/payroll_employee_detail/payroll_employee_detail.py rename to erpnext/payroll/doctype/payroll_employee_detail/payroll_employee_detail.py diff --git a/erpnext/hr/doctype/payroll_period/__init__.py b/erpnext/payroll/doctype/payroll_entry/__init__.py similarity index 100% rename from erpnext/hr/doctype/payroll_period/__init__.py rename to erpnext/payroll/doctype/payroll_entry/__init__.py diff --git a/erpnext/hr/doctype/payroll_entry/payroll_entry.js b/erpnext/payroll/doctype/payroll_entry/payroll_entry.js similarity index 95% rename from erpnext/hr/doctype/payroll_entry/payroll_entry.js rename to erpnext/payroll/doctype/payroll_entry/payroll_entry.js index da25d7574e..1ae3553b9b 100644 --- a/erpnext/hr/doctype/payroll_entry/payroll_entry.js +++ b/erpnext/payroll/doctype/payroll_entry/payroll_entry.js @@ -84,7 +84,7 @@ frappe.ui.form.on('Payroll Entry', { add_bank_entry_button: function(frm) { frappe.call({ - method: 'erpnext.hr.doctype.payroll_entry.payroll_entry.payroll_entry_has_bank_entries', + method: 'erpnext.payroll.doctype.payroll_entry.payroll_entry.payroll_entry_has_bank_entries', args: { 'name': frm.doc.name }, @@ -170,7 +170,7 @@ frappe.ui.form.on('Payroll Entry', { set_start_end_dates: function (frm) { if (!frm.doc.salary_slip_based_on_timesheet) { frappe.call({ - method: 'erpnext.hr.doctype.payroll_entry.payroll_entry.get_start_end_dates', + method: 'erpnext.payroll.doctype.payroll_entry.payroll_entry.get_start_end_dates', args: { payroll_frequency: frm.doc.payroll_frequency, start_date: frm.doc.posting_date @@ -188,7 +188,7 @@ frappe.ui.form.on('Payroll Entry', { set_end_date: function(frm){ frappe.call({ - method: 'erpnext.hr.doctype.payroll_entry.payroll_entry.get_end_date', + method: 'erpnext.payroll.doctype.payroll_entry.payroll_entry.get_end_date', args: { frequency: frm.doc.payroll_frequency, start_date: frm.doc.start_date diff --git a/erpnext/hr/doctype/payroll_entry/payroll_entry.json b/erpnext/payroll/doctype/payroll_entry/payroll_entry.json similarity index 98% rename from erpnext/hr/doctype/payroll_entry/payroll_entry.json rename to erpnext/payroll/doctype/payroll_entry/payroll_entry.json index 9356f3e7b3..31a899699d 100644 --- a/erpnext/hr/doctype/payroll_entry/payroll_entry.json +++ b/erpnext/payroll/doctype/payroll_entry/payroll_entry.json @@ -1,4 +1,5 @@ { + "actions": [], "allow_copy": 1, "autoname": "HR-PRUN-.YYYY.-.#####", "creation": "2017-10-23 15:22:29.291323", @@ -260,9 +261,10 @@ ], "icon": "fa fa-cog", "is_submittable": 1, - "modified": "2019-09-12 15:46:31.436381", + "links": [], + "modified": "2020-06-22 20:06:06.953904", "modified_by": "Administrator", - "module": "HR", + "module": "Payroll", "name": "Payroll Entry", "owner": "Administrator", "permissions": [ diff --git a/erpnext/hr/doctype/payroll_entry/payroll_entry.py b/erpnext/payroll/doctype/payroll_entry/payroll_entry.py similarity index 99% rename from erpnext/hr/doctype/payroll_entry/payroll_entry.py rename to erpnext/payroll/doctype/payroll_entry/payroll_entry.py index 656de0170d..e6bb708e41 100644 --- a/erpnext/hr/doctype/payroll_entry/payroll_entry.py +++ b/erpnext/payroll/doctype/payroll_entry/payroll_entry.py @@ -55,7 +55,7 @@ class PayrollEntry(Document): ifnull(salary_slip_based_on_timesheet,0) = %(salary_slip_based_on_timesheet)s {condition}""".format(condition=condition), {"company": self.company, "salary_slip_based_on_timesheet":self.salary_slip_based_on_timesheet}) - + if sal_struct: cond += "and t2.salary_structure IN %(sal_struct)s " cond += "and %(from_date)s >= t2.from_date" @@ -154,7 +154,7 @@ class PayrollEntry(Document): submit_salary_slips_for_employees(self, ss_list, publish_progress=False) def email_salary_slip(self, submitted_ss): - if frappe.db.get_single_value("HR Settings", "email_salary_slip_to_employee"): + if frappe.db.get_single_value("Payroll Settings", "email_salary_slip_to_employee"): for ss in submitted_ss: ss.email_salary_slip() @@ -170,7 +170,7 @@ class PayrollEntry(Document): def get_salary_components(self, component_type): salary_slips = self.get_sal_slip_list(ss_status = 1, as_dict = True) - if salary_slips: + if salary_slips: salary_components = frappe.db.sql(""" select ssd.salary_component, ssd.amount, ssd.parentfield, ss.payroll_cost_center from `tabSalary Slip` ss, `tabSalary Detail` ssd @@ -197,7 +197,7 @@ class PayrollEntry(Document): return account_details def get_account(self, component_dict = None): - account_dict = {} + account_dict = {} for key, amount in component_dict.items(): account = self.get_salary_component_account(key[0]) account_dict[(account, key[1])] = account_dict.get((account, key[1]), 0) + amount diff --git a/erpnext/hr/doctype/payroll_entry/payroll_entry_dashboard.py b/erpnext/payroll/doctype/payroll_entry/payroll_entry_dashboard.py similarity index 100% rename from erpnext/hr/doctype/payroll_entry/payroll_entry_dashboard.py rename to erpnext/payroll/doctype/payroll_entry/payroll_entry_dashboard.py diff --git a/erpnext/hr/doctype/payroll_entry/test_payroll_entry.js b/erpnext/payroll/doctype/payroll_entry/test_payroll_entry.js similarity index 100% rename from erpnext/hr/doctype/payroll_entry/test_payroll_entry.js rename to erpnext/payroll/doctype/payroll_entry/test_payroll_entry.js diff --git a/erpnext/hr/doctype/payroll_entry/test_payroll_entry.py b/erpnext/payroll/doctype/payroll_entry/test_payroll_entry.py similarity index 96% rename from erpnext/hr/doctype/payroll_entry/test_payroll_entry.py rename to erpnext/payroll/doctype/payroll_entry/test_payroll_entry.py index 3c318e78a2..b0f225d909 100644 --- a/erpnext/hr/doctype/payroll_entry/test_payroll_entry.py +++ b/erpnext/payroll/doctype/payroll_entry/test_payroll_entry.py @@ -7,11 +7,11 @@ import frappe from dateutil.relativedelta import relativedelta from erpnext.accounts.utils import get_fiscal_year, getdate, nowdate from frappe.utils import add_months -from erpnext.hr.doctype.payroll_entry.payroll_entry import get_start_end_dates, get_end_date +from erpnext.payroll.doctype.payroll_entry.payroll_entry import get_start_end_dates, get_end_date from erpnext.hr.doctype.employee.test_employee import make_employee -from erpnext.hr.doctype.salary_slip.test_salary_slip import get_salary_component_account, \ +from erpnext.payroll.doctype.salary_slip.test_salary_slip import get_salary_component_account, \ make_earning_salary_component, make_deduction_salary_component, create_account -from erpnext.hr.doctype.salary_structure.test_salary_structure import make_salary_structure +from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure from erpnext.loan_management.doctype.loan.test_loan import create_loan, make_loan_disbursement_entry from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_term_loans @@ -24,7 +24,7 @@ class TestPayrollEntry(unittest.TestCase): make_earning_salary_component(setup=True, company_list=["_Test Company"]) make_deduction_salary_component(setup=True, company_list=["_Test Company"]) - frappe.db.set_value("HR Settings", None, "email_salary_slip_to_employee", 0) + frappe.db.set_value("Payroll Settings", None, "email_salary_slip_to_employee", 0) def test_payroll_entry(self): # pylint: disable=no-self-use company = erpnext.get_default_company() diff --git a/erpnext/hr/doctype/payroll_entry/test_set_salary_components.js b/erpnext/payroll/doctype/payroll_entry/test_set_salary_components.js similarity index 100% rename from erpnext/hr/doctype/payroll_entry/test_set_salary_components.js rename to erpnext/payroll/doctype/payroll_entry/test_set_salary_components.js diff --git a/erpnext/hr/doctype/payroll_period_date/__init__.py b/erpnext/payroll/doctype/payroll_period/__init__.py similarity index 100% rename from erpnext/hr/doctype/payroll_period_date/__init__.py rename to erpnext/payroll/doctype/payroll_period/__init__.py diff --git a/erpnext/hr/doctype/payroll_period/payroll_period.js b/erpnext/payroll/doctype/payroll_period/payroll_period.js similarity index 100% rename from erpnext/hr/doctype/payroll_period/payroll_period.js rename to erpnext/payroll/doctype/payroll_period/payroll_period.js diff --git a/erpnext/hr/doctype/payroll_period/payroll_period.json b/erpnext/payroll/doctype/payroll_period/payroll_period.json similarity index 96% rename from erpnext/hr/doctype/payroll_period/payroll_period.json rename to erpnext/payroll/doctype/payroll_period/payroll_period.json index c0fa506e7f..c919b4fe13 100644 --- a/erpnext/hr/doctype/payroll_period/payroll_period.json +++ b/erpnext/payroll/doctype/payroll_period/payroll_period.json @@ -53,9 +53,9 @@ } ], "links": [], - "modified": "2020-03-18 18:13:23.859980", + "modified": "2020-06-22 20:12:32.684189", "modified_by": "Administrator", - "module": "HR", + "module": "Payroll", "name": "Payroll Period", "owner": "Administrator", "permissions": [ diff --git a/erpnext/hr/doctype/payroll_period/payroll_period.py b/erpnext/payroll/doctype/payroll_period/payroll_period.py similarity index 97% rename from erpnext/hr/doctype/payroll_period/payroll_period.py rename to erpnext/payroll/doctype/payroll_period/payroll_period.py index 6956c38285..d7893d0657 100644 --- a/erpnext/hr/doctype/payroll_period/payroll_period.py +++ b/erpnext/payroll/doctype/payroll_period/payroll_period.py @@ -64,7 +64,7 @@ def get_payroll_period_days(start_date, end_date, employee, company=None): if len(payroll_period) > 0: actual_no_of_days = date_diff(getdate(payroll_period[0][2]), getdate(payroll_period[0][1])) + 1 working_days = actual_no_of_days - if not cint(frappe.db.get_value("HR Settings", None, "include_holidays_in_total_working_days")): + if not cint(frappe.db.get_value("Payroll Settings", None, "include_holidays_in_total_working_days")): holidays = get_holidays_for_employee(employee, getdate(payroll_period[0][1]), getdate(payroll_period[0][2])) working_days -= len(holidays) return payroll_period[0][0], working_days, actual_no_of_days diff --git a/erpnext/hr/doctype/payroll_period/payroll_period_dashboard.py b/erpnext/payroll/doctype/payroll_period/payroll_period_dashboard.py similarity index 100% rename from erpnext/hr/doctype/payroll_period/payroll_period_dashboard.py rename to erpnext/payroll/doctype/payroll_period/payroll_period_dashboard.py diff --git a/erpnext/hr/doctype/payroll_period/test_payroll_period.js b/erpnext/payroll/doctype/payroll_period/test_payroll_period.js similarity index 100% rename from erpnext/hr/doctype/payroll_period/test_payroll_period.js rename to erpnext/payroll/doctype/payroll_period/test_payroll_period.js diff --git a/erpnext/hr/doctype/payroll_period/test_payroll_period.py b/erpnext/payroll/doctype/payroll_period/test_payroll_period.py similarity index 100% rename from erpnext/hr/doctype/payroll_period/test_payroll_period.py rename to erpnext/payroll/doctype/payroll_period/test_payroll_period.py diff --git a/erpnext/hr/doctype/retention_bonus/__init__.py b/erpnext/payroll/doctype/payroll_period_date/__init__.py similarity index 100% rename from erpnext/hr/doctype/retention_bonus/__init__.py rename to erpnext/payroll/doctype/payroll_period_date/__init__.py diff --git a/erpnext/payroll/doctype/payroll_period_date/payroll_period_date.json b/erpnext/payroll/doctype/payroll_period_date/payroll_period_date.json new file mode 100644 index 0000000000..4a2f383b37 --- /dev/null +++ b/erpnext/payroll/doctype/payroll_period_date/payroll_period_date.json @@ -0,0 +1,39 @@ +{ + "actions": [], + "creation": "2018-04-13 15:17:30.513630", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "start_date", + "end_date" + ], + "fields": [ + { + "fieldname": "start_date", + "fieldtype": "Date", + "in_list_view": 1, + "label": "Start Date", + "reqd": 1 + }, + { + "fieldname": "end_date", + "fieldtype": "Date", + "in_list_view": 1, + "label": "End Date", + "reqd": 1 + } + ], + "istable": 1, + "links": [], + "modified": "2020-06-22 23:30:15.943356", + "modified_by": "Administrator", + "module": "Payroll", + "name": "Payroll Period Date", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/hr/doctype/payroll_period_date/payroll_period_date.py b/erpnext/payroll/doctype/payroll_period_date/payroll_period_date.py similarity index 71% rename from erpnext/hr/doctype/payroll_period_date/payroll_period_date.py rename to erpnext/payroll/doctype/payroll_period_date/payroll_period_date.py index 06ecb495f3..a3ee269d8e 100644 --- a/erpnext/hr/doctype/payroll_period_date/payroll_period_date.py +++ b/erpnext/payroll/doctype/payroll_period_date/payroll_period_date.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors # For license information, please see license.txt from __future__ import unicode_literals -import frappe +# import frappe from frappe.model.document import Document class PayrollPeriodDate(Document): diff --git a/erpnext/hr/doctype/salary_component/__init__.py b/erpnext/payroll/doctype/payroll_settings/__init__.py similarity index 100% rename from erpnext/hr/doctype/salary_component/__init__.py rename to erpnext/payroll/doctype/payroll_settings/__init__.py diff --git a/erpnext/payroll/doctype/payroll_settings/payroll_settings.js b/erpnext/payroll/doctype/payroll_settings/payroll_settings.js new file mode 100644 index 0000000000..941464dc51 --- /dev/null +++ b/erpnext/payroll/doctype/payroll_settings/payroll_settings.js @@ -0,0 +1,19 @@ +// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Payroll Settings', { + encrypt_salary_slips_in_emails: function(frm) { + let encrypt_state = frm.doc.encrypt_salary_slips_in_emails; + frm.set_df_property('password_policy', 'reqd', encrypt_state); + }, + + validate: function(frm) { + let policy = frm.doc.password_policy; + if (policy) { + if (policy.includes(' ') || policy.includes('--')) { + frappe.msgprint(__("Password policy cannot contain spaces or simultaneous hyphens. The format will be restructured automatically")); + } + frm.set_value('password_policy', policy.split(new RegExp(" |-", 'g')).filter((token) => token).join('-')); + } + }, +}); diff --git a/erpnext/payroll/doctype/payroll_settings/payroll_settings.json b/erpnext/payroll/doctype/payroll_settings/payroll_settings.json new file mode 100644 index 0000000000..c47caa1227 --- /dev/null +++ b/erpnext/payroll/doctype/payroll_settings/payroll_settings.json @@ -0,0 +1,130 @@ +{ + "actions": [], + "creation": "2020-06-04 15:13:33.589685", + "doctype": "DocType", + "document_type": "Other", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "payroll_based_on", + "consider_unmarked_attendance_as", + "max_working_hours_against_timesheet", + "include_holidays_in_total_working_days", + "disable_rounded_total", + "column_break_11", + "daily_wages_fraction_for_half_day", + "email_salary_slip_to_employee", + "encrypt_salary_slips_in_emails", + "password_policy" + ], + "fields": [ + { + "default": "Leave", + "fieldname": "payroll_based_on", + "fieldtype": "Select", + "label": "Calculate Payroll Working Days Based On", + "options": "Leave\nAttendance", + "show_days": 1, + "show_seconds": 1 + }, + { + "fieldname": "max_working_hours_against_timesheet", + "fieldtype": "Float", + "label": "Max working hours against Timesheet", + "show_days": 1, + "show_seconds": 1 + }, + { + "default": "0", + "description": "If checked, Total no. of Working Days will include holidays, and this will reduce the value of Salary Per Day", + "fieldname": "include_holidays_in_total_working_days", + "fieldtype": "Check", + "label": "Include holidays in Total no. of Working Days", + "show_days": 1, + "show_seconds": 1 + }, + { + "default": "0", + "description": "If checked, hides and disables Rounded Total field in Salary Slips", + "fieldname": "disable_rounded_total", + "fieldtype": "Check", + "label": "Disable Rounded Total", + "show_days": 1, + "show_seconds": 1 + }, + { + "fieldname": "column_break_11", + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 + }, + { + "default": "0.5", + "description": "The fraction of daily wages to be paid for half-day attendance", + "fieldname": "daily_wages_fraction_for_half_day", + "fieldtype": "Float", + "label": "Fraction of Daily Salary for Half Day", + "show_days": 1, + "show_seconds": 1 + }, + { + "default": "1", + "description": "Emails salary slip to employee based on preferred email selected in Employee", + "fieldname": "email_salary_slip_to_employee", + "fieldtype": "Check", + "label": "Email Salary Slip to Employee", + "show_days": 1, + "show_seconds": 1 + }, + { + "default": "0", + "depends_on": "eval: doc.email_salary_slip_to_employee == 1;", + "description": "The salary slip emailed to the employee will be password protected, the password will be generated based on the password policy.", + "fieldname": "encrypt_salary_slips_in_emails", + "fieldtype": "Check", + "label": "Encrypt Salary Slips in Emails", + "show_days": 1, + "show_seconds": 1 + }, + { + "depends_on": "eval: doc.encrypt_salary_slips_in_emails == 1", + "description": "Example: SAL-{first_name}-{date_of_birth.year}
This will generate a password like SAL-Jane-1972", + "fieldname": "password_policy", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Password Policy", + "show_days": 1, + "show_seconds": 1 + }, + { + "depends_on": "eval:doc.payroll_based_on == 'Attendance'", + "fieldname": "consider_unmarked_attendance_as", + "fieldtype": "Select", + "label": "Consider Unmarked Attendance As", + "options": "Present\nAbsent", + "show_days": 1, + "show_seconds": 1 + } + ], + "icon": "fa fa-cog", + "issingle": 1, + "links": [], + "modified": "2020-06-22 17:00:58.408030", + "modified_by": "Administrator", + "module": "Payroll", + "name": "Payroll Settings", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "ASC" +} \ No newline at end of file diff --git a/erpnext/payroll/doctype/payroll_settings/payroll_settings.py b/erpnext/payroll/doctype/payroll_settings/payroll_settings.py new file mode 100644 index 0000000000..5efa41db1f --- /dev/null +++ b/erpnext/payroll/doctype/payroll_settings/payroll_settings.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document +from frappe.utils import cint +from frappe.custom.doctype.property_setter.property_setter import make_property_setter +from frappe import _ + +class PayrollSettings(Document): + def validate(self): + self.validate_password_policy() + + if not self.daily_wages_fraction_for_half_day: + self.daily_wages_fraction_for_half_day = 0.5 + + def validate_password_policy(self): + if self.email_salary_slip_to_employee and self.encrypt_salary_slips_in_emails: + if not self.password_policy: + frappe.throw(_("Password policy for Salary Slips is not set")) + + + def on_update(self): + self.toggle_rounded_total() + frappe.clear_cache() + + def toggle_rounded_total(self): + self.disable_rounded_total = cint(self.disable_rounded_total) + make_property_setter("Salary Slip", "rounded_total", "hidden", self.disable_rounded_total, "Check") + make_property_setter("Salary Slip", "rounded_total", "print_hide", self.disable_rounded_total, "Check") diff --git a/erpnext/payroll/doctype/payroll_settings/test_payroll_settings.py b/erpnext/payroll/doctype/payroll_settings/test_payroll_settings.py new file mode 100644 index 0000000000..314866e128 --- /dev/null +++ b/erpnext/payroll/doctype/payroll_settings/test_payroll_settings.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +# import frappe +import unittest + +class TestPayrollSettings(unittest.TestCase): + pass diff --git a/erpnext/hr/doctype/salary_detail/__init__.py b/erpnext/payroll/doctype/retention_bonus/__init__.py similarity index 100% rename from erpnext/hr/doctype/salary_detail/__init__.py rename to erpnext/payroll/doctype/retention_bonus/__init__.py diff --git a/erpnext/hr/doctype/retention_bonus/retention_bonus.js b/erpnext/payroll/doctype/retention_bonus/retention_bonus.js similarity index 100% rename from erpnext/hr/doctype/retention_bonus/retention_bonus.js rename to erpnext/payroll/doctype/retention_bonus/retention_bonus.js diff --git a/erpnext/hr/doctype/retention_bonus/retention_bonus.json b/erpnext/payroll/doctype/retention_bonus/retention_bonus.json similarity index 90% rename from erpnext/hr/doctype/retention_bonus/retention_bonus.json rename to erpnext/payroll/doctype/retention_bonus/retention_bonus.json index 7781053e13..da884c2f28 100644 --- a/erpnext/hr/doctype/retention_bonus/retention_bonus.json +++ b/erpnext/payroll/doctype/retention_bonus/retention_bonus.json @@ -1,4 +1,5 @@ { + "actions": [], "allow_import": 1, "allow_rename": 1, "autoname": "HR-RTB-.YYYY.-.#####", @@ -16,8 +17,7 @@ "column_break_6", "employee_name", "department", - "date_of_joining", - "additional_salary" + "date_of_joining" ], "fields": [ { @@ -83,14 +83,6 @@ "label": "Date of Joining", "read_only": 1 }, - { - "fieldname": "additional_salary", - "fieldtype": "Link", - "label": "Additional Salary", - "no_copy": 1, - "options": "Additional Salary", - "read_only": 1 - }, { "fieldname": "salary_component", "fieldtype": "Link", @@ -100,9 +92,10 @@ } ], "is_submittable": 1, - "modified": "2019-09-03 16:47:24.210422", + "links": [], + "modified": "2020-06-22 22:42:05.251951", "modified_by": "Administrator", - "module": "HR", + "module": "Payroll", "name": "Retention Bonus", "owner": "Administrator", "permissions": [ diff --git a/erpnext/hr/doctype/retention_bonus/retention_bonus.py b/erpnext/payroll/doctype/retention_bonus/retention_bonus.py similarity index 76% rename from erpnext/hr/doctype/retention_bonus/retention_bonus.py rename to erpnext/payroll/doctype/retention_bonus/retention_bonus.py index 48637a350c..ed0d36cfa5 100644 --- a/erpnext/hr/doctype/retention_bonus/retention_bonus.py +++ b/erpnext/payroll/doctype/retention_bonus/retention_bonus.py @@ -17,13 +17,7 @@ class RetentionBonus(Document): def on_submit(self): company = frappe.db.get_value('Employee', self.employee, 'company') - additional_salary = frappe.db.exists('Additional Salary', { - 'employee': self.employee, - 'salary_component': self.salary_component, - 'payroll_date': self.bonus_payment_date, - 'company': company, - 'docstatus': 1 - }) + additional_salary = self.get_additional_salary() if not additional_salary: additional_salary = frappe.new_doc('Additional Salary') @@ -32,8 +26,10 @@ class RetentionBonus(Document): additional_salary.amount = self.bonus_amount additional_salary.payroll_date = self.bonus_payment_date additional_salary.company = company + additional_salary.ref_doctype = self.doctype + additional_salary.ref_docname = self.name additional_salary.submit() - self.db_set('additional_salary', additional_salary.name) + # self.db_set('additional_salary', additional_salary.name) else: bonus_added = frappe.db.get_value('Additional Salary', additional_salary, 'amount') + self.bonus_amount @@ -41,11 +37,24 @@ class RetentionBonus(Document): self.db_set('additional_salary', additional_salary) def on_cancel(self): + + additional_salary = self.get_additional_salary() if self.additional_salary: bonus_removed = frappe.db.get_value('Additional Salary', self.additional_salary, 'amount') - self.bonus_amount if bonus_removed == 0: frappe.get_doc('Additional Salary', self.additional_salary).cancel() else: frappe.db.set_value('Additional Salary', self.additional_salary, 'amount', bonus_removed) - - self.db_set('additional_salary', '') \ No newline at end of file + + # self.db_set('additional_salary', '') + + def get_additional_salary(self): + return frappe.db.exists('Additional Salary', { + 'employee': self.employee, + 'salary_component': self.salary_component, + 'payroll_date': self.bonus_payment_date, + 'company': company, + 'docstatus': 1, + 'ref_doctype': self.doctype, + 'ref_docname': self.name + }) diff --git a/erpnext/hr/doctype/retention_bonus/test_retention_bonus.js b/erpnext/payroll/doctype/retention_bonus/test_retention_bonus.js similarity index 100% rename from erpnext/hr/doctype/retention_bonus/test_retention_bonus.js rename to erpnext/payroll/doctype/retention_bonus/test_retention_bonus.js diff --git a/erpnext/hr/doctype/retention_bonus/test_retention_bonus.py b/erpnext/payroll/doctype/retention_bonus/test_retention_bonus.py similarity index 100% rename from erpnext/hr/doctype/retention_bonus/test_retention_bonus.py rename to erpnext/payroll/doctype/retention_bonus/test_retention_bonus.py diff --git a/erpnext/hr/doctype/salary_component/README.md b/erpnext/payroll/doctype/salary_component/README.md similarity index 100% rename from erpnext/hr/doctype/salary_component/README.md rename to erpnext/payroll/doctype/salary_component/README.md diff --git a/erpnext/hr/doctype/salary_slip_timesheet/__init__.py b/erpnext/payroll/doctype/salary_component/__init__.py similarity index 100% rename from erpnext/hr/doctype/salary_slip_timesheet/__init__.py rename to erpnext/payroll/doctype/salary_component/__init__.py diff --git a/erpnext/hr/doctype/salary_component/salary_component.js b/erpnext/payroll/doctype/salary_component/salary_component.js similarity index 100% rename from erpnext/hr/doctype/salary_component/salary_component.js rename to erpnext/payroll/doctype/salary_component/salary_component.js diff --git a/erpnext/hr/doctype/salary_component/salary_component.json b/erpnext/payroll/doctype/salary_component/salary_component.json similarity index 95% rename from erpnext/hr/doctype/salary_component/salary_component.json rename to erpnext/payroll/doctype/salary_component/salary_component.json index 97c46c829e..225b048293 100644 --- a/erpnext/hr/doctype/salary_component/salary_component.json +++ b/erpnext/payroll/doctype/salary_component/salary_component.json @@ -16,6 +16,7 @@ "column_break_4", "depends_on_payment_days", "is_tax_applicable", + "is_income_tax_component", "deduct_full_tax_on_selected_payroll_date", "variable_based_on_taxable_salary", "exempted_from_income_tax", @@ -231,13 +232,22 @@ "fieldname": "exempted_from_income_tax", "fieldtype": "Check", "label": "Exempted from Income Tax" + }, + { + "default": "0", + "depends_on": "eval:doc.type == \"Deduction\"", + "fieldname": "is_income_tax_component", + "fieldtype": "Check", + "label": "Is Income Tax Component", + "show_days": 1, + "show_seconds": 1 } ], "icon": "fa fa-flag", "links": [], - "modified": "2020-04-28 15:46:45.252945", + "modified": "2020-06-22 15:39:20.826565", "modified_by": "Administrator", - "module": "HR", + "module": "Payroll", "name": "Salary Component", "owner": "Administrator", "permissions": [ diff --git a/erpnext/hr/doctype/salary_component/salary_component.py b/erpnext/payroll/doctype/salary_component/salary_component.py similarity index 100% rename from erpnext/hr/doctype/salary_component/salary_component.py rename to erpnext/payroll/doctype/salary_component/salary_component.py diff --git a/erpnext/hr/doctype/salary_component/test_records.json b/erpnext/payroll/doctype/salary_component/test_records.json similarity index 100% rename from erpnext/hr/doctype/salary_component/test_records.json rename to erpnext/payroll/doctype/salary_component/test_records.json diff --git a/erpnext/hr/doctype/salary_component/test_salary_component.js b/erpnext/payroll/doctype/salary_component/test_salary_component.js similarity index 100% rename from erpnext/hr/doctype/salary_component/test_salary_component.js rename to erpnext/payroll/doctype/salary_component/test_salary_component.js diff --git a/erpnext/hr/doctype/salary_component/test_salary_component.py b/erpnext/payroll/doctype/salary_component/test_salary_component.py similarity index 100% rename from erpnext/hr/doctype/salary_component/test_salary_component.py rename to erpnext/payroll/doctype/salary_component/test_salary_component.py diff --git a/erpnext/hr/doctype/salary_structure_assignment/__init__.py b/erpnext/payroll/doctype/salary_detail/__init__.py similarity index 100% rename from erpnext/hr/doctype/salary_structure_assignment/__init__.py rename to erpnext/payroll/doctype/salary_detail/__init__.py diff --git a/erpnext/hr/doctype/salary_detail/salary_detail.json b/erpnext/payroll/doctype/salary_detail/salary_detail.json similarity index 99% rename from erpnext/hr/doctype/salary_detail/salary_detail.json rename to erpnext/payroll/doctype/salary_detail/salary_detail.json index fe5f83b532..adb54f26c6 100644 --- a/erpnext/hr/doctype/salary_detail/salary_detail.json +++ b/erpnext/payroll/doctype/salary_detail/salary_detail.json @@ -211,13 +211,13 @@ ], "istable": 1, "links": [], - "modified": "2020-04-04 20:00:16.475295", + "modified": "2020-06-22 23:21:26.300951", "modified_by": "Administrator", - "module": "HR", + "module": "Payroll", "name": "Salary Detail", "owner": "Administrator", "permissions": [], "quick_entry": 1, "sort_field": "modified", "sort_order": "DESC" -} +} \ No newline at end of file diff --git a/erpnext/hr/doctype/salary_detail/salary_detail.py b/erpnext/payroll/doctype/salary_detail/salary_detail.py similarity index 100% rename from erpnext/hr/doctype/salary_detail/salary_detail.py rename to erpnext/payroll/doctype/salary_detail/salary_detail.py diff --git a/erpnext/hr/doctype/salary_slip/README.md b/erpnext/payroll/doctype/salary_slip/README.md similarity index 100% rename from erpnext/hr/doctype/salary_slip/README.md rename to erpnext/payroll/doctype/salary_slip/README.md diff --git a/erpnext/hr/doctype/salary_slip/__init__.py b/erpnext/payroll/doctype/salary_slip/__init__.py similarity index 100% rename from erpnext/hr/doctype/salary_slip/__init__.py rename to erpnext/payroll/doctype/salary_slip/__init__.py diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.js b/erpnext/payroll/doctype/salary_slip/salary_slip.js similarity index 93% rename from erpnext/hr/doctype/salary_slip/salary_slip.js rename to erpnext/payroll/doctype/salary_slip/salary_slip.js index 1c4d4e34c5..4b623e57b4 100644 --- a/erpnext/hr/doctype/salary_slip/salary_slip.js +++ b/erpnext/payroll/doctype/salary_slip/salary_slip.js @@ -56,7 +56,7 @@ frappe.ui.form.on("Salary Slip", { set_end_date: function(frm){ frappe.call({ - method: 'erpnext.hr.doctype.payroll_entry.payroll_entry.get_end_date', + method: 'erpnext.payroll.doctype.payroll_entry.payroll_entry.get_end_date', args: { frequency: frm.doc.payroll_frequency, start_date: frm.doc.start_date @@ -123,6 +123,9 @@ frappe.ui.form.on("Salary Slip", { doc: frm.doc, callback: function(r, rt) { frm.refresh(); + if (frm.doc.absent_days){ + frm.fields_dict.absent_days.set_description("Unmarked Days is treated as "+ r.message +". You can can change this in " + frappe.utils.get_form_link("Payroll Settings", "Payroll Settings", true)); + } } }); } diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.json b/erpnext/payroll/doctype/salary_slip/salary_slip.json similarity index 70% rename from erpnext/hr/doctype/salary_slip/salary_slip.json rename to erpnext/payroll/doctype/salary_slip/salary_slip.json index cfd4d89731..663a3ef9ea 100644 --- a/erpnext/hr/doctype/salary_slip/salary_slip.json +++ b/erpnext/payroll/doctype/salary_slip/salary_slip.json @@ -23,11 +23,13 @@ "salary_slip_based_on_timesheet", "start_date", "end_date", - "column_break_15", "salary_structure", "payroll_frequency", + "column_break_15", "total_working_days", + "unmarked_days", "leave_without_pay", + "absent_days", "payment_days", "hourly_wages", "timesheets", @@ -37,6 +39,7 @@ "section_break_26", "bank_name", "bank_account_no", + "mode_of_payment", "section_break_32", "deduct_tax_for_unclaimed_employee_benefits", "deduct_tax_for_unsubmitted_tax_exemption_proof", @@ -71,7 +74,9 @@ "fieldtype": "Date", "in_list_view": 1, "label": "Posting Date", - "reqd": 1 + "reqd": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "employee", @@ -84,7 +89,9 @@ "oldfieldtype": "Link", "options": "Employee", "reqd": 1, - "search_index": 1 + "search_index": 1, + "show_days": 1, + "show_seconds": 1 }, { "fetch_from": "employee.employee_name", @@ -95,7 +102,9 @@ "label": "Employee Name", "oldfieldname": "employee_name", "oldfieldtype": "Data", - "reqd": 1 + "reqd": 1, + "show_days": 1, + "show_seconds": 1 }, { "fetch_from": "employee.department", @@ -106,7 +115,9 @@ "oldfieldname": "department", "oldfieldtype": "Link", "options": "Department", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "depends_on": "eval:doc.designation", @@ -115,7 +126,9 @@ "fieldtype": "Read Only", "label": "Designation", "oldfieldname": "designation", - "oldfieldtype": "Link" + "oldfieldtype": "Link", + "show_days": 1, + "show_seconds": 1 }, { "fetch_from": "employee.branch", @@ -126,12 +139,16 @@ "oldfieldname": "branch", "oldfieldtype": "Link", "options": "Branch", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "column_break1", "fieldtype": "Column Break", "oldfieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1, "width": "50%" }, { @@ -139,21 +156,27 @@ "fieldtype": "Select", "label": "Status", "options": "Draft\nSubmitted\nCancelled", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "journal_entry", "fieldtype": "Link", "label": "Journal Entry", "options": "Journal Entry", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "payroll_entry", "fieldtype": "Link", "label": "Payroll Entry", "options": "Payroll Entry", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "company", @@ -163,7 +186,9 @@ "label": "Company", "options": "Company", "remember_last_selected_value": 1, - "reqd": 1 + "reqd": 1, + "show_days": 1, + "show_seconds": 1 }, { "allow_on_submit": 1, @@ -172,46 +197,62 @@ "ignore_user_permissions": 1, "label": "Letter Head", "options": "Letter Head", - "print_hide": 1 + "print_hide": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "section_break_10", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "show_days": 1, + "show_seconds": 1 }, { "default": "0", "fieldname": "salary_slip_based_on_timesheet", "fieldtype": "Check", "label": "Salary Slip Based on Timesheet", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "start_date", "fieldtype": "Date", - "label": "Start Date" + "label": "Start Date", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "end_date", "fieldtype": "Date", - "label": "End Date" + "label": "End Date", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "column_break_15", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "salary_structure", "fieldtype": "Link", "label": "Salary Structure", "options": "Salary Structure", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "depends_on": "eval:(!doc.salary_slip_based_on_timesheet)", "fieldname": "payroll_frequency", "fieldtype": "Select", "label": "Payroll Frequency", - "options": "\nMonthly\nFortnightly\nBimonthly\nWeekly\nDaily" + "options": "\nMonthly\nFortnightly\nBimonthly\nWeekly\nDaily", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "total_working_days", @@ -220,14 +261,18 @@ "oldfieldname": "total_days_in_month", "oldfieldtype": "Int", "read_only": 1, - "reqd": 1 + "reqd": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "leave_without_pay", "fieldtype": "Float", "label": "Leave Without Pay", "oldfieldname": "leave_without_pay", - "oldfieldtype": "Currency" + "oldfieldtype": "Currency", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "payment_days", @@ -236,38 +281,52 @@ "oldfieldname": "payment_days", "oldfieldtype": "Float", "read_only": 1, - "reqd": 1 + "reqd": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "hourly_wages", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "timesheets", "fieldtype": "Table", "label": "Salary Slip Timesheet", - "options": "Salary Slip Timesheet" + "options": "Salary Slip Timesheet", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "column_break_20", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "total_working_hours", "fieldtype": "Float", "label": "Total Working Hours", - "print_hide_if_no_value": 1 + "print_hide_if_no_value": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "hour_rate", "fieldtype": "Currency", "label": "Hour Rate", "options": "Company:company:default_currency", - "print_hide_if_no_value": 1 + "print_hide_if_no_value": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "section_break_26", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "bank_name", @@ -275,7 +334,9 @@ "label": "Bank Name", "oldfieldname": "bank_name", "oldfieldtype": "Data", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "bank_account_no", @@ -283,35 +344,47 @@ "label": "Bank Account No.", "oldfieldname": "bank_account_no", "oldfieldtype": "Data", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "section_break_32", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "show_days": 1, + "show_seconds": 1 }, { "default": "0", "fieldname": "deduct_tax_for_unclaimed_employee_benefits", "fieldtype": "Check", - "label": "Deduct Tax For Unclaimed Employee Benefits" + "label": "Deduct Tax For Unclaimed Employee Benefits", + "show_days": 1, + "show_seconds": 1 }, { "default": "0", "fieldname": "deduct_tax_for_unsubmitted_tax_exemption_proof", "fieldtype": "Check", - "label": "Deduct Tax For Unsubmitted Tax Exemption Proof" + "label": "Deduct Tax For Unsubmitted Tax Exemption Proof", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "earning_deduction", "fieldtype": "Section Break", "label": "Earning & Deduction", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "earning", "fieldtype": "Column Break", "label": "Earning", "oldfieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1, "width": "50%" }, { @@ -320,13 +393,17 @@ "label": "Earnings", "oldfieldname": "earning_details", "oldfieldtype": "Table", - "options": "Salary Detail" + "options": "Salary Detail", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "deduction", "fieldtype": "Column Break", "label": "Deduction", "oldfieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1, "width": "50%" }, { @@ -335,12 +412,16 @@ "label": "Deductions", "oldfieldname": "deduction_details", "oldfieldtype": "Table", - "options": "Salary Detail" + "options": "Salary Detail", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "totals", "fieldtype": "Section Break", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "gross_pay", @@ -349,11 +430,15 @@ "oldfieldname": "gross_pay", "oldfieldtype": "Currency", "options": "Company:company:default_currency", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "column_break_25", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "total_deduction", @@ -362,24 +447,32 @@ "oldfieldname": "total_deduction", "oldfieldtype": "Currency", "options": "Company:company:default_currency", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "depends_on": "total_loan_repayment", "fieldname": "loan_repayment", "fieldtype": "Section Break", - "label": "Loan repayment" + "label": "Loan repayment", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "loans", "fieldtype": "Table", "label": "Employee Loan", "options": "Salary Slip Loan", - "print_hide": 1 + "print_hide": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "section_break_43", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "show_days": 1, + "show_seconds": 1 }, { "default": "0", @@ -387,7 +480,9 @@ "fieldtype": "Currency", "label": "Total Principal Amount", "options": "Company:company:default_currency", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "default": "0", @@ -395,11 +490,15 @@ "fieldtype": "Currency", "label": "Total Interest Amount", "options": "Company:company:default_currency", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "column_break_45", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 }, { "default": "0", @@ -407,12 +506,16 @@ "fieldtype": "Currency", "label": "Total Loan Repayment", "options": "Company:company:default_currency", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "net_pay_info", "fieldtype": "Section Break", - "label": "net pay info" + "label": "net pay info", + "show_days": 1, + "show_seconds": 1 }, { "description": "Gross Pay - Total Deduction - Loan Repayment", @@ -422,11 +525,15 @@ "oldfieldname": "net_pay", "oldfieldtype": "Currency", "options": "Company:company:default_currency", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "column_break_53", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 }, { "bold": 1, @@ -434,11 +541,15 @@ "fieldtype": "Currency", "label": "Rounded Total", "options": "Company:company:default_currency", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "section_break_55", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "show_days": 1, + "show_seconds": 1 }, { "description": "Net Pay (in words) will be visible once you save the Salary Slip.", @@ -447,7 +558,9 @@ "label": "Total in words", "oldfieldname": "net_pay_in_words", "oldfieldtype": "Data", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "amended_from", @@ -459,7 +572,9 @@ "oldfieldtype": "Data", "options": "Salary Slip", "print_hide": 1, - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fetch_from": "employee.payroll_cost_center", @@ -468,16 +583,42 @@ "fieldtype": "Link", "label": "Payroll Cost Center", "options": "Cost Center", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 + }, + { + "fieldname": "mode_of_payment", + "fieldtype": "Select", + "label": "Mode Of Payment", + "read_only": 1, + "show_days": 1, + "show_seconds": 1 + }, + { + "fieldname": "absent_days", + "fieldtype": "Float", + "label": "Absent Days", + "read_only": 1, + "show_days": 1, + "show_seconds": 1 + }, + { + "fieldname": "unmarked_days", + "fieldtype": "Float", + "hidden": 1, + "label": "Unmarked days", + "show_days": 1, + "show_seconds": 1 } ], "icon": "fa fa-file-text", "idx": 9, "is_submittable": 1, "links": [], - "modified": "2020-05-05 18:55:26.173629", + "modified": "2020-06-22 14:42:43.921828", "modified_by": "Administrator", - "module": "HR", + "module": "Payroll", "name": "Salary Slip", "owner": "Administrator", "permissions": [ diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/payroll/doctype/salary_slip/salary_slip.py similarity index 92% rename from erpnext/hr/doctype/salary_slip/salary_slip.py rename to erpnext/payroll/doctype/salary_slip/salary_slip.py index 4d5c8437c6..2da19b0397 100644 --- a/erpnext/hr/doctype/salary_slip/salary_slip.py +++ b/erpnext/payroll/doctype/salary_slip/salary_slip.py @@ -9,14 +9,14 @@ from frappe.utils import add_days, cint, cstr, flt, getdate, rounded, date_diff, from frappe.model.naming import make_autoname from frappe import msgprint, _ -from erpnext.hr.doctype.payroll_entry.payroll_entry import get_start_end_dates +from erpnext.payroll.doctype.payroll_entry.payroll_entry import get_start_end_dates from erpnext.hr.doctype.employee.employee import get_holiday_list_for_employee from erpnext.utilities.transaction_base import TransactionBase from frappe.utils.background_jobs import enqueue -from erpnext.hr.doctype.additional_salary.additional_salary import get_additional_salary_component -from erpnext.hr.doctype.payroll_period.payroll_period import get_period_factor, get_payroll_period -from erpnext.hr.doctype.employee_benefit_application.employee_benefit_application import get_benefit_component_amount -from erpnext.hr.doctype.employee_benefit_claim.employee_benefit_claim import get_benefit_claim_amount, get_last_payroll_period_benefits +from erpnext.payroll.doctype.additional_salary.additional_salary import get_additional_salary_component +from erpnext.payroll.doctype.payroll_period.payroll_period import get_period_factor, get_payroll_period +from erpnext.payroll.doctype.employee_benefit_application.employee_benefit_application import get_benefit_component_amount +from erpnext.payroll.doctype.employee_benefit_claim.employee_benefit_claim import get_benefit_claim_amount, get_last_payroll_period_benefits from erpnext.loan_management.doctype.loan_repayment.loan_repayment import calculate_amounts, create_repayment_entry class SalarySlip(TransactionBase): @@ -54,8 +54,8 @@ class SalarySlip(TransactionBase): total = self.net_pay if self.is_rounding_total_disabled() else self.rounded_total self.total_in_words = money_in_words(total, company_currency) - if frappe.db.get_single_value("HR Settings", "max_working_hours_against_timesheet"): - max_working_hours = frappe.db.get_single_value("HR Settings", "max_working_hours_against_timesheet") + if frappe.db.get_single_value("Payroll Settings", "max_working_hours_against_timesheet"): + max_working_hours = frappe.db.get_single_value("Payroll Settings", "max_working_hours_against_timesheet") if self.salary_slip_based_on_timesheet and (self.total_working_hours > int(max_working_hours)): frappe.msgprint(_("Total working hours should not be greater than max working hours {0}"). format(max_working_hours), alert=True) @@ -67,7 +67,7 @@ class SalarySlip(TransactionBase): self.set_status() self.update_status(self.name) self.make_loan_repayment_entry() - if (frappe.db.get_single_value("HR Settings", "email_salary_slip_to_employee")) and not frappe.flags.via_payroll_entry: + if (frappe.db.get_single_value("Payroll Settings", "email_salary_slip_to_employee")) and not frappe.flags.via_payroll_entry: self.email_salary_slip() def on_cancel(self): @@ -93,7 +93,7 @@ class SalarySlip(TransactionBase): frappe.throw(_("To date cannot be before From date")) def is_rounding_total_disabled(self): - return cint(frappe.db.get_single_value("HR Settings", "disable_rounded_total")) + return cint(frappe.db.get_single_value("Payroll Settings", "disable_rounded_total")) def check_existing(self): if not self.salary_slip_based_on_timesheet: @@ -136,6 +136,8 @@ class SalarySlip(TransactionBase): self.salary_slip_based_on_timesheet = self._salary_structure_doc.salary_slip_based_on_timesheet or 0 self.set_time_sheet() self.pull_sal_struct() + consider_unmarked_attendance_as = frappe.db.get_value("Payroll Settings", None, "consider_unmarked_attendance_as") or "Present" + return consider_unmarked_attendance_as def set_time_sheet(self): if self.salary_slip_based_on_timesheet: @@ -175,7 +177,7 @@ class SalarySlip(TransactionBase): .format(self.employee), title=_('Salary Structure Missing')) def pull_sal_struct(self): - from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip + from erpnext.payroll.doctype.salary_structure.salary_structure import make_salary_slip if self.salary_slip_based_on_timesheet: self.salary_structure = self._salary_structure_doc.name @@ -188,8 +190,8 @@ class SalarySlip(TransactionBase): make_salary_slip(self._salary_structure_doc.name, self) def get_working_days_details(self, joining_date=None, relieving_date=None, lwp=None, for_preview=0): - payroll_based_on = frappe.db.get_value("HR Settings", None, "payroll_based_on") - include_holidays_in_total_working_days = frappe.db.get_single_value("HR Settings", "include_holidays_in_total_working_days") + payroll_based_on = frappe.db.get_value("Payroll Settings", None, "payroll_based_on") + include_holidays_in_total_working_days = frappe.db.get_single_value("Payroll Settings", "include_holidays_in_total_working_days") working_days = date_diff(self.end_date, self.start_date) + 1 if for_preview: @@ -198,7 +200,7 @@ class SalarySlip(TransactionBase): return holidays = self.get_holidays_for_employee(self.start_date, self.end_date) - + if not cint(include_holidays_in_total_working_days): working_days -= len(holidays) if working_days < 0: @@ -206,9 +208,10 @@ class SalarySlip(TransactionBase): if not payroll_based_on: frappe.throw(_("Please set Payroll based on in HR settings")) - + if payroll_based_on == "Attendance": - actual_lwp = self.calculate_lwp_based_on_attendance(holidays) + actual_lwp, absent = self.calculate_lwp_and_absent_days_based_on_attendance(holidays) + self.absent_days = absent else: actual_lwp = self.calculate_lwp_based_on_leave_application(holidays, working_days) @@ -226,9 +229,36 @@ class SalarySlip(TransactionBase): if flt(payment_days) > flt(lwp): self.payment_days = flt(payment_days) - flt(lwp) + + if payroll_based_on == "Attendance": + self.payment_days -= flt(absent) + + unmarked_days = self.get_unmarked_days() + consider_unmarked_attendance_as = frappe.db.get_value("Payroll Settings", None, "consider_unmarked_attendance_as") or "Present" + + if payroll_based_on == "Attendance" and consider_unmarked_attendance_as =="Absent": + self.absent_days += unmarked_days #will be treated as absent + self.payment_days -= unmarked_days + if include_holidays_in_total_working_days: + self.absent_days -= len(holidays) + for holiday in holidays: + if not frappe.db.exists("Attendance", {"employee": self.employee, "attendance_date": holiday, "docstatus": 1 }): + self.payment_days += 1 + + else: self.payment_days = 0 + def get_unmarked_days(self): + marked_days = frappe.get_all("Attendance", filters = { + "attendance_date": ["between", ['2020-05-1',"2020-05-30"]], + "employee": 'HR-EMP-00003', + "docstatus": 1 + }, fields = ["COUNT(*) as marked_days"])[0].marked_days + + return self.total_working_days - marked_days + + def get_payment_days(self, joining_date, relieving_date, include_holidays_in_total_working_days): if not joining_date: joining_date, relieving_date = frappe.get_cached_value("Employee", self.employee, @@ -277,7 +307,7 @@ class SalarySlip(TransactionBase): lwp = 0 holidays = "','".join(holidays) daily_wages_fraction_for_half_day = \ - flt(frappe.db.get_value("HR Settings", None, "daily_wages_fraction_for_half_day")) or 0.5 + flt(frappe.db.get_value("Payroll Settings", None, "daily_wages_fraction_for_half_day")) or 0.5 for d in range(working_days): dt = add_days(cstr(getdate(self.start_date)), d) @@ -304,15 +334,15 @@ class SalarySlip(TransactionBase): lwp += (1 - daily_wages_fraction_for_half_day) if is_half_day_leave else 1 return lwp - - def calculate_lwp_based_on_attendance(self, holidays): + + def calculate_lwp_and_absent_days_based_on_attendance(self, holidays): lwp = 0 + absent = 0 daily_wages_fraction_for_half_day = \ - flt(frappe.db.get_value("HR Settings", None, "daily_wages_fraction_for_half_day")) or 0.5 + flt(frappe.db.get_value("Payroll Settings", None, "daily_wages_fraction_for_half_day")) or 0.5 lwp_leave_types = dict(frappe.get_all("Leave Type", {"is_lwp": 1}, ["name", "include_holiday"], as_list=1)) - attendances = frappe.db.sql(''' SELECT attendance_date, status, leave_type FROM `tabAttendance` @@ -322,7 +352,7 @@ class SalarySlip(TransactionBase): AND docstatus = 1 AND attendance_date between %s and %s ''', values=(self.employee, self.start_date, self.end_date), as_dict=1) - + for d in attendances: if d.status in ('Half Day', 'On Leave') and d.leave_type and d.leave_type not in lwp_leave_types: continue @@ -332,9 +362,14 @@ class SalarySlip(TransactionBase): (d.leave_type and d.leave_type in lwp_leave_types and not lwp_leave_types[d.leave_type]): continue - lwp += (1 - daily_wages_fraction_for_half_day) if d.status == "Half Day" else 1 + if d.status == "Half Day": + lwp += (1 - daily_wages_fraction_for_half_day) + elif d.status == "On Leave" and d.leave_type in lwp_leave_types: + lwp += 1 + elif d.status == "Absent": + absent += 1 - return lwp + return lwp, absent def add_earning_for_hourly_wages(self, doc, salary_component, amount): row_exists = False @@ -578,7 +613,7 @@ class SalarySlip(TransactionBase): # Total taxable earnings including additional and other incomes total_taxable_earnings = previous_taxable_earnings + current_structured_taxable_earnings + future_structured_taxable_earnings \ + current_additional_earnings + other_incomes + unclaimed_taxable_benefits - total_exemption_amount - + # Total taxable earnings without additional earnings with full tax total_taxable_earnings_without_full_tax_addl_components = total_taxable_earnings - current_additional_earnings_with_full_tax @@ -586,7 +621,7 @@ class SalarySlip(TransactionBase): total_structured_tax_amount = self.calculate_tax_by_tax_slab( total_taxable_earnings_without_full_tax_addl_components, tax_slab) current_structured_tax_amount = (total_structured_tax_amount - previous_total_paid_taxes) / remaining_sub_periods - + # Total taxable earnings with additional earnings with full tax full_tax_on_additional_earnings = 0.0 if current_additional_earnings_with_full_tax: @@ -622,7 +657,7 @@ class SalarySlip(TransactionBase): select sum(sd.amount) from `tabSalary Detail` sd join `tabSalary Slip` ss on sd.parent=ss.name - where + where sd.parentfield='earnings' and sd.is_tax_applicable=1 and is_flexible_benefit=0 @@ -841,7 +876,7 @@ class SalarySlip(TransactionBase): if flt(d.max_taxable_income) and flt(d.max_taxable_income) < tax_amount: continue - + tax_amount += tax_amount * flt(d.percent) / 100 return tax_amount @@ -955,13 +990,13 @@ class SalarySlip(TransactionBase): def email_salary_slip(self): receiver = frappe.db.get_value("Employee", self.employee, "prefered_email") - hr_settings = frappe.get_single("HR Settings") + payroll_settings = frappe.get_single("Payroll Settings") message = "Please see attachment" password = None - if hr_settings.encrypt_salary_slips_in_emails: - password = generate_password_for_pdf(hr_settings.password_policy, self.employee) + if payroll_settings.encrypt_salary_slips_in_emails: + password = generate_password_for_pdf(payroll_settings.password_policy, self.employee) message += """
Note: Your salary slip is password protected, - the password to unlock the PDF is of the format {0}. """.format(hr_settings.password_policy) + the password to unlock the PDF is of the format {0}. """.format(payroll_settings.password_policy) if receiver: email_args = { @@ -1004,8 +1039,9 @@ class SalarySlip(TransactionBase): self.calculate_net_pay() def pull_emp_details(self): - emp = frappe.db.get_value("Employee", self.employee, ["bank_name", "bank_ac_no"], as_dict=1) + emp = frappe.db.get_value("Employee", self.employee, ["bank_name", "bank_ac_no", "salary_mode"], as_dict=1) if emp: + self.mode_of_payment = emp.salary_mode self.bank_name = emp.bank_name self.bank_account_no = emp.bank_ac_no diff --git a/erpnext/hr/doctype/salary_slip/salary_slip_list.js b/erpnext/payroll/doctype/salary_slip/salary_slip_list.js similarity index 100% rename from erpnext/hr/doctype/salary_slip/salary_slip_list.js rename to erpnext/payroll/doctype/salary_slip/salary_slip_list.js diff --git a/erpnext/hr/doctype/salary_slip/test_salary_slip.js b/erpnext/payroll/doctype/salary_slip/test_salary_slip.js similarity index 100% rename from erpnext/hr/doctype/salary_slip/test_salary_slip.js rename to erpnext/payroll/doctype/salary_slip/test_salary_slip.js diff --git a/erpnext/hr/doctype/salary_slip/test_salary_slip.py b/erpnext/payroll/doctype/salary_slip/test_salary_slip.py similarity index 94% rename from erpnext/hr/doctype/salary_slip/test_salary_slip.py rename to erpnext/payroll/doctype/salary_slip/test_salary_slip.py index 3eff738ec8..f42b9ad11d 100644 --- a/erpnext/hr/doctype/salary_slip/test_salary_slip.py +++ b/erpnext/payroll/doctype/salary_slip/test_salary_slip.py @@ -10,17 +10,17 @@ import random from erpnext.accounts.utils import get_fiscal_year from frappe.utils.make_random import get_random from frappe.utils import getdate, nowdate, add_days, add_months, flt, get_first_day, get_last_day -from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip -from erpnext.hr.doctype.payroll_entry.payroll_entry import get_month_details +from erpnext.payroll.doctype.salary_structure.salary_structure import make_salary_slip +from erpnext.payroll.doctype.payroll_entry.payroll_entry import get_month_details from erpnext.hr.doctype.employee.test_employee import make_employee -from erpnext.hr.doctype.employee_tax_exemption_declaration.test_employee_tax_exemption_declaration \ +from erpnext.payroll.doctype.employee_tax_exemption_declaration.test_employee_tax_exemption_declaration \ import create_payroll_period, create_exemption_category class TestSalarySlip(unittest.TestCase): def setUp(self): setup_test() def tearDown(self): - frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0) + frappe.db.set_value("Payroll Settings", None, "include_holidays_in_total_working_days", 0) frappe.set_user("Administrator") def test_payment_days_based_on_attendance(self): @@ -28,8 +28,8 @@ class TestSalarySlip(unittest.TestCase): no_of_days = self.get_no_of_days() # Payroll based on attendance - frappe.db.set_value("HR Settings", None, "payroll_based_on", "Attendance") - frappe.db.set_value("HR Settings", None, "daily_wages_fraction_for_half_day", 0.75) + frappe.db.set_value("Payroll Settings", None, "payroll_based_on", "Attendance") + frappe.db.set_value("Payroll Settings", None, "daily_wages_fraction_for_half_day", 0.75) emp_id = make_employee("test_for_attendance@salary.com") frappe.db.set_value("Employee", emp_id, {"relieving_date": None, "status": "Active"}) @@ -47,7 +47,7 @@ class TestSalarySlip(unittest.TestCase): """, (month_start_date, month_end_date))[0][0] mark_attendance(emp_id, first_sunday, 'Absent', ignore_validate=True) # invalid lwp - mark_attendance(emp_id, add_days(first_sunday, 1), 'Absent', ignore_validate=True) # valid lwp + mark_attendance(emp_id, add_days(first_sunday, 1), 'Absent', ignore_validate=True) # counted as absent mark_attendance(emp_id, add_days(first_sunday, 2), 'Half Day', leave_type='Leave Without Pay', ignore_validate=True) # valid 0.75 lwp mark_attendance(emp_id, add_days(first_sunday, 3), 'On Leave', leave_type='Leave Without Pay', ignore_validate=True) # valid lwp mark_attendance(emp_id, add_days(first_sunday, 4), 'On Leave', leave_type='Casual Leave', ignore_validate=True) # invalid lwp @@ -55,7 +55,8 @@ class TestSalarySlip(unittest.TestCase): ss = make_employee_salary_slip("test_for_attendance@salary.com", "Monthly") - self.assertEqual(ss.leave_without_pay, 2.25) + self.assertEqual(ss.leave_without_pay, 1.25) + self.assertEqual(ss.absent_days, 1) days_in_month = no_of_days[0] no_of_holidays = no_of_days[1] @@ -63,17 +64,17 @@ class TestSalarySlip(unittest.TestCase): self.assertEqual(ss.payment_days, days_in_month - no_of_holidays - 2.25) #Gross pay calculation based on attendances - gross_pay = 78000 - ((78000 / (days_in_month - no_of_holidays)) * flt(ss.leave_without_pay)) + gross_pay = 78000 - ((78000 / (days_in_month - no_of_holidays)) * flt(ss.leave_without_pay + ss.absent_days)) self.assertEqual(ss.gross_pay, gross_pay) - frappe.db.set_value("HR Settings", None, "payroll_based_on", "Leave") + frappe.db.set_value("Payroll Settings", None, "payroll_based_on", "Leave") def test_payment_days_based_on_leave_application(self): no_of_days = self.get_no_of_days() # Payroll based on attendance - frappe.db.set_value("HR Settings", None, "payroll_based_on", "Leave") + frappe.db.set_value("Payroll Settings", None, "payroll_based_on", "Leave") emp_id = make_employee("test_for_attendance@salary.com") frappe.db.set_value("Employee", emp_id, {"relieving_date": None, "status": "Active"}) @@ -106,11 +107,11 @@ class TestSalarySlip(unittest.TestCase): self.assertEqual(ss.gross_pay, gross_pay) - frappe.db.set_value("HR Settings", None, "payroll_based_on", "Leave") + frappe.db.set_value("Payroll Settings", None, "payroll_based_on", "Leave") 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) + frappe.db.set_value("Payroll Settings", None, "include_holidays_in_total_working_days", 1) 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) @@ -126,7 +127,7 @@ class TestSalarySlip(unittest.TestCase): 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) + frappe.db.set_value("Payroll Settings", None, "include_holidays_in_total_working_days", 0) 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) @@ -144,7 +145,7 @@ class TestSalarySlip(unittest.TestCase): 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", 1) + frappe.db.set_value("Payroll Settings", None, "include_holidays_in_total_working_days", 1) # set joinng date in the same month make_employee("test_employee@salary.com") @@ -200,7 +201,7 @@ class TestSalarySlip(unittest.TestCase): def test_email_salary_slip(self): frappe.db.sql("delete from `tabEmail Queue`") - frappe.db.set_value("HR Settings", None, "email_salary_slip_to_employee", 1) + frappe.db.set_value("Payroll Settings", None, "email_salary_slip_to_employee", 1) make_employee("test_employee@salary.com") ss = make_employee_salary_slip("test_employee@salary.com", "Monthly") @@ -270,7 +271,7 @@ class TestSalarySlip(unittest.TestCase): # as per assigned salary structure 40500 in monthly salary so 236000*5/100/12 frappe.db.sql("""delete from `tabPayroll Period`""") frappe.db.sql("""delete from `tabSalary Component`""") - + payroll_period = create_payroll_period() create_tax_slab(payroll_period, allow_tax_exemption=True) @@ -287,7 +288,7 @@ class TestSalarySlip(unittest.TestCase): for doc in delete_docs: frappe.db.sql("delete from `tab%s` where employee='%s'" % (doc, employee)) - from erpnext.hr.doctype.salary_structure.test_salary_structure import \ + from erpnext.payroll.doctype.salary_structure.test_salary_structure import \ make_salary_structure, create_salary_structure_assignment salary_structure = make_salary_structure("Stucture to test tax", "Monthly", other_details={"max_benefits": 100000}, test_tax=True) @@ -378,7 +379,7 @@ class TestSalarySlip(unittest.TestCase): return [no_of_days_in_month[1], no_of_holidays_in_month] def make_employee_salary_slip(user, payroll_frequency, salary_structure=None): - from erpnext.hr.doctype.salary_structure.test_salary_structure import make_salary_structure + from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure if not salary_structure: salary_structure = payroll_frequency + " Salary Structure Test for Salary Slip" @@ -699,7 +700,7 @@ def setup_test(): make_holiday_list() frappe.db.set_value("Company", erpnext.get_default_company(), "default_holiday_list", "Salary Slip Test Holiday List") - frappe.db.set_value("HR Settings", None, "email_salary_slip_to_employee", 0) + frappe.db.set_value("Payroll Settings", None, "email_salary_slip_to_employee", 0) frappe.db.set_value('HR Settings', None, 'leave_status_notification_template', None) frappe.db.set_value('HR Settings', None, 'leave_approval_notification_template', None) diff --git a/erpnext/hr/doctype/taxable_salary_slab/__init__.py b/erpnext/payroll/doctype/salary_slip_timesheet/__init__.py similarity index 100% rename from erpnext/hr/doctype/taxable_salary_slab/__init__.py rename to erpnext/payroll/doctype/salary_slip_timesheet/__init__.py diff --git a/erpnext/payroll/doctype/salary_slip_timesheet/salary_slip_timesheet.json b/erpnext/payroll/doctype/salary_slip_timesheet/salary_slip_timesheet.json new file mode 100644 index 0000000000..9930c53ec9 --- /dev/null +++ b/erpnext/payroll/doctype/salary_slip_timesheet/salary_slip_timesheet.json @@ -0,0 +1,40 @@ +{ + "actions": [], + "creation": "2016-06-14 19:22:29.811658", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "time_sheet", + "working_hours" + ], + "fields": [ + { + "fieldname": "time_sheet", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Time Sheet", + "options": "Timesheet", + "reqd": 1 + }, + { + "fieldname": "working_hours", + "fieldtype": "Float", + "in_list_view": 1, + "label": "Working Hours", + "no_copy": 1, + "read_only": 1 + } + ], + "istable": 1, + "links": [], + "modified": "2020-06-22 23:27:43.463532", + "modified_by": "Administrator", + "module": "Payroll", + "name": "Salary Slip Timesheet", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC" +} \ No newline at end of file diff --git a/erpnext/hr/doctype/salary_slip_timesheet/salary_slip_timesheet.py b/erpnext/payroll/doctype/salary_slip_timesheet/salary_slip_timesheet.py similarity index 72% rename from erpnext/hr/doctype/salary_slip_timesheet/salary_slip_timesheet.py rename to erpnext/payroll/doctype/salary_slip_timesheet/salary_slip_timesheet.py index 1bbfc53a32..7adb12e83a 100644 --- a/erpnext/hr/doctype/salary_slip_timesheet/salary_slip_timesheet.py +++ b/erpnext/payroll/doctype/salary_slip_timesheet/salary_slip_timesheet.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors # For license information, please see license.txt from __future__ import unicode_literals -import frappe +# import frappe from frappe.model.document import Document class SalarySlipTimesheet(Document): diff --git a/erpnext/hr/doctype/salary_structure/README.md b/erpnext/payroll/doctype/salary_structure/README.md similarity index 100% rename from erpnext/hr/doctype/salary_structure/README.md rename to erpnext/payroll/doctype/salary_structure/README.md diff --git a/erpnext/hr/doctype/salary_structure/__init__.py b/erpnext/payroll/doctype/salary_structure/__init__.py similarity index 100% rename from erpnext/hr/doctype/salary_structure/__init__.py rename to erpnext/payroll/doctype/salary_structure/__init__.py diff --git a/erpnext/payroll/doctype/salary_structure/condition_and_formula_help.html b/erpnext/payroll/doctype/salary_structure/condition_and_formula_help.html new file mode 100644 index 0000000000..e59d78d1b8 --- /dev/null +++ b/erpnext/payroll/doctype/salary_structure/condition_and_formula_help.html @@ -0,0 +1,47 @@ +

Variables

+ + +

Examples for Conditions and formula

+ \ No newline at end of file diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.js b/erpnext/payroll/doctype/salary_structure/salary_structure.js similarity index 91% rename from erpnext/hr/doctype/salary_structure/salary_structure.js rename to erpnext/payroll/doctype/salary_structure/salary_structure.js index 7748403513..ca458f976f 100755 --- a/erpnext/hr/doctype/salary_structure/salary_structure.js +++ b/erpnext/payroll/doctype/salary_structure/salary_structure.js @@ -14,7 +14,30 @@ cur_frm.cscript.onload = function(doc, dt, dn){ frappe.ui.form.on('Salary Structure', { onload: function(frm) { - frm.toggle_reqd(['payroll_frequency'], !frm.doc.salary_slip_based_on_timesheet), + + let help_button = $(` + Condition and Formula Help + `).click(()=>{ + + let d = new frappe.ui.Dialog({ + title: 'Condition and Formula Help', + fields: [ + { + fieldname: 'msg_wrapper', + fieldtype: 'HTML' + } + ] + }); + + let message_html = frappe.render_template("condition_and_formula_help") + + d.fields_dict.msg_wrapper.$wrapper.append(message_html) + + d.show() + }); + frm.get_field("conditions_and_formula_variable_and_example").$wrapper.append(frm.doc.filters_html).append(help_button) + + frm.toggle_reqd(['payroll_frequency'], !frm.doc.salary_slip_based_on_timesheet) frm.set_query("salary_component", "earnings", function() { return { @@ -114,7 +137,7 @@ frappe.ui.form.on('Salary Structure', { preview_salary_slip: function(frm) { frappe.call({ - method: "erpnext.hr.doctype.salary_structure.salary_structure.get_employees", + method: "erpnext.payroll.doctype.salary_structure.salary_structure.get_employees", args: { salary_structure: frm.doc.name }, @@ -155,7 +178,7 @@ frappe.ui.form.on('Salary Structure', { open_salary_slip: function(frm, employee){ var print_format = frm.doc.salary_slip_based_on_timesheet ? "Salary Slip based on Timesheet" : "Salary Slip Standard"; frappe.call({ - method: "erpnext.hr.doctype.salary_structure.salary_structure.make_salary_slip", + method: "erpnext.payroll.doctype.salary_structure.salary_structure.make_salary_slip", args: { source_name: frm.doc.name, employee: employee, diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.json b/erpnext/payroll/doctype/salary_structure/salary_structure.json similarity index 71% rename from erpnext/hr/doctype/salary_structure/salary_structure.json rename to erpnext/payroll/doctype/salary_structure/salary_structure.json index 58c4044093..5f94929f0b 100644 --- a/erpnext/hr/doctype/salary_structure/salary_structure.json +++ b/erpnext/payroll/doctype/salary_structure/salary_structure.json @@ -22,10 +22,9 @@ "leave_encashment_amount_per_day", "max_benefits", "earning_deduction", - "earning", "earnings", - "deduction", "deductions", + "conditions_and_formula_variable_and_example", "net_pay_detail", "column_break2", "total_earning", @@ -44,17 +43,23 @@ "label": "Company", "options": "Company", "remember_last_selected_value": 1, - "reqd": 1 + "reqd": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "letter_head", "fieldtype": "Link", "label": "Letter Head", - "options": "Letter Head" + "options": "Letter Head", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "column_break1", "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1, "width": "50%" }, { @@ -67,7 +72,9 @@ "oldfieldname": "is_active", "oldfieldtype": "Select", "options": "\nYes\nNo", - "reqd": 1 + "reqd": 1, + "show_days": 1, + "show_seconds": 1 }, { "default": "Monthly", @@ -75,7 +82,9 @@ "fieldname": "payroll_frequency", "fieldtype": "Select", "label": "Payroll Frequency", - "options": "\nMonthly\nFortnightly\nBimonthly\nWeekly\nDaily" + "options": "\nMonthly\nFortnightly\nBimonthly\nWeekly\nDaily", + "show_days": 1, + "show_seconds": 1 }, { "default": "No", @@ -86,46 +95,62 @@ "no_copy": 1, "options": "Yes\nNo", "print_hide": 1, - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "time_sheet_earning_detail", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "show_days": 1, + "show_seconds": 1 }, { "default": "0", "fieldname": "salary_slip_based_on_timesheet", "fieldtype": "Check", - "label": "Salary Slip Based on Timesheet" + "label": "Salary Slip Based on Timesheet", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "column_break_17", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 }, { "description": "Salary Component for timesheet based payroll.", "fieldname": "salary_component", "fieldtype": "Link", "label": "Salary Component", - "options": "Salary Component" + "options": "Salary Component", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "hour_rate", "fieldtype": "Currency", "label": "Hour Rate", - "options": "Company:company:default_currency" + "options": "Company:company:default_currency", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "leave_encashment_amount_per_day", "fieldtype": "Currency", "label": "Leave Encashment Amount Per Day", - "options": "Company:company:default_currency" + "options": "Company:company:default_currency", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "max_benefits", "fieldtype": "Currency", "label": "Max Benefits (Amount)", - "options": "Company:company:default_currency" + "options": "Company:company:default_currency", + "show_days": 1, + "show_seconds": 1 }, { "description": "Salary breakup based on Earning and Deduction.", @@ -133,15 +158,9 @@ "fieldtype": "Section Break", "oldfieldname": "earning_deduction", "oldfieldtype": "Section Break", - "precision": "2" - }, - { - "fieldname": "earning", - "fieldtype": "Section Break", - "label": "Earning", - "oldfieldname": "col_brk2", - "oldfieldtype": "Column Break", - "width": "50%" + "precision": "2", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "earnings", @@ -149,15 +168,9 @@ "label": "Earnings", "oldfieldname": "earning_details", "oldfieldtype": "Table", - "options": "Salary Detail" - }, - { - "fieldname": "deduction", - "fieldtype": "Section Break", - "label": "Deduction", - "oldfieldname": "col_brk3", - "oldfieldtype": "Column Break", - "width": "50%" + "options": "Salary Detail", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "deductions", @@ -165,16 +178,22 @@ "label": "Deductions", "oldfieldname": "deduction_details", "oldfieldtype": "Table", - "options": "Salary Detail" + "options": "Salary Detail", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "net_pay_detail", "fieldtype": "Section Break", - "options": "Simple" + "options": "Simple", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "column_break2", "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1, "width": "50%" }, { @@ -185,7 +204,9 @@ "oldfieldname": "total_earning", "oldfieldtype": "Currency", "options": "Company:company:default_currency", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "total_deduction", @@ -195,7 +216,9 @@ "oldfieldname": "total_deduction", "oldfieldtype": "Currency", "options": "Company:company:default_currency", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "net_pay", @@ -203,28 +226,38 @@ "hidden": 1, "label": "Net Pay", "options": "Company:company:default_currency", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "account", "fieldtype": "Section Break", - "label": "Account" + "label": "Account", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "mode_of_payment", "fieldtype": "Link", "label": "Mode of Payment", - "options": "Mode of Payment" + "options": "Mode of Payment", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "column_break_28", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "payment_account", "fieldtype": "Link", "label": "Payment Account", - "options": "Account" + "options": "Account", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "amended_from", @@ -233,16 +266,25 @@ "no_copy": 1, "options": "Salary Structure", "print_hide": 1, - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 + }, + { + "fieldname": "conditions_and_formula_variable_and_example", + "fieldtype": "HTML", + "label": "Conditions and Formula variable and example", + "show_days": 1, + "show_seconds": 1 } ], "icon": "fa fa-file-text", "idx": 1, "is_submittable": 1, "links": [], - "modified": "2019-12-31 16:34:35.087658", + "modified": "2020-06-22 17:07:26.129355", "modified_by": "Administrator", - "module": "HR", + "module": "Payroll", "name": "Salary Structure", "owner": "Administrator", "permissions": [ diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.py b/erpnext/payroll/doctype/salary_structure/salary_structure.py similarity index 100% rename from erpnext/hr/doctype/salary_structure/salary_structure.py rename to erpnext/payroll/doctype/salary_structure/salary_structure.py diff --git a/erpnext/hr/doctype/salary_structure/salary_structure_dashboard.py b/erpnext/payroll/doctype/salary_structure/salary_structure_dashboard.py similarity index 100% rename from erpnext/hr/doctype/salary_structure/salary_structure_dashboard.py rename to erpnext/payroll/doctype/salary_structure/salary_structure_dashboard.py diff --git a/erpnext/hr/doctype/salary_structure/test_salary_structure.js b/erpnext/payroll/doctype/salary_structure/test_salary_structure.js similarity index 100% rename from erpnext/hr/doctype/salary_structure/test_salary_structure.js rename to erpnext/payroll/doctype/salary_structure/test_salary_structure.js diff --git a/erpnext/hr/doctype/salary_structure/test_salary_structure.py b/erpnext/payroll/doctype/salary_structure/test_salary_structure.py similarity index 94% rename from erpnext/hr/doctype/salary_structure/test_salary_structure.py rename to erpnext/payroll/doctype/salary_structure/test_salary_structure.py index eb5311e3b8..e04fda8120 100644 --- a/erpnext/hr/doctype/salary_structure/test_salary_structure.py +++ b/erpnext/payroll/doctype/salary_structure/test_salary_structure.py @@ -7,11 +7,11 @@ import unittest import erpnext from frappe.utils.make_random import get_random from frappe.utils import nowdate, add_days, add_years, getdate, add_months -from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip -from erpnext.hr.doctype.salary_slip.test_salary_slip import make_earning_salary_component,\ +from erpnext.payroll.doctype.salary_structure.salary_structure import make_salary_slip +from erpnext.payroll.doctype.salary_slip.test_salary_slip import make_earning_salary_component,\ make_deduction_salary_component, make_employee_salary_slip, create_tax_slab from erpnext.hr.doctype.employee.test_employee import make_employee -from erpnext.hr.doctype.employee_tax_exemption_declaration.test_employee_tax_exemption_declaration import create_payroll_period +from erpnext.payroll.doctype.employee_tax_exemption_declaration.test_employee_tax_exemption_declaration import create_payroll_period test_dependencies = ["Fiscal Year"] @@ -62,7 +62,7 @@ class TestSalaryStructure(unittest.TestCase): self.assertEqual(assignment.base * 0.2, ss.deductions[0].amount) def test_amount_totals(self): - frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0) + frappe.db.set_value("Payroll Settings", None, "include_holidays_in_total_working_days", 0) sal_slip = frappe.get_value("Salary Slip", {"employee_name":"test_employee_2@salary.com"}) if not sal_slip: sal_slip = make_employee_salary_slip("test_employee_2@salary.com", "Monthly", "Salary Structure Sample") @@ -128,7 +128,7 @@ def make_salary_structure(salary_structure, payroll_frequency, employee=None, do salary_structure_doc.insert() if not dont_submit: salary_structure_doc.submit() - + else: salary_structure_doc = frappe.get_doc("Salary Structure", salary_structure) diff --git a/erpnext/hr/notification/retention_bonus/__init__.py b/erpnext/payroll/doctype/salary_structure_assignment/__init__.py similarity index 100% rename from erpnext/hr/notification/retention_bonus/__init__.py rename to erpnext/payroll/doctype/salary_structure_assignment/__init__.py diff --git a/erpnext/hr/doctype/salary_structure_assignment/salary_structure_assignment.js b/erpnext/payroll/doctype/salary_structure_assignment/salary_structure_assignment.js similarity index 100% rename from erpnext/hr/doctype/salary_structure_assignment/salary_structure_assignment.js rename to erpnext/payroll/doctype/salary_structure_assignment/salary_structure_assignment.js diff --git a/erpnext/hr/doctype/salary_structure_assignment/salary_structure_assignment.json b/erpnext/payroll/doctype/salary_structure_assignment/salary_structure_assignment.json similarity index 98% rename from erpnext/hr/doctype/salary_structure_assignment/salary_structure_assignment.json rename to erpnext/payroll/doctype/salary_structure_assignment/salary_structure_assignment.json index 0098aa8ec8..c84e034c72 100644 --- a/erpnext/hr/doctype/salary_structure_assignment/salary_structure_assignment.json +++ b/erpnext/payroll/doctype/salary_structure_assignment/salary_structure_assignment.json @@ -124,9 +124,9 @@ ], "is_submittable": 1, "links": [], - "modified": "2020-04-25 18:24:23.617088", + "modified": "2020-06-22 19:58:09.964692", "modified_by": "Administrator", - "module": "HR", + "module": "Payroll", "name": "Salary Structure Assignment", "owner": "Administrator", "permissions": [ diff --git a/erpnext/hr/doctype/salary_structure_assignment/salary_structure_assignment.py b/erpnext/payroll/doctype/salary_structure_assignment/salary_structure_assignment.py similarity index 100% rename from erpnext/hr/doctype/salary_structure_assignment/salary_structure_assignment.py rename to erpnext/payroll/doctype/salary_structure_assignment/salary_structure_assignment.py diff --git a/erpnext/hr/doctype/salary_structure_assignment/test_salary_structure_assignment.js b/erpnext/payroll/doctype/salary_structure_assignment/test_salary_structure_assignment.js similarity index 100% rename from erpnext/hr/doctype/salary_structure_assignment/test_salary_structure_assignment.js rename to erpnext/payroll/doctype/salary_structure_assignment/test_salary_structure_assignment.js diff --git a/erpnext/hr/doctype/salary_structure_assignment/test_salary_structure_assignment.py b/erpnext/payroll/doctype/salary_structure_assignment/test_salary_structure_assignment.py similarity index 100% rename from erpnext/hr/doctype/salary_structure_assignment/test_salary_structure_assignment.py rename to erpnext/payroll/doctype/salary_structure_assignment/test_salary_structure_assignment.py diff --git a/erpnext/hr/print_format/salary_slip_based_on_timesheet/__init__.py b/erpnext/payroll/doctype/taxable_salary_slab/__init__.py similarity index 100% rename from erpnext/hr/print_format/salary_slip_based_on_timesheet/__init__.py rename to erpnext/payroll/doctype/taxable_salary_slab/__init__.py diff --git a/erpnext/payroll/doctype/taxable_salary_slab/taxable_salary_slab.json b/erpnext/payroll/doctype/taxable_salary_slab/taxable_salary_slab.json new file mode 100644 index 0000000000..ce9512f898 --- /dev/null +++ b/erpnext/payroll/doctype/taxable_salary_slab/taxable_salary_slab.json @@ -0,0 +1,64 @@ +{ + "actions": [], + "creation": "2018-04-13 17:42:13.516032", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "from_amount", + "to_amount", + "percent_deduction", + "condition", + "column_break_5", + "html_6" + ], + "fields": [ + { + "fieldname": "from_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "From Amount", + "reqd": 1 + }, + { + "fieldname": "to_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "To Amount" + }, + { + "fieldname": "percent_deduction", + "fieldtype": "Percent", + "in_list_view": 1, + "label": "Percent Deduction", + "reqd": 1 + }, + { + "fieldname": "condition", + "fieldtype": "Code", + "in_list_view": 1, + "label": "Condition" + }, + { + "fieldname": "column_break_5", + "fieldtype": "Column Break" + }, + { + "fieldname": "html_6", + "fieldtype": "HTML", + "options": "

Condition Examples

\n
    \n
  1. Applying tax if employee born between 31-12-1937 and 01-01-1958 (Employees aged 60 to 80)
    \nCondition: date_of_birth>date(1937, 12, 31) and date_of_birth<date(1958, 01, 01)

  2. Applying tax by employee gender
    \nCondition: gender==\"Male\"

  3. \n
  4. Applying tax by Salary Component
    \nCondition: base > 10000
" + } + ], + "istable": 1, + "links": [], + "modified": "2020-06-22 23:32:47.253106", + "modified_by": "Administrator", + "module": "Payroll", + "name": "Taxable Salary Slab", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/hr/doctype/taxable_salary_slab/taxable_salary_slab.py b/erpnext/payroll/doctype/taxable_salary_slab/taxable_salary_slab.py similarity index 71% rename from erpnext/hr/doctype/taxable_salary_slab/taxable_salary_slab.py rename to erpnext/payroll/doctype/taxable_salary_slab/taxable_salary_slab.py index 23e5ffbe62..49c52557db 100644 --- a/erpnext/hr/doctype/taxable_salary_slab/taxable_salary_slab.py +++ b/erpnext/payroll/doctype/taxable_salary_slab/taxable_salary_slab.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors # For license information, please see license.txt from __future__ import unicode_literals -import frappe +# import frappe from frappe.model.document import Document class TaxableSalarySlab(Document): diff --git a/erpnext/payroll/module_onboarding/payroll/payroll.json b/erpnext/payroll/module_onboarding/payroll/payroll.json new file mode 100644 index 0000000000..a4ea53640e --- /dev/null +++ b/erpnext/payroll/module_onboarding/payroll/payroll.json @@ -0,0 +1,51 @@ +{ + "allow_roles": [ + { + "role": "HR Manager" + }, + { + "role": "HR User" + } + ], + "creation": "2020-06-01 12:10:52.560472", + "docstatus": 0, + "doctype": "Module Onboarding", + "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/human-resources/payroll-entry", + "idx": 0, + "is_complete": 0, + "modified": "2020-06-04 16:35:30.650792", + "modified_by": "Administrator", + "module": "Payroll", + "name": "Payroll", + "owner": "Administrator", + "steps": [ + { + "step": "Create Employee" + }, + { + "step": "Create Salary Component" + }, + { + "step": "Create Payroll Period" + }, + { + "step": "Create Income Tax Slab" + }, + { + "step": "Create Salary Structure" + }, + { + "step": "Assign Salary Structure" + }, + { + "step": "Create Salary Slip" + }, + { + "step": "Payroll Settings" + } + ], + "subtitle": "Salary, Compensations and more.", + "success_message": "The Payroll is all set up!", + "title": "Let's Setup the Payroll Module. ", + "user_can_dismiss": 1 +} \ No newline at end of file diff --git a/erpnext/payroll/notification/as b/erpnext/payroll/notification/as new file mode 100644 index 0000000000..7a39557261 --- /dev/null +++ b/erpnext/payroll/notification/as @@ -0,0 +1 @@ +update from `tabNotification` set module='Payroll' where name = "Retention Bonus" \ No newline at end of file diff --git a/erpnext/hr/print_format/salary_slip_standard/__init__.py b/erpnext/payroll/notification/retention_bonus/__init__.py similarity index 100% rename from erpnext/hr/print_format/salary_slip_standard/__init__.py rename to erpnext/payroll/notification/retention_bonus/__init__.py diff --git a/erpnext/hr/notification/retention_bonus/retention_bonus.json b/erpnext/payroll/notification/retention_bonus/retention_bonus.json similarity index 86% rename from erpnext/hr/notification/retention_bonus/retention_bonus.json rename to erpnext/payroll/notification/retention_bonus/retention_bonus.json index cbc8e2d078..50db0338c4 100644 --- a/erpnext/hr/notification/retention_bonus/retention_bonus.json +++ b/erpnext/payroll/notification/retention_bonus/retention_bonus.json @@ -13,10 +13,10 @@ "is_standard": 1, "message": "

{{ _(\"Hello\") }},

\n\n

{{ _(\"Retention Bonus for\") }} {{ doc.employee_name }} {{ _(\"due on\") }} {{ doc.bonus_payment_date }}

", "modified": "2018-05-15 19:00:24.294418", - "modified_by": "ranjith@earthianslive.com", - "module": "HR", + "modified_by": "Administrator", + "module": "Payroll", "name": "Retention Bonus", - "owner": "ranjith@earthianslive.com", + "owner": "Administrator", "recipients": [ { "email_by_role": "HR Manager" diff --git a/erpnext/hr/notification/retention_bonus/retention_bonus.md b/erpnext/payroll/notification/retention_bonus/retention_bonus.md similarity index 100% rename from erpnext/hr/notification/retention_bonus/retention_bonus.md rename to erpnext/payroll/notification/retention_bonus/retention_bonus.md diff --git a/erpnext/hr/notification/retention_bonus/retention_bonus.py b/erpnext/payroll/notification/retention_bonus/retention_bonus.py similarity index 100% rename from erpnext/hr/notification/retention_bonus/retention_bonus.py rename to erpnext/payroll/notification/retention_bonus/retention_bonus.py diff --git a/erpnext/payroll/onboarding_step/assign_salary_structure/assign_salary_structure.json b/erpnext/payroll/onboarding_step/assign_salary_structure/assign_salary_structure.json new file mode 100644 index 0000000000..8a07b10276 --- /dev/null +++ b/erpnext/payroll/onboarding_step/assign_salary_structure/assign_salary_structure.json @@ -0,0 +1,19 @@ +{ + "action": "Create Entry", + "creation": "2020-06-01 11:58:43.927590", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_mandatory": 1, + "is_single": 0, + "is_skipped": 0, + "modified": "2020-06-01 11:58:43.927590", + "modified_by": "Administrator", + "name": "Assign Salary Structure", + "owner": "Administrator", + "reference_document": "Salary Structure Assignment", + "show_full_form": 1, + "title": "Assign Salary Structure", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/payroll/onboarding_step/create_employee/create_employee.json b/erpnext/payroll/onboarding_step/create_employee/create_employee.json new file mode 100644 index 0000000000..5839ae6ca4 --- /dev/null +++ b/erpnext/payroll/onboarding_step/create_employee/create_employee.json @@ -0,0 +1,19 @@ +{ + "action": "Create Entry", + "creation": "2020-05-14 11:43:25.561152", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_mandatory": 1, + "is_single": 0, + "is_skipped": 0, + "modified": "2020-05-14 12:26:28.629074", + "modified_by": "Administrator", + "name": "Create Employee", + "owner": "Administrator", + "reference_document": "Employee", + "show_full_form": 0, + "title": "Create Employee", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/payroll/onboarding_step/create_income_tax_slab/create_income_tax_slab.json b/erpnext/payroll/onboarding_step/create_income_tax_slab/create_income_tax_slab.json new file mode 100644 index 0000000000..faada7e411 --- /dev/null +++ b/erpnext/payroll/onboarding_step/create_income_tax_slab/create_income_tax_slab.json @@ -0,0 +1,19 @@ +{ + "action": "Create Entry", + "creation": "2020-06-01 11:54:54.823796", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_mandatory": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2020-06-01 11:54:54.823796", + "modified_by": "Administrator", + "name": "Create Income Tax Slab", + "owner": "Administrator", + "reference_document": "Income Tax Slab", + "show_full_form": 1, + "title": "Create Income Tax Slab", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/payroll/onboarding_step/create_payroll_period/create_payroll_period.json b/erpnext/payroll/onboarding_step/create_payroll_period/create_payroll_period.json new file mode 100644 index 0000000000..4bae67546c --- /dev/null +++ b/erpnext/payroll/onboarding_step/create_payroll_period/create_payroll_period.json @@ -0,0 +1,19 @@ +{ + "action": "Create Entry", + "creation": "2020-06-01 11:53:54.553947", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_mandatory": 1, + "is_single": 0, + "is_skipped": 0, + "modified": "2020-06-01 11:53:54.553947", + "modified_by": "Administrator", + "name": "Create Payroll Period", + "owner": "Administrator", + "reference_document": "Payroll Period", + "show_full_form": 0, + "title": "Create Payroll Period", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/payroll/onboarding_step/create_salary_component/create_salary_component.json b/erpnext/payroll/onboarding_step/create_salary_component/create_salary_component.json new file mode 100644 index 0000000000..002d819618 --- /dev/null +++ b/erpnext/payroll/onboarding_step/create_salary_component/create_salary_component.json @@ -0,0 +1,19 @@ +{ + "action": "Create Entry", + "creation": "2020-06-01 11:57:04.002073", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_mandatory": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2020-06-01 11:57:04.002073", + "modified_by": "Administrator", + "name": "Create Salary Component", + "owner": "Administrator", + "reference_document": "Salary Component", + "show_full_form": 1, + "title": "Create Salary Component", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/payroll/onboarding_step/create_salary_slip/create_salary_slip.json b/erpnext/payroll/onboarding_step/create_salary_slip/create_salary_slip.json new file mode 100644 index 0000000000..2aa31f485f --- /dev/null +++ b/erpnext/payroll/onboarding_step/create_salary_slip/create_salary_slip.json @@ -0,0 +1,19 @@ +{ + "action": "Create Entry", + "creation": "2020-06-01 11:59:29.972393", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_mandatory": 1, + "is_single": 0, + "is_skipped": 0, + "modified": "2020-06-01 11:59:29.972393", + "modified_by": "Administrator", + "name": "Create Salary Slip", + "owner": "Administrator", + "reference_document": "Salary Slip", + "show_full_form": 1, + "title": "Create Salary Slip", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/payroll/onboarding_step/create_salary_structure/create_salary_structure.json b/erpnext/payroll/onboarding_step/create_salary_structure/create_salary_structure.json new file mode 100644 index 0000000000..11d8327259 --- /dev/null +++ b/erpnext/payroll/onboarding_step/create_salary_structure/create_salary_structure.json @@ -0,0 +1,19 @@ +{ + "action": "Create Entry", + "creation": "2020-06-01 11:57:54.527808", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_mandatory": 1, + "is_single": 0, + "is_skipped": 0, + "modified": "2020-06-01 11:57:54.527808", + "modified_by": "Administrator", + "name": "Create Salary Structure", + "owner": "Administrator", + "reference_document": "Salary Structure", + "show_full_form": 1, + "title": "Create Salary Structure", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/payroll/onboarding_step/payroll_settings/payroll_settings.json b/erpnext/payroll/onboarding_step/payroll_settings/payroll_settings.json new file mode 100644 index 0000000000..946b8c8707 --- /dev/null +++ b/erpnext/payroll/onboarding_step/payroll_settings/payroll_settings.json @@ -0,0 +1,19 @@ +{ + "action": "Go to Page", + "creation": "2020-06-04 16:34:29.664917", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_mandatory": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2020-06-04 16:34:29.664917", + "modified_by": "Administrator", + "name": "Payroll Settings", + "owner": "Administrator", + "path": "#Form/Payroll Settings", + "show_full_form": 0, + "title": "Payroll Settings", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/hr/report/bank_remittance/__init__.py b/erpnext/payroll/print_format/salary_slip_based_on_timesheet/__init__.py similarity index 100% rename from erpnext/hr/report/bank_remittance/__init__.py rename to erpnext/payroll/print_format/salary_slip_based_on_timesheet/__init__.py diff --git a/erpnext/hr/print_format/salary_slip_based_on_timesheet/salary_slip_based_on_timesheet.json b/erpnext/payroll/print_format/salary_slip_based_on_timesheet/salary_slip_based_on_timesheet.json similarity index 100% rename from erpnext/hr/print_format/salary_slip_based_on_timesheet/salary_slip_based_on_timesheet.json rename to erpnext/payroll/print_format/salary_slip_based_on_timesheet/salary_slip_based_on_timesheet.json diff --git a/erpnext/hr/report/salary_register/__init__.py b/erpnext/payroll/print_format/salary_slip_standard/__init__.py similarity index 100% rename from erpnext/hr/report/salary_register/__init__.py rename to erpnext/payroll/print_format/salary_slip_standard/__init__.py diff --git a/erpnext/hr/print_format/salary_slip_standard/salary_slip_standard.json b/erpnext/payroll/print_format/salary_slip_standard/salary_slip_standard.json similarity index 100% rename from erpnext/hr/print_format/salary_slip_standard/salary_slip_standard.json rename to erpnext/payroll/print_format/salary_slip_standard/salary_slip_standard.json diff --git a/erpnext/stock/report/ordered_items_to_be_delivered/__init__.py b/erpnext/payroll/report/__init__.py similarity index 100% rename from erpnext/stock/report/ordered_items_to_be_delivered/__init__.py rename to erpnext/payroll/report/__init__.py diff --git a/erpnext/payroll/report/bank_remittance/__init__.py b/erpnext/payroll/report/bank_remittance/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/hr/report/bank_remittance/bank_remittance.js b/erpnext/payroll/report/bank_remittance/bank_remittance.js similarity index 68% rename from erpnext/hr/report/bank_remittance/bank_remittance.js rename to erpnext/payroll/report/bank_remittance/bank_remittance.js index 1e10f24301..6482ed3451 100644 --- a/erpnext/hr/report/bank_remittance/bank_remittance.js +++ b/erpnext/payroll/report/bank_remittance/bank_remittance.js @@ -5,12 +5,12 @@ frappe.query_reports["Bank Remittance"] = { "filters": [ { - "fieldname":"company", - "label": __("Company"), - "fieldtype": "Link", - "options": "Company", - "default": frappe.defaults.get_user_default("Company"), - "reqd": 1 + fieldname:"company", + label: __("Company"), + fieldtype: "Link", + options: "Company", + default: frappe.defaults.get_user_default("Company"), + reqd: 1 }, { fieldname:"from_date", diff --git a/erpnext/hr/report/bank_remittance/bank_remittance.json b/erpnext/payroll/report/bank_remittance/bank_remittance.json similarity index 87% rename from erpnext/hr/report/bank_remittance/bank_remittance.json rename to erpnext/payroll/report/bank_remittance/bank_remittance.json index b8aa4e98d2..2a697b2589 100644 --- a/erpnext/hr/report/bank_remittance/bank_remittance.json +++ b/erpnext/payroll/report/bank_remittance/bank_remittance.json @@ -7,9 +7,9 @@ "doctype": "Report", "idx": 0, "is_standard": "Yes", - "modified": "2019-04-26 16:57:52.558895", + "modified": "2020-05-28 00:08:08.097494", "modified_by": "Administrator", - "module": "HR", + "module": "Payroll", "name": "Bank Remittance", "owner": "Administrator", "prepared_report": 0, diff --git a/erpnext/hr/report/bank_remittance/bank_remittance.py b/erpnext/payroll/report/bank_remittance/bank_remittance.py similarity index 96% rename from erpnext/hr/report/bank_remittance/bank_remittance.py rename to erpnext/payroll/report/bank_remittance/bank_remittance.py index b2d2c53024..a35d8e550e 100644 --- a/erpnext/hr/report/bank_remittance/bank_remittance.py +++ b/erpnext/payroll/report/bank_remittance/bank_remittance.py @@ -125,7 +125,10 @@ def get_salary_slips(payroll_entries): # appending company debit accounts for slip in salary_slips: - slip["debit_acc_no"] = payroll_entry_map[slip.payroll_entry]['company_account'] + if slip.payroll_entry: + slip["debit_acc_no"] = payroll_entry_map[slip.payroll_entry]['company_account'] + else: + slip["debit_acc_no"] = None return salary_slips diff --git a/erpnext/payroll/report/income_tax_deductions/__init__.py b/erpnext/payroll/report/income_tax_deductions/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/payroll/report/income_tax_deductions/income_tax_deductions.js b/erpnext/payroll/report/income_tax_deductions/income_tax_deductions.js new file mode 100644 index 0000000000..4bbb7f6a1b --- /dev/null +++ b/erpnext/payroll/report/income_tax_deductions/income_tax_deductions.js @@ -0,0 +1,7 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.require("assets/erpnext/js/salary_slip_deductions_report_filters.js", function() { + frappe.query_reports["Income Tax Deductions"] = erpnext.salary_slip_deductions_report_filters; +}); \ No newline at end of file diff --git a/erpnext/payroll/report/income_tax_deductions/income_tax_deductions.json b/erpnext/payroll/report/income_tax_deductions/income_tax_deductions.json new file mode 100644 index 0000000000..cf80398f98 --- /dev/null +++ b/erpnext/payroll/report/income_tax_deductions/income_tax_deductions.json @@ -0,0 +1,30 @@ +{ + "add_total_row": 0, + "creation": "2020-05-30 00:07:56.744372", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "modified": "2020-05-30 00:07:56.744372", + "modified_by": "Administrator", + "module": "Payroll", + "name": "Income Tax Deductions", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Salary Slip", + "report_name": "Income Tax Deductions", + "report_type": "Script Report", + "roles": [ + { + "role": "HR User" + }, + { + "role": "HR Manager" + }, + { + "role": "Employee" + } + ] +} \ No newline at end of file diff --git a/erpnext/payroll/report/income_tax_deductions/income_tax_deductions.py b/erpnext/payroll/report/income_tax_deductions/income_tax_deductions.py new file mode 100644 index 0000000000..3bad5879bb --- /dev/null +++ b/erpnext/payroll/report/income_tax_deductions/income_tax_deductions.py @@ -0,0 +1,127 @@ +# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe, erpnext +from frappe import _ + +def execute(filters=None): + columns = get_columns(filters) + data = get_data(filters) + + return columns, data + +def get_columns(filters): + columns = [ + { + "label": _("Employee"), + "options": "Employee", + "fieldname": "employee", + "fieldtype": "Link", + "width": 200 + }, + { + "label": _("Employee Name"), + "options": "Employee", + "fieldname": "employee_name", + "fieldtype": "Link", + "width": 160 + }] + + if erpnext.get_region() == "India": + columns.append({ + "label": _("PAN Number"), + "fieldname": "pan_number", + "fieldtype": "Data", + "width": 140 + }) + + columns += [{ + "label": _("Income Tax Component"), + "fieldname": "it_comp", + "fieldtype": "Data", + "width": 170 + }, + { + "label": _("Income Tax Amount"), + "fieldname": "it_amount", + "fieldtype": "Currency", + "options": "currency", + "width": 140 + }, + { + "label": _("Gross Pay"), + "fieldname": "gross_pay", + "fieldtype": "Currency", + "options": "currency", + "width": 140 + }, + { + "label": _("Posting Date"), + "fieldname": "posting_date", + "fieldtype": "Date", + "width": 140 + } + ] + + return columns + +def get_conditions(filters): + conditions = [""] + + if filters.get("department"): + conditions.append("sal.department = '%s' " % (filters["department"]) ) + + if filters.get("branch"): + conditions.append("sal.branch = '%s' " % (filters["branch"]) ) + + if filters.get("company"): + conditions.append("sal.company = '%s' " % (filters["company"]) ) + + if filters.get("period"): + conditions.append("month(sal.start_date) = '%s' " % (filters["period"])) + + return " and ".join(conditions) + + +def get_data(filters): + + data = [] + + if erpnext.get_region() == "India": + employee_pan_dict = frappe._dict(frappe.db.sql(""" select employee, pan_number from `tabEmployee`""")) + + component_types = frappe.db.sql(""" select name from `tabSalary Component` + where is_income_tax_component = 1 """) + + component_types = [comp_type[0] for comp_type in component_types] + + conditions = get_conditions(filters) + + entry = frappe.db.sql(""" select sal.employee, sal.employee_name, sal.posting_date, ded.salary_component, ded.amount,sal.gross_pay + from `tabSalary Slip` sal, `tabSalary Detail` ded + where sal.name = ded.parent + and ded.parentfield = 'deductions' + and ded.parenttype = 'Salary Slip' + and sal.docstatus = 1 %s + and ded.salary_component in (%s) + """ % (conditions , ", ".join(['%s']*len(component_types))), tuple(component_types), as_dict=1) + + for d in entry: + + employee = { + "employee": d.employee, + "employee_name": d.employee_name, + "it_comp": d.salary_component, + "posting_date": d.posting_date, + # "pan_number": employee_pan_dict.get(d.employee), + "it_amount": d.amount, + "gross_pay": d.gross_pay + } + + if erpnext.get_region() == "India": + employee["pan_number"] = employee_pan_dict.get(d.employee) + + data.append(employee) + + return data diff --git a/erpnext/payroll/report/salary_payments_based_on_payment_mode/__init__.py b/erpnext/payroll/report/salary_payments_based_on_payment_mode/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/payroll/report/salary_payments_based_on_payment_mode/salary_payments_based_on_payment_mode.js b/erpnext/payroll/report/salary_payments_based_on_payment_mode/salary_payments_based_on_payment_mode.js new file mode 100644 index 0000000000..166d982c9c --- /dev/null +++ b/erpnext/payroll/report/salary_payments_based_on_payment_mode/salary_payments_based_on_payment_mode.js @@ -0,0 +1,7 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.require("assets/erpnext/js/salary_slip_deductions_report_filters.js", function() { + frappe.query_reports["Salary Payments Based On Payment Mode"] = erpnext.salary_slip_deductions_report_filters; +}); \ No newline at end of file diff --git a/erpnext/payroll/report/salary_payments_based_on_payment_mode/salary_payments_based_on_payment_mode.json b/erpnext/payroll/report/salary_payments_based_on_payment_mode/salary_payments_based_on_payment_mode.json new file mode 100644 index 0000000000..c04cc32b9b --- /dev/null +++ b/erpnext/payroll/report/salary_payments_based_on_payment_mode/salary_payments_based_on_payment_mode.json @@ -0,0 +1,30 @@ +{ + "add_total_row": 0, + "creation": "2020-06-16 18:43:43.107246", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "modified": "2020-06-16 18:43:43.107246", + "modified_by": "Administrator", + "module": "Payroll", + "name": "Salary Payments Based On Payment Mode", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Salary Slip", + "report_name": "Salary Payments Based On Payment Mode", + "report_type": "Script Report", + "roles": [ + { + "role": "HR User" + }, + { + "role": "HR Manager" + }, + { + "role": "Employee" + } + ] +} \ No newline at end of file diff --git a/erpnext/payroll/report/salary_payments_based_on_payment_mode/salary_payments_based_on_payment_mode.py b/erpnext/payroll/report/salary_payments_based_on_payment_mode/salary_payments_based_on_payment_mode.py new file mode 100644 index 0000000000..7f0c2e2e00 --- /dev/null +++ b/erpnext/payroll/report/salary_payments_based_on_payment_mode/salary_payments_based_on_payment_mode.py @@ -0,0 +1,177 @@ +# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe, erpnext +from frappe import _ +from erpnext.regional.report.provident_fund_deductions.provident_fund_deductions import get_conditions + +def execute(filters=None): + mode_of_payments = get_payment_modes() + + if not len(mode_of_payments): + return [], [] + + columns = get_columns(filters, mode_of_payments) + data, total_rows, report_summary = get_data(filters, mode_of_payments) + chart = get_chart(mode_of_payments, total_rows) + + return columns, data, None, chart, report_summary + +def get_columns(filters, mode_of_payments): + columns = [{ + "label": _("Branch"), + "options": "Branch", + "fieldname": "branch", + "fieldtype": "Link", + "width": 200 + }] + + for mode in mode_of_payments: + columns.append({ + "label": _(mode), + "fieldname": mode, + "fieldtype": "Currency", + "width": 160 + }) + + columns.append({ + "label": _("Total"), + "fieldname": "total", + "fieldtype": "Currency", + "width": 140 + }) + + return columns + +def get_payment_modes(): + mode_of_payments = frappe.db.sql_list(""" + select distinct mode_of_payment from `tabSalary Slip` where docstatus = 1 + """) + return mode_of_payments + +def prepare_data(entry): + branch_wise_entries = {} + gross_pay = 0 + + for d in entry: + gross_pay += d.gross_pay + if branch_wise_entries.get(d.branch): + branch_wise_entries[d.branch][d.mode_of_payment] = d.net_pay + else: + branch_wise_entries.setdefault(d.branch, {}).setdefault(d.mode_of_payment, d.net_pay) + + return branch_wise_entries, gross_pay + +def get_data(filters, mode_of_payments): + data = [] + + conditions = get_conditions(filters) + + entry = frappe.db.sql(""" + select branch, mode_of_payment, sum(net_pay) as net_pay, sum(gross_pay) as gross_pay + from `tabSalary Slip` sal + where docstatus = 1 %s + group by branch, mode_of_payment + """ % (conditions), as_dict=1) + + branch_wise_entries, gross_pay = prepare_data(entry) + + branches = frappe.db.sql_list(""" + select distinct branch from `tabSalary Slip` sal + where docstatus = 1 %s + """ % (conditions)) + + total_row = {"total": 0, "branch": "Total"} + + for branch in branches: + total = 0 + row = { + "branch": branch + } + for mode in mode_of_payments: + if branch_wise_entries.get(branch).get(mode): + row[mode] = branch_wise_entries.get(branch).get(mode) + total += branch_wise_entries.get(branch).get(mode) + + row["total"] = total + data.append(row) + + total_row = get_total_based_on_mode_of_payment(data, mode_of_payments) + total_deductions = gross_pay - total_row.get("total") + + if data: + data.append(total_row) + data.append({}) + data.append({ + "branch": "Total Gross Pay", + mode_of_payments[0]:gross_pay + }) + data.append({ + "branch": "Total Deductions", + mode_of_payments[0]:total_deductions + }) + data.append({ + "branch": "Total Net Pay", + mode_of_payments[0]:total_row.get("total") + }) + + currency = erpnext.get_company_currency(filters.company) + report_summary = get_report_summary(gross_pay, total_deductions, total_row.get("total"), currency) + + return data, total_row, report_summary + +def get_total_based_on_mode_of_payment(data, mode_of_payments): + + total = 0 + total_row = {"branch": "Total"} + for mode in mode_of_payments: + sum_of_payment = sum([detail[mode] for detail in data if mode in detail.keys()]) + total_row[mode] = sum_of_payment + total += sum_of_payment + + total_row["total"] = total + return total_row + +def get_report_summary(gross_pay, total_deductions, net_pay, currency): + return [ + { + "value": gross_pay, + "label": "Total Gross Pay", + "indicator": "Green", + "datatype": "Currency", + "currency": currency + }, + { + "value": total_deductions, + "label": "Total Deduction", + "datatype": "Currency", + "indicator": "Red", + "currency": currency + }, + { + "value": net_pay, + "label": "Total Net Pay", + "datatype": "Currency", + "indicator": "Blue", + "currency": currency + } + ] + +def get_chart(mode_of_payments, data): + if data: + values = [] + labels = [] + + for mode in mode_of_payments: + values.append(data[mode]) + labels.append([mode]) + + chart = { + "data": { + "labels": labels, + "datasets": [{'name': 'Mode Of Payments', "values": values}] + } + } + chart['type'] = "bar" + return chart diff --git a/erpnext/payroll/report/salary_payments_via_ecs/__init__.py b/erpnext/payroll/report/salary_payments_via_ecs/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/payroll/report/salary_payments_via_ecs/salary_payments_via_ecs.js b/erpnext/payroll/report/salary_payments_via_ecs/salary_payments_via_ecs.js new file mode 100644 index 0000000000..e49fc112ff --- /dev/null +++ b/erpnext/payroll/report/salary_payments_via_ecs/salary_payments_via_ecs.js @@ -0,0 +1,16 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.require("assets/erpnext/js/salary_slip_deductions_report_filters.js", function() { + + let ecs_checklist_filter = erpnext.salary_slip_deductions_report_filters + ecs_checklist_filter['filters'].push({ + fieldname: "type", + label: __("Type"), + fieldtype: "Select", + options:["", "Bank", "Cash", "Cheque"] + }) + + frappe.query_reports["Salary Payments via ECS"] = ecs_checklist_filter +}); diff --git a/erpnext/payroll/report/salary_payments_via_ecs/salary_payments_via_ecs.json b/erpnext/payroll/report/salary_payments_via_ecs/salary_payments_via_ecs.json new file mode 100644 index 0000000000..dd0ac7c4ef --- /dev/null +++ b/erpnext/payroll/report/salary_payments_via_ecs/salary_payments_via_ecs.json @@ -0,0 +1,27 @@ +{ + "add_total_row": 0, + "creation": "2020-06-16 18:35:30.508143", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "modified": "2020-06-16 18:38:23.680185", + "modified_by": "Administrator", + "module": "Payroll", + "name": "Salary Payments via ECS", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Salary Slip", + "report_name": "Salary Payments via ECS", + "report_type": "Script Report", + "roles": [ + { + "role": "HR Manager" + }, + { + "role": "HR User" + } + ] +} \ No newline at end of file diff --git a/erpnext/payroll/report/salary_payments_via_ecs/salary_payments_via_ecs.py b/erpnext/payroll/report/salary_payments_via_ecs/salary_payments_via_ecs.py new file mode 100644 index 0000000000..073bd91300 --- /dev/null +++ b/erpnext/payroll/report/salary_payments_via_ecs/salary_payments_via_ecs.py @@ -0,0 +1,147 @@ +# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe, erpnext +from frappe import _ + +def execute(filters=None): + columns = get_columns(filters) + data = get_data(filters) + + return columns, data + +def get_columns(filters): + columns = [ + { + "label": _("Branch"), + "options": "Branch", + "fieldname": "branch", + "fieldtype": "Link", + "width": 200 + }, + { + "label": _("Employee Name"), + "options": "Employee", + "fieldname": "employee_name", + "fieldtype": "Link", + "width": 160 + }, + { + "label": _("Employee"), + "options":"Employee", + "fieldname": "employee", + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Gross Pay"), + "fieldname": "gross_pay", + "fieldtype": "Currency", + "options": "currency", + "width": 140 + }, + { + "label": _("Bank"), + "fieldname": "bank", + "fieldtype": "Data", + "width": 140 + }, + { + "label": _("Account No"), + "fieldname": "account_no", + "fieldtype": "Data", + "width": 140 + }, + ] + if erpnext.get_region() == "India": + columns += [ + { + "label": _("IFSC"), + "fieldname": "ifsc", + "fieldtype": "Data", + "width": 140 + }, + { + "label": _("MICR"), + "fieldname": "micr", + "fieldtype": "Data", + "width": 140 + } + ] + + return columns + +def get_conditions(filters): + conditions = [""] + + if filters.get("department"): + conditions.append("department = '%s' " % (filters["department"]) ) + + if filters.get("branch"): + conditions.append("branch = '%s' " % (filters["branch"]) ) + + if filters.get("company"): + conditions.append("company = '%s' " % (filters["company"]) ) + + if filters.get("period"): + conditions.append("month(start_date) = '%s' " % (filters["period"])) + conditions.append("year(start_date) = '%s' " % (frappe.utils.getdate().year)) + + return " and ".join(conditions) + +def get_data(filters): + + data = [] + + fields = ["employee", "branch", "bank_name", "bank_ac_no", "salary_mode"] + if erpnext.get_region() == "India": + fields += ["ifsc_code", "micr_code"] + + + employee_details = frappe.get_list("Employee", fields = fields) + employee_data_dict = {} + + for d in employee_details: + employee_data_dict.setdefault( + d.employee,{ + "bank_ac_no" : d.bank_ac_no, + "ifsc_code" : d.ifsc_code or None, + "micr_code" : d.micr_code or None, + "branch" : d.branch, + "salary_mode" : d.salary_mode, + "bank_name": d.bank_name + } + ) + + conditions = get_conditions(filters) + + entry = frappe.db.sql(""" select employee, employee_name, gross_pay + from `tabSalary Slip` + where docstatus = 1 %s """ + %(conditions), as_dict =1) + + for d in entry: + + employee = { + "branch" : employee_data_dict.get(d.employee).get("branch"), + "employee_name" : d.employee_name, + "employee" : d.employee, + "gross_pay" : d.gross_pay, + } + + if employee_data_dict.get(d.employee).get("salary_mode") == "Bank": + employee["bank"] = employee_data_dict.get(d.employee).get("bank_name") + employee["account_no"] = employee_data_dict.get(d.employee).get("bank_ac_no") + if erpnext.get_region() == "India": + employee["ifsc"] = employee_data_dict.get(d.employee).get("ifsc_code") + employee["micr"] = employee_data_dict.get(d.employee).get("micr_code") + else: + employee["account_no"] = employee_data_dict.get(d.employee).get("salary_mode") + + if filters.get("type") and employee_data_dict.get(d.employee).get("salary_mode") == filters.get("type"): + data.append(employee) + elif not filters.get("type"): + data.append(employee) + + return data diff --git a/erpnext/payroll/report/salary_register/__init__.py b/erpnext/payroll/report/salary_register/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/hr/report/salary_register/salary_register.html b/erpnext/payroll/report/salary_register/salary_register.html similarity index 100% rename from erpnext/hr/report/salary_register/salary_register.html rename to erpnext/payroll/report/salary_register/salary_register.html diff --git a/erpnext/hr/report/salary_register/salary_register.js b/erpnext/payroll/report/salary_register/salary_register.js similarity index 100% rename from erpnext/hr/report/salary_register/salary_register.js rename to erpnext/payroll/report/salary_register/salary_register.js diff --git a/erpnext/payroll/report/salary_register/salary_register.json b/erpnext/payroll/report/salary_register/salary_register.json new file mode 100644 index 0000000000..5a70c32593 --- /dev/null +++ b/erpnext/payroll/report/salary_register/salary_register.json @@ -0,0 +1,27 @@ +{ + "add_total_row": 1, + "creation": "2017-01-10 17:36:58.153863", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 2, + "is_standard": "Yes", + "modified": "2020-05-28 00:07:18.576661", + "modified_by": "Administrator", + "module": "Payroll", + "name": "Salary Register", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Salary Slip", + "report_name": "Salary Register", + "report_type": "Script Report", + "roles": [ + { + "role": "HR User" + }, + { + "role": "HR Manager" + } + ] +} \ No newline at end of file diff --git a/erpnext/hr/report/salary_register/salary_register.py b/erpnext/payroll/report/salary_register/salary_register.py similarity index 96% rename from erpnext/hr/report/salary_register/salary_register.py rename to erpnext/payroll/report/salary_register/salary_register.py index ea7fc06cff..87010855fd 100644 --- a/erpnext/hr/report/salary_register/salary_register.py +++ b/erpnext/payroll/report/salary_register/salary_register.py @@ -55,8 +55,8 @@ def get_columns(salary_slips): columns = [ _("Salary Slip ID") + ":Link/Salary Slip:150",_("Employee") + ":Link/Employee:120", _("Employee Name") + "::140", _("Date of Joining") + "::80", _("Branch") + ":Link/Branch:-1", _("Department") + ":Link/Department:-1", - _("Designation") + ":Link/Designation:-1", _("Company") + ":Link/Company:120", _("Start Date") + "::80", - _("End Date") + "::80", _("Leave Without Pay") + ":Float:-1", _("Payment Days") + ":Float:120" + _("Designation") + ":Link/Designation:120", _("Company") + ":Link/Company:120", _("Start Date") + "::80", + _("End Date") + "::80", _("Leave Without Pay") + ":Float:50", _("Payment Days") + ":Float:120" ] salary_components = {_("Earning"): [], _("Deduction"): []} diff --git a/erpnext/projects/doctype/timesheet/test_timesheet.py b/erpnext/projects/doctype/timesheet/test_timesheet.py index cbc624c064..03b67b1023 100644 --- a/erpnext/projects/doctype/timesheet/test_timesheet.py +++ b/erpnext/projects/doctype/timesheet/test_timesheet.py @@ -11,7 +11,7 @@ from frappe.utils import now_datetime, nowdate, add_days, add_months from erpnext.projects.doctype.timesheet.timesheet import OverlapError from erpnext.projects.doctype.timesheet.timesheet import make_salary_slip, make_sales_invoice from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice -from erpnext.hr.doctype.salary_structure.test_salary_structure \ +from erpnext.payroll.doctype.salary_structure.test_salary_structure \ import make_salary_structure, create_salary_structure_assignment from erpnext.hr.doctype.employee.test_employee import make_employee diff --git a/erpnext/public/js/salary_slip_deductions_report_filters.js b/erpnext/public/js/salary_slip_deductions_report_filters.js new file mode 100644 index 0000000000..242037991a --- /dev/null +++ b/erpnext/public/js/salary_slip_deductions_report_filters.js @@ -0,0 +1,47 @@ +frappe.provide("erpnext.salary_slip_deductions_report_filters"); + +erpnext.salary_slip_deductions_report_filters = { + "filters": [ + { + fieldname: "company", + label: __("Company"), + fieldtype: "Link", + options: "Company", + reqd:1, + default: frappe.defaults.get_user_default("Company"), + }, + { + fieldname: "period", + label: __("Period"), + fieldtype: "Select", + reqd: 1 , + options: [ + { "value": 1, "label": __("Jan") }, + { "value": 2, "label": __("Feb") }, + { "value": 3, "label": __("Mar") }, + { "value": 4, "label": __("Apr") }, + { "value": 5, "label": __("May") }, + { "value": 6, "label": __("June") }, + { "value": 7, "label": __("July") }, + { "value": 8, "label": __("Aug") }, + { "value": 9, "label": __("Sep") }, + { "value": 10, "label": __("Oct") }, + { "value": 11, "label": __("Nov") }, + { "value": 12, "label": __("Dec") }, + ], + default: frappe.datetime.str_to_obj(frappe.datetime.get_today()).getMonth() + 1 + }, + { + fieldname: "department", + label: __("Department"), + fieldtype: "Link", + options: "Department", + }, + { + fieldname: "branch", + label: __("Barnch"), + fieldtype: "Link", + options: "Branch", + } + ] +} \ No newline at end of file diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py index 8593966cc3..290694a789 100644 --- a/erpnext/regional/india/setup.py +++ b/erpnext/regional/india/setup.py @@ -60,6 +60,19 @@ def add_custom_roles_for_reports(): ] )).insert() + for report_name in ('Professional Tax Deductions', 'Provident Fund Deductions'): + + if not frappe.db.get_value('Custom Role', dict(report=report_name)): + frappe.get_doc(dict( + doctype='Custom Role', + report=report_name, + roles= [ + dict(role='HR User'), + dict(role='HR Manager'), + dict(role='Employee') + ] + )).insert() + def add_permissions(): for doctype in ('GST HSN Code', 'GST Settings', 'GSTR 3B Report', 'Lower Deduction Certificate'): add_permission(doctype, 'All', 0) @@ -402,10 +415,45 @@ def make_custom_fields(update=True): 'Purchase Receipt Item': [hsn_sac_field, nil_rated_exempt, is_non_gst], 'Purchase Invoice Item': [hsn_sac_field, nil_rated_exempt, is_non_gst], 'Material Request Item': [hsn_sac_field, nil_rated_exempt, is_non_gst], + 'Salary Component': [ + dict(fieldname= 'component_type', + label= 'Component Type', + fieldtype= 'Select', + insert_after= 'description', + options= "\nProvident Fund\nAdditional Provident Fund\nProvident Fund Loan\nProfessional Tax", + depends_on = 'eval:doc.type == "Deduction"' + ) + ], 'Employee': [ - dict(fieldname='ifsc_code', label='IFSC Code', - fieldtype='Data', insert_after='bank_ac_no', print_hide=1, - depends_on='eval:doc.salary_mode == "Bank"') + dict(fieldname='ifsc_code', + label='IFSC Code', + fieldtype='Data', + insert_after='bank_ac_no', + print_hide=1, + depends_on='eval:doc.salary_mode == "Bank"' + ), + dict( + fieldname = 'pan_number', + label = 'PAN Number', + fieldtype = 'Data', + insert_after = 'payroll_cost_center', + print_hide = 1 + ), + dict( + fieldname = 'micr_code', + label = 'MICR Code', + fieldtype = 'Data', + insert_after = 'ifsc_code', + print_hide = 1, + depends_on='eval:doc.salary_mode == "Bank"' + ), + dict( + fieldname = 'provident_fund_account', + label = 'Provident Fund Account', + fieldtype = 'Data', + insert_after = 'pan_number' + ) + ], 'Company': [ dict(fieldname='hra_section', label='HRA Settings', diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index 9fe29eba1b..05ffa87f14 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -6,7 +6,7 @@ from erpnext.regional.india import states, state_numbers from erpnext.controllers.taxes_and_totals import get_itemised_tax, get_itemised_taxable_amount from erpnext.controllers.accounts_controller import get_taxes_and_charges from erpnext.hr.utils import get_salary_assignment -from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip +from erpnext.payroll.doctype.salary_structure.salary_structure import make_salary_slip from erpnext.regional.india import number_state_mapping from six import string_types from erpnext.accounts.general_ledger import make_gl_entries diff --git a/erpnext/regional/report/professional_tax_deductions/__init__.py b/erpnext/regional/report/professional_tax_deductions/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/regional/report/professional_tax_deductions/professional_tax_deductions.js b/erpnext/regional/report/professional_tax_deductions/professional_tax_deductions.js new file mode 100644 index 0000000000..29c7dbf43c --- /dev/null +++ b/erpnext/regional/report/professional_tax_deductions/professional_tax_deductions.js @@ -0,0 +1,7 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.require("assets/erpnext/js/salary_slip_deductions_report_filters.js", function() { + frappe.query_reports["Professional Tax Deductions"] = erpnext.salary_slip_deductions_report_filters; +}); \ No newline at end of file diff --git a/erpnext/regional/report/professional_tax_deductions/professional_tax_deductions.json b/erpnext/regional/report/professional_tax_deductions/professional_tax_deductions.json new file mode 100644 index 0000000000..9938e9db52 --- /dev/null +++ b/erpnext/regional/report/professional_tax_deductions/professional_tax_deductions.json @@ -0,0 +1,20 @@ +{ + "add_total_row": 0, + "creation": "2020-06-02 00:37:44.537355", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "modified": "2020-06-16 19:02:26.306348", + "modified_by": "Administrator", + "module": "Regional", + "name": "Professional Tax Deductions", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Salary Slip", + "report_name": "Professional Tax Deductions", + "report_type": "Script Report", + "roles": [] +} \ No newline at end of file diff --git a/erpnext/regional/report/professional_tax_deductions/professional_tax_deductions.py b/erpnext/regional/report/professional_tax_deductions/professional_tax_deductions.py new file mode 100644 index 0000000000..900fe963b4 --- /dev/null +++ b/erpnext/regional/report/professional_tax_deductions/professional_tax_deductions.py @@ -0,0 +1,69 @@ +# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _ +from erpnext.regional.report.provident_fund_deductions.provident_fund_deductions import get_conditions + +def execute(filters=None): + columns = get_columns(filters) + data = get_data(filters) + + return columns, data + +def get_columns(filters): + columns = [ + { + "label": _("Employee"), + "options": "Employee", + "fieldname": "employee", + "fieldtype": "Link", + "width": 200 + }, + { + "label": _("Employee Name"), + "options": "Employee", + "fieldname": "employee_name", + "fieldtype": "Link", + "width": 160 + }, + { + "label": _("Amount"), + "fieldname": "amount", + "fieldtype": "Currency", + "width": 140 + } + ] + + return columns + +def get_data(filters): + + data = [] + + component_type_dict = frappe._dict(frappe.db.sql(""" select name, component_type from `tabSalary Component` + where component_type = 'Professional Tax' """)) + + conditions = get_conditions(filters) + + entry = frappe.db.sql(""" select sal.employee, sal.employee_name, ded.salary_component, ded.amount + from `tabSalary Slip` sal, `tabSalary Detail` ded + where sal.name = ded.parent + and ded.parentfield = 'deductions' + and ded.parenttype = 'Salary Slip' + and sal.docstatus = 1 %s + and ded.salary_component in (%s) + """ % (conditions , ", ".join(['%s']*len(component_type_dict))), tuple(component_type_dict.keys()), as_dict=1) + + for d in entry: + + employee = { + "employee": d.employee, + "employee_name": d.employee_name, + "amount": d.amount + } + + data.append(employee) + + return data \ No newline at end of file diff --git a/erpnext/regional/report/provident_fund_deductions/__init__.py b/erpnext/regional/report/provident_fund_deductions/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/regional/report/provident_fund_deductions/provident_fund_deductions.js b/erpnext/regional/report/provident_fund_deductions/provident_fund_deductions.js new file mode 100644 index 0000000000..b4dc28d177 --- /dev/null +++ b/erpnext/regional/report/provident_fund_deductions/provident_fund_deductions.js @@ -0,0 +1,7 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.require("assets/erpnext/js/salary_slip_deductions_report_filters.js", function() { + frappe.query_reports["Provident Fund Deductions"] = erpnext.salary_slip_deductions_report_filters; +}); \ No newline at end of file diff --git a/erpnext/regional/report/provident_fund_deductions/provident_fund_deductions.json b/erpnext/regional/report/provident_fund_deductions/provident_fund_deductions.json new file mode 100644 index 0000000000..e25d335f9b --- /dev/null +++ b/erpnext/regional/report/provident_fund_deductions/provident_fund_deductions.json @@ -0,0 +1,20 @@ +{ + "add_total_row": 0, + "creation": "2020-06-01 23:44:07.919117", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "modified": "2020-06-16 18:54:19.305763", + "modified_by": "Administrator", + "module": "Regional", + "name": "Provident Fund Deductions", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Salary Slip", + "report_name": "Provident Fund Deductions", + "report_type": "Script Report", + "roles": [] +} \ No newline at end of file diff --git a/erpnext/regional/report/provident_fund_deductions/provident_fund_deductions.py b/erpnext/regional/report/provident_fund_deductions/provident_fund_deductions.py new file mode 100644 index 0000000000..9f58957fed --- /dev/null +++ b/erpnext/regional/report/provident_fund_deductions/provident_fund_deductions.py @@ -0,0 +1,153 @@ +# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _ + +def execute(filters=None): + columns = get_columns(filters) + data = get_data(filters) + + return columns, data + +def get_columns(filters): + columns = [ + { + "label": _("Employee"), + "options": "Employee", + "fieldname": "employee", + "fieldtype": "Link", + "width": 200 + }, + { + "label": _("Employee Name"), + "options": "Employee", + "fieldname": "employee_name", + "fieldtype": "Link", + "width": 160 + }, + { + "label": _("PF Account"), + "fieldname": "pf_account", + "fieldtype": "Data", + "width": 140 + }, + { + "label": _("PF Amount"), + "fieldname": "pf_amount", + "fieldtype": "Currency", + "width": 140 + }, + { + "label": _("Additional PF"), + "fieldname": "additional_pf", + "fieldtype": "Currency", + "width": 140 + }, + { + "label": _("PF Loan"), + "fieldname": "pf_loan", + "fieldtype": "Currency", + "width": 140 + }, + { + "label": _("Total"), + "fieldname": "total", + "fieldtype": "Currency", + "width": 140 + } + ] + + return columns + +def get_conditions(filters): + conditions = [""] + + if filters.get("department"): + conditions.append("sal.department = '%s' " % (filters["department"]) ) + + if filters.get("branch"): + conditions.append("sal.branch = '%s' " % (filters["branch"]) ) + + if filters.get("company"): + conditions.append("sal.company = '%s' " % (filters["company"]) ) + + if filters.get("period"): + conditions.append("month(sal.start_date) = '%s' " % (filters["period"])) + + if filters.get("mode_of_payment"): + conditions.append("sal.mode_of_payment = '%s' " % (filters["mode_of_payment"])) + + return " and ".join(conditions) + +def prepare_data(entry,component_type_dict): + data_list = {} + + employee_account_dict = frappe._dict(frappe.db.sql(""" select name, provident_fund_account from `tabEmployee`""")) + + for d in entry: + + component_type = component_type_dict.get(d.salary_component) + + if data_list.get(d.name): + data_list[d.name][component_type] = d.amount + else: + data_list.setdefault(d.name,{ + "employee": d.employee, + "employee_name": d.employee_name, + "pf_account": employee_account_dict.get(d.employee), + "component_type": d.amount + }) + + return data_list + +def get_data(filters): + data = [] + + conditions = get_conditions(filters) + + salary_slips = frappe.db.sql(""" select sal.name from `tabSalary Slip` sal + where docstatus = 1 %s + """ % (conditions), as_dict=1) + + component_type_dict = frappe._dict(frappe.db.sql(""" select name, component_type from `tabSalary Component` + where component_type in ('Provident Fund', 'Additional Provident Fund', 'Provident Fund Loan')""")) + + entry = frappe.db.sql(""" select sal.name, sal.employee, sal.employee_name, ded.salary_component, ded.amount + from `tabSalary Slip` sal, `tabSalary Detail` ded + where sal.name = ded.parent + and ded.parentfield = 'deductions' + and ded.parenttype = 'Salary Slip' + and sal.docstatus = 1 %s + and ded.salary_component in (%s) + """ % (conditions, ", ".join(['%s']*len(component_type_dict))), tuple(component_type_dict.keys()), as_dict=1) + + data_list = prepare_data(entry,component_type_dict) + + for d in salary_slips: + total = 0 + if data_list.get(d.name): + employee = { + "employee": data_list.get(d.name).get("employee"), + "employee_name": data_list.get(d.name).get("employee_name"), + "pf_account": data_list.get(d.name).get("pf_account") + } + + if data_list.get(d.name).get("Provident Fund"): + employee["pf_amount"] = data_list.get(d.name).get("Provident Fund") + total += data_list.get(d.name).get("Provident Fund") + + if data_list.get(d.name).get("Additional Provident Fund"): + employee["additional_pf"] = data_list.get(d.name).get("Additional Provident Fund") + total += data_list.get(d.name).get("Additional Provident Fund") + + if data_list.get(d.name).get("Provident Fund Loan"): + employee["pf_loan"] = data_list.get(d.name).get("Provident Fund Loan") + total += data_list.get(d.name).get("Provident Fund Loan") + + employee["total"] = total + + data.append(employee) + + return data \ No newline at end of file diff --git a/erpnext/selling/dashboard_fixtures.py b/erpnext/selling/dashboard_fixtures.py new file mode 100644 index 0000000000..889cb88dce --- /dev/null +++ b/erpnext/selling/dashboard_fixtures.py @@ -0,0 +1,198 @@ +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +import frappe +import json +from frappe import _ +from frappe.utils import nowdate +from erpnext.accounts.utils import get_fiscal_year + +def get_data(): + return frappe._dict({ + "dashboards": get_dashboards(), + "charts": get_charts(), + "number_cards": get_number_cards(), + }) + +def get_company_for_dashboards(): + company = frappe.defaults.get_defaults().company + if company: + return company + else: + company_list = frappe.get_list("Company") + if company_list: + return company_list[0].name + return None + +company = frappe.get_doc("Company", get_company_for_dashboards()) +fiscal_year = get_fiscal_year(nowdate(), as_dict=1) +fiscal_year_name = fiscal_year.get("name") +start_date = str(fiscal_year.get("year_start_date")) +end_date = str(fiscal_year.get("year_end_date")) + +def get_dashboards(): + return [{ + "name": "Selling", + "dashboard_name": "Selling", + "charts": [ + { "chart": "Sales Order Trends", "width": "Full"}, + { "chart": "Top Customers", "width": "Half"}, + { "chart": "Sales Order Analysis", "width": "Half"}, + { "chart": "Item-wise Annual Sales", "width": "Full"} + ], + "cards": [ + { "card": "Annual Sales"}, + { "card": "Sales Orders to Deliver"}, + { "card": "Sales Orders to Bill"}, + { "card": "Active Customers"} + ] + }] + +def get_charts(): + return [ + { + "name": "Sales Order Analysis", + "chart_name": _("Sales Order Analysis"), + "chart_type": "Report", + "custom_options": json.dumps({ + "type": "donut", + "height": 300, + "axisOptions": {"shortenYAxisNumbers": 1} + }), + "doctype": "Dashboard Chart", + "filters_json": json.dumps({ + "company": company.name, + "from_date": start_date, + "to_date": end_date + }), + "is_custom": 1, + "is_public": 1, + "owner": "Administrator", + "report_name": "Sales Order Analysis", + "type": "Donut" + }, + { + "name": "Item-wise Annual Sales", + "chart_name": _("Item-wise Annual Sales"), + "chart_type": "Report", + "doctype": "Dashboard Chart", + "filters_json": json.dumps({ + "company": company.name, + "from_date": start_date, + "to_date": end_date + }), + "is_custom": 1, + "is_public": 1, + "owner": "Administrator", + "report_name": "Item-wise Sales History", + "type": "Bar" + }, + { + "name": "Sales Order Trends", + "chart_name": _("Sales Order Trends"), + "chart_type": "Report", + "custom_options": json.dumps({ + "type": "line", + "axisOptions": {"shortenYAxisNumbers": 1}, + "tooltipOptions": {}, + "lineOptions": { + "regionFill": 1 + } + }), + "doctype": "Dashboard Chart", + "filters_json": json.dumps({ + "company": company.name, + "period": "Monthly", + "fiscal_year": fiscal_year_name, + "based_on": "Item" + }), + "is_custom": 1, + "is_public": 1, + "owner": "Administrator", + "report_name": "Sales Order Trends", + "type": "Line" + }, + { + "name": "Top Customers", + "chart_name": _("Top Customers"), + "chart_type": "Report", + "doctype": "Dashboard Chart", + "filters_json": json.dumps({ + "company": company.name, + "period": "Monthly", + "fiscal_year": fiscal_year_name, + "based_on": "Customer" + }), + "is_custom": 1, + "is_public": 1, + "owner": "Administrator", + "report_name": "Delivery Note Trends", + "type": "Bar" + } + ] + +def get_number_cards(): + return [ + { + "name": "Annual Sales", + "aggregate_function_based_on": "base_net_total", + "doctype": "Number Card", + "document_type": "Sales Order", + "filters_json": json.dumps([ + ["Sales Order", "transaction_date", "Between", [start_date, end_date], False], + ["Sales Order", "status", "not in", ["Draft", "Cancelled", "Closed", None], False], + ["Sales Order", "docstatus", "=", 1, False], + ["Sales Order", "company", "=", company.name, False] + ]), + "function": "Sum", + "is_public": 1, + "label": _("Annual Sales"), + "owner": "Administrator", + "show_percentage_stats": 1, + "stats_time_interval": "Monthly" + }, + { + "name": "Sales Orders to Deliver", + "doctype": "Number Card", + "document_type": "Sales Order", + "filters_json": json.dumps([ + ["Sales Order", "status", "in", ["To Deliver and Bill", "To Deliver", None], False], + ["Sales Order", "docstatus", "=", 1, False], + ["Sales Order", "company", "=", company.name, False] + ]), + "function": "Count", + "is_public": 1, + "label": _("Sales Orders to Deliver"), + "owner": "Administrator", + "show_percentage_stats": 1, + "stats_time_interval": "Weekly" + }, + { + "name": "Sales Orders to Bill", + "doctype": "Number Card", + "document_type": "Sales Order", + "filters_json": json.dumps([ + ["Sales Order", "status", "in", ["To Deliver and Bill", "To Bill", None], False], + ["Sales Order", "docstatus", "=", 1, False], + ["Sales Order", "company", "=", company.name, False] + ]), + "function": "Count", + "is_public": 1, + "label": _("Sales Orders to Bill"), + "owner": "Administrator", + "show_percentage_stats": 1, + "stats_time_interval": "Weekly" + }, + { + "name": "Active Customers", + "doctype": "Number Card", + "document_type": "Customer", + "filters_json": json.dumps([["Customer", "disabled", "=", "0"]]), + "function": "Count", + "is_public": 1, + "label": "Active Customers", + "owner": "Administrator", + "show_percentage_stats": 1, + "stats_time_interval": "Monthly" + } + ] \ No newline at end of file diff --git a/erpnext/selling/desk_page/selling/selling.json b/erpnext/selling/desk_page/selling/selling.json index 9ec634354d..60b15326e8 100644 --- a/erpnext/selling/desk_page/selling/selling.json +++ b/erpnext/selling/desk_page/selling/selling.json @@ -1,5 +1,10 @@ { "cards": [ + { + "hidden": 0, + "label": "Selling", + "links": "[\n {\n \"description\": \"Customer Database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Quotes to Leads or Customers.\",\n \"label\": \"Quotation\",\n \"name\": \"Quotation\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Confirmed orders from Customers.\",\n \"label\": \"Sales Order\",\n \"name\": \"Sales Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Blanket Orders from Costumers.\",\n \"label\": \"Blanket Order\",\n \"name\": \"Blanket Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Manage Sales Partners.\",\n \"label\": \"Sales Partner\",\n \"name\": \"Sales Partner\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Manage Sales Person Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Sales Person\",\n \"link\": \"Tree/Sales Person\",\n \"name\": \"Sales Person\",\n \"type\": \"doctype\"\n }\n]" + }, { "hidden": 0, "label": "Items and Pricing", @@ -10,29 +15,25 @@ "label": "Settings", "links": "[\n {\n \"description\": \"Default settings for selling transactions.\",\n \"label\": \"Selling Settings\",\n \"name\": \"Selling Settings\",\n \"settings\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Template of terms or contract.\",\n \"label\": \"Terms and Conditions Template\",\n \"name\": \"Terms and Conditions\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for selling transactions.\",\n \"label\": \"Sales Taxes and Charges Template\",\n \"name\": \"Sales Taxes and Charges Template\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Track Leads by Lead Source.\",\n \"label\": \"Lead Source\",\n \"name\": \"Lead Source\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Customer Group Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Customer Group\",\n \"link\": \"Tree/Customer Group\",\n \"name\": \"Customer Group\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Contacts.\",\n \"label\": \"Contact\",\n \"name\": \"Contact\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Addresses.\",\n \"label\": \"Address\",\n \"name\": \"Address\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Territory Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Territory\",\n \"link\": \"Tree/Territory\",\n \"name\": \"Territory\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Sales campaigns.\",\n \"label\": \"Campaign\",\n \"name\": \"Campaign\",\n \"type\": \"doctype\"\n }\n]" }, - { - "hidden": 0, - "label": "Other Reports", - "links": "[\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Details\",\n \"name\": \"Lead Details\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Address\"\n ],\n \"doctype\": \"Address\",\n \"is_query_report\": true,\n \"label\": \"Customer Addresses And Contacts\",\n \"name\": \"Address And Contacts\",\n \"route_options\": {\n \"party_type\": \"Customer\"\n },\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"BOM\"\n ],\n \"doctype\": \"BOM\",\n \"is_query_report\": true,\n \"label\": \"BOM Search\",\n \"name\": \"BOM Search\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Available Stock for Packing Items\",\n \"name\": \"Available Stock for Packing Items\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Pending SO Items For Purchase Request\",\n \"name\": \"Pending SO Items For Purchase Request\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customer Credit Balance\",\n \"name\": \"Customer Credit Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customers Without Any Sales Transactions\",\n \"name\": \"Customers Without Any Sales Transactions\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Sales Partners Commission\",\n \"name\": \"Sales Partners Commission\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Sales", - "links": "[\n {\n \"description\": \"Customer Database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Quotes to Leads or Customers.\",\n \"label\": \"Quotation\",\n \"name\": \"Quotation\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Confirmed orders from Customers.\",\n \"label\": \"Sales Order\",\n \"name\": \"Sales Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Invoices for Costumers.\",\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Blanket Orders from Costumers.\",\n \"label\": \"Blanket Order\",\n \"name\": \"Blanket Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Manage Sales Partners.\",\n \"label\": \"Sales Partner\",\n \"name\": \"Sales Partner\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Manage Sales Person Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Sales Person\",\n \"link\": \"Tree/Sales Person\",\n \"name\": \"Sales Person\",\n \"type\": \"doctype\"\n }\n]" - }, { "hidden": 0, "label": "Key Reports", - "links": "[\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Analytics\",\n \"name\": \"Sales Analytics\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"icon\": \"fa fa-bar-chart\",\n \"label\": \"Sales Funnel\",\n \"name\": \"sales-funnel\",\n \"onboard\": 1,\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"icon\": \"fa fa-bar-chart\",\n \"is_query_report\": true,\n \"label\": \"Customer Acquisition and Loyalty\",\n \"name\": \"Customer Acquisition and Loyalty\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Inactive Customers\",\n \"name\": \"Inactive Customers\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Ordered Items To Be Delivered\",\n \"name\": \"Ordered Items To Be Delivered\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Person-wise Transaction Summary\",\n \"name\": \"Sales Person-wise Transaction Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales History\",\n \"name\": \"Item-wise Sales History\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Quotation\"\n ],\n \"doctype\": \"Quotation\",\n \"is_query_report\": true,\n \"label\": \"Quotation Trends\",\n \"name\": \"Quotation Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Trends\",\n \"name\": \"Sales Order Trends\",\n \"type\": \"report\"\n }\n]" + "links": "[\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Analytics\",\n \"name\": \"Sales Analytics\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Analysis\",\n \"name\": \"Sales Order Analysis\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"icon\": \"fa fa-bar-chart\",\n \"label\": \"Sales Funnel\",\n \"name\": \"sales-funnel\",\n \"onboard\": 1,\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Trends\",\n \"name\": \"Sales Order Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Quotation\"\n ],\n \"doctype\": \"Quotation\",\n \"is_query_report\": true,\n \"label\": \"Quotation Trends\",\n \"name\": \"Quotation Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"icon\": \"fa fa-bar-chart\",\n \"is_query_report\": true,\n \"label\": \"Customer Acquisition and Loyalty\",\n \"name\": \"Customer Acquisition and Loyalty\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Inactive Customers\",\n \"name\": \"Inactive Customers\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Person-wise Transaction Summary\",\n \"name\": \"Sales Person-wise Transaction Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales History\",\n \"name\": \"Item-wise Sales History\",\n \"type\": \"report\"\n }\n]" + }, + { + "hidden": 0, + "label": "Other Reports", + "links": "[\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Details\",\n \"name\": \"Lead Details\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Address\"\n ],\n \"doctype\": \"Address\",\n \"is_query_report\": true,\n \"label\": \"Customer Addresses And Contacts\",\n \"name\": \"Address And Contacts\",\n \"route_options\": {\n \"party_type\": \"Customer\"\n },\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Available Stock for Packing Items\",\n \"name\": \"Available Stock for Packing Items\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Pending SO Items For Purchase Request\",\n \"name\": \"Pending SO Items For Purchase Request\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customer Credit Balance\",\n \"name\": \"Customer Credit Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customers Without Any Sales Transactions\",\n \"name\": \"Customers Without Any Sales Transactions\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Sales Partners Commission\",\n \"name\": \"Sales Partners Commission\",\n \"type\": \"report\"\n }\n]" } ], "category": "Modules", "charts": [ { - "chart_name": "Incoming Bills (Purchase Invoice)", - "label": "Income" + "chart_name": "Sales Order Trends", + "label": "Sales Order Trends" } ], + "charts_label": "Selling ", "creation": "2020-01-28 11:49:12.092882", "developer_mode_only": 0, "disable_user_customization": 0, @@ -43,52 +44,49 @@ "idx": 0, "is_standard": 1, "label": "Selling", - "modified": "2020-06-03 13:23:24.861706", + "modified": "2020-06-19 13:23:24.861706", "modified_by": "Administrator", "module": "Selling", "name": "Selling", + "onboarding": "Selling", "owner": "Administrator", "pin_to_bottom": 0, "pin_to_top": 0, "shortcuts": [ { - "color": "#ffe8cd", - "format": "{} Draft", - "label": "Sales Invoice", - "link_to": "Sales Invoice", - "stats_filter": "{ \"status\": \"Draft\" }", + "color": "#cef6d1", + "format": "{} Available", + "label": "Item", + "link_to": "Item", + "stats_filter": "{\n \"disabled\":0\n}", "type": "DocType" }, { "color": "#ffe8cd", - "format": "{} To Deliver", + "format": "{} To Deliver", "label": "Sales Order", "link_to": "Sales Order", - "stats_filter": "{\"Status\": \"To Deliver and Bill\"}", + "stats_filter": "{\n \"company\": [\"like\", '%' + frappe.defaults.get_global_default(\"company\") + '%'],\n \"status\":[\"in\", [\"To Deliver\", \"To Deliver and Bill\"]]\n}", "type": "DocType" }, { "color": "#cef6d1", "format": "{} Open", - "label": "Quotation", - "link_to": "Quotation", + "label": "Sales Analytics", + "link_to": "Sales Analytics", "stats_filter": "{ \"Status\": \"Open\" }", - "type": "DocType" - }, - { - "label": "Delivery Note", - "link_to": "Delivery Note", - "type": "DocType" - }, - { - "label": "Accounts Receivable", - "link_to": "Accounts Receivable", "type": "Report" }, { - "label": "Sales Register", - "link_to": "Sales Register", + "label": "Sales Order Analysis", + "link_to": "Sales Order Analysis", "type": "Report" + }, + { + "label": "Dashboard", + "link_to": "Selling", + "type": "Dashboard" } - ] + ], + "shortcuts_label": "Quick Access" } \ No newline at end of file diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index 0e771c3025..449a968a4f 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -99,6 +99,8 @@ class Quotation(SellingController): self.update_lead() def on_cancel(self): + if self.lost_reasons: + self.lost_reasons = [] super(Quotation, self).on_cancel() #update enquiry status diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.js b/erpnext/selling/doctype/selling_settings/selling_settings.js index cf6fb2806e..95a4243fb4 100644 --- a/erpnext/selling/doctype/selling_settings/selling_settings.js +++ b/erpnext/selling/doctype/selling_settings/selling_settings.js @@ -6,3 +6,26 @@ frappe.ui.form.on('Selling Settings', { } }); + +frappe.tour['Selling Settings'] = [ + { + fieldname: "cust_master_name", + title: "Customer Naming By", + description: __("By default, the Customer Name is set as per the Full Name entered. If you want Customers to be named by a ") + "Naming Series" + __(" choose the 'Naming Series' option."), + }, + { + fieldname: "selling_price_list", + title: "Default Selling Price List", + description: __("Configure the default Price List when creating a new Sales transaction. Item prices will be fetched from this Price List.") + }, + { + fieldname: "so_required", + title: "Sales Order Required for Sales Invoice & Delivery Note Creation", + description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Sales Invoice or Delivery Note without creating a Sales Order first. This configuration can be overridden for a particular Customer by enabling the 'Allow Sales Invoice Creation Without Sales Order' checkbox in the Customer master.") + }, + { + fieldname: "dn_required", + title: "Delivery Note Required for Sales Invoice Creation", + description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Sales Invoice without creating a Delivery Note first. This configuration can be overridden for a particular Customer by enabling the 'Allow Sales Invoice Creation Without Delivery Note' checkbox in the Customer master.") + } +]; \ No newline at end of file diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.json b/erpnext/selling/doctype/selling_settings/selling_settings.json index c04bfd281e..dcbc0748f7 100644 --- a/erpnext/selling/doctype/selling_settings/selling_settings.json +++ b/erpnext/selling/doctype/selling_settings/selling_settings.json @@ -1,4 +1,5 @@ { + "actions": [], "creation": "2013-06-25 10:25:16", "description": "Settings for Selling Module", "doctype": "DocType", @@ -79,13 +80,13 @@ { "fieldname": "so_required", "fieldtype": "Select", - "label": "Sales Order Required", + "label": "Sales Order Required for Sales Invoice & Delivery Note Creation", "options": "No\nYes" }, { "fieldname": "dn_required", "fieldtype": "Select", - "label": "Delivery Note Required", + "label": "Delivery Note Required for Sales Invoice Creation", "options": "No\nYes" }, { @@ -137,7 +138,8 @@ "icon": "fa fa-cog", "idx": 1, "issingle": 1, - "modified": "2019-12-09 13:38:36.486298", + "links": [], + "modified": "2020-06-01 13:58:35.637858", "modified_by": "Administrator", "module": "Selling", "name": "Selling Settings", diff --git a/erpnext/selling/module_onboarding/selling/selling.json b/erpnext/selling/module_onboarding/selling/selling.json new file mode 100644 index 0000000000..10a33c9cf5 --- /dev/null +++ b/erpnext/selling/module_onboarding/selling/selling.json @@ -0,0 +1,54 @@ +{ + "allow_roles": [ + { + "role": "Sales Manager" + }, + { + "role": "Sales User" + }, + { + "role": "Stock Manager" + }, + { + "role": "Stock User" + } + ], + "creation": "2020-06-01 12:44:42.589930", + "docstatus": 0, + "doctype": "Module Onboarding", + "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/selling", + "idx": 0, + "is_complete": 0, + "modified": "2020-06-01 13:35:16.100512", + "modified_by": "Administrator", + "module": "Selling", + "name": "Selling", + "owner": "Administrator", + "steps": [ + { + "step": "Introduction to Selling" + }, + { + "step": "Create a Customer" + }, + { + "step": "Setup your Warehouse" + }, + { + "step": "Create a Product" + }, + { + "step": "Create a Quotation" + }, + { + "step": "Create your first Sales Order" + }, + { + "step": "Selling Settings" + } + ], + "subtitle": "Products, Sales, Analysis and more.", + "success_message": "The Selling Module is all set up!", + "title": "Let's Set Up the Selling Module.", + "user_can_dismiss": 1 +} \ No newline at end of file diff --git a/erpnext/selling/onboarding_step/create_a_customer/create_a_customer.json b/erpnext/selling/onboarding_step/create_a_customer/create_a_customer.json new file mode 100644 index 0000000000..5a403b06cf --- /dev/null +++ b/erpnext/selling/onboarding_step/create_a_customer/create_a_customer.json @@ -0,0 +1,19 @@ +{ + "action": "Create Entry", + "creation": "2020-05-14 17:46:41.831517", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_mandatory": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2020-06-01 13:16:19.731719", + "modified_by": "Administrator", + "name": "Create a Customer", + "owner": "Administrator", + "reference_document": "Customer", + "show_full_form": 0, + "title": "Create a Customer", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/selling/onboarding_step/create_a_product/create_a_product.json b/erpnext/selling/onboarding_step/create_a_product/create_a_product.json new file mode 100644 index 0000000000..d2068e167b --- /dev/null +++ b/erpnext/selling/onboarding_step/create_a_product/create_a_product.json @@ -0,0 +1,19 @@ +{ + "action": "Create Entry", + "creation": "2020-05-12 18:16:06.624554", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_mandatory": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2020-05-12 18:30:02.489949", + "modified_by": "Administrator", + "name": "Create a Product", + "owner": "Administrator", + "reference_document": "Item", + "show_full_form": 0, + "title": "Create a Product", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/selling/onboarding_step/create_a_quotation/create_a_quotation.json b/erpnext/selling/onboarding_step/create_a_quotation/create_a_quotation.json new file mode 100644 index 0000000000..27253d15b6 --- /dev/null +++ b/erpnext/selling/onboarding_step/create_a_quotation/create_a_quotation.json @@ -0,0 +1,19 @@ +{ + "action": "Create Entry", + "creation": "2020-06-01 13:34:58.958641", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_mandatory": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2020-06-01 13:34:58.958641", + "modified_by": "Administrator", + "name": "Create a Quotation", + "owner": "Administrator", + "reference_document": "Quotation", + "show_full_form": 1, + "title": "Create a Quotation", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/selling/onboarding_step/create_product/create_product.json b/erpnext/selling/onboarding_step/create_product/create_product.json new file mode 100644 index 0000000000..0ffa30158b --- /dev/null +++ b/erpnext/selling/onboarding_step/create_product/create_product.json @@ -0,0 +1,19 @@ +{ + "action": "Create Entry", + "creation": "2020-05-05 16:42:31.476275", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_mandatory": 1, + "is_single": 0, + "is_skipped": 0, + "modified": "2020-05-19 12:50:59.010439", + "modified_by": "Administrator", + "name": "Create Product", + "owner": "Administrator", + "reference_document": "Item", + "show_full_form": 0, + "title": "Create a Finished Good", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/selling/onboarding_step/create_your_first_sales_order/create_your_first_sales_order.json b/erpnext/selling/onboarding_step/create_your_first_sales_order/create_your_first_sales_order.json new file mode 100644 index 0000000000..5b601a7a90 --- /dev/null +++ b/erpnext/selling/onboarding_step/create_your_first_sales_order/create_your_first_sales_order.json @@ -0,0 +1,19 @@ +{ + "action": "Create Entry", + "creation": "2020-06-01 12:52:27.181841", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_mandatory": 1, + "is_single": 0, + "is_skipped": 0, + "modified": "2020-06-01 12:52:27.181841", + "modified_by": "Administrator", + "name": "Create your first Sales Order", + "owner": "Administrator", + "reference_document": "Sales Order", + "show_full_form": 1, + "title": "Create your first Sales Order", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/selling/onboarding_step/introduction_to_selling/introduction_to_selling.json b/erpnext/selling/onboarding_step/introduction_to_selling/introduction_to_selling.json new file mode 100644 index 0000000000..d21c1f4954 --- /dev/null +++ b/erpnext/selling/onboarding_step/introduction_to_selling/introduction_to_selling.json @@ -0,0 +1,19 @@ +{ + "action": "Watch Video", + "creation": "2020-06-01 12:44:32.089234", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_mandatory": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2020-06-01 13:29:13.703177", + "modified_by": "Administrator", + "name": "Introduction to Selling", + "owner": "Administrator", + "show_full_form": 0, + "title": "Introduction to Selling", + "validate_action": 1, + "video_url": "https://youtu.be/1eP90MWoDQM" +} \ No newline at end of file diff --git a/erpnext/selling/onboarding_step/selling_settings/selling_settings.json b/erpnext/selling/onboarding_step/selling_settings/selling_settings.json new file mode 100644 index 0000000000..7996d7b159 --- /dev/null +++ b/erpnext/selling/onboarding_step/selling_settings/selling_settings.json @@ -0,0 +1,19 @@ +{ + "action": "Show Form Tour", + "creation": "2020-06-01 13:01:45.615189", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_mandatory": 0, + "is_single": 1, + "is_skipped": 0, + "modified": "2020-06-01 13:04:14.980743", + "modified_by": "Administrator", + "name": "Selling Settings", + "owner": "Administrator", + "reference_document": "Selling Settings", + "show_full_form": 0, + "title": "Configure Selling Settings.", + "validate_action": 0 +} \ No newline at end of file diff --git a/erpnext/selling/onboarding_step/setup_your_warehouse/setup_your_warehouse.json b/erpnext/selling/onboarding_step/setup_your_warehouse/setup_your_warehouse.json new file mode 100644 index 0000000000..557c905bd6 --- /dev/null +++ b/erpnext/selling/onboarding_step/setup_your_warehouse/setup_your_warehouse.json @@ -0,0 +1,20 @@ +{ + "action": "Go to Page", + "creation": "2020-05-19 18:54:19.383397", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_mandatory": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2020-05-19 18:54:19.383397", + "modified_by": "Administrator", + "name": "Setup your Warehouse", + "owner": "Administrator", + "path": "Tree/Warehouse", + "reference_document": "Warehouse", + "show_full_form": 0, + "title": "Setup your Warehouse", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.js b/erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.js index daca2e3bd0..f47d67fe49 100644 --- a/erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.js +++ b/erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.js @@ -12,12 +12,6 @@ frappe.query_reports["Item-wise Sales History"] = { default: frappe.defaults.get_user_default("Company"), reqd: 1 }, - { - fieldname:"item_group", - label: __("Item Group"), - fieldtype: "Link", - options: "Item Group" - }, { fieldname:"from_date", reqd: 1, @@ -32,6 +26,38 @@ frappe.query_reports["Item-wise Sales History"] = { label: __("To Date"), fieldtype: "Date", }, + { + fieldname:"item_group", + label: __("Item Group"), + fieldtype: "Link", + options: "Item Group" + }, + { + fieldname:"item_code", + label: __("Item"), + fieldtype: "Link", + options: "Item", + get_query: () => { + return { + query: "erpnext.controllers.queries.item_query" + } + } + }, + { + fieldname:"customer", + label: __("Customer"), + fieldtype: "Link", + options: "Customer" + } + ], - ] + "formatter": function (value, row, column, data, default_formatter) { + value = default_formatter(value, row, column, data); + let format_fields = ["delivered_quantity", "billed_amount"]; + + if (in_list(format_fields, column.fieldname) && data && data[column.fieldname] > 0) { + value = "" + value + ""; + } + return value; + } }; \ No newline at end of file diff --git a/erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.py b/erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.py index 08a98ba6c0..bd59be663a 100644 --- a/erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.py +++ b/erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.py @@ -11,7 +11,10 @@ def execute(filters=None): filters = frappe._dict(filters or {}) columns = get_columns(filters) data = get_data(filters) - return columns, data + + chart_data = get_chart_data(data) + + return columns, data, None, chart_data def get_columns(filters): return [ @@ -181,6 +184,12 @@ def get_conditions(filters): if filters.get('to_date'): conditions += "AND so.transaction_date <= '%s'" %filters.to_date + if filters.get("item_code"): + conditions += "AND so_item.item_code = '%s'" %frappe.db.escape(filters.item_code) + + if filters.get("customer"): + conditions += "AND so.customer = '%s'" %frappe.db.escape(filters.customer) + return conditions def get_customer_details(): @@ -212,3 +221,34 @@ def get_sales_order_details(company_list, filters): AND so.company in ({0}) AND so.docstatus = 1 {1} """.format(','.join(["%s"] * len(company_list)), conditions), tuple(company_list), as_dict=1) + +def get_chart_data(data): + item_wise_sales_map = {} + labels, datapoints = [], [] + + for row in data: + item_key = row.get("item_code") + + if not item_key in item_wise_sales_map: + item_wise_sales_map[item_key] = 0 + + item_wise_sales_map[item_key] = flt(item_wise_sales_map[item_key]) + flt(row.get("amount")) + + item_wise_sales_map = { item: value for item, value in (sorted(item_wise_sales_map.items(), key = lambda i: i[1], reverse=True))} + + for key in item_wise_sales_map: + labels.append(key) + datapoints.append(item_wise_sales_map[key]) + + return { + "data" : { + "labels" : labels[:30], # show max of 30 items in chart + "datasets" : [ + { + "name" : _(" Total Sales Amount"), + "values" : datapoints[:30] + } + ] + }, + "type" : "bar" + } \ No newline at end of file diff --git a/erpnext/selling/report/quotation_trends/quotation_trends.py b/erpnext/selling/report/quotation_trends/quotation_trends.py index 67375f98b3..968e2ff26f 100644 --- a/erpnext/selling/report/quotation_trends/quotation_trends.py +++ b/erpnext/selling/report/quotation_trends/quotation_trends.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals import frappe +from frappe import _ from erpnext.controllers.trends import get_columns, get_data def execute(filters=None): @@ -11,4 +12,48 @@ def execute(filters=None): conditions = get_columns(filters, "Quotation") data = get_data(filters, conditions) - return conditions["columns"], data \ No newline at end of file + chart_data = get_chart_data(data, conditions, filters) + + return conditions["columns"], data, None, chart_data + +def get_chart_data(data, conditions, filters): + if not (data and conditions): + return [] + + datapoints = [] + + start = 2 if filters.get("based_on") in ["Item", "Customer"] else 1 + if filters.get("group_by"): + start += 1 + + # fetch only periodic columns as labels + columns = conditions.get("columns")[start:-2][1::2] + labels = [column.split(':')[0] for column in columns] + datapoints = [0] * len(labels) + + for row in data: + # If group by filter, don't add first row of group (it's already summed) + if not row[start-1]: + continue + # Remove None values and compute only periodic data + row = [x if x else 0 for x in row[start:-2]] + row = row[1::2] + + for i in range(len(row)): + datapoints[i] += row[i] + + return { + "data" : { + "labels" : labels, + "datasets" : [ + { + "name" : _("{0}").format(filters.get("period")) + _(" Quoted Amount"), + "values" : datapoints + } + ] + }, + "type" : "line", + "lineOptions": { + "regionFill": 1 + } + } diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.json b/erpnext/selling/report/sales_analytics/sales_analytics.json index bf9edd6cd4..de5c3a6b2a 100644 --- a/erpnext/selling/report/sales_analytics/sales_analytics.json +++ b/erpnext/selling/report/sales_analytics/sales_analytics.json @@ -1,5 +1,5 @@ { - "add_total_row": 0, + "add_total_row": 1, "creation": "2018-09-21 12:46:29.451048", "disable_prepared_report": 0, "disabled": 0, @@ -7,7 +7,7 @@ "doctype": "Report", "idx": 0, "is_standard": "Yes", - "modified": "2020-04-30 19:49:02.303320", + "modified": "2020-06-19 17:41:03.132101", "modified_by": "Administrator", "module": "Selling", "name": "Sales Analytics", diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.py b/erpnext/selling/report/sales_analytics/sales_analytics.py index 97d9322918..4d113c8e9e 100644 --- a/erpnext/selling/report/sales_analytics/sales_analytics.py +++ b/erpnext/selling/report/sales_analytics/sales_analytics.py @@ -23,7 +23,14 @@ class Analytics(object): self.get_columns() self.get_data() self.get_chart_data() - return self.columns, self.data, None, self.chart + + # Skipping total row for tree-view reports + skip_total_row = 0 + + if self.filters.tree_type in ["Supplier Group", "Item Group", "Customer Group", "Territory"]: + skip_total_row = 1 + + return self.columns, self.data, None, self.chart, None, skip_total_row def get_columns(self): self.columns = [{ @@ -194,9 +201,6 @@ class Analytics(object): def get_rows(self): self.data = [] self.get_periodic_data() - total_row = { - "entity": "Total", - } for entity, period_data in iteritems(self.entity_periodic_data): row = { @@ -210,9 +214,6 @@ class Analytics(object): row[scrub(period)] = amount total += amount - if not total_row.get(scrub(period)): total_row[scrub(period)] = 0 - total_row[scrub(period)] += amount - row["total"] = total if self.filters.tree_type == "Item": @@ -220,8 +221,6 @@ class Analytics(object): self.data.append(row) - self.data.append(total_row) - def get_rows_by_group(self): self.get_periodic_data() out = [] diff --git a/erpnext/selling/report/sales_analytics/test_analytics.py b/erpnext/selling/report/sales_analytics/test_analytics.py index 7e8501dcc1..4d81a1e4dd 100644 --- a/erpnext/selling/report/sales_analytics/test_analytics.py +++ b/erpnext/selling/report/sales_analytics/test_analytics.py @@ -33,21 +33,6 @@ class TestAnalytics(unittest.TestCase): report = execute(filters) expected_data = [ - { - 'entity': 'Total', - 'apr_2017': 0.0, - 'may_2017': 0.0, - 'jun_2017': 2000.0, - 'jul_2017': 1000.0, - 'aug_2017': 0.0, - 'sep_2017': 1500.0, - 'oct_2017': 1000.0, - 'nov_2017': 0.0, - 'dec_2017': 0.0, - 'jan_2018': 0.0, - 'feb_2018': 2000.0, - 'mar_2018': 0.0 - }, { "entity": "_Test Customer 1", "entity_name": "_Test Customer 1", @@ -149,21 +134,6 @@ class TestAnalytics(unittest.TestCase): report = execute(filters) expected_data = [ - { - 'entity': 'Total', - 'apr_2017': 0.0, - 'may_2017': 0.0, - 'jun_2017': 20.0, - 'jul_2017': 10.0, - 'aug_2017': 0.0, - 'sep_2017': 15.0, - 'oct_2017': 10.0, - 'nov_2017': 0.0, - 'dec_2017': 0.0, - 'jan_2018': 0.0, - 'feb_2018': 20.0, - 'mar_2018': 0.0 - }, { "entity": "_Test Customer 1", "entity_name": "_Test Customer 1", diff --git a/erpnext/selling/report/sales_order_analysis/__init__.py b/erpnext/selling/report/sales_order_analysis/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/selling/report/sales_order_analysis/sales_order_analysis.js b/erpnext/selling/report/sales_order_analysis/sales_order_analysis.js new file mode 100644 index 0000000000..76a5bb51ca --- /dev/null +++ b/erpnext/selling/report/sales_order_analysis/sales_order_analysis.js @@ -0,0 +1,85 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["Sales Order Analysis"] = { + "filters": [ + { + "fieldname": "company", + "label": __("Company"), + "fieldtype": "Link", + "width": "80", + "options": "Company", + "reqd": 1, + "default": frappe.defaults.get_default("company") + }, + { + "fieldname":"from_date", + "label": __("From Date"), + "fieldtype": "Date", + "width": "80", + "reqd": 1, + "default": frappe.datetime.add_months(frappe.datetime.get_today(), -1), + }, + { + "fieldname":"to_date", + "label": __("To Date"), + "fieldtype": "Date", + "width": "80", + "reqd": 1, + "default": frappe.datetime.get_today() + }, + { + "fieldname": "sales_order", + "label": __("Sales Order"), + "fieldtype": "MultiSelectList", + "width": "80", + "options": "Sales Order", + "get_data": function(txt) { + return frappe.db.get_link_options("Sales Order", txt); + }, + "get_query": () =>{ + return { + filters: { "docstatus": 1 } + } + } + }, + { + "fieldname": "status", + "label": __("Status"), + "fieldtype": "MultiSelectList", + "width": "80", + get_data: function(txt) { + let status = ["To Bill", "To Deliver", "To Deliver and Bill", "Completed"] + let options = [] + for (let option of status){ + options.push({ + "value": option, + "description": "" + }) + } + return options + } + }, + { + "fieldname": "group_by_so", + "label": __("Group by Sales Order"), + "fieldtype": "Check", + "default": 0 + } + ], + + "formatter": function (value, row, column, data, default_formatter) { + value = default_formatter(value, row, column, data); + let format_fields = ["delivered_qty", "billed_amount"]; + + if (in_list(format_fields, column.fieldname) && data && data[column.fieldname] > 0) { + value = "" + value + ""; + } + + if (column.fieldname == "delay" && data && data[column.fieldname] > 0) { + value = "" + value + ""; + } + return value; + } +}; diff --git a/erpnext/selling/report/sales_order_analysis/sales_order_analysis.json b/erpnext/selling/report/sales_order_analysis/sales_order_analysis.json new file mode 100644 index 0000000000..c0b1d9aa8c --- /dev/null +++ b/erpnext/selling/report/sales_order_analysis/sales_order_analysis.json @@ -0,0 +1,36 @@ +{ + "add_total_row": 1, + "creation": "2020-05-29 14:54:53.591445", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "modified": "2020-05-29 14:54:53.591445", + "modified_by": "Administrator", + "module": "Selling", + "name": "Sales Order Analysis", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Sales Order", + "report_name": "Sales Order Analysis", + "report_type": "Script Report", + "roles": [ + { + "role": "Sales User" + }, + { + "role": "Sales Manager" + }, + { + "role": "Maintenance User" + }, + { + "role": "Accounts User" + }, + { + "role": "Stock User" + } + ] +} \ No newline at end of file diff --git a/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py b/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py new file mode 100644 index 0000000000..7e8e6e9e8b --- /dev/null +++ b/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py @@ -0,0 +1,279 @@ +# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +import copy +from frappe import _ +from frappe.utils import flt, date_diff, getdate + +def execute(filters=None): + if not filters: + return [], [], None, [] + + validate_filters(filters) + + columns = get_columns(filters) + conditions = get_conditions(filters) + data = get_data(conditions, filters) + + if not data: + return [], [], None, [] + + data, chart_data = prepare_data(data, filters) + + return columns, data, None, chart_data + +def validate_filters(filters): + from_date, to_date = filters.get("from_date"), filters.get("to_date") + + if not from_date and to_date: + frappe.throw(_("From and To Dates are required.")) + elif date_diff(to_date, from_date) < 0: + frappe.throw(_("To Date cannot be before From Date.")) + +def get_conditions(filters): + conditions = "" + if filters.get("from_date") and filters.get("to_date"): + conditions += " and so.transaction_date between %(from_date)s and %(to_date)s" + + if filters.get("company"): + conditions += " and so.company = %(company)s" + + if filters.get("sales_order"): + conditions += " and so.name in %(sales_order)s" + + if filters.get("status"): + conditions += " and so.status in %(status)s" + + return conditions + +def get_data(conditions, filters): + data = frappe.db.sql(""" + SELECT + so.transaction_date as date, + soi.delivery_date as delivery_date, + so.name as sales_order, + so.status, so.customer, soi.item_code, + DATEDIFF(CURDATE(), soi.delivery_date) as delay_days, + IF(so.status in ('Completed','To Bill'), 0, (SELECT delay_days)) as delay, + soi.qty, soi.delivered_qty, + (soi.qty - soi.delivered_qty) AS pending_qty, + IFNULL(sii.qty, 0) as billed_qty, + soi.base_amount as amount, + (soi.delivered_qty * soi.base_rate) as delivered_qty_amount, + (soi.billed_amt * IFNULL(so.conversion_rate, 1)) as billed_amount, + (soi.base_amount - (soi.billed_amt * IFNULL(so.conversion_rate, 1))) as pending_amount, + soi.warehouse as warehouse, + so.company, soi.name + FROM + `tabSales Order` so, + `tabSales Order Item` soi + LEFT JOIN `tabSales Invoice Item` sii + ON sii.so_detail = soi.name + WHERE + soi.parent = so.name + and so.status not in ('Stopped', 'Closed', 'On Hold') + and so.docstatus = 1 + {conditions} + GROUP BY soi.name + ORDER BY so.transaction_date ASC + """.format(conditions=conditions), filters, as_dict=1) + + return data + +def prepare_data(data, filters): + completed, pending = 0, 0 + + if filters.get("group_by_so"): + sales_order_map = {} + + for row in data: + # sum data for chart + completed += row["billed_amount"] + pending += row["pending_amount"] + + # prepare data for report view + row["qty_to_bill"] = flt(row["qty"]) - flt(row["billed_qty"]) + + row["delay"] = 0 if row["delay"] < 0 else row["delay"] + if filters.get("group_by_so"): + so_name = row["sales_order"] + + if not so_name in sales_order_map: + # create an entry + row_copy = copy.deepcopy(row) + sales_order_map[so_name] = row_copy + else: + # update existing entry + so_row = sales_order_map[so_name] + so_row["required_date"] = max(getdate(so_row["delivery_date"]), getdate(row["delivery_date"])) + so_row["delay"] = min(so_row["delay"], row["delay"]) + + # sum numeric columns + fields = ["qty", "delivered_qty", "pending_qty", "billed_qty", "qty_to_bill", "amount", + "delivered_qty_amount", "billed_amount", "pending_amount"] + for field in fields: + so_row[field] = flt(row[field]) + flt(so_row[field]) + + chart_data = prepare_chart_data(pending, completed) + + if filters.get("group_by_so"): + data = [] + for so in sales_order_map: + data.append(sales_order_map[so]) + return data, chart_data + + return data, chart_data + +def prepare_chart_data(pending, completed): + labels = ["Amount to Bill", "Billed Amount"] + + return { + "data" : { + "labels": labels, + "datasets": [ + {"values": [pending, completed]} + ] + }, + "type": 'donut', + "height": 300 + } + +def get_columns(filters): + columns = [ + { + "label":_("Date"), + "fieldname": "date", + "fieldtype": "Date", + "width": 90 + }, + { + "label": _("Sales Order"), + "fieldname": "sales_order", + "fieldtype": "Link", + "options": "Sales Order", + "width": 160 + }, + { + "label":_("Status"), + "fieldname": "status", + "fieldtype": "Data", + "width": 130 + }, + { + "label": _("Customer"), + "fieldname": "customer", + "fieldtype": "Link", + "options": "Customer", + "width": 130 + }] + + if not filters.get("group_by_so"): + columns.append({ + "label":_("Item Code"), + "fieldname": "item_code", + "fieldtype": "Link", + "options": "Item", + "width": 100 + }) + + columns.extend([ + { + "label": _("Qty"), + "fieldname": "qty", + "fieldtype": "Float", + "width": 120, + "convertible": "qty" + }, + { + "label": _("Delivered Qty"), + "fieldname": "delivered_qty", + "fieldtype": "Float", + "width": 120, + "convertible": "qty" + }, + { + "label": _("Qty to Deliver"), + "fieldname": "pending_qty", + "fieldtype": "Float", + "width": 120, + "convertible": "qty" + }, + { + "label": _("Billed Qty"), + "fieldname": "billed_qty", + "fieldtype": "Float", + "width": 80, + "convertible": "qty" + }, + { + "label": _("Qty to Bill"), + "fieldname": "qty_to_bill", + "fieldtype": "Float", + "width": 80, + "convertible": "qty" + }, + { + "label": _("Amount"), + "fieldname": "amount", + "fieldtype": "Currency", + "width": 110, + "options": "Company:company:default_currency", + "convertible": "rate" + }, + { + "label": _("Billed Amount"), + "fieldname": "billed_amount", + "fieldtype": "Currency", + "width": 110, + "options": "Company:company:default_currency", + "convertible": "rate" + }, + { + "label": _("Pending Amount"), + "fieldname": "pending_amount", + "fieldtype": "Currency", + "width": 130, + "options": "Company:company:default_currency", + "convertible": "rate" + }, + { + "label": _("Amount Delivered"), + "fieldname": "delivered_qty_amount", + "fieldtype": "Currency", + "width": 100, + "options": "Company:company:default_currency", + "convertible": "rate" + }, + { + "label":_("Delivery Date"), + "fieldname": "delivery_date", + "fieldtype": "Date", + "width": 120 + }, + { + "label": _("Delay (in Days)"), + "fieldname": "delay", + "fieldtype": "Data", + "width": 100 + } + ]) + if not filters.get("group_by_so"): + columns.append({ + "label": _("Warehouse"), + "fieldname": "warehouse", + "fieldtype": "Link", + "options": "Warehouse", + "width": 100 + }) + columns.append({ + "label": _("Company"), + "fieldname": "company", + "fieldtype": "Link", + "options": "Company", + "width": 100 + }) + + + return columns \ No newline at end of file diff --git a/erpnext/selling/report/sales_order_trends/sales_order_trends.py b/erpnext/selling/report/sales_order_trends/sales_order_trends.py index c0a0f085d9..de7d3f2f77 100644 --- a/erpnext/selling/report/sales_order_trends/sales_order_trends.py +++ b/erpnext/selling/report/sales_order_trends/sales_order_trends.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals import frappe +from frappe import _ from erpnext.controllers.trends import get_columns,get_data def execute(filters=None): @@ -10,4 +11,48 @@ def execute(filters=None): data = [] conditions = get_columns(filters, "Sales Order") data = get_data(filters, conditions) - return conditions["columns"], data + chart_data = get_chart_data(data, conditions, filters) + + return conditions["columns"], data, None, chart_data + +def get_chart_data(data, conditions, filters): + if not (data and conditions): + return [] + + datapoints = [] + + start = 2 if filters.get("based_on") in ["Item", "Customer"] else 1 + if filters.get("group_by"): + start += 1 + + # fetch only periodic columns as labels + columns = conditions.get("columns")[start:-2][1::2] + labels = [column.split(':')[0] for column in columns] + datapoints = [0] * len(labels) + + for row in data: + # If group by filter, don't add first row of group (it's already summed) + if not row[start-1]: + continue + # Remove None values and compute only periodic data + row = [x if x else 0 for x in row[start:-2]] + row = row[1::2] + + for i in range(len(row)): + datapoints[i] += row[i] + + return { + "data" : { + "labels" : labels, + "datasets" : [ + { + "name" : _("{0}").format(filters.get("period")) + _(" Sales Value"), + "values" : datapoints + } + ] + }, + "type" : "line", + "lineOptions": { + "regionFill": 1 + } + } diff --git a/erpnext/setup/setup_wizard/operations/install_fixtures.py b/erpnext/setup/setup_wizard/operations/install_fixtures.py index 0d70d91f73..ad063cfc9d 100644 --- a/erpnext/setup/setup_wizard/operations/install_fixtures.py +++ b/erpnext/setup/setup_wizard/operations/install_fixtures.py @@ -50,7 +50,7 @@ def install(country=None): 'is_group': 0, 'parent_item_group': _('All Item Groups') }, # salary component - {'doctype': 'Salary Component', 'salary_component': _('Income Tax'), 'description': _('Income Tax'), 'type': 'Deduction'}, + {'doctype': 'Salary Component', 'salary_component': _('Income Tax'), 'description': _('Income Tax'), 'type': 'Deduction', 'is_income_tax_component': 1}, {'doctype': 'Salary Component', 'salary_component': _('Basic'), 'description': _('Basic'), 'type': 'Earning'}, {'doctype': 'Salary Component', 'salary_component': _('Arrear'), 'description': _('Arrear'), 'type': 'Earning'}, {'doctype': 'Salary Component', 'salary_component': _('Leave Encashment'), 'description': _('Leave Encashment'), 'type': 'Earning'}, diff --git a/erpnext/stock/desk_page/stock/stock.json b/erpnext/stock/desk_page/stock/stock.json index 9404292c04..1bf81f7f0e 100644 --- a/erpnext/stock/desk_page/stock/stock.json +++ b/erpnext/stock/desk_page/stock/stock.json @@ -33,7 +33,7 @@ { "hidden": 0, "label": "Key Reports", - "links": "[\n {\n \"dependencies\": [\n \"Item Price\"\n ],\n \"doctype\": \"Item Price\",\n \"is_query_report\": false,\n \"label\": \"Item-wise Price List Rate\",\n \"name\": \"Item-wise Price List Rate\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Stock Entry\"\n ],\n \"doctype\": \"Stock Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock Analytics\",\n \"name\": \"Stock Analytics\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Delivery Note\"\n ],\n \"doctype\": \"Delivery Note\",\n \"is_query_report\": true,\n \"label\": \"Delivery Note Trends\",\n \"name\": \"Delivery Note Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Receipt\"\n ],\n \"doctype\": \"Purchase Receipt\",\n \"is_query_report\": true,\n \"label\": \"Purchase Receipt Trends\",\n \"name\": \"Purchase Receipt Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Delivery Note\"\n ],\n \"doctype\": \"Delivery Note\",\n \"is_query_report\": true,\n \"label\": \"Ordered Items To Be Delivered\",\n \"name\": \"Ordered Items To Be Delivered\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Order\"\n ],\n \"doctype\": \"Purchase Order\",\n \"is_query_report\": true,\n \"label\": \"Purchase Order Analysis\",\n \"name\": \"Purchase Order Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Bin\"\n ],\n \"doctype\": \"Bin\",\n \"is_query_report\": true,\n \"label\": \"Item Shortage Report\",\n \"name\": \"Item Shortage Report\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Batch\"\n ],\n \"doctype\": \"Batch\",\n \"is_query_report\": true,\n \"label\": \"Batch-Wise Balance History\",\n \"name\": \"Batch-Wise Balance History\",\n \"type\": \"report\"\n }\n]" + "links": "[\n {\n \"dependencies\": [\n \"Item Price\"\n ],\n \"doctype\": \"Item Price\",\n \"is_query_report\": false,\n \"label\": \"Item-wise Price List Rate\",\n \"name\": \"Item-wise Price List Rate\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Stock Entry\"\n ],\n \"doctype\": \"Stock Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock Analytics\",\n \"name\": \"Stock Analytics\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Delivery Note\"\n ],\n \"doctype\": \"Delivery Note\",\n \"is_query_report\": true,\n \"label\": \"Delivery Note Trends\",\n \"name\": \"Delivery Note Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Receipt\"\n ],\n \"doctype\": \"Purchase Receipt\",\n \"is_query_report\": true,\n \"label\": \"Purchase Receipt Trends\",\n \"name\": \"Purchase Receipt Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Analysis\",\n \"name\": \"Sales Order Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Order\"\n ],\n \"doctype\": \"Purchase Order\",\n \"is_query_report\": true,\n \"label\": \"Purchase Order Analysis\",\n \"name\": \"Purchase Order Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Bin\"\n ],\n \"doctype\": \"Bin\",\n \"is_query_report\": true,\n \"label\": \"Item Shortage Report\",\n \"name\": \"Item Shortage Report\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Batch\"\n ],\n \"doctype\": \"Batch\",\n \"is_query_report\": true,\n \"label\": \"Batch-Wise Balance History\",\n \"name\": \"Batch-Wise Balance History\",\n \"type\": \"report\"\n }\n]" }, { "hidden": 0, @@ -58,7 +58,7 @@ "idx": 0, "is_standard": 1, "label": "Stock", - "modified": "2020-05-27 20:38:25.255323", + "modified": "2020-05-30 17:32:11.062681", "modified_by": "Administrator", "module": "Stock", "name": "Stock", diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.js b/erpnext/stock/doctype/stock_settings/stock_settings.js index 877d0c3bbf..d5049ac6ed 100644 --- a/erpnext/stock/doctype/stock_settings/stock_settings.js +++ b/erpnext/stock/doctype/stock_settings/stock_settings.js @@ -20,7 +20,7 @@ frappe.tour['Stock Settings'] = [ { fieldname: "item_naming_by", title: __("Item Naming By"), - description: __("By default, the Item Name is set as per the Item Code entered. If you want Items to be named by a set Naming Series choose the 'Naming Series' option.") + description: __("By default, the Item Name is set as per the Item Code entered. If you want Items to be named by a") + "Naming Series" + __(" choose the 'Naming Series' option."), }, { fieldname: "default_warehouse", diff --git a/erpnext/stock/report/delivery_note_trends/delivery_note_trends.py b/erpnext/stock/report/delivery_note_trends/delivery_note_trends.py index 5a931e7efa..446d3049b7 100644 --- a/erpnext/stock/report/delivery_note_trends/delivery_note_trends.py +++ b/erpnext/stock/report/delivery_note_trends/delivery_note_trends.py @@ -26,9 +26,10 @@ def get_chart_data(data, filters): # consider only consolidated row data = [row for row in data if row[0]] + data = sorted(data, key = lambda i: i[-1],reverse=True) + if len(data) > 10: # get top 10 if data too long - data = sorted(data, key = lambda i: i[-1],reverse=True) data = data[:10] for row in data: diff --git a/erpnext/stock/report/ordered_items_to_be_delivered/ordered_items_to_be_delivered.json b/erpnext/stock/report/ordered_items_to_be_delivered/ordered_items_to_be_delivered.json deleted file mode 100644 index aa5fd0f165..0000000000 --- a/erpnext/stock/report/ordered_items_to_be_delivered/ordered_items_to_be_delivered.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "add_total_row": 1, - "creation": "2018-01-09 18:38:23.540100", - "disable_prepared_report": 0, - "disabled": 0, - "docstatus": 0, - "doctype": "Report", - "idx": 0, - "is_standard": "Yes", - "modified": "2019-04-01 22:10:09.829361", - "modified_by": "Administrator", - "module": "Stock", - "name": "Ordered Items To Be Delivered", - "owner": "Administrator", - "prepared_report": 0, - "query": "select \n `tabSales Order`.`name` as \"Sales Order:Link/Sales Order:120\",\n `tabSales Order`.`status` as \"Status:Data:120\",\n `tabSales Order`.`customer` as \"Customer:Link/Customer:120\",\n `tabSales Order`.`customer_name` as \"Customer Name::150\",\n `tabSales Order`.`transaction_date` as \"Date:Date\",\n `tabSales Order`.`project` as \"Project:Link/Project:120\",\n `tabSales Order Item`.item_code as \"Item:Link/Item:120\",\n `tabSales Order Item`.qty as \"Qty:Float:140\",\n `tabSales Order Item`.delivered_qty as \"Delivered Qty:Float:140\",\n (`tabSales Order Item`.qty - ifnull(`tabSales Order Item`.delivered_qty, 0)) as \"Qty to Deliver:Float:140\",\n `tabSales Order Item`.base_rate as \"Rate:Float:140\",\n `tabSales Order Item`.base_amount as \"Amount:Float:140\",\n ((`tabSales Order Item`.qty - ifnull(`tabSales Order Item`.delivered_qty, 0))*`tabSales Order Item`.base_rate) as \"Amount to Deliver:Float:140\",\n `tabBin`.actual_qty as \"Available Qty:Float:120\",\n `tabBin`.projected_qty as \"Projected Qty:Float:120\",\n `tabSales Order Item`.`delivery_date` as \"Item Delivery Date:Date:120\",\n DATEDIFF(CURDATE(),`tabSales Order Item`.`delivery_date`) as \"Delay Days:Int:120\",\n `tabSales Order Item`.item_name as \"Item Name::150\",\n `tabSales Order Item`.description as \"Description::200\",\n `tabSales Order Item`.item_group as \"Item Group:Link/Item Group:120\",\n `tabSales Order Item`.warehouse as \"Warehouse:Link/Warehouse:200\"\nfrom\n `tabSales Order` JOIN `tabSales Order Item` \n LEFT JOIN `tabBin` ON (`tabBin`.item_code = `tabSales Order Item`.item_code\n and `tabBin`.warehouse = `tabSales Order Item`.warehouse)\nwhere\n `tabSales Order Item`.`parent` = `tabSales Order`.`name`\n and `tabSales Order`.docstatus = 1\n and `tabSales Order`.status not in (\"Stopped\", \"Closed\")\n and ifnull(`tabSales Order Item`.delivered_qty,0) < ifnull(`tabSales Order Item`.qty,0)\norder by `tabSales Order`.transaction_date asc", - "ref_doctype": "Delivery Note", - "report_name": "Ordered Items To Be Delivered", - "report_type": "Query Report", - "roles": [ - { - "role": "Stock User" - }, - { - "role": "Stock Manager" - }, - { - "role": "Sales User" - }, - { - "role": "Accounts User" - } - ] -} \ No newline at end of file diff --git a/erpnext/www/lms/content.html b/erpnext/www/lms/content.html index cdc71412c4..dc9b6d80fb 100644 --- a/erpnext/www/lms/content.html +++ b/erpnext/www/lms/content.html @@ -59,7 +59,7 @@ {% macro title() %}
- Back to Course + {{_('Back to Course')}}
@@ -69,15 +69,15 @@ {% macro navigation() %} {% if previous %} - Previous + {{_('Previous')}} {% else %} - Back to Course + {{ _('Back to Course') }} {% endif %} {% if next %} - + {% else %} - + {% endif %} {% endmacro %} @@ -86,7 +86,7 @@ {{ title() }}
{% if content.duration %} - {{ content.duration }} Mins + {{ content.duration }} {{_('Mins')}} {% endif %} {% if content.publish_date and content.duration%} @@ -94,7 +94,7 @@ {% endif %} {% if content.publish_date %} - Published on {{ content.publish_date.strftime('%d, %b %Y') }} + {{_('Published on')}} {{ content.publish_date.strftime('%d, %b %Y') }} {% endif %}
@@ -109,13 +109,13 @@ {{ title() }}
{% if content.author or content.publish_date %} - Published + {{_('Published')}} {% endif %} {% if content.author %} - by {{ content.author }} + {{_('by')}} {{ content.author }} {% endif %} {% if content.publish_date %} - on {{ content.publish_date.strftime('%d, %b %Y') }} + {{_('on')}} {{ content.publish_date.strftime('%d, %b %Y') }} {% endif %}
@@ -205,4 +205,4 @@ {% endif %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/erpnext/www/lms/course.html b/erpnext/www/lms/course.html index f2fd9363e8..0d70ed5cef 100644 --- a/erpnext/www/lms/course.html +++ b/erpnext/www/lms/course.html @@ -72,11 +72,11 @@ {% if has_access %} diff --git a/erpnext/www/lms/index.html b/erpnext/www/lms/index.html index ffb4419f36..7ce3521273 100644 --- a/erpnext/www/lms/index.html +++ b/erpnext/www/lms/index.html @@ -45,7 +45,7 @@

{{ education_settings.description }}

{% if frappe.session.user == 'Guest' %} - Sign Up + {{_('Sign Up')}} {% endif %}

diff --git a/erpnext/www/lms/macros/card.html b/erpnext/www/lms/macros/card.html index 076061d41b..dc8fc5c72c 100644 --- a/erpnext/www/lms/macros/card.html +++ b/erpnext/www/lms/macros/card.html @@ -15,8 +15,8 @@ {% if has_access or program.intro_video%} {% endif %} diff --git a/erpnext/www/lms/macros/hero.html b/erpnext/www/lms/macros/hero.html index 66bb861c46..94f239eb8e 100644 --- a/erpnext/www/lms/macros/hero.html +++ b/erpnext/www/lms/macros/hero.html @@ -2,16 +2,16 @@
- Back to {{ back.name }} + {{_('Back to')}} {{ _(back.name) }}

{{ title }}

{{ description or ''}}

{% if frappe.session.user == 'Guest' %} - Sign Up + {{_('Sign Up')}} {% elif not has_access %} - + {% endif %}

@@ -28,7 +28,7 @@ let btn = document.getElementById('enroll'); btn.disbaled = true; - btn.innerText = 'Enrolling...' + btn.innerText = __('Enrolling...') let opts = { method: 'erpnext.education.utils.enroll_in_program', @@ -44,7 +44,7 @@ window.location.reload() } }) - success_dialog.set_message('You have successfully enrolled for the program '); + success_dialog.set_message(__('You have successfully enrolled for the program ')); success_dialog.$message.show() success_dialog.show(); btn.disbaled = false; diff --git a/erpnext/www/lms/profile.html b/erpnext/www/lms/profile.html index 9508daedb7..5755dfe6d8 100644 --- a/erpnext/www/lms/profile.html +++ b/erpnext/www/lms/profile.html @@ -30,7 +30,7 @@ @@ -43,11 +43,11 @@
- Back to Home + {{_('Back to Home')}}
- Edit Profile + {{_('Edit Profile')}}

{{ student.first_name }} {{ student.last_name or '' }}

@@ -61,4 +61,4 @@ -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/erpnext/www/lms/program.html b/erpnext/www/lms/program.html index 271b7813bb..7ad618630a 100644 --- a/erpnext/www/lms/program.html +++ b/erpnext/www/lms/program.html @@ -55,11 +55,11 @@ {% if has_access and progress[course.name] %} {% endif %} diff --git a/erpnext/www/lms/topic.html b/erpnext/www/lms/topic.html index 1f0d187664..cd24616cd4 100644 --- a/erpnext/www/lms/topic.html +++ b/erpnext/www/lms/topic.html @@ -23,13 +23,13 @@ {% if has_access %}