[re-org] setup wizard in frappe

This commit is contained in:
Rushabh Mehta
2015-11-09 16:53:11 +05:30
committed by Anand Doshi
parent f71ecbba2c
commit 37b4d75e4a
22 changed files with 465 additions and 1119 deletions

View File

View File

@@ -0,0 +1,3 @@
<p class="lead">We have just starting using ERPNext, the Open Source ERP built for the web and loving it.</p>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p>

View File

@@ -0,0 +1,40 @@
.page-header {
color: white;
background: #263248;
text-align: center;
padding: 80px 0px;
}
.page-header .page-header-left {
width: 100%;
}
.page-header h1 {
color: white;
}
.slide h2 {
margin-bottom: 30px;
}
.slides {
margin-top: -15px;
}
.slide {
padding: 30px 40px;
max-width: 800px;
margin: auto;
}
.container {
max-width: 900px;
}
.img-wrapper {
text-align: center;
padding: 30px;
background-color: #eee;
border-radius: 5px;
margin-bottom: 15px;
}

View File

@@ -0,0 +1,28 @@
<div class="slides">
<div class="row slide">
<h2 class="text-center">{{ _("Awesome Products") }}</h2>
<div class="col-md-6 text-center">
<div class="img-wrapper">
<i class="icon-wrench text-muted" style="font-size: 100px;"></i>
</div>
</div>
<div class="col-md-6">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p>
</div>
</div>
<div class="row slide alt">
<h2 class="text-center">{{ _("Awesome Services") }}</h2>
<div class="col-md-6 text-center">
<div class="img-wrapper">
<i class="icon-phone text-muted" style="font-size: 100px;"></i>
</div>
</div>
<div class="col-md-6">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p>
</div>
</div>
</div>
<p class="text-center" style="margin-bottom: 50px;">
<a href="/products" class="btn btn-success">Explore <i class="icon-chevron-right"></i></a>
</p>
<!-- no-sidebar -->

View File

@@ -0,0 +1,92 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import nowdate
class website_maker(object):
def __init__(self, company, tagline, user):
self.company = company
self.tagline = tagline
self.user = user
self.make_web_page()
self.make_website_settings()
self.make_blog()
def make_web_page(self):
# home page
self.webpage = frappe.get_doc({
"doctype": "Web Page",
"title": self.company,
"published": 1,
"header": "<div class='hero text-center'><h1>{0}</h1>".format(self.tagline or "Headline")+\
'<p>'+_("This is an example website auto-generated from ERPNext")+"</p>"+\
'<p><a class="btn btn-primary" href="/login">Login</a></p></div>',
"description": self.company + ":" + (self.tagline or ""),
"css": frappe.get_template("setup/setup_wizard/data/sample_home_page.css").render(),
"main_section": frappe.get_template("setup/setup_wizard/data/sample_home_page.html").render({
"company": self.company, "tagline": (self.tagline or "")
})
}).insert()
def make_website_settings(self):
# update in home page in settings
website_settings = frappe.get_doc("Website Settings", "Website Settings")
website_settings.home_page = self.webpage.name
website_settings.brand_html = self.company
website_settings.copyright = self.company
website_settings.top_bar_items = []
website_settings.append("top_bar_items", {
"doctype": "Top Bar Item",
"label":"Contact",
"url": "/contact"
})
website_settings.append("top_bar_items", {
"doctype": "Top Bar Item",
"label":"Blog",
"url": "/blog"
})
website_settings.append("top_bar_items", {
"doctype": "Top Bar Item",
"label": _("Products"),
"url": "/products"
})
website_settings.save()
def make_blog(self):
blogger = frappe.new_doc("Blogger")
user = frappe.get_doc("User", self.user)
blogger.user = self.user
blogger.full_name = user.first_name + (" " + user.last_name if user.last_name else "")
blogger.short_name = user.first_name.lower()
blogger.avatar = user.user_image
blogger.insert()
blog_category = frappe.get_doc({
"doctype": "Blog Category",
"category_name": "general",
"published": 1,
"title": _("General")
}).insert()
frappe.get_doc({
"doctype": "Blog Post",
"title": "Welcome",
"published": 1,
"published_on": nowdate(),
"blogger": blogger.name,
"blog_category": blog_category.name,
"blog_intro": "My First Blog",
"content": frappe.get_template("setup/setup_wizard/data/sample_blog_post.html").render(),
}).insert()
def test():
frappe.delete_doc("Web Page", "test-company")
frappe.delete_doc("Blog Post", "welcome")
frappe.delete_doc("Blogger", "administrator")
frappe.delete_doc("Blog Category", "general")
website_maker("Test Company", "Better Tools for Everyone", "Administrator")
frappe.db.commit()

View File

@@ -0,0 +1,56 @@
from frappe import _
def get_industry_types():
return [
_('Accounting'),
_('Advertising'),
_('Aerospace'),
_('Agriculture'),
_('Airline'),
_('Apparel & Accessories'),
_('Automotive'),
_('Banking'),
_('Biotechnology'),
_('Broadcasting'),
_('Brokerage'),
_('Chemical'),
_('Computer'),
_('Consulting'),
_('Consumer Products'),
_('Cosmetics'),
_('Defense'),
_('Department Stores'),
_('Education'),
_('Electronics'),
_('Energy'),
_('Entertainment & Leisure'),
_('Executive Search'),
_('Financial Services'),
_('Food, Beverage & Tobacco'),
_('Grocery'),
_('Health Care'),
_('Internet Publishing'),
_('Investment Banking'),
_('Legal'),
_('Manufacturing'),
_('Motion Picture & Video'),
_('Music'),
_('Newspaper Publishers'),
_('Online Auctions'),
_('Pension Funds'),
_('Pharmaceuticals'),
_('Private Equity'),
_('Publishing'),
_('Real Estate'),
_('Retail & Wholesale'),
_('Securities & Commodity Exchanges'),
_('Service'),
_('Soap & Detergent'),
_('Software'),
_('Sports'),
_('Technology'),
_('Telecommunications'),
_('Television'),
_('Transportation'),
_('Venture Capital')
]

View File

@@ -0,0 +1,203 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
from frappe import _
def install(country=None):
records = [
# address template
{'doctype':"Address Template", "country": country},
# item group
{'doctype': 'Item Group', 'item_group_name': _('All Item Groups'),
'is_group': 'Yes', 'parent_item_group': ''},
{'doctype': 'Item Group', 'item_group_name': _('Products'),
'is_group': 'No', 'parent_item_group': _('All Item Groups'), "show_in_website": 1 },
{'doctype': 'Item Group', 'item_group_name': _('Raw Material'),
'is_group': 'No', 'parent_item_group': _('All Item Groups') },
{'doctype': 'Item Group', 'item_group_name': _('Services'),
'is_group': 'No', 'parent_item_group': _('All Item Groups') },
{'doctype': 'Item Group', 'item_group_name': _('Sub Assemblies'),
'is_group': 'No', 'parent_item_group': _('All Item Groups') },
{'doctype': 'Item Group', 'item_group_name': _('Consumable'),
'is_group': 'No', 'parent_item_group': _('All Item Groups') },
# deduction type
{'doctype': 'Deduction Type', 'name': _('Income Tax'), 'description': _('Income Tax'), 'deduction_name': _('Income Tax')},
# earning type
{'doctype': 'Earning Type', 'name': _('Basic'), 'description': _('Basic'), 'earning_name': _('Basic'), 'taxable': 'Yes'},
# expense claim type
{'doctype': 'Expense Claim Type', 'name': _('Calls'), 'expense_type': _('Calls')},
{'doctype': 'Expense Claim Type', 'name': _('Food'), 'expense_type': _('Food')},
{'doctype': 'Expense Claim Type', 'name': _('Medical'), 'expense_type': _('Medical')},
{'doctype': 'Expense Claim Type', 'name': _('Others'), 'expense_type': _('Others')},
{'doctype': 'Expense Claim Type', 'name': _('Travel'), 'expense_type': _('Travel')},
# leave type
{'doctype': 'Leave Type', 'leave_type_name': _('Casual Leave'), 'name': _('Casual Leave'),
'is_encash': 1, 'is_carry_forward': 1, 'max_days_allowed': '3', 'include_holiday': 1},
{'doctype': 'Leave Type', 'leave_type_name': _('Compensatory Off'), 'name': _('Compensatory Off'),
'is_encash': 0, 'is_carry_forward': 0, 'include_holiday': 1},
{'doctype': 'Leave Type', 'leave_type_name': _('Sick Leave'), 'name': _('Sick Leave'),
'is_encash': 0, 'is_carry_forward': 0, 'include_holiday': 1},
{'doctype': 'Leave Type', 'leave_type_name': _('Privilege Leave'), 'name': _('Privilege Leave'),
'is_encash': 0, 'is_carry_forward': 0, 'include_holiday': 1},
{'doctype': 'Leave Type', 'leave_type_name': _('Leave Without Pay'), 'name': _('Leave Without Pay'),
'is_encash': 0, 'is_carry_forward': 0, 'is_lwp':1, 'include_holiday': 1},
# Employment Type
{'doctype': 'Employment Type', 'employee_type_name': _('Full-time')},
{'doctype': 'Employment Type', 'employee_type_name': _('Part-time')},
{'doctype': 'Employment Type', 'employee_type_name': _('Probation')},
{'doctype': 'Employment Type', 'employee_type_name': _('Contract')},
{'doctype': 'Employment Type', 'employee_type_name': _('Commission')},
{'doctype': 'Employment Type', 'employee_type_name': _('Piecework')},
{'doctype': 'Employment Type', 'employee_type_name': _('Intern')},
{'doctype': 'Employment Type', 'employee_type_name': _('Apprentice')},
# Department
{'doctype': 'Department', 'department_name': _('Accounts')},
{'doctype': 'Department', 'department_name': _('Marketing')},
{'doctype': 'Department', 'department_name': _('Sales')},
{'doctype': 'Department', 'department_name': _('Purchase')},
{'doctype': 'Department', 'department_name': _('Operations')},
{'doctype': 'Department', 'department_name': _('Production')},
{'doctype': 'Department', 'department_name': _('Dispatch')},
{'doctype': 'Department', 'department_name': _('Customer Service')},
{'doctype': 'Department', 'department_name': _('Human Resources')},
{'doctype': 'Department', 'department_name': _('Management')},
{'doctype': 'Department', 'department_name': _('Quality Management')},
{'doctype': 'Department', 'department_name': _('Research & Development')},
{'doctype': 'Department', 'department_name': _('Legal')},
# Designation
{'doctype': 'Designation', 'designation_name': _('CEO')},
{'doctype': 'Designation', 'designation_name': _('Manager')},
{'doctype': 'Designation', 'designation_name': _('Analyst')},
{'doctype': 'Designation', 'designation_name': _('Engineer')},
{'doctype': 'Designation', 'designation_name': _('Accountant')},
{'doctype': 'Designation', 'designation_name': _('Secretary')},
{'doctype': 'Designation', 'designation_name': _('Associate')},
{'doctype': 'Designation', 'designation_name': _('Administrative Officer')},
{'doctype': 'Designation', 'designation_name': _('Business Development Manager')},
{'doctype': 'Designation', 'designation_name': _('HR Manager')},
{'doctype': 'Designation', 'designation_name': _('Project Manager')},
{'doctype': 'Designation', 'designation_name': _('Head of Marketing and Sales')},
{'doctype': 'Designation', 'designation_name': _('Software Developer')},
{'doctype': 'Designation', 'designation_name': _('Designer')},
{'doctype': 'Designation', 'designation_name': _('Researcher')},
# territory
{'doctype': 'Territory', 'territory_name': _('All Territories'), 'is_group': 'Yes', 'name': _('All Territories'), 'parent_territory': ''},
# customer group
{'doctype': 'Customer Group', 'customer_group_name': _('All Customer Groups'), 'is_group': 'Yes', 'name': _('All Customer Groups'), 'parent_customer_group': ''},
{'doctype': 'Customer Group', 'customer_group_name': _('Individual'), 'is_group': 'No', 'parent_customer_group': _('All Customer Groups')},
{'doctype': 'Customer Group', 'customer_group_name': _('Commercial'), 'is_group': 'No', 'parent_customer_group': _('All Customer Groups')},
{'doctype': 'Customer Group', 'customer_group_name': _('Non Profit'), 'is_group': 'No', 'parent_customer_group': _('All Customer Groups')},
{'doctype': 'Customer Group', 'customer_group_name': _('Government'), 'is_group': 'No', 'parent_customer_group': _('All Customer Groups')},
# supplier type
{'doctype': 'Supplier Type', 'supplier_type': _('Services')},
{'doctype': 'Supplier Type', 'supplier_type': _('Local')},
{'doctype': 'Supplier Type', 'supplier_type': _('Raw Material')},
{'doctype': 'Supplier Type', 'supplier_type': _('Electrical')},
{'doctype': 'Supplier Type', 'supplier_type': _('Hardware')},
{'doctype': 'Supplier Type', 'supplier_type': _('Pharmaceutical')},
{'doctype': 'Supplier Type', 'supplier_type': _('Distributor')},
# Sales Person
{'doctype': 'Sales Person', 'sales_person_name': _('Sales Team'), 'is_group': "Yes", "parent_sales_person": ""},
# UOM
{'uom_name': _('Unit'), 'doctype': 'UOM', 'name': _('Unit'), "must_be_whole_number": 1},
{'uom_name': _('Box'), 'doctype': 'UOM', 'name': _('Box'), "must_be_whole_number": 1},
{'uom_name': _('Kg'), 'doctype': 'UOM', 'name': _('Kg')},
{'uom_name': _('Nos'), 'doctype': 'UOM', 'name': _('Nos'), "must_be_whole_number": 1},
{'uom_name': _('Pair'), 'doctype': 'UOM', 'name': _('Pair'), "must_be_whole_number": 1},
{'uom_name': _('Set'), 'doctype': 'UOM', 'name': _('Set'), "must_be_whole_number": 1},
{'uom_name': _('Hour'), 'doctype': 'UOM', 'name': _('Hour')},
{'uom_name': _('Minute'), 'doctype': 'UOM', 'name': _('Minute')},
# Mode of Payment
{'doctype': 'Mode of Payment', 'mode_of_payment': 'Check' if country=="United States" else _('Cheque')},
{'doctype': 'Mode of Payment', 'mode_of_payment': _('Cash')},
{'doctype': 'Mode of Payment', 'mode_of_payment': _('Credit Card')},
{'doctype': 'Mode of Payment', 'mode_of_payment': _('Wire Transfer')},
{'doctype': 'Mode of Payment', 'mode_of_payment': _('Bank Draft')},
# Activity Type
{'doctype': 'Activity Type', 'activity_type': _('Planning')},
{'doctype': 'Activity Type', 'activity_type': _('Research')},
{'doctype': 'Activity Type', 'activity_type': _('Proposal Writing')},
{'doctype': 'Activity Type', 'activity_type': _('Execution')},
{'doctype': 'Activity Type', 'activity_type': _('Communication')},
{'doctype': "Item Attribute", "attribute_name": _("Size"), "item_attribute_values": [
{"attribute_value": _("Extra Small"), "abbr": "XS"},
{"attribute_value": _("Small"), "abbr": "S"},
{"attribute_value": _("Medium"), "abbr": "M"},
{"attribute_value": _("Large"), "abbr": "L"},
{"attribute_value": _("Extra Large"), "abbr": "XL"}
]},
{'doctype': "Item Attribute", "attribute_name": _("Colour"), "item_attribute_values": [
{"attribute_value": _("Red"), "abbr": "RED"},
{"attribute_value": _("Green"), "abbr": "GRE"},
{"attribute_value": _("Blue"), "abbr": "BLU"},
{"attribute_value": _("Black"), "abbr": "BLA"},
{"attribute_value": _("White"), "abbr": "WHI"}
]},
{'doctype': "Email Account", "email_id": "sales@example.com", "append_to": "Opportunity"},
{'doctype': "Email Account", "email_id": "support@example.com", "append_to": "Issue"},
{'doctype': "Email Account", "email_id": "jobs@example.com", "append_to": "Job Applicant"},
{"doctype": "Offer Term", "offer_term": _("Date of Joining")},
{"doctype": "Offer Term", "offer_term": _("Annual Salary")},
{"doctype": "Offer Term", "offer_term": _("Probationary Period")},
{"doctype": "Offer Term", "offer_term": _("Employee Benefits")},
{"doctype": "Offer Term", "offer_term": _("Working Hours")},
{"doctype": "Offer Term", "offer_term": _("Stock Options")},
{"doctype": "Offer Term", "offer_term": _("Department")},
{"doctype": "Offer Term", "offer_term": _("Job Description")},
{"doctype": "Offer Term", "offer_term": _("Responsibilities")},
{"doctype": "Offer Term", "offer_term": _("Leaves per Year")},
{"doctype": "Offer Term", "offer_term": _("Notice Period")},
{"doctype": "Offer Term", "offer_term": _("Incentives")},
{'doctype': "Print Heading", 'print_heading': _("Credit Note")},
{'doctype': "Print Heading", 'print_heading': _("Debit Note")}
]
from erpnext.setup.setup_wizard.industry_type import get_industry_types
records += [{"doctype":"Industry Type", "industry": d} for d in get_industry_types()]
# records += [{"doctype":"Operation", "operation": d} for d in get_operations()]
from frappe.modules import scrub
for r in records:
doc = frappe.new_doc(r.get("doctype"))
doc.update(r)
# ignore mandatory for root
parent_link_field = ("parent_" + scrub(doc.doctype))
if doc.meta.get_field(parent_link_field) and not doc.get(parent_link_field):
doc.flags.ignore_mandatory = True
try:
doc.insert(ignore_permissions=True)
except frappe.DuplicateEntryError, e:
# pass DuplicateEntryError and continue
if e.args and e.args[0]==doc.doctype and e.args[1]==doc.name:
# make sure DuplicateEntryError is for the exact same doc and not a related doc
pass
else:
raise

View File

@@ -0,0 +1,125 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
from frappe.utils.make_random import add_random_children
import frappe.utils
import random
def make_sample_data():
"""Create a few opportunities, quotes, material requests, issues, todos, projects
to help the user get started"""
selling_items = frappe.get_all("Item", filters = {"is_sales_item": 1})
buying_items = frappe.get_all("Item", filters = {"is_purchase_item": 1})
customers = frappe.get_all("Customer")
if selling_items and customers:
for i in range(3):
customer = random.choice(customers).name
make_opportunity(selling_items, customer)
make_quote(selling_items, customer)
make_projects()
if buying_items:
make_material_request(buying_items)
frappe.db.commit()
def make_opportunity(selling_items, customer):
b = frappe.get_doc({
"doctype": "Opportunity",
"enquiry_from": "Customer",
"customer": customer,
"enquiry_type": "Sales",
"with_items": 1
})
add_random_children(b, "items", rows=len(selling_items), randomize = {
"qty": (1, 5),
"item_code": ("Item", {"is_sales_item": 1})
}, unique="item_code")
b.insert(ignore_permissions=True)
b.add_comment("This is a dummy record")
def make_quote(selling_items, customer):
qtn = frappe.get_doc({
"doctype": "Quotation",
"quotation_to": "Customer",
"customer": customer,
"order_type": "Sales"
})
add_random_children(qtn, "items", rows=len(selling_items), randomize = {
"qty": (1, 5),
"item_code": ("Item", {"is_sales_item": 1})
}, unique="item_code")
qtn.insert(ignore_permissions=True)
qtn.add_comment("This is a dummy record")
def make_material_request(buying_items):
for i in buying_items:
mr = frappe.get_doc({
"doctype": "Material Request",
"material_request_type": "Purchase",
"items": [{
"schedule_date": frappe.utils.add_days(frappe.utils.nowdate(), 7),
"item_code": i.name,
"qty": 10
}]
})
mr.insert()
mr.submit()
mr.add_comment("This is a dummy record")
def make_issue():
pass
def make_projects():
project = frappe.get_doc({
"doctype": "Project",
"project_name": "ERPNext Implementation",
})
current_date = frappe.utils.nowdate()
project.set("tasks", [
{
"title": "Explore ERPNext",
"start_date": frappe.utils.add_days(current_date, 1),
"end_date": frappe.utils.add_days(current_date, 2)
},
{
"title": "Run Sales Cycle",
"start_date": frappe.utils.add_days(current_date, 2),
"end_date": frappe.utils.add_days(current_date, 3)
},
{
"title": "Run Billing Cycle",
"start_date": frappe.utils.add_days(current_date, 3),
"end_date": frappe.utils.add_days(current_date, 4)
},
{
"title": "Run Purchase Cycle",
"start_date": frappe.utils.add_days(current_date, 4),
"end_date": frappe.utils.add_days(current_date, 5)
},
{
"title": "Import Data",
"start_date": frappe.utils.add_days(current_date, 5),
"end_date": frappe.utils.add_days(current_date, 6)
},
{
"title": "Go Live!",
"start_date": frappe.utils.add_days(current_date, 6),
"end_date": frappe.utils.add_days(current_date, 7)
}])
project.insert(ignore_permissions=True)

View File

@@ -0,0 +1,523 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe, copy
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
from frappe.geo.country_info import get_country_info
from .default_website import website_maker
import install_fixtures
from .sample_data import make_sample_data
from erpnext.accounts.utils import FiscalYearError
from erpnext.accounts.doctype.account.account import RootNotEditable
def setup_complete(args=None):
if frappe.db.sql("select name from tabCompany"):
frappe.throw(_("Setup Already Complete!!"))
if args.language and args.language != "english":
set_default_language(args.language)
frappe.clear_cache()
install_fixtures.install(args.get("country"))
update_user_name(args)
create_fiscal_year_and_company(args)
create_users(args)
set_defaults(args)
create_territories()
create_price_lists(args)
create_feed_and_todo()
create_email_digest()
create_letter_head(args)
create_taxes(args)
create_items(args)
create_customers(args)
create_suppliers(args)
frappe.local.message_log = []
website_maker(args.company_name.strip(), args.company_tagline, args.name)
create_logo(args)
frappe.db.commit()
login_as_first_user(args)
frappe.db.commit()
frappe.clear_cache()
if args.get("add_sample_data"):
try:
make_sample_data()
frappe.clear_cache()
except FiscalYearError:
pass
def update_user_name(args):
if args.get("email"):
args['name'] = args.get("email")
_mute_emails, frappe.flags.mute_emails = frappe.flags.mute_emails, True
doc = frappe.get_doc({
"doctype":"User",
"email": args.get("email"),
"first_name": args.get("first_name"),
"last_name": args.get("last_name")
})
doc.flags.no_welcome_mail = True
doc.insert()
frappe.flags.mute_emails = _mute_emails
from frappe.auth import _update_password
_update_password(args.get("email"), args.get("password"))
else:
args['name'] = frappe.session.user
# Update User
if not args.get('last_name') or args.get('last_name')=='None':
args['last_name'] = None
frappe.db.sql("""update `tabUser` SET first_name=%(first_name)s,
last_name=%(last_name)s WHERE name=%(name)s""", args)
if args.get("attach_user"):
attach_user = args.get("attach_user").split(",")
if len(attach_user)==3:
filename, filetype, content = attach_user
fileurl = save_file(filename, content, "User", args.get("name"), decode=True).file_url
frappe.db.set_value("User", args.get("name"), "user_image", fileurl)
add_all_roles_to(args.get("name"))
def create_fiscal_year_and_company(args):
curr_fiscal_year = get_fy_details(args.get('fy_start_date'), args.get('fy_end_date'))
frappe.get_doc({
"doctype":"Fiscal Year",
'year': curr_fiscal_year,
'year_start_date': args.get('fy_start_date'),
'year_end_date': args.get('fy_end_date'),
}).insert()
# Company
frappe.get_doc({
"doctype":"Company",
'domain': args.get("industry"),
'company_name':args.get('company_name').strip(),
'abbr':args.get('company_abbr'),
'default_currency':args.get('currency'),
'country': args.get('country'),
'chart_of_accounts': args.get(('chart_of_accounts')),
}).insert()
# Bank Account
args["curr_fiscal_year"] = curr_fiscal_year
def create_price_lists(args):
for pl_type, pl_name in (("Selling", _("Standard Selling")), ("Buying", _("Standard Buying"))):
frappe.get_doc({
"doctype": "Price List",
"price_list_name": pl_name,
"enabled": 1,
"buying": 1 if pl_type == "Buying" else 0,
"selling": 1 if pl_type == "Selling" else 0,
"currency": args["currency"]
}).insert()
def set_defaults(args):
# enable default currency
frappe.db.set_value("Currency", args.get("currency"), "enabled", 1)
global_defaults = frappe.get_doc("Global Defaults", "Global Defaults")
global_defaults.update({
'current_fiscal_year': args.curr_fiscal_year,
'default_currency': args.get('currency'),
'default_company':args.get('company_name').strip(),
"country": args.get("country"),
})
global_defaults.save()
number_format = get_country_info(args.get("country")).get("number_format", "#,###.##")
# replace these as float number formats, as they have 0 precision
# and are currency number formats and not for floats
if number_format=="#.###":
number_format = "#.###,##"
elif number_format=="#,###":
number_format = "#,###.##"
system_settings = frappe.get_doc("System Settings", "System Settings")
system_settings.update({
"language": args.get("language"),
"time_zone": args.get("timezone"),
"float_precision": 3,
"email_footer_address": args.get("company"),
'date_format': frappe.db.get_value("Country", args.get("country"), "date_format"),
'number_format': number_format,
'enable_scheduler': 1 if not frappe.flags.in_test else 0
})
system_settings.save()
accounts_settings = frappe.get_doc("Accounts Settings")
accounts_settings.auto_accounting_for_stock = 1
accounts_settings.save()
stock_settings = frappe.get_doc("Stock Settings")
stock_settings.item_naming_by = "Item Code"
stock_settings.valuation_method = "FIFO"
stock_settings.stock_uom = _("Nos")
stock_settings.auto_indent = 1
stock_settings.auto_insert_price_list_rate_if_missing = 1
stock_settings.automatically_set_serial_nos_based_on_fifo = 1
stock_settings.save()
selling_settings = frappe.get_doc("Selling Settings")
selling_settings.cust_master_name = "Customer Name"
selling_settings.so_required = "No"
selling_settings.dn_required = "No"
selling_settings.save()
buying_settings = frappe.get_doc("Buying Settings")
buying_settings.supp_master_name = "Supplier Name"
buying_settings.po_required = "No"
buying_settings.pr_required = "No"
buying_settings.maintain_same_rate = 1
buying_settings.save()
notification_control = frappe.get_doc("Notification Control")
notification_control.quotation = 1
notification_control.sales_invoice = 1
notification_control.purchase_order = 1
notification_control.save()
hr_settings = frappe.get_doc("HR Settings")
hr_settings.emp_created_by = "Naming Series"
hr_settings.save()
def create_feed_and_todo():
"""update Activity feed and create todo for creation of item, customer, vendor"""
frappe.get_doc({
"doctype": "Feed",
"feed_type": "Comment",
"subject": "ERPNext Setup Complete!"
}).insert(ignore_permissions=True)
def create_email_digest():
from frappe.utils.user import get_system_managers
system_managers = get_system_managers(only_name=True)
if not system_managers:
return
companies = frappe.db.sql_list("select name FROM `tabCompany`")
for company in companies:
if not frappe.db.exists("Email Digest", "Default Weekly Digest - " + company):
edigest = frappe.get_doc({
"doctype": "Email Digest",
"name": "Default Weekly Digest - " + company,
"company": company,
"frequency": "Weekly",
"recipient_list": "\n".join(system_managers)
})
for df in edigest.meta.get("fields", {"fieldtype": "Check"}):
if df.fieldname != "scheduler_errors":
edigest.set(df.fieldname, 1)
edigest.insert()
# scheduler errors digest
if companies:
edigest = frappe.new_doc("Email Digest")
edigest.update({
"name": "Scheduler Errors",
"company": companies[0],
"frequency": "Daily",
"recipient_list": "\n".join(system_managers),
"scheduler_errors": 1,
"enabled": 1
})
edigest.insert()
def get_fy_details(fy_start_date, fy_end_date):
start_year = getdate(fy_start_date).year
if start_year == getdate(fy_end_date).year:
fy = cstr(start_year)
else:
fy = cstr(start_year) + '-' + cstr(start_year + 1)
return fy
def create_taxes(args):
for i in xrange(1,6):
if args.get("tax_" + str(i)):
# replace % in case someone also enters the % symbol
tax_rate = (args.get("tax_rate_" + str(i)) or "").replace("%", "")
try:
tax_group = frappe.db.get_value("Account", {"company": args.get("company_name"),
"is_group": 1, "account_type": "Tax", "root_type": "Liability"})
if tax_group:
account = make_tax_head(args, i, tax_group, tax_rate)
make_sales_and_purchase_tax_templates(account)
except frappe.NameError, e:
if e.args[2][0]==1062:
pass
else:
raise
except RootNotEditable, e:
pass
def make_tax_head(args, i, tax_group, tax_rate):
return frappe.get_doc({
"doctype":"Account",
"company": args.get("company_name").strip(),
"parent_account": tax_group,
"account_name": args.get("tax_" + str(i)),
"is_group": 0,
"report_type": "Balance Sheet",
"account_type": "Tax",
"tax_rate": flt(tax_rate) if tax_rate else None
}).insert(ignore_permissions=True)
def make_sales_and_purchase_tax_templates(account):
doc = {
"doctype": "Sales Taxes and Charges Template",
"title": account.name,
"taxes": [{
"category": "Valuation and Total",
"charge_type": "On Net Total",
"account_head": account.name,
"description": "{0} @ {1}".format(account.account_name, account.tax_rate),
"rate": account.tax_rate
}]
}
# Sales
frappe.get_doc(copy.deepcopy(doc)).insert()
# Purchase
doc["doctype"] = "Purchase Taxes and Charges Template"
frappe.get_doc(copy.deepcopy(doc)).insert()
def create_items(args):
for i in xrange(1,6):
item = args.get("item_" + str(i))
if item:
item_group = args.get("item_group_" + str(i))
is_sales_item = args.get("is_sales_item_" + str(i))
is_purchase_item = args.get("is_purchase_item_" + str(i))
is_stock_item = item_group!=_("Services")
is_pro_applicable = item_group!=_("Services")
default_warehouse = ""
if is_stock_item:
default_warehouse = frappe.db.get_value("Warehouse", filters={
"warehouse_name": _("Finished Goods") if is_sales_item else _("Stores"),
"company": args.get("company_name").strip()
})
try:
frappe.get_doc({
"doctype":"Item",
"item_code": item,
"item_name": item,
"description": item,
"is_sales_item": 1 if is_sales_item else 0,
"is_purchase_item": 1 if is_purchase_item else 0,
"show_in_website": 1,
"is_stock_item": is_stock_item and 1 or 0,
"is_pro_applicable": is_pro_applicable and 1 or 0,
"item_group": item_group,
"stock_uom": args.get("item_uom_" + str(i)),
"default_warehouse": default_warehouse
}).insert()
if args.get("item_img_" + str(i)):
item_image = args.get("item_img_" + str(i)).split(",")
if len(item_image)==3:
filename, filetype, content = item_image
fileurl = save_file(filename, content, "Item", item, decode=True).file_url
frappe.db.set_value("Item", item, "image", fileurl)
if args.get("item_price_" + str(i)):
item_price = flt(args.get("item_price_" + str(i)))
if is_sales_item:
price_list_name = frappe.db.get_value("Price List", {"selling": 1})
make_item_price(item, price_list_name, item_price)
if is_purchase_item:
price_list_name = frappe.db.get_value("Price List", {"buying": 1})
make_item_price(item, price_list_name, item_price)
except frappe.NameError:
pass
def make_item_price(item, price_list_name, item_price):
frappe.get_doc({
"doctype": "Item Price",
"price_list": price_list_name,
"item_code": item,
"price_list_rate": item_price
}).insert()
def create_customers(args):
for i in xrange(1,6):
customer = args.get("customer_" + str(i))
if customer:
try:
frappe.get_doc({
"doctype":"Customer",
"customer_name": customer,
"customer_type": "Company",
"customer_group": _("Commercial"),
"territory": args.get("country"),
"company": args.get("company_name").strip()
}).insert()
if args.get("customer_contact_" + str(i)):
create_contact(args.get("customer_contact_" + str(i)),
"customer", customer)
except frappe.NameError:
pass
def create_suppliers(args):
for i in xrange(1,6):
supplier = args.get("supplier_" + str(i))
if supplier:
try:
frappe.get_doc({
"doctype":"Supplier",
"supplier_name": supplier,
"supplier_type": _("Local"),
"company": args.get("company_name").strip()
}).insert()
if args.get("supplier_contact_" + str(i)):
create_contact(args.get("supplier_contact_" + str(i)),
"supplier", supplier)
except frappe.NameError:
pass
def create_contact(contact, party_type, party):
"""Create contact based on given contact name"""
contact = contact.strip().split(" ")
frappe.get_doc({
"doctype":"Contact",
party_type: party,
"first_name":contact[0],
"last_name": len(contact) > 1 and contact[1] or ""
}).insert()
def create_letter_head(args):
if args.get("attach_letterhead"):
frappe.get_doc({
"doctype":"Letter Head",
"letter_head_name": _("Standard"),
"is_default": 1
}).insert()
attach_letterhead = args.get("attach_letterhead").split(",")
if len(attach_letterhead)==3:
filename, filetype, content = attach_letterhead
fileurl = save_file(filename, content, "Letter Head", _("Standard"), decode=True).file_url
frappe.db.set_value("Letter Head", _("Standard"), "content", "<img src='%s' style='max-width: 100%%;'>" % fileurl)
def create_logo(args):
if args.get("attach_logo"):
attach_logo = args.get("attach_logo").split(",")
if len(attach_logo)==3:
filename, filetype, content = attach_logo
fileurl = save_file(filename, content, "Website Settings", "Website Settings",
decode=True).file_url
frappe.db.set_value("Website Settings", "Website Settings", "brand_html",
"<img src='{0}' style='max-width: 40px; max-height: 25px;'> {1}".format(fileurl, args.get("company_name").strip()))
def add_all_roles_to(name):
user = frappe.get_doc("User", name)
for role in frappe.db.sql("""select name from tabRole"""):
if role[0] not in ["Administrator", "Guest", "All", "Customer", "Supplier", "Partner", "Employee"]:
d = user.append("user_roles")
d.role = role[0]
user.save()
def create_territories():
"""create two default territories, one for home country and one named Rest of the World"""
from frappe.utils.nestedset import get_root_of
country = frappe.db.get_default("country")
root_territory = get_root_of("Territory")
for name in (country, _("Rest Of The World")):
if name and not frappe.db.exists("Territory", name):
frappe.get_doc({
"doctype": "Territory",
"territory_name": name.replace("'", ""),
"parent_territory": root_territory,
"is_group": "No"
}).insert()
def login_as_first_user(args):
if args.get("email") and hasattr(frappe.local, "login_manager"):
frappe.local.login_manager.login_as(args.get("email"))
def create_users(args):
# create employee for self
emp = frappe.get_doc({
"doctype": "Employee",
"full_name": " ".join(filter(None, [args.get("first_name"), args.get("last_name")])),
"user_id": frappe.session.user,
"status": "Active",
"company": args.get("company_name")
})
emp.flags.ignore_mandatory = True
emp.insert(ignore_permissions = True)
for i in xrange(1,5):
email = args.get("user_email_" + str(i))
fullname = args.get("user_fullname_" + str(i))
if email:
if not fullname:
fullname = email.split("@")[0]
parts = fullname.split(" ", 1)
user = frappe.get_doc({
"doctype": "User",
"email": email,
"first_name": parts[0],
"last_name": parts[1] if len(parts) > 1 else "",
"enabled": 1,
"user_type": "System User"
})
# default roles
user.append_roles("Projects User", "Stock User", "Support Team")
if args.get("user_sales_" + str(i)):
user.append_roles("Sales User", "Sales Manager", "Accounts User")
if args.get("user_purchaser_" + str(i)):
user.append_roles("Purchase User", "Purchase Manager", "Accounts User")
if args.get("user_accountant_" + str(i)):
user.append_roles("Accounts Manager", "Accounts User")
user.flags.delay_emails = True
if not frappe.db.get_value("User", email):
user.insert(ignore_permissions=True)
# create employee
emp = frappe.get_doc({
"doctype": "Employee",
"full_name": fullname,
"user_id": email,
"status": "Active",
"company": args.get("company_name")
})
emp.flags.ignore_mandatory = True
emp.insert(ignore_permissions = True)

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,15 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
from frappe.desk.page.setup_wizard.test_setup_data import args
from frappe.desk.page.setup_wizard.setup_wizard import setup_complete
import frappe.utils.scheduler
if __name__=="__main__":
frappe.connect()
frappe.local.form_dict = frappe._dict(args)
setup_complete()
frappe.utils.scheduler.disable_scheduler()