Anand Doshi | 885e074 | 2015-03-03 14:55:30 +0530 | [diff] [blame] | 1 | # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors |
Rushabh Mehta | e67d1fb | 2013-08-05 14:59:54 +0530 | [diff] [blame] | 2 | # License: GNU General Public License v3. See license.txt |
| 3 | |
Rushabh Mehta | 6f9915c | 2013-01-16 17:48:17 +0530 | [diff] [blame] | 4 | |
Rushabh Mehta | 793ba6b | 2014-02-14 15:47:51 +0530 | [diff] [blame] | 5 | import frappe |
Rushabh Mehta | d42167e | 2016-05-11 16:47:14 +0530 | [diff] [blame] | 6 | from frappe import _ |
Nabin Hait | 45dce89 | 2017-09-14 15:17:38 +0530 | [diff] [blame] | 7 | from frappe.custom.doctype.custom_field.custom_field import create_custom_field |
Chillar Anand | 915b343 | 2021-09-02 16:44:59 +0530 | [diff] [blame] | 8 | from frappe.desk.page.setup_wizard.setup_wizard import add_all_roles_to |
| 9 | from frappe.installer import update_site_config |
| 10 | from frappe.utils import cint |
Rushabh Mehta | 6f9915c | 2013-01-16 17:48:17 +0530 | [diff] [blame] | 11 | |
Chillar Anand | 915b343 | 2021-09-02 16:44:59 +0530 | [diff] [blame] | 12 | from erpnext.accounts.doctype.cash_flow_mapper.default_cash_flow_mapper import DEFAULT_MAPPERS |
| 13 | from erpnext.setup.default_energy_point_rules import get_default_energy_point_rules |
| 14 | |
| 15 | from .default_success_action import get_default_success_action |
| 16 | |
Anand Doshi | 56198f4 | 2014-06-26 12:47:45 +0530 | [diff] [blame] | 17 | default_mail_footer = """<div style="padding: 7px; text-align: right; color: #888"><small>Sent via |
Anand Doshi | 7f41ff2 | 2014-06-26 12:02:55 +0530 | [diff] [blame] | 18 | <a style="color: #888" href="http://erpnext.org">ERPNext</a></div>""" |
| 19 | |
tundebabzy | cad22db | 2018-02-22 06:38:36 +0100 | [diff] [blame] | 20 | |
Rushabh Mehta | 1f84799 | 2013-12-12 19:12:19 +0530 | [diff] [blame] | 21 | def after_install(): |
Rushabh Mehta | 40b2b03 | 2014-04-21 13:43:11 +0530 | [diff] [blame] | 22 | frappe.get_doc({'doctype': "Role", "role_name": "Analytics"}).insert() |
Rushabh Mehta | 33003c6 | 2014-04-30 11:16:02 +0530 | [diff] [blame] | 23 | set_single_defaults() |
Rushabh Mehta | d42167e | 2016-05-11 16:47:14 +0530 | [diff] [blame] | 24 | create_compact_item_print_custom_field() |
Frappe ERPnext | f28bef8 | 2020-09-02 21:42:52 +0200 | [diff] [blame] | 25 | create_print_uom_after_qty_custom_field() |
Nabin Hait | 45dce89 | 2017-09-14 15:17:38 +0530 | [diff] [blame] | 26 | create_print_zero_amount_taxes_custom_field() |
Rushabh Mehta | db7139a | 2013-01-17 18:22:22 +0530 | [diff] [blame] | 27 | add_all_roles_to("Administrator") |
tundebabzy | cad22db | 2018-02-22 06:38:36 +0100 | [diff] [blame] | 28 | create_default_cash_flow_mapper_templates() |
Suraj Shetty | 00cced1 | 2018-05-03 19:06:32 +0530 | [diff] [blame] | 29 | create_default_success_action() |
Suraj Shetty | 627a3dc | 2019-09-17 15:54:41 +0530 | [diff] [blame] | 30 | create_default_energy_point_rules() |
Rucha Mahabal | 4865eab | 2019-07-24 13:37:54 +0530 | [diff] [blame] | 31 | add_company_to_session_defaults() |
Deepesh Garg | a306af8 | 2020-08-06 20:52:02 +0530 | [diff] [blame] | 32 | add_standard_navbar_items() |
Shivam Mishra | 1323a9a | 2020-09-30 16:33:14 +0530 | [diff] [blame] | 33 | add_app_name() |
Rohit Waghchaure | 03635fb | 2021-01-18 15:06:35 +0530 | [diff] [blame] | 34 | add_non_standard_user_types() |
Anand Doshi | e9baaa6 | 2014-02-26 12:35:33 +0530 | [diff] [blame] | 35 | frappe.db.commit() |
Rushabh Mehta | db7139a | 2013-01-17 18:22:22 +0530 | [diff] [blame] | 36 | |
tundebabzy | cad22db | 2018-02-22 06:38:36 +0100 | [diff] [blame] | 37 | |
Rushabh Mehta | d55bdcf | 2015-12-31 11:12:48 +0530 | [diff] [blame] | 38 | def check_setup_wizard_not_completed(): |
Saurabh | 58d05ac | 2020-08-10 19:36:45 +0530 | [diff] [blame] | 39 | if cint(frappe.db.get_single_value('System Settings', 'setup_complete') or 0): |
Deepesh Garg | a306af8 | 2020-08-06 20:52:02 +0530 | [diff] [blame] | 40 | message = """ERPNext can only be installed on a fresh site where the setup wizard is not completed. |
Faris Ansari | f3a6e30 | 2020-07-08 10:45:55 +0530 | [diff] [blame] | 41 | You can reinstall this site (after saving your data) using: bench --site [sitename] reinstall""" |
Ankush Menat | ff96bdf | 2021-05-25 19:54:40 +0530 | [diff] [blame] | 42 | frappe.throw(message) # nosemgrep |
Rushabh Mehta | d55bdcf | 2015-12-31 11:12:48 +0530 | [diff] [blame] | 43 | |
tundebabzy | cad22db | 2018-02-22 06:38:36 +0100 | [diff] [blame] | 44 | |
Pratik Vyas | 28da752 | 2014-02-19 20:53:45 +0530 | [diff] [blame] | 45 | def set_single_defaults(): |
Rushabh Mehta | b62ed7a | 2016-10-13 11:00:00 +0530 | [diff] [blame] | 46 | for dt in ('Accounts Settings', 'Print Settings', 'HR Settings', 'Buying Settings', |
Suraj Shetty | d3069fe | 2018-02-21 15:15:43 +0530 | [diff] [blame] | 47 | 'Selling Settings', 'Stock Settings'): |
Anand Doshi | eb7fea6 | 2014-03-19 17:10:01 +0530 | [diff] [blame] | 48 | default_values = frappe.db.sql("""select fieldname, `default` from `tabDocField` |
Rushabh Mehta | f14b809 | 2014-04-03 14:30:42 +0530 | [diff] [blame] | 49 | where parent=%s""", dt) |
Anand Doshi | eb7fea6 | 2014-03-19 17:10:01 +0530 | [diff] [blame] | 50 | if default_values: |
| 51 | try: |
Rushabh Mehta | b385ecf | 2014-03-28 16:44:37 +0530 | [diff] [blame] | 52 | b = frappe.get_doc(dt, dt) |
Anand Doshi | eb7fea6 | 2014-03-19 17:10:01 +0530 | [diff] [blame] | 53 | for fieldname, value in default_values: |
Anand Doshi | f78d1ae | 2014-03-28 13:55:00 +0530 | [diff] [blame] | 54 | b.set(fieldname, value) |
Anand Doshi | eb7fea6 | 2014-03-19 17:10:01 +0530 | [diff] [blame] | 55 | b.save() |
| 56 | except frappe.MandatoryError: |
| 57 | pass |
Rushabh Mehta | b62ed7a | 2016-10-13 11:00:00 +0530 | [diff] [blame] | 58 | except frappe.ValidationError: |
| 59 | pass |
Rushabh Mehta | d42167e | 2016-05-11 16:47:14 +0530 | [diff] [blame] | 60 | |
rtdany10 | 227466c | 2021-09-04 14:04:56 +0530 | [diff] [blame] | 61 | frappe.db.set_default("date_format", "dd-mm-yyyy") |
Deepesh Garg | e2dab6f | 2022-01-10 17:31:38 +0530 | [diff] [blame] | 62 | |
| 63 | setup_currency_exchange() |
| 64 | |
| 65 | def setup_currency_exchange(): |
rtdany10 | 227466c | 2021-09-04 14:04:56 +0530 | [diff] [blame] | 66 | ces = frappe.get_single('Currency Exchange Settings') |
| 67 | try: |
Deepesh Garg | e2dab6f | 2022-01-10 17:31:38 +0530 | [diff] [blame] | 68 | ces.set('result_key', []) |
| 69 | ces.set('req_params', []) |
| 70 | |
| 71 | ces.api_endpoint = "https://frankfurter.app/{transaction_date}" |
| 72 | ces.append('result_key', {'key': 'rates'}) |
| 73 | ces.append('result_key', {'key': '{to_currency}'}) |
| 74 | ces.append('req_params', {'key': 'base', 'value': '{from_currency}'}) |
| 75 | ces.append('req_params', {'key': 'symbols', 'value': '{to_currency}'}) |
rtdany10 | 227466c | 2021-09-04 14:04:56 +0530 | [diff] [blame] | 76 | ces.save() |
| 77 | except frappe.ValidationError: |
| 78 | pass |
tundebabzy | cad22db | 2018-02-22 06:38:36 +0100 | [diff] [blame] | 79 | |
Rushabh Mehta | d42167e | 2016-05-11 16:47:14 +0530 | [diff] [blame] | 80 | def create_compact_item_print_custom_field(): |
Rushabh Mehta | d42167e | 2016-05-11 16:47:14 +0530 | [diff] [blame] | 81 | create_custom_field('Print Settings', { |
| 82 | 'label': _('Compact Item Print'), |
| 83 | 'fieldname': 'compact_item_print', |
| 84 | 'fieldtype': 'Check', |
| 85 | 'default': 1, |
| 86 | 'insert_after': 'with_letterhead' |
Nabin Hait | 45dce89 | 2017-09-14 15:17:38 +0530 | [diff] [blame] | 87 | }) |
| 88 | |
tundebabzy | cad22db | 2018-02-22 06:38:36 +0100 | [diff] [blame] | 89 | |
Frappe ERPnext | f28bef8 | 2020-09-02 21:42:52 +0200 | [diff] [blame] | 90 | def create_print_uom_after_qty_custom_field(): |
| 91 | create_custom_field('Print Settings', { |
| 92 | 'label': _('Print UOM after Quantity'), |
| 93 | 'fieldname': 'print_uom_after_quantity', |
| 94 | 'fieldtype': 'Check', |
| 95 | 'default': 0, |
| 96 | 'insert_after': 'compact_item_print' |
| 97 | }) |
| 98 | |
| 99 | |
Nabin Hait | 45dce89 | 2017-09-14 15:17:38 +0530 | [diff] [blame] | 100 | def create_print_zero_amount_taxes_custom_field(): |
| 101 | create_custom_field('Print Settings', { |
| 102 | 'label': _('Print taxes with zero amount'), |
| 103 | 'fieldname': 'print_taxes_with_zero_amount', |
| 104 | 'fieldtype': 'Check', |
| 105 | 'default': 0, |
| 106 | 'insert_after': 'allow_print_for_cancelled' |
tundebabzy | cad22db | 2018-02-22 06:38:36 +0100 | [diff] [blame] | 107 | }) |
| 108 | |
| 109 | |
| 110 | def create_default_cash_flow_mapper_templates(): |
Suraj Shetty | 00cced1 | 2018-05-03 19:06:32 +0530 | [diff] [blame] | 111 | for mapper in DEFAULT_MAPPERS: |
tundebabzy | cad22db | 2018-02-22 06:38:36 +0100 | [diff] [blame] | 112 | if not frappe.db.exists('Cash Flow Mapper', mapper['section_name']): |
| 113 | doc = frappe.get_doc(mapper) |
| 114 | doc.insert(ignore_permissions=True) |
Suraj Shetty | 00cced1 | 2018-05-03 19:06:32 +0530 | [diff] [blame] | 115 | |
| 116 | def create_default_success_action(): |
| 117 | for success_action in get_default_success_action(): |
| 118 | if not frappe.db.exists('Success Action', success_action.get("ref_doctype")): |
| 119 | doc = frappe.get_doc(success_action) |
| 120 | doc.insert(ignore_permissions=True) |
Rucha Mahabal | 4865eab | 2019-07-24 13:37:54 +0530 | [diff] [blame] | 121 | |
Suraj Shetty | 627a3dc | 2019-09-17 15:54:41 +0530 | [diff] [blame] | 122 | def create_default_energy_point_rules(): |
| 123 | |
| 124 | for rule in get_default_energy_point_rules(): |
| 125 | # check if any rule for ref. doctype exists |
| 126 | rule_exists = frappe.db.exists('Energy Point Rule', { |
| 127 | 'reference_doctype': rule.get('reference_doctype') |
| 128 | }) |
| 129 | if rule_exists: continue |
| 130 | doc = frappe.get_doc(rule) |
| 131 | doc.insert(ignore_permissions=True) |
| 132 | |
Rucha Mahabal | 4865eab | 2019-07-24 13:37:54 +0530 | [diff] [blame] | 133 | def add_company_to_session_defaults(): |
| 134 | settings = frappe.get_single("Session Default Settings") |
| 135 | settings.append("session_defaults", { |
| 136 | "ref_doctype": "Company" |
| 137 | }) |
| 138 | settings.save() |
Deepesh Garg | a306af8 | 2020-08-06 20:52:02 +0530 | [diff] [blame] | 139 | |
| 140 | def add_standard_navbar_items(): |
| 141 | navbar_settings = frappe.get_single("Navbar Settings") |
| 142 | |
| 143 | erpnext_navbar_items = [ |
| 144 | { |
| 145 | 'item_label': 'Documentation', |
| 146 | 'item_type': 'Route', |
| 147 | 'route': 'https://erpnext.com/docs/user/manual', |
| 148 | 'is_standard': 1 |
| 149 | }, |
| 150 | { |
| 151 | 'item_label': 'User Forum', |
| 152 | 'item_type': 'Route', |
| 153 | 'route': 'https://discuss.erpnext.com', |
| 154 | 'is_standard': 1 |
| 155 | }, |
| 156 | { |
| 157 | 'item_label': 'Report an Issue', |
| 158 | 'item_type': 'Route', |
| 159 | 'route': 'https://github.com/frappe/erpnext/issues', |
| 160 | 'is_standard': 1 |
| 161 | } |
| 162 | ] |
| 163 | |
prssanna | 194dd12 | 2021-03-24 16:45:32 +0530 | [diff] [blame] | 164 | current_navbar_items = navbar_settings.help_dropdown |
Deepesh Garg | a306af8 | 2020-08-06 20:52:02 +0530 | [diff] [blame] | 165 | navbar_settings.set('help_dropdown', []) |
| 166 | |
| 167 | for item in erpnext_navbar_items: |
prssanna | 194dd12 | 2021-03-24 16:45:32 +0530 | [diff] [blame] | 168 | current_labels = [item.get('item_label') for item in current_navbar_items] |
| 169 | if not item.get('item_label') in current_labels: |
| 170 | navbar_settings.append('help_dropdown', item) |
Deepesh Garg | a306af8 | 2020-08-06 20:52:02 +0530 | [diff] [blame] | 171 | |
prssanna | 194dd12 | 2021-03-24 16:45:32 +0530 | [diff] [blame] | 172 | for item in current_navbar_items: |
Deepesh Garg | a306af8 | 2020-08-06 20:52:02 +0530 | [diff] [blame] | 173 | navbar_settings.append('help_dropdown', { |
| 174 | 'item_label': item.item_label, |
| 175 | 'item_type': item.item_type, |
| 176 | 'route': item.route, |
| 177 | 'action': item.action, |
| 178 | 'is_standard': item.is_standard, |
| 179 | 'hidden': item.hidden |
| 180 | }) |
| 181 | |
| 182 | navbar_settings.save() |
Shivam Mishra | 1323a9a | 2020-09-30 16:33:14 +0530 | [diff] [blame] | 183 | |
| 184 | def add_app_name(): |
Rushabh Mehta | 45735b3 | 2021-03-16 12:22:31 +0530 | [diff] [blame] | 185 | frappe.db.set_value('System Settings', None, 'app_name', 'ERPNext') |
Rohit Waghchaure | 03635fb | 2021-01-18 15:06:35 +0530 | [diff] [blame] | 186 | |
| 187 | def add_non_standard_user_types(): |
| 188 | user_types = get_user_types_data() |
| 189 | |
| 190 | user_type_limit = {} |
Ankush Menat | 8fe5feb | 2021-11-04 19:48:32 +0530 | [diff] [blame] | 191 | for user_type, data in user_types.items(): |
Rucha Mahabal | 6c1c85b | 2022-01-27 00:51:29 +0530 | [diff] [blame] | 192 | user_type_limit.setdefault(frappe.scrub(user_type), 20) |
Rohit Waghchaure | 03635fb | 2021-01-18 15:06:35 +0530 | [diff] [blame] | 193 | |
| 194 | update_site_config('user_type_doctype_limit', user_type_limit) |
| 195 | |
Ankush Menat | 8fe5feb | 2021-11-04 19:48:32 +0530 | [diff] [blame] | 196 | for user_type, data in user_types.items(): |
Rohit Waghchaure | 03635fb | 2021-01-18 15:06:35 +0530 | [diff] [blame] | 197 | create_custom_role(data) |
| 198 | create_user_type(user_type, data) |
| 199 | |
| 200 | def get_user_types_data(): |
| 201 | return { |
Rohit Waghchaure | 610ccd4 | 2021-03-16 00:39:10 +0530 | [diff] [blame] | 202 | 'Employee Self Service': { |
| 203 | 'role': 'Employee Self Service', |
Rohit Waghchaure | 03635fb | 2021-01-18 15:06:35 +0530 | [diff] [blame] | 204 | 'apply_user_permission_on': 'Employee', |
| 205 | 'user_id_field': 'user_id', |
| 206 | 'doctypes': { |
Rucha Mahabal | 6c1c85b | 2022-01-27 00:51:29 +0530 | [diff] [blame] | 207 | # masters |
| 208 | 'Holiday List': ['read'], |
Rohit Waghchaure | 03635fb | 2021-01-18 15:06:35 +0530 | [diff] [blame] | 209 | 'Employee': ['read', 'write'], |
Rucha Mahabal | 6c1c85b | 2022-01-27 00:51:29 +0530 | [diff] [blame] | 210 | # payroll |
| 211 | 'Salary Slip': ['read'], |
| 212 | 'Employee Benefit Application': ['read', 'write', 'create', 'delete'], |
| 213 | # expenses |
Rohit Waghchaure | 610ccd4 | 2021-03-16 00:39:10 +0530 | [diff] [blame] | 214 | 'Expense Claim': ['read', 'write', 'create', 'delete'], |
Rucha Mahabal | 6c1c85b | 2022-01-27 00:51:29 +0530 | [diff] [blame] | 215 | 'Employee Advance': ['read', 'write', 'create', 'delete'], |
| 216 | # leave and attendance |
Rohit Waghchaure | 610ccd4 | 2021-03-16 00:39:10 +0530 | [diff] [blame] | 217 | 'Leave Application': ['read', 'write', 'create', 'delete'], |
| 218 | 'Attendance Request': ['read', 'write', 'create', 'delete'], |
| 219 | 'Compensatory Leave Request': ['read', 'write', 'create', 'delete'], |
Rucha Mahabal | 6c1c85b | 2022-01-27 00:51:29 +0530 | [diff] [blame] | 220 | # tax |
Rohit Waghchaure | 610ccd4 | 2021-03-16 00:39:10 +0530 | [diff] [blame] | 221 | 'Employee Tax Exemption Declaration': ['read', 'write', 'create', 'delete'], |
| 222 | 'Employee Tax Exemption Proof Submission': ['read', 'write', 'create', 'delete'], |
Rucha Mahabal | 6c1c85b | 2022-01-27 00:51:29 +0530 | [diff] [blame] | 223 | # projects |
| 224 | 'Timesheet': ['read', 'write', 'create', 'delete', 'submit', 'cancel', 'amend'], |
| 225 | # trainings |
| 226 | 'Training Program': ['read'], |
| 227 | 'Training Feedback': ['read', 'write', 'create', 'delete', 'submit', 'cancel', 'amend'], |
| 228 | # shifts |
| 229 | 'Shift Request': ['read', 'write', 'create', 'delete', 'submit', 'cancel', 'amend'], |
| 230 | # misc |
| 231 | 'Employee Grievance': ['read', 'write', 'create', 'delete'], |
| 232 | 'Employee Referral': ['read', 'write', 'create', 'delete'], |
| 233 | 'Travel Request': ['read', 'write', 'create', 'delete'] |
Rohit Waghchaure | 03635fb | 2021-01-18 15:06:35 +0530 | [diff] [blame] | 234 | } |
| 235 | } |
| 236 | } |
| 237 | |
| 238 | def create_custom_role(data): |
| 239 | if data.get('role') and not frappe.db.exists('Role', data.get('role')): |
| 240 | frappe.get_doc({ |
| 241 | 'doctype': 'Role', |
| 242 | 'role_name': data.get('role'), |
| 243 | 'desk_access': 1, |
| 244 | 'is_custom': 1 |
| 245 | }).insert(ignore_permissions=True) |
| 246 | |
| 247 | def create_user_type(user_type, data): |
| 248 | if frappe.db.exists('User Type', user_type): |
| 249 | doc = frappe.get_cached_doc('User Type', user_type) |
| 250 | doc.user_doctypes = [] |
| 251 | else: |
| 252 | doc = frappe.new_doc('User Type') |
| 253 | doc.update({ |
| 254 | 'name': user_type, |
| 255 | 'role': data.get('role'), |
| 256 | 'user_id_field': data.get('user_id_field'), |
| 257 | 'apply_user_permission_on': data.get('apply_user_permission_on') |
| 258 | }) |
| 259 | |
| 260 | create_role_permissions_for_doctype(doc, data) |
| 261 | doc.save(ignore_permissions=True) |
| 262 | |
| 263 | def create_role_permissions_for_doctype(doc, data): |
Ankush Menat | 8fe5feb | 2021-11-04 19:48:32 +0530 | [diff] [blame] | 264 | for doctype, perms in data.get('doctypes').items(): |
Rohit Waghchaure | 03635fb | 2021-01-18 15:06:35 +0530 | [diff] [blame] | 265 | args = {'document_type': doctype} |
| 266 | for perm in perms: |
| 267 | args[perm] = 1 |
| 268 | |
| 269 | doc.append('user_doctypes', args) |
Rohit Waghchaure | a8f78fa | 2021-04-13 18:43:57 +0530 | [diff] [blame] | 270 | |
| 271 | def update_select_perm_after_install(): |
| 272 | if not frappe.flags.update_select_perm_after_migrate: |
| 273 | return |
| 274 | |
| 275 | frappe.flags.ignore_select_perm = False |
| 276 | for row in frappe.get_all('User Type', filters= {'is_standard': 0}): |
| 277 | print('Updating user type :- ', row.name) |
| 278 | doc = frappe.get_doc('User Type', row.name) |
| 279 | doc.save() |
| 280 | |
| 281 | frappe.flags.update_select_perm_after_migrate = False |