Merge pull request #3681 from rmehta/sample-data

[enhancement] update to setup wizard, added users, employees, sample data
This commit is contained in:
Anand Doshi 2015-07-23 16:45:28 +05:30
commit 03ae61afce
9 changed files with 342 additions and 30 deletions

View File

@ -49,7 +49,7 @@ class Account(Document):
self.root_type = par.root_type
def validate_root_details(self):
#does not exists parent
# does not exists parent
if frappe.db.exists("Account", self.name):
if not frappe.db.get_value("Account", self.name, "parent_account"):
throw(_("Root cannot be edited."))

View File

@ -4,10 +4,9 @@
from __future__ import unicode_literals
from frappe.model.document import Document
from erpnext.controllers.accounts_controller import validate_taxes_and_charges, validate_inclusive_tax
from erpnext.accounts.doctype.sales_taxes_and_charges_template.sales_taxes_and_charges_template \
import valdiate_taxes_and_charges_template
class PurchaseTaxesandChargesTemplate(Document):
def validate(self):
for tax in self.get("taxes"):
validate_taxes_and_charges(tax)
validate_inclusive_tax(tax, self)
valdiate_taxes_and_charges_template(self)

View File

@ -5,21 +5,25 @@ from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from erpnext.controllers.accounts_controller import validate_taxes_and_charges, validate_inclusive_tax
from frappe.utils.nestedset import get_root_of
class SalesTaxesandChargesTemplate(Document):
def validate(self):
if self.is_default == 1:
frappe.db.sql("""update `tabSales Taxes and Charges Template`
set is_default = 0
where ifnull(is_default,0) = 1
and name != %s and company = %s""",
(self.name, self.company))
valdiate_taxes_and_charges_template(self)
# at least one territory
self.validate_table_has_rows("territories")
def valdiate_taxes_and_charges_template(doc):
if not doc.is_default and not frappe.get_all(doc.doctype, filters={"is_default": 1}):
doc.is_default = 1
for tax in self.get("taxes"):
validate_taxes_and_charges(tax)
validate_inclusive_tax(tax, self)
if doc.is_default == 1:
frappe.db.sql("""update `tab{0}` set is_default = 0
where ifnull(is_default,0) = 1 and name != %s and company = %s""".format(doc.doctype),
(doc.name, doc.company))
if doc.meta.get_field("territories"):
if not doc.territories:
doc.append("territories", {"territory": get_root_of("Territory") })
for tax in doc.get("taxes"):
validate_taxes_and_charges(tax)
validate_inclusive_tax(tax, doc)

View File

@ -183,4 +183,4 @@ def install(country=None):
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
doc.insert()
doc.insert(ignore_permissions=True)

View File

@ -0,0 +1,117 @@
# 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, get_random
import frappe.utils
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": "Yes"})
buying_items = frappe.get_all("Item", filters = {"is_sales_item": "No"})
if selling_items:
for i in range(3):
make_opportunity(selling_items)
make_quote(selling_items)
make_projects()
if buying_items:
make_material_request(buying_items)
frappe.db.commit()
def make_opportunity(selling_items):
b = frappe.get_doc({
"doctype": "Opportunity",
"enquiry_from": "Customer",
"customer": get_random("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": "Yes"})
}, unique="item_code")
b.insert(ignore_permissions=True)
b.add_comment("This is a dummy record")
def make_quote(selling_items):
qtn = frappe.get_doc({
"doctype": "Quotation",
"quotation_to": "Customer",
"customer": get_random("Customer"),
"order_type": "Sales"
})
add_random_children(qtn, "items", rows=len(selling_items), randomize = {
"qty": (1, 5),
"item_code": ("Item", {"is_sales_item": "Yes"})
}, 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": "Go Live!",
"start_date": frappe.utils.add_days(current_date, 5),
"end_date": frappe.utils.add_days(current_date, 6)
}])
project.insert(ignore_permissions=True)

View File

@ -25,6 +25,7 @@ frappe.pages['setup-wizard'].on_page_load = function(wrapper) {
erpnext.wiz.user.slide,
erpnext.wiz.org.slide,
erpnext.wiz.branding.slide,
erpnext.wiz.users.slide,
erpnext.wiz.taxes.slide,
erpnext.wiz.customers.slide,
erpnext.wiz.suppliers.slide,
@ -137,7 +138,7 @@ erpnext.wiz.WizardSlide = Class.extend({
});
this.form.make();
} else {
$(this.body).html(this.html)
$(this.body).html(this.html);
}
if(this.id > 0) {
@ -412,11 +413,30 @@ $.extend(erpnext.wiz, {
onload: function(slide) {
erpnext.wiz.org.load_chart_of_accounts(slide);
erpnext.wiz.org.bind_events(slide);
erpnext.wiz.org.set_fy_dates(slide);
},
css_class: "single-column"
},
set_fy_dates: function(slide) {
var country = slide.wiz.get_values().country;
if(country) {
var fy = erpnext.wiz.fiscal_years[country];
var current_year = moment(new Date()).year();
var next_year = current_year + 1;
if(!fy) {
fy = ["01-01", "12-31"];
next_year = current_year;
}
slide.get_field("fy_start_date").set_input(current_year + "-" + fy[0]);
slide.get_field("fy_end_date").set_input(next_year + "-" + fy[1]);
}
},
load_chart_of_accounts: function(slide) {
var country = slide.wiz.get_values().country;
@ -486,11 +506,41 @@ $.extend(erpnext.wiz, {
},
},
users: {
slide: {
icon: "icon-money",
"title": __("Add Users"),
"help": __("Add users to your organization"),
"fields": [],
before_load: function(slide) {
slide.fields = [];
for(var i=1; i<5; i++) {
slide.fields = slide.fields.concat([
{fieldtype:"Section Break"},
{fieldtype:"Data", fieldname:"user_fullname_"+ i,
label:__("Full Name")},
{fieldtype:"Data", fieldname:"user_email_" + i,
label:__("Email ID"), placeholder:__("user@example.com"),
options: "Email"},
{fieldtype:"Column Break"},
{fieldtype: "Check", fieldname: "user_sales_" + i,
label:__("Sales"), default: 1},
{fieldtype: "Check", fieldname: "user_purchaser_" + i,
label:__("Purchaser"), default: 1},
{fieldtype: "Check", fieldname: "user_accountant_" + i,
label:__("Accountant"), default: 1},
]);
}
},
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."),
"help": __("List your tax heads (e.g. VAT, Customs etc; 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 = [];
@ -526,6 +576,7 @@ $.extend(erpnext.wiz, {
label:__("Contact Name") + " " + i, placeholder:__("Contact Name")}
])
}
slide.fields[1].reqd = 1;
},
css_class: "two-column"
},
@ -549,6 +600,7 @@ $.extend(erpnext.wiz, {
label:__("Contact Name") + " " + i, placeholder:__("Contact Name")},
])
}
slide.fields[1].reqd = 1;
},
css_class: "two-column"
},
@ -578,9 +630,11 @@ $.extend(erpnext.wiz, {
{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:"Currency", fieldname:"item_price_" + i, label:__("Rate")},
{fieldtype:"Attach Image", fieldname:"item_img_" + i, label:__("Attach Image")},
])
}
slide.fields[1].reqd = 1;
},
css_class: "two-column"
},
@ -627,3 +681,25 @@ $.extend(erpnext.wiz, {
},
});
// Source: https://en.wikipedia.org/wiki/Fiscal_year
// default 1st Jan - 31st Dec
erpnext.wiz.fiscal_years = {
"Afghanistan": ["12-20", "12-21"],
"Australia": ["07-01", "06-30"],
"Bangladesh": ["07-01", "06-30"],
"Canada": ["04-01", "03-31"],
"Costa Rica": ["10-01", "09-30"],
"Egypt": ["07-01", "06-30"],
"Hong Kong": ["04-01", "03-31"],
"India": ["04-01", "03-31"],
"Iran": ["06-23", "06-22"],
"Italy": ["07-01", "06-30"],
"Myanmar": ["04-01", "03-31"],
"New Zealand": ["04-01", "03-31"],
"Pakistan": ["07-01", "06-30"],
"Singapore": ["04-01", "03-31"],
"South Africa": ["03-01", "02-28"],
"Thailand": ["10-01", "09-30"],
"United Kingdom": ["04-01", "03-31"],
}

View File

@ -2,7 +2,7 @@
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe, json
import frappe, json, copy
from frappe.utils import cstr, flt, getdate
from frappe import _
@ -13,6 +13,7 @@ from frappe.geo.country_info import get_country_info
from frappe.utils.nestedset import get_root_of
from .default_website import website_maker
import install_fixtures
from .sample_data import make_sample_data
@frappe.whitelist()
def setup_account(args=None):
@ -38,6 +39,9 @@ def setup_account(args=None):
create_fiscal_year_and_company(args)
frappe.local.message_log = []
create_users(args)
frappe.local.message_log = []
set_defaults(args)
frappe.local.message_log = []
@ -81,6 +85,7 @@ def setup_account(args=None):
frappe.clear_cache()
make_sample_data()
except:
if args:
traceback = frappe.get_traceback()
@ -297,21 +302,45 @@ def create_taxes(args):
tax_group = frappe.db.get_value("Account", {"company": args.get("company_name"),
"is_group": 1, "account_type": "Tax", "root_type": "Liability"})
if tax_group:
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()
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
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):
@ -349,9 +378,30 @@ def create_items(args):
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))
@ -451,6 +501,60 @@ 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
user.insert(ignore_permissions=True)
# create employee
emp = frappe.get_doc({
"doctype": "Employee",
"full_name": fullname,
"user_id": user.name,
"status": "Active",
"company": args.get("company_name")
})
emp.flags.ignore_mandatory = True
emp.insert(ignore_permissions = True)
@frappe.whitelist()
def load_messages(language):
frappe.clear_cache()

View File

@ -51,4 +51,15 @@ args = {
"timezone": "America/New_York",
"password": "password",
"email": "test@erpnext.com",
"user_email_1": "testsetup1@example.com",
"user_fullname_1": "test setup user",
"user_sales_1": 1,
"user_purchaser_1": 1,
"user_accountant_1": 1,
"user_email_1": "testsetup2@example.com",
"user_fullname_1": "test setup user",
"user_sales_2": 1,
"user_purchaser_2": 0,
"user_accountant_2": 0
}

View File

@ -10,6 +10,7 @@ def get_notification_config():
"Issue": {"status": "Open"},
"Warranty Claim": {"status": "Open"},
"Task": {"status": "Open"},
"Project": {"status": "Open"},
"Lead": {"status": "Open"},
"Contact": {"status": "Open"},
"Opportunity": {"status": "Open"},