Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

install.py 7.8 KiB

il y a 11 ans
il y a 11 ans
Workflow actions (#5598) * Init workflow actions - WIP code - Add hooks to create and update workflow action on document status changes. - Tweak listview to show host document on list view item click - Add new doctype "Pending Workflow Action" - Add allow_self_approval check in Workflow master * Rename doctypes - Rename "Workflow Action" to "Workflow Action Master" - Rename "Pending Workflow Action" to "Workflow Action" - Remove irrelevant files * Clear old workflow action on docstatus change - Add check for user permission before creating a workflow action record - Make doctype changes to support the Workflow Action System * Show host document only if workflow action status is open * Send workflow action mail notifications * Add patch to rename `tabWorkflow Action` to `tab Workflow Master` - Rename table to retain data in `tabWorkflow Action` as it will be overwritten with new structure on migration * Enqueue email * Remove unused files * Add hook for custom has_permission * Optimize send_workflow_action_email method * Add permission_query_condition hook * Show notification based on status * Override get_form_link in list view * Refactor workflow action - Add action link - update workflow action hooks * Avoid repeated creation of Worklow Actions - Update hooks entry to avoid unwanted method call * Fix error with frappe.db.count usage * Fix ui/ux for Workflow Action - Fix action url and improve response on action button click - Fix workflow action template style * Fix Codacy * Add self approval check * Fix codacy * Fix test * Fix python version confilct and a permission error * Fix incorrect 'this' reference * Update with requested changes * Add next action email template option * Fix string formatting * Refactor workflow Action - Make process_workflow_action smaller * Fix bugs and errors due to refactor * Fix workflow field caching * Add a workflow action test * Fix bugs with email template
il y a 7 ans
Email inbox (#2485) * Communication_reconciliation * Email inbox * added collapsed timeline for communication * new email prefill from when only one address * timeline duplication and notifcation and stability fixs * add subject to timeline * email system v7 fixes * added password required validation * use proper email datetime * email inbox v7.1 fixes * email inbox communication_date used instead of created * email inbox communication data cleanup * remove old patch * email inbox permit unlinking * [fix] duplication queue and rename domain to email domain * fix rename domain * email inbox index optimisation * email inbox relink doctype query usability fix * email_inbox Set attachment variable for forwards and replies based on whether it exists or not * uidnext fixes and cleanup * email inbox fix tests * fix rebase timeline issue * email inbox threading and cleanup * email inbox cleanup * bring inbox into frappe and cleanup * fix missed path * inbox cleanup * email-inbox move service back to account * separate to erpnext contact match * email inbox cleanup and move relink and timeline fix * relink optimisation * inbox fix footer * keep email drafts on pages not just forms * email inbox add sent items * email inbox allow not save list settings on query * email inbox cleanup and remove communications recon * add suspend sending button in email queue * fix rebase error * email inbox assorted fixes * email inbox fixes and relink option only when linked otherwise link; * email inbox fix sender fullname as administrator * create user email to custom button * email inbox sent no match and seen * email inbox fix unicode issues with subject recipient and sender
il y a 8 ans
il y a 11 ans
il y a 11 ans
Python 3 compatible print statements (#3199) * changes print statements in file to python 3 compatible style using `__future__` * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * changes deprecated md5 module to hashlib * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements * adds python 3 style for print statements
il y a 8 ans
il y a 8 ans
feat: Optionally remove seconds from datetime (#8531) * fix: Add updated datepicker; fixed seconds formatting bug. Seconds between 0 and 9 were not zero-padded. * feat: Add framework for time format * feat: datetime server-side formatters. * tests: Added server-side datetime formatter tests * feat: Update client-side datetime formatters * tests: Add Cypress client-side formatting tests. * fix: JSON errors * fix: Update to not hard-code admin password * fix: Change to using bulk_update rather than the REST API * tests: Use Custom doctype for testing, not Standard * fix: Codacy style fixes * fix: Commonify update_datetime_picker in date.js, datetime.js, time.js Fix order of time_format in System Settings Restore get_user_fmt in utils/datetime.js * feat: Drastically reduce scale of Cypress testing (to make tests faster) Full testing is possible by setting 'fast_mode' to false in the spec file. * fix: Fix issues with datepicker/timepicker expansion * fix: typo * style: Various style fixes as requested by DeppSource: Python * fix: Timepicker not hiding on 'now' button. Force hiding on click. * style: Codacy style fixes. * fix: Use datepicker from node_modules * test: Refactor Datetime UI tests - cy.get_field - cy.set_value - cy.insert_doc with ignore_duplicate - Nominal datetime tests to cover most formats - Formatting with prettier * test: Datetime UI tests; wait for cur_frm.doc.datetime to update * tests: Add whitespace to typed input - Clear input only for Time field * test: Wait timeout 200 * test: Fix form test Co-authored-by: Faris Ansari <netchampfaris@users.noreply.github.com>
il y a 5 ans
il y a 10 ans
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
  2. # License: MIT. See LICENSE
  3. import frappe
  4. import getpass
  5. from frappe.utils.password import update_password
  6. def before_install():
  7. frappe.reload_doc("core", "doctype", "doctype_state")
  8. frappe.reload_doc("core", "doctype", "docfield")
  9. frappe.reload_doc("core", "doctype", "docperm")
  10. frappe.reload_doc("core", "doctype", "doctype_action")
  11. frappe.reload_doc("core", "doctype", "doctype_link")
  12. frappe.reload_doc("desk", "doctype", "form_tour_step")
  13. frappe.reload_doc("desk", "doctype", "form_tour")
  14. frappe.reload_doc("core", "doctype", "doctype")
  15. def after_install():
  16. # reset installed apps for re-install
  17. frappe.db.set_global("installed_apps", '["frappe"]')
  18. create_user_type()
  19. install_basic_docs()
  20. from frappe.core.doctype.file.file import make_home_folder
  21. make_home_folder()
  22. import_country_and_currency()
  23. from frappe.core.doctype.language.language import sync_languages
  24. sync_languages()
  25. # save default print setting
  26. print_settings = frappe.get_doc("Print Settings")
  27. print_settings.save()
  28. # all roles to admin
  29. frappe.get_doc("User", "Administrator").add_roles(*frappe.db.sql_list("""select name from tabRole"""))
  30. # update admin password
  31. update_password("Administrator", get_admin_password())
  32. if not frappe.conf.skip_setup_wizard:
  33. frappe.db.set_default('desktop:home_page', 'setup-wizard')
  34. # clear test log
  35. with open(frappe.get_site_path('.test_log'), 'w') as f:
  36. f.write('')
  37. add_standard_navbar_items()
  38. frappe.db.commit()
  39. def create_user_type():
  40. for user_type in ['System User', 'Website User']:
  41. if not frappe.db.exists('User Type', user_type):
  42. frappe.get_doc({
  43. 'doctype': 'User Type',
  44. 'name': user_type,
  45. 'is_standard': 1
  46. }).insert(ignore_permissions=True)
  47. def install_basic_docs():
  48. # core users / roles
  49. install_docs = [
  50. {'doctype':'User', 'name':'Administrator', 'first_name':'Administrator',
  51. 'email':'admin@example.com', 'enabled':1, "is_admin": 1,
  52. 'roles': [{'role': 'Administrator'}],
  53. 'thread_notify': 0, 'send_me_a_copy': 0
  54. },
  55. {'doctype':'User', 'name':'Guest', 'first_name':'Guest',
  56. 'email':'guest@example.com', 'enabled':1, "is_guest": 1,
  57. 'roles': [{'role': 'Guest'}],
  58. 'thread_notify': 0, 'send_me_a_copy': 0
  59. },
  60. {'doctype': "Role", "role_name": "Report Manager"},
  61. {'doctype': "Role", "role_name": "Translator"},
  62. {'doctype': "Workflow State", "workflow_state_name": "Pending",
  63. "icon": "question-sign", "style": ""},
  64. {'doctype': "Workflow State", "workflow_state_name": "Approved",
  65. "icon": "ok-sign", "style": "Success"},
  66. {'doctype': "Workflow State", "workflow_state_name": "Rejected",
  67. "icon": "remove", "style": "Danger"},
  68. {'doctype': "Workflow Action Master", "workflow_action_name": "Approve"},
  69. {'doctype': "Workflow Action Master", "workflow_action_name": "Reject"},
  70. {'doctype': "Workflow Action Master", "workflow_action_name": "Review"},
  71. {'doctype': "Email Domain", "domain_name":"example.com", "email_id": "account@example.com", "password": "pass", "email_server": "imap.example.com","use_imap": 1, "smtp_server": "smtp.example.com"},
  72. {'doctype': "Email Account", "domain":"example.com", "email_id": "notifications@example.com", "default_outgoing": 1},
  73. {'doctype': "Email Account", "domain":"example.com", "email_id": "replies@example.com", "default_incoming": 1}
  74. ]
  75. for d in install_docs:
  76. try:
  77. frappe.get_doc(d).insert()
  78. except frappe.NameError:
  79. pass
  80. def get_admin_password():
  81. def ask_admin_password():
  82. admin_password = getpass.getpass("Set Administrator password: ")
  83. admin_password2 = getpass.getpass("Re-enter Administrator password: ")
  84. if not admin_password == admin_password2:
  85. print("\nPasswords do not match")
  86. return ask_admin_password()
  87. return admin_password
  88. admin_password = frappe.conf.get("admin_password")
  89. if not admin_password:
  90. return ask_admin_password()
  91. return admin_password
  92. def before_tests():
  93. if len(frappe.get_installed_apps()) > 1:
  94. # don't run before tests if any other app is installed
  95. return
  96. frappe.db.truncate("Custom Field")
  97. frappe.db.truncate("Event")
  98. frappe.clear_cache()
  99. # complete setup if missing
  100. if not int(frappe.db.get_single_value('System Settings', 'setup_complete') or 0):
  101. complete_setup_wizard()
  102. frappe.db.commit()
  103. frappe.clear_cache()
  104. def complete_setup_wizard():
  105. from frappe.desk.page.setup_wizard.setup_wizard import setup_complete
  106. setup_complete({
  107. "language" :"English",
  108. "email" :"test@erpnext.com",
  109. "full_name" :"Test User",
  110. "password" :"test",
  111. "country" :"United States",
  112. "timezone" :"America/New_York",
  113. "currency" :"USD"
  114. })
  115. def import_country_and_currency():
  116. from frappe.geo.country_info import get_all
  117. from frappe.utils import update_progress_bar
  118. data = get_all()
  119. for i, name in enumerate(data):
  120. update_progress_bar("Updating country info", i, len(data))
  121. country = frappe._dict(data[name])
  122. add_country_and_currency(name, country)
  123. print("")
  124. # enable frequently used currencies
  125. for currency in ("INR", "USD", "GBP", "EUR", "AED", "AUD", "JPY", "CNY", "CHF"):
  126. frappe.db.set_value("Currency", currency, "enabled", 1)
  127. def add_country_and_currency(name, country):
  128. if not frappe.db.exists("Country", name):
  129. frappe.get_doc({
  130. "doctype": "Country",
  131. "country_name": name,
  132. "code": country.code,
  133. "date_format": country.date_format or "dd-mm-yyyy",
  134. "time_format": country.time_format or "HH:mm:ss",
  135. "time_zones": "\n".join(country.timezones or []),
  136. "docstatus": 0
  137. }).db_insert()
  138. if country.currency and not frappe.db.exists("Currency", country.currency):
  139. frappe.get_doc({
  140. "doctype": "Currency",
  141. "currency_name": country.currency,
  142. "fraction": country.currency_fraction,
  143. "symbol": country.currency_symbol,
  144. "fraction_units": country.currency_fraction_units,
  145. "smallest_currency_fraction_value": country.smallest_currency_fraction_value,
  146. "number_format": country.number_format,
  147. "docstatus": 0
  148. }).db_insert()
  149. def add_standard_navbar_items():
  150. navbar_settings = frappe.get_single("Navbar Settings")
  151. standard_navbar_items = [
  152. {
  153. 'item_label': 'My Profile',
  154. 'item_type': 'Route',
  155. 'route': '/app/user-profile',
  156. 'is_standard': 1
  157. },
  158. {
  159. 'item_label': 'My Settings',
  160. 'item_type': 'Action',
  161. 'action': 'frappe.ui.toolbar.route_to_user()',
  162. 'is_standard': 1
  163. },
  164. {
  165. 'item_label': 'Session Defaults',
  166. 'item_type': 'Action',
  167. 'action': 'frappe.ui.toolbar.setup_session_defaults()',
  168. 'is_standard': 1
  169. },
  170. {
  171. 'item_label': 'Reload',
  172. 'item_type': 'Action',
  173. 'action': 'frappe.ui.toolbar.clear_cache()',
  174. 'is_standard': 1
  175. },
  176. {
  177. 'item_label': 'View Website',
  178. 'item_type': 'Action',
  179. 'action': 'frappe.ui.toolbar.view_website()',
  180. 'is_standard': 1
  181. },
  182. {
  183. 'item_label': 'Toggle Full Width',
  184. 'item_type': 'Action',
  185. 'action': 'frappe.ui.toolbar.toggle_full_width()',
  186. 'is_standard': 1
  187. },
  188. {
  189. 'item_label': 'Toggle Theme',
  190. 'item_type': 'Action',
  191. 'action': 'new frappe.ui.ThemeSwitcher().show()',
  192. 'is_standard': 1
  193. },
  194. {
  195. 'item_label': 'Background Jobs',
  196. 'item_type': 'Route',
  197. 'route': '/app/background_jobs',
  198. 'is_standard': 1
  199. },
  200. {
  201. 'item_type': 'Separator',
  202. 'is_standard': 1
  203. },
  204. {
  205. 'item_label': 'Logout',
  206. 'item_type': 'Action',
  207. 'action': 'frappe.app.logout()',
  208. 'is_standard': 1
  209. }
  210. ]
  211. standard_help_items = [
  212. {
  213. 'item_label': 'About',
  214. 'item_type': 'Action',
  215. 'action': 'frappe.ui.toolbar.show_about()',
  216. 'is_standard': 1
  217. },
  218. {
  219. 'item_label': 'Keyboard Shortcuts',
  220. 'item_type': 'Action',
  221. 'action': 'frappe.ui.toolbar.show_shortcuts(event)',
  222. 'is_standard': 1
  223. }
  224. ]
  225. navbar_settings.settings_dropdown = []
  226. navbar_settings.help_dropdown = []
  227. for item in standard_navbar_items:
  228. navbar_settings.append('settings_dropdown', item)
  229. for item in standard_help_items:
  230. navbar_settings.append('help_dropdown', item)
  231. navbar_settings.save()