blob: 09e6470f28fd67db266f35378fa2b73f05e03f66 [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
Ankush Menate4b863a2023-08-10 17:49:28 +05309from frappe import _
Deepesh Garg371413a2023-07-29 22:39:07 +053010from frappe.utils import add_days, getdate
Deepesh Garg8ef257a2023-06-14 12:54:10 +053011
Deepesh Garg77a29572023-06-16 13:43:55 +053012import erpnext
Deepesh Garg371413a2023-07-29 22:39:07 +053013from erpnext.accounts.utils import get_fiscal_year
Deepesh Garg85e1c852023-06-19 14:12:23 +053014from erpnext.setup.setup_wizard.operations.install_fixtures import create_bank_account
Deepesh Garg77a29572023-06-16 13:43:55 +053015
Deepesh Garg8ef257a2023-06-14 12:54:10 +053016
Deepesh Garg8ef257a2023-06-14 12:54:10 +053017def setup_demo_data():
Ankush Menat3a21c902023-08-10 15:48:57 +053018 from frappe.utils.telemetry import capture
19
20 capture("demo_data_creation_started", "erpnext")
21 try:
22 company = create_demo_company()
23 process_masters()
24 make_transactions(company)
25 frappe.cache.delete_keys("bootinfo")
26 frappe.publish_realtime("demo_data_complete")
27 except Exception:
28 frappe.log_error("Failed to create demo data")
29 capture("demo_data_creation_failed", "erpnext", properties={"exception": frappe.get_traceback()})
30 raise
31 capture("demo_data_creation_completed", "erpnext")
Deepesh Garg77a29572023-06-16 13:43:55 +053032
33
34@frappe.whitelist()
35def clear_demo_data():
Ankush Menatc8e6e062023-08-10 18:27:34 +053036 from frappe.utils.telemetry import capture
37
Ankush Menat3a21c902023-08-10 15:48:57 +053038 frappe.only_for("System Manager")
Ankush Menatc8e6e062023-08-10 18:27:34 +053039
40 capture("demo_data_erased", "erpnext")
Ankush Menate4b863a2023-08-10 17:49:28 +053041 try:
42 company = frappe.db.get_single_value("Global Defaults", "demo_company")
43 create_transaction_deletion_record(company)
44 clear_masters()
45 delete_company(company)
46 default_company = frappe.db.get_single_value("Global Defaults", "default_company")
47 frappe.db.set_default("company", default_company)
48 except Exception:
49 frappe.db.rollback()
50 frappe.log_error("Failed to erase demo data")
51 frappe.throw(
52 _("Failed to erase demo data, please delete the demo company manually."),
53 title=_("Could Not Delete Demo Data"),
54 )
Deepesh Garg8ef257a2023-06-14 12:54:10 +053055
56
57def create_demo_company():
Deepesh Gargbb5387f2023-07-07 10:49:56 +053058 company = frappe.db.get_all("Company")[0].name
Deepesh Garg8ef257a2023-06-14 12:54:10 +053059 company_doc = frappe.get_doc("Company", company)
60
61 # Make a dummy company
62 new_company = frappe.new_doc("Company")
63 new_company.company_name = company_doc.company_name + " (Demo)"
64 new_company.abbr = company_doc.abbr + "D"
65 new_company.enable_perpetual_inventory = 1
66 new_company.default_currency = company_doc.default_currency
67 new_company.country = company_doc.country
68 new_company.chart_of_accounts_based_on = "Standard Template"
69 new_company.chart_of_accounts = company_doc.chart_of_accounts
70 new_company.insert()
71
Deepesh Garg5b6a9fc2023-06-17 13:08:18 +053072 # Set Demo Company as default to
Deepesh Garg86744b62023-06-19 09:44:57 +053073 frappe.db.set_single_value("Global Defaults", "demo_company", new_company.name)
74 frappe.db.set_default("company", new_company.name)
75
Deepesh Garg85e1c852023-06-19 14:12:23 +053076 bank_account = create_bank_account({"company_name": new_company.name})
77 frappe.db.set_value("Company", new_company.name, "default_bank_account", bank_account.name)
78
Deepesh Garg77a29572023-06-16 13:43:55 +053079 return new_company.name
Deepesh Garg8ef257a2023-06-14 12:54:10 +053080
Deepesh Garg77a29572023-06-16 13:43:55 +053081
82def process_masters():
Deepesh Garg5b6a9fc2023-06-17 13:08:18 +053083 for doctype in frappe.get_hooks("demo_master_doctypes"):
84 data = read_data_file_using_hooks(doctype)
85 if data:
86 for item in json.loads(data):
87 create_demo_record(item)
Deepesh Garg8ef257a2023-06-14 12:54:10 +053088
89
90def create_demo_record(doctype):
91 frappe.get_doc(doctype).insert(ignore_permissions=True)
92
93
Deepesh Garg77a29572023-06-16 13:43:55 +053094def make_transactions(company):
Deepesh Garg371413a2023-07-29 22:39:07 +053095 start_date = get_fiscal_year(date=getdate())[1]
Deepesh Garg85e1c852023-06-19 14:12:23 +053096 frappe.db.set_single_value("Stock Settings", "allow_negative_stock", 1)
Deepesh Garg86744b62023-06-19 09:44:57 +053097
Deepesh Garg5b6a9fc2023-06-17 13:08:18 +053098 for doctype in frappe.get_hooks("demo_transaction_doctypes"):
99 data = read_data_file_using_hooks(doctype)
100 if data:
101 for item in json.loads(data):
Deepesh Garg86744b62023-06-19 09:44:57 +0530102 create_transaction(item, company, start_date)
Deepesh Garg77a29572023-06-16 13:43:55 +0530103
104
Deepesh Garg86744b62023-06-19 09:44:57 +0530105def create_transaction(doctype, company, start_date):
Deepesh Garg85e1c852023-06-19 14:12:23 +0530106 warehouse = get_warehouse(company)
107 posting_date = (
108 start_date if doctype.get("doctype") == "Purchase Invoice" else get_random_date(start_date)
109 )
Deepesh Garg333f2a52023-08-01 10:10:50 +0530110 bank_account, default_receivable_account = frappe.db.get_value(
111 "Company", company, ["default_bank_account", "default_receivable_account"]
112 )
Deepesh Garg85e1c852023-06-19 14:12:23 +0530113 bank_field = "paid_to" if doctype.get("party_type") == "Customer" else "paid_from"
114
Deepesh Garg86744b62023-06-19 09:44:57 +0530115 doctype.update(
116 {
117 "company": company,
118 "set_posting_time": 1,
Deepesh Garg85e1c852023-06-19 14:12:23 +0530119 "posting_date": posting_date,
120 "set_warehouse": warehouse,
121 bank_field: bank_account,
122 "reference_date": posting_date,
Deepesh Garg86744b62023-06-19 09:44:57 +0530123 }
124 )
Deepesh Garg77a29572023-06-16 13:43:55 +0530125
126 income_account, expense_account = frappe.db.get_value(
127 "Company", company, ["default_income_account", "default_expense_account"]
128 )
129
Deepesh Garg333f2a52023-08-01 10:10:50 +0530130 if doctype in ("Purchase Invoice", "Sales Invoice"):
131 for item in doctype.get("items") or []:
132 item.update(
133 {
134 "cost_center": erpnext.get_default_cost_center(company),
135 "income_account": income_account,
136 "expense_account": expense_account,
137 }
138 )
139 elif doctype == "Journal Entry":
140 pass
141 # update_accounts(doctype, bank_account, default_receivable_account)
Deepesh Garg77a29572023-06-16 13:43:55 +0530142
143 doc = frappe.get_doc(doctype)
144 doc.save(ignore_permissions=True)
145 doc.submit()
146
147
Deepesh Garg333f2a52023-08-01 10:10:50 +0530148# def update_accounts(doctype, company, bank_account):
149
150
Deepesh Garg86744b62023-06-19 09:44:57 +0530151def get_random_date(start_date):
152 return add_days(start_date, randint(1, 365))
153
154
Deepesh Garg77a29572023-06-16 13:43:55 +0530155def create_transaction_deletion_record(company):
156 transaction_deletion_record = frappe.new_doc("Transaction Deletion Record")
157 transaction_deletion_record.company = company
158 transaction_deletion_record.save(ignore_permissions=True)
159 transaction_deletion_record.submit()
Deepesh Garg5b6a9fc2023-06-17 13:08:18 +0530160
161
162def clear_masters():
163 for doctype in frappe.get_hooks("demo_master_doctypes")[::-1]:
164 data = read_data_file_using_hooks(doctype)
165 if data:
166 for item in json.loads(data):
167 clear_demo_record(item)
168
169
Ankush Menate4b863a2023-08-10 17:49:28 +0530170def clear_demo_record(document):
171 doc_type = document.get("doctype")
172 del document["doctype"]
173 doc = frappe.get_doc(doc_type, document)
Deepesh Garg5b6a9fc2023-06-17 13:08:18 +0530174 frappe.delete_doc(doc.doctype, doc.name, ignore_permissions=True)
175
176
177def delete_company(company):
Deepesh Garg85e1c852023-06-19 14:12:23 +0530178 frappe.db.set_single_value("Global Defaults", "demo_company", "")
Deepesh Garg5b6a9fc2023-06-17 13:08:18 +0530179 frappe.delete_doc("Company", company, ignore_permissions=True)
180
181
182def read_data_file_using_hooks(doctype):
183 path = os.path.join(os.path.dirname(__file__), "demo_data")
184 with open(os.path.join(path, doctype + ".json"), "r") as f:
185 data = f.read()
186
187 return data
Deepesh Garg85e1c852023-06-19 14:12:23 +0530188
189
190def get_warehouse(company):
191 abbr = frappe.db.get_value("Company", company, "abbr")
192 warehouse = "Stores - {0}".format(abbr)
193
194 return warehouse