From 067245933ecb3465ae8b190fde12caf0e486ae0b Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Mon, 22 Aug 2016 12:57:09 +0530 Subject: [PATCH] Fixed Demo --- .../doctype/sales_invoice/sales_invoice.py | 1 - .../accounts_receivable.py | 6 +- erpnext/demo/data/course.json | 134 ++ erpnext/demo/data/department.json | 30 + erpnext/demo/data/instructor.json | 128 ++ erpnext/demo/data/item_schools.json | 94 + erpnext/demo/data/program.json | 102 ++ erpnext/demo/data/random_student_data.json | 1604 +++++++++++++++++ erpnext/demo/data/room.json | 122 ++ erpnext/demo/data/user.json | 4 +- erpnext/demo/demo.py | 55 +- erpnext/demo/domains.py | 3 + erpnext/demo/setup/__init__.py | 0 erpnext/demo/setup/education.py | 140 ++ erpnext/demo/setup/manufacture.py | 131 ++ erpnext/demo/{ => setup}/setup_data.py | 409 ++--- erpnext/demo/user/accounts.py | 2 +- erpnext/demo/user/hr.py | 15 +- erpnext/demo/user/projects.py | 14 +- erpnext/demo/user/purchase.py | 57 +- erpnext/demo/user/schools.py | 97 + erpnext/demo/user/stock.py | 6 +- erpnext/schools/api.py | 3 +- 23 files changed, 2818 insertions(+), 339 deletions(-) create mode 100644 erpnext/demo/data/course.json create mode 100644 erpnext/demo/data/department.json create mode 100644 erpnext/demo/data/instructor.json create mode 100644 erpnext/demo/data/item_schools.json create mode 100644 erpnext/demo/data/program.json create mode 100644 erpnext/demo/data/random_student_data.json create mode 100644 erpnext/demo/data/room.json create mode 100644 erpnext/demo/setup/__init__.py create mode 100644 erpnext/demo/setup/education.py create mode 100644 erpnext/demo/setup/manufacture.py rename erpnext/demo/{ => setup}/setup_data.py (73%) create mode 100644 erpnext/demo/user/schools.py diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 35df29955d5..45dc9ee19d3 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -330,7 +330,6 @@ class SalesInvoice(SellingController): against_acc.append(d.income_account) self.against_income_account = ','.join(against_acc) - def add_remarks(self): if not self.remarks: self.remarks = 'No Remarks' diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index ed429d6c5b5..e1f4f803930 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -53,9 +53,9 @@ class ReceivablePayableReport(object): self.filters["range3"] = "90" for label in ("0-{range1}".format(range1=self.filters["range1"]), - "{range1}-{range2}".format(range1=self.filters["range1"]+1, range2=self.filters["range2"]), - "{range2}-{range3}".format(range2=self.filters["range2"]+1, range3=self.filters["range3"]), - "{range3}-{above}".format(range3=self.filters["range3"] + 1, above=_("Above"))): + "{range1}-{range2}".format(range1=cint(self.filters["range1"])+ 1, range2=self.filters["range2"]), + "{range2}-{range3}".format(range2=cint(self.filters["range2"])+ 1, range3=self.filters["range3"]), + "{range3}-{above}".format(range3=cint(self.filters["range3"])+ 1, above=_("Above"))): columns.append({ "label": label, "fieldtype": "Currency", diff --git a/erpnext/demo/data/course.json b/erpnext/demo/data/course.json new file mode 100644 index 00000000000..15728d51d3b --- /dev/null +++ b/erpnext/demo/data/course.json @@ -0,0 +1,134 @@ +[ + { + "doctype": "Course", + "course_name": "Communication Skiils", + "course_code": "BCA2040", + "department": "Information Technology" + }, + { + "doctype": "Course", + "course_name": "Object Oriented Programing - C++", + "course_code": "BCA2030", + "department": "Information Technology" + }, + { + "doctype": "Course", + "course_name": "Data Structures and Algorithm", + "course_code": "BCA2020", + "department": "Information Technology" + }, + { + "doctype": "Course", + "course_name": "Operating System", + "course_code": "BCA2010", + "department": "Information Technology" + }, + { + "doctype": "Course", + "course_name": "Digital Logic", + "course_code": "BCA1040", + "department": "Information Technology" + }, + { + "doctype": "Course", + "course_name": "Basic Mathematics", + "course_code": "BCA1030", + "department": "Information Technology" + }, + { + "doctype": "Course", + "course_name": "Programing in C", + "course_code": "BCA1020", + "department": "Information Technology" + }, + { + "doctype": "Course", + "course_name": "Fundamentals of IT & Programing", + "course_code": "BCA1010", + "department": "Information Technology" + }, + { + "doctype": "Course", + "course_name": "Microprocessor", + "course_code": "MCA4010", + "department": "Information Technology" + }, + { + "doctype": "Course", + "course_name": "Probability and Statistics", + "course_code": "MCA4020", + "department": "Information Technology" + }, + { + "doctype": "Course", + "course_name": "Programing in Java", + "course_code": "MCA4030", + "department": "Information Technology" + }, + { + "doctype": "Course", + "course_name": "Communication Skills", + "course_code": "BBA 101", + "department": "Management Studies" + }, + { + "doctype": "Course", + "course_name": "Organizational Behavior", + "course_code": "BBA 102", + "department": "Management Studies" + }, + { + "doctype": "Course", + "course_name": "Business Environment", + "course_code": "BBA 103", + "department": "Management Studies" + }, + { + "doctype": "Course", + "course_name": "Legal and Regulatory Framework", + "course_code": "BBA 301", + "department": "Management Studies" + }, + { + "doctype": "Course", + "course_name": "Human Resource Management", + "course_code": "BBA 302", + "department": "Management Studies" + }, + { + "doctype": "Course", + "course_name": "Advertising and Sales", + "course_code": "BBA 304", + "department": "Management Studies" + }, + { + "doctype": "Course", + "course_name": "Entrepreneurship Management", + "course_code": "BBA 505", + "department": "Management Studies" + }, + { + "doctype": "Course", + "course_name": "Visual Merchandising", + "course_code": "BBR 504", + "department": "Management Studies" + }, + { + "doctype": "Course", + "course_name": "Warehouse Management", + "course_code": "BBR 505", + "department": "Management Studies" + }, + { + "doctype": "Course", + "course_name": "Store Operations and Job Knowledge", + "course_code": "BBR 501", + "department": "Management Studies" + }, + { + "doctype": "Course", + "course_name": "Management Development and Skills", + "course_code": "BBA 602", + "department": "Management Studies" + } +] diff --git a/erpnext/demo/data/department.json b/erpnext/demo/data/department.json new file mode 100644 index 00000000000..f4355ba1e79 --- /dev/null +++ b/erpnext/demo/data/department.json @@ -0,0 +1,30 @@ +[ + { + "doctype": "Department", + "department_name": "Information Technology" + }, + { + "doctype": "Department", + "department_name": "Physics" + }, + { + "doctype": "Department", + "department_name": "Chemistry" + }, + { + "doctype": "Department", + "department_name": "Biology" + }, + { + "doctype": "Department", + "department_name": "Commerce" + }, + { + "doctype": "Department", + "department_name": "English" + }, + { + "doctype": "Department", + "department_name": "Management Studies" + } +] \ No newline at end of file diff --git a/erpnext/demo/data/instructor.json b/erpnext/demo/data/instructor.json new file mode 100644 index 00000000000..a25d16304d7 --- /dev/null +++ b/erpnext/demo/data/instructor.json @@ -0,0 +1,128 @@ +[ + { + "doctype": "Instructor", + "instructor_name": "Eddie Jessup", + "naming_series": "INS/", + "department": "Information Technology" + }, + { + "doctype": "Instructor", + "instructor_name": "William Dyer", + "naming_series": "INS/", + "department": "Information Technology" + }, + { + "doctype": "Instructor", + "instructor_name": "Alastor Moody", + "naming_series": "INS/", + "department": "Information Technology" + }, + { + "doctype": "Instructor", + "instructor_name": "Charles Xavier", + "naming_series": "INS/", + "department": "Information Technology" + }, + { + "doctype": "Instructor", + "instructor_name": "Cuthbert Calculus", + "naming_series": "INS/", + "department": "Information Technology" + }, + { + "doctype": "Instructor", + "instructor_name": "Reed Richards", + "naming_series": "INS/", + "department": "Information Technology" + }, + { + "doctype": "Instructor", + "instructor_name": "Urban Chronotis", + "naming_series": "INS/", + "department": "Physics" + }, + { + "doctype": "Instructor", + "instructor_name": "River Song", + "naming_series": "INS/", + "department": "Physics" + }, + { + "doctype": "Instructor", + "instructor_name": "Yana", + "naming_series": "INS/", + "department": "Physics" + }, + { + "doctype": "Instructor", + "instructor_name": "Neil Lasrado", + "naming_series": "INS/", + "department": "Information Technology" + }, + { + "doctype": "Instructor", + "instructor_name": "Deepshi Garg", + "naming_series": "INS/", + "department": "Chemistry" + }, + { + "doctype": "Instructor", + "instructor_name": "Shubham Saxena", + "naming_series": "INS/", + "department": "Physics" + }, + { + "doctype": "Instructor", + "instructor_name": "Rushabh Mehta", + "naming_series": "INS/", + "department": "Information Technology" + }, + { + "doctype": "Instructor", + "instructor_name": "Umari Syed", + "naming_series": "INS/", + "department": "Chemistry" + }, + { + "doctype": "Instructor", + "instructor_name": "Aman Singh", + "naming_series": "INS/", + "department": "Physics" + }, + { + "doctype": "Instructor", + "instructor_name": "Nabin", + "naming_series": "INS/", + "department": "Chemistry" + }, + { + "doctype": "Instructor", + "instructor_name": "Kanchan Chauhan", + "naming_series": "INS/", + "department": "Information Technology" + }, + { + "doctype": "Instructor", + "instructor_name": "Valmik Jangla", + "naming_series": "INS/", + "department": "Chemistry" + }, + { + "doctype": "Instructor", + "instructor_name": "Amit Jain", + "naming_series": "INS/", + "department": "Physics" + }, + { + "doctype": "Instructor", + "instructor_name": "Shreyas P", + "naming_series": "INS/", + "department": "Chemistry" + }, + { + "doctype": "Instructor", + "instructor_name": "Rohit", + "naming_series": "INS/", + "department": "Information Technology" + } +] \ No newline at end of file diff --git a/erpnext/demo/data/item_schools.json b/erpnext/demo/data/item_schools.json new file mode 100644 index 00000000000..5eb60820f5a --- /dev/null +++ b/erpnext/demo/data/item_schools.json @@ -0,0 +1,94 @@ +[ + { + "default_supplier": "Asiatic Solutions", + "default_warehouse": "Stores", + "item_code": "Books", + "item_group": "Raw Material", + "item_name": "Books" + }, + { + "default_supplier": "HomeBase", + "default_warehouse": "Stores", + "item_code": "Pencil", + "item_group": "Raw Material", + "item_name": "Pencil" + }, + { + "default_supplier": "New World Realty", + "default_warehouse": "Stores", + "item_code": "Tables", + "item_group": "Raw Material", + "item_name": "Tables" + }, + { + "default_supplier": "Eagle Hardware", + "default_warehouse": "Stores", + "item_code": "Chair", + "item_group": "Raw Material", + "item_name": "Chair" + }, + { + "default_supplier": "Asiatic Solutions", + "default_warehouse": "Stores", + "item_code": "Black Board", + "item_group": "Sub Assemblies", + "item_name": "Black Board" + }, + { + "default_supplier": "HomeBase", + "default_warehouse": "Stores", + "item_code": "Chalk", + "item_group": "Raw Material", + "item_name": "Chalk" + }, + { + "default_supplier": "HomeBase", + "default_warehouse": "Stores", + "item_code": "Notepad", + "item_group": "Raw Material", + "item_name": "Notepad" + }, + { + "default_supplier": "Ks Merchandise", + "default_warehouse": "Stores", + "item_code": "Uniform", + "item_group": "Raw Material", + "item_name": "Uniform" + }, + { + "is_stock_item": 0, + "description": "Computer", + "item_code": "Computer", + "item_name": "Computer", + "item_group": "Products" + }, + { + "is_stock_item": 0, + "description": "Mobile", + "item_code": "Mobile", + "item_name": "Mobile", + "item_group": "Products" + }, + { + "is_stock_item": 0, + "description": "ERP", + "item_code": "ERP", + "item_name": "ERP", + "item_group": "All Item Groups" + }, + { + "is_stock_item": 0, + "description": "Autocad", + "item_code": "Autocad", + "item_name": "Autocad", + "item_group": "All Item Groups" + }, + { + "default_warehouse": "Stores", + "item_code": "Service", + "item_group": "Services", + "item_name": "Service", + "has_variants": 0, + "is_stock_item": 0 + } +] \ No newline at end of file diff --git a/erpnext/demo/data/program.json b/erpnext/demo/data/program.json new file mode 100644 index 00000000000..8638311a380 --- /dev/null +++ b/erpnext/demo/data/program.json @@ -0,0 +1,102 @@ +[ + { + "doctype": "Program", + "program_name": "Masters of Computer Applications", + "program_code": "MCA", + "department": "Information Technology", + "courses": [ + { + "course": "Microprocessor", + "academic_term": "Semester 1" + }, + { + "course": "Probability and Statistics", + "academic_term": "Semester 1" + }, + { + "course": "Programing in Java", + "academic_term": "Semester 2" + } + ] + }, + { + "doctype": "Program", + "program_name": "Bachelor of Computer Applications", + "program_code": "BCA", + "department": "Information Technology", + "courses": [ + { + "course": "Communication Skiils", + "academic_term": "Semester 3" + }, + { + "course": "Object Oriented Programing - C++", + "academic_term": "Semester 3" + }, + { + "course": "Basic Mathematics", + "academic_term": "Semester 2" + }, + { + "course": "Data Structures and Algorithm", + "academic_term": "Semester 2" + }, + { + "course": "Digital Logic", + "academic_term": "Semester 2" + }, + { + "course": "Fundamentals of IT & Programing", + "academic_term": "Semester 1" + }, + { + "course": "Operating System", + "academic_term": "Semester 1" + }, + { + "course": "Programing in C", + "academic_term": "Semester 1" + } + ] + }, + { + "doctype": "Program", + "program_name": "Bachelor of Business Administration", + "program_code": "BBA", + "department": "Management Studies", + "courses": [ + { + "course": "Organizational Behavior", + "academic_term": "Semester 1" + }, + { + "course": "Management Development and Skills", + "academic_term": "Semester 1" + }, + { + "course": "Legal and Regulatory Framework", + "academic_term": "Semester 1" + }, + { + "course": "Human Resource Management", + "academic_term": "Semester 2" + }, + { + "course": "Entrepreneurship Management", + "academic_term": "Semester 2" + }, + { + "course": "Communication Skills", + "academic_term": "Semester 2" + }, + { + "course": "Business Environment", + "academic_term": "Semester 3" + }, + { + "course": "Advertising and Sales", + "academic_term": "Semester 3" + } + ] + } +] \ No newline at end of file diff --git a/erpnext/demo/data/random_student_data.json b/erpnext/demo/data/random_student_data.json new file mode 100644 index 00000000000..babcc715760 --- /dev/null +++ b/erpnext/demo/data/random_student_data.json @@ -0,0 +1,1604 @@ +[ +{ +"first_name": "amanda", +"last_name": "edwards", +"image": "https://randomuser.me/api/portraits/women/55.jpg", +"gender": "Female" +}, +{ +"first_name": "abbie", +"last_name": "johnston", +"image": "https://randomuser.me/api/portraits/women/46.jpg", +"gender": "Female" +}, +{ +"first_name": "heather", +"last_name": "nelson", +"image": "https://randomuser.me/api/portraits/women/13.jpg", +"gender": "Female" +}, +{ +"first_name": "maxwell", +"last_name": "gilbert", +"image": "https://randomuser.me/api/portraits/men/56.jpg", +"gender": "Male" +}, +{ +"first_name": "molly", +"last_name": "ramirez", +"image": "https://randomuser.me/api/portraits/women/71.jpg", +"gender": "Female" +}, +{ +"first_name": "ian", +"last_name": "barrett", +"image": "https://randomuser.me/api/portraits/men/68.jpg", +"gender": "Male" +}, +{ +"first_name": "kim", +"last_name": "hudson", +"image": "https://randomuser.me/api/portraits/women/53.jpg", +"gender": "Female" +}, +{ +"first_name": "bruce", +"last_name": "murray", +"image": "https://randomuser.me/api/portraits/men/59.jpg", +"gender": "Male" +}, +{ +"first_name": "henry", +"last_name": "powell", +"image": "https://randomuser.me/api/portraits/men/88.jpg", +"gender": "Male" +}, +{ +"first_name": "chris", +"last_name": "foster", +"image": "https://randomuser.me/api/portraits/men/5.jpg", +"gender": "Male" +}, +{ +"first_name": "billy", +"last_name": "kim", +"image": "https://randomuser.me/api/portraits/men/91.jpg", +"gender": "Male" +}, +{ +"first_name": "samuel", +"last_name": "harper", +"image": "https://randomuser.me/api/portraits/men/56.jpg", +"gender": "Male" +}, +{ +"first_name": "jayden", +"last_name": "kelly", +"image": "https://randomuser.me/api/portraits/men/31.jpg", +"gender": "Male" +}, +{ +"first_name": "grace", +"last_name": "berry", +"image": "https://randomuser.me/api/portraits/women/69.jpg", +"gender": "Female" +}, +{ +"first_name": "ronnie", +"last_name": "nelson", +"image": "https://randomuser.me/api/portraits/men/83.jpg", +"gender": "Male" +}, +{ +"first_name": "harvey", +"last_name": "harper", +"image": "https://randomuser.me/api/portraits/men/68.jpg", +"gender": "Male" +}, +{ +"first_name": "maya", +"last_name": "fernandez", +"image": "https://randomuser.me/api/portraits/women/79.jpg", +"gender": "Female" +}, +{ +"first_name": "faith", +"last_name": "lewis", +"image": "https://randomuser.me/api/portraits/women/84.jpg", +"gender": "Female" +}, +{ +"first_name": "kirk", +"last_name": "macrae", +"image": "https://randomuser.me/api/portraits/men/13.jpg", +"gender": "Male" +}, +{ +"first_name": "tracy", +"last_name": "holt", +"image": "https://randomuser.me/api/portraits/women/18.jpg", +"gender": "Female" +}, +{ +"first_name": "mandy", +"last_name": "dean", +"image": "https://randomuser.me/api/portraits/women/0.jpg", +"gender": "Female" +}, +{ +"first_name": "sam", +"last_name": "dunn", +"image": "https://randomuser.me/api/portraits/women/12.jpg", +"gender": "Female" +}, +{ +"first_name": "zoe", +"last_name": "fleming", +"image": "https://randomuser.me/api/portraits/women/9.jpg", +"gender": "Female" +}, +{ +"first_name": "jeffrey", +"last_name": "stewart", +"image": "https://randomuser.me/api/portraits/men/56.jpg", +"gender": "Male" +}, +{ +"first_name": "dick", +"last_name": "ryan", +"image": "https://randomuser.me/api/portraits/men/63.jpg", +"gender": "Male" +}, +{ +"first_name": "carl", +"last_name": "neal", +"image": "https://randomuser.me/api/portraits/men/41.jpg", +"gender": "Male" +}, +{ +"first_name": "scarlett", +"last_name": "ruiz", +"image": "https://randomuser.me/api/portraits/women/24.jpg", +"gender": "Female" +}, +{ +"first_name": "rene", +"last_name": "hughes", +"image": "https://randomuser.me/api/portraits/men/3.jpg", +"gender": "Male" +}, +{ +"first_name": "greg", +"last_name": "montgomery", +"image": "https://randomuser.me/api/portraits/men/12.jpg", +"gender": "Male" +}, +{ +"first_name": "matt", +"last_name": "lane", +"image": "https://randomuser.me/api/portraits/men/85.jpg", +"gender": "Male" +}, +{ +"first_name": "eleanor", +"last_name": "pearson", +"image": "https://randomuser.me/api/portraits/women/61.jpg", +"gender": "Female" +}, +{ +"first_name": "theodore", +"last_name": "burton", +"image": "https://randomuser.me/api/portraits/men/81.jpg", +"gender": "Male" +}, +{ +"first_name": "jesus", +"last_name": "hunt", +"image": "https://randomuser.me/api/portraits/men/50.jpg", +"gender": "Male" +}, +{ +"first_name": "taylor", +"last_name": "alvarez", +"image": "https://randomuser.me/api/portraits/men/0.jpg", +"gender": "Male" +}, +{ +"first_name": "barbara", +"last_name": "lucas", +"image": "https://randomuser.me/api/portraits/women/21.jpg", +"gender": "Female" +}, +{ +"first_name": "nicky", +"last_name": "simmons", +"image": "https://randomuser.me/api/portraits/women/29.jpg", +"gender": "Female" +}, +{ +"first_name": "arthur", +"last_name": "obrien", +"image": "https://randomuser.me/api/portraits/men/11.jpg", +"gender": "Male" +}, +{ +"first_name": "donna", +"last_name": "holmes", +"image": "https://randomuser.me/api/portraits/women/33.jpg", +"gender": "Female" +}, +{ +"first_name": "mitchell", +"last_name": "castro", +"image": "https://randomuser.me/api/portraits/men/26.jpg", +"gender": "Male" +}, +{ +"first_name": "byron", +"last_name": "marshall", +"image": "https://randomuser.me/api/portraits/men/57.jpg", +"gender": "Male" +}, +{ +"first_name": "larry", +"last_name": "king", +"image": "https://randomuser.me/api/portraits/men/58.jpg", +"gender": "Male" +}, +{ +"first_name": "deborah", +"last_name": "fuller", +"image": "https://randomuser.me/api/portraits/women/50.jpg", +"gender": "Female" +}, +{ +"first_name": "eleanor", +"last_name": "elliott", +"image": "https://randomuser.me/api/portraits/women/80.jpg", +"gender": "Female" +}, +{ +"first_name": "derrick", +"last_name": "shaw", +"image": "https://randomuser.me/api/portraits/men/78.jpg", +"gender": "Male" +}, +{ +"first_name": "barbara", +"last_name": "lynch", +"image": "https://randomuser.me/api/portraits/women/15.jpg", +"gender": "Female" +}, +{ +"first_name": "elijah", +"last_name": "allen", +"image": "https://randomuser.me/api/portraits/men/43.jpg", +"gender": "Male" +}, +{ +"first_name": "nicholas", +"last_name": "harper", +"image": "https://randomuser.me/api/portraits/men/2.jpg", +"gender": "Male" +}, +{ +"first_name": "sofia", +"last_name": "riley", +"image": "https://randomuser.me/api/portraits/women/96.jpg", +"gender": "Female" +}, +{ +"first_name": "jar", +"last_name": "hunt", +"image": "https://randomuser.me/api/portraits/men/72.jpg", +"gender": "Male" +}, +{ +"first_name": "philip", +"last_name": "rose", +"image": "https://randomuser.me/api/portraits/men/16.jpg", +"gender": "Male" +}, +{ +"first_name": "ella", +"last_name": "moore", +"image": "https://randomuser.me/api/portraits/women/83.jpg", +"gender": "Female" +}, +{ +"first_name": "seth", +"last_name": "tucker", +"image": "https://randomuser.me/api/portraits/men/6.jpg", +"gender": "Male" +}, +{ +"first_name": "abby", +"last_name": "gonzalez", +"image": "https://randomuser.me/api/portraits/women/18.jpg", +"gender": "Female" +}, +{ +"first_name": "noah", +"last_name": "williamson", +"image": "https://randomuser.me/api/portraits/men/54.jpg", +"gender": "Male" +}, +{ +"first_name": "cathy", +"last_name": "gray", +"image": "https://randomuser.me/api/portraits/women/88.jpg", +"gender": "Female" +}, +{ +"first_name": "barb", +"last_name": "snyder", +"image": "https://randomuser.me/api/portraits/women/49.jpg", +"gender": "Female" +}, +{ +"first_name": "rosalyn", +"last_name": "hale", +"image": "https://randomuser.me/api/portraits/women/64.jpg", +"gender": "Female" +}, +{ +"first_name": "jessica", +"last_name": "armstrong", +"image": "https://randomuser.me/api/portraits/women/95.jpg", +"gender": "Female" +}, +{ +"first_name": "vicki", +"last_name": "wheeler", +"image": "https://randomuser.me/api/portraits/women/49.jpg", +"gender": "Female" +}, +{ +"first_name": "luke", +"last_name": "fisher", +"image": "https://randomuser.me/api/portraits/men/77.jpg", +"gender": "Male" +}, +{ +"first_name": "joey", +"last_name": "wheeler", +"image": "https://randomuser.me/api/portraits/men/50.jpg", +"gender": "Male" +}, +{ +"first_name": "victoria", +"last_name": "jimenez", +"image": "https://randomuser.me/api/portraits/women/25.jpg", +"gender": "Female" +}, +{ +"first_name": "daryl", +"last_name": "patterson", +"image": "https://randomuser.me/api/portraits/men/30.jpg", +"gender": "Male" +}, +{ +"first_name": "dwayne", +"last_name": "jensen", +"image": "https://randomuser.me/api/portraits/men/71.jpg", +"gender": "Male" +}, +{ +"first_name": "herbert", +"last_name": "silva", +"image": "https://randomuser.me/api/portraits/men/83.jpg", +"gender": "Male" +}, +{ +"first_name": "walter", +"last_name": "walker", +"image": "https://randomuser.me/api/portraits/men/91.jpg", +"gender": "Male" +}, +{ +"first_name": "logan", +"last_name": "banks", +"image": "https://randomuser.me/api/portraits/men/67.jpg", +"gender": "Male" +}, +{ +"first_name": "shawn", +"last_name": "harvey", +"image": "https://randomuser.me/api/portraits/men/87.jpg", +"gender": "Male" +}, +{ +"first_name": "lawrence", +"last_name": "bradley", +"image": "https://randomuser.me/api/portraits/men/40.jpg", +"gender": "Male" +}, +{ +"first_name": "jack", +"last_name": "fleming", +"image": "https://randomuser.me/api/portraits/men/37.jpg", +"gender": "Male" +}, +{ +"first_name": "jackson", +"last_name": "boyd", +"image": "https://randomuser.me/api/portraits/men/68.jpg", +"gender": "Male" +}, +{ +"first_name": "cecil", +"last_name": "webb", +"image": "https://randomuser.me/api/portraits/men/9.jpg", +"gender": "Male" +}, +{ +"first_name": "eliza", +"last_name": "mills", +"image": "https://randomuser.me/api/portraits/women/20.jpg", +"gender": "Female" +}, +{ +"first_name": "jenny", +"last_name": "frazier", +"image": "https://randomuser.me/api/portraits/women/61.jpg", +"gender": "Female" +}, +{ +"first_name": "kent", +"last_name": "butler", +"image": "https://randomuser.me/api/portraits/men/64.jpg", +"gender": "Male" +}, +{ +"first_name": "rose", +"last_name": "perry", +"image": "https://randomuser.me/api/portraits/women/74.jpg", +"gender": "Female" +}, +{ +"first_name": "jack", +"last_name": "king", +"image": "https://randomuser.me/api/portraits/men/60.jpg", +"gender": "Male" +}, +{ +"first_name": "elmer", +"last_name": "williams", +"image": "https://randomuser.me/api/portraits/men/26.jpg", +"gender": "Male" +}, +{ +"first_name": "vanessa", +"last_name": "torres", +"image": "https://randomuser.me/api/portraits/women/41.jpg", +"gender": "Female" +}, +{ +"first_name": "tyrone", +"last_name": "coleman", +"image": "https://randomuser.me/api/portraits/men/59.jpg", +"gender": "Male" +}, +{ +"first_name": "julie", +"last_name": "bradley", +"image": "https://randomuser.me/api/portraits/women/50.jpg", +"gender": "Female" +}, +{ +"first_name": "fernando", +"last_name": "castro", +"image": "https://randomuser.me/api/portraits/men/44.jpg", +"gender": "Male" +}, +{ +"first_name": "sara", +"last_name": "craig", +"image": "https://randomuser.me/api/portraits/women/8.jpg", +"gender": "Female" +}, +{ +"first_name": "steven", +"last_name": "stone", +"image": "https://randomuser.me/api/portraits/men/47.jpg", +"gender": "Male" +}, +{ +"first_name": "barb", +"last_name": "rodriquez", +"image": "https://randomuser.me/api/portraits/women/73.jpg", +"gender": "Female" +}, +{ +"first_name": "charlie", +"last_name": "king", +"image": "https://randomuser.me/api/portraits/men/79.jpg", +"gender": "Male" +}, +{ +"first_name": "jessica", +"last_name": "davis", +"image": "https://randomuser.me/api/portraits/women/26.jpg", +"gender": "Female" +}, +{ +"first_name": "lewis", +"last_name": "watson", +"image": "https://randomuser.me/api/portraits/men/56.jpg", +"gender": "Male" +}, +{ +"first_name": "charlotte", +"last_name": "johnson", +"image": "https://randomuser.me/api/portraits/women/46.jpg", +"gender": "Female" +}, +{ +"first_name": "danielle", +"last_name": "bell", +"image": "https://randomuser.me/api/portraits/women/54.jpg", +"gender": "Female" +}, +{ +"first_name": "kristin", +"last_name": "dixon", +"image": "https://randomuser.me/api/portraits/women/23.jpg", +"gender": "Female" +}, +{ +"first_name": "andrea", +"last_name": "thompson", +"image": "https://randomuser.me/api/portraits/women/54.jpg", +"gender": "Female" +}, +{ +"first_name": "ashley", +"last_name": "andrews", +"image": "https://randomuser.me/api/portraits/women/46.jpg", +"gender": "Female" +}, +{ +"first_name": "sharon", +"last_name": "martinez", +"image": "https://randomuser.me/api/portraits/women/6.jpg", +"gender": "Female" +}, +{ +"first_name": "tristan", +"last_name": "cunningham", +"image": "https://randomuser.me/api/portraits/men/62.jpg", +"gender": "Male" +}, +{ +"first_name": "carol", +"last_name": "chavez", +"image": "https://randomuser.me/api/portraits/women/85.jpg", +"gender": "Female" +}, +{ +"first_name": "lauren", +"last_name": "hudson", +"image": "https://randomuser.me/api/portraits/women/88.jpg", +"gender": "Female" +}, +{ +"first_name": "guy", +"last_name": "robertson", +"image": "https://randomuser.me/api/portraits/men/78.jpg", +"gender": "Male" +}, +{ +"first_name": "debra", +"last_name": "long", +"image": "https://randomuser.me/api/portraits/women/23.jpg", +"gender": "Female" +}, +{ +"first_name": "taylor", +"last_name": "carpenter", +"image": "https://randomuser.me/api/portraits/men/0.jpg", +"gender": "Male" +}, +{ +"first_name": "eetu", +"last_name": "annala", +"image": "https://randomuser.me/api/portraits/men/31.jpg", +"gender": "Male" +}, +{ +"first_name": "oliver", +"last_name": "moilanen", +"image": "https://randomuser.me/api/portraits/men/14.jpg", +"gender": "Male" +}, +{ +"first_name": "leo", +"last_name": "maunu", +"image": "https://randomuser.me/api/portraits/men/72.jpg", +"gender": "Male" +}, +{ +"first_name": "iiris", +"last_name": "kalas", +"image": "https://randomuser.me/api/portraits/women/49.jpg", +"gender": "Female" +}, +{ +"first_name": "aada", +"last_name": "kinnunen", +"image": "https://randomuser.me/api/portraits/women/64.jpg", +"gender": "Female" +}, +{ +"first_name": "topias", +"last_name": "walli", +"image": "https://randomuser.me/api/portraits/men/58.jpg", +"gender": "Male" +}, +{ +"first_name": "viivi", +"last_name": "toivonen", +"image": "https://randomuser.me/api/portraits/women/16.jpg", +"gender": "Female" +}, +{ +"first_name": "iina", +"last_name": "makinen", +"image": "https://randomuser.me/api/portraits/women/44.jpg", +"gender": "Female" +}, +{ +"first_name": "lumi", +"last_name": "tuominen", +"image": "https://randomuser.me/api/portraits/women/11.jpg", +"gender": "Female" +}, +{ +"first_name": "ellen", +"last_name": "koski", +"image": "https://randomuser.me/api/portraits/women/22.jpg", +"gender": "Female" +}, +{ +"first_name": "onni", +"last_name": "laurila", +"image": "https://randomuser.me/api/portraits/men/74.jpg", +"gender": "Male" +}, +{ +"first_name": "eevi", +"last_name": "niskanen", +"image": "https://randomuser.me/api/portraits/women/72.jpg", +"gender": "Female" +}, +{ +"first_name": "julius", +"last_name": "maijala", +"image": "https://randomuser.me/api/portraits/men/8.jpg", +"gender": "Male" +}, +{ +"first_name": "sofia", +"last_name": "tuomi", +"image": "https://randomuser.me/api/portraits/women/1.jpg", +"gender": "Female" +}, +{ +"first_name": "oliver", +"last_name": "jarvela", +"image": "https://randomuser.me/api/portraits/men/60.jpg", +"gender": "Male" +}, +{ +"first_name": "luukas", +"last_name": "mikkola", +"image": "https://randomuser.me/api/portraits/men/90.jpg", +"gender": "Male" +}, +{ +"first_name": "amanda", +"last_name": "anttila", +"image": "https://randomuser.me/api/portraits/women/65.jpg", +"gender": "Female" +}, +{ +"first_name": "ella", +"last_name": "sakala", +"image": "https://randomuser.me/api/portraits/women/79.jpg", +"gender": "Female" +}, +{ +"first_name": "siiri", +"last_name": "kinnunen", +"image": "https://randomuser.me/api/portraits/women/37.jpg", +"gender": "Female" +}, +{ +"first_name": "joona", +"last_name": "korhonen", +"image": "https://randomuser.me/api/portraits/men/87.jpg", +"gender": "Male" +}, +{ +"first_name": "topias", +"last_name": "korpi", +"image": "https://randomuser.me/api/portraits/men/75.jpg", +"gender": "Male" +}, +{ +"first_name": "mikael", +"last_name": "remes", +"image": "https://randomuser.me/api/portraits/men/89.jpg", +"gender": "Male" +}, +{ +"first_name": "veera", +"last_name": "peltola", +"image": "https://randomuser.me/api/portraits/women/69.jpg", +"gender": "Female" +}, +{ +"first_name": "emil", +"last_name": "makela", +"image": "https://randomuser.me/api/portraits/men/98.jpg", +"gender": "Male" +}, +{ +"first_name": "luukas", +"last_name": "kujala", +"image": "https://randomuser.me/api/portraits/men/83.jpg", +"gender": "Male" +}, +{ +"first_name": "eemil", +"last_name": "honkala", +"image": "https://randomuser.me/api/portraits/men/85.jpg", +"gender": "Male" +}, +{ +"first_name": "peetu", +"last_name": "kalm", +"image": "https://randomuser.me/api/portraits/men/17.jpg", +"gender": "Male" +}, +{ +"first_name": "eemeli", +"last_name": "lehtonen", +"image": "https://randomuser.me/api/portraits/men/55.jpg", +"gender": "Male" +}, +{ +"first_name": "viivi", +"last_name": "koistinen", +"image": "https://randomuser.me/api/portraits/women/53.jpg", +"gender": "Female" +}, +{ +"first_name": "elli", +"last_name": "savela", +"image": "https://randomuser.me/api/portraits/women/77.jpg", +"gender": "Female" +}, +{ +"first_name": "venla", +"last_name": "walli", +"image": "https://randomuser.me/api/portraits/women/52.jpg", +"gender": "Female" +}, +{ +"first_name": "amanda", +"last_name": "wuollet", +"image": "https://randomuser.me/api/portraits/women/11.jpg", +"gender": "Female" +}, +{ +"first_name": "valtteri", +"last_name": "hokkanen", +"image": "https://randomuser.me/api/portraits/men/30.jpg", +"gender": "Male" +}, +{ +"first_name": "veera", +"last_name": "maki", +"image": "https://randomuser.me/api/portraits/women/34.jpg", +"gender": "Female" +}, +{ +"first_name": "kerttu", +"last_name": "maunu", +"image": "https://randomuser.me/api/portraits/women/1.jpg", +"gender": "Female" +}, +{ +"first_name": "nella", +"last_name": "hanka", +"image": "https://randomuser.me/api/portraits/women/70.jpg", +"gender": "Female" +}, +{ +"first_name": "iiris", +"last_name": "hakala", +"image": "https://randomuser.me/api/portraits/women/33.jpg", +"gender": "Female" +}, +{ +"first_name": "viivi", +"last_name": "ojala", +"image": "https://randomuser.me/api/portraits/women/69.jpg", +"gender": "Female" +}, +{ +"first_name": "iina", +"last_name": "peura", +"image": "https://randomuser.me/api/portraits/women/22.jpg", +"gender": "Female" +}, +{ +"first_name": "samuel", +"last_name": "mattila", +"image": "https://randomuser.me/api/portraits/men/88.jpg", +"gender": "Male" +}, +{ +"first_name": "julius", +"last_name": "kumpula", +"image": "https://randomuser.me/api/portraits/men/26.jpg", +"gender": "Male" +}, +{ +"first_name": "nooa", +"last_name": "haapala", +"image": "https://randomuser.me/api/portraits/men/77.jpg", +"gender": "Male" +}, +{ +"first_name": "elias", +"last_name": "leppo", +"image": "https://randomuser.me/api/portraits/men/50.jpg", +"gender": "Male" +}, +{ +"first_name": "niklas", +"last_name": "elo", +"image": "https://randomuser.me/api/portraits/men/64.jpg", +"gender": "Male" +}, +{ +"first_name": "olivia", +"last_name": "nurmi", +"image": "https://randomuser.me/api/portraits/women/82.jpg", +"gender": "Female" +}, +{ +"first_name": "milja", +"last_name": "lassila", +"image": "https://randomuser.me/api/portraits/women/47.jpg", +"gender": "Female" +}, +{ +"first_name": "daniel", +"last_name": "kalas", +"image": "https://randomuser.me/api/portraits/men/53.jpg", +"gender": "Male" +}, +{ +"first_name": "enni", +"last_name": "ramo", +"image": "https://randomuser.me/api/portraits/women/18.jpg", +"gender": "Female" +}, +{ +"first_name": "matilda", +"last_name": "salmi", +"image": "https://randomuser.me/api/portraits/women/84.jpg", +"gender": "Female" +}, +{ +"first_name": "valtteri", +"last_name": "wirta", +"image": "https://randomuser.me/api/portraits/men/26.jpg", +"gender": "Male" +}, +{ +"first_name": "julius", +"last_name": "maijala", +"image": "https://randomuser.me/api/portraits/men/39.jpg", +"gender": "Male" +}, +{ +"first_name": "kerttu", +"last_name": "peltola", +"image": "https://randomuser.me/api/portraits/women/39.jpg", +"gender": "Female" +}, +{ +"first_name": "aada", +"last_name": "kokko", +"image": "https://randomuser.me/api/portraits/women/26.jpg", +"gender": "Female" +}, +{ +"first_name": "elsa", +"last_name": "niska", +"image": "https://randomuser.me/api/portraits/women/26.jpg", +"gender": "Female" +}, +{ +"first_name": "ella", +"last_name": "kalm", +"image": "https://randomuser.me/api/portraits/women/61.jpg", +"gender": "Female" +}, +{ +"first_name": "lilja", +"last_name": "heinonen", +"image": "https://randomuser.me/api/portraits/women/65.jpg", +"gender": "Female" +}, +{ +"first_name": "akseli", +"last_name": "laakso", +"image": "https://randomuser.me/api/portraits/men/64.jpg", +"gender": "Male" +}, +{ +"first_name": "lotta", +"last_name": "saarela", +"image": "https://randomuser.me/api/portraits/women/69.jpg", +"gender": "Female" +}, +{ +"first_name": "leo", +"last_name": "polon", +"image": "https://randomuser.me/api/portraits/men/5.jpg", +"gender": "Male" +}, +{ +"first_name": "aleksi", +"last_name": "wuollet", +"image": "https://randomuser.me/api/portraits/men/87.jpg", +"gender": "Male" +}, +{ +"first_name": "eemil", +"last_name": "kalas", +"image": "https://randomuser.me/api/portraits/men/6.jpg", +"gender": "Male" +}, +{ +"first_name": "emmi", +"last_name": "koistinen", +"image": "https://randomuser.me/api/portraits/women/66.jpg", +"gender": "Female" +}, +{ +"first_name": "väinö", +"last_name": "halla", +"image": "https://randomuser.me/api/portraits/men/65.jpg", +"gender": "Male" +}, +{ +"first_name": "eemil", +"last_name": "heikkila", +"image": "https://randomuser.me/api/portraits/men/18.jpg", +"gender": "Male" +}, +{ +"first_name": "amanda", +"last_name": "lakso", +"image": "https://randomuser.me/api/portraits/women/29.jpg", +"gender": "Female" +}, +{ +"first_name": "vilho", +"last_name": "kivela", +"image": "https://randomuser.me/api/portraits/men/19.jpg", +"gender": "Male" +}, +{ +"first_name": "peppi", +"last_name": "lehtinen", +"image": "https://randomuser.me/api/portraits/women/80.jpg", +"gender": "Female" +}, +{ +"first_name": "onni", +"last_name": "lehtinen", +"image": "https://randomuser.me/api/portraits/men/0.jpg", +"gender": "Male" +}, +{ +"first_name": "onni", +"last_name": "ahonen", +"image": "https://randomuser.me/api/portraits/men/49.jpg", +"gender": "Male" +}, +{ +"first_name": "venla", +"last_name": "ranta", +"image": "https://randomuser.me/api/portraits/women/0.jpg", +"gender": "Female" +}, +{ +"first_name": "ronja", +"last_name": "korhonen", +"image": "https://randomuser.me/api/portraits/women/69.jpg", +"gender": "Female" +}, +{ +"first_name": "emmi", +"last_name": "niva", +"image": "https://randomuser.me/api/portraits/women/65.jpg", +"gender": "Female" +}, +{ +"first_name": "oskari", +"last_name": "leppanen", +"image": "https://randomuser.me/api/portraits/men/43.jpg", +"gender": "Male" +}, +{ +"first_name": "arttu", +"last_name": "heinonen", +"image": "https://randomuser.me/api/portraits/men/94.jpg", +"gender": "Male" +}, +{ +"first_name": "toivo", +"last_name": "makela", +"image": "https://randomuser.me/api/portraits/men/23.jpg", +"gender": "Male" +}, +{ +"first_name": "otto", +"last_name": "leino", +"image": "https://randomuser.me/api/portraits/men/51.jpg", +"gender": "Male" +}, +{ +"first_name": "milla", +"last_name": "kokko", +"image": "https://randomuser.me/api/portraits/women/66.jpg", +"gender": "Female" +}, +{ +"first_name": "konsta", +"last_name": "lehto", +"image": "https://randomuser.me/api/portraits/men/29.jpg", +"gender": "Male" +}, +{ +"first_name": "eeli", +"last_name": "heikkinen", +"image": "https://randomuser.me/api/portraits/men/50.jpg", +"gender": "Male" +}, +{ +"first_name": "matilda", +"last_name": "tanner", +"image": "https://randomuser.me/api/portraits/women/2.jpg", +"gender": "Female" +}, +{ +"first_name": "elias", +"last_name": "kivisto", +"image": "https://randomuser.me/api/portraits/men/40.jpg", +"gender": "Male" +}, +{ +"first_name": "akseli", +"last_name": "wirta", +"image": "https://randomuser.me/api/portraits/men/90.jpg", +"gender": "Male" +}, +{ +"first_name": "leevi", +"last_name": "kallio", +"image": "https://randomuser.me/api/portraits/men/89.jpg", +"gender": "Male" +}, +{ +"first_name": "emilia", +"last_name": "pelto", +"image": "https://randomuser.me/api/portraits/women/0.jpg", +"gender": "Female" +}, +{ +"first_name": "niilo", +"last_name": "keranen", +"image": "https://randomuser.me/api/portraits/men/29.jpg", +"gender": "Male" +}, +{ +"first_name": "mikael", +"last_name": "wainio", +"image": "https://randomuser.me/api/portraits/men/85.jpg", +"gender": "Male" +}, +{ +"first_name": "elias", +"last_name": "saksa", +"image": "https://randomuser.me/api/portraits/men/53.jpg", +"gender": "Male" +}, +{ +"first_name": "aatu", +"last_name": "erkkila", +"image": "https://randomuser.me/api/portraits/men/6.jpg", +"gender": "Male" +}, +{ +"first_name": "arttu", +"last_name": "jarvela", +"image": "https://randomuser.me/api/portraits/men/49.jpg", +"gender": "Male" +}, +{ +"first_name": "matilda", +"last_name": "lassila", +"image": "https://randomuser.me/api/portraits/women/46.jpg", +"gender": "Female" +}, +{ +"first_name": "alisa", +"last_name": "waara", +"image": "https://randomuser.me/api/portraits/women/67.jpg", +"gender": "Female" +}, +{ +"first_name": "emilia", +"last_name": "saksa", +"image": "https://randomuser.me/api/portraits/women/66.jpg", +"gender": "Female" +}, +{ +"first_name": "valtteri", +"last_name": "tikkanen", +"image": "https://randomuser.me/api/portraits/men/88.jpg", +"gender": "Male" +}, +{ +"first_name": "konsta", +"last_name": "rantala", +"image": "https://randomuser.me/api/portraits/men/50.jpg", +"gender": "Male" +}, +{ +"first_name": "minttu", +"last_name": "murto", +"image": "https://randomuser.me/api/portraits/women/14.jpg", +"gender": "Female" +}, +{ +"first_name": "vilma", +"last_name": "hatala", +"image": "https://randomuser.me/api/portraits/women/60.jpg", +"gender": "Female" +}, +{ +"first_name": "anni", +"last_name": "linna", +"image": "https://randomuser.me/api/portraits/women/59.jpg", +"gender": "Female" +}, +{ +"first_name": "niklas", +"last_name": "hautala", +"image": "https://randomuser.me/api/portraits/men/7.jpg", +"gender": "Male" +}, +{ +"first_name": "niilo", +"last_name": "lehtinen", +"image": "https://randomuser.me/api/portraits/men/54.jpg", +"gender": "Male" +}, +{ +"first_name": "oona", +"last_name": "saarinen", +"image": "https://randomuser.me/api/portraits/women/71.jpg", +"gender": "Female" +}, +{ +"first_name": "constance", +"last_name": "marie", +"image": "https://randomuser.me/api/portraits/women/40.jpg", +"gender": "Female" +}, +{ +"first_name": "charles", +"last_name": "pierre", +"image": "https://randomuser.me/api/portraits/men/96.jpg", +"gender": "Male" +}, +{ +"first_name": "bérénice", +"last_name": "leclerc", +"image": "https://randomuser.me/api/portraits/women/39.jpg", +"gender": "Female" +}, +{ +"first_name": "clémence", +"last_name": "arnaud", +"image": "https://randomuser.me/api/portraits/women/48.jpg", +"gender": "Female" +}, +{ +"first_name": "melvin", +"last_name": "lemoine", +"image": "https://randomuser.me/api/portraits/men/47.jpg", +"gender": "Male" +}, +{ +"first_name": "marceau", +"last_name": "joly", +"image": "https://randomuser.me/api/portraits/men/56.jpg", +"gender": "Male" +}, +{ +"first_name": "garance", +"last_name": "mathieu", +"image": "https://randomuser.me/api/portraits/women/87.jpg", +"gender": "Female" +}, +{ +"first_name": "angèle", +"last_name": "perrin", +"image": "https://randomuser.me/api/portraits/women/88.jpg", +"gender": "Female" +}, +{ +"first_name": "pauline", +"last_name": "simon", +"image": "https://randomuser.me/api/portraits/women/82.jpg", +"gender": "Female" +}, +{ +"first_name": "apolline", +"last_name": "laurent", +"image": "https://randomuser.me/api/portraits/women/27.jpg", +"gender": "Female" +}, +{ +"first_name": "luca", +"last_name": "lefevre", +"image": "https://randomuser.me/api/portraits/men/40.jpg", +"gender": "Male" +}, +{ +"first_name": "bastien", +"last_name": "roger", +"image": "https://randomuser.me/api/portraits/men/73.jpg", +"gender": "Male" +}, +{ +"first_name": "marie", +"last_name": "rodriguez", +"image": "https://randomuser.me/api/portraits/women/18.jpg", +"gender": "Female" +}, +{ +"first_name": "tristan", +"last_name": "renaud", +"image": "https://randomuser.me/api/portraits/men/41.jpg", +"gender": "Male" +}, +{ +"first_name": "eva", +"last_name": "philippe", +"image": "https://randomuser.me/api/portraits/women/26.jpg", +"gender": "Female" +}, +{ +"first_name": "coline", +"last_name": "dufour", +"image": "https://randomuser.me/api/portraits/women/64.jpg", +"gender": "Female" +}, +{ +"first_name": "marilou", +"last_name": "adam", +"image": "https://randomuser.me/api/portraits/women/53.jpg", +"gender": "Female" +}, +{ +"first_name": "lia", +"last_name": "renard", +"image": "https://randomuser.me/api/portraits/women/88.jpg", +"gender": "Female" +}, +{ +"first_name": "timothee", +"last_name": "rolland", +"image": "https://randomuser.me/api/portraits/men/75.jpg", +"gender": "Male" +}, +{ +"first_name": "hélèna", +"last_name": "boyer", +"image": "https://randomuser.me/api/portraits/women/8.jpg", +"gender": "Female" +}, +{ +"first_name": "mélody", +"last_name": "andre", +"image": "https://randomuser.me/api/portraits/women/75.jpg", +"gender": "Female" +}, +{ +"first_name": "jeanne", +"last_name": "duval", +"image": "https://randomuser.me/api/portraits/women/44.jpg", +"gender": "Female" +}, +{ +"first_name": "elias", +"last_name": "dupont", +"image": "https://randomuser.me/api/portraits/men/60.jpg", +"gender": "Male" +}, +{ +"first_name": "estelle", +"last_name": "bernard", +"image": "https://randomuser.me/api/portraits/women/23.jpg", +"gender": "Female" +}, +{ +"first_name": "roxane", +"last_name": "garnier", +"image": "https://randomuser.me/api/portraits/women/14.jpg", +"gender": "Female" +}, +{ +"first_name": "maëva", +"last_name": "guerin", +"image": "https://randomuser.me/api/portraits/women/44.jpg", +"gender": "Female" +}, +{ +"first_name": "liam", +"last_name": "carpentier", +"image": "https://randomuser.me/api/portraits/men/41.jpg", +"gender": "Male" +}, +{ +"first_name": "théo", +"last_name": "gaillard", +"image": "https://randomuser.me/api/portraits/men/40.jpg", +"gender": "Male" +}, +{ +"first_name": "angelina", +"last_name": "clement", +"image": "https://randomuser.me/api/portraits/women/53.jpg", +"gender": "Female" +}, +{ +"first_name": "emma", +"last_name": "bertrand", +"image": "https://randomuser.me/api/portraits/women/86.jpg", +"gender": "Female" +}, +{ +"first_name": "charles", +"last_name": "rolland", +"image": "https://randomuser.me/api/portraits/men/14.jpg", +"gender": "Male" +}, +{ +"first_name": "nolan", +"last_name": "gautier", +"image": "https://randomuser.me/api/portraits/men/6.jpg", +"gender": "Male" +}, +{ +"first_name": "agathe", +"last_name": "menard", +"image": "https://randomuser.me/api/portraits/women/69.jpg", +"gender": "Female" +}, +{ +"first_name": "gaëtan", +"last_name": "leclerc", +"image": "https://randomuser.me/api/portraits/men/60.jpg", +"gender": "Male" +}, +{ +"first_name": "clarisse", +"last_name": "lemaire", +"image": "https://randomuser.me/api/portraits/women/21.jpg", +"gender": "Female" +}, +{ +"first_name": "samuel", +"last_name": "garnier", +"image": "https://randomuser.me/api/portraits/men/16.jpg", +"gender": "Male" +}, +{ +"first_name": "eden", +"last_name": "fontai", +"image": "https://randomuser.me/api/portraits/women/17.jpg", +"gender": "Female" +}, +{ +"first_name": "maëva", +"last_name": "pierre", +"image": "https://randomuser.me/api/portraits/women/19.jpg", +"gender": "Female" +}, +{ +"first_name": "thomas", +"last_name": "barbier", +"image": "https://randomuser.me/api/portraits/men/31.jpg", +"gender": "Male" +}, +{ +"first_name": "lily", +"last_name": "lefebvre", +"image": "https://randomuser.me/api/portraits/women/76.jpg", +"gender": "Female" +}, +{ +"first_name": "lise", +"last_name": "perez", +"image": "https://randomuser.me/api/portraits/women/74.jpg", +"gender": "Female" +}, +{ +"first_name": "mila", +"last_name": "moulin", +"image": "https://randomuser.me/api/portraits/women/43.jpg", +"gender": "Female" +}, +{ +"first_name": "dylan", +"last_name": "picard", +"image": "https://randomuser.me/api/portraits/men/37.jpg", +"gender": "Male" +}, +{ +"first_name": "amandine", +"last_name": "rodriguez", +"image": "https://randomuser.me/api/portraits/women/65.jpg", +"gender": "Female" +}, +{ +"first_name": "diego", +"last_name": "girard", +"image": "https://randomuser.me/api/portraits/men/84.jpg", +"gender": "Male" +}, +{ +"first_name": "elouan", +"last_name": "garnier", +"image": "https://randomuser.me/api/portraits/men/94.jpg", +"gender": "Male" +}, +{ +"first_name": "apolline", +"last_name": "fleury", +"image": "https://randomuser.me/api/portraits/women/65.jpg", +"gender": "Female" +}, +{ +"first_name": "coline", +"last_name": "menard", +"image": "https://randomuser.me/api/portraits/women/83.jpg", +"gender": "Female" +}, +{ +"first_name": "maëly", +"last_name": "le gall", +"image": "https://randomuser.me/api/portraits/women/60.jpg", +"gender": "Female" +}, +{ +"first_name": "justin", +"last_name": "robert", +"image": "https://randomuser.me/api/portraits/men/20.jpg", +"gender": "Male" +}, +{ +"first_name": "ryan", +"last_name": "faure", +"image": "https://randomuser.me/api/portraits/men/16.jpg", +"gender": "Male" +}, +{ +"first_name": "ninon", +"last_name": "brunet", +"image": "https://randomuser.me/api/portraits/women/68.jpg", +"gender": "Female" +}, +{ +"first_name": "tessa", +"last_name": "garnier", +"image": "https://randomuser.me/api/portraits/women/54.jpg", +"gender": "Female" +}, +{ +"first_name": "ryan", +"last_name": "bonnet", +"image": "https://randomuser.me/api/portraits/men/28.jpg", +"gender": "Male" +}, +{ +"first_name": "aurélien", +"last_name": "andre", +"image": "https://randomuser.me/api/portraits/men/29.jpg", +"gender": "Male" +}, +{ +"first_name": "clément", +"last_name": "dumas", +"image": "https://randomuser.me/api/portraits/men/10.jpg", +"gender": "Male" +}, +{ +"first_name": "alexis", +"last_name": "fournier", +"image": "https://randomuser.me/api/portraits/men/83.jpg", +"gender": "Male" +}, +{ +"first_name": "valentin", +"last_name": "lecomte", +"image": "https://randomuser.me/api/portraits/men/44.jpg", +"gender": "Male" +}, +{ +"first_name": "florian", +"last_name": "olivier", +"image": "https://randomuser.me/api/portraits/men/36.jpg", +"gender": "Male" +}, +{ +"first_name": "ewen", +"last_name": "lefebvre", +"image": "https://randomuser.me/api/portraits/men/32.jpg", +"gender": "Male" +}, +{ +"first_name": "titouan", +"last_name": "charles", +"image": "https://randomuser.me/api/portraits/men/59.jpg", +"gender": "Male" +}, +{ +"first_name": "lila", +"last_name": "aubert", +"image": "https://randomuser.me/api/portraits/women/6.jpg", +"gender": "Female" +}, +{ +"first_name": "charline", +"last_name": "caron", +"image": "https://randomuser.me/api/portraits/women/49.jpg", +"gender": "Female" +}, +{ +"first_name": "soren", +"last_name": "le gall", +"image": "https://randomuser.me/api/portraits/men/77.jpg", +"gender": "Male" +}, +{ +"first_name": "fanny", +"last_name": "louis", +"image": "https://randomuser.me/api/portraits/women/90.jpg", +"gender": "Female" +}, +{ +"first_name": "julie", +"last_name": "adam", +"image": "https://randomuser.me/api/portraits/women/34.jpg", +"gender": "Female" +}, +{ +"first_name": "louka", +"last_name": "boyer", +"image": "https://randomuser.me/api/portraits/men/98.jpg", +"gender": "Male" +} +] diff --git a/erpnext/demo/data/room.json b/erpnext/demo/data/room.json new file mode 100644 index 00000000000..82f0868b5a0 --- /dev/null +++ b/erpnext/demo/data/room.json @@ -0,0 +1,122 @@ +[ + { + "doctype": "Room", + "room_name": "Lecture Hall 1", + "room_number": "101", + "seating_capacity": 80 + }, + { + "doctype": "Room", + "room_name": "Lecture Hall 2", + "room_number": "102", + "seating_capacity": 80 + }, + { + "doctype": "Room", + "room_name": "Lecture Hall 3", + "room_number": "103", + "seating_capacity": 80 + }, + { + "doctype": "Room", + "room_name": "Lecture Hall 4", + "room_number": "104", + "seating_capacity": 80 + }, + { + "doctype": "Room", + "room_name": "Lecture Hall 4", + "room_number": "104", + "seating_capacity": 80 + }, + { + "doctype": "Room", + "room_name": "Lecture Hall 5", + "room_number": "201", + "seating_capacity": 120 + }, + { + "doctype": "Room", + "room_name": "Lecture Hall 6", + "room_number": "202", + "seating_capacity": 120 + }, + { + "doctype": "Room", + "room_name": "Lecture Hall 7", + "room_number": "203", + "seating_capacity": 120 + }, + { + "doctype": "Room", + "room_name": "Computer Lab 1", + "room_number": "301", + "seating_capacity": 40 + }, + { + "doctype": "Room", + "room_name": "Computer Lab 2", + "room_number": "302", + "seating_capacity": 60 + }, + { + "doctype": "Room", + "room_name": "Seminar Hall 1", + "room_number": "303", + "seating_capacity": 240 + }, + { + "doctype": "Room", + "room_name": "Auditorium", + "room_number": "400", + "seating_capacity": 450 + }, + { + "doctype": "Room", + "room_name": "Exam hall 1", + "room_number": "560", + "seating_capacity": 70 + }, + { + "doctype": "Room", + "room_name": "Exam hall 2", + "room_number": "561", + "seating_capacity": 70 + }, + { + "doctype": "Room", + "room_name": "Exam hall 2", + "room_number": "562", + "seating_capacity": 70 + }, + { + "doctype": "Room", + "room_name": "Exam hall 3", + "room_number": "563", + "seating_capacity": 70 + }, + { + "doctype": "Room", + "room_name": "Exam hall 4", + "room_number": "564", + "seating_capacity": 70 + }, + { + "doctype": "Room", + "room_name": "Exam hall 5", + "room_number": "565", + "seating_capacity": 70 + }, + { + "doctype": "Room", + "room_name": "Exam hall 6", + "room_number": "566", + "seating_capacity": 70 + }, + { + "doctype": "Room", + "room_name": "Exam hall 7", + "room_number": "567", + "seating_capacity": 70 + } +] \ No newline at end of file diff --git a/erpnext/demo/data/user.json b/erpnext/demo/data/user.json index e353efb6735..811e8afa525 100644 --- a/erpnext/demo/data/user.json +++ b/erpnext/demo/data/user.json @@ -26,8 +26,8 @@ }, { "email": "aromn@example.com", - "first_name": "\u0414\u043c\u0438\u0442\u0440\u0438\u0439", - "last_name": "\u041f\u0438\u0440\u043e\u0433\u043e\u0432" + "first_name": "Arom", + "last_name": "Nolan" }, { "email": "TildeLindqvist@example.com", diff --git a/erpnext/demo/demo.py b/erpnext/demo/demo.py index d1f498280f5..180ddfac804 100644 --- a/erpnext/demo/demo.py +++ b/erpnext/demo/demo.py @@ -3,9 +3,8 @@ 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, purchase, manufacturing, stock, accounts, projects, fixed_asset - +from erpnext.demo.user import hr, sales, purchase, manufacturing, stock, accounts, projects, fixed_asset, schools +from erpnext.demo.setup import education, manufacture, setup_data """ Make a demo @@ -26,14 +25,19 @@ bench --site demo.erpnext.dev execute erpnext.demo.demo.simulate def make(domain='Manufacturing'): frappe.flags.domain = domain frappe.flags.mute_emails = True - setup_data() + setup_data.setup(domain) + if domain== 'Manufacturing': + manufacture.setup_data() + elif domain== 'Education': + education.setup_data() + site = frappe.local.site frappe.destroy() frappe.init(site) frappe.connect() - simulate() + simulate(domain) -def simulate(): +def simulate(domain='Manufacturing'): runs_for = frappe.flags.runs_for or 150 frappe.flags.company = erpnext.get_default_company() frappe.flags.mute_emails = True @@ -47,33 +51,38 @@ def simulate(): # 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) - + current_date = frappe.utils.add_days(frappe.utils.getdate(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 fixed_asset.work() - 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() - purchase.work() - manufacturing.work() - stock.work() - accounts.work() - projects.run_projects(current_date) - # run_messages() - - current_date = frappe.utils.add_days(current_date, 1) - - frappe.db.commit() + try: + hr.work() + purchase.work() + stock.work() + accounts.work() + projects.run_projects(current_date) + #run_messages() + + if domain=='Manufacturing': + sales.work() + manufacturing.work() + elif domain=='Education': + schools.work() + + except: + frappe.db.set_global('demo_last_date', current_date) + raise + finally: + current_date = frappe.utils.add_days(current_date, 1) + frappe.db.commit() diff --git a/erpnext/demo/domains.py b/erpnext/demo/domains.py index 0217f248706..5743e27bf29 100644 --- a/erpnext/demo/domains.py +++ b/erpnext/demo/domains.py @@ -12,5 +12,8 @@ data = { }, 'Services': { 'company_name': 'Acme Consulting' + }, + 'Education': { + 'company_name': 'Whitmore College' } } \ No newline at end of file diff --git a/erpnext/demo/setup/__init__.py b/erpnext/demo/setup/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/demo/setup/education.py b/erpnext/demo/setup/education.py new file mode 100644 index 00000000000..b1640573629 --- /dev/null +++ b/erpnext/demo/setup/education.py @@ -0,0 +1,140 @@ +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +import frappe, json +from frappe.utils.make_random import get_random +from datetime import datetime +from erpnext.demo.setup.setup_data import import_json +import random + +def setup_data(): + frappe.flags.mute_emails = True + make_masters() + setup_item() + make_student_applicants() + make_student_group() + make_fees_category() + make_fees_structure() + frappe.db.commit() + frappe.clear_cache() + +def make_masters(): + import_json("Room") + import_json("Department") + import_json("Instructor") + import_json("Course") + import_json("Program") + frappe.db.commit() + +def setup_item(): + items = json.loads(open(frappe.get_app_path('erpnext', 'demo', 'data', 'item_schools.json')).read()) + for i in items: + item = frappe.new_doc('Item') + item.update(i) + item.min_order_qty = random.randint(10, 30) + item.default_warehouse = frappe.get_all('Warehouse', filters={'warehouse_name': item.default_warehouse}, limit=1)[0].name + item.insert() + +def make_student_applicants(): + blood_group = ["A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-"] + male_names = [] + female_names = [] + + file_path = get_json_path("Random Student Data") + with open(file_path, "r") as open_file: + random_student_data = json.loads(open_file.read()) + count = 1 + + for d in random_student_data: + if d.get('gender') == "Male": + male_names.append(d.get('first_name').title()) + + if d.get('gender') == "Female": + female_names.append(d.get('first_name').title()) + + for idx, d in enumerate(random_student_data): + student_applicant = frappe.new_doc("Student Applicant") + student_applicant.first_name = d.get('first_name').title() + student_applicant.last_name = d.get('last_name').title() + student_applicant.image = d.get('image') + student_applicant.gender = d.get('gender') + student_applicant.program = get_random("Program") + student_applicant.blood_group = random.choice(blood_group) + year = random.randint(1990, 1998) + month = random.randint(1, 12) + day = random.randint(1, 28) + student_applicant.date_of_birth = datetime(year, month, day) + student_applicant.mother_name = random.choice(female_names) + " " + d.get('last_name').title() + student_applicant.father_name = random.choice(male_names) + " " + d.get('last_name').title() + if student_applicant.gender == "Male": + student_applicant.middle_name = random.choice(male_names) + else: + student_applicant.middle_name = random.choice(female_names) + student_applicant.student_email_id = d.get('first_name') + "_" + \ + student_applicant.middle_name + "_" + d.get('last_name') + "@example.com" + if count <5: + student_applicant.insert() + frappe.db.commit() + else: + student_applicant.submit() + frappe.db.commit() + count+=1 + +def make_student_group(): + for d in frappe.db.get_list("Academic Term"): + sg_tool = frappe.new_doc("Student Group Creation Tool") + sg_tool.academic_year = "2016-17" + sg_tool.academic_term = d.name + sg_tool.courses = sg_tool.get_courses() + sg_tool.create_student_groups() + frappe.db.commit() + +def make_fees_category(): + fee_type = ["Tuition Fee", "Hostel Fee", "Logistics Fee", + "Medical Fee", "Mess Fee", "Security Deposit"] + + fee_desc = {"Tuition Fee" : "Curricular activities which includes books, notebooks and faculty charges" , + "Hostel Fee" : "Stay of students in institute premises", + "Logistics Fee" : "Lodging boarding of the students" , + "Medical Fee" : "Medical welfare of the students", + "Mess Fee" : "Food and beverages for your ward", + "Security Deposit" : "In case your child is found to have damaged institutes property" + } + + for i in fee_type: + fee_category = frappe.new_doc("Fee Category") + fee_category.category_name = i + fee_category.description = fee_desc[i] + fee_category.insert() + frappe.db.commit() + +def make_fees_structure(): + for d in frappe.db.get_list("Program"): + program = frappe.get_doc("Program", d.name) + for academic_term in ["Semester 1", "Semester 2", "Semester 3"]: + fee_structure = frappe.new_doc("Fee Structure") + fee_structure.program = d.name + fee_structure.academic_term = random.choice(frappe.db.get_list("Academic Term")).name + for j in range(1,4): + temp = {"fees_category": random.choice(frappe.db.get_list("Fee Category")).name , "amount" : random.randint(500,1000)} + fee_structure.append("components", temp) + fee_structure.insert() + program.append("fees", {"academic_term": academic_term, "fee_structure": fee_structure.name, "amount": fee_structure.total_amount}) + program.save() + frappe.db.commit() + +def get_json_path(doctype): + return frappe.get_app_path('erpnext', 'demo', 'data', frappe.scrub(doctype) + '.json') + +def weighted_choice(weights): + totals = [] + running_total = 0 + + for w in weights: + running_total += w + totals.append(running_total) + + rnd = random.random() * running_total + for i, total in enumerate(totals): + if rnd < total: + return i diff --git a/erpnext/demo/setup/manufacture.py b/erpnext/demo/setup/manufacture.py new file mode 100644 index 00000000000..8ac203903b2 --- /dev/null +++ b/erpnext/demo/setup/manufacture.py @@ -0,0 +1,131 @@ +from __future__ import unicode_literals + +import random, json +import frappe +from frappe.utils import nowdate, add_days +from erpnext.demo.setup.setup_data import import_json + +def setup_data(): + import_json("Asset Category") + setup_item() + setup_workstation() + setup_asset() + import_json('Operation') + setup_item_price() + show_item_groups_in_website() + import_json('BOM', submit=True) + frappe.db.commit() + frappe.clear_cache() + +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_asset(): + assets = json.loads(open(frappe.get_app_path('erpnext', 'demo', 'data', 'asset.json')).read()) + for d in assets: + asset = frappe.new_doc('Asset') + asset.update(d) + asset.purchase_date = add_days(nowdate(), -random.randint(20, 1500)) + asset.next_depreciation_date = add_days(asset.purchase_date, 30) + asset.warehouse = "Stores - WPL" + asset.set_missing_values() + asset.make_depreciation_schedule() + asset.flags.ignore_validate = True + asset.save() + asset.submit() + +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_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_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() diff --git a/erpnext/demo/setup_data.py b/erpnext/demo/setup/setup_data.py similarity index 73% rename from erpnext/demo/setup_data.py rename to erpnext/demo/setup/setup_data.py index 97dc89476c0..d279a64b886 100644 --- a/erpnext/demo/setup_data.py +++ b/erpnext/demo/setup/setup_data.py @@ -1,43 +1,35 @@ from __future__ import unicode_literals import random, json +import frappe, erpnext +from frappe.utils import flt, now_datetime, cstr from frappe.utils.make_random import add_random_children, get_random from erpnext.demo.domains import data -import frappe, erpnext -from frappe.utils import flt, now_datetime, cstr, nowdate, add_days from frappe import _ -def setup_data(): - domain = frappe.flags.domain +def setup(domain): complete_setup(domain) setup_demo_page() setup_fiscal_year() setup_holiday_list() - setup_customer() - setup_supplier() - import_json("Asset Category") - setup_item() - setup_warehouse() - setup_asset() - 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_salary_structure_for_timesheet() setup_leave_allocation() + setup_user_roles() + setup_customer() + setup_supplier() + setup_warehouse() + import_json('Address') + import_json('Contact') + import_json('Lead') + setup_currency_exchange() setup_mode_of_payment() setup_account_to_expense_type() - setup_user_roles() setup_budget() setup_pos_profile() + frappe.db.commit() frappe.clear_cache() @@ -105,106 +97,6 @@ def setup_holiday_list(): 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.min_order_qty = random.randint(10, 30) - item.default_warehouse = frappe.get_all('Warehouse', filters={'warehouse_name': item.default_warehouse}, limit=1)[0].name - item.insert() - -def setup_warehouse(): - w = frappe.new_doc('Warehouse') - w.warehouse_name = 'Supplier' - w.insert() - -def setup_asset(): - assets = json.loads(open(frappe.get_app_path('erpnext', 'demo', 'data', 'asset.json')).read()) - for d in assets: - asset = frappe.new_doc('Asset') - asset.update(d) - asset.purchase_date = add_days(nowdate(), -random.randint(20, 1500)) - asset.next_depreciation_date = add_days(asset.purchase_date, 30) - asset.warehouse = "Stores - WPL" - asset.set_missing_values() - asset.make_depreciation_schedule() - asset.flags.ignore_validate = True - asset.save() - asset.submit() - -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")') @@ -215,78 +107,12 @@ def setup_user(): user.new_password = 'demo' user.insert() -def import_json(doctype, submit=False, values=None): - 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() - - frappe.db.commit() - 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')) @@ -331,69 +157,12 @@ def setup_salary_structure_for_timesheet(): ss_doc.hour_rate = flt(random.random() * 10, 2) ss_doc.save(ignore_permissions=True) -def setup_mode_of_payment(): - account_dict = {'Cash': 'Cash - WPL', 'Bank': 'National Bank - WPL'} - for payment_mode in frappe.get_all('Mode of Payment', fields = ["name", "type"]): - if payment_mode.type: - mop = frappe.get_doc('Mode of Payment', payment_mode.name) - mop.append('accounts', { - 'company': erpnext.get_default_company(), - 'default_account': account_dict.get(payment_mode.type) - }) - - mop.save(ignore_permissions=True) - -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_account_to_expense_type(): - expense_types = [{'name': _('Calls'), "account": "Sales Expenses - WPL"}, - {'name': _('Food'), "account": "Entertainment Expenses - WPL"}, - {'name': _('Medical'), "account": "Utility Expenses - WPL"}, - {'name': _('Others'), "account": "Miscellaneous Expenses - WPL"}, - {'name': _('Travel'), "account": "Travel Expenses - WPL"}] - - for expense_type in expense_types: - doc = frappe.get_doc("Expense Claim Type", expense_type["name"]) - doc.append("accounts", { - "company" : erpnext.get_default_company(), - "default_account" : expense_type["account"] - }) - doc.save(ignore_permissions=True) - -def setup_budget(): - fiscal_years = frappe.get_all("Fiscal Year", order_by="year_start_date")[-2:] - - for fy in fiscal_years: - budget = frappe.new_doc("Budget") - budget.cost_center = get_random("Cost Center") - budget.fiscal_year = fy.name - budget.action_if_annual_budget_exceeded = "Warn" - expense_ledger_count = frappe.db.count("Account", {"is_group": "0", "root_type": "Expense"}) - - add_random_children(budget, "accounts", rows=random.randint(10, expense_ledger_count), randomize = { "account": ("Account", {"is_group": "0", "root_type": "Expense"}) - }, unique="account") - - for d in budget.accounts: - d.budget_amount = random.randint(5, 100) * 10000 - - budget.save() - budget.submit() - - def setup_user_roles(): user = frappe.get_doc('User', 'demo@erpnext.com') user.add_roles('HR User', 'HR Manager', 'Accounts User', 'Accounts Manager', 'Stock User', 'Stock Manager', 'Sales User', 'Sales Manager', 'Purchase User', 'Purchase Manager', 'Projects User', 'Manufacturing User', 'Manufacturing Manager', - 'Support Team') + 'Support Team', 'Academics User') if not frappe.db.get_global('demo_hr_user'): user = frappe.get_doc('User', 'CharmaineGaudreau@example.com') @@ -435,21 +204,15 @@ def setup_user_roles(): user.add_roles('HR User', 'Projects User') frappe.db.set_global('demo_projects_user', user.name) -def setup_pos_profile(): - pos = frappe.new_doc('POS Profile') - pos.user = frappe.db.get_global('demo_accounts_user') - pos.naming_series = 'SINV-' - pos.update_stock = 0 - pos.write_off_account = 'Cost of Goods Sold - WPL' - pos.write_off_cost_center = 'Main - WPL' - - pos.append('payments', { - 'mode_of_payment': frappe.db.get_value('Mode of Payment', {'type': 'Cash'}, 'name'), - 'amount': 0.0 - }) - - pos.insert() - + if not frappe.db.get_global('demo_schools_user'): + user = frappe.get_doc('User', 'aromn@example.com') + user.add_roles('Academics User') + frappe.db.set_global('demo_schools_user', user.name) + + #Add Expense Approver + user = frappe.get_doc('User', 'WanMai@example.com') + user.add_roles('Expense Approver') + def setup_leave_allocation(): year = now_datetime().year for employee in frappe.get_all('Employee', fields=['name']): @@ -469,3 +232,131 @@ def setup_leave_allocation(): leave_allocation.insert() leave_allocation.submit() frappe.db.commit() + +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_warehouse(): + w = frappe.new_doc('Warehouse') + w.warehouse_name = 'Supplier' + w.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_mode_of_payment(): + company_abbr = frappe.db.get_value("Company", erpnext.get_default_company(), "abbr") + account_dict = {'Cash': 'Cash - '+ company_abbr , 'Bank': 'National Bank - '+ company_abbr} + for payment_mode in frappe.get_all('Mode of Payment', fields = ["name", "type"]): + if payment_mode.type: + mop = frappe.get_doc('Mode of Payment', payment_mode.name) + mop.append('accounts', { + 'company': erpnext.get_default_company(), + 'default_account': account_dict.get(payment_mode.type) + }) + mop.save(ignore_permissions=True) + +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_account_to_expense_type(): + company_abbr = frappe.db.get_value("Company", erpnext.get_default_company(), "abbr") + expense_types = [{'name': _('Calls'), "account": "Sales Expenses - "+ company_abbr}, + {'name': _('Food'), "account": "Entertainment Expenses - "+ company_abbr}, + {'name': _('Medical'), "account": "Utility Expenses - "+ company_abbr}, + {'name': _('Others'), "account": "Miscellaneous Expenses - "+ company_abbr}, + {'name': _('Travel'), "account": "Travel Expenses - "+ company_abbr}] + + for expense_type in expense_types: + doc = frappe.get_doc("Expense Claim Type", expense_type["name"]) + doc.append("accounts", { + "company" : erpnext.get_default_company(), + "default_account" : expense_type["account"] + }) + doc.save(ignore_permissions=True) + +def setup_budget(): + fiscal_years = frappe.get_all("Fiscal Year", order_by="year_start_date")[-2:] + + for fy in fiscal_years: + budget = frappe.new_doc("Budget") + budget.cost_center = get_random("Cost Center") + budget.fiscal_year = fy.name + budget.action_if_annual_budget_exceeded = "Warn" + expense_ledger_count = frappe.db.count("Account", {"is_group": "0", "root_type": "Expense"}) + + add_random_children(budget, "accounts", rows=random.randint(10, expense_ledger_count), randomize = { "account": ("Account", {"is_group": "0", "root_type": "Expense"}) + }, unique="account") + + for d in budget.accounts: + d.budget_amount = random.randint(5, 100) * 10000 + + budget.save() + budget.submit() + +def setup_pos_profile(): + company_abbr = frappe.db.get_value("Company", erpnext.get_default_company(), "abbr") + pos = frappe.new_doc('POS Profile') + pos.user = frappe.db.get_global('demo_accounts_user') + pos.naming_series = 'SINV-' + pos.update_stock = 0 + pos.write_off_account = 'Cost of Goods Sold - '+ company_abbr + pos.write_off_cost_center = 'Main - '+ company_abbr + + pos.append('payments', { + 'mode_of_payment': frappe.db.get_value('Mode of Payment', {'type': 'Cash'}, 'name'), + 'amount': 0.0 + }) + + pos.insert() + +def import_json(doctype, submit=False, values=None): + 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() + + frappe.db.commit() + + diff --git a/erpnext/demo/user/accounts.py b/erpnext/demo/user/accounts.py index 045c306487d..392d13db92c 100644 --- a/erpnext/demo/user/accounts.py +++ b/erpnext/demo/user/accounts.py @@ -67,7 +67,7 @@ def work(): def make_payment_entries(ref_doctype, report): outstanding_invoices = list(set([r[3] for r in query_report.run(report, {"report_date": frappe.flags.current_date })["result"] if r[2]==ref_doctype])) - + # make Payment Entry for inv in outstanding_invoices[:random.randint(1, 2)]: pe = get_payment_entry(ref_doctype, inv) diff --git a/erpnext/demo/user/hr.py b/erpnext/demo/user/hr.py index 73f330d5078..2b80afbabb4 100644 --- a/erpnext/demo/user/hr.py +++ b/erpnext/demo/user/hr.py @@ -1,25 +1,28 @@ from __future__ import unicode_literals import frappe import random -from frappe.utils import random_string, add_days +from frappe.utils import random_string, add_days, cint from erpnext.projects.doctype.timesheet.test_timesheet import make_timesheet from erpnext.projects.doctype.timesheet.timesheet import make_salary_slip, make_sales_invoice -from frappe.utils.make_random import how_many, get_random +from frappe.utils.make_random import get_random from erpnext.hr.doctype.expense_claim.expense_claim import get_expense_approver, make_bank_entry from erpnext.hr.doctype.leave_application.leave_application import get_leave_balance_on, OverlapError def work(): frappe.set_user(frappe.db.get_global('demo_hr_user')) year, month = frappe.flags.current_date.strftime("%Y-%m").split("-") + prev_month = str(cint(month)- 1).zfill(2) + if month=="01": + prev_month = "12" mark_attendance() make_leave_application() # process payroll - if not frappe.db.get_value("Salary Slip", {"month": month, "fiscal_year": year}): + if not frappe.db.get_value("Salary Slip", {"month": prev_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.month = prev_month process_payroll.fiscal_year = year process_payroll.create_sal_slip() process_payroll.submit_salary_slip() @@ -180,7 +183,7 @@ def mark_attendance(): if leave: attendance.status = "Absent" else: - attendance.status = "Present" + attendance.status = "Present" attendance.save() attendance.submit() - frappe.db.commit() \ No newline at end of file + frappe.db.commit() diff --git a/erpnext/demo/user/projects.py b/erpnext/demo/user/projects.py index e7febd0b8ad..505ccfd077f 100644 --- a/erpnext/demo/user/projects.py +++ b/erpnext/demo/user/projects.py @@ -5,8 +5,7 @@ from __future__ import unicode_literals import frappe from frappe.utils import flt -from frappe.utils.make_random import can_make -from frappe.utils.make_random import how_many, get_random +from frappe.utils.make_random import get_random from erpnext.projects.doctype.timesheet.test_timesheet import make_timesheet from erpnext.demo.user.hr import make_sales_invoice_for_timesheet @@ -20,13 +19,12 @@ def run_projects(current_date): def make_timesheet_for_projects(current_date ): for data in frappe.get_all("Task", ["name", "project"], {"status": "Open", "exp_end_date": ("<", current_date)}): employee = get_random("Employee") - if frappe.db.get_value('Salary Structure', {'employee': employee}, 'salary_slip_based_on_timesheet'): - ts = make_timesheet(employee, simulate = True, billable = 1, - activity_type=get_random("Activity Type"), project=data.project, task =data.name) + ts = make_timesheet(employee, simulate = True, billable = 1, + activity_type=get_random("Activity Type"), project=data.project, task =data.name) - if flt(ts.total_billing_amount) > 0.0: - make_sales_invoice_for_timesheet(ts.name) - frappe.db.commit() + if flt(ts.total_billing_amount) > 0.0: + make_sales_invoice_for_timesheet(ts.name) + frappe.db.commit() def close_tasks(current_date): for task in frappe.get_all("Task", ["name"], {"status": "Open", "exp_end_date": ("<", current_date)}): diff --git a/erpnext/demo/user/purchase.py b/erpnext/demo/user/purchase.py index 6f06f26fb11..ab8ec772574 100644 --- a/erpnext/demo/user/purchase.py +++ b/erpnext/demo/user/purchase.py @@ -27,7 +27,6 @@ def work(): for mr in frappe.get_all('Material Request', filters={'material_request_type': 'Purchase', 'status': 'Open'}, limit=random.randint(1,6)): - print mr.name if not frappe.get_all('Request for Quotation', filters={'material_request': mr.name}, limit=1): rfq = make_request_for_quotation(mr.name) @@ -104,14 +103,12 @@ def make_material_request(item_code, qty): mr.material_request_type = "Purchase" mr.transaction_date = frappe.flags.current_date - - moq = frappe.db.get_value('Item', item_code, 'min_order_qty') - + mr.append("items", { "doctype": "Material Request Item", "schedule_date": frappe.utils.add_days(mr.transaction_date, 7), "item_code": item_code, - "qty": qty if qty > moq else moq + "qty": qty }) mr.insert() mr.submit() @@ -125,33 +122,33 @@ def add_suppliers(rfq): 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") - item_code = get_random("Item", {"is_sub_contracted_item": 1}) - moq = frappe.db.get_value('Item', item_code, 'min_order_qty') + if item_code: + # make sub-contract PO + po = frappe.new_doc("Purchase Order") + po.is_subcontracted = "Yes" + po.supplier = get_random("Supplier") - po.append("items", { - "item_code": item_code, - "schedule_date": frappe.utils.add_days(frappe.flags.current_date, 7), - "qty": moq - }) - po.set_missing_values() - try: - po.insert() - except InvalidCurrency: - return + item_code = get_random("Item", {"is_sub_contracted_item": 1}) + + po.append("items", { + "item_code": item_code, + "schedule_date": frappe.utils.add_days(frappe.flags.current_date, 7), + "qty": random.randint(10, 30) + }) + po.set_missing_values() + try: + po.insert() + except InvalidCurrency: + return - po.submit() + po.submit() - # make material request for - make_material_request(po.items[0].item_code, po.items[0].qty) + # 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 - WPL" - stock_entry.to_warehouse = "Supplier - WPL" - stock_entry.insert() + # 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 - WPL" + stock_entry.to_warehouse = "Supplier - WPL" + stock_entry.insert() diff --git a/erpnext/demo/user/schools.py b/erpnext/demo/user/schools.py new file mode 100644 index 00000000000..6388f9ac7ed --- /dev/null +++ b/erpnext/demo/user/schools.py @@ -0,0 +1,97 @@ +# 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 +import random +from frappe.utils import cstr +from frappe.utils.make_random import get_random +from datetime import timedelta +from erpnext.schools.api import get_student_group_students, make_attendance_records, enroll_student, get_fee_schedule, collect_fees + +def work(): + frappe.set_user(frappe.db.get_global('demo_schools_user')) + for d in xrange(20): + approve_random_student_applicant() + enroll_random_student(frappe.flags.current_date) + if frappe.flags.current_date.weekday()== 0: + make_course_schedule(frappe.flags.current_date, frappe.utils.add_days(frappe.flags.current_date, 5)) + mark_student_attendance(frappe.flags.current_date) + make_fees() + +def mark_student_attendance(current_date): + status = ["Present", "Absent"] + for d in frappe.db.get_list("Course Schedule", filters={"schedule_date": current_date}, fields=("name", "student_group")): + students = get_student_group_students(d.student_group) + for stud in students: + make_attendance_records(stud.student, stud.student_name, d.name, status[weighted_choice([9,4])]) + +def make_fees(): + for d in range(1,10): + random_fee = get_random("Fees", {"paid_amount": 0}) + collect_fees(random_fee, frappe.db.get_value("Fees", random_fee, "outstanding_amount")) + +def approve_random_student_applicant(): + random_student = get_random("Student Applicant", {"application_status": "Applied"}) + if random_student: + status = ["Approved", "Rejected"] + frappe.db.set_value("Student Applicant", random_student, "application_status", status[weighted_choice([9,3])]) + +def enroll_random_student(current_date): + random_student = get_random("Student Applicant", {"application_status": "Approved"}) + if random_student: + enrollment = enroll_student(random_student) + enrollment.academic_year = get_random("Academic Year") + enrollment.enrollment_date = current_date + fee_schedule = get_fee_schedule(enrollment.program) + for fee in fee_schedule: + enrollment.append("fees", fee) + enrollment.submit() + frappe.db.commit() + assign_student_group(enrollment.student, enrollment.program) + +def assign_student_group(student, program): + courses = [] + for d in frappe.get_list("Program Course", fields=("course"), filters={"parent": program }): + courses.append(d.course) + + for d in xrange(3): + course = random.choice(courses) + random_sg = get_random("Student Group", {"course": course}) + if random_sg: + student_group = frappe.get_doc("Student Group", random_sg) + student_group.append("students", {"student": student}) + student_group.save() + courses.remove(course) + +def make_course_schedule(start_date, end_date): + for d in frappe.db.get_list("Student Group"): + cs = frappe.new_doc("Scheduling Tool") + cs.student_group = d.name + cs.room = get_random("Room") + cs.instructor = get_random("Instructor") + cs.course_start_date = cstr(start_date) + cs.course_end_date = cstr(end_date) + day = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] + for x in xrange(3): + random_day = random.choice(day) + cs.day = random_day + cs.from_time = timedelta(hours=(random.randrange(7, 17,1))) + cs.to_time = cs.from_time + timedelta(hours=1) + cs.schedule_course() + day.remove(random_day) + + +def weighted_choice(weights): + totals = [] + running_total = 0 + + for w in weights: + running_total += w + totals.append(running_total) + + rnd = random.random() * running_total + for i, total in enumerate(totals): + if rnd < total: + return i \ No newline at end of file diff --git a/erpnext/demo/user/stock.py b/erpnext/demo/user/stock.py index c86a11bb530..ac380f2e474 100644 --- a/erpnext/demo/user/stock.py +++ b/erpnext/demo/user/stock.py @@ -102,23 +102,21 @@ def submit_draft_stock_entries(): def make_sales_return_records(): for data in frappe.get_all('Delivery Note', fields=["name"], filters={"docstatus": 1}): if random.random() < 0.2: - print "dn" try: dn = make_sales_return(data.name) dn.insert() dn.submit() frappe.db.commit() - except Exception, e: + except Exception: frappe.db.rollback() def make_purchase_return_records(): for data in frappe.get_all('Purchase Receipt', fields=["name"], filters={"docstatus": 1}): if random.random() < 0.2: - print "purchase" try: pr = make_purchase_return(data.name) pr.insert() pr.submit() frappe.db.commit() - except Exception, e: + except Exception: frappe.db.rollback() diff --git a/erpnext/schools/api.py b/erpnext/schools/api.py index 4649d0cc04e..3554fe76dd3 100644 --- a/erpnext/schools/api.py +++ b/erpnext/schools/api.py @@ -21,9 +21,8 @@ def enroll_student(source_name): "field_map": { "name": "student_applicant" } - }}) + }}, ignore_permissions=True) student.save() - program_enrollment = frappe.new_doc("Program Enrollment") program_enrollment.student = student.name program_enrollment.student_name = student.title