blob: 355c373d33d728d896650fbb4bd297fd9053106a [file] [log] [blame]
Deepesh Garg8ef257a2023-06-14 12:54:10 +05301# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors
2# License: GNU General Public License v3. See license.txt
3
4import json
5import os
Deepesh Garg86744b62023-06-19 09:44:57 +05306from random import randint
Deepesh Garg8ef257a2023-06-14 12:54:10 +05307
8import frappe
Deepesh Garg371413a2023-07-29 22:39:07 +05309from frappe.utils import add_days, getdate
Deepesh Garg8ef257a2023-06-14 12:54:10 +053010
Deepesh Garg77a29572023-06-16 13:43:55 +053011import erpnext
Deepesh Garg371413a2023-07-29 22:39:07 +053012from erpnext.accounts.utils import get_fiscal_year
Deepesh Garg85e1c852023-06-19 14:12:23 +053013from erpnext.setup.setup_wizard.operations.install_fixtures import create_bank_account
Deepesh Garg77a29572023-06-16 13:43:55 +053014
Deepesh Garg8ef257a2023-06-14 12:54:10 +053015
Deepesh Garg8ef257a2023-06-14 12:54:10 +053016def setup_demo_data():
Ankush Menat3a21c902023-08-10 15:48:57 +053017 from frappe.utils.telemetry import capture
18
19 capture("demo_data_creation_started", "erpnext")
20 try:
21 company = create_demo_company()
22 process_masters()
23 make_transactions(company)
24 frappe.cache.delete_keys("bootinfo")
25 frappe.publish_realtime("demo_data_complete")
26 except Exception:
27 frappe.log_error("Failed to create demo data")
28 capture("demo_data_creation_failed", "erpnext", properties={"exception": frappe.get_traceback()})
29 raise
30 capture("demo_data_creation_completed", "erpnext")
Deepesh Garg77a29572023-06-16 13:43:55 +053031
32
33@frappe.whitelist()
34def clear_demo_data():
Ankush Menat3a21c902023-08-10 15:48:57 +053035 frappe.only_for("System Manager")
Deepesh Garg86744b62023-06-19 09:44:57 +053036 company = frappe.db.get_single_value("Global Defaults", "demo_company")
Deepesh Garg77a29572023-06-16 13:43:55 +053037 create_transaction_deletion_record(company)
Deepesh Garg5b6a9fc2023-06-17 13:08:18 +053038 clear_masters()
39 delete_company(company)
Deepesh Garg7805abbb2023-07-30 20:29:20 +053040 default_company = frappe.db.get_single_value("Global Defaults", "default_company")
41 frappe.db.set_default("company", default_company)
Deepesh Garg8ef257a2023-06-14 12:54:10 +053042
43
44def create_demo_company():
Deepesh Gargbb5387f2023-07-07 10:49:56 +053045 company = frappe.db.get_all("Company")[0].name
Deepesh Garg8ef257a2023-06-14 12:54:10 +053046 company_doc = frappe.get_doc("Company", company)
47
48 # Make a dummy company
49 new_company = frappe.new_doc("Company")
50 new_company.company_name = company_doc.company_name + " (Demo)"
51 new_company.abbr = company_doc.abbr + "D"
52 new_company.enable_perpetual_inventory = 1
53 new_company.default_currency = company_doc.default_currency
54 new_company.country = company_doc.country
55 new_company.chart_of_accounts_based_on = "Standard Template"
56 new_company.chart_of_accounts = company_doc.chart_of_accounts
57 new_company.insert()
58
Deepesh Garg5b6a9fc2023-06-17 13:08:18 +053059 # Set Demo Company as default to
Deepesh Garg86744b62023-06-19 09:44:57 +053060 frappe.db.set_single_value("Global Defaults", "demo_company", new_company.name)
61 frappe.db.set_default("company", new_company.name)
62
Deepesh Garg85e1c852023-06-19 14:12:23 +053063 bank_account = create_bank_account({"company_name": new_company.name})
64 frappe.db.set_value("Company", new_company.name, "default_bank_account", bank_account.name)
65
Deepesh Garg77a29572023-06-16 13:43:55 +053066 return new_company.name
Deepesh Garg8ef257a2023-06-14 12:54:10 +053067
Deepesh Garg77a29572023-06-16 13:43:55 +053068
69def process_masters():
Deepesh Garg5b6a9fc2023-06-17 13:08:18 +053070 for doctype in frappe.get_hooks("demo_master_doctypes"):
71 data = read_data_file_using_hooks(doctype)
72 if data:
73 for item in json.loads(data):
74 create_demo_record(item)
Deepesh Garg8ef257a2023-06-14 12:54:10 +053075
76
77def create_demo_record(doctype):
78 frappe.get_doc(doctype).insert(ignore_permissions=True)
79
80
Deepesh Garg77a29572023-06-16 13:43:55 +053081def make_transactions(company):
Deepesh Garg371413a2023-07-29 22:39:07 +053082 start_date = get_fiscal_year(date=getdate())[1]
Deepesh Garg85e1c852023-06-19 14:12:23 +053083 frappe.db.set_single_value("Stock Settings", "allow_negative_stock", 1)
Deepesh Garg86744b62023-06-19 09:44:57 +053084
Deepesh Garg5b6a9fc2023-06-17 13:08:18 +053085 for doctype in frappe.get_hooks("demo_transaction_doctypes"):
86 data = read_data_file_using_hooks(doctype)
87 if data:
88 for item in json.loads(data):
Deepesh Garg86744b62023-06-19 09:44:57 +053089 create_transaction(item, company, start_date)
Deepesh Garg77a29572023-06-16 13:43:55 +053090
91
Deepesh Garg86744b62023-06-19 09:44:57 +053092def create_transaction(doctype, company, start_date):
Deepesh Garg85e1c852023-06-19 14:12:23 +053093 warehouse = get_warehouse(company)
94 posting_date = (
95 start_date if doctype.get("doctype") == "Purchase Invoice" else get_random_date(start_date)
96 )
Deepesh Garg333f2a52023-08-01 10:10:50 +053097 bank_account, default_receivable_account = frappe.db.get_value(
98 "Company", company, ["default_bank_account", "default_receivable_account"]
99 )
Deepesh Garg85e1c852023-06-19 14:12:23 +0530100 bank_field = "paid_to" if doctype.get("party_type") == "Customer" else "paid_from"
101
Deepesh Garg86744b62023-06-19 09:44:57 +0530102 doctype.update(
103 {
104 "company": company,
105 "set_posting_time": 1,
Deepesh Garg85e1c852023-06-19 14:12:23 +0530106 "posting_date": posting_date,
107 "set_warehouse": warehouse,
108 bank_field: bank_account,
109 "reference_date": posting_date,
Deepesh Garg86744b62023-06-19 09:44:57 +0530110 }
111 )
Deepesh Garg77a29572023-06-16 13:43:55 +0530112
113 income_account, expense_account = frappe.db.get_value(
114 "Company", company, ["default_income_account", "default_expense_account"]
115 )
116
Deepesh Garg333f2a52023-08-01 10:10:50 +0530117 if doctype in ("Purchase Invoice", "Sales Invoice"):
118 for item in doctype.get("items") or []:
119 item.update(
120 {
121 "cost_center": erpnext.get_default_cost_center(company),
122 "income_account": income_account,
123 "expense_account": expense_account,
124 }
125 )
126 elif doctype == "Journal Entry":
127 pass
128 # update_accounts(doctype, bank_account, default_receivable_account)
Deepesh Garg77a29572023-06-16 13:43:55 +0530129
130 doc = frappe.get_doc(doctype)
131 doc.save(ignore_permissions=True)
132 doc.submit()
133
134
Deepesh Garg333f2a52023-08-01 10:10:50 +0530135# def update_accounts(doctype, company, bank_account):
136
137
Deepesh Garg86744b62023-06-19 09:44:57 +0530138def get_random_date(start_date):
139 return add_days(start_date, randint(1, 365))
140
141
Deepesh Garg77a29572023-06-16 13:43:55 +0530142def create_transaction_deletion_record(company):
143 transaction_deletion_record = frappe.new_doc("Transaction Deletion Record")
144 transaction_deletion_record.company = company
145 transaction_deletion_record.save(ignore_permissions=True)
146 transaction_deletion_record.submit()
Deepesh Garg5b6a9fc2023-06-17 13:08:18 +0530147
148
149def clear_masters():
150 for doctype in frappe.get_hooks("demo_master_doctypes")[::-1]:
151 data = read_data_file_using_hooks(doctype)
152 if data:
153 for item in json.loads(data):
154 clear_demo_record(item)
155
156
157def clear_demo_record(doctype):
158 doc_type = doctype.get("doctype")
159 del doctype["doctype"]
160 doc = frappe.get_doc(doc_type, doctype)
161 frappe.delete_doc(doc.doctype, doc.name, ignore_permissions=True)
162
163
164def delete_company(company):
Deepesh Garg85e1c852023-06-19 14:12:23 +0530165 frappe.db.set_single_value("Global Defaults", "demo_company", "")
Deepesh Garg5b6a9fc2023-06-17 13:08:18 +0530166 frappe.delete_doc("Company", company, ignore_permissions=True)
167
168
169def read_data_file_using_hooks(doctype):
170 path = os.path.join(os.path.dirname(__file__), "demo_data")
171 with open(os.path.join(path, doctype + ".json"), "r") as f:
172 data = f.read()
173
174 return data
Deepesh Garg85e1c852023-06-19 14:12:23 +0530175
176
177def get_warehouse(company):
178 abbr = frappe.db.get_value("Company", company, "abbr")
179 warehouse = "Stores - {0}".format(abbr)
180
181 return warehouse