From c82331bc1982a675f681c73df8155789945033d3 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Thu, 12 Feb 2015 18:58:28 +0530 Subject: [PATCH] [design] Setup Wizard --- .../chart_of_accounts/chart_of_accounts.py | 4 +- erpnext/hooks.py | 5 + .../setup/page/setup_wizard/setup_wizard.css | 78 +- .../setup/page/setup_wizard/setup_wizard.js | 807 ++++++++++-------- .../setup/page/setup_wizard/setup_wizard.py | 10 +- .../setup_wizard/setup_wizard_message.html | 7 + .../page/setup_wizard/setup_wizard_page.html | 18 +- 7 files changed, 553 insertions(+), 376 deletions(-) create mode 100644 erpnext/setup/page/setup_wizard/setup_wizard_message.html diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py b/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py index 9df3b88ea6..02ffb99aa8 100644 --- a/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py +++ b/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py @@ -97,5 +97,7 @@ def get_charts_for_country(country): with open(os.path.join(os.path.dirname(__file__), "syscohada_syscohada_chart_template.json"), "r") as f: _get_chart_name(f.read()) - charts.append("Standard") + if len(charts) > 1: + charts.append("Standard") + return charts diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 2499a61a8f..ffc9496def 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -68,3 +68,8 @@ scheduler_events = { default_mail_footer = """
Sent via ERPNext
""" + +get_translated_dict = { + ("page", "setup-wizard"): "frappe.geo.country_info.get_translated_dict", + ("doctype", "Global Defaults"): "frappe.geo.country_info.get_translated_dict" +} diff --git a/erpnext/setup/page/setup_wizard/setup_wizard.css b/erpnext/setup/page/setup_wizard/setup_wizard.css index 6ff5b12d7d..41eef343c0 100644 --- a/erpnext/setup/page/setup_wizard/setup_wizard.css +++ b/erpnext/setup/page/setup_wizard/setup_wizard.css @@ -1,26 +1,70 @@ -#page-setup-wizard { - position: fixed; - top: 0px; bottom: 0px; - left: 0px; right: 0px; - overflow: auto; - padding-top: 30px; -} -.setup-wizard-wrapper { - margin: 0px auto; +.setup-wizard-slide { + padding-left: 0px; + padding-right: 0px; } @media (min-width: 768px) { - .setup-wizard-wrapper { - width: 725px; + .setup-wizard-slide.single-column { + max-width: 500px; + } + + .setup-wizard-slide.two-column { + max-width: 768px; } } -#page-setup-wizard .col-md-6 .control-input .btn { - width: 100%; +.setup-wizard-slide .lead { + margin-bottom: 10px; } -#page-setup-wizard .form-section { - margin: 0px -15px; - padding: 0px; - max-width: 400px; +.setup-wizard-slide .form { + margin-top: 20px; + border: 1px solid #d1d8dd; + box-shadow: 0px 3px 5px rgba(0, 0, 0, 0.1); +} + +.setup-wizard-slide .footer { + margin: 20px auto; +} + +.setup-wizard-progress { + border-bottom: 1px solid #d1d8dd; + padding-bottom: 15px; + margin: -20px auto 20px; +} + +.setup-wizard-slide .icon-fixed-width { + vertical-align: middle; +} + +.setup-wizard-slide .icon-circle-blank { + font-size: 7px; +} + +.setup-wizard-slide .icon-circle { + font-size: 10px; +} + +.setup-wizard-slide .frappe-control[data-fieldtype="Attach Image"] { + text-align: center; +} + +.setup-wizard-slide .missing-image, +.setup-wizard-slide .attach-image-display { + display: block; + position: relative; + left: 50%; + transform: translate(-50%, 0); + -webkit-transform: translate(-50%, 0); +} + +.setup-wizard-slide .missing-image .octicon { + position: relative; + top: 50%; + transform: translate(0px, -50%); + -webkit-transform: translate(0px, -50%); +} + +.setup-wizard-message-image { + margin: 15px auto; } diff --git a/erpnext/setup/page/setup_wizard/setup_wizard.js b/erpnext/setup/page/setup_wizard/setup_wizard.js index c31fab4cdf..a10dc80388 100644 --- a/erpnext/setup/page/setup_wizard/setup_wizard.js +++ b/erpnext/setup/page/setup_wizard/setup_wizard.js @@ -1,3 +1,5 @@ +frappe.provide("erpnext.wiz"); + frappe.pages['setup-wizard'].on_page_load = function(wrapper) { if(sys_defaults.company) { frappe.set_route("desktop"); @@ -10,360 +12,36 @@ frappe.pages['setup-wizard'].on_page_load = function(wrapper) { page_name: "setup-wizard", parent: wrapper, on_complete: function(wiz) { - var values = wiz.get_values(); - wiz.show_working(); - frappe.call({ - method: "erpnext.setup.page.setup_wizard.setup_wizard.setup_account", - args: values, - callback: function(r) { - wiz.show_complete(); - setTimeout(function() { - if(user==="Administrator") { - msgprint(__("Login with your new User ID") + ": " + values.email); - setTimeout(function() { - frappe.app.logout(); - }, 2000); - } else { - window.location = "/desk"; - } - }, 2000); - }, - error: function(r) { - - var d = msgprint(__("There were errors.")); - d.custom_onhide = function() { - frappe.set_route(erpnext.wiz.page_name, "0"); - }; - } - }) + erpnext.wiz.setup_account(wiz); }, title: __("Welcome"), - working_html: function() { return '

\ -

'+__('Setting up...')+'

\ -

' + - __('Sit tight while your system is being setup. This may take a few moments.') + - '

' }, - complete_html: function() { return '

\ -

'+__('Setup Complete')+'

\ -

' + - __('Your setup is complete. Refreshing...') + - '

'}, + working_html: erpnext.wiz.working_html, + complete_html: erpnext.wiz.complete_html, slides: [ - // User - { - title: __("Select Your Language"), - icon: "icon-globe", - fields: [ - { - "fieldname": "language", "label": __("Language"), "fieldtype": "Select", - reqd:1 - }, - ], - help: "", - onload: function(slide) { - var me = this; - var select = slide.get_field("language"); - - if (!this.language_list) { - frappe.call({ - method: "erpnext.setup.page.setup_wizard.setup_wizard.load_languages", - callback: function(r) { - me.language_list = r.message; - select.df.options = me.language_list; - select.set_input("english"); - } - }) - } else { - select.df.options = this.language_list; - select.refresh(); - } - - slide.get_input("language").on("change", function() { - var lang = $(this).val() || "english"; - frappe._messages = {}; - frappe.call({ - method: "erpnext.setup.page.setup_wizard.setup_wizard.load_messages", - args: { - language: lang - }, - callback: function(r) { - // re-render all slides - $.each(slide.wiz.slide_dict, function(key, s) { - s.make(); - }); - - // select is re-made after language change - var select = slide.get_field("language"); - select.set_input(lang); - } - }) - }); - } - }, - - { - title: __("The First User: You"), - icon: "icon-user", - fields: [ - {"fieldname": "first_name", "label": __("First Name"), "fieldtype": "Data", - reqd:1}, - {"fieldname": "last_name", "label": __("Last Name"), "fieldtype": "Data", - reqd:1}, - {"fieldname": "email", "label": __("Email Id"), "fieldtype": "Data", - reqd:1, "description": __("Your Login Id"), "options":"Email"}, - {"fieldname": "password", "label": __("Password"), "fieldtype": "Password", - reqd:1}, - {fieldtype:"Attach Image", fieldname:"attach_user", - label: __("Attach Your Picture")}, - ], - help: __('The first user will become the System Manager (you can change that later).'), - onload: function(slide) { - if(user!=="Administrator") { - slide.form.fields_dict.password.$wrapper.toggle(false); - slide.form.fields_dict.email.$wrapper.toggle(false); - slide.form.fields_dict.first_name.set_input(frappe.boot.user.first_name); - slide.form.fields_dict.last_name.set_input(frappe.boot.user.last_name); - - var user_image = frappe.get_cookie("user_image"); - if(user_image) { - var $attach_user = slide.form.fields_dict.attach_user.$wrapper; - $attach_user.find(".missing-image").toggle(false); - $attach_user.find("img").attr("src", user_image).toggle(true); - } - - delete slide.form.fields_dict.email; - delete slide.form.fields_dict.password; - } - } - }, - - // Country - { - title: __("Country, Timezone and Currency"), - icon: "icon-flag", - fields: [ - {fieldname:'country', label: __('Country'), reqd:1, - options: "", fieldtype: 'Select'}, - {fieldname:'currency', label: __('Default Currency'), reqd:1, - options: "", fieldtype: 'Select'}, - {fieldname:'timezone', label: __('Time Zone'), reqd:1, - options: "", fieldtype: 'Select'}, - {fieldname:'chart_of_accounts', label: __('Chart of Accounts'), - options: "", fieldtype: 'Select'} - ], - help: __('Select your home country and check the timezone and currency.'), - onload: function(slide, form) { - frappe.call({ - method:"frappe.geo.country_info.get_country_timezone_info", - callback: function(data) { - frappe.country_info = data.message.country_info; - frappe.all_timezones = data.message.all_timezones; - slide.get_input("country").empty() - .add_options([""].concat(keys(frappe.country_info).sort())); - slide.get_input("currency").empty() - .add_options(frappe.utils.unique([""].concat($.map(frappe.country_info, - function(opts, country) { return opts.currency; }))).sort()); - slide.get_input("timezone").empty() - .add_options([""].concat(frappe.all_timezones)); - } - }) - - slide.get_input("country").on("change", function() { - var country = slide.get_input("country").val(); - var $timezone = slide.get_input("timezone"); - $timezone.empty(); - // add country specific timezones first - if(country){ - var timezone_list = frappe.country_info[country].timezones || []; - $timezone.add_options(timezone_list.sort()); - slide.get_field("currency").set_input(frappe.country_info[country].currency); - } - // add all timezones at the end, so that user has the option to change it to any timezone - $timezone.add_options([""].concat(frappe.all_timezones)); - - slide.get_field("timezone").set_input($timezone.val()); - - // temporarily set date format - frappe.boot.sysdefaults.date_format = (frappe.country_info[country].date_format - || "dd-mm-yyyy"); - - // get country specific chart of accounts - frappe.call({ - method: "erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts.get_charts_for_country", - args: {"country": country}, - callback: function(r) { - if(r.message) - slide.get_input("chart_of_accounts").empty() - .add_options([""].concat(r.message)); - } - }) - }); - } - }, - - // Organization - { - title: __("The Organization"), - icon: "icon-building", - fields: [ - {fieldname:'company_name', label: __('Company Name'), fieldtype:'Data', reqd:1, - placeholder: __('e.g. "My Company LLC"')}, - {fieldname:'company_abbr', label: __('Company Abbreviation'), fieldtype:'Data', - description: __('Max 5 characters'), placeholder: __('e.g. "MC"'), reqd:1}, - {fieldname:'bank_account', label: __('Bank Account'), fieldtype:'Data', - placeholder: __('e.g. "XYZ National Bank"'), reqd:1 }, - {fieldname:'fy_start_date', label:__('Financial Year Start Date'), fieldtype:'Date', - description: __('Your financial year begins on'), reqd:1}, - {fieldname:'fy_end_date', label:__('Financial Year End Date'), fieldtype:'Date', - description: __('Your financial year ends on'), reqd:1}, - {fieldname:'company_tagline', label: __('What does it do?'), fieldtype:'Data', - placeholder:__('e.g. "Build tools for builders"'), reqd:1}, - ], - help: __('The name of your company for which you are setting up this system.'), - onload: function(slide) { - slide.get_input("company_name").on("change", function() { - var parts = slide.get_input("company_name").val().split(" "); - var abbr = $.map(parts, function(p) { return p ? p.substr(0,1) : null }).join(""); - slide.get_field("company_abbr").set_input(abbr.slice(0, 5).toUpperCase()); - }).val(frappe.boot.sysdefaults.company_name || "").trigger("change"); - - slide.get_input("company_abbr").on("change", function() { - if(slide.get_input("company_abbr").val().length > 5) { - msgprint("Company Abbreviation cannot have more than 5 characters"); - slide.get_field("company_abbr").set_input(""); - } - }); - - slide.get_input("fy_start_date").on("change", function() { - var year_end_date = - frappe.datetime.add_days(frappe.datetime.add_months( - frappe.datetime.user_to_obj(slide.get_input("fy_start_date").val()), 12), -1); - slide.get_field("fy_end_date").set_input(year_end_date); - - }); - } - }, - - // Logo - { - icon: "icon-bookmark", - title: __("Logo and Letter Heads"), - help: __('Upload your letter head and logo - you can edit them later.'), - fields: [ - {fieldtype:"Attach Image", fieldname:"attach_letterhead", - label: __("Attach Letterhead"), - description: __("Keep it web friendly 900px (w) by 100px (h)") - }, - {fieldtype:"Attach Image", fieldname:"attach_logo", - label:__("Attach Logo"), - description: __("100px by 100px")}, - ], - }, - - // Taxes - { - icon: "icon-money", - "title": __("Add Taxes"), - "help": __("List your tax heads (e.g. VAT, Excise; they should have unique names) and their standard rates. This will create a standard template, which you can edit and add more later."), - "fields": [], - before_load: function(slide) { - slide.fields = []; - for(var i=1; i<4; i++) { - slide.fields = slide.fields.concat([ - {fieldtype:"Data", fieldname:"tax_"+ i, label:__("Tax") + " " + i, - placeholder:__("e.g. VAT") + " " + i}, - {fieldtype:"Column Break"}, - {fieldtype:"Float", fieldname:"tax_rate_" + i, label:__("Rate (%)"), placeholder:__("e.g. 5")}, - {fieldtype:"Section Break"}, - ]); - } - } - }, - - // Customers - { - icon: "icon-group", - "title": __("Your Customers"), - "help": __("List a few of your customers. They could be organizations or individuals."), - "fields": [], - before_load: function(slide) { - slide.fields = []; - for(var i=1; i<6; i++) { - slide.fields = slide.fields.concat([ - {fieldtype:"Data", fieldname:"customer_" + i, label:__("Customer") + " " + i, - placeholder:__("Customer Name")}, - {fieldtype:"Column Break"}, - {fieldtype:"Data", fieldname:"customer_contact_" + i, - label:__("Contact Name") + " " + i, placeholder:__("Contact Name")}, - {fieldtype:"Section Break"} - ]) - } - } - }, - - // Suppliers - { - icon: "icon-group", - "title": __("Your Suppliers"), - "help": __("List a few of your suppliers. They could be organizations or individuals."), - "fields": [], - before_load: function(slide) { - slide.fields = []; - for(var i=1; i<6; i++) { - slide.fields = slide.fields.concat([ - {fieldtype:"Data", fieldname:"supplier_" + i, label:__("Supplier")+" " + i, - placeholder:__("Supplier Name")}, - {fieldtype:"Column Break"}, - {fieldtype:"Data", fieldname:"supplier_contact_" + i, - label:__("Contact Name") + " " + i, placeholder:__("Contact Name")}, - {fieldtype:"Section Break"} - ]) - } - } - }, - - // Items to Sell - { - icon: "icon-barcode", - "title": __("Your Products or Services"), - "help": __("List your products or services that you buy or sell. Make sure to check the Item Group, Unit of Measure and other properties when you start."), - "fields": [], - before_load: function(slide) { - slide.fields = []; - for(var i=1; i<6; i++) { - slide.fields = slide.fields.concat([ - {fieldtype:"Section Break", show_section_border: true}, - {fieldtype:"Data", fieldname:"item_" + i, label:__("Item") + " " + i, - placeholder:__("A Product or Service")}, - {fieldtype: "Check", fieldname: "is_sales_item_" + i, label:__("We sell this Item")}, - {fieldtype: "Check", fieldname: "is_purchase_item_" + i, label:__("We buy this Item")}, - {fieldtype:"Column Break"}, - {fieldtype:"Select", label:__("Group"), fieldname:"item_group_" + i, - options:[__("Products"), __("Services"), - __("Raw Material"), __("Consumable"), __("Sub Assemblies")]}, - {fieldtype:"Select", fieldname:"item_uom_" + i, label:__("UOM"), - options:[__("Unit"), __("Nos"), __("Box"), __("Pair"), __("Kg"), __("Set"), - __("Hour"), __("Minute")]}, - {fieldtype:"Attach", fieldname:"item_img_" + i, label:__("Attach Image")}, - ]) - } - } - }, + erpnext.wiz.welcome.slide, + erpnext.wiz.region.slide, + erpnext.wiz.user.slide, + erpnext.wiz.org.slide, + erpnext.wiz.branding.slide, + erpnext.wiz.taxes.slide, + erpnext.wiz.customers.slide, + erpnext.wiz.suppliers.slide, + erpnext.wiz.items.slide, ] } - erpnext.wiz = new frappe.wiz.Wizard(wizard_settings) + erpnext.wiz.wizard = new erpnext.wiz.Wizard(wizard_settings) } frappe.pages['setup-wizard'].on_page_show = function(wrapper) { - if(frappe.get_route()[1]) - erpnext.wiz.show(frappe.get_route()[1]); + if(frappe.get_route()[1]) { + erpnext.wiz.wizard.show(frappe.get_route()[1]); + } + } -frappe.provide("frappe.wiz"); - -frappe.wiz.Wizard = Class.extend({ +erpnext.wiz.Wizard = Class.extend({ init: function(opts) { $.extend(this, opts); this.make(); @@ -398,7 +76,7 @@ frappe.wiz.Wizard = Class.extend({ if(this.current_slide && this.current_slide.id===id) return; if(!this.slide_dict[id]) { - this.slide_dict[id] = new frappe.wiz.WizardSlide($.extend(this.slides[id], {wiz:this, id:id})); + this.slide_dict[id] = new erpnext.wiz.WizardSlide($.extend(this.slides[id], {wiz:this, id:id})); this.slide_dict[id].make(); } @@ -422,7 +100,7 @@ frappe.wiz.Wizard = Class.extend({ } }); -frappe.wiz.WizardSlide = Class.extend({ +erpnext.wiz.WizardSlide = Class.extend({ init: function(opts) { $.extend(this, opts); this.$wrapper = $("
") @@ -437,9 +115,15 @@ frappe.wiz.WizardSlide = Class.extend({ this.before_load(this); } - this.$body = $(frappe.render_template("setup_wizard_page", - {help: __(this.help), title:__(this.title), main_title:__(this.wiz.title), step: this.id + 1 })) - .appendTo(this.$wrapper); + this.$body = $(frappe.render_template("setup_wizard_page", { + help: __(this.help), + title:__(this.title), + main_title:__(this.wiz.title), + step: this.id + 1, + name: this.name, + css_class: this.css_class || "", + slides_count: this.wiz.slides.length + })).appendTo(this.$wrapper); this.body = this.$body.find(".form")[0]; @@ -494,4 +178,431 @@ frappe.wiz.WizardSlide = Class.extend({ get_field: function(fn) { return this.form.get_field(fn); } -}) +}); + +$.extend(erpnext.wiz, { + welcome: { + slide: { + name: "welcome", + title: __("Welcome to ERPNext"), + icon: "icon-world", + help: __("Let's prepare the system for first use."), + + fields: [ + { fieldname: "language", label: __("Select Your Language"), reqd:1, + fieldtype: "Select" }, + ], + + onload: function(slide) { + if (!erpnext.wiz.welcome.data) { + erpnext.wiz.welcome.load_languages(slide); + } else { + erpnext.wiz.welcome.setup_fields(slide); + } + }, + + css_class: "single-column" + }, + + load_languages: function(slide) { + frappe.call({ + method: "erpnext.setup.page.setup_wizard.setup_wizard.load_languages", + callback: function(r) { + erpnext.wiz.welcome.data = r.message; + erpnext.wiz.welcome.setup_fields(slide); + + slide.get_field("language") + .set_input(erpnext.wiz.welcome.data.default_language || "english"); + } + }); + }, + + setup_fields: function(slide) { + var select = slide.get_field("language"); + select.df.options = erpnext.wiz.welcome.data.languages; + select.refresh(); + erpnext.wiz.welcome.bind_events(slide); + }, + + bind_events: function(slide) { + slide.get_input("language").unbind("change").on("change", function() { + var lang = $(this).val() || "english"; + frappe._messages = {}; + frappe.call({ + method: "erpnext.setup.page.setup_wizard.setup_wizard.load_messages", + args: { + language: lang + }, + callback: function(r) { + // TODO save values! + + // re-render all slides + $.each(slide.wiz.slide_dict, function(key, s) { + s.make(); + }); + + // select is re-made after language change + var select = slide.get_field("language"); + select.set_input(lang); + } + }) + }); + }, + }, + + region: { + slide: { + title: __("Region"), + icon: "icon-flag", + help: __("Select your Country, Time Zone and Currency"), + fields: [ + { fieldname: "country", label: __("Country"), reqd:1, + fieldtype: "Select" }, + { fieldname: "timezone", label: __("Time Zone"), reqd:1, + fieldtype: "Select" }, + { fieldname: "currency", label: __("Currency"), reqd:1, + fieldtype: "Select" }, + ], + + onload: function(slide) { + frappe.call({ + method:"frappe.geo.country_info.get_country_timezone_info", + callback: function(data) { + erpnext.wiz.region.data = data.message; + erpnext.wiz.region.setup_fields(slide); + erpnext.wiz.region.bind_events(slide); + } + }); + }, + + css_class: "single-column" + }, + + setup_fields: function(slide) { + var data = erpnext.wiz.region.data; + + slide.get_input("country").empty() + .add_options([""].concat(keys(data.country_info).sort())); + + slide.get_input("currency").empty() + .add_options(frappe.utils.unique([""].concat($.map(data.country_info, + function(opts, country) { return opts.currency; }))).sort()); + + slide.get_input("timezone").empty() + .add_options([""].concat(data.all_timezones)); + + if (data.default_country) { + slide.set_input("country", data.default_country); + } + }, + + bind_events: function(slide) { + slide.get_input("country").on("change", function() { + var country = slide.get_input("country").val(); + var $timezone = slide.get_input("timezone"); + var data = erpnext.wiz.region.data; + + $timezone.empty(); + + // add country specific timezones first + if(country){ + var timezone_list = data.country_info[country].timezones || []; + $timezone.add_options(timezone_list.sort()); + slide.get_field("currency").set_input(data.country_info[country].currency); + } + + // add all timezones at the end, so that user has the option to change it to any timezone + $timezone.add_options([""].concat(data.all_timezones)); + + slide.get_field("timezone").set_input($timezone.val()); + + // temporarily set date format + frappe.boot.sysdefaults.date_format = (data.country_info[country].date_format + || "dd-mm-yyyy"); + }); + } + }, + + user: { + slide: { + title: __("The First User: You"), + icon: "icon-user", + fields: [ + {"fieldname": "first_name", "label": __("First Name"), "fieldtype": "Data", + reqd:1}, + {"fieldname": "last_name", "label": __("Last Name"), "fieldtype": "Data"}, + {"fieldname": "email", "label": __("Email Address"), "fieldtype": "Data", + reqd:1, "description": __("You will use it to Login"), "options":"Email"}, + {"fieldname": "password", "label": __("Password"), "fieldtype": "Password", + reqd:1}, + {fieldtype:"Attach Image", fieldname:"attach_user", + label: __("Attach Your Picture")}, + ], + help: __('The first user will become the System Manager (you can change this later).'), + onload: function(slide) { + if(user!=="Administrator") { + slide.form.fields_dict.password.$wrapper.toggle(false); + slide.form.fields_dict.email.$wrapper.toggle(false); + slide.form.fields_dict.first_name.set_input(frappe.boot.user.first_name); + slide.form.fields_dict.last_name.set_input(frappe.boot.user.last_name); + + var user_image = frappe.get_cookie("user_image"); + if(user_image) { + var $attach_user = slide.form.fields_dict.attach_user.$wrapper; + $attach_user.find(".missing-image").toggle(false); + $attach_user.find("img").attr("src", user_image).toggle(true); + } + + delete slide.form.fields_dict.email; + delete slide.form.fields_dict.password; + } + }, + css_class: "single-column" + }, + }, + + org: { + slide: { + title: __("The Organization"), + icon: "icon-building", + fields: [ + {fieldname:'company_name', label: __('Company Name'), fieldtype:'Data', reqd:1, + placeholder: __('e.g. "My Company LLC"')}, + {fieldname:'company_abbr', label: __('Company Abbreviation'), fieldtype:'Data', + description: __('Max 5 characters'), placeholder: __('e.g. "MC"'), reqd:1}, + {fieldname:'company_tagline', label: __('What does it do?'), fieldtype:'Data', + placeholder:__('e.g. "Build tools for builders"'), reqd:1}, + {fieldname:'bank_account', label: __('Bank Account'), fieldtype:'Data', + placeholder: __('e.g. "XYZ National Bank"'), reqd:1 }, + {fieldname:'chart_of_accounts', label: __('Chart of Accounts'), + options: "", fieldtype: 'Select'}, + + // TODO remove this + {fieldtype: "Section Break"}, + {fieldname:'fy_start_date', label:__('Financial Year Start Date'), fieldtype:'Date', + description: __('Your financial year begins on'), reqd:1}, + {fieldname:'fy_end_date', label:__('Financial Year End Date'), fieldtype:'Date', + description: __('Your financial year ends on'), reqd:1}, + + ], + help: __('The name of your company for which you are setting up this system.'), + + onload: function(slide) { + erpnext.wiz.org.load_chart_of_accounts(slide); + erpnext.wiz.org.bind_events(slide); + }, + + css_class: "single-column" + }, + + load_chart_of_accounts: function(slide) { + var country = slide.wiz.get_values().country; + + frappe.call({ + method: "erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts.get_charts_for_country", + args: {"country": country}, + callback: function(r) { + if(r.message) { + slide.get_input("chart_of_accounts").empty() + .add_options(r.message); + + if (r.message.length===1) { + var field = slide.get_field("chart_of_accounts"); + field.set_value(r.message[0]); + field.df.hidden = 1; + field.refresh(); + } + } + } + }) + }, + + bind_events: function(slide) { + slide.get_input("company_name").on("change", function() { + var parts = slide.get_input("company_name").val().split(" "); + var abbr = $.map(parts, function(p) { return p ? p.substr(0,1) : null }).join(""); + slide.get_field("company_abbr").set_input(abbr.slice(0, 5).toUpperCase()); + }).val(frappe.boot.sysdefaults.company_name || "").trigger("change"); + + slide.get_input("company_abbr").on("change", function() { + if(slide.get_input("company_abbr").val().length > 5) { + msgprint("Company Abbreviation cannot have more than 5 characters"); + slide.get_field("company_abbr").set_input(""); + } + }); + + // TODO remove this + slide.get_input("fy_start_date").on("change", function() { + var year_end_date = + frappe.datetime.add_days(frappe.datetime.add_months( + frappe.datetime.user_to_obj(slide.get_input("fy_start_date").val()), 12), -1); + slide.get_input("fy_end_date").val(frappe.datetime.obj_to_user(year_end_date)); + + }); + } + }, + + branding: { + slide: { + icon: "icon-bookmark", + title: __("The Brand"), + help: __('Upload your letter head and logo. (you can edit them later).'), + fields: [ + {fieldtype:"Attach Image", fieldname:"attach_letterhead", + label: __("Attach Letterhead"), + description: __("Keep it web friendly 900px (w) by 100px (h)") + }, + {fieldtype: "Column Break"}, + {fieldtype:"Attach Image", fieldname:"attach_logo", + label:__("Attach Logo"), + description: __("100px by 100px")}, + ], + + css_class: "two-column" + }, + }, + + taxes: { + slide: { + icon: "icon-money", + "title": __("Add Taxes"), + "help": __("List your tax heads (e.g. VAT, Excise; they should have unique names) and their standard rates. This will create a standard template, which you can edit and add more later."), + "fields": [], + before_load: function(slide) { + slide.fields = []; + for(var i=1; i<4; i++) { + slide.fields = slide.fields.concat([ + {fieldtype:"Section Break"}, + {fieldtype:"Data", fieldname:"tax_"+ i, label:__("Tax") + " " + i, + placeholder:__("e.g. VAT") + " " + i}, + {fieldtype:"Column Break"}, + {fieldtype:"Float", fieldname:"tax_rate_" + i, label:__("Rate (%)"), placeholder:__("e.g. 5")}, + ]); + } + }, + css_class: "two-column" + }, + }, + + customers: { + slide: { + icon: "icon-group", + "title": __("Your Customers"), + "help": __("List a few of your customers. They could be organizations or individuals."), + "fields": [], + before_load: function(slide) { + slide.fields = []; + for(var i=1; i<6; i++) { + slide.fields = slide.fields.concat([ + {fieldtype:"Section Break"}, + {fieldtype:"Data", fieldname:"customer_" + i, label:__("Customer") + " " + i, + placeholder:__("Customer Name")}, + {fieldtype:"Column Break"}, + {fieldtype:"Data", fieldname:"customer_contact_" + i, + label:__("Contact Name") + " " + i, placeholder:__("Contact Name")} + ]) + } + }, + css_class: "two-column" + }, + }, + + suppliers: { + slide: { + icon: "icon-group", + "title": __("Your Suppliers"), + "help": __("List a few of your suppliers. They could be organizations or individuals."), + "fields": [], + before_load: function(slide) { + slide.fields = []; + for(var i=1; i<6; i++) { + slide.fields = slide.fields.concat([ + {fieldtype:"Section Break"}, + {fieldtype:"Data", fieldname:"supplier_" + i, label:__("Supplier")+" " + i, + placeholder:__("Supplier Name")}, + {fieldtype:"Column Break"}, + {fieldtype:"Data", fieldname:"supplier_contact_" + i, + label:__("Contact Name") + " " + i, placeholder:__("Contact Name")}, + ]) + } + }, + css_class: "two-column" + }, + }, + + items: { + slide: { + icon: "icon-barcode", + "title": __("Your Products or Services"), + "help": __("List your products or services that you buy or sell. Make sure to check the Item Group, Unit of Measure and other properties when you start."), + "fields": [], + before_load: function(slide) { + slide.fields = []; + for(var i=1; i<6; i++) { + slide.fields = slide.fields.concat([ + {fieldtype:"Section Break", show_section_border: true}, + {fieldtype:"Data", fieldname:"item_" + i, label:__("Item") + " " + i, + placeholder:__("A Product or Service")}, + {fieldtype:"Select", label:__("Group"), fieldname:"item_group_" + i, + options:[__("Products"), __("Services"), + __("Raw Material"), __("Consumable"), __("Sub Assemblies")]}, + {fieldtype:"Select", fieldname:"item_uom_" + i, label:__("UOM"), + options:[__("Unit"), __("Nos"), __("Box"), __("Pair"), __("Kg"), __("Set"), + __("Hour"), __("Minute")]}, + {fieldtype: "Check", fieldname: "is_sales_item_" + i, label:__("We sell this Item"), default: 1}, + {fieldtype: "Check", fieldname: "is_purchase_item_" + i, label:__("We buy this Item")}, + {fieldtype:"Column Break"}, + {fieldtype:"Attach Image", fieldname:"item_img_" + i, label:__("Attach Image")}, + ]) + } + }, + css_class: "two-column" + }, + }, + + working_html: function() { + return frappe.render_template("setup_wizard_message", { + image: "/assets/frappe/images/ui/bubble-tea-smile.svg", + title: __("Setting Up"), + message: __('Sit tight while your system is being setup. This may take a few moments.') + }); + }, + + complete_html: function() { + return frappe.render_template("setup_wizard_message", { + image: "/assets/frappe/images/ui/bubble-tea-happy.svg", + title: __('Setup Complete'), + message: __('Your setup is complete. Refreshing.') + ".." + }); + }, + + setup_account: function(wiz) { + var values = wiz.get_values(); + wiz.show_working(); + return frappe.call({ + method: "erpnext.setup.page.setup_wizard.setup_wizard.setup_account", + args: values, + callback: function(r) { + wiz.show_complete(); + setTimeout(function() { + if(user==="Administrator") { + msgprint(__("Login with your new User ID") + ": " + values.email); + setTimeout(function() { + frappe.app.logout(); + }, 2000); + } else { + window.location = "/desk"; + } + }, 2000); + }, + error: function(r) { + + var d = msgprint(__("There were errors.")); + d.custom_onhide = function() { + frappe.set_route(erpnext.wiz.page_name, "0"); + }; + } + }); + }, +}); + diff --git a/erpnext/setup/page/setup_wizard/setup_wizard.py b/erpnext/setup/page/setup_wizard/setup_wizard.py index d234f4fc3d..445aa3dc87 100644 --- a/erpnext/setup/page/setup_wizard/setup_wizard.py +++ b/erpnext/setup/page/setup_wizard/setup_wizard.py @@ -7,7 +7,8 @@ import frappe, json from frappe.utils import cstr, flt, getdate from frappe import _ from frappe.utils.file_manager import save_file -from frappe.translate import set_default_language, get_dict, get_lang_dict, send_translations +from frappe.translate import (set_default_language, get_dict, + get_lang_dict, send_translations, get_language_from_code) from frappe.geo.country_info import get_country_info from frappe.utils.nestedset import get_root_of from default_website import website_maker @@ -443,4 +444,9 @@ def load_messages(language): @frappe.whitelist() def load_languages(): - return sorted(get_lang_dict().keys()) + from frappe.sessions import get_geo_from_ip + + return { + "default_language": get_language_from_code(frappe.local.lang), + "languages": sorted(get_lang_dict().keys()) + } diff --git a/erpnext/setup/page/setup_wizard/setup_wizard_message.html b/erpnext/setup/page/setup_wizard/setup_wizard_message.html new file mode 100644 index 0000000000..e2f6bbc51d --- /dev/null +++ b/erpnext/setup/page/setup_wizard/setup_wizard_message.html @@ -0,0 +1,7 @@ +
+ + +

{%= title %}

+ +

{%= message %}

+
diff --git a/erpnext/setup/page/setup_wizard/setup_wizard_page.html b/erpnext/setup/page/setup_wizard/setup_wizard_page.html index 81a79a0e9b..00673174ce 100644 --- a/erpnext/setup/page/setup_wizard/setup_wizard_page.html +++ b/erpnext/setup/page/setup_wizard/setup_wizard_page.html @@ -1,19 +1,21 @@ -
-

{%= title %}

-
+
+
+ {% for (var i=0; i < slides_count; i++) { %} + + {% } %} +
+

{%= title %}

-

{%= help %}


+ {% if (help) { %}

{%= help %}

{% } %}
-
-