[demo] new cleaner, more-flexible demo
diff --git a/erpnext/demo/__init__.py b/erpnext/demo/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/demo/__init__.py
diff --git a/erpnext/demo/data/account.json b/erpnext/demo/data/account.json
new file mode 100644
index 0000000..b50b0c9
--- /dev/null
+++ b/erpnext/demo/data/account.json
@@ -0,0 +1,18 @@
+[{
+ "account_name": "Debtors EUR",
+ "parent_account": "Accounts Receivable",
+ "account_type": "Receivable",
+ "account_currency": "EUR"
+},
+{
+ "account_name": "Creditors EUR",
+ "parent_account": "Accounts Payable",
+ "account_type": "Payable",
+ "account_currency": "EUR"
+},
+{
+ "account_name": "Paypal",
+ "parent_account": "Bank Accounts",
+ "account_type": "Bank",
+ "account_currency": "EUR"
+}]
\ No newline at end of file
diff --git a/erpnext/demo/data/address.json b/erpnext/demo/data/address.json
new file mode 100644
index 0000000..be4d5ec
--- /dev/null
+++ b/erpnext/demo/data/address.json
@@ -0,0 +1,245 @@
+[
+ {
+ "address_line1": "254 Theotokopoulou Str.",
+ "address_type": "Office",
+ "city": "Larnaka",
+ "country": "Cyprus",
+ "customer": "Adaptas",
+ "phone": "23566775757",
+ "supplier": null
+ },
+ {
+ "address_line1": "R Patr\u00e3o Caramelho 116",
+ "address_type": "Office",
+ "city": "Fajozes",
+ "country": "Portugal",
+ "customer": "Asian Fusion",
+ "phone": "23566775757",
+ "supplier": null
+ },
+ {
+ "address_line1": "30 Fulford Road",
+ "address_type": "Office",
+ "city": "PENTRE-PIOD",
+ "country": "United Kingdom",
+ "customer": "Asian Junction",
+ "phone": "23566775757",
+ "supplier": null
+ },
+ {
+ "address_line1": "Schoenebergerstrasse 13",
+ "address_type": "Office",
+ "city": "Raschau",
+ "country": "Germany",
+ "customer": "Big D Supermarkets",
+ "phone": "23566775757",
+ "supplier": null
+ },
+ {
+ "address_line1": "Hoheluftchaussee 43",
+ "address_type": "Office",
+ "city": "Kieritzsch",
+ "country": "Germany",
+ "customer": "Buttrey Food & Drug",
+ "phone": "23566775757",
+ "supplier": null
+ },
+ {
+ "address_line1": "R Cimo Vila 6",
+ "address_type": "Office",
+ "city": "Rebordosa",
+ "country": "Portugal",
+ "customer": "Chi-Chis",
+ "phone": "23566775757",
+ "supplier": null
+ },
+ {
+ "address_line1": "R 5 Outubro 9",
+ "address_type": "Office",
+ "city": "Quinta Nova S\u00e3o Domingos",
+ "country": "Portugal",
+ "customer": "Choices",
+ "phone": "23566775757",
+ "supplier": null
+ },
+ {
+ "address_line1": "Avenida Macambira 953",
+ "address_type": "Office",
+ "city": "Goi\u00e2nia",
+ "country": "Brazil",
+ "customer": "Consumers and Consumers Express",
+ "phone": "23566775757",
+ "supplier": null
+ },
+ {
+ "address_line1": "2342 Goyeau Ave",
+ "address_type": "Office",
+ "city": "Windsor",
+ "country": "Canada",
+ "customer": "Crafts Canada",
+ "phone": "23566775757",
+ "supplier": null
+ },
+ {
+ "address_line1": "Laukaantie 82",
+ "address_type": "Office",
+ "city": "KOKKOLA",
+ "country": "Finland",
+ "customer": "Endicott Shoes",
+ "phone": "23566775757",
+ "supplier": null
+ },
+ {
+ "address_line1": "9 Brown Street",
+ "address_type": "Office",
+ "city": "PETERSHAM",
+ "country": "Australia",
+ "customer": "Fayva",
+ "phone": "23566775757",
+ "supplier": null
+ },
+ {
+ "address_line1": "Via Donnalbina 41",
+ "address_type": "Office",
+ "city": "Cala Gonone",
+ "country": "Italy",
+ "customer": "Intelacard",
+ "phone": "23566775757",
+ "supplier": null
+ },
+ {
+ "address_line1": "Liljerum Grenadj\u00e4rtorpet 69",
+ "address_type": "Office",
+ "city": "TOMTEBODA",
+ "country": "Sweden",
+ "customer": "Landskip Yard Care",
+ "phone": "23566775757",
+ "supplier": null
+ },
+ {
+ "address_line1": "72 Bishopgate Street",
+ "address_type": "Office",
+ "city": "SEAHAM",
+ "country": "United Kingdom",
+ "customer": "Life Plan Counselling",
+ "phone": "23566775757",
+ "supplier": null
+ },
+ {
+ "address_line1": "\u03a3\u03ba\u03b1\u03c6\u03af\u03b4\u03b9\u03b1 105",
+ "address_type": "Office",
+ "city": "\u03a0\u0391\u03a1\u0395\u039a\u039a\u039b\u0397\u03a3\u0399\u0391",
+ "country": "Cyprus",
+ "customer": "Mr Fables",
+ "phone": "23566775757",
+ "supplier": null
+ },
+ {
+ "address_line1": "Mellemvej 7",
+ "address_type": "Office",
+ "city": "Aabybro",
+ "country": "Denmark",
+ "customer": "Nelson Brothers",
+ "phone": "23566775757",
+ "supplier": null
+ },
+ {
+ "address_line1": "Plougg\u00e5rdsvej 98",
+ "address_type": "Office",
+ "city": "Karby",
+ "country": "Denmark",
+ "customer": "Netobill",
+ "phone": "23566775757",
+ "supplier": null
+ },
+ {
+ "address_line1": "176 Michalakopoulou Street",
+ "address_type": "Office",
+ "city": "Agio Georgoudi",
+ "country": "Cyprus",
+ "customer": null,
+ "phone": "23566775757",
+ "supplier": "Helios Air"
+ },
+ {
+ "address_line1": "Fibichova 1102",
+ "address_type": "Office",
+ "city": "Kokor\u00edn",
+ "country": "Czech Republic",
+ "customer": null,
+ "phone": "23566775757",
+ "supplier": "Ks Merchandise"
+ },
+ {
+ "address_line1": "Zahradn\u00ed 888",
+ "address_type": "Office",
+ "city": "Cecht\u00edn",
+ "country": "Czech Republic",
+ "customer": null,
+ "phone": "23566775757",
+ "supplier": "HomeBase"
+ },
+ {
+ "address_line1": "ul. Grochowska 94",
+ "address_type": "Office",
+ "city": "Warszawa",
+ "country": "Poland",
+ "customer": null,
+ "phone": "23566775757",
+ "supplier": "Scott Ties"
+ },
+ {
+ "address_line1": "Norra Esplanaden 87",
+ "address_type": "Office",
+ "city": "HELSINKI",
+ "country": "Finland",
+ "customer": null,
+ "phone": "23566775757",
+ "supplier": "Reliable Investments"
+ },
+ {
+ "address_line1": "2038 Fallon Drive",
+ "address_type": "Office",
+ "city": "Dresden",
+ "country": "Canada",
+ "customer": null,
+ "phone": "23566775757",
+ "supplier": "Nan Duskin"
+ },
+ {
+ "address_line1": "77 cours Franklin Roosevelt",
+ "address_type": "Office",
+ "city": "MARSEILLE",
+ "country": "France",
+ "customer": null,
+ "phone": "23566775757",
+ "supplier": "Rainbow Records"
+ },
+ {
+ "address_line1": "ul. Tuwima Juliana 85",
+ "address_type": "Office",
+ "city": "\u0141\u00f3d\u017a",
+ "country": "Poland",
+ "customer": null,
+ "phone": "23566775757",
+ "supplier": "New World Realty"
+ },
+ {
+ "address_line1": "Gl. Sygehusvej 41",
+ "address_type": "Office",
+ "city": "Narsaq",
+ "country": "Greenland",
+ "customer": null,
+ "phone": "23566775757",
+ "supplier": "Asiatic Solutions"
+ },
+ {
+ "address_line1": "Gosposka ulica 50",
+ "address_type": "Office",
+ "city": "Nova Gorica",
+ "country": "Slovenia",
+ "customer": null,
+ "phone": "23566775757",
+ "supplier": "Eagle Hardware"
+ }
+]
\ No newline at end of file
diff --git a/erpnext/demo/data/bom.json b/erpnext/demo/data/bom.json
new file mode 100644
index 0000000..145c0ba
--- /dev/null
+++ b/erpnext/demo/data/bom.json
@@ -0,0 +1,147 @@
+[
+ {
+ "item": "Bearing Assembly",
+ "items": [
+ {
+ "item_code": "Base Bearing Plate",
+ "qty": 1.0,
+ "rate": 15.0
+ },
+ {
+ "item_code": "Bearing Block",
+ "qty": 1.0,
+ "rate": 10.0
+ },
+ {
+ "item_code": "Bearing Collar",
+ "qty": 2.0,
+ "rate": 20.0
+ },
+ {
+ "item_code": "Bearing Pipe",
+ "qty": 1.0,
+ "rate": 15.0
+ },
+ {
+ "item_code": "Upper Bearing Plate",
+ "qty": 1.0,
+ "rate": 50.0
+ }
+ ]
+ },
+ {
+ "item": "Wind Mill A Series",
+ "items": [
+ {
+ "item_code": "Base Bearing Plate",
+ "qty": 1.0,
+ "rate": 15.0
+ },
+ {
+ "item_code": "Base Plate",
+ "qty": 1.0,
+ "rate": 20.0
+ },
+ {
+ "item_code": "Bearing Block",
+ "qty": 1.0,
+ "rate": 10.0
+ },
+ {
+ "item_code": "Bearing Pipe",
+ "qty": 1.0,
+ "rate": 15.0
+ },
+ {
+ "item_code": "External Disc",
+ "qty": 1.0,
+ "rate": 45.0
+ },
+ {
+ "item_code": "Shaft",
+ "qty": 1.0,
+ "rate": 30.0
+ },
+ {
+ "item_code": "Wing Sheet",
+ "qty": 4.0,
+ "rate": 22.0
+ }
+ ]
+ },
+ {
+ "item": "Wind MIll C Series",
+ "items": [
+ {
+ "item_code": "Base Plate",
+ "qty": 2.0,
+ "rate": 20.0
+ },
+ {
+ "item_code": "Internal Disc",
+ "qty": 1.0,
+ "rate": 33.0
+ },
+ {
+ "item_code": "External Disc",
+ "qty": 1.0,
+ "rate": 45.0
+ },
+ {
+ "item_code": "Bearing Assembly",
+ "qty": 1.0,
+ "rate": 130.0
+ },
+ {
+ "item_code": "Wing Sheet",
+ "qty": 3.0,
+ "rate": 22.0
+ }
+ ]
+ },
+ {
+ "item": "Wind Turbine",
+ "items": [
+ {
+ "item_code": "Base Bearing Plate",
+ "qty": 1.0,
+ "rate": 15.0
+ },
+ {
+ "item_code": "Base Plate",
+ "qty": 1.0,
+ "rate": 20.0
+ },
+ {
+ "item_code": "Bearing Collar",
+ "qty": 1.0,
+ "rate": 20.0
+ },
+ {
+ "item_code": "Blade Rib",
+ "qty": 1.0,
+ "rate": 10.0
+ },
+ {
+ "item_code": "Shaft",
+ "qty": 1.0,
+ "rate": 30.0
+ },
+ {
+ "item_code": "Wing Sheet",
+ "qty": 2.0,
+ "rate": 22.0
+ }
+ ]
+ },
+ {
+ "item": "Base Plate",
+ "items": [
+ {
+ "item_code": "Base Plate Un Painted",
+ "qty": 1.0,
+ "rate": 16.0
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/erpnext/demo/data/contact.json b/erpnext/demo/data/contact.json
new file mode 100644
index 0000000..130845b
--- /dev/null
+++ b/erpnext/demo/data/contact.json
@@ -0,0 +1,191 @@
+[
+ {
+ "customer": "Adaptas",
+ "email_id": "JanVaclavik@example.com",
+ "first_name": "January",
+ "last_name": "V\u00e1clav\u00edk",
+ "supplier": null
+ },
+ {
+ "customer": "Asian Fusion",
+ "email_id": "ChidumagaTobeolisa@example.com",
+ "first_name": "Chidumaga",
+ "last_name": "Tobeolisa",
+ "supplier": null
+ },
+ {
+ "customer": "Asian Junction",
+ "email_id": "JanaKubanova@example.com",
+ "first_name": "Jana",
+ "last_name": "Kub\u00e1\u0148ov\u00e1",
+ "supplier": null
+ },
+ {
+ "customer": "Big D Supermarkets",
+ "email_id": "XuChaoXuan@example.com",
+ "first_name": "\u7d39\u8431",
+ "last_name": "\u4e8e",
+ "supplier": null
+ },
+ {
+ "customer": "Buttrey Food & Drug",
+ "email_id": "OzlemVerwijmeren@example.com",
+ "first_name": "\u00d6zlem",
+ "last_name": "Verwijmeren",
+ "supplier": null
+ },
+ {
+ "customer": "Chi-Chis",
+ "email_id": "HansRasmussen@example.com",
+ "first_name": "Hans",
+ "last_name": "Rasmussen",
+ "supplier": null
+ },
+ {
+ "customer": "Choices",
+ "email_id": "SatomiShigeki@example.com",
+ "first_name": "Satomi",
+ "last_name": "Shigeki",
+ "supplier": null
+ },
+ {
+ "customer": "Consumers and Consumers Express",
+ "email_id": "SimonVJessen@example.com",
+ "first_name": "Simon",
+ "last_name": "Jessen",
+ "supplier": null
+ },
+ {
+ "customer": "Crafts Canada",
+ "email_id": "NeguaranShahsaah@example.com",
+ "first_name": "\u0646\u06af\u0627\u0631\u06cc\u0646",
+ "last_name": "\u0634\u0627\u0647 \u0633\u06cc\u0627\u0647",
+ "supplier": null
+ },
+ {
+ "customer": "Endicott Shoes",
+ "email_id": "Lom-AliBataev@example.com",
+ "first_name": "Lom-Ali",
+ "last_name": "Bataev",
+ "supplier": null
+ },
+ {
+ "customer": "Fayva",
+ "email_id": "VanNgocTien@example.com",
+ "first_name": "Ti\u00ean",
+ "last_name": "V\u0103n",
+ "supplier": null
+ },
+ {
+ "customer": "Intelacard",
+ "email_id": "QuimeyOsorioRuelas@example.com",
+ "first_name": "Quimey",
+ "last_name": "Osorio",
+ "supplier": null
+ },
+ {
+ "customer": "Landskip Yard Care",
+ "email_id": "EdgardaSalcedoRaya@example.com",
+ "first_name": "Edgarda",
+ "last_name": "Salcedo",
+ "supplier": null
+ },
+ {
+ "customer": "Life Plan Counselling",
+ "email_id": "HafsteinnBjarnarsonar@example.com",
+ "first_name": "Hafsteinn",
+ "last_name": "Bjarnarsonar",
+ "supplier": null
+ },
+ {
+ "customer": "Mr Fables",
+ "email_id": "\u0434\u0430\u043d\u0438\u0438\u043b@example.com",
+ "first_name": "\u0414\u0430\u043d\u0438\u0438\u043b",
+ "last_name": "\u041a\u043e\u043d\u043e\u0432\u0430\u043b\u043e\u0432",
+ "supplier": null
+ },
+ {
+ "customer": "Nelson Brothers",
+ "email_id": "SelmaMAndersen@example.com",
+ "first_name": "Selma",
+ "last_name": "Andersen",
+ "supplier": null
+ },
+ {
+ "customer": "Netobill",
+ "email_id": "LadislavKolaja@example.com",
+ "first_name": "Ladislav",
+ "last_name": "Kolaja",
+ "supplier": null
+ },
+ {
+ "customer": null,
+ "email_id": "TewoldeAbaalom@example.com",
+ "first_name": "Tewolde",
+ "last_name": "Abaalom",
+ "supplier": "Helios Air"
+ },
+ {
+ "customer": null,
+ "email_id": "LeilaFernandesRodrigues@example.com",
+ "first_name": "Leila",
+ "last_name": "Rodrigues",
+ "supplier": "Ks Merchandise"
+ },
+ {
+ "customer": null,
+ "email_id": "DmitryBulgakov@example.com",
+ "first_name": "Dmitry",
+ "last_name": "Bulgakov",
+ "supplier": "HomeBase"
+ },
+ {
+ "customer": null,
+ "email_id": "HaiducWhitfoot@example.com",
+ "first_name": "Haiduc",
+ "last_name": "Whitfoot",
+ "supplier": "Scott Ties"
+ },
+ {
+ "customer": null,
+ "email_id": "SesseljaPetursdottir@example.com",
+ "first_name": "Sesselja",
+ "last_name": "P\u00e9tursd\u00f3ttir",
+ "supplier": "Reliable Investments"
+ },
+ {
+ "customer": null,
+ "email_id": "HajdarPignar@example.com",
+ "first_name": "Hajdar",
+ "last_name": "Pignar",
+ "supplier": "Nan Duskin"
+ },
+ {
+ "customer": null,
+ "email_id": "GustavaLorenzo@example.com",
+ "first_name": "Gustava",
+ "last_name": "Lorenzo",
+ "supplier": "Rainbow Records"
+ },
+ {
+ "customer": null,
+ "email_id": "BethanyWood@example.com",
+ "first_name": "Bethany",
+ "last_name": "Wood",
+ "supplier": "New World Realty"
+ },
+ {
+ "customer": null,
+ "email_id": "GlorianaBrownlock@example.com",
+ "first_name": "Gloriana",
+ "last_name": "Brownlock",
+ "supplier": "Asiatic Solutions"
+ },
+ {
+ "customer": null,
+ "email_id": "JensonFraser@gustr.com",
+ "first_name": "Jenson",
+ "last_name": "Fraser",
+ "supplier": "Eagle Hardware"
+ }
+]
\ No newline at end of file
diff --git a/erpnext/demo/data/employee.json b/erpnext/demo/data/employee.json
new file mode 100644
index 0000000..d9f4d2a
--- /dev/null
+++ b/erpnext/demo/data/employee.json
@@ -0,0 +1,72 @@
+[
+ {
+ "date_of_birth": "1982-01-03",
+ "date_of_joining": "2001-10-10",
+ "employee_name": "Dikman Shervashidze Shervashidze",
+ "gender": "Female",
+ "user_id": "DikmanShervashidze@example.com"
+ },
+ {
+ "date_of_birth": "1959-02-03",
+ "date_of_joining": "1976-09-16",
+ "employee_name": "Zukutakitoteka",
+ "gender": "Female",
+ "user_id": "Zukutakitoteka@example.com"
+ },
+ {
+ "date_of_birth": "1982-03-03",
+ "date_of_joining": "2000-06-16",
+ "employee_name": "Hatsue Kashiwagi",
+ "gender": "Female",
+ "user_id": "HatsueKashiwagi@example.com"
+ },
+ {
+ "date_of_birth": "1945-04-04",
+ "date_of_joining": "1969-07-01",
+ "employee_name": "Nuran Verkleij",
+ "gender": "Female",
+ "user_id": "NuranVerkleij@example.com"
+ },
+ {
+ "date_of_birth": "1978-05-03",
+ "date_of_joining": "1999-12-24",
+ "employee_name": "\u0414\u043c\u0438\u0442\u0440\u0438\u0439 \u041f\u0438\u0440\u043e\u0433\u043e\u0432",
+ "gender": "Male",
+ "user_id": "aromn@example.com"
+ },
+ {
+ "date_of_birth": "1964-06-03",
+ "date_of_joining": "1981-08-05",
+ "employee_name": "Tilde Lindqvist",
+ "gender": "Female",
+ "user_id": "TildeLindqvist@example.com"
+ },
+ {
+ "date_of_birth": "1982-07-03",
+ "date_of_joining": "2006-06-10",
+ "employee_name": "Micha\u0142 Sobczak",
+ "gender": "Male",
+ "user_id": "MichalSobczak@example.com"
+ },
+ {
+ "date_of_birth": "1969-08-03",
+ "date_of_joining": "1993-10-21",
+ "employee_name": "Gabrielle Loftus",
+ "gender": "Female",
+ "user_id": "GabrielleLoftus@example.com"
+ },
+ {
+ "date_of_birth": "1982-09-03",
+ "date_of_joining": "2005-09-06",
+ "employee_name": "Vakhita Ryzaev",
+ "gender": "Male",
+ "user_id": "VakhitaRyzaev@example.com"
+ },
+ {
+ "date_of_birth": "1985-10-03",
+ "date_of_joining": "2007-12-25",
+ "employee_name": "Charmaine Gaudreau",
+ "gender": "Female",
+ "user_id": "CharmaineGaudreau@example.com"
+ }
+]
\ No newline at end of file
diff --git a/erpnext/demo/data/item.json b/erpnext/demo/data/item.json
new file mode 100644
index 0000000..30436d1
--- /dev/null
+++ b/erpnext/demo/data/item.json
@@ -0,0 +1,224 @@
+[
+ {
+ "default_supplier": "Asiatic Solutions",
+ "default_warehouse": "Stores",
+ "description": "For Upper Bearing",
+ "image": "/assets/erpnext_demo/images/disc.png",
+ "item_code": "Disc Collars",
+ "item_group": "Raw Material",
+ "item_name": "Disc Collars"
+ },
+ {
+ "default_supplier": "Nan Duskin",
+ "default_warehouse": "Stores",
+ "description": "CAST IRON, MCMASTER PART NO. 3710T13",
+ "image": "/assets/erpnext_demo/images/bearing.jpg",
+ "item_code": "Bearing Block",
+ "item_group": "Raw Material",
+ "item_name": "Bearing Block"
+ },
+ {
+ "default_supplier": null,
+ "default_warehouse": "Finished Goods",
+ "description": "Wind Mill C Series for Commercial Use 18ft",
+ "image": "/assets/erpnext_demo/images/wind-turbine-2.png",
+ "item_code": "Wind MIll C Series",
+ "item_group": "Products",
+ "item_name": "Wind MIll C Series"
+ },
+ {
+ "default_supplier": null,
+ "default_warehouse": "Finished Goods",
+ "description": "Wind Mill A Series for Home Use 9ft",
+ "image": "/assets/erpnext_demo/images/wind-turbine.png",
+ "item_code": "Wind Mill A Series",
+ "item_group": "Products",
+ "item_name": "Wind Mill A Series"
+ },
+ {
+ "default_supplier": null,
+ "default_warehouse": "Finished Goods",
+ "description": "Small Wind Turbine for Home Use\n\n\n<!-- html -->",
+ "image": "/assets/erpnext_demo/images/wind-turbine-1.jpg",
+ "item_code": "Wind Turbine",
+ "item_group": "Products",
+ "item_name": "Wind Turbine",
+ "has_variants": 1,
+ "has_serial_no": 1,
+ "attributes":[
+ { "attribute": "Size" }
+ ]
+ },
+ {
+ "default_supplier": "HomeBase",
+ "default_warehouse": "Stores",
+ "description": "1.5 in. Diameter x 36 in. Mild Steel Tubing",
+ "image": null,
+ "item_code": "Bearing Pipe",
+ "item_group": "Raw Material",
+ "item_name": "Bearing Pipe"
+ },
+ {
+ "default_supplier": "New World Realty",
+ "default_warehouse": "Stores",
+ "description": "1/32 in. x 24 in. x 47 in. HDPE Opaque Sheet",
+ "image": null,
+ "item_code": "Wing Sheet",
+ "item_group": "Raw Material",
+ "item_name": "Wing Sheet"
+ },
+ {
+ "default_supplier": "Eagle Hardware",
+ "default_warehouse": "Stores",
+ "description": "3/16 in. x 6 in. x 6 in. Low Carbon Steel Plate",
+ "image": null,
+ "item_code": "Upper Bearing Plate",
+ "item_group": "Raw Material",
+ "item_name": "Upper Bearing Plate"
+ },
+ {
+ "default_supplier": "Asiatic Solutions",
+ "default_warehouse": "Stores",
+ "description": "Bearing Assembly",
+ "image": null,
+ "item_code": "Bearing Assembly",
+ "item_group": "Sub Assemblies",
+ "item_name": "Bearing Assembly"
+ },
+ {
+ "default_supplier": "HomeBase",
+ "default_warehouse": "Stores",
+ "description": "3/4 in. x 2 ft. x 4 ft. Pine Plywood",
+ "image": null,
+ "item_code": "Base Plate",
+ "item_group": "Raw Material",
+ "item_name": "Base Plate"
+ },
+ {
+ "default_supplier": "Scott Ties",
+ "default_warehouse": "Stores",
+ "description": "N/A",
+ "image": null,
+ "item_code": "Stand",
+ "item_group": "Raw Material",
+ "item_name": "Stand"
+ },
+ {
+ "default_supplier": "Eagle Hardware",
+ "default_warehouse": "Stores",
+ "description": "1 in. x 3 in. x 1 ft. Multipurpose Al Alloy Bar",
+ "image": null,
+ "item_code": "Bearing Collar",
+ "item_group": "Raw Material",
+ "item_name": "Bearing Collar"
+ },
+ {
+ "default_supplier": "Eagle Hardware",
+ "default_warehouse": "Stores",
+ "description": "1/4 in. x 6 in. x 6 in. Mild Steel Plate",
+ "image": null,
+ "item_code": "Base Bearing Plate",
+ "item_group": "Raw Material",
+ "item_name": "Base Bearing Plate"
+ },
+ {
+ "default_supplier": "HomeBase",
+ "default_warehouse": "Stores",
+ "description": "15/32 in. x 4 ft. x 8 ft. 3-Ply Rtd Sheathing",
+ "image": null,
+ "item_code": "External Disc",
+ "item_group": "Raw Material",
+ "item_name": "External Disc"
+ },
+ {
+ "default_supplier": "Eagle Hardware",
+ "default_warehouse": "Stores",
+ "description": "1.25 in. Diameter x 6 ft. Mild Steel Tubing",
+ "image": null,
+ "item_code": "Shaft",
+ "item_group": "Raw Material",
+ "item_name": "Shaft"
+ },
+ {
+ "default_supplier": "Ks Merchandise",
+ "default_warehouse": "Stores",
+ "description": "1/2 in. x 2 ft. x 4 ft. Pine Plywood",
+ "image": null,
+ "item_code": "Blade Rib",
+ "item_group": "Raw Material",
+ "item_name": "Blade Rib"
+ },
+ {
+ "default_supplier": "HomeBase",
+ "default_warehouse": "Stores",
+ "description": "For Bearing Collar",
+ "image": null,
+ "item_code": "Internal Disc",
+ "item_group": "Raw Material",
+ "item_name": "Internal Disc"
+ },
+ {
+ "default_supplier": null,
+ "default_warehouse": "Finished Goods",
+ "description": "Small Wind Turbine for Home Use\n\n\n<!-- html -->\n<p>Size: Small</p>",
+ "image": "/assets/erpnext_demo/images/wind-turbine-1.jpg",
+ "item_code": "Wind Turbine-S",
+ "item_group": "Products",
+ "item_name": "Wind Turbine-S",
+ "variant_of": "Wind Turbine",
+ "attributes":[
+ {
+ "attribute": "Size",
+ "attribute_value": "Small"
+ }
+ ]
+ },
+ {
+ "default_supplier": null,
+ "default_warehouse": "Finished Goods",
+ "description": "Small Wind Turbine for Home Use\n\n\n<!-- html -->\n<p>Size: Medium</p>",
+ "image": "/assets/erpnext_demo/images/wind-turbine-1.jpg",
+ "item_code": "Wind Turbine-M",
+ "item_group": "Products",
+ "item_name": "Wind Turbine-M",
+ "variant_of": "Wind Turbine",
+ "attributes":[
+ {
+ "attribute": "Size",
+ "attribute_value": "Medium"
+ }
+ ]
+ },
+ {
+ "default_supplier": null,
+ "default_warehouse": "Finished Goods",
+ "description": "Small Wind Turbine for Home Use\n\n\n<!-- html -->\n<p>Size: Large</p>",
+ "image": "/assets/erpnext_demo/images/wind-turbine-1.jpg",
+ "item_code": "Wind Turbine-L",
+ "item_group": "Products",
+ "item_name": "Wind Turbine-L",
+ "variant_of": "Wind Turbine",
+ "attributes":[
+ {
+ "attribute": "Size",
+ "attribute_value": "Large"
+ }
+ ]
+ },
+ {
+ "is_stock_item": 0,
+ "description": "Wind Mill A Series with Spare Bearing",
+ "item_code": "Wind Mill A Series with Spare Bearing",
+ "item_group": "Products",
+ "item_name": "Wind Mill A Series with Spare Bearing"
+ },
+ {
+ "default_supplier": "HomeBase",
+ "default_warehouse": "Stores",
+ "description": "3/4 in. x 2 ft. x 4 ft. Pine Plywood",
+ "image": null,
+ "item_code": "Base Plate Un Painted",
+ "item_group": "Raw Material",
+ "item_name": "Base Plate Un Painted"
+ }
+]
\ No newline at end of file
diff --git a/erpnext/demo/data/lead.json b/erpnext/demo/data/lead.json
new file mode 100644
index 0000000..ff78877
--- /dev/null
+++ b/erpnext/demo/data/lead.json
@@ -0,0 +1,127 @@
+[
+ {
+ "company_name": "Zany Brainy",
+ "email_id": "MartLakeman@example.com",
+ "lead_name": "Mart Lakeman"
+ },
+ {
+ "company_name": "Patterson-Fletcher",
+ "email_id": "SagaLundqvist@example.com",
+ "lead_name": "Saga Lundqvist"
+ },
+ {
+ "company_name": "Griff's Hamburgers",
+ "email_id": "AdnaSjoberg@example.com",
+ "lead_name": "Adna Sj\u00f6berg"
+ },
+ {
+ "company_name": "Rhodes Furniture",
+ "email_id": "IdaDSvendsen@example.com",
+ "lead_name": "Ida Svendsen"
+ },
+ {
+ "company_name": "Burger Chef",
+ "email_id": "EmppuHameenniemi@example.com",
+ "lead_name": "Emppu H\u00e4meenniemi"
+ },
+ {
+ "company_name": "Stratabiz",
+ "email_id": "EugenioPisano@example.com",
+ "lead_name": "Eugenio Pisano"
+ },
+ {
+ "company_name": "Home Quarters Warehouse",
+ "email_id": "SemharHagos@example.com",
+ "lead_name": "Semhar Hagos"
+ },
+ {
+ "company_name": "Enviro Architectural Designs",
+ "email_id": "BranimiraIvankovic@example.com",
+ "lead_name": "Branimira Ivankovi\u0107"
+ },
+ {
+ "company_name": "Ideal Garden Management",
+ "email_id": "ShellyLFields@example.com",
+ "lead_name": "Shelly Fields"
+ },
+ {
+ "company_name": "Listen Up",
+ "email_id": "LeoMikulic@example.com",
+ "lead_name": "Leo Mikuli\u0107"
+ },
+ {
+ "company_name": "I. Magnin",
+ "email_id": "DenisaJarosova@example.com",
+ "lead_name": "Denisa Jaro\u0161ov\u00e1"
+ },
+ {
+ "company_name": "First Rate Choice",
+ "email_id": "JanekRutkowski@example.com",
+ "lead_name": "Janek Rutkowski"
+ },
+ {
+ "company_name": "Multi Tech Development",
+ "email_id": "mm@example.com",
+ "lead_name": "\u7f8e\u6708 \u5b87\u85e4"
+ },
+ {
+ "company_name": "National Auto Parts",
+ "email_id": "dd@example.com",
+ "lead_name": "\u0414\u0430\u043d\u0438\u0438\u043b \u0410\u0444\u0430\u043d\u0430\u0441\u044c\u0435\u0432"
+ },
+ {
+ "company_name": "Integra Investment Plan",
+ "email_id": "ZorislavPetkovic@example.com",
+ "lead_name": "Zorislav Petkovi\u0107"
+ },
+ {
+ "company_name": "The Lawn Guru",
+ "email_id": "NanaoNiwa@example.com",
+ "lead_name": "Nanao Niwa"
+ },
+ {
+ "company_name": "Buena Vista Realty Service",
+ "email_id": "HreiarJorundsson@example.com",
+ "lead_name": "Hrei\u00f0ar J\u00f6rundsson"
+ },
+ {
+ "company_name": "Bountiful Harvest Health Food Store",
+ "email_id": "ChuThiBichLai@example.com",
+ "lead_name": "Lai Chu"
+ },
+ {
+ "company_name": "P. Samuels Men's Clothiers",
+ "email_id": "VictorAksakov@example.com",
+ "lead_name": "Victor Aksakov"
+ },
+ {
+ "company_name": "Vinyl Fever",
+ "email_id": "SaidalimBisliev@example.com",
+ "lead_name": "Saidalim Bisliev"
+ },
+ {
+ "company_name": "Garden Master",
+ "email_id": "TotteJakobsson@example.com",
+ "lead_name": "Totte Jakobsson"
+ },
+ {
+ "company_name": "Big Apple",
+ "email_id": "NanaArmasRobles@example.com",
+ "lead_name": "Nan\u00e1 Armas"
+ },
+ {
+ "company_name": "Monk House Sales",
+ "email_id": "WalerianDuda@example.com",
+ "lead_name": "Walerian Duda"
+ },
+ {
+ "company_name": "ManCharm",
+ "email_id": "Moarimikashi@example.com",
+ "lead_name": "Moarimikashi"
+ },
+ {
+ "company_name": "Custom Lawn Care",
+ "email_id": "DobromilDabrowski@example.com",
+ "lead_name": "Dobromi\u0142 D\u0105browski"
+ }
+]
\ No newline at end of file
diff --git a/erpnext/demo/data/operation.json b/erpnext/demo/data/operation.json
new file mode 100644
index 0000000..47f26d1
--- /dev/null
+++ b/erpnext/demo/data/operation.json
@@ -0,0 +1,32 @@
+[
+ {
+ "description": "Setup Fixtures for Assembly",
+ "name": "Setup Fixtures",
+ "workstation": "Assembly Station 1"
+ },
+ {
+ "description": "Assemble Unit as per Standard Operating Procedures",
+ "name": "Assembly Operation",
+ "workstation": "Assembly Station 1"
+ },
+ {
+ "description": "Final Testing Checklist",
+ "name": "Testing",
+ "workstation": "Packing and Testing Station"
+ },
+ {
+ "description": "Final Packing and add Instructions",
+ "name": "Packing",
+ "workstation": "Packing and Testing Station"
+ },
+ {
+ "description": "Prepare frame for assembly",
+ "name": "Prepare Frame",
+ "workstation": "Drilling Machine 1"
+ },
+ {
+ "description": "Connect wires",
+ "name": "Wiring",
+ "workstation": "Assembly Station 1"
+ }
+]
\ No newline at end of file
diff --git a/erpnext/demo/data/user.json b/erpnext/demo/data/user.json
new file mode 100644
index 0000000..e353efb
--- /dev/null
+++ b/erpnext/demo/data/user.json
@@ -0,0 +1,112 @@
+[
+ {
+ "email": "test_demo@erpnext.com",
+ "first_name": "Test",
+ "last_name": "User"
+ },
+ {
+ "email": "DikmanShervashidze@example.com",
+ "first_name": "Dikman",
+ "last_name": "Shervashidze"
+ },
+ {
+ "email": "Zukutakitoteka@example.com",
+ "first_name": "Zukutakitoteka",
+ "last_name": null
+ },
+ {
+ "email": "HatsueKashiwagi@example.com",
+ "first_name": "Hatsue",
+ "last_name": "Kashiwagi"
+ },
+ {
+ "email": "NuranVerkleij@example.com",
+ "first_name": "Nuran",
+ "last_name": "Verkleij"
+ },
+ {
+ "email": "aromn@example.com",
+ "first_name": "\u0414\u043c\u0438\u0442\u0440\u0438\u0439",
+ "last_name": "\u041f\u0438\u0440\u043e\u0433\u043e\u0432"
+ },
+ {
+ "email": "TildeLindqvist@example.com",
+ "first_name": "Tilde",
+ "last_name": "Lindqvist"
+ },
+ {
+ "email": "MichalSobczak@example.com",
+ "first_name": "Micha\u0142",
+ "last_name": "Sobczak"
+ },
+ {
+ "email": "GabrielleLoftus@example.com",
+ "first_name": "Gabrielle",
+ "last_name": "Loftus"
+ },
+ {
+ "email": "VakhitaRyzaev@example.com",
+ "first_name": "Vakhita",
+ "last_name": "Ryzaev"
+ },
+ {
+ "email": "CharmaineGaudreau@example.com",
+ "first_name": "Charmaine",
+ "last_name": "Gaudreau"
+ },
+ {
+ "email": "RafaelaMaartens@example.com",
+ "first_name": "Rafa\u00ebla",
+ "last_name": "Maartens"
+ },
+ {
+ "email": "NuguseYohannes@example.com",
+ "first_name": "Nuguse",
+ "last_name": "Yohannes"
+ },
+ {
+ "email": "panca@example.com",
+ "first_name": "\u0420\u0430\u0438\u0441\u0430",
+ "last_name": "\u0411\u0435\u043b\u044f\u043a\u043e\u0432\u0430"
+ },
+ {
+ "email": "CaYinLong@example.com",
+ "first_name": "\u80e4\u9686",
+ "last_name": "\u8521"
+ },
+ {
+ "email": "FreddieScott@example.com",
+ "first_name": "Freddie",
+ "last_name": "Scott"
+ },
+ {
+ "email": "BergoraVigfusdottir@example.com",
+ "first_name": "Berg\u00fe\u00f3ra",
+ "last_name": "Vigf\u00fasd\u00f3ttir"
+ },
+ {
+ "email": "WardNajmalDinKalb@example.com",
+ "first_name": "Ward",
+ "last_name": "Kalb"
+ },
+ {
+ "email": "WanMai@example.com",
+ "first_name": "Wan",
+ "last_name": "Mai"
+ },
+ {
+ "email": "LeonAbdulov@example.com",
+ "first_name": "Leon",
+ "last_name": "Abdulov"
+ },
+ {
+ "email": "SabinaNovotna@example.com",
+ "first_name": "Sabina",
+ "last_name": "Novotn\u00e1"
+ },
+ {
+ "email": "demo@erpnext.com",
+ "first_name": "Demo",
+ "last_name": "User"
+ }
+]
\ No newline at end of file
diff --git a/erpnext/demo/demo.py b/erpnext/demo/demo.py
new file mode 100644
index 0000000..3ca8eb9
--- /dev/null
+++ b/erpnext/demo/demo.py
@@ -0,0 +1,54 @@
+from __future__ import unicode_literals
+
+import frappe, sys
+import erpnext
+import frappe.utils
+from erpnext.demo.setup_data import setup_data
+from erpnext.demo.user import hr, sales
+
+def make(domain='Manufacturing'):
+ frappe.flags.domain = domain
+ setup_data()
+ simulate()
+
+def simulate():
+ runs_for = frappe.flags.runs_for or 150
+ frappe.flags.company = erpnext.get_default_company()
+
+ if not frappe.flags.start_date:
+ # start date = 100 days back
+ frappe.flags.start_date = frappe.utils.add_days(frappe.utils.nowdate(), -1 * runs_for)
+
+ current_date = frappe.utils.getdate(frappe.flags.start_date)
+
+ # continue?
+ demo_last_date = frappe.db.get_global('demo_last_date')
+ if demo_last_date:
+ current_date = frappe.utils.add_days(demo_last_date, 1)
+
+ # run till today
+ if not runs_for:
+ runs_for = frappe.utils.date_diff(frappe.utils.nowdate(), current_date)
+ # runs_for = 100
+
+ for i in xrange(runs_for):
+ sys.stdout.write("\rSimulating {0}".format(current_date.strftime("%Y-%m-%d")))
+ sys.stdout.flush()
+ frappe.flags.current_date = current_date
+
+ if current_date.weekday() in (5, 6):
+ current_date = frappe.utils.add_days(current_date, 1)
+ continue
+
+ hr.work()
+ sales.work()
+ # run_purchase()
+ # run_manufacturing()
+ # run_stock()
+ # run_accounts()
+ # run_projects()
+ # run_messages()
+
+ current_date = frappe.utils.add_days(current_date, 1)
+
+ frappe.db.commit()
diff --git a/erpnext/demo/domains.py b/erpnext/demo/domains.py
new file mode 100644
index 0000000..0217f24
--- /dev/null
+++ b/erpnext/demo/domains.py
@@ -0,0 +1,16 @@
+from __future__ import unicode_literals
+
+data = {
+ 'Manufacturing': {
+ 'company_name': 'Wind Power LLC'
+ },
+ 'Retail': {
+ 'company_name': 'Annapurna Dairy Shop',
+ },
+ 'Distribution': {
+ 'company_name': 'Soltice Hardware',
+ },
+ 'Services': {
+ 'company_name': 'Acme Consulting'
+ }
+}
\ No newline at end of file
diff --git a/erpnext/demo/setup_data.py b/erpnext/demo/setup_data.py
new file mode 100644
index 0000000..bfaee47
--- /dev/null
+++ b/erpnext/demo/setup_data.py
@@ -0,0 +1,302 @@
+from __future__ import unicode_literals
+
+import random, json
+from erpnext.demo.domains import data
+import frappe, erpnext
+import frappe.utils
+
+def setup_data():
+ domain = frappe.flags.domain
+ complete_setup(domain)
+ setup_demo_page()
+ setup_fiscal_year()
+ setup_holiday_list()
+ setup_customer()
+ setup_supplier()
+ setup_item()
+ import_json('Address')
+ import_json('Contact')
+ setup_workstation()
+ import_json('Operation')
+ import_json('Lead')
+ setup_item_price()
+ show_item_groups_in_website()
+ setup_currency_exchange()
+ import_json('BOM', submit=True)
+ setup_user()
+ setup_employee()
+ setup_salary_structure()
+ setup_user_roles()
+
+def complete_setup(domain='Manufacturing'):
+ print "Complete Setup..."
+ from frappe.desk.page.setup_wizard.setup_wizard import setup_complete
+
+ if not frappe.get_all('Company', limit=1):
+ setup_complete({
+ "first_name": "Test",
+ "last_name": "User",
+ "email": "test_demo@erpnext.com",
+ "company_tagline": 'Awesome Products and Services',
+ "password": "test",
+ "fy_start_date": "2015-01-01",
+ "fy_end_date": "2015-12-31",
+ "bank_account": "National Bank",
+ "industry": domain,
+ "company_name": data.get(domain).get('company_name'),
+ "chart_of_accounts": "Standard",
+ "company_abbr": ''.join([d[0] for d in data.get(domain).get('company_name').split()]).upper(),
+ "currency": 'USD',
+ "timezone": 'America/New_York',
+ "country": 'United States',
+ "language": "english"
+ })
+
+def setup_demo_page():
+ # home page should always be "start"
+ website_settings = frappe.get_doc("Website Settings", "Website Settings")
+ website_settings.home_page = "demo"
+ website_settings.save()
+
+def setup_fiscal_year():
+ fiscal_year = None
+ for year in xrange(2014, frappe.utils.now_datetime().year + 1, 1):
+ try:
+ fiscal_year = frappe.get_doc({
+ "doctype": "Fiscal Year",
+ "year": frappe.utils.cstr(year),
+ "year_start_date": "{0}-01-01".format(year),
+ "year_end_date": "{0}-12-31".format(year)
+ }).insert()
+ except frappe.DuplicateEntryError:
+ pass
+
+ # set the last fiscal year (current year) as default
+ fiscal_year.set_as_default()
+
+def setup_holiday_list():
+ """Setup Holiday List for the current year"""
+ year = frappe.utils.now_datetime().year
+ holiday_list = frappe.get_doc({
+ "doctype": "Holiday List",
+ "holiday_list_name": str(year),
+ "from_date": "{0}-01-01".format(year),
+ "to_date": "{0}-12-31".format(year),
+ })
+ holiday_list.insert()
+ holiday_list.weekly_off = "Saturday"
+ holiday_list.get_weekly_off_dates()
+ holiday_list.weekly_off = "Sunday"
+ holiday_list.get_weekly_off_dates()
+ holiday_list.save()
+
+ frappe.set_value("Company", erpnext.get_default_company(), "default_holiday_list", holiday_list.name)
+
+def setup_customer():
+ customers = [u'Asian Junction', u'Life Plan Counselling', u'Two Pesos', u'Mr Fables', u'Intelacard', u'Big D Supermarkets', u'Adaptas', u'Nelson Brothers', u'Landskip Yard Care', u'Buttrey Food & Drug', u'Fayva', u'Asian Fusion', u'Crafts Canada', u'Consumers and Consumers Express', u'Netobill', u'Choices', u'Chi-Chis', u'Red Food', u'Endicott Shoes', u'Hind Enterprises']
+ for c in customers:
+ frappe.get_doc({
+ "doctype": "Customer",
+ "customer_name": c,
+ "customer_group": "Commercial",
+ "customer_type": random.choice(["Company", "Individual"]),
+ "territory": "Rest Of The World"
+ }).insert()
+
+def setup_supplier():
+ suppliers = [u'Helios Air', u'Ks Merchandise', u'HomeBase', u'Scott Ties', u'Reliable Investments', u'Nan Duskin', u'Rainbow Records', u'New World Realty', u'Asiatic Solutions', u'Eagle Hardware', u'Modern Electricals']
+ for s in suppliers:
+ frappe.get_doc({
+ "doctype": "Supplier",
+ "supplier_name": s,
+ "supplier_type": random.choice(["Services", "Raw Material"]),
+ }).insert()
+
+def setup_workstation():
+ workstations = [u'Drilling Machine 1', u'Lathe 1', u'Assembly Station 1', u'Assembly Station 2', u'Packing and Testing Station']
+ for w in workstations:
+ frappe.get_doc({
+ "doctype": "Workstation",
+ "workstation_name": w,
+ "holiday_list": frappe.get_all("Holiday List")[0].name,
+ "hour_rate_consumable": int(random.random() * 20),
+ "hour_rate_electricity": int(random.random() * 10),
+ "hour_rate_labour": int(random.random() * 40),
+ "hour_rate_rent": int(random.random() * 10),
+ "working_hours": [
+ {
+ "enabled": 1,
+ "start_time": "8:00:00",
+ "end_time": "15:00:00"
+ }
+ ]
+ }).insert()
+
+def show_item_groups_in_website():
+ """set show_in_website=1 for Item Groups"""
+ products = frappe.get_doc("Item Group", "Products")
+ products.show_in_website = 1
+ products.route = 'products'
+ products.save()
+
+def setup_item():
+ items = json.loads(open(frappe.get_app_path('erpnext', 'demo', 'data', 'item.json')).read())
+ for i in items:
+ item = frappe.new_doc('Item')
+ item.update(i)
+ item.default_warehouse = frappe.get_all('Warehouse', filters={'warehouse_name': item.default_warehouse}, limit=1)[0].name
+ item.insert()
+
+def setup_currency_exchange():
+ frappe.get_doc({
+ 'doctype': 'Currency Exchange',
+ 'from_currency': 'EUR',
+ 'to_currency': 'USD',
+ 'exchange_rate': 1.13
+ }).insert()
+
+ frappe.get_doc({
+ 'doctype': 'Currency Exchange',
+ 'from_currency': 'CNY',
+ 'to_currency': 'USD',
+ 'exchange_rate': 0.16
+ }).insert()
+
+def setup_product_bundle():
+ frappe.get_doc({
+ 'doctype': 'Product Bundle',
+ 'new_item_code': 'Wind Mill A Series with Spare Bearing',
+ 'items': [
+ {'item_code': 'Wind Mill A Series', 'qty': 1},
+ {'item_code': 'Bearing Collar', 'qty': 1},
+ {'item_code': 'Bearing Assembly', 'qty': 1},
+ ]
+ }).insert()
+
+def setup_user():
+ frappe.db.sql('delete from tabUser where name not in ("Guest", "Administrator")')
+ for u in json.loads(open(frappe.get_app_path('erpnext', 'demo', 'data', 'user.json')).read()):
+ user = frappe.new_doc("User")
+ user.update(u)
+ user.flags.no_welcome_mail
+ user.password = 'demo'
+ user.insert()
+
+def import_json(doctype, submit=False):
+ frappe.flags.in_import = True
+ data = json.loads(open(frappe.get_app_path('erpnext', 'demo', 'data',
+ frappe.scrub(doctype) + '.json')).read())
+ for d in data:
+ doc = frappe.new_doc(doctype)
+ doc.update(d)
+ doc.insert()
+ if submit:
+ doc.submit()
+
+def setup_employee():
+ frappe.db.set_value("HR Settings", None, "emp_created_by", "Naming Series")
+ frappe.db.commit()
+
+ import_json('Employee')
+
+def setup_item_price():
+ frappe.db.sql("delete from `tabItem Price`")
+
+ standard_selling = {
+ "Base Bearing Plate": 28,
+ "Base Plate": 21,
+ "Bearing Assembly": 300,
+ "Bearing Block": 14,
+ "Bearing Collar": 103.6,
+ "Bearing Pipe": 63,
+ "Blade Rib": 46.2,
+ "Disc Collars": 42,
+ "External Disc": 56,
+ "Internal Disc": 70,
+ "Shaft": 340,
+ "Stand": 400,
+ "Upper Bearing Plate": 300,
+ "Wind Mill A Series": 320,
+ "Wind Mill A Series with Spare Bearing": 750,
+ "Wind MIll C Series": 400,
+ "Wind Turbine": 400,
+ "Wing Sheet": 30.8
+ }
+
+ standard_buying = {
+ "Base Bearing Plate": 20,
+ "Base Plate": 28,
+ "Base Plate Un Painted": 16,
+ "Bearing Block": 13,
+ "Bearing Collar": 96.4,
+ "Bearing Pipe": 55,
+ "Blade Rib": 38,
+ "Disc Collars": 34,
+ "External Disc": 50,
+ "Internal Disc": 60,
+ "Shaft": 250,
+ "Stand": 300,
+ "Upper Bearing Plate": 200,
+ "Wing Sheet": 25
+ }
+
+ for price_list in ("standard_buying", "standard_selling"):
+ for item, rate in locals().get(price_list).iteritems():
+ frappe.get_doc({
+ "doctype": "Item Price",
+ "price_list": price_list.replace("_", " ").title(),
+ "item_code": item,
+ "selling": 1 if price_list=="standard_selling" else 0,
+ "buying": 1 if price_list=="standard_buying" else 0,
+ "price_list_rate": rate,
+ "currency": "USD"
+ }).insert()
+
+def setup_salary_structure():
+ f = frappe.get_doc('Fiscal Year', frappe.defaults.get_global_default('fiscal_year'))
+
+ for e in frappe.get_all('Employee', fields=['name', 'date_of_joining']):
+ ss = frappe.new_doc('Salary Structure')
+ ss.employee = e.name
+
+ if not e.date_of_joining:
+ continue
+
+ ss.from_date = e.date_of_joining if (e.date_of_joining
+ and e.date_of_joining > f.year_start_date) else f.year_start_date
+ ss.to_date = f.year_end_date
+ ss.append('earnings', {
+ 'earning_type': 'Basic',
+ 'modified_value': random.random() * 10000
+ })
+ ss.append('deductions', {
+ 'deduction_type': 'Income Tax',
+ 'd_modified_amt': random.random() * 1000
+ })
+ ss.insert()
+
+def setup_account():
+ frappe.flags.in_import = True
+ data = json.loads(open(frappe.get_app_path('erpnext', 'demo', 'data',
+ 'account.json')).read())
+ for d in data:
+ doc = frappe.new_doc('Account')
+ doc.update(d)
+ doc.parent_account = frappe.db.get_value('Account', {'account_name': doc.parent_account})
+ doc.insert()
+
+def setup_user_roles():
+ if not frappe.db.get_global('demo_hr_user'):
+ user = frappe.get_doc('User', 'CharmaineGaudreau@example.com')
+ user.add_roles('HR User', 'HR Manager', 'Accounts User')
+ frappe.db.set_global('demo_hr_user', user.name)
+
+ if not frappe.db.get_global('demo_sales_user_1'):
+ user = frappe.get_doc('User', 'VakhitaRyzaev@example.com')
+ user.add_roles('Sales User')
+ frappe.db.set_global('demo_sales_user_1', user.name)
+
+ if not frappe.db.get_global('demo_sales_user_2'):
+ user = frappe.get_doc('User', 'GabrielleLoftus@example.com')
+ user.add_roles('Sales User', 'Sales Manager', 'Accounts User')
+ frappe.db.set_global('demo_sales_user_2', user.name)
diff --git a/erpnext/demo/user/__init__.py b/erpnext/demo/user/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/demo/user/__init__.py
diff --git a/erpnext/demo/user/hr.py b/erpnext/demo/user/hr.py
new file mode 100644
index 0000000..8196701
--- /dev/null
+++ b/erpnext/demo/user/hr.py
@@ -0,0 +1,26 @@
+from __future__ import unicode_literals
+import frappe
+from frappe.utils import random_string
+
+def work():
+ frappe.set_user(frappe.db.get_global('demo_hr_user'))
+
+ year, month = frappe.flags.current_date.strftime("%Y-%m").split("-")
+
+ # process payroll
+ if not frappe.db.get_value("Salary Slip", {"month": month, "fiscal_year": year}):
+ process_payroll = frappe.get_doc("Process Payroll", "Process Payroll")
+ process_payroll.company = frappe.flags.company
+ process_payroll.month = month
+ process_payroll.fiscal_year = year
+ process_payroll.create_sal_slip()
+ process_payroll.submit_salary_slip()
+ r = process_payroll.make_journal_entry(frappe.get_value('Account',
+ {'account_name': 'Salary'}))
+
+ journal_entry = frappe.get_doc(r)
+ journal_entry.cheque_no = random_string(10)
+ journal_entry.cheque_date = frappe.flags.current_date
+ journal_entry.posting_date = frappe.flags.current_date
+ journal_entry.insert()
+ journal_entry.submit()
diff --git a/erpnext/demo/user/purchase.py b/erpnext/demo/user/purchase.py
new file mode 100644
index 0000000..cf27358
--- /dev/null
+++ b/erpnext/demo/user/purchase.py
@@ -0,0 +1,138 @@
+# 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, random
+from frappe.utils.make_random import how_many, can_make, get_random
+from frappe.desk import query_report
+from erpnext.setup.utils import get_exchange_rate
+from erpnext.accounts.party import get_party_account_currency
+from erpnext.exceptions import InvalidCurrency
+from erpnext.stock.doctype.material_request.material_request import make_request_for_quotation
+from erpnext.buying.doctype.request_for_quotation.request_for_quotation import \
+ make_supplier_quotation as make_quotation_from_rfq
+
+def run_purchase(current_date):
+ if random.random() < 0.3:
+ report = "Items To Be Requested"
+ for row in query_report.run(report)["result"][:how_many("Material Request")]:
+ item_code, qty = row[0], abs(row[-1])
+
+ mr = make_material_request(item_code, qty)
+
+ if random.random() < 0.3:
+ for mr in frappe.get_all('Material Request', filters={'material_request_type': 'Purchase', 'status': 'Open'}):
+ rfq = make_request_for_quotation(mr.name)
+ rfq.transaction_date = frappe.flags.current_date
+ add_suppliers(rfq)
+ rfq.save()
+ rfq.submit()
+
+ # Make suppier quotation from RFQ against each supplier.
+ if random.random() < 0.3:
+ for supplier_quotation in frappe.get_all('Request for Quotation', {'status': 'Open'}):
+ rfq = frappe.get_doc('Request for Quotation', rfq.name)
+ for supplier in rfq.suppliers:
+ supplier_quotation = make_quotation_from_rfq(rfq.name, supplier.supplier)
+ supplier_quotation.save()
+ supplier_quotation.submit()
+
+ # get supplier details
+ supplier = get_random("Supplier")
+
+ company_currency = frappe.db.get_value("Company", "Wind Power LLC", "default_currency")
+ party_account_currency = get_party_account_currency("Supplier", supplier, "Wind Power LLC")
+ if company_currency == party_account_currency:
+ exchange_rate = 1
+ else:
+ exchange_rate = get_exchange_rate(party_account_currency, company_currency)
+
+ # make supplier quotations
+ if can_make("Supplier Quotation"):
+ from erpnext.stock.doctype.material_request.material_request import make_supplier_quotation
+
+ report = "Material Requests for which Supplier Quotations are not created"
+ for row in query_report.run(report)["result"][:how_many("Supplier Quotation")]:
+ if row[0] != "'Total'":
+ sq = frappe.get_doc(make_supplier_quotation(row[0]))
+ sq.transaction_date = current_date
+ sq.supplier = supplier
+ sq.currency = party_account_currency or company_currency
+ sq.conversion_rate = exchange_rate
+ sq.insert()
+ sq.submit()
+ frappe.db.commit()
+
+ # make purchase orders
+ if can_make("Purchase Order"):
+ from erpnext.stock.doctype.material_request.material_request import make_purchase_order
+ report = "Requested Items To Be Ordered"
+ for row in query_report.run(report)["result"][:how_many("Purchase Order")]:
+ if row[0] != "'Total'":
+ po = frappe.get_doc(make_purchase_order(row[0]))
+ po.supplier = supplier
+ po.currency = party_account_currency or company_currency
+ po.conversion_rate = exchange_rate
+ po.transaction_date = current_date
+ po.insert()
+ po.submit()
+ frappe.db.commit()
+
+ if can_make("Subcontract"):
+ make_subcontract(current_date)
+
+def make_material_request(item_code, qty):
+ mr = frappe.new_doc("Material Request")
+
+ if frappe.db.get_value('BOM', {'item': item_code, 'is_default': 1, 'is_active': 1}):
+ mr.material_request_type = 'Manufacture'
+ else:
+ mr.material_request_type = "Purchase"
+
+ mr.transaction_date = frappe.flags.current_date
+ mr.append("items", {
+ "doctype": "Material Request Item",
+ "schedule_date": frappe.utils.add_days(mr.transaction_date, 7),
+ "item_code": item_code,
+ "qty": qty
+ })
+ mr.insert()
+ mr.submit()
+ return mr
+
+def add_suppliers(rfq):
+ for i in xrange(2):
+ supplier = get_random("Supplier")
+ if supplier not in [d.supplier for d in rfq.get('suppliers')]:
+ rfq.append("suppliers", { "supplier": supplier })
+
+def make_subcontract():
+ from erpnext.buying.doctype.purchase_order.purchase_order import make_stock_entry
+
+ # make sub-contract PO
+ po = frappe.new_doc("Purchase Order")
+ po.is_subcontracted = "Yes"
+ po.supplier = get_random("Supplier")
+
+ po.append("items", {
+ "item_code": get_random("Item", {"is_sub_contracted_item": 1}),
+ "schedule_date": frappe.utils.add_days(frappe.flags.current_date, 7),
+ "qty": 20
+ })
+ po.set_missing_values()
+ try:
+ po.insert()
+ except InvalidCurrency:
+ return
+
+ po.submit()
+
+ # make material request for
+ make_material_request(po.items[0].item_code, po.items[0].qty)
+
+ # transfer material for sub-contract
+ stock_entry = frappe.get_doc(make_stock_entry(po.name, po.items[0].item_code))
+ stock_entry.from_warehouse = "Stores - WP"
+ stock_entry.to_warehouse = "Supplier - WP"
+ stock_entry.insert()
diff --git a/erpnext/demo/user/sales.py b/erpnext/demo/user/sales.py
new file mode 100644
index 0000000..7432ba0
--- /dev/null
+++ b/erpnext/demo/user/sales.py
@@ -0,0 +1,109 @@
+# 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, random
+from frappe.utils.make_random import add_random_children, get_random
+from erpnext.setup.utils import get_exchange_rate
+from erpnext.accounts.party import get_party_account_currency
+
+def work():
+ frappe.set_user(frappe.db.get_global('demo_sales_user_2'))
+ if random.random() < 0.5:
+ for i in xrange(random.randint(1,7)):
+ make_opportunity()
+
+ if random.random() < 0.5:
+ for i in xrange(random.randint(1,3)):
+ make_quotation()
+
+ # lost quotations / inquiries
+ if random.random() < 0.3:
+ for i in xrange(random.randint(1,3)):
+ quotation = get_random('Quotation', doc=True)
+ if quotation and quotation.status == 'Submitted':
+ quotation.declare_order_lost('Did not ask')
+
+ for i in xrange(random.randint(1,3)):
+ opportunity = get_random('Opportunity', doc=True)
+ if opportunity and opportunity.status in ('Open', 'Replied'):
+ opportunity.declare_enquiry_lost('Did not ask')
+
+ if random.random() < 0.3:
+ for i in xrange(random.randint(1,3)):
+ make_sales_order()
+
+def make_opportunity():
+ b = frappe.get_doc({
+ "doctype": "Opportunity",
+ "enquiry_from": "Customer",
+ "customer": get_random("Customer"),
+ "enquiry_type": "Sales",
+ "transaction_date": frappe.flags.current_date,
+ })
+
+ add_random_children(b, "items", rows=4, randomize = {
+ "qty": (1, 5),
+ "item_code": ("Item", {"has_variants": "0"})
+ }, unique="item_code")
+
+ b.insert()
+ frappe.db.commit()
+
+def make_quotation():
+ # get open opportunites
+ opportunity = get_random("Opportunity", {"status": "Open"})
+
+ if opportunity:
+ from erpnext.crm.doctype.opportunity.opportunity import make_quotation
+ qtn = frappe.get_doc(make_quotation(opportunity))
+ qtn.insert()
+ frappe.db.commit()
+ qtn.submit()
+ frappe.db.commit()
+ else:
+ # make new directly
+
+ # get customer, currency and exchange_rate
+ customer = get_random("Customer")
+
+ company_currency = frappe.db.get_value("Company", "Wind Power LLC", "default_currency")
+ party_account_currency = get_party_account_currency("Customer", customer, "Wind Power LLC")
+ if company_currency == party_account_currency:
+ exchange_rate = 1
+ else:
+ exchange_rate = get_exchange_rate(party_account_currency, company_currency)
+
+ qtn = frappe.get_doc({
+ "creation": frappe.flags.current_date,
+ "doctype": "Quotation",
+ "quotation_to": "Customer",
+ "customer": customer,
+ "currency": party_account_currency or company_currency,
+ "conversion_rate": exchange_rate,
+ "order_type": "Sales",
+ "transaction_date": frappe.flags.current_date,
+ })
+
+ add_random_children(qtn, "items", rows=3, randomize = {
+ "qty": (1, 5),
+ "item_code": ("Item", {"has_variants": "0"})
+ }, unique="item_code")
+
+ qtn.insert()
+ frappe.db.commit()
+ qtn.submit()
+ frappe.db.commit()
+
+def make_sales_order():
+ q = get_random("Quotation", {"status": "Submitted"})
+ if q:
+ from erpnext.selling.doctype.quotation.quotation import make_sales_order
+ so = frappe.get_doc(make_sales_order(q))
+ so.transaction_date = frappe.flags.current_date
+ so.delivery_date = frappe.utils.add_days(frappe.flags.current_date, 10)
+ so.insert()
+ frappe.db.commit()
+ so.submit()
+ frappe.db.commit()
diff --git a/erpnext/templates/pages/demo.html b/erpnext/templates/pages/demo.html
new file mode 100644
index 0000000..23a9a21
--- /dev/null
+++ b/erpnext/templates/pages/demo.html
@@ -0,0 +1,43 @@
+{% extends "templates/web.html" %}
+
+{% block script %}
+ <script>{% include "templates/includes/start.js" %}</script>
+{% endblock %}
+
+{% block style %}
+<style>
+ footer, .navbar {
+ display: none;
+ }
+ .page-content {
+ right: 0%;
+ width: 100%;
+ }
+</style>
+{% endblock %}
+
+{% block title %}
+{{ _("Login") }}
+{% endblock %}
+
+{% block page_content %}
+
+<!-- no-header -->
+<div class="page-hero text-center">
+ <img src="/assets/erpnext_demo/images/erp-icon-box.svg" style="max-width: 100px; max-height: 100px;">
+ <h1>ERPNext Demo</h1>
+ <p style="margin-top: 60px;">
+ <input id="lead-email" type="email"
+ class="form-control" placeholder="Your Email Id (optional)"
+ style="width: 75%; max-width: 400px; margin: auto;">
+ </p>
+
+ <button type="submit" id="login_btn" class="btn btn-default">Launch Demo</button>
+
+ <hr style="margin: 60px 0px;">
+ <p class="text-muted small">Some functionality is disabled for the demo app. The demo data will be cleared regulary.
+ <br class="hidden-xs">
+ To start your free ERPNext account, <a href="https://erpnext.com/signup?plan=Free-Solo">click here</a></p>
+</div>
+
+{% endblock %}