Merge pull request #35777 from deepeshgarg007/demo_data_on_install

feat: Demo setup
This commit is contained in:
Ankush Menat 2023-08-11 14:38:38 +05:30 committed by GitHub
commit 581d98c5ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 849 additions and 74 deletions

View File

@ -707,6 +707,7 @@ def get_payment_terms_template(party_name, party_type, company=None):
if party_type not in ("Customer", "Supplier"):
return
template = None
if party_type == "Customer":
customer = frappe.get_cached_value(
"Customer", party_name, fieldname=["payment_terms", "customer_group"], as_dict=1

View File

@ -5,7 +5,7 @@
"label": "Profit and Loss"
}
],
"content": "[{\"id\":\"MmUf9abwxg\",\"type\":\"onboarding\",\"data\":{\"onboarding_name\":\"Accounts\",\"col\":12}},{\"id\":\"i0EtSjDAXq\",\"type\":\"chart\",\"data\":{\"chart_name\":\"Profit and Loss\",\"col\":12}},{\"id\":\"X78jcbq1u3\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"vikWSkNm6_\",\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Your Shortcuts</b></span>\",\"col\":12}},{\"id\":\"pMywM0nhlj\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Chart of Accounts\",\"col\":3}},{\"id\":\"_pRdD6kqUG\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Sales Invoice\",\"col\":3}},{\"id\":\"G984SgVRJN\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Invoice\",\"col\":3}},{\"id\":\"1ArNvt9qhz\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Journal Entry\",\"col\":3}},{\"id\":\"F9f4I1viNr\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Payment Entry\",\"col\":3}},{\"id\":\"4IBBOIxfqW\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Accounts Receivable\",\"col\":3}},{\"id\":\"El2anpPaFY\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"General Ledger\",\"col\":3}},{\"id\":\"1nwcM9upJo\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Trial Balance\",\"col\":3}},{\"id\":\"OF9WOi1Ppc\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"id\":\"iAwpe-Chra\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Learn Accounting\",\"col\":3}},{\"id\":\"B7-uxs8tkU\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"tHb3yxthkR\",\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Reports &amp; Masters</b></span>\",\"col\":12}},{\"id\":\"DnNtsmxpty\",\"type\":\"card\",\"data\":{\"card_name\":\"Accounting Masters\",\"col\":4}},{\"id\":\"nKKr6fjgjb\",\"type\":\"card\",\"data\":{\"card_name\":\"General Ledger\",\"col\":4}},{\"id\":\"xOHTyD8b5l\",\"type\":\"card\",\"data\":{\"card_name\":\"Accounts Receivable\",\"col\":4}},{\"id\":\"_Cb7C8XdJJ\",\"type\":\"card\",\"data\":{\"card_name\":\"Accounts Payable\",\"col\":4}},{\"id\":\"p7NY6MHe2Y\",\"type\":\"card\",\"data\":{\"card_name\":\"Financial Statements\",\"col\":4}},{\"id\":\"KlqilF5R_V\",\"type\":\"card\",\"data\":{\"card_name\":\"Taxes\",\"col\":4}},{\"id\":\"jTUy8LB0uw\",\"type\":\"card\",\"data\":{\"card_name\":\"Cost Center and Budgeting\",\"col\":4}},{\"id\":\"Wn2lhs7WLn\",\"type\":\"card\",\"data\":{\"card_name\":\"Multi Currency\",\"col\":4}},{\"id\":\"PAQMqqNkBM\",\"type\":\"card\",\"data\":{\"card_name\":\"Bank Statement\",\"col\":4}},{\"id\":\"Q_hBCnSeJY\",\"type\":\"card\",\"data\":{\"card_name\":\"Reports\",\"col\":4}},{\"id\":\"3AK1Zf0oew\",\"type\":\"card\",\"data\":{\"card_name\":\"Profitability\",\"col\":4}},{\"id\":\"kxhoaiqdLq\",\"type\":\"card\",\"data\":{\"card_name\":\"Opening and Closing\",\"col\":4}},{\"id\":\"q0MAlU2j_Z\",\"type\":\"card\",\"data\":{\"card_name\":\"Subscription Management\",\"col\":4}},{\"id\":\"ptm7T6Hwu-\",\"type\":\"card\",\"data\":{\"card_name\":\"Share Management\",\"col\":4}},{\"id\":\"OX7lZHbiTr\",\"type\":\"card\",\"data\":{\"card_name\":\"Settings\",\"col\":4}}]",
"content": "[{\"id\":\"MmUf9abwxg\",\"type\":\"onboarding\",\"data\":{\"onboarding_name\":\"Accounts\",\"col\":12}},{\"id\":\"VVvJ1lUcfc\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Outgoing Bills\",\"col\":3}},{\"id\":\"Vlj2FZtlHV\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Incoming Bills\",\"col\":3}},{\"id\":\"VVVjQVAhPf\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Incoming Payment\",\"col\":3}},{\"id\":\"DySNdlysIW\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Outgoing Payment\",\"col\":3}},{\"id\":\"i0EtSjDAXq\",\"type\":\"chart\",\"data\":{\"chart_name\":\"Profit and Loss\",\"col\":12}},{\"id\":\"X78jcbq1u3\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"vikWSkNm6_\",\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Your Shortcuts</b></span>\",\"col\":12}},{\"id\":\"pMywM0nhlj\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Chart of Accounts\",\"col\":3}},{\"id\":\"_pRdD6kqUG\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Sales Invoice\",\"col\":3}},{\"id\":\"G984SgVRJN\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Invoice\",\"col\":3}},{\"id\":\"1ArNvt9qhz\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Journal Entry\",\"col\":3}},{\"id\":\"F9f4I1viNr\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Payment Entry\",\"col\":3}},{\"id\":\"4IBBOIxfqW\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Accounts Receivable\",\"col\":3}},{\"id\":\"El2anpPaFY\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"General Ledger\",\"col\":3}},{\"id\":\"1nwcM9upJo\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Trial Balance\",\"col\":3}},{\"id\":\"OF9WOi1Ppc\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"id\":\"iAwpe-Chra\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Learn Accounting\",\"col\":3}},{\"id\":\"B7-uxs8tkU\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"tHb3yxthkR\",\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Reports &amp; Masters</b></span>\",\"col\":12}},{\"id\":\"DnNtsmxpty\",\"type\":\"card\",\"data\":{\"card_name\":\"Accounting Masters\",\"col\":4}},{\"id\":\"nKKr6fjgjb\",\"type\":\"card\",\"data\":{\"card_name\":\"General Ledger\",\"col\":4}},{\"id\":\"xOHTyD8b5l\",\"type\":\"card\",\"data\":{\"card_name\":\"Accounts Receivable\",\"col\":4}},{\"id\":\"_Cb7C8XdJJ\",\"type\":\"card\",\"data\":{\"card_name\":\"Accounts Payable\",\"col\":4}},{\"id\":\"p7NY6MHe2Y\",\"type\":\"card\",\"data\":{\"card_name\":\"Financial Statements\",\"col\":4}},{\"id\":\"KlqilF5R_V\",\"type\":\"card\",\"data\":{\"card_name\":\"Taxes\",\"col\":4}},{\"id\":\"jTUy8LB0uw\",\"type\":\"card\",\"data\":{\"card_name\":\"Cost Center and Budgeting\",\"col\":4}},{\"id\":\"Wn2lhs7WLn\",\"type\":\"card\",\"data\":{\"card_name\":\"Multi Currency\",\"col\":4}},{\"id\":\"PAQMqqNkBM\",\"type\":\"card\",\"data\":{\"card_name\":\"Bank Statement\",\"col\":4}},{\"id\":\"Q_hBCnSeJY\",\"type\":\"card\",\"data\":{\"card_name\":\"Reports\",\"col\":4}},{\"id\":\"3AK1Zf0oew\",\"type\":\"card\",\"data\":{\"card_name\":\"Profitability\",\"col\":4}},{\"id\":\"kxhoaiqdLq\",\"type\":\"card\",\"data\":{\"card_name\":\"Opening and Closing\",\"col\":4}},{\"id\":\"q0MAlU2j_Z\",\"type\":\"card\",\"data\":{\"card_name\":\"Subscription Management\",\"col\":4}},{\"id\":\"ptm7T6Hwu-\",\"type\":\"card\",\"data\":{\"card_name\":\"Share Management\",\"col\":4}},{\"id\":\"OX7lZHbiTr\",\"type\":\"card\",\"data\":{\"card_name\":\"Settings\",\"col\":4}}]",
"creation": "2020-03-02 15:41:59.515192",
"custom_blocks": [],
"docstatus": 0,
@ -1061,11 +1061,28 @@
"type": "Link"
}
],
"modified": "2023-07-04 14:32:15.842044",
"modified": "2023-08-10 17:41:14.059005",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounting",
"number_cards": [],
"number_cards": [
{
"label": "Total Outgoing Bills",
"number_card_name": "Total Outgoing Bills"
},
{
"label": "Total Incoming Bills",
"number_card_name": "Total Incoming Bills"
},
{
"label": "Total Incoming Payment",
"number_card_name": "Total Incoming Payment"
},
{
"label": "Total Outgoing Payment",
"number_card_name": "Total Outgoing Payment"
}
],
"owner": "Administrator",
"parent_page": "",
"public": 1,

View File

@ -70,6 +70,19 @@ treeviews = [
"Department",
]
demo_master_doctypes = [
"item_group",
"item",
"customer_group",
"supplier_group",
"customer",
"supplier",
]
demo_transaction_doctypes = [
"purchase_order",
"sales_order",
]
jinja = {
"methods": [
"erpnext.stock.serial_batch_bundle.get_serial_or_batch_nos",

View File

@ -1,68 +0,0 @@
{
"css/erpnext.css": [
"public/less/erpnext.less",
"public/scss/call_popup.scss",
"public/scss/point-of-sale.scss"
],
"js/erpnext-web.min.js": [
"public/js/website_utils.js",
"public/js/shopping_cart.js",
"public/js/wishlist.js"
],
"css/erpnext-web.css": [
"public/scss/website.scss",
"public/scss/shopping_cart.scss"
],
"js/erpnext.min.js": [
"public/js/conf.js",
"public/js/utils.js",
"public/js/queries.js",
"public/js/sms_manager.js",
"public/js/utils/party.js",
"public/js/controllers/stock_controller.js",
"public/js/payment/payments.js",
"public/js/controllers/taxes_and_totals.js",
"public/js/controllers/transaction.js",
"public/js/templates/item_selector.html",
"public/js/utils/item_selector.js",
"public/js/help_links.js",
"public/js/templates/item_quick_entry.html",
"public/js/utils/customer_quick_entry.js",
"public/js/utils/supplier_quick_entry.js",
"public/js/education/student_button.html",
"public/js/education/assessment_result_tool.html",
"public/js/call_popup/call_popup.js",
"public/js/utils/dimension_tree_filter.js",
"public/js/telephony.js",
"public/js/templates/call_link.html",
"public/js/bulk_transaction_processing.js"
],
"js/item-dashboard.min.js": [
"stock/dashboard/item_dashboard.html",
"stock/dashboard/item_dashboard_list.html",
"stock/dashboard/item_dashboard.js",
"stock/page/warehouse_capacity_summary/warehouse_capacity_summary.html",
"stock/page/warehouse_capacity_summary/warehouse_capacity_summary_header.html"
],
"js/point-of-sale.min.js": [
"selling/page/point_of_sale/pos_item_selector.js",
"selling/page/point_of_sale/pos_item_cart.js",
"selling/page/point_of_sale/pos_item_details.js",
"selling/page/point_of_sale/pos_number_pad.js",
"selling/page/point_of_sale/pos_payment.js",
"selling/page/point_of_sale/pos_past_order_list.js",
"selling/page/point_of_sale/pos_past_order_summary.js",
"selling/page/point_of_sale/pos_controller.js"
],
"js/bank-reconciliation-tool.min.js": [
"public/js/bank_reconciliation_tool/data_table_manager.js",
"public/js/bank_reconciliation_tool/number_card.js",
"public/js/bank_reconciliation_tool/dialog_manager.js"
],
"js/e-commerce.min.js": [
"e_commerce/product_ui/views.js",
"e_commerce/product_ui/grid.js",
"e_commerce/product_ui/list.js",
"e_commerce/product_ui/search.js"
]
}

View File

@ -28,5 +28,6 @@ import "./controllers/accounts.js"
import "./utils/landed_taxes_and_charges_common.js";
import "./utils/sales_common.js";
import "./controllers/buying.js";
import "./utils/demo.js";
// import { sum } from 'frappe/public/utils/util.js'

View File

@ -40,6 +40,12 @@ erpnext.setup.slides_settings = [
{ fieldname: 'fy_start_date', label: __('Financial Year Begins On'), fieldtype: 'Date', reqd: 1 },
// end date should be hidden (auto calculated)
{ fieldname: 'fy_end_date', label: __('End Date'), fieldtype: 'Date', reqd: 1, hidden: 1 },
{ fieldtype: "Section Break" },
{
fieldname: 'setup_demo',
label: __('Generate Demo Data for Exploration'),
fieldtype: 'Check',
description: 'If checked, we will create demo data for you to explore the system. This demo data can be erased later.'},
],
onload: function (slide) {

View File

@ -0,0 +1,71 @@
$(document).on("toolbar_setup", function () {
if (frappe.boot.sysdefaults.demo_company) {
erpnext.setup_clear_button();
}
// for first load
frappe.realtime.on("demo_data_complete", () => {
erpnext.setup_clear_button();
});
});
erpnext.setup_clear_button = function () {
let message_string = __(
"Demo data is present on the system, erase data before starting real usage."
);
let $floatingBar = $(`
<div class="flex justify-content-center" style="width: 100%;">
<div class="flex justify-content-center flex-col shadow rounded p-2"
style="
background-color: #e0f2fe;
position: fixed;
bottom: 20px;
z-index: 1;">
<p style="margin: auto 0; padding-left: 10px; margin-right: 20px; font-size: 15px;">
${message_string}
</p>
<button id="clear-demo" type="button"
class="
px-4
py-2
border
border-transparent
text-white
"
style="
margin: auto 0;
height: fit-content;
background-color: #007bff;
border-radius: 5px;
margin-right: 10px
"
>
Clear Demo Data
</button>
</div>
</div>
`);
$("footer").append($floatingBar);
$("#clear-demo").on("click", function () {
frappe.confirm(
__("Are you sure you want to clear all demo data?"),
() => {
frappe.call({
method: "erpnext.setup.demo.clear_demo_data",
freeze: true,
freeze_message: __("Clearing Demo Data..."),
callback: function (r) {
frappe.ui.toolbar.clear_cache();
frappe.show_alert({
message: __("Demo data cleared"),
indicator: "green",
});
$("footer").remove($floatingBar);
},
});
}
);
});
};

202
erpnext/setup/demo.py Normal file
View File

@ -0,0 +1,202 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
import json
import os
from random import randint
import frappe
from frappe import _
from frappe.utils import add_days, getdate
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
from erpnext.accounts.utils import get_fiscal_year
from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_invoice
from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
from erpnext.setup.setup_wizard.operations.install_fixtures import create_bank_account
def setup_demo_data():
from frappe.utils.telemetry import capture
capture("demo_data_creation_started", "erpnext")
try:
company = create_demo_company()
process_masters()
make_transactions(company)
frappe.cache.delete_keys("bootinfo")
frappe.publish_realtime("demo_data_complete")
except Exception:
frappe.log_error("Failed to create demo data")
capture("demo_data_creation_failed", "erpnext", properties={"exception": frappe.get_traceback()})
raise
capture("demo_data_creation_completed", "erpnext")
@frappe.whitelist()
def clear_demo_data():
from frappe.utils.telemetry import capture
frappe.only_for("System Manager")
capture("demo_data_erased", "erpnext")
try:
company = frappe.db.get_single_value("Global Defaults", "demo_company")
create_transaction_deletion_record(company)
clear_masters()
delete_company(company)
default_company = frappe.db.get_single_value("Global Defaults", "default_company")
frappe.db.set_default("company", default_company)
except Exception:
frappe.db.rollback()
frappe.log_error("Failed to erase demo data")
frappe.throw(
_("Failed to erase demo data, please delete the demo company manually."),
title=_("Could Not Delete Demo Data"),
)
def create_demo_company():
company = frappe.db.get_all("Company")[0].name
company_doc = frappe.get_doc("Company", company)
# Make a dummy company
new_company = frappe.new_doc("Company")
new_company.company_name = company_doc.company_name + " (Demo)"
new_company.abbr = company_doc.abbr + "D"
new_company.enable_perpetual_inventory = 1
new_company.default_currency = company_doc.default_currency
new_company.country = company_doc.country
new_company.chart_of_accounts_based_on = "Standard Template"
new_company.chart_of_accounts = company_doc.chart_of_accounts
new_company.insert()
# Set Demo Company as default to
frappe.db.set_single_value("Global Defaults", "demo_company", new_company.name)
frappe.db.set_default("company", new_company.name)
bank_account = create_bank_account({"company_name": new_company.name})
frappe.db.set_value("Company", new_company.name, "default_bank_account", bank_account.name)
return new_company.name
def process_masters():
for doctype in frappe.get_hooks("demo_master_doctypes"):
data = read_data_file_using_hooks(doctype)
if data:
for item in json.loads(data):
create_demo_record(item)
def create_demo_record(doctype):
frappe.get_doc(doctype).insert(ignore_permissions=True)
def make_transactions(company):
frappe.db.set_single_value("Stock Settings", "allow_negative_stock", 1)
start_date = get_fiscal_year(date=getdate())[1]
for doctype in frappe.get_hooks("demo_transaction_doctypes"):
data = read_data_file_using_hooks(doctype)
if data:
for item in json.loads(data):
create_transaction(item, company, start_date)
convert_order_to_invoices()
frappe.db.set_single_value("Stock Settings", "allow_negative_stock", 0)
def create_transaction(doctype, company, start_date):
document_type = doctype.get("doctype")
warehouse = get_warehouse(company)
if document_type == "Purchase Order":
posting_date = get_random_date(start_date, 1, 30)
else:
posting_date = get_random_date(start_date, 31, 365)
doctype.update(
{
"company": company,
"set_posting_time": 1,
"transaction_date": posting_date,
"schedule_date": posting_date,
"delivery_date": posting_date,
"set_warehouse": warehouse,
}
)
doc = frappe.get_doc(doctype)
doc.save(ignore_permissions=True)
doc.submit()
def convert_order_to_invoices():
for document in ["Purchase Order", "Sales Order"]:
# Keep some orders intentionally unbilled/unpaid
for i, order in enumerate(
frappe.db.get_all(
document, filters={"docstatus": 1}, fields=["name", "transaction_date"], limit=6
)
):
if document == "Purchase Order":
invoice = make_purchase_invoice(order.name)
elif document == "Sales Order":
invoice = make_sales_invoice(order.name)
invoice.set_posting_time = 1
invoice.posting_date = order.transaction_date
invoice.due_date = order.transaction_date
invoice.update_stock = 1
invoice.submit()
if i % 2 != 0:
payment = get_payment_entry(invoice.doctype, invoice.name)
payment.reference_no = invoice.name
payment.submit()
def get_random_date(start_date, start_range, end_range):
return add_days(start_date, randint(start_range, end_range))
def create_transaction_deletion_record(company):
transaction_deletion_record = frappe.new_doc("Transaction Deletion Record")
transaction_deletion_record.company = company
transaction_deletion_record.save(ignore_permissions=True)
transaction_deletion_record.submit()
def clear_masters():
for doctype in frappe.get_hooks("demo_master_doctypes")[::-1]:
data = read_data_file_using_hooks(doctype)
if data:
for item in json.loads(data):
clear_demo_record(item)
def clear_demo_record(document):
document_type = document.get("doctype")
del document["doctype"]
doc = frappe.get_doc(document_type, document)
frappe.delete_doc(doc.doctype, doc.name, ignore_permissions=True)
def delete_company(company):
frappe.db.set_single_value("Global Defaults", "demo_company", "")
frappe.delete_doc("Company", company, ignore_permissions=True)
def read_data_file_using_hooks(doctype):
path = os.path.join(os.path.dirname(__file__), "demo_data")
with open(os.path.join(path, doctype + ".json"), "r") as f:
data = f.read()
return data
def get_warehouse(company):
warehouses = frappe.db.get_all("Warehouse", {"company": company, "is_group": 0})
return warehouses[randint(0, 3)].name

View File

@ -0,0 +1,20 @@
[
{
"doctype": "Customer",
"customer_group": "Demo Customer Group",
"territory": "All Territories",
"customer_name": "Grant Plastics Ltd."
},
{
"doctype": "Customer",
"customer_group": "Demo Customer Group",
"territory": "All Territories",
"customer_name": "West View Software Ltd."
},
{
"doctype": "Customer",
"customer_group": "Demo Customer Group",
"territory": "All Territories",
"customer_name": "Palmer Productions Ltd."
}
]

View File

@ -0,0 +1,6 @@
[
{
"doctype": "Customer Group",
"customer_group_name": "Demo Customer Group"
}
]

View File

@ -0,0 +1,72 @@
[
{
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU001",
"item_name": "T-shirt",
"image": "https://images.pexels.com/photos/1484808/pexels-photo-1484808.jpeg"
},
{
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU002",
"item_name": "Laptop",
"image": "https://images.pexels.com/photos/3999538/pexels-photo-3999538.jpeg"
},
{
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU003",
"item_name": "Book",
"image": "https://images.pexels.com/photos/2422178/pexels-photo-2422178.jpeg"
},
{
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU004",
"item_name": "Smartphone",
"image": "https://images.pexels.com/photos/1647976/pexels-photo-1647976.jpeg"
},
{
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU005",
"item_name": "Sneakers",
"image": "https://images.pexels.com/photos/1598505/pexels-photo-1598505.jpeg"
},
{
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU006",
"item_name": "Coffee Mug",
"image": "https://images.pexels.com/photos/585753/pexels-photo-585753.jpeg"
},
{
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU007",
"item_name": "Television",
"image": "https://images.pexels.com/photos/8059376/pexels-photo-8059376.jpeg"
},
{
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU008",
"item_name": "Backpack",
"image": "https://images.pexels.com/photos/3731256/pexels-photo-3731256.jpeg"
},
{
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU009",
"item_name": "Headphones",
"image": "https://images.pexels.com/photos/3587478/pexels-photo-3587478.jpeg"
},
{
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU010",
"item_name": "Camera",
"image": "https://images.pexels.com/photos/51383/photo-camera-subject-photographer-51383.jpeg"
}
]

View File

@ -0,0 +1,7 @@
[
{
"doctype": "Item Group",
"item_group_name": "Demo Item Group",
"parent_item_group": "All Item Groups"
}
]

View File

@ -0,0 +1,25 @@
[
{
"cheque_date": "2023-03-14",
"cheque_no": "33",
"doctype": "Journal Entry",
"accounts": [
{
"party_type": "Customer",
"party": "ABC Enterprises",
"credit_in_account_currency": 40000.0,
"debit_in_account_currency": 0.0,
"doctype": "Journal Entry Account",
"parentfield": "accounts",
},
{
"credit_in_account_currency": 0.0,
"debit_in_account_currency": 40000.0,
"doctype": "Journal Entry Account",
"parentfield": "accounts",
}
],
"user_remark": "test",
"voucher_type": "Bank Entry"
}
]

View File

@ -0,0 +1,57 @@
[
{
"doctype": "Payment Entry",
"payment_type": "Receive",
"party_type": "Customer",
"party": "ABC Enterprises",
"paid_amount": 67000,
"received_amount": 67000,
"reference_no": "#ref0001",
"source_exchange_rate": 1,
"target_exchange_rate": 1
},
{
"doctype": "Payment Entry",
"payment_type": "Receive",
"party_type": "Customer",
"party": "XYZ Corporation",
"paid_amount": 500000,
"received_amount": 500000,
"reference_no": "#ref0001",
"source_exchange_rate": 1,
"target_exchange_rate": 1
},
{
"doctype": "Payment Entry",
"payment_type": "Receive",
"party_type": "Customer",
"party": "KJPR Pvt. Ltd.",
"paid_amount": 300000,
"received_amount": 30000,
"reference_no": "#ref0001",
"source_exchange_rate": 1,
"target_exchange_rate": 1
},
{
"doctype": "Payment Entry",
"payment_type": "Pay",
"party_type": "Supplier",
"party": "DQ Industries",
"paid_amount": 85000,
"received_amount": 85000,
"reference_no": "#ref0005",
"source_exchange_rate": 1,
"target_exchange_rate": 1
},
{
"doctype": "Payment Entry",
"payment_type": "Pay",
"party_type": "Supplier",
"party": "KC Corp.",
"paid_amount": 100000,
"received_amount": 100000,
"reference_no": "#ref0006",
"source_exchange_rate": 1,
"target_exchange_rate": 1
}
]

View File

@ -0,0 +1,162 @@
[
{
"conversion_rate": 1.0,
"supplier": "Zuckerman Security Ltd.",
"doctype": "Purchase Order",
"update_stock": 1,
"items": [
{
"doctype": "Purchase Order Item",
"item_code": "SKU001",
"parentfield": "items",
"qty": 100.0,
"rate": 400.0,
"conversion_factor": 1
}
]
},
{
"conversion_rate": 1.0,
"supplier": "MA Inc.",
"doctype": "Purchase Order",
"update_stock": 1,
"items": [
{
"doctype": "Purchase Order Item",
"item_code": "SKU002",
"parentfield": "items",
"qty": 50.0,
"rate": 300.0,
"conversion_factor": 1
}
]
},
{
"conversion_rate": 1.0,
"supplier": "Summit Traders Ltd.",
"doctype": "Purchase Order",
"update_stock": 1,
"items": [
{
"doctype": "Purchase Order Item",
"item_code": "SKU003",
"parentfield": "items",
"qty": 200.0,
"rate": 523.0,
"conversion_factor": 1
}
]
},
{
"conversion_rate": 1.0,
"supplier": "Zuckerman Security Ltd.",
"doctype": "Purchase Order",
"update_stock": 1,
"items": [
{
"doctype": "Purchase Order Item",
"item_code": "SKU004",
"parentfield": "items",
"qty": 60.0,
"rate": 725.0,
"conversion_factor": 1
}
]
},
{
"conversion_rate": 1.0,
"supplier": "MA Inc.",
"doctype": "Purchase Order",
"update_stock": 1,
"items": [
{
"doctype": "Purchase Order Item",
"item_code": "SKU005",
"parentfield": "items",
"qty": 182.0,
"rate": 222.0,
"conversion_factor": 1
}
]
},
{
"conversion_rate": 1.0,
"supplier": "Summit Traders Ltd.",
"doctype": "Purchase Order",
"update_stock": 1,
"items": [
{
"doctype": "Purchase Order Item",
"item_code": "SKU006",
"parentfield": "items",
"qty": 250.0,
"rate": 420.0,
"conversion_factor": 1
}
]
},
{
"conversion_rate": 1.0,
"supplier": "Zuckerman Security Ltd.",
"doctype": "Purchase Order",
"update_stock": 1,
"items": [
{
"doctype": "Purchase Order Item",
"item_code": "SKU007",
"parentfield": "items",
"qty": 190.0,
"rate": 375.0,
"conversion_factor": 1
}
]
},
{
"conversion_rate": 1.0,
"supplier": "MA Inc.",
"doctype": "Purchase Order",
"update_stock": 1,
"items": [
{
"doctype": "Purchase Order Item",
"item_code": "SKU008",
"parentfield": "items",
"qty": 121.0,
"rate": 333.0,
"conversion_factor": 1
}
]
},
{
"conversion_rate": 1.0,
"supplier": "Summit Traders Ltd.",
"doctype": "Purchase Order",
"update_stock": 1,
"items": [
{
"doctype": "Purchase Order Item",
"item_code": "SKU009",
"parentfield": "items",
"qty": 76.0,
"rate": 700.0,
"conversion_factor": 1
}
]
},
{
"conversion_rate": 1.0,
"supplier": "Zuckerman Security Ltd.",
"doctype": "Purchase Order",
"update_stock": 1,
"items": [
{
"doctype": "Purchase Order Item",
"item_code": "SKU010",
"parentfield": "items",
"qty": 78.0,
"rate": 500.0,
"conversion_factor": 1
}
]
}
]

View File

@ -0,0 +1,122 @@
[
{
"conversion_rate": 1.0,
"customer": "Grant Plastics Ltd.",
"doctype": "Sales Order",
"update_stock": 1,
"items": [
{
"doctype": "Sales Order Item",
"item_code": "SKU004",
"parentfield": "items",
"qty": 20.0,
"rate": 1000.0,
"conversion_factor": 1
}
]
},
{
"conversion_rate": 1.0,
"customer": "West View Software Ltd.",
"doctype": "Sales Order",
"update_stock": 1,
"items": [
{
"doctype": "Sales Order Item",
"item_code": "SKU001",
"parentfield": "items",
"qty": 25.0,
"rate": 800.0,
"conversion_factor": 1
},
{
"doctype": "Sales Order Item",
"item_code": "SKU002",
"parentfield": "items",
"qty": 15.0,
"rate": 800.0,
"conversion_factor": 1
}
]
},
{
"conversion_rate": 1.0,
"customer": "West View Software Ltd.",
"doctype": "Sales Order",
"update_stock": 1,
"items": [
{
"doctype": "Sales Order Item",
"item_code": "SKU003",
"parentfield": "items",
"qty": 100,
"rate": 500.0,
"conversion_factor": 1
},
{
"doctype": "Sales Order Item",
"item_code": "SKU006",
"parentfield": "items",
"qty": 100,
"rate": 890.0,
"conversion_factor": 1
},
{
"doctype": "Sales Order Item",
"item_code": "SKU007",
"parentfield": "items",
"qty": 100,
"rate": 900.0,
"conversion_factor": 1
}
]
},
{
"conversion_rate": 1.0,
"customer": "Palmer Productions Ltd.",
"doctype": "Sales Order",
"update_stock": 1,
"items": [
{
"doctype": "Sales Order Item",
"item_code": "SKU005",
"parentfield": "items",
"qty": 150.0,
"rate": 100.0,
"conversion_factor": 1
}
]
},
{
"conversion_rate": 1.0,
"customer": "Grant Plastics Ltd.",
"doctype": "Sales Order",
"update_stock": 1,
"items": [
{
"doctype": "Sales Order Item",
"item_code": "SKU008",
"parentfield": "items",
"qty": 20.0,
"rate": 500.0,
"conversion_factor": 1
},
{
"doctype": "Sales Order Item",
"item_code": "SKU009",
"parentfield": "items",
"qty": 40.0,
"rate": 300.0,
"conversion_factor": 1
},
{
"doctype": "Sales Order Item",
"item_code": "SKU010",
"parentfield": "items",
"qty": 50.0,
"rate": 900.0,
"conversion_factor": 1
}
]
}
]

View File

@ -0,0 +1,17 @@
[
{
"doctype": "Supplier",
"supplier_group": "Demo Supplier Group",
"supplier_name": "Zuckerman Security Ltd."
},
{
"doctype": "Supplier",
"supplier_group": "Demo Supplier Group",
"supplier_name": "MA Inc."
},
{
"doctype": "Supplier",
"supplier_group": "Demo Supplier Group",
"supplier_name": "Summit Traders Ltd."
}
]

View File

@ -0,0 +1,6 @@
[
{
"doctype": "Supplier Group",
"supplier_group_name": "Demo Supplier Group"
}
]

View File

@ -195,6 +195,22 @@ class TestCompany(unittest.TestCase):
child_company.save()
self.test_basic_tree()
def test_demo_data(self):
from erpnext.setup.demo import clear_demo_data, setup_demo_data
setup_demo_data()
company_name = frappe.db.get_value("Company", {"name": ("like", "%(Demo)")})
self.assertTrue(company_name)
for transaction in frappe.get_hooks("demo_transaction_doctypes"):
self.assertTrue(frappe.db.exists(frappe.unscrub(transaction), {"company": company_name}))
clear_demo_data()
company_name = frappe.db.get_value("Company", {"name": ("like", "%(Demo)")})
self.assertFalse(company_name)
for transaction in frappe.get_hooks("demo_transaction_doctypes"):
self.assertFalse(frappe.db.exists(frappe.unscrub(transaction), {"company": company_name}))
def create_company_communication(doctype, docname):
comm = frappe.get_doc(

View File

@ -12,7 +12,8 @@
"default_currency",
"hide_currency_symbol",
"disable_rounded_total",
"disable_in_words"
"disable_in_words",
"demo_company"
],
"fields": [
{
@ -71,6 +72,14 @@
"fieldtype": "Check",
"in_list_view": 1,
"label": "Disable In Words"
},
{
"fieldname": "demo_company",
"fieldtype": "Link",
"hidden": 1,
"label": "Demo Company",
"options": "Company",
"read_only": 1
}
],
"icon": "fa fa-cog",

View File

@ -490,7 +490,7 @@ def update_stock_settings():
def create_bank_account(args):
if not args.get("bank_account"):
return
args["bank_account"] = _("Bank Account")
company_name = args.get("company_name")
bank_account_group = frappe.db.get_value(

View File

@ -5,7 +5,8 @@
import frappe
from frappe import _
from .operations import install_fixtures as fixtures
from erpnext.setup.demo import setup_demo_data
from erpnext.setup.setup_wizard.operations import install_fixtures as fixtures
def get_setup_stages(args=None):
@ -36,6 +37,11 @@ def get_setup_stages(args=None):
{"fn": setup_defaults, "args": args, "fail_msg": _("Failed to setup defaults")},
],
},
{
"status": _("Setting up demo data"),
"fail_msg": _("Failed to setup demo data"),
"tasks": [{"fn": setup_demo, "args": args, "fail_msg": _("Failed to setup demo data")}],
},
{
"status": _("Wrapping up"),
"fail_msg": _("Failed to login"),
@ -63,6 +69,11 @@ def fin(args):
login_as_first_user(args)
def setup_demo(args):
if args.get("setup_demo"):
frappe.enqueue(setup_demo_data, enqueue_after_commit=True, at_front=True)
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"))

View File

@ -61,6 +61,8 @@ def boot_session(bootinfo):
)
bootinfo.party_account_types = frappe._dict(party_account_types)
bootinfo.sysdefaults.demo_company = frappe.db.get_single_value("Global Defaults", "demo_company")
def update_page_info(bootinfo):
bootinfo.page_info.update(