From fa7c8a9f8be4b9abc69d580df78eb7b039a67e5c Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Tue, 25 Sep 2018 15:44:38 +0530 Subject: [PATCH 01/33] update employee and user records --- erpnext/demo/data/employee.json | 60 ++++++++++------ erpnext/demo/data/user.json | 120 +++++++++++++++---------------- erpnext/demo/setup/setup_data.py | 22 +++--- 3 files changed, 111 insertions(+), 91 deletions(-) diff --git a/erpnext/demo/data/employee.json b/erpnext/demo/data/employee.json index d9f4d2a220..a77d706ae5 100644 --- a/erpnext/demo/data/employee.json +++ b/erpnext/demo/data/employee.json @@ -2,71 +2,91 @@ { "date_of_birth": "1982-01-03", "date_of_joining": "2001-10-10", - "employee_name": "Dikman Shervashidze Shervashidze", + "employee_name": "Diana Prince", + "first_name": "Diana", + "last_name": "Prince", "gender": "Female", - "user_id": "DikmanShervashidze@example.com" + "user_id": "DianaPrince@example.com" }, { "date_of_birth": "1959-02-03", "date_of_joining": "1976-09-16", - "employee_name": "Zukutakitoteka", + "employee_name": "Zatanna Zatara", "gender": "Female", - "user_id": "Zukutakitoteka@example.com" + "user_id": "ZatannaZatara@example.com", + "first_name": "Zatanna", + "last_name": "Zatara" }, { "date_of_birth": "1982-03-03", "date_of_joining": "2000-06-16", - "employee_name": "Hatsue Kashiwagi", + "employee_name": "Holly Granger", "gender": "Female", - "user_id": "HatsueKashiwagi@example.com" + "user_id": "HollyGranger@example.com", + "first_name": "Holly", + "last_name": "Granger" }, { "date_of_birth": "1945-04-04", "date_of_joining": "1969-07-01", - "employee_name": "Nuran Verkleij", + "employee_name": "Neptunia Aquaria", "gender": "Female", - "user_id": "NuranVerkleij@example.com" + "user_id": "NeptuniaAquaria@example.com", + "first_name": "Neptunia", + "last_name": "Aquaria" }, { "date_of_birth": "1978-05-03", "date_of_joining": "1999-12-24", - "employee_name": "\u0414\u043c\u0438\u0442\u0440\u0438\u0439 \u041f\u0438\u0440\u043e\u0433\u043e\u0432", + "employee_name": "Arthur Curry", "gender": "Male", - "user_id": "aromn@example.com" + "user_id": "ArthurCurry@example.com", + "first_name": "Arthur", + "last_name": "Curry" }, { "date_of_birth": "1964-06-03", "date_of_joining": "1981-08-05", - "employee_name": "Tilde Lindqvist", + "employee_name": "Thalia Al Ghul", "gender": "Female", - "user_id": "TildeLindqvist@example.com" + "user_id": "ThaliaAlGhul@example.com", + "first_name": "Thalia", + "last_name": "Al Ghul" }, { "date_of_birth": "1982-07-03", "date_of_joining": "2006-06-10", - "employee_name": "Micha\u0142 Sobczak", + "employee_name": "Maxwell Lord", "gender": "Male", - "user_id": "MichalSobczak@example.com" + "user_id": "MaxwellLord@example.com", + "first_name": "Maxwell", + "last_name": "Lord" }, { "date_of_birth": "1969-08-03", "date_of_joining": "1993-10-21", - "employee_name": "Gabrielle Loftus", + "employee_name": "Grace Choi", "gender": "Female", - "user_id": "GabrielleLoftus@example.com" + "user_id": "GraceChoi@example.com", + "first_name": "Grace", + "last_name": "Choi" }, { "date_of_birth": "1982-09-03", "date_of_joining": "2005-09-06", - "employee_name": "Vakhita Ryzaev", + "employee_name": "Vandal Savage", "gender": "Male", - "user_id": "VakhitaRyzaev@example.com" + "user_id": "VandalSavage@example.com", + "first_name": "Vandal", + "last_name": "Savage" }, { "date_of_birth": "1985-10-03", "date_of_joining": "2007-12-25", - "employee_name": "Charmaine Gaudreau", + "employee_name": "Caitlin Snow", "gender": "Female", - "user_id": "CharmaineGaudreau@example.com" + "user_id": "CaitlinSnow@example.com", + "first_name": "Caitlin", + "last_name": "Snow" } ] \ No newline at end of file diff --git a/erpnext/demo/data/user.json b/erpnext/demo/data/user.json index 811e8afa52..9ee5e780ac 100644 --- a/erpnext/demo/data/user.json +++ b/erpnext/demo/data/user.json @@ -5,104 +5,104 @@ "last_name": "User" }, { - "email": "DikmanShervashidze@example.com", - "first_name": "Dikman", - "last_name": "Shervashidze" + "email": "DianaPrince@example.com", + "first_name": "Diana", + "last_name": "Prince" }, { - "email": "Zukutakitoteka@example.com", - "first_name": "Zukutakitoteka", - "last_name": null + "email": "ZatannaZatara@example.com", + "first_name": "Zatanna", + "last_name": "Zatara" }, { - "email": "HatsueKashiwagi@example.com", - "first_name": "Hatsue", - "last_name": "Kashiwagi" + "email": "HollyGranger@example.com", + "first_name": "Holly", + "last_name": "Granger" }, { - "email": "NuranVerkleij@example.com", - "first_name": "Nuran", - "last_name": "Verkleij" + "email": "NeptuniaAquaria@example.com", + "first_name": "Neptunia", + "last_name": "Aquaria" }, { - "email": "aromn@example.com", - "first_name": "Arom", - "last_name": "Nolan" + "email": "ArthurCurry@example.com", + "first_name": "Arthur", + "last_name": "Curry" }, { - "email": "TildeLindqvist@example.com", - "first_name": "Tilde", - "last_name": "Lindqvist" + "email": "ThaliaAlGhul@example.com", + "first_name": "Thalia", + "last_name": "Al Ghul" }, { - "email": "MichalSobczak@example.com", - "first_name": "Micha\u0142", - "last_name": "Sobczak" + "email": "MaxwellLord@example.com", + "first_name": "Maxwell", + "last_name": "Lord" }, { - "email": "GabrielleLoftus@example.com", - "first_name": "Gabrielle", - "last_name": "Loftus" + "email": "GraceChoi@example.com", + "first_name": "Grace", + "last_name": "Choi" }, { - "email": "VakhitaRyzaev@example.com", - "first_name": "Vakhita", - "last_name": "Ryzaev" + "email": "VandalSavage@example.com", + "first_name": "Vandal", + "last_name": "Savage" }, { - "email": "CharmaineGaudreau@example.com", - "first_name": "Charmaine", - "last_name": "Gaudreau" + "email": "CaitlinSnow@example.com", + "first_name": "Caitlin", + "last_name": "Snow" }, { - "email": "RafaelaMaartens@example.com", - "first_name": "Rafa\u00ebla", - "last_name": "Maartens" + "email": "RipHunter@example.com", + "first_name": "Rip", + "last_name": "Hunter" }, { - "email": "NuguseYohannes@example.com", - "first_name": "Nuguse", - "last_name": "Yohannes" + "email": "NicholasFury@example.com", + "first_name": "Nicholas", + "last_name": "Fury" }, { - "email": "panca@example.com", - "first_name": "\u0420\u0430\u0438\u0441\u0430", - "last_name": "\u0411\u0435\u043b\u044f\u043a\u043e\u0432\u0430" + "email": "PeterParker@example.com", + "first_name": "Peter", + "last_name": "Parker" }, { - "email": "CaYinLong@example.com", - "first_name": "\u80e4\u9686", - "last_name": "\u8521" + "email": "JohnConstantine@example.com", + "first_name": "John", + "last_name": "Constantine" }, { - "email": "FreddieScott@example.com", - "first_name": "Freddie", - "last_name": "Scott" + "email": "HalJordan@example.com", + "first_name": "Hal", + "last_name": "Jordan" }, { - "email": "BergoraVigfusdottir@example.com", - "first_name": "Berg\u00fe\u00f3ra", - "last_name": "Vigf\u00fasd\u00f3ttir" + "email": "VictorStone@example.com", + "first_name": "Victor", + "last_name": "Stone" }, { - "email": "WardNajmalDinKalb@example.com", - "first_name": "Ward", - "last_name": "Kalb" + "email": "BruceWayne@example.com", + "first_name": "Bruce", + "last_name": "Wayne" }, { - "email": "WanMai@example.com", - "first_name": "Wan", - "last_name": "Mai" + "email": "ClarkKent@example.com", + "first_name": "Clark", + "last_name": "Kent" }, { - "email": "LeonAbdulov@example.com", - "first_name": "Leon", - "last_name": "Abdulov" + "email": "BarryAllen@example.com", + "first_name": "Barry", + "last_name": "Allen" }, { - "email": "SabinaNovotna@example.com", - "first_name": "Sabina", - "last_name": "Novotn\u00e1" + "email": "KaraZorEl@example.com", + "first_name": "Kara", + "last_name": "Zor El" }, { "email": "demo@erpnext.com", diff --git a/erpnext/demo/setup/setup_data.py b/erpnext/demo/setup/setup_data.py index 911d41838e..0ff32622f6 100644 --- a/erpnext/demo/setup/setup_data.py +++ b/erpnext/demo/setup/setup_data.py @@ -14,7 +14,7 @@ def setup(domain): setup_fiscal_year() setup_holiday_list() setup_user() - #setup_employee() + setup_employee() setup_user_roles() setup_role_permissions() @@ -184,52 +184,52 @@ def setup_user_roles(): 'Nursing User', 'Patient') if not frappe.db.get_global('demo_hr_user'): - user = frappe.get_doc('User', 'CharmaineGaudreau@example.com') + user = frappe.get_doc('User', 'CaitlinSnow@example.com') user.add_roles('HR User', 'HR Manager', 'Accounts User') frappe.db.set_global('demo_hr_user', user.name) if not frappe.db.get_global('demo_sales_user_1'): - user = frappe.get_doc('User', 'VakhitaRyzaev@example.com') + user = frappe.get_doc('User', 'VandalSavage@example.com') user.add_roles('Sales User') frappe.db.set_global('demo_sales_user_1', user.name) if not frappe.db.get_global('demo_sales_user_2'): - user = frappe.get_doc('User', 'GabrielleLoftus@example.com') + user = frappe.get_doc('User', 'GraceChoi@example.com') user.add_roles('Sales User', 'Sales Manager', 'Accounts User') frappe.db.set_global('demo_sales_user_2', user.name) if not frappe.db.get_global('demo_purchase_user'): - user = frappe.get_doc('User', 'MichalSobczak@example.com') + user = frappe.get_doc('User', 'MaxwellLord@example.com') user.add_roles('Purchase User', 'Purchase Manager', 'Accounts User', 'Stock User') frappe.db.set_global('demo_purchase_user', user.name) if not frappe.db.get_global('demo_manufacturing_user'): - user = frappe.get_doc('User', 'NuranVerkleij@example.com') + user = frappe.get_doc('User', 'NeptuniaAquaria@example.com') user.add_roles('Manufacturing User', 'Stock User', 'Purchase User', 'Accounts User') frappe.db.set_global('demo_manufacturing_user', user.name) if not frappe.db.get_global('demo_stock_user'): - user = frappe.get_doc('User', 'HatsueKashiwagi@example.com') + user = frappe.get_doc('User', 'HollyGranger@example.com') user.add_roles('Manufacturing User', 'Stock User', 'Purchase User', 'Accounts User') frappe.db.set_global('demo_stock_user', user.name) if not frappe.db.get_global('demo_accounts_user'): - user = frappe.get_doc('User', 'LeonAbdulov@example.com') + user = frappe.get_doc('User', 'BarryAllen@example.com') user.add_roles('Accounts User', 'Accounts Manager', 'Sales User', 'Purchase User') frappe.db.set_global('demo_accounts_user', user.name) if not frappe.db.get_global('demo_projects_user'): - user = frappe.get_doc('User', 'panca@example.com') + user = frappe.get_doc('User', 'PeterParker@example.com') user.add_roles('HR User', 'Projects User') frappe.db.set_global('demo_projects_user', user.name) if not frappe.db.get_global('demo_education_user'): - user = frappe.get_doc('User', 'aromn@example.com') + user = frappe.get_doc('User', 'ArthurCurry@example.com') user.add_roles('Academics User') frappe.db.set_global('demo_education_user', user.name) #Add Expense Approver - user = frappe.get_doc('User', 'WanMai@example.com') + user = frappe.get_doc('User', 'ClarkKent@example.com') user.add_roles('Expense Approver') def setup_leave_allocation(): From 4c07970545669e1567d8d792397a602e3d427afe Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Tue, 25 Sep 2018 16:32:21 +0530 Subject: [PATCH 02/33] remove user permission from HR Manager user --- erpnext/demo/setup/setup_data.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/demo/setup/setup_data.py b/erpnext/demo/setup/setup_data.py index 0ff32622f6..726c67484a 100644 --- a/erpnext/demo/setup/setup_data.py +++ b/erpnext/demo/setup/setup_data.py @@ -187,6 +187,8 @@ def setup_user_roles(): user = frappe.get_doc('User', 'CaitlinSnow@example.com') user.add_roles('HR User', 'HR Manager', 'Accounts User') frappe.db.set_global('demo_hr_user', user.name) + for d in frappe.get_all('User Permission', filters={"user": "CaitlinSnow@example.com"}): + frappe.delete_doc('User Permission', d.name) if not frappe.db.get_global('demo_sales_user_1'): user = frappe.get_doc('User', 'VandalSavage@example.com') From 796bffbee12ac6c21e120433de3d419a6111b39f Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Wed, 26 Sep 2018 12:27:09 +0530 Subject: [PATCH 03/33] fix payroll and stock related data --- erpnext/demo/setup/setup_data.py | 4 ++++ erpnext/demo/user/hr.py | 33 ++++++++++++++++++++------------ erpnext/demo/user/purchase.py | 4 ++-- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/erpnext/demo/setup/setup_data.py b/erpnext/demo/setup/setup_data.py index 726c67484a..2269377a6f 100644 --- a/erpnext/demo/setup/setup_data.py +++ b/erpnext/demo/setup/setup_data.py @@ -166,12 +166,16 @@ def setup_salary_structure(employees, salary_slip_based_on_timesheet=0): "idx": 1 }) ss.insert() + ss.submit() for e in employees: sa = frappe.new_doc("Salary Structure Assignment") sa.employee = e.name + sa.salary_structure = ss.name sa.from_date = "2015-01-01" sa.base = random.random() * 10000 + sa.insert() + sa.submit() return ss diff --git a/erpnext/demo/user/hr.py b/erpnext/demo/user/hr.py index b8016869cf..db2d167dd0 100644 --- a/erpnext/demo/user/hr.py +++ b/erpnext/demo/user/hr.py @@ -19,29 +19,25 @@ def work(): # payroll entry if not frappe.db.sql('select name from `tabSalary Slip` where month(adddate(start_date, interval 1 month))=month(curdate())'): - # process payroll for previous month - payroll_entry = frappe.new_doc("Payroll Entry") - payroll_entry.company = frappe.flags.company - payroll_entry.payroll_frequency = 'Monthly' - - # select a posting date from the previous month - payroll_entry.posting_date = get_last_day(getdate(frappe.flags.current_date) - datetime.timedelta(days=10)) - payroll_entry.payment_account = frappe.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name") - - payroll_entry.set_start_end_dates() - # based on frequency + payroll_entry = get_payroll_entry() payroll_entry.salary_slip_based_on_timesheet = 0 + payroll_entry.save() payroll_entry.create_salary_slips() payroll_entry.submit_salary_slips() payroll_entry.make_accrual_jv_entry() + payroll_entry.submit() # payroll_entry.make_journal_entry(reference_date=frappe.flags.current_date, # reference_number=random_string(10)) + # based on timesheet + payroll_entry = get_payroll_entry() payroll_entry.salary_slip_based_on_timesheet = 1 + payroll_entry.save() payroll_entry.create_salary_slips() payroll_entry.submit_salary_slips() payroll_entry.make_accrual_jv_entry() + payroll_entry.submit() # payroll_entry.make_journal_entry(reference_date=frappe.flags.current_date, # reference_number=random_string(10)) @@ -72,6 +68,19 @@ def work(): je.flags.ignore_permissions = 1 je.submit() +def get_payroll_entry(): + # process payroll for previous month + payroll_entry = frappe.new_doc("Payroll Entry") + payroll_entry.company = frappe.flags.company + payroll_entry.payroll_frequency = 'Monthly' + + # select a posting date from the previous month + payroll_entry.posting_date = get_last_day(getdate(frappe.flags.current_date) - datetime.timedelta(days=10)) + payroll_entry.payment_account = frappe.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name") + + payroll_entry.set_start_end_dates() + return payroll_entry + def get_expenses(): expenses = [] expese_types = frappe.db.sql("""select ect.name, eca.default_account from `tabExpense Claim Type` ect, @@ -114,7 +123,7 @@ def get_timesheet_based_salary_slip_employee(): def make_timesheet_records(): employees = get_timesheet_based_salary_slip_employee() for e in employees: - ts = make_timesheet(e.employee, simulate = True, billable = 1, activity_type=get_random("Activity Type")) + ts = make_timesheet(e.employee, simulate = True, billable = 1, activity_type=get_random("Activity Type"), company=frappe.flags.company) frappe.db.commit() rand = random.random() diff --git a/erpnext/demo/user/purchase.py b/erpnext/demo/user/purchase.py index ad99de907a..a9a603c256 100644 --- a/erpnext/demo/user/purchase.py +++ b/erpnext/demo/user/purchase.py @@ -122,7 +122,7 @@ def add_suppliers(rfq): rfq.append("suppliers", { "supplier": supplier }) def make_subcontract(): - from erpnext.buying.doctype.purchase_order.purchase_order import make_stock_entry + from erpnext.buying.doctype.purchase_order.purchase_order import make_rm_stock_entry item_code = get_random("Item", {"is_sub_contracted_item": 1}) if item_code: # make sub-contract PO @@ -150,7 +150,7 @@ def make_subcontract(): 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 = frappe.get_doc(make_rm_stock_entry(po.name, po.items[0].item_code)) stock_entry.from_warehouse = "Stores - WPL" stock_entry.to_warehouse = "Supplier - WPL" stock_entry.insert() From 0309bbee30cf0ff31ba6936e264e287212df2cd7 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Thu, 27 Sep 2018 18:45:30 +0530 Subject: [PATCH 04/33] function call requires company as parameter --- .../stock/doctype/stock_reconciliation/stock_reconciliation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index 363db39a4d..3b20b1cf64 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -254,7 +254,7 @@ class StockReconciliation(StockController): def get_items_for(self, warehouse): self.items = [] - for item in get_items(warehouse, self.posting_date, self.posting_time): + for item in get_items(warehouse, self.posting_date, self.posting_time, self.company): self.append("items", item) def submit(self): From a259466643b90fe5f6b0f85983895fe83c82b770 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Thu, 27 Sep 2018 18:47:31 +0530 Subject: [PATCH 05/33] add relevant department to employees --- erpnext/demo/setup/setup_data.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/erpnext/demo/setup/setup_data.py b/erpnext/demo/setup/setup_data.py index 2269377a6f..4f9e6885d5 100644 --- a/erpnext/demo/setup/setup_data.py +++ b/erpnext/demo/setup/setup_data.py @@ -191,47 +191,56 @@ def setup_user_roles(): user = frappe.get_doc('User', 'CaitlinSnow@example.com') user.add_roles('HR User', 'HR Manager', 'Accounts User') frappe.db.set_global('demo_hr_user', user.name) + update_employee_department(user.name, 'Human Resources') for d in frappe.get_all('User Permission', filters={"user": "CaitlinSnow@example.com"}): frappe.delete_doc('User Permission', d.name) if not frappe.db.get_global('demo_sales_user_1'): user = frappe.get_doc('User', 'VandalSavage@example.com') user.add_roles('Sales User') + update_employee_department(user.name, 'Sales') frappe.db.set_global('demo_sales_user_1', user.name) if not frappe.db.get_global('demo_sales_user_2'): user = frappe.get_doc('User', 'GraceChoi@example.com') user.add_roles('Sales User', 'Sales Manager', 'Accounts User') + update_employee_department(user.name, 'Sales') frappe.db.set_global('demo_sales_user_2', user.name) if not frappe.db.get_global('demo_purchase_user'): user = frappe.get_doc('User', 'MaxwellLord@example.com') user.add_roles('Purchase User', 'Purchase Manager', 'Accounts User', 'Stock User') + update_employee_department(user.name, 'Purchase') frappe.db.set_global('demo_purchase_user', user.name) if not frappe.db.get_global('demo_manufacturing_user'): user = frappe.get_doc('User', 'NeptuniaAquaria@example.com') user.add_roles('Manufacturing User', 'Stock User', 'Purchase User', 'Accounts User') + update_employee_department(user.name, 'Production') frappe.db.set_global('demo_manufacturing_user', user.name) if not frappe.db.get_global('demo_stock_user'): user = frappe.get_doc('User', 'HollyGranger@example.com') user.add_roles('Manufacturing User', 'Stock User', 'Purchase User', 'Accounts User') + update_employee_department(user.name, 'Production') frappe.db.set_global('demo_stock_user', user.name) if not frappe.db.get_global('demo_accounts_user'): user = frappe.get_doc('User', 'BarryAllen@example.com') user.add_roles('Accounts User', 'Accounts Manager', 'Sales User', 'Purchase User') + update_employee_department(user.name, 'Accounts') frappe.db.set_global('demo_accounts_user', user.name) if not frappe.db.get_global('demo_projects_user'): user = frappe.get_doc('User', 'PeterParker@example.com') user.add_roles('HR User', 'Projects User') + update_employee_department(user.name, 'Management') frappe.db.set_global('demo_projects_user', user.name) if not frappe.db.get_global('demo_education_user'): user = frappe.get_doc('User', 'ArthurCurry@example.com') user.add_roles('Academics User') + update_employee_department(user.name, 'Management') frappe.db.set_global('demo_education_user', user.name) #Add Expense Approver @@ -409,3 +418,8 @@ def import_json(doctype, submit=False, values=None): frappe.db.commit() frappe.flags.in_import = False + +def update_employee_department(user_id, department): + employee = frappe.db.get_value('Employee', {"user_id": user_id}, 'name') + department = frappe.db.get_value('Department', {'department_name': department}, 'name') + frappe.db.set_value('Employee', employee, 'department', department) From c24d2fdf6c33041d3c08e5851374d49da1eda719 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Thu, 27 Sep 2018 18:49:00 +0530 Subject: [PATCH 06/33] setup leave & expense approver for each department - assign approver in expense claim --- erpnext/demo/user/hr.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/erpnext/demo/user/hr.py b/erpnext/demo/user/hr.py index db2d167dd0..aace773425 100644 --- a/erpnext/demo/user/hr.py +++ b/erpnext/demo/user/hr.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals import frappe, erpnext import random import datetime +from frappe import _ from frappe.utils import random_string, add_days, get_last_day, getdate from erpnext.projects.doctype.timesheet.test_timesheet import make_timesheet from erpnext.projects.doctype.timesheet.timesheet import make_salary_slip, make_sales_invoice @@ -14,6 +15,7 @@ from erpnext.hr.doctype.leave_application.leave_application import (get_leave_ba def work(): frappe.set_user(frappe.db.get_global('demo_hr_user')) year, month = frappe.flags.current_date.strftime("%Y-%m").split("-") + setup_department_approvers() mark_attendance() make_leave_application() @@ -51,12 +53,14 @@ def work(): expense_claim.company = frappe.flags.company expense_claim.payable_account = get_payable_account(expense_claim.company) expense_claim.posting_date = frappe.flags.current_date - expense_claim.insert() + expense_claim.expense_approver = frappe.db.get_global('demo_hr_user') + expense_claim.save() rand = random.random() if rand < 0.4: update_sanctioned_amount(expense_claim) + expense_claim.approval_status = 'Approved' expense_claim.submit() if random.randint(0, 1): @@ -204,3 +208,11 @@ def mark_attendance(): attendance.save() attendance.submit() frappe.db.commit() + +def setup_department_approvers(): + for d in frappe.get_all('Department', filters={'department_name': ['!=', 'All Departments']}): + doc = frappe.get_doc('Department', d.name) + doc.append("leave_approvers", {'approver': frappe.session.user}) + doc.append("expense_approvers", {'approver': frappe.session.user}) + doc.flags.ignore_mandatory = True + doc.save() From 143d4da901aaa2aa6a7bb1e06729a731ae9e8a33 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Thu, 27 Sep 2018 18:49:52 +0530 Subject: [PATCH 07/33] Production Plan fix --- erpnext/demo/user/manufacturing.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/erpnext/demo/user/manufacturing.py b/erpnext/demo/user/manufacturing.py index 0231eda947..128ca1a2c9 100644 --- a/erpnext/demo/user/manufacturing.py +++ b/erpnext/demo/user/manufacturing.py @@ -14,15 +14,17 @@ def work(): from erpnext.projects.doctype.timesheet.timesheet import OverlapError - ppt = frappe.get_doc("Production Planning Tool", "Production Planning Tool") + ppt = frappe.new_doc("Production Plan") ppt.company = erpnext.get_default_company() - ppt.use_multi_level_bom = 1 + # ppt.use_multi_level_bom = 1 #refactored ppt.get_items_from = "Sales Order" - ppt.purchase_request_for_warehouse = "Stores - WPL" + # ppt.purchase_request_for_warehouse = "Stores - WPL" # refactored ppt.run_method("get_open_sales_orders") ppt.run_method("get_items") - ppt.run_method("raise_work_orders") ppt.run_method("raise_material_requests") + ppt.save() + ppt.submit() + ppt.run_method("raise_work_orders") frappe.db.commit() # submit work orders From dcf740110466d021e8d84c1e002616134f45b8de Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Thu, 27 Sep 2018 18:51:18 +0530 Subject: [PATCH 08/33] random time fix and other minor fixes --- erpnext/demo/user/accounts.py | 2 +- erpnext/demo/user/projects.py | 4 ++-- erpnext/demo/user/purchase.py | 15 ++++++++------- erpnext/demo/user/sales.py | 19 ++++++++++--------- erpnext/demo/user/stock.py | 11 ++++++----- 5 files changed, 27 insertions(+), 24 deletions(-) diff --git a/erpnext/demo/user/accounts.py b/erpnext/demo/user/accounts.py index a12933bcfb..18855041ed 100644 --- a/erpnext/demo/user/accounts.py +++ b/erpnext/demo/user/accounts.py @@ -56,7 +56,7 @@ def work(): if random.random() < 0.5: make_payment_entries("Purchase Invoice", "Accounts Payable") - if random.random() < 0.1: + if random.random() < 0.4: #make payment request against sales invoice sales_invoice_name = get_random("Sales Invoice", filters={"docstatus": 1}) if sales_invoice_name: diff --git a/erpnext/demo/user/projects.py b/erpnext/demo/user/projects.py index 9802447679..ee87199796 100644 --- a/erpnext/demo/user/projects.py +++ b/erpnext/demo/user/projects.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals -import frappe +import frappe, erpnext from frappe.utils import flt from frappe.utils.make_random import get_random from erpnext.projects.doctype.timesheet.test_timesheet import make_timesheet @@ -19,7 +19,7 @@ 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") - ts = make_timesheet(employee, simulate = True, billable = 1, + ts = make_timesheet(employee, simulate = True, billable = 1, company = erpnext.get_default_company(), activity_type=get_random("Activity Type"), project=data.project, task =data.name) if flt(ts.total_billable_amount) > 0.0: diff --git a/erpnext/demo/user/purchase.py b/erpnext/demo/user/purchase.py index a9a603c256..4796bf3ad4 100644 --- a/erpnext/demo/user/purchase.py +++ b/erpnext/demo/user/purchase.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals -import frappe, random +import frappe, random, json from frappe.utils.make_random import how_many, get_random from frappe.desk import query_report from erpnext.setup.utils import get_exchange_rate @@ -16,14 +16,14 @@ from erpnext.buying.doctype.request_for_quotation.request_for_quotation import \ def work(): frappe.set_user(frappe.db.get_global('demo_purchase_user')) - if random.random() < 0.3: + if random.random() < 0.6: report = "Items To Be Requested" for row in query_report.run(report)["result"][:random.randint(1, 5)]: item_code, qty = row[0], abs(row[-1]) mr = make_material_request(item_code, qty) - if random.random() < 0.3: + if random.random() < 0.6: for mr in frappe.get_all('Material Request', filters={'material_request_type': 'Purchase', 'status': 'Open'}, limit=random.randint(1,6)): @@ -36,7 +36,7 @@ def work(): rfq.submit() # Make suppier quotation from RFQ against each supplier. - if random.random() < 0.3: + if random.random() < 0.6: for rfq in frappe.get_all('Request for Quotation', filters={'status': 'Open'}, limit=random.randint(1, 6)): if not frappe.get_all('Supplier Quotation', @@ -59,7 +59,7 @@ def work(): exchange_rate = get_exchange_rate(party_account_currency, company_currency, args="for_buying") # make supplier quotations - if random.random() < 0.2: + if random.random() < 0.5: from erpnext.stock.doctype.material_request.material_request import make_supplier_quotation report = "Material Requests for which Supplier Quotations are not created" @@ -89,7 +89,7 @@ def work(): po.submit() frappe.db.commit() - if random.random() < 0.2: + if random.random() < 0.5: make_subcontract() def make_material_request(item_code, qty): @@ -129,6 +129,7 @@ def make_subcontract(): po = frappe.new_doc("Purchase Order") po.is_subcontracted = "Yes" po.supplier = get_random("Supplier") + po.transaction_date = frappe.flags.current_date # added po.schedule_date = frappe.utils.add_days(frappe.flags.current_date, 7) item_code = get_random("Item", {"is_sub_contracted_item": 1}) @@ -150,7 +151,7 @@ def make_subcontract(): make_material_request(po.items[0].item_code, po.items[0].qty) # transfer material for sub-contract - stock_entry = frappe.get_doc(make_rm_stock_entry(po.name, po.items[0].item_code)) + stock_entry = frappe.get_doc(make_rm_stock_entry(po.name, frappe.as_json(po.items))) stock_entry.from_warehouse = "Stores - WPL" stock_entry.to_warehouse = "Supplier - WPL" stock_entry.insert() diff --git a/erpnext/demo/user/sales.py b/erpnext/demo/user/sales.py index 65d7f55558..304576aca9 100644 --- a/erpnext/demo/user/sales.py +++ b/erpnext/demo/user/sales.py @@ -12,12 +12,13 @@ from erpnext.accounts.doctype.payment_request.payment_request import make_paymen def work(): frappe.set_user(frappe.db.get_global('demo_sales_user_2')) - if random.random() < 0.5: - for i in range(random.randint(1,7)): + + for i in range(random.randint(1,7)): + if random.random() < 0.5: make_opportunity() - if random.random() < 0.5: - for i in range(random.randint(1,3)): + for i in range(random.randint(1,3)): + if random.random() < 0.5: make_quotation() # lost quotations / inquiries @@ -32,11 +33,11 @@ def work(): if opportunity and opportunity.status in ('Open', 'Replied'): opportunity.declare_enquiry_lost('Did not ask') - if random.random() < 0.3: - for i in range(random.randint(1,3)): + for i in range(random.randint(1,3)): + if random.random() < 0.3: make_sales_order() - if random.random() < 0.1: + if random.random() < 0.5: #make payment request against Sales Order sales_order_name = get_random("Sales Order", filters={"docstatus": 1}) if sales_order_name: @@ -115,8 +116,8 @@ def make_quotation(): def make_sales_order(): q = get_random("Quotation", {"status": "Submitted"}) if q: - from erpnext.selling.doctype.quotation.quotation import make_sales_order - so = frappe.get_doc(make_sales_order(q)) + from erpnext.selling.doctype.quotation.quotation import make_sales_order as mso + so = frappe.get_doc(mso(q)) so.transaction_date = frappe.flags.current_date so.delivery_date = frappe.utils.add_days(frappe.flags.current_date, 10) so.insert() diff --git a/erpnext/demo/user/stock.py b/erpnext/demo/user/stock.py index a6b0e0061d..50257dc0b1 100644 --- a/erpnext/demo/user/stock.py +++ b/erpnext/demo/user/stock.py @@ -3,7 +3,7 @@ from __future__ import print_function, unicode_literals -import frappe, random +import frappe, random, erpnext from frappe.desk import query_report from erpnext.stock.stock_ledger import NegativeStockError from erpnext.stock.doctype.serial_no.serial_no import SerialNoRequiredError, SerialNoQtyError @@ -45,7 +45,7 @@ def make_delivery_note(): # make purchase requests # make delivery notes (if possible) - if random.random() < 0.3: + if random.random() < 0.6: from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note report = "Ordered Items To Be Delivered" for so in list(set([r[0] for r in query_report.run(report)["result"] @@ -68,9 +68,10 @@ def make_stock_reconciliation(): from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation \ import OpeningEntryAccountError, EmptyStockReconciliationItemsError - if random.random() < 0.1: + if random.random() < 0.4: stock_reco = frappe.new_doc("Stock Reconciliation") stock_reco.posting_date = frappe.flags.current_date + stock_reco.company = erpnext.get_default_company() stock_reco.get_items_for("Stores - WP") if stock_reco.items: for item in stock_reco.items: @@ -87,7 +88,7 @@ def make_stock_reconciliation(): def submit_draft_stock_entries(): from erpnext.stock.doctype.stock_entry.stock_entry import IncorrectValuationRateError, \ - DuplicateEntryForProductionOrderError, OperationsNotCompleteError + DuplicateEntryForWorkOrderError, OperationsNotCompleteError # try posting older drafts (if exists) frappe.db.commit() @@ -98,7 +99,7 @@ def submit_draft_stock_entries(): ste.save() ste.submit() frappe.db.commit() - except (NegativeStockError, IncorrectValuationRateError, DuplicateEntryForProductionOrderError, + except (NegativeStockError, IncorrectValuationRateError, DuplicateEntryForWorkOrderError, OperationsNotCompleteError): frappe.db.rollback() From 523f77e82b29d8af6bd88ede4092829ca6099ae0 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Fri, 28 Sep 2018 13:59:09 +0530 Subject: [PATCH 09/33] make_rm_stock_entry fix --- erpnext/demo/user/purchase.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/erpnext/demo/user/purchase.py b/erpnext/demo/user/purchase.py index 4796bf3ad4..69dee00b1c 100644 --- a/erpnext/demo/user/purchase.py +++ b/erpnext/demo/user/purchase.py @@ -151,7 +151,20 @@ def make_subcontract(): make_material_request(po.items[0].item_code, po.items[0].qty) # transfer material for sub-contract - stock_entry = frappe.get_doc(make_rm_stock_entry(po.name, frappe.as_json(po.items))) + rm_items = get_rm_item(po.items[0], po.supplied_items[0]) + stock_entry = frappe.get_doc(make_rm_stock_entry(po.name, json.dumps([rm_items]))) stock_entry.from_warehouse = "Stores - WPL" stock_entry.to_warehouse = "Supplier - WPL" stock_entry.insert() + +def get_rm_item(items, supplied_items): + return { + "item_code": items.get("item_code"), + "rm_item_code": supplied_items.get("rm_item_code"), + "item_name": supplied_items.get("rm_item_code"), + "qty": supplied_items.get("required_qty"), + "amount": supplied_items.get("amount"), + "warehouse": supplied_items.get("reserve_warehouse"), + "rate": supplied_items.get("rate"), + "stock_uom": supplied_items.get("stock_uom") + } From e895845ae11160369ca1a1c3b257b311fdc00584 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Mon, 1 Oct 2018 10:47:29 +0530 Subject: [PATCH 10/33] import fix --- erpnext/demo/demo.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/demo/demo.py b/erpnext/demo/demo.py index f765469499..8cafd402f7 100644 --- a/erpnext/demo/demo.py +++ b/erpnext/demo/demo.py @@ -3,7 +3,8 @@ from __future__ import unicode_literals import frappe, sys import erpnext import frappe.utils -from erpnext.demo.user import hr, sales, purchase, manufacturing, stock, accounts, projects, fixed_asset, education +from erpnext.demo.user import hr, sales, purchase, manufacturing, stock, accounts, projects, fixed_asset +from erpnext.demo.user import education as edu from erpnext.demo.setup import education, manufacture, setup_data, healthcare """ Make a demo @@ -83,7 +84,7 @@ def simulate(domain='Manufacturing', days=100): sales.work() manufacturing.work() elif domain=='Education': - education.work() + edu.work() except: frappe.db.set_global('demo_last_date', current_date) From e64dcfc2f93063048a2d955f578e29b5740d4199 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Mon, 1 Oct 2018 10:48:38 +0530 Subject: [PATCH 11/33] timesheet logic changed to job card --- erpnext/demo/user/manufacturing.py | 47 +++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/erpnext/demo/user/manufacturing.py b/erpnext/demo/user/manufacturing.py index 128ca1a2c9..612dc49131 100644 --- a/erpnext/demo/user/manufacturing.py +++ b/erpnext/demo/user/manufacturing.py @@ -4,13 +4,17 @@ from __future__ import unicode_literals import frappe, random, erpnext +from datetime import datetime, timedelta from frappe.utils.make_random import how_many from frappe.desk import query_report from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError from erpnext.manufacturing.doctype.work_order.test_work_order import make_wo_order_test_record def work(): + if random.random() < 0.3: return + frappe.set_user(frappe.db.get_global('demo_manufacturing_user')) + if not frappe.get_all('Sales Order'): return from erpnext.projects.doctype.timesheet.timesheet import OverlapError @@ -20,6 +24,7 @@ def work(): ppt.get_items_from = "Sales Order" # ppt.purchase_request_for_warehouse = "Stores - WPL" # refactored ppt.run_method("get_open_sales_orders") + if not ppt.get("sales_orders"): return ppt.run_method("get_items") ppt.run_method("raise_material_requests") ppt.save() @@ -41,12 +46,12 @@ def work(): frappe.db.commit() # stores -> wip - if random.random() < 0.3: + if random.random() < 0.4: for pro in query_report.run("Open Work Orders")["result"][:how_many("Stock Entry for WIP")]: make_stock_entry_from_pro(pro[0], "Material Transfer for Manufacture") # wip -> fg - if random.random() < 0.3: + if random.random() < 0.4: for pro in query_report.run("Work Orders in Progress")["result"][:how_many("Stock Entry for FG")]: make_stock_entry_from_pro(pro[0], "Manufacture") @@ -57,17 +62,9 @@ def work(): stock_uom = frappe.db.get_value('Item', bom.item, 'stock_uom'), planned_start_date = frappe.flags.current_date) - # submit time logs - for timesheet in frappe.get_all("Timesheet", ["name"], {"docstatus": 0, - "work_order": ("!=", ""), "to_time": ("<", frappe.flags.current_date)}): - timesheet = frappe.get_doc("Timesheet", timesheet.name) - try: - timesheet.submit() - frappe.db.commit() - except OverlapError: - pass - except WorkstationHolidayError: - pass + # submit job card + if random.random() < 0.4: + submit_job_cards() def make_stock_entry_from_pro(pro_id, purpose): from erpnext.manufacturing.doctype.work_order.work_order import make_stock_entry @@ -88,3 +85,27 @@ def make_stock_entry_from_pro(pro_id, purpose): except (NegativeStockError, IncorrectValuationRateError, DuplicateEntryForWorkOrderError, OperationsNotCompleteError): frappe.db.rollback() + +def submit_job_cards(): + work_orders = frappe.get_all("Work Order", ["name", "creation"], {"docstatus": 1, "status": "Not Started"}) + work_order = random.choice(work_orders) + # for work_order in work_orders: + start_date = work_order.creation + work_order = frappe.get_doc("Work Order", work_order.name) + job = frappe.get_all("Job Card", ["name", "operation", "work_order"], + {"docstatus": 0, "work_order": work_order.name}) + + if not job: return + job_map = {} + for d in job: + job_map[d.operation] = frappe.get_doc("Job Card", d.name) + + for operation in work_order.operations: + job = job_map[operation.operation] + job.actual_start_date = start_date + minutes = operation.get("time_in_mins") + random_minutes = random.randint(int(minutes/2), minutes) + job.actual_end_date = job.actual_start_date + timedelta(minutes=random_minutes) + start_date = job.actual_end_date + job.save() + job.submit() From d080a179615c6727fdc93f38dec1043d2b798f88 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Mon, 1 Oct 2018 10:49:06 +0530 Subject: [PATCH 12/33] minor random trigger changes and exception handling --- erpnext/demo/user/purchase.py | 2 +- erpnext/demo/user/sales.py | 21 ++++++++++++--------- erpnext/demo/user/stock.py | 3 ++- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/erpnext/demo/user/purchase.py b/erpnext/demo/user/purchase.py index 69dee00b1c..781c304271 100644 --- a/erpnext/demo/user/purchase.py +++ b/erpnext/demo/user/purchase.py @@ -162,7 +162,7 @@ def get_rm_item(items, supplied_items): "item_code": items.get("item_code"), "rm_item_code": supplied_items.get("rm_item_code"), "item_name": supplied_items.get("rm_item_code"), - "qty": supplied_items.get("required_qty"), + "qty": supplied_items.get("required_qty") + random.randint(3,10), "amount": supplied_items.get("amount"), "warehouse": supplied_items.get("reserve_warehouse"), "rate": supplied_items.get("rate"), diff --git a/erpnext/demo/user/sales.py b/erpnext/demo/user/sales.py index 304576aca9..fbeeff477c 100644 --- a/erpnext/demo/user/sales.py +++ b/erpnext/demo/user/sales.py @@ -34,21 +34,24 @@ def work(): opportunity.declare_enquiry_lost('Did not ask') for i in range(random.randint(1,3)): - if random.random() < 0.3: + if random.random() < 0.6: make_sales_order() if random.random() < 0.5: #make payment request against Sales Order sales_order_name = get_random("Sales Order", filters={"docstatus": 1}) - if sales_order_name: - so = frappe.get_doc("Sales Order", sales_order_name) - if flt(so.per_billed) != 100: - payment_request = make_payment_request(dt="Sales Order", dn=so.name, recipient_id=so.contact_email, - submit_doc=True, mute_email=True, use_dummy_message=True) + try: + if sales_order_name: + so = frappe.get_doc("Sales Order", sales_order_name) + if flt(so.per_billed) != 100: + payment_request = make_payment_request(dt="Sales Order", dn=so.name, recipient_id=so.contact_email, + submit_doc=True, mute_email=True, use_dummy_message=True) - payment_entry = frappe.get_doc(make_payment_entry(payment_request.name)) - payment_entry.posting_date = frappe.flags.current_date - payment_entry.submit() + payment_entry = frappe.get_doc(make_payment_entry(payment_request.name)) + payment_entry.posting_date = frappe.flags.current_date + payment_entry.submit() + except Exception: + pass def make_opportunity(): b = frappe.get_doc({ diff --git a/erpnext/demo/user/stock.py b/erpnext/demo/user/stock.py index 50257dc0b1..6036a2621f 100644 --- a/erpnext/demo/user/stock.py +++ b/erpnext/demo/user/stock.py @@ -56,8 +56,9 @@ def make_delivery_note(): if not d.expense_account: d.expense_account = ("Cost of Goods Sold - {0}".format( frappe.get_cached_value('Company', dn.company, 'abbr'))) - dn.insert() + try: + dn.insert() dn.submit() frappe.db.commit() except (NegativeStockError, SerialNoRequiredError, SerialNoQtyError, UnableToSelectBatchError): From 8b1133cb2489525ba48d13393b52a3ba964487ce Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Mon, 1 Oct 2018 12:55:07 +0530 Subject: [PATCH 13/33] item data fix for default supplier, exception handling for purchase order --- erpnext/demo/data/item.json | 128 +++++++++++++++++----------------- erpnext/demo/user/purchase.py | 22 +++--- 2 files changed, 77 insertions(+), 73 deletions(-) diff --git a/erpnext/demo/data/item.json b/erpnext/demo/data/item.json index 908de15d0b..e77d8cb17d 100644 --- a/erpnext/demo/data/item.json +++ b/erpnext/demo/data/item.json @@ -1,9 +1,9 @@ [ { - "default_supplier": "Asiatic Solutions", - "item_defaults": [{ - "default_warehouse": "Stores" - }], + "item_defaults": [{ + "default_supplier": "Asiatic Solutions", + "default_warehouse": "Stores" + }], "description": "For Upper Bearing", "image": "/assets/erpnext_demo/images/disc.png", "item_code": "Disc Collars", @@ -11,9 +11,9 @@ "item_name": "Disc Collars" }, { - "default_supplier": "Nan Duskin", - "item_defaults": [{ - "default_warehouse": "Stores" + "item_defaults": [{ + "default_supplier": "Nan Duskin", + "default_warehouse": "Stores" }], "description": "CAST IRON, MCMASTER PART NO. 3710T13", "image": "/assets/erpnext_demo/images/bearing.jpg", @@ -22,9 +22,9 @@ "item_name": "Bearing Block" }, { - "default_supplier": null, - "item_defaults": [{ - "default_warehouse": "Finished Goods" + "item_defaults": [{ + "default_supplier": null, + "default_warehouse": "Finished Goods" }], "description": "Wind Mill C Series for Commercial Use 18ft", "image": "/assets/erpnext_demo/images/wind-turbine-2.png", @@ -33,9 +33,9 @@ "item_name": "Wind MIll C Series" }, { - "default_supplier": null, - "item_defaults": [{ - "default_warehouse": "Finished Goods" + "item_defaults": [{ + "default_supplier": null, + "default_warehouse": "Finished Goods" }], "description": "Wind Mill A Series for Home Use 9ft", "image": "/assets/erpnext_demo/images/wind-turbine.png", @@ -44,9 +44,9 @@ "item_name": "Wind Mill A Series" }, { - "default_supplier": null, - "item_defaults": [{ - "default_warehouse": "Finished Goods" + "item_defaults": [{ + "default_supplier": null, + "default_warehouse": "Finished Goods" }], "description": "Small Wind Turbine for Home Use\n\n\n", "image": "/assets/erpnext_demo/images/wind-turbine-1.jpg", @@ -60,9 +60,9 @@ ] }, { - "default_supplier": "HomeBase", - "item_defaults": [{ - "default_warehouse": "Stores" + "item_defaults": [{ + "default_supplier": "HomeBase", + "default_warehouse": "Stores" }], "description": "1.5 in. Diameter x 36 in. Mild Steel Tubing", "image": null, @@ -71,9 +71,9 @@ "item_name": "Bearing Pipe" }, { - "default_supplier": "New World Realty", - "item_defaults": [{ - "default_warehouse": "Stores" + "item_defaults": [{ + "default_supplier": "New World Realty", + "default_warehouse": "Stores" }], "description": "1/32 in. x 24 in. x 47 in. HDPE Opaque Sheet", "image": null, @@ -82,9 +82,9 @@ "item_name": "Wing Sheet" }, { - "default_supplier": "Eagle Hardware", - "item_defaults": [{ - "default_warehouse": "Stores" + "item_defaults": [{ + "default_supplier": "Eagle Hardware", + "default_warehouse": "Stores" }], "description": "3/16 in. x 6 in. x 6 in. Low Carbon Steel Plate", "image": null, @@ -93,9 +93,9 @@ "item_name": "Upper Bearing Plate" }, { - "default_supplier": "Asiatic Solutions", - "item_defaults": [{ - "default_warehouse": "Stores" + "item_defaults": [{ + "default_supplier": "Asiatic Solutions", + "default_warehouse": "Stores" }], "description": "Bearing Assembly", "image": null, @@ -104,9 +104,9 @@ "item_name": "Bearing Assembly" }, { - "default_supplier": "HomeBase", - "item_defaults": [{ - "default_warehouse": "Stores" + "item_defaults": [{ + "default_supplier": "HomeBase", + "default_warehouse": "Stores" }], "description": "3/4 in. x 2 ft. x 4 ft. Pine Plywood", "image": null, @@ -116,9 +116,9 @@ "is_sub_contracted_item": 1 }, { - "default_supplier": "Scott Ties", - "item_defaults": [{ - "default_warehouse": "Stores" + "item_defaults": [{ + "default_supplier": "Scott Ties", + "default_warehouse": "Stores" }], "description": "N/A", "image": null, @@ -127,9 +127,9 @@ "item_name": "Stand" }, { - "default_supplier": "Eagle Hardware", - "item_defaults": [{ - "default_warehouse": "Stores" + "item_defaults": [{ + "default_supplier": "Eagle Hardware", + "default_warehouse": "Stores" }], "description": "1 in. x 3 in. x 1 ft. Multipurpose Al Alloy Bar", "image": null, @@ -138,9 +138,9 @@ "item_name": "Bearing Collar" }, { - "default_supplier": "Eagle Hardware", - "item_defaults": [{ - "default_warehouse": "Stores" + "item_defaults": [{ + "default_supplier": "Eagle Hardware", + "default_warehouse": "Stores" }], "description": "1/4 in. x 6 in. x 6 in. Mild Steel Plate", "image": null, @@ -149,9 +149,9 @@ "item_name": "Base Bearing Plate" }, { - "default_supplier": "HomeBase", - "item_defaults": [{ - "default_warehouse": "Stores" + "item_defaults": [{ + "default_supplier": "HomeBase", + "default_warehouse": "Stores" }], "description": "15/32 in. x 4 ft. x 8 ft. 3-Ply Rtd Sheathing", "image": null, @@ -160,9 +160,9 @@ "item_name": "External Disc" }, { - "default_supplier": "Eagle Hardware", - "item_defaults": [{ - "default_warehouse": "Stores" + "item_defaults": [{ + "default_supplier": "Eagle Hardware", + "default_warehouse": "Stores" }], "description": "1.25 in. Diameter x 6 ft. Mild Steel Tubing", "image": null, @@ -171,9 +171,9 @@ "item_name": "Shaft" }, { - "default_supplier": "Ks Merchandise", - "item_defaults": [{ - "default_warehouse": "Stores" + "item_defaults": [{ + "default_supplier": "Ks Merchandise", + "default_warehouse": "Stores" }], "description": "1/2 in. x 2 ft. x 4 ft. Pine Plywood", "image": null, @@ -182,9 +182,9 @@ "item_name": "Blade Rib" }, { - "default_supplier": "HomeBase", - "item_defaults": [{ - "default_warehouse": "Stores" + "item_defaults": [{ + "default_supplier": "HomeBase", + "default_warehouse": "Stores" }], "description": "For Bearing Collar", "image": null, @@ -193,9 +193,9 @@ "item_name": "Internal Disc" }, { - "default_supplier": null, - "item_defaults": [{ - "default_warehouse": "Finished Goods" + "item_defaults": [{ + "default_supplier": null, + "default_warehouse": "Finished Goods" }], "description": "Small Wind Turbine for Home Use\n\n\n\n

Size: Small

", "image": "/assets/erpnext_demo/images/wind-turbine-1.jpg", @@ -212,9 +212,9 @@ ] }, { - "default_supplier": null, - "item_defaults": [{ - "default_warehouse": "Finished Goods" + "item_defaults": [{ + "default_supplier": null, + "default_warehouse": "Finished Goods" }], "description": "Small Wind Turbine for Home Use\n\n\n\n

Size: Medium

", "image": "/assets/erpnext_demo/images/wind-turbine-1.jpg", @@ -231,9 +231,9 @@ ] }, { - "default_supplier": null, - "item_defaults": [{ - "default_warehouse": "Finished Goods" + "item_defaults": [{ + "default_supplier": null, + "default_warehouse": "Finished Goods" }], "description": "Small Wind Turbine for Home Use\n\n\n\n

Size: Large

", "image": "/assets/erpnext_demo/images/wind-turbine-1.jpg", @@ -257,9 +257,9 @@ "item_name": "Wind Mill A Series with Spare Bearing" }, { - "default_supplier": "HomeBase", - "item_defaults": [{ - "default_warehouse": "Stores" + "item_defaults": [{ + "default_supplier": "HomeBase", + "default_warehouse": "Stores" }], "description": "3/4 in. x 2 ft. x 4 ft. Pine Plywood", "image": null, diff --git a/erpnext/demo/user/purchase.py b/erpnext/demo/user/purchase.py index 781c304271..822a4fcd2e 100644 --- a/erpnext/demo/user/purchase.py +++ b/erpnext/demo/user/purchase.py @@ -51,7 +51,7 @@ def work(): # get supplier details supplier = get_random("Supplier") - company_currency = frappe.get_cached_value('Company', "Wind Power LLC", "default_currency") + company_currency = frappe.get_cached_value('Company', "Wind Power LLC", "default_currency") party_account_currency = get_party_account_currency("Supplier", supplier, "Wind Power LLC") if company_currency == party_account_currency: exchange_rate = 1 @@ -80,14 +80,18 @@ def work(): report = "Requested Items To Be Ordered" for row in query_report.run(report)["result"][:how_many("Purchase Order")]: if row[0] != "'Total'": - po = frappe.get_doc(make_purchase_order(row[0])) - po.supplier = supplier - po.currency = party_account_currency or company_currency - po.conversion_rate = exchange_rate - po.transaction_date = frappe.flags.current_date - po.insert() - po.submit() - frappe.db.commit() + try: + po = frappe.get_doc(make_purchase_order(row[0])) + po.supplier = supplier + po.currency = party_account_currency or company_currency + po.conversion_rate = exchange_rate + po.transaction_date = frappe.flags.current_date + po.insert() + po.submit() + except Exception: + pass + else: + frappe.db.commit() if random.random() < 0.5: make_subcontract() From 275ef826a4837eefc097cfdbf1be553205e535fa Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Tue, 2 Oct 2018 12:55:56 +0530 Subject: [PATCH 14/33] codacy fixes --- erpnext/demo/data/employee.json | 180 ++++++++++++++--------------- erpnext/demo/user/hr.py | 1 - erpnext/demo/user/manufacturing.py | 2 +- 3 files changed, 91 insertions(+), 92 deletions(-) diff --git a/erpnext/demo/data/employee.json b/erpnext/demo/data/employee.json index a77d706ae5..2d2dbe894b 100644 --- a/erpnext/demo/data/employee.json +++ b/erpnext/demo/data/employee.json @@ -1,92 +1,92 @@ [ - { - "date_of_birth": "1982-01-03", - "date_of_joining": "2001-10-10", - "employee_name": "Diana Prince", - "first_name": "Diana", - "last_name": "Prince", - "gender": "Female", - "user_id": "DianaPrince@example.com" - }, - { - "date_of_birth": "1959-02-03", - "date_of_joining": "1976-09-16", - "employee_name": "Zatanna Zatara", - "gender": "Female", - "user_id": "ZatannaZatara@example.com", - "first_name": "Zatanna", - "last_name": "Zatara" - }, - { - "date_of_birth": "1982-03-03", - "date_of_joining": "2000-06-16", - "employee_name": "Holly Granger", - "gender": "Female", - "user_id": "HollyGranger@example.com", - "first_name": "Holly", - "last_name": "Granger" - }, - { - "date_of_birth": "1945-04-04", - "date_of_joining": "1969-07-01", - "employee_name": "Neptunia Aquaria", - "gender": "Female", - "user_id": "NeptuniaAquaria@example.com", - "first_name": "Neptunia", - "last_name": "Aquaria" - }, - { - "date_of_birth": "1978-05-03", - "date_of_joining": "1999-12-24", - "employee_name": "Arthur Curry", - "gender": "Male", - "user_id": "ArthurCurry@example.com", - "first_name": "Arthur", - "last_name": "Curry" - }, - { - "date_of_birth": "1964-06-03", - "date_of_joining": "1981-08-05", - "employee_name": "Thalia Al Ghul", - "gender": "Female", - "user_id": "ThaliaAlGhul@example.com", - "first_name": "Thalia", - "last_name": "Al Ghul" - }, - { - "date_of_birth": "1982-07-03", - "date_of_joining": "2006-06-10", - "employee_name": "Maxwell Lord", - "gender": "Male", - "user_id": "MaxwellLord@example.com", - "first_name": "Maxwell", - "last_name": "Lord" - }, - { - "date_of_birth": "1969-08-03", - "date_of_joining": "1993-10-21", - "employee_name": "Grace Choi", - "gender": "Female", - "user_id": "GraceChoi@example.com", - "first_name": "Grace", - "last_name": "Choi" - }, - { - "date_of_birth": "1982-09-03", - "date_of_joining": "2005-09-06", - "employee_name": "Vandal Savage", - "gender": "Male", - "user_id": "VandalSavage@example.com", - "first_name": "Vandal", - "last_name": "Savage" - }, - { - "date_of_birth": "1985-10-03", - "date_of_joining": "2007-12-25", - "employee_name": "Caitlin Snow", - "gender": "Female", - "user_id": "CaitlinSnow@example.com", - "first_name": "Caitlin", - "last_name": "Snow" - } + { + "date_of_birth": "1982-01-03", + "date_of_joining": "2001-10-10", + "employee_name": "Diana Prince", + "first_name": "Diana", + "last_name": "Prince", + "gender": "Female", + "user_id": "DianaPrince@example.com" + }, + { + "date_of_birth": "1959-02-03", + "date_of_joining": "1976-09-16", + "employee_name": "Zatanna Zatara", + "gender": "Female", + "user_id": "ZatannaZatara@example.com", + "first_name": "Zatanna", + "last_name": "Zatara" + }, + { + "date_of_birth": "1982-03-03", + "date_of_joining": "2000-06-16", + "employee_name": "Holly Granger", + "gender": "Female", + "user_id": "HollyGranger@example.com", + "first_name": "Holly", + "last_name": "Granger" + }, + { + "date_of_birth": "1945-04-04", + "date_of_joining": "1969-07-01", + "employee_name": "Neptunia Aquaria", + "gender": "Female", + "user_id": "NeptuniaAquaria@example.com", + "first_name": "Neptunia", + "last_name": "Aquaria" + }, + { + "date_of_birth": "1978-05-03", + "date_of_joining": "1999-12-24", + "employee_name": "Arthur Curry", + "gender": "Male", + "user_id": "ArthurCurry@example.com", + "first_name": "Arthur", + "last_name": "Curry" + }, + { + "date_of_birth": "1964-06-03", + "date_of_joining": "1981-08-05", + "employee_name": "Thalia Al Ghul", + "gender": "Female", + "user_id": "ThaliaAlGhul@example.com", + "first_name": "Thalia", + "last_name": "Al Ghul" + }, + { + "date_of_birth": "1982-07-03", + "date_of_joining": "2006-06-10", + "employee_name": "Maxwell Lord", + "gender": "Male", + "user_id": "MaxwellLord@example.com", + "first_name": "Maxwell", + "last_name": "Lord" + }, + { + "date_of_birth": "1969-08-03", + "date_of_joining": "1993-10-21", + "employee_name": "Grace Choi", + "gender": "Female", + "user_id": "GraceChoi@example.com", + "first_name": "Grace", + "last_name": "Choi" + }, + { + "date_of_birth": "1982-09-03", + "date_of_joining": "2005-09-06", + "employee_name": "Vandal Savage", + "gender": "Male", + "user_id": "VandalSavage@example.com", + "first_name": "Vandal", + "last_name": "Savage" + }, + { + "date_of_birth": "1985-10-03", + "date_of_joining": "2007-12-25", + "employee_name": "Caitlin Snow", + "gender": "Female", + "user_id": "CaitlinSnow@example.com", + "first_name": "Caitlin", + "last_name": "Snow" + } ] \ No newline at end of file diff --git a/erpnext/demo/user/hr.py b/erpnext/demo/user/hr.py index aace773425..79f3c19287 100644 --- a/erpnext/demo/user/hr.py +++ b/erpnext/demo/user/hr.py @@ -2,7 +2,6 @@ from __future__ import unicode_literals import frappe, erpnext import random import datetime -from frappe import _ from frappe.utils import random_string, add_days, get_last_day, getdate from erpnext.projects.doctype.timesheet.test_timesheet import make_timesheet from erpnext.projects.doctype.timesheet.timesheet import make_salary_slip, make_sales_invoice diff --git a/erpnext/demo/user/manufacturing.py b/erpnext/demo/user/manufacturing.py index 612dc49131..a28d061f38 100644 --- a/erpnext/demo/user/manufacturing.py +++ b/erpnext/demo/user/manufacturing.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import frappe, random, erpnext -from datetime import datetime, timedelta +from datetime import timedelta from frappe.utils.make_random import how_many from frappe.desk import query_report from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError From d1fbaf8f329c3b0c9a0d4c73c406d5b6e53db7d6 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Wed, 10 Oct 2018 14:25:53 +0530 Subject: [PATCH 15/33] custom field added for item - domainification, password changed --- erpnext/demo/setup/setup_data.py | 17 ++++++++++++++++- erpnext/templates/pages/demo.html | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/erpnext/demo/setup/setup_data.py b/erpnext/demo/setup/setup_data.py index 4f9e6885d5..0fd7bb7ac8 100644 --- a/erpnext/demo/setup/setup_data.py +++ b/erpnext/demo/setup/setup_data.py @@ -5,6 +5,7 @@ import frappe, erpnext from frappe.utils.nestedset import get_root_of from frappe.utils import flt, now_datetime, cstr, random_string from frappe.utils.make_random import add_random_children, get_random +from frappe.custom.doctype.custom_field.custom_field import create_custom_fields from erpnext.demo.domains import data from frappe import _ @@ -17,6 +18,7 @@ def setup(domain): setup_employee() setup_user_roles() setup_role_permissions() + setup_custom_field_for_domain() employees = frappe.get_all('Employee', fields=['name', 'date_of_joining']) @@ -120,7 +122,7 @@ def setup_user(): user = frappe.new_doc("User") user.update(u) user.flags.no_welcome_mail = True - user.new_password = 'demo' + user.new_password = 'Demo1234567!!!' user.insert() def setup_employee(): @@ -136,6 +138,8 @@ def setup_employee(): salary_component.save() import_json('Employee') + holiday_list = frappe.db.get_value("Holiday List", {"holiday_list_name": str(now_datetime().year)}, 'name') + frappe.db.sql('''update tabEmployee set holiday_list={0}'''.format(holiday_list)) def setup_salary_structure(employees, salary_slip_based_on_timesheet=0): ss = frappe.new_doc('Salary Structure') @@ -423,3 +427,14 @@ def update_employee_department(user_id, department): employee = frappe.db.get_value('Employee', {"user_id": user_id}, 'name') department = frappe.db.get_value('Department', {'department_name': department}, 'name') frappe.db.set_value('Employee', employee, 'department', department) + +def setup_custom_field_for_domain(): + field = { + "Item": [ + dict(fieldname='domain', label='Domain', + fieldtype='Select', hidden=1, default="Manufacturing", + options="Manufacturing\nService\nDistribution\nRetail" + ) + ] + } + create_custom_fields(field) diff --git a/erpnext/templates/pages/demo.html b/erpnext/templates/pages/demo.html index 10743b8231..8eec800d68 100644 --- a/erpnext/templates/pages/demo.html +++ b/erpnext/templates/pages/demo.html @@ -10,7 +10,7 @@ $(document).ready(function() { "method": "login", args: { usr: "demo@erpnext.com", - pwd: "demo", + pwd: "Demo1234567!!!", lead_email: $("#lead-email").val(), }, callback: function(r) { From fd9c45190944a2831481586b05f5faa740ba4c48 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Wed, 10 Oct 2018 14:27:07 +0530 Subject: [PATCH 16/33] company name picked up dynamically, domainification --- erpnext/demo/demo.py | 6 ++++-- erpnext/demo/user/purchase.py | 6 +++--- erpnext/demo/user/sales.py | 20 ++++++++++---------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/erpnext/demo/demo.py b/erpnext/demo/demo.py index 8cafd402f7..e89b6895a0 100644 --- a/erpnext/demo/demo.py +++ b/erpnext/demo/demo.py @@ -5,7 +5,7 @@ import erpnext import frappe.utils from erpnext.demo.user import hr, sales, purchase, manufacturing, stock, accounts, projects, fixed_asset from erpnext.demo.user import education as edu -from erpnext.demo.setup import education, manufacture, setup_data, healthcare +from erpnext.demo.setup import education, manufacture, setup_data, healthcare, retail """ Make a demo @@ -29,6 +29,8 @@ def make(domain='Manufacturing', days=100): setup_data.setup(domain) if domain== 'Manufacturing': manufacture.setup_data() + elif domain == "Retail": + retail.setup_data() elif domain== 'Education': education.setup_data() elif domain== 'Healthcare': @@ -78,10 +80,10 @@ def simulate(domain='Manufacturing', days=100): stock.work() accounts.work() projects.run_projects(current_date) + sales.work(domain) # run_messages() if domain=='Manufacturing': - sales.work() manufacturing.work() elif domain=='Education': edu.work() diff --git a/erpnext/demo/user/purchase.py b/erpnext/demo/user/purchase.py index 822a4fcd2e..69930448dc 100644 --- a/erpnext/demo/user/purchase.py +++ b/erpnext/demo/user/purchase.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals -import frappe, random, json +import frappe, random, json, erpnext from frappe.utils.make_random import how_many, get_random from frappe.desk import query_report from erpnext.setup.utils import get_exchange_rate @@ -51,8 +51,8 @@ def work(): # get supplier details supplier = get_random("Supplier") - company_currency = frappe.get_cached_value('Company', "Wind Power LLC", "default_currency") - party_account_currency = get_party_account_currency("Supplier", supplier, "Wind Power LLC") + company_currency = frappe.get_cached_value('Company', erpnext.get_default_company(), "default_currency") + party_account_currency = get_party_account_currency("Supplier", supplier, erpnext.get_default_company()) if company_currency == party_account_currency: exchange_rate = 1 else: diff --git a/erpnext/demo/user/sales.py b/erpnext/demo/user/sales.py index fbeeff477c..69ba9007a6 100644 --- a/erpnext/demo/user/sales.py +++ b/erpnext/demo/user/sales.py @@ -3,23 +3,23 @@ from __future__ import unicode_literals -import frappe, random +import frappe, random, erpnext from frappe.utils import flt from frappe.utils.make_random import add_random_children, get_random from erpnext.setup.utils import get_exchange_rate from erpnext.accounts.party import get_party_account_currency from erpnext.accounts.doctype.payment_request.payment_request import make_payment_request, make_payment_entry -def work(): +def work(domain="Manufacturing"): frappe.set_user(frappe.db.get_global('demo_sales_user_2')) for i in range(random.randint(1,7)): if random.random() < 0.5: - make_opportunity() + make_opportunity(domain) for i in range(random.randint(1,3)): if random.random() < 0.5: - make_quotation() + make_quotation(domain) # lost quotations / inquiries if random.random() < 0.3: @@ -53,7 +53,7 @@ def work(): except Exception: pass -def make_opportunity(): +def make_opportunity(domain): b = frappe.get_doc({ "doctype": "Opportunity", "enquiry_from": "Customer", @@ -65,13 +65,13 @@ def make_opportunity(): add_random_children(b, "items", rows=4, randomize = { "qty": (1, 5), - "item_code": ("Item", {"has_variants": 0, "is_fixed_asset": 0}) + "item_code": ("Item", {"has_variants": 0, "is_fixed_asset": 0, "domain": domain}) }, unique="item_code") b.insert() frappe.db.commit() -def make_quotation(): +def make_quotation(domain): # get open opportunites opportunity = get_random("Opportunity", {"status": "Open", "with_items": 1}) @@ -88,8 +88,8 @@ def make_quotation(): # get customer, currency and exchange_rate customer = get_random("Customer") - company_currency = frappe.get_cached_value('Company', "Wind Power LLC", "default_currency") - party_account_currency = get_party_account_currency("Customer", customer, "Wind Power LLC") + company_currency = frappe.get_cached_value('Company', erpnext.get_default_company(), "default_currency") + party_account_currency = get_party_account_currency("Customer", customer, erpnext.get_default_company()) if company_currency == party_account_currency: exchange_rate = 1 else: @@ -108,7 +108,7 @@ def make_quotation(): add_random_children(qtn, "items", rows=3, randomize = { "qty": (1, 5), - "item_code": ("Item", {"has_variants": "0", "is_fixed_asset": 0}) + "item_code": ("Item", {"has_variants": "0", "is_fixed_asset": 0, "domain": domain}) }, unique="item_code") qtn.insert() From 62592d3c446fed86321af44cf18c9fc681a2ff19 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Wed, 10 Oct 2018 14:27:40 +0530 Subject: [PATCH 17/33] setup data for retail added --- erpnext/demo/domains.py | 2 +- erpnext/demo/setup/retail.py | 65 ++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 erpnext/demo/setup/retail.py diff --git a/erpnext/demo/domains.py b/erpnext/demo/domains.py index 5ad3e04013..d5c2bfd2f0 100644 --- a/erpnext/demo/domains.py +++ b/erpnext/demo/domains.py @@ -5,7 +5,7 @@ data = { 'company_name': 'Wind Power LLC' }, 'Retail': { - 'company_name': 'Annapurna Dairy Shop', + 'company_name': 'Mobile Next', }, 'Distribution': { 'company_name': 'Soltice Hardware', diff --git a/erpnext/demo/setup/retail.py b/erpnext/demo/setup/retail.py new file mode 100644 index 0000000000..82d1c15ea3 --- /dev/null +++ b/erpnext/demo/setup/retail.py @@ -0,0 +1,65 @@ +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 +from erpnext.demo.domains import data + +from six import iteritems + +def setup_data(): + setup_item() + setup_item_price() + frappe.db.commit() + frappe.clear_cache() + +def setup_item(): + items = json.loads(open(frappe.get_app_path('erpnext', 'demo', 'data', 'item.json')).read()) + for i in items: + if not i.get("domain") == "Retail": continue + item = frappe.new_doc('Item') + item.update(i) + if hasattr(item, 'item_defaults') and item.item_defaults[0].default_warehouse: + item.item_defaults[0].company = data.get("Retail").get('company_name') + warehouse = frappe.get_all('Warehouse', filters={'warehouse_name': item.item_defaults[0].default_warehouse}, limit=1) + if warehouse: + item.item_defaults[0].default_warehouse = warehouse[0].name + item.insert() + +def setup_item_price(): + frappe.db.sql("delete from `tabItem Price`") + + standard_selling = { + "OnePlus 6": 579, + "OnePlus 6T": 600, + "Xiaomi Poco F1": 300, + "Iphone XS": 999, + "Samsung Galaxy S9": 720, + "Sony Bluetooth Headphone": 99, + "Xiaomi Phone Repair": 10, + "Samsung Phone Repair": 20, + "OnePlus Phone Repair": 15, + "Apple Phone Repair": 30, + } + + standard_buying = { + "OnePlus 6": 300, + "OnePlus 6T": 350, + "Xiaomi Poco F1": 200, + "Iphone XS": 600, + "Samsung Galaxy S9": 500, + "Sony Bluetooth Headphone": 69 + } + + for price_list in ("standard_buying", "standard_selling"): + for item, rate in iteritems(locals().get(price_list)): + 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() From 6a8957b4303d1dc5fe2907e2627a781484667250 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Wed, 10 Oct 2018 14:27:58 +0530 Subject: [PATCH 18/33] item data updated with retail data --- erpnext/demo/data/item.json | 826 +++++++++++++++++++++--------------- 1 file changed, 491 insertions(+), 335 deletions(-) diff --git a/erpnext/demo/data/item.json b/erpnext/demo/data/item.json index e77d8cb17d..1d4ed343be 100644 --- a/erpnext/demo/data/item.json +++ b/erpnext/demo/data/item.json @@ -1,337 +1,493 @@ [ - { - "item_defaults": [{ - "default_supplier": "Asiatic Solutions", - "default_warehouse": "Stores" - }], - "description": "For Upper Bearing", - "image": "/assets/erpnext_demo/images/disc.png", - "item_code": "Disc Collars", - "item_group": "Raw Material", - "item_name": "Disc Collars" - }, - { - "item_defaults": [{ - "default_supplier": "Nan Duskin", - "default_warehouse": "Stores" - }], - "description": "CAST IRON, MCMASTER PART NO. 3710T13", - "image": "/assets/erpnext_demo/images/bearing.jpg", - "item_code": "Bearing Block", - "item_group": "Raw Material", - "item_name": "Bearing Block" - }, - { - "item_defaults": [{ - "default_supplier": null, - "default_warehouse": "Finished Goods" - }], - "description": "Wind Mill C Series for Commercial Use 18ft", - "image": "/assets/erpnext_demo/images/wind-turbine-2.png", - "item_code": "Wind MIll C Series", - "item_group": "Products", - "item_name": "Wind MIll C Series" - }, - { - "item_defaults": [{ - "default_supplier": null, - "default_warehouse": "Finished Goods" - }], - "description": "Wind Mill A Series for Home Use 9ft", - "image": "/assets/erpnext_demo/images/wind-turbine.png", - "item_code": "Wind Mill A Series", - "item_group": "Products", - "item_name": "Wind Mill A Series" - }, - { - "item_defaults": [{ - "default_supplier": null, - "default_warehouse": "Finished Goods" - }], - "description": "Small Wind Turbine for Home Use\n\n\n", - "image": "/assets/erpnext_demo/images/wind-turbine-1.jpg", - "item_code": "Wind Turbine", - "item_group": "Products", - "item_name": "Wind Turbine", - "has_variants": 1, - "has_serial_no": 1, - "attributes":[ - { "attribute": "Size" } - ] - }, - { - "item_defaults": [{ - "default_supplier": "HomeBase", - "default_warehouse": "Stores" - }], - "description": "1.5 in. Diameter x 36 in. Mild Steel Tubing", - "image": null, - "item_code": "Bearing Pipe", - "item_group": "Raw Material", - "item_name": "Bearing Pipe" - }, - { - "item_defaults": [{ - "default_supplier": "New World Realty", - "default_warehouse": "Stores" - }], - "description": "1/32 in. x 24 in. x 47 in. HDPE Opaque Sheet", - "image": null, - "item_code": "Wing Sheet", - "item_group": "Raw Material", - "item_name": "Wing Sheet" - }, - { - "item_defaults": [{ - "default_supplier": "Eagle Hardware", - "default_warehouse": "Stores" - }], - "description": "3/16 in. x 6 in. x 6 in. Low Carbon Steel Plate", - "image": null, - "item_code": "Upper Bearing Plate", - "item_group": "Raw Material", - "item_name": "Upper Bearing Plate" - }, - { - "item_defaults": [{ - "default_supplier": "Asiatic Solutions", - "default_warehouse": "Stores" - }], - "description": "Bearing Assembly", - "image": null, - "item_code": "Bearing Assembly", - "item_group": "Sub Assemblies", - "item_name": "Bearing Assembly" - }, - { - "item_defaults": [{ - "default_supplier": "HomeBase", - "default_warehouse": "Stores" - }], - "description": "3/4 in. x 2 ft. x 4 ft. Pine Plywood", - "image": null, - "item_code": "Base Plate", - "item_group": "Raw Material", - "item_name": "Base Plate", - "is_sub_contracted_item": 1 - }, - { - "item_defaults": [{ - "default_supplier": "Scott Ties", - "default_warehouse": "Stores" - }], - "description": "N/A", - "image": null, - "item_code": "Stand", - "item_group": "Raw Material", - "item_name": "Stand" - }, - { - "item_defaults": [{ - "default_supplier": "Eagle Hardware", - "default_warehouse": "Stores" - }], - "description": "1 in. x 3 in. x 1 ft. Multipurpose Al Alloy Bar", - "image": null, - "item_code": "Bearing Collar", - "item_group": "Raw Material", - "item_name": "Bearing Collar" - }, - { - "item_defaults": [{ - "default_supplier": "Eagle Hardware", - "default_warehouse": "Stores" - }], - "description": "1/4 in. x 6 in. x 6 in. Mild Steel Plate", - "image": null, - "item_code": "Base Bearing Plate", - "item_group": "Raw Material", - "item_name": "Base Bearing Plate" - }, - { - "item_defaults": [{ - "default_supplier": "HomeBase", - "default_warehouse": "Stores" - }], - "description": "15/32 in. x 4 ft. x 8 ft. 3-Ply Rtd Sheathing", - "image": null, - "item_code": "External Disc", - "item_group": "Raw Material", - "item_name": "External Disc" - }, - { - "item_defaults": [{ - "default_supplier": "Eagle Hardware", - "default_warehouse": "Stores" - }], - "description": "1.25 in. Diameter x 6 ft. Mild Steel Tubing", - "image": null, - "item_code": "Shaft", - "item_group": "Raw Material", - "item_name": "Shaft" - }, - { - "item_defaults": [{ - "default_supplier": "Ks Merchandise", - "default_warehouse": "Stores" - }], - "description": "1/2 in. x 2 ft. x 4 ft. Pine Plywood", - "image": null, - "item_code": "Blade Rib", - "item_group": "Raw Material", - "item_name": "Blade Rib" - }, - { - "item_defaults": [{ - "default_supplier": "HomeBase", - "default_warehouse": "Stores" - }], - "description": "For Bearing Collar", - "image": null, - "item_code": "Internal Disc", - "item_group": "Raw Material", - "item_name": "Internal Disc" - }, - { - "item_defaults": [{ - "default_supplier": null, - "default_warehouse": "Finished Goods" - }], - "description": "Small Wind Turbine for Home Use\n\n\n\n

Size: Small

", - "image": "/assets/erpnext_demo/images/wind-turbine-1.jpg", - "item_code": "Wind Turbine-S", - "item_group": "Products", - "item_name": "Wind Turbine-S", - "variant_of": "Wind Turbine", - "valuation_rate": 300, - "attributes":[ - { - "attribute": "Size", - "attribute_value": "Small" - } - ] - }, - { - "item_defaults": [{ - "default_supplier": null, - "default_warehouse": "Finished Goods" - }], - "description": "Small Wind Turbine for Home Use\n\n\n\n

Size: Medium

", - "image": "/assets/erpnext_demo/images/wind-turbine-1.jpg", - "item_code": "Wind Turbine-M", - "item_group": "Products", - "item_name": "Wind Turbine-M", - "variant_of": "Wind Turbine", - "valuation_rate": 300, - "attributes":[ - { - "attribute": "Size", - "attribute_value": "Medium" - } - ] - }, - { - "item_defaults": [{ - "default_supplier": null, - "default_warehouse": "Finished Goods" - }], - "description": "Small Wind Turbine for Home Use\n\n\n\n

Size: Large

", - "image": "/assets/erpnext_demo/images/wind-turbine-1.jpg", - "item_code": "Wind Turbine-L", - "item_group": "Products", - "item_name": "Wind Turbine-L", - "variant_of": "Wind Turbine", - "valuation_rate": 300, - "attributes":[ - { - "attribute": "Size", - "attribute_value": "Large" - } - ] - }, - { - "is_stock_item": 0, - "description": "Wind Mill A Series with Spare Bearing", - "item_code": "Wind Mill A Series with Spare Bearing", - "item_group": "Products", - "item_name": "Wind Mill A Series with Spare Bearing" - }, - { - "item_defaults": [{ - "default_supplier": "HomeBase", - "default_warehouse": "Stores" - }], - "description": "3/4 in. x 2 ft. x 4 ft. Pine Plywood", - "image": null, - "item_code": "Base Plate Un Painted", - "item_group": "Raw Material", - "item_name": "Base Plate Un Painted" - }, - { - "is_fixed_asset": 1, - "asset_category": "Furnitures", - "is_stock_item": 0, - "description": "Table", - "item_code": "Table", - "item_name": "Table", - "item_group": "Products" - }, - { - "is_fixed_asset": 1, - "asset_category": "Furnitures", - "is_stock_item": 0, - "description": "Chair", - "item_code": "Chair", - "item_name": "Chair", - "item_group": "Products" - }, - { - "is_fixed_asset": 1, - "asset_category": "Electronic Equipments", - "is_stock_item": 0, - "description": "Computer", - "item_code": "Computer", - "item_name": "Computer", - "item_group": "Products" - }, - { - "is_fixed_asset": 1, - "asset_category": "Electronic Equipments", - "is_stock_item": 0, - "description": "Mobile", - "item_code": "Mobile", - "item_name": "Mobile", - "item_group": "Products" - }, - { - "is_fixed_asset": 1, - "asset_category": "Softwares", - "is_stock_item": 0, - "description": "ERP", - "item_code": "ERP", - "item_name": "ERP", - "item_group": "All Item Groups" - }, - { - "is_fixed_asset": 1, - "asset_category": "Softwares", - "is_stock_item": 0, - "description": "Autocad", - "item_code": "Autocad", - "item_name": "Autocad", - "item_group": "All Item Groups" - }, - { - "is_stock_item": 1, - "has_batch_no": 1, - "create_new_batch": 1, - "valuation_rate": 200, - "item_defaults": [{ - "default_warehouse": "Stores" - }], - "description": "Corrugated Box", - "item_code": "Corrugated Box", - "item_name": "Corrugated Box", - "item_group": "All Item Groups" - } + { + "item_defaults": [ + { + "default_supplier": "Asiatic Solutions", + "default_warehouse": "Stores" + } + ], + "description": "For Upper Bearing", + "image": "/assets/erpnext_demo/images/disc.png", + "item_code": "Disc Collars", + "item_group": "Raw Material", + "item_name": "Disc Collars" + }, + { + "item_defaults": [ + { + "default_supplier": "Nan Duskin", + "default_warehouse": "Stores" + } + ], + "description": "CAST IRON, MCMASTER PART NO. 3710T13", + "image": "/assets/erpnext_demo/images/bearing.jpg", + "item_code": "Bearing Block", + "item_group": "Raw Material", + "item_name": "Bearing Block" + }, + { + "item_defaults": [ + { + "default_supplier": null, + "default_warehouse": "Finished Goods" + } + ], + "description": "Wind Mill C Series for Commercial Use 18ft", + "image": "/assets/erpnext_demo/images/wind-turbine-2.png", + "item_code": "Wind MIll C Series", + "item_group": "Products", + "item_name": "Wind MIll C Series" + }, + { + "item_defaults": [ + { + "default_supplier": null, + "default_warehouse": "Finished Goods" + } + ], + "description": "Wind Mill A Series for Home Use 9ft", + "image": "/assets/erpnext_demo/images/wind-turbine.png", + "item_code": "Wind Mill A Series", + "item_group": "Products", + "item_name": "Wind Mill A Series" + }, + { + "item_defaults": [ + { + "default_supplier": null, + "default_warehouse": "Finished Goods" + } + ], + "description": "Small Wind Turbine for Home Use\n\n\n", + "image": "/assets/erpnext_demo/images/wind-turbine-1.jpg", + "item_code": "Wind Turbine", + "item_group": "Products", + "item_name": "Wind Turbine", + "has_variants": 1, + "has_serial_no": 1, + "attributes": [ + { + "attribute": "Size" + } + ] + }, + { + "item_defaults": [ + { + "default_supplier": "HomeBase", + "default_warehouse": "Stores" + } + ], + "description": "1.5 in. Diameter x 36 in. Mild Steel Tubing", + "image": null, + "item_code": "Bearing Pipe", + "item_group": "Raw Material", + "item_name": "Bearing Pipe" + }, + { + "item_defaults": [ + { + "default_supplier": "New World Realty", + "default_warehouse": "Stores" + } + ], + "description": "1/32 in. x 24 in. x 47 in. HDPE Opaque Sheet", + "image": null, + "item_code": "Wing Sheet", + "item_group": "Raw Material", + "item_name": "Wing Sheet" + }, + { + "item_defaults": [ + { + "default_supplier": "Eagle Hardware", + "default_warehouse": "Stores" + } + ], + "description": "3/16 in. x 6 in. x 6 in. Low Carbon Steel Plate", + "image": null, + "item_code": "Upper Bearing Plate", + "item_group": "Raw Material", + "item_name": "Upper Bearing Plate" + }, + { + "item_defaults": [ + { + "default_supplier": "Asiatic Solutions", + "default_warehouse": "Stores" + } + ], + "description": "Bearing Assembly", + "image": null, + "item_code": "Bearing Assembly", + "item_group": "Sub Assemblies", + "item_name": "Bearing Assembly" + }, + { + "item_defaults": [ + { + "default_supplier": "HomeBase", + "default_warehouse": "Stores" + } + ], + "description": "3/4 in. x 2 ft. x 4 ft. Pine Plywood", + "image": null, + "item_code": "Base Plate", + "item_group": "Raw Material", + "item_name": "Base Plate", + "is_sub_contracted_item": 1 + }, + { + "item_defaults": [ + { + "default_supplier": "Scott Ties", + "default_warehouse": "Stores" + } + ], + "description": "N/A", + "image": null, + "item_code": "Stand", + "item_group": "Raw Material", + "item_name": "Stand" + }, + { + "item_defaults": [ + { + "default_supplier": "Eagle Hardware", + "default_warehouse": "Stores" + } + ], + "description": "1 in. x 3 in. x 1 ft. Multipurpose Al Alloy Bar", + "image": null, + "item_code": "Bearing Collar", + "item_group": "Raw Material", + "item_name": "Bearing Collar" + }, + { + "item_defaults": [ + { + "default_supplier": "Eagle Hardware", + "default_warehouse": "Stores" + } + ], + "description": "1/4 in. x 6 in. x 6 in. Mild Steel Plate", + "image": null, + "item_code": "Base Bearing Plate", + "item_group": "Raw Material", + "item_name": "Base Bearing Plate" + }, + { + "item_defaults": [ + { + "default_supplier": "HomeBase", + "default_warehouse": "Stores" + } + ], + "description": "15/32 in. x 4 ft. x 8 ft. 3-Ply Rtd Sheathing", + "image": null, + "item_code": "External Disc", + "item_group": "Raw Material", + "item_name": "External Disc" + }, + { + "item_defaults": [ + { + "default_supplier": "Eagle Hardware", + "default_warehouse": "Stores" + } + ], + "description": "1.25 in. Diameter x 6 ft. Mild Steel Tubing", + "image": null, + "item_code": "Shaft", + "item_group": "Raw Material", + "item_name": "Shaft" + }, + { + "item_defaults": [ + { + "default_supplier": "Ks Merchandise", + "default_warehouse": "Stores" + } + ], + "description": "1/2 in. x 2 ft. x 4 ft. Pine Plywood", + "image": null, + "item_code": "Blade Rib", + "item_group": "Raw Material", + "item_name": "Blade Rib" + }, + { + "item_defaults": [ + { + "default_supplier": "HomeBase", + "default_warehouse": "Stores" + } + ], + "description": "For Bearing Collar", + "image": null, + "item_code": "Internal Disc", + "item_group": "Raw Material", + "item_name": "Internal Disc" + }, + { + "item_defaults": [ + { + "default_supplier": null, + "default_warehouse": "Finished Goods" + } + ], + "description": "Small Wind Turbine for Home Use\n\n\n\n

Size: Small

", + "image": "/assets/erpnext_demo/images/wind-turbine-1.jpg", + "item_code": "Wind Turbine-S", + "item_group": "Products", + "item_name": "Wind Turbine-S", + "variant_of": "Wind Turbine", + "valuation_rate": 300, + "attributes": [ + { + "attribute": "Size", + "attribute_value": "Small" + } + ] + }, + { + "item_defaults": [ + { + "default_supplier": null, + "default_warehouse": "Finished Goods" + } + ], + "description": "Small Wind Turbine for Home Use\n\n\n\n

Size: Medium

", + "image": "/assets/erpnext_demo/images/wind-turbine-1.jpg", + "item_code": "Wind Turbine-M", + "item_group": "Products", + "item_name": "Wind Turbine-M", + "variant_of": "Wind Turbine", + "valuation_rate": 300, + "attributes": [ + { + "attribute": "Size", + "attribute_value": "Medium" + } + ] + }, + { + "item_defaults": [ + { + "default_supplier": null, + "default_warehouse": "Finished Goods" + } + ], + "description": "Small Wind Turbine for Home Use\n\n\n\n

Size: Large

", + "image": "/assets/erpnext_demo/images/wind-turbine-1.jpg", + "item_code": "Wind Turbine-L", + "item_group": "Products", + "item_name": "Wind Turbine-L", + "variant_of": "Wind Turbine", + "valuation_rate": 300, + "attributes": [ + { + "attribute": "Size", + "attribute_value": "Large" + } + ] + }, + { + "is_stock_item": 0, + "description": "Wind Mill A Series with Spare Bearing", + "item_code": "Wind Mill A Series with Spare Bearing", + "item_group": "Products", + "item_name": "Wind Mill A Series with Spare Bearing" + }, + { + "item_defaults": [ + { + "default_supplier": "HomeBase", + "default_warehouse": "Stores" + } + ], + "description": "3/4 in. x 2 ft. x 4 ft. Pine Plywood", + "image": null, + "item_code": "Base Plate Un Painted", + "item_group": "Raw Material", + "item_name": "Base Plate Un Painted" + }, + { + "is_fixed_asset": 1, + "asset_category": "Furnitures", + "is_stock_item": 0, + "description": "Table", + "item_code": "Table", + "item_name": "Table", + "item_group": "Products" + }, + { + "is_fixed_asset": 1, + "asset_category": "Furnitures", + "is_stock_item": 0, + "description": "Chair", + "item_code": "Chair", + "item_name": "Chair", + "item_group": "Products" + }, + { + "is_fixed_asset": 1, + "asset_category": "Electronic Equipments", + "is_stock_item": 0, + "description": "Computer", + "item_code": "Computer", + "item_name": "Computer", + "item_group": "Products" + }, + { + "is_fixed_asset": 1, + "asset_category": "Electronic Equipments", + "is_stock_item": 0, + "description": "Mobile", + "item_code": "Mobile", + "item_name": "Mobile", + "item_group": "Products" + }, + { + "is_fixed_asset": 1, + "asset_category": "Softwares", + "is_stock_item": 0, + "description": "ERP", + "item_code": "ERP", + "item_name": "ERP", + "item_group": "All Item Groups" + }, + { + "is_fixed_asset": 1, + "asset_category": "Softwares", + "is_stock_item": 0, + "description": "Autocad", + "item_code": "Autocad", + "item_name": "Autocad", + "item_group": "All Item Groups" + }, + { + "is_stock_item": 1, + "has_batch_no": 1, + "create_new_batch": 1, + "valuation_rate": 200, + "item_defaults": [ + { + "default_warehouse": "Stores" + } + ], + "description": "Corrugated Box", + "item_code": "Corrugated Box", + "item_name": "Corrugated Box", + "item_group": "All Item Groups" + }, + { + "item_defaults": [ + { + "default_warehouse": "Finished Goods" + } + ], + "is_stock_item": 1, + "description": "OnePlus 6", + "item_code": "OnePlus 6", + "item_name": "OnePlus 6", + "item_group": "Products", + "domain": "Retail" + }, + { + "item_defaults": [ + { + "default_warehouse": "Finished Goods" + } + ], + "is_stock_item": 1, + "description": "OnePlus 6T", + "item_code": "OnePlus 6T", + "item_name": "OnePlus 6T", + "item_group": "Products", + "domain": "Retail" + }, + { + "item_defaults": [ + { + "default_warehouse": "Finished Goods" + } + ], + "is_stock_item": 1, + "description": "Xiaomi Poco F1", + "item_code": "Xiaomi Poco F1", + "item_name": "Xiaomi Poco F1", + "item_group": "Products", + "domain": "Retail" + }, + { + "item_defaults": [ + { + "default_warehouse": "Finished Goods" + } + ], + "is_stock_item": 1, + "description": "Iphone XS", + "item_code": "Iphone XS", + "item_name": "Iphone XS", + "item_group": "Products", + "domain": "Retail" + }, + { + "item_defaults": [ + { + "default_warehouse": "Finished Goods" + } + ], + "is_stock_item": 1, + "description": "Samsung Galaxy S9", + "item_code": "Samsung Galaxy S9", + "item_name": "Samsung Galaxy S9", + "item_group": "Products", + "domain": "Retail" + }, + { + "item_defaults": [ + { + "default_warehouse": "Finished Goods" + } + ], + "is_stock_item": 1, + "description": "Sony Bluetooth Headphone", + "item_code": "Sony Bluetooth Headphone", + "item_name": "Sony Bluetooth Headphone", + "item_group": "Products", + "domain": "Retail" + }, + { + "is_stock_item": 0, + "description": "Samsung Phone Repair", + "item_code": "Samsung Phone Repair", + "item_name": "Samsung Phone Repair", + "item_group": "Services", + "domain": "Retail" + }, + { + "is_stock_item": 0, + "description": "OnePlus Phone Repair", + "item_code": "OnePlus Phone Repair", + "item_name": "OnePlus Phone Repair", + "item_group": "Services", + "domain": "Retail" + }, + { + "is_stock_item": 0, + "description": "Xiaomi Phone Repair", + "item_code": "Xiaomi Phone Repair", + "item_name": "Xiaomi Phone Repair", + "item_group": "Services", + "domain": "Retail" + }, + { + "is_stock_item": 0, + "description": "Apple Phone Repair", + "item_code": "Apple Phone Repair", + "item_name": "Apple Phone Repair", + "item_group": "Services", + "domain": "Retail" + } ] \ No newline at end of file From 10dfd4a48faf37b7dab8c386c128f0b8e3b4b296 Mon Sep 17 00:00:00 2001 From: JodeQ Date: Mon, 10 Sep 2018 13:40:43 +0200 Subject: [PATCH 19/33] Show project attachments in portal view --- .../doctype/project_user/project_user.json | 56 ++++++++++++++++++- erpnext/templates/pages/projects.html | 26 ++++++++- erpnext/templates/pages/projects.js | 4 ++ erpnext/templates/pages/projects.py | 7 ++- 4 files changed, 88 insertions(+), 5 deletions(-) diff --git a/erpnext/projects/doctype/project_user/project_user.json b/erpnext/projects/doctype/project_user/project_user.json index a7cc810a0a..596681676f 100644 --- a/erpnext/projects/doctype/project_user/project_user.json +++ b/erpnext/projects/doctype/project_user/project_user.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, "beta": 0, @@ -11,16 +12,21 @@ "editable_grid": 1, "fields": [ { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "user", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, + "in_standard_filter": 0, "label": "User", "length": 0, "no_copy": 0, @@ -30,23 +36,30 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, "search_index": 1, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "welcome_email_sent", "fieldtype": "Check", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Welcome email sent", "length": 0, "no_copy": 0, @@ -55,24 +68,58 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 1, + "fieldname": "view_attachments", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "View attachments", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "idx": 0, "image_view": 0, "in_create": 0, - "is_submittable": 0, "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2016-07-11 03:28:04.756894", + "modified": "2018-09-09 12:39:38.376816", "modified_by": "Administrator", "module": "Projects", "name": "Project User", @@ -82,7 +129,10 @@ "quick_entry": 0, "read_only": 0, "read_only_onload": 0, + "show_name_in_global_search": 0, "sort_field": "modified", "sort_order": "DESC", - "track_seen": 0 + "track_changes": 0, + "track_seen": 0, + "track_views": 0 } \ No newline at end of file diff --git a/erpnext/templates/pages/projects.html b/erpnext/templates/pages/projects.html index 765e43fb36..baa2ae62cc 100644 --- a/erpnext/templates/pages/projects.html +++ b/erpnext/templates/pages/projects.html @@ -57,10 +57,34 @@ {% else %}

{{ _("No time sheets") }}

{% endif %} + +{% if doc.attachments %} +
+ +

{{ _("Attachments") }}

+
+ {% for attachment in doc.attachments %} + + {% endfor %} +
+{% endif %} + {% endblock %} diff --git a/erpnext/templates/pages/projects.js b/erpnext/templates/pages/projects.js index 99f0663ee4..b6a2553aed 100644 --- a/erpnext/templates/pages/projects.js +++ b/erpnext/templates/pages/projects.js @@ -36,6 +36,10 @@ frappe.ready(function() { more_items('timeline', false); }); + $(".file-size").each(function() { + $(this).text(frappe.form.formatters.FileSize($(this).text())); + }); + var reload_items = function(item_status, item, $btn) { $.ajax({ diff --git a/erpnext/templates/pages/projects.py b/erpnext/templates/pages/projects.py index d68770dc4d..ddca27455e 100644 --- a/erpnext/templates/pages/projects.py +++ b/erpnext/templates/pages/projects.py @@ -6,7 +6,7 @@ import frappe import json def get_context(context): - project_user = frappe.db.get_value("Project User", {"parent": frappe.form_dict.project, "user": frappe.session.user} , "user") + project_user = frappe.db.get_value("Project User", {"parent": frappe.form_dict.project, "user": frappe.session.user} , ["user", "view_attachments"], as_dict= True) if not project_user or frappe.session.user == 'Guest': raise frappe.PermissionError @@ -22,6 +22,8 @@ def get_context(context): project.timesheets = get_timesheets(project.name, start=0, search=frappe.form_dict.get("search")) + if project_user.view_attachments: + project.attachments = get_attachments(project.name) context.doc = project @@ -92,3 +94,6 @@ def get_timesheet_html(project, start=0): return frappe.render_template("erpnext/templates/includes/projects/project_timesheets.html", {"doc": {"timesheets": get_timesheets(project, start)}}, is_path=True) +def get_attachments(project): + return frappe.get_all('File', filters= {"attached_to_name": project, "attached_to_doctype": 'Project', "is_private":0}, + fields=['file_name','file_url', 'file_size']) From 7c443264a47664f4d15d84827b244a5a06b33bf4 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 <42651287+deepeshgarg007@users.noreply.github.com> Date: Mon, 15 Oct 2018 18:22:28 +0530 Subject: [PATCH 20/33] Currency symbol bug fix (#15690) --- .../sales_person_wise_transaction_summary.py | 111 ++++++++++++++++-- 1 file changed, 103 insertions(+), 8 deletions(-) diff --git a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py index 8897792114..180fd092cb 100644 --- a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py +++ b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py @@ -5,6 +5,7 @@ from __future__ import unicode_literals import frappe from frappe import msgprint, _ from frappe.utils import flt +from erpnext import get_company_currency def execute(filters=None): if not filters: filters = {} @@ -14,12 +15,14 @@ def execute(filters=None): item_details = get_item_details() data = [] + company_currency = get_company_currency(filters["company"]) + for d in entries: if d.stock_qty > 0 or filters.get('show_return_entries', 0): data.append([ d.name, d.customer, d.territory, item_details.get(d.item_code, {}).get("website_warehouse"), d.posting_date, d.item_code, item_details.get(d.item_code, {}).get("item_group"), item_details.get(d.item_code, {}).get("brand"), - d.stock_qty, d.base_net_amount, d.sales_person, d.allocated_percentage, d.contribution_amt + d.stock_qty, d.base_net_amount, d.sales_person, d.allocated_percentage, d.contribution_amt, company_currency ]) if data: @@ -32,13 +35,105 @@ def get_columns(filters): if not filters.get("doc_type"): msgprint(_("Please select the document type first"), raise_exception=1) - return [filters["doc_type"] + ":Link/" + filters["doc_type"] + ":140", - _("Customer") + ":Link/Customer:140", _("Territory") + ":Link/Territory:100", _("Warehouse") + ":Link/Warehouse:100", - _("Posting Date") + ":Date:100", - _("Item Code") + ":Link/Item:120", _("Item Group") + ":Link/Item Group:120", - _("Brand") + ":Link/Brand:120", _("Qty") + ":Float:100", _("Amount") + ":Currency:120", - _("Sales Person") + ":Link/Sales Person:140", _("Contribution %") + "::110", - _("Contribution Amount") + ":Currency:140"] + columns = [ + { + "label": _(filters["doc_type"]), + "options": filters["doc_type"], + "fieldname": frappe.scrub(filters['doc_type']), + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Customer"), + "options": "Customer", + "fieldname": "customer", + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Territory"), + "options": "Territory", + "fieldname": "territory", + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Warehouse"), + "options": "Warehouse", + "fieldname": "warehouse", + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Posting Date"), + "fieldname": "posting_date", + "fieldtype": "Date", + "width": 140 + }, + { + "label": _("Item Code"), + "options": "Item", + "fieldname": "item_code", + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Item Group"), + "options": "Item Group", + "fieldname": "item_group", + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Brand"), + "options": "Brand", + "fieldname": "brand", + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Qty"), + "fieldname": "qty", + "fieldtype": "Float", + "width": 140 + }, + { + "label": _("Amount"), + "options": "currency", + "fieldname": "amount", + "fieldtype": "Currency", + "width": 140 + }, + { + "label": _("Sales Person"), + "options": "Sales Person", + "fieldname": "sales_person", + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Contribution %"), + "fieldname": "contribution", + "fieldtype": "Float", + "width": 140 + }, + { + "label": _("Contribution Amount"), + "options": "currency", + "fieldname": "contribution_amt", + "fieldtype": "Currency", + "width": 140 + }, + { + "label":_("Currency"), + "options": "Currency", + "fieldname":"currency", + "fieldtype":"Link", + "hidden" : 1 + } + ] + + return columns def get_entries(filters): date_field = filters["doc_type"] == "Sales Order" and "transaction_date" or "posting_date" From 7844b79274b7f6cc7beb20e66383d07e03cdfaeb Mon Sep 17 00:00:00 2001 From: Bibin <17405044+bibinqcs@users.noreply.github.com> Date: Mon, 15 Oct 2018 16:55:26 +0400 Subject: [PATCH 21/33] [Bug-Fix] accounts_receivable.html (#15688) * Update accounts_receivable.html In the print format and PDF the total was showing as 0 (Zero) , when I made these changes it fixed the issue * Update accounts_receivable.html --- .../accounts_receivable/accounts_receivable.html | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html index 0a21181399..7f663d8ded 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html @@ -167,7 +167,7 @@ {%= format_currency(data[i]["paid_amount"], data[i]["currency"]) %} - {%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["credit_note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %} + {%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["credit_note"], data[i]["currency"]) : format_currency(data[i]["debit_note"], data[i]["currency"]) %} {% } %} {%= format_currency(data[i]["outstanding_amount"], data[i]["currency"]) %} @@ -189,15 +189,15 @@ {% } %} {%= __("Total") %} - {%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"] ) %} + {%= format_currency(data[i]["invoiced_amount"], data[i]["currency"] ) %} {% if(!filters.show_pdc_in_print) { %} - {%= format_currency(data[i]["Paid Amount"], data[i]["currency"]) %} - {%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["Credit Note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %} + {%= format_currency(data[i]["paid_amount"], data[i]["currency"]) %} + {%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["credit_note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %} {% } %} - {%= format_currency(data[i]["Outstanding Amount"], data[i]["currency"]) %} + {%= format_currency(data[i]["outstanding_amount"], data[i]["currency"]) %} {% if(filters.show_pdc_in_print) { %} {% if(report.report_name === "Accounts Receivable") { %} @@ -238,4 +238,4 @@ {% } %} -

{{ __("Printed On ") }}{%= dateutil.str_to_user(dateutil.get_datetime_as_string()) %}

\ No newline at end of file +

{{ __("Printed On ") }}{%= dateutil.str_to_user(dateutil.get_datetime_as_string()) %}

From 615571dd21fe33f9db30e90b123bcefbd42527e0 Mon Sep 17 00:00:00 2001 From: Charles-Henri Decultot Date: Mon, 15 Oct 2018 14:56:02 +0200 Subject: [PATCH 22/33] Add safe decode for payer name (#15692) --- erpnext/accounts/doctype/payment_request/payment_request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py index 5fa0707333..f3e85b231d 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -123,7 +123,7 @@ class PaymentRequest(Document): "reference_doctype": "Payment Request", "reference_docname": self.name, "payer_email": self.email_to or frappe.session.user, - "payer_name": data.customer_name, + "payer_name": frappe.safe_decode(data.customer_name), "order_id": self.name, "currency": self.currency }) From 44ec05f79bfa3a2d76d160ac4805d36450ea8b8e Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 15 Oct 2018 18:56:16 +0530 Subject: [PATCH 23/33] fix(bom): deadlock issue via bom replace tool (#15694) --- erpnext/manufacturing/doctype/bom/bom.py | 3 ++- .../manufacturing/doctype/bom_update_tool/bom_update_tool.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index 7a2aa8a06b..0af7a86b93 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -354,7 +354,8 @@ class BOM(WebsiteGenerator): bom_list = self.traverse_tree(bom_list) for bom in bom_list: bom_obj = frappe.get_doc("BOM", bom) - bom_obj.on_update() + bom_obj.check_recursion() + bom_obj.update_exploded_items() return bom_list diff --git a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py index 3f6cb44c49..59861ceba3 100644 --- a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py +++ b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py @@ -62,7 +62,7 @@ class BOMUpdateTool(Document): bom_list.append(d[0]) self.get_parent_boms(d[0], bom_list) - return bom_list + return list(set(bom_list)) @frappe.whitelist() def enqueue_replace_bom(args): From 4bb90add1df6e6b5aa9cc69e6589ef7e8e902ae0 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 <42651287+deepeshgarg007@users.noreply.github.com> Date: Mon, 15 Oct 2018 19:07:49 +0530 Subject: [PATCH 24/33] Currency symbol bug fix (#15698) --- .../sales_person_wise_transaction_summary.py | 110 ++++++++++++++++-- 1 file changed, 103 insertions(+), 7 deletions(-) diff --git a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py index ae2cf8c550..345d608fef 100644 --- a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py +++ b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py @@ -5,6 +5,7 @@ from __future__ import unicode_literals import frappe from frappe import msgprint, _ from frappe.utils import flt +from erpnext import get_company_currency def execute(filters=None): if not filters: filters = {} @@ -14,12 +15,14 @@ def execute(filters=None): item_details = get_item_details() data = [] + company_currency = get_company_currency(filters["company"]) + for d in entries: if d.stock_qty > 0 or filters.get('show_return_entries', 0): data.append([ d.name, d.customer, d.territory, d.posting_date, d.item_code, item_details.get(d.item_code, {}).get("item_group"), item_details.get(d.item_code, {}).get("brand"), - d.stock_qty, d.base_net_amount, d.sales_person, d.allocated_percentage, d.contribution_amt + d.stock_qty, d.base_net_amount, d.sales_person, d.allocated_percentage, d.contribution_amt, company_currency ]) if data: @@ -32,12 +35,105 @@ def get_columns(filters): if not filters.get("doc_type"): msgprint(_("Please select the document type first"), raise_exception=1) - return [filters["doc_type"] + ":Link/" + filters["doc_type"] + ":140", - _("Customer") + ":Link/Customer:140", _("Territory") + ":Link/Territory:100", _("Posting Date") + ":Date:100", - _("Item Code") + ":Link/Item:120", _("Item Group") + ":Link/Item Group:120", - _("Brand") + ":Link/Brand:120", _("Qty") + ":Float:100", _("Amount") + ":Currency:120", - _("Sales Person") + ":Link/Sales Person:140", _("Contribution %") + "::110", - _("Contribution Amount") + ":Currency:140"] + columns = [ + { + "label": _(filters["doc_type"]), + "options": filters["doc_type"], + "fieldname": frappe.scrub(filters['doc_type']), + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Customer"), + "options": "Customer", + "fieldname": "customer", + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Territory"), + "options": "Territory", + "fieldname": "territory", + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Warehouse"), + "options": "Warehouse", + "fieldname": "warehouse", + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Posting Date"), + "fieldname": "posting_date", + "fieldtype": "Date", + "width": 140 + }, + { + "label": _("Item Code"), + "options": "Item", + "fieldname": "item_code", + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Item Group"), + "options": "Item Group", + "fieldname": "item_group", + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Brand"), + "options": "Brand", + "fieldname": "brand", + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Qty"), + "fieldname": "qty", + "fieldtype": "Float", + "width": 140 + }, + { + "label": _("Amount"), + "options": "currency", + "fieldname": "amount", + "fieldtype": "Currency", + "width": 140 + }, + { + "label": _("Sales Person"), + "options": "Sales Person", + "fieldname": "sales_person", + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Contribution %"), + "fieldname": "contribution", + "fieldtype": "Float", + "width": 140 + }, + { + "label": _("Contribution Amount"), + "options": "currency", + "fieldname": "contribution_amt", + "fieldtype": "Currency", + "width": 140 + }, + { + "label":_("Currency"), + "options": "Currency", + "fieldname":"currency", + "fieldtype":"Link", + "hidden" : 1 + } + ] + + return columns def get_entries(filters): date_field = filters["doc_type"] == "Sales Order" and "transaction_date" or "posting_date" From 666e6e665b18d4f4daaecd71c34ee6d4cc13e051 Mon Sep 17 00:00:00 2001 From: Joe Paul Date: Wed, 3 Oct 2018 13:22:00 +0530 Subject: [PATCH 25/33] feat: Add provision for prebilled subscription invoices (cherry picked from commit db33e6304d3167d0a2c0c9cee4a9405f5833120e) --- .../doctype/subscription/subscription.json | 34 ++++++++++++- .../doctype/subscription/subscription.py | 21 +++++++- .../doctype/subscription/test_subscription.py | 48 +++++++++++++++++++ 3 files changed, 100 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/subscription/subscription.json b/erpnext/accounts/doctype/subscription/subscription.json index 39ad0d4a80..aa29907d06 100644 --- a/erpnext/accounts/doctype/subscription/subscription.json +++ b/erpnext/accounts/doctype/subscription/subscription.json @@ -437,6 +437,38 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "generate_invoice_at_period_start", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Generate Invoice At Beginning Of Period", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -814,7 +846,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-08-21 16:15:44.533482", + "modified": "2018-10-04 10:29:03.338893", "modified_by": "Administrator", "module": "Accounts", "name": "Subscription", diff --git a/erpnext/accounts/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py index fe39161960..7fb6b7a096 100644 --- a/erpnext/accounts/doctype/subscription/subscription.py +++ b/erpnext/accounts/doctype/subscription/subscription.py @@ -321,6 +321,23 @@ class Subscription(Document): self.save() + @property + def is_postpaid_to_invoice(self): + return getdate(nowdate()) > getdate(self.current_invoice_end) or \ + (getdate(nowdate()) >= getdate(self.current_invoice_end) and getdate(self.current_invoice_end) == getdate(self.current_invoice_start)) and \ + not self.has_outstanding_invoice() + + @property + def is_prepaid_to_invoice(self): + if not self.generate_invoice_at_period_start: + return False + + if self.is_new_subscription(): + return True + + # Check invoice dates and make sure it doesn't have outstanding invoices + return getdate(nowdate()) >= getdate(self.current_invoice_start) and not self.has_outstanding_invoice() + def process_for_active(self): """ Called by `process` if the status of the `Subscription` is 'Active'. @@ -330,7 +347,7 @@ class Subscription(Document): 2. Change the `Subscription` status to 'Past Due Date' 3. Change the `Subscription` status to 'Cancelled' """ - if getdate(nowdate()) > getdate(self.current_invoice_end) or (getdate(nowdate()) >= getdate(self.current_invoice_end) and getdate(self.current_invoice_end) == getdate(self.current_invoice_start)) and not self.has_outstanding_invoice(): + if self.is_postpaid_to_invoice or self.is_prepaid_to_invoice: self.generate_invoice() if self.current_invoice_is_past_due(): self.status = 'Past Due Date' @@ -338,7 +355,7 @@ class Subscription(Document): if self.current_invoice_is_past_due() and getdate(nowdate()) > getdate(self.current_invoice_end): self.status = 'Past Due Date' - if self.cancel_at_period_end and getdate(nowdate()) > self.current_invoice_end: + if self.cancel_at_period_end and getdate(nowdate()) > getdate(self.current_invoice_end): self.cancel_subscription_at_period_end() def cancel_subscription_at_period_end(self): diff --git a/erpnext/accounts/doctype/subscription/test_subscription.py b/erpnext/accounts/doctype/subscription/test_subscription.py index c42b8e824b..a5285ea16a 100644 --- a/erpnext/accounts/doctype/subscription/test_subscription.py +++ b/erpnext/accounts/doctype/subscription/test_subscription.py @@ -500,3 +500,51 @@ class TestSubscription(unittest.TestCase): self.assertEqual(invoice.apply_discount_on, 'Grand Total') subscription.delete() + + def test_prepaid_subscriptions(self): + # Create a non pre-billed subscription, processing should not create + # invoices. + subscription = frappe.new_doc('Subscription') + subscription.subscriber = '_Test Customer' + subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1}) + subscription.save() + subscription.process() + + self.assertEqual(len(subscription.invoices), 0) + + # Change the subscription type to prebilled and process it. + # Prepaid invoice should be generated + subscription.generate_invoice_at_period_start = True + subscription.save() + subscription.process() + + self.assertEqual(len(subscription.invoices), 1) + + def test_prepaid_subscriptions_with_prorate_true(self): + settings = frappe.get_single('Subscription Settings') + to_prorate = settings.prorate + settings.prorate = 1 + settings.save() + + subscription = frappe.new_doc('Subscription') + subscription.subscriber = '_Test Customer' + subscription.generate_invoice_at_period_start = True + subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1}) + subscription.save() + subscription.cancel_subscription() + + self.assertEqual(len(subscription.invoices), 1) + + current_inv = subscription.get_current_invoice() + self.assertEqual(current_inv.status, "Unpaid") + + diff = flt(date_diff(nowdate(), subscription.current_invoice_start) + 1) + plan_days = flt(date_diff(subscription.current_invoice_end, subscription.current_invoice_start) + 1) + prorate_factor = flt(diff / plan_days) + + self.assertEqual(flt(current_inv.grand_total, 2), flt(prorate_factor * 900, 2)) + + settings.prorate = to_prorate + settings.save() + + subscription.delete() From 8aca56836b4f857e3f0b4ddd020579f555f436a7 Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 16 Oct 2018 12:00:46 +0530 Subject: [PATCH 26/33] fix(margin): Make user avatar display in line --- .../templates/includes/projects/project_timesheets.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/templates/includes/projects/project_timesheets.html b/erpnext/templates/includes/projects/project_timesheets.html index 66f47713d2..fb3806cd98 100644 --- a/erpnext/templates/includes/projects/project_timesheets.html +++ b/erpnext/templates/includes/projects/project_timesheets.html @@ -2,16 +2,16 @@
-
+
{{ timesheet.info.name }}
{{ _("From") }} {{ frappe.format_date(timesheet.from_time) }} {{ _("to") }} {{ frappe.format_date(timesheet.to_time) }}
-
- +
+
-
+
{{ timesheet.info.comment_count }} From 82660913a5f3902e3536b2bc557a019560a88a1a Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 16 Oct 2018 12:15:56 +0530 Subject: [PATCH 27/33] fix(report): Add column for Item Name --- .../report/item_price_stock/item_price_stock.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/report/item_price_stock/item_price_stock.py b/erpnext/stock/report/item_price_stock/item_price_stock.py index 30fcad8073..e539aff59c 100644 --- a/erpnext/stock/report/item_price_stock/item_price_stock.py +++ b/erpnext/stock/report/item_price_stock/item_price_stock.py @@ -13,12 +13,18 @@ def execute(filters=None): def get_columns(): return [ { - "label": _("Item Name"), - "fieldname": "item_name", + "label": _("Item Code"), + "fieldname": "item_code", "fieldtype": "Link", "options": "Item", "width": 120 }, + { + "label": _("Item Name"), + "fieldname": "item_name", + "fieldtype": "Data", + "width": 120 + }, { "label": _("Brand"), "fieldname": "brand", @@ -76,7 +82,7 @@ def get_item_price_qty_data(filters): if filters.get("item_code"): conditions += "where a.item_code=%(item_code)s" - item_results = frappe.db.sql("""select a.item_code as item_name, a.name as price_list_name, + item_results = frappe.db.sql("""select a.item_code, a.item_name, a.name as price_list_name, a.brand as brand, b.warehouse as warehouse, b.actual_qty as actual_qty from `tabItem Price` a left join `tabBin` b ON a.item_code = b.item_code @@ -92,6 +98,7 @@ def get_item_price_qty_data(filters): if item_results: for item_dict in item_results: data = { + 'item_code': item_dict.item_code, 'item_name': item_dict.item_name, 'brand': item_dict.brand, 'warehouse': item_dict.warehouse, From ff0deedca93eb056992f59558812ce3390bc9c88 Mon Sep 17 00:00:00 2001 From: Shreya Shah Date: Tue, 16 Oct 2018 14:34:30 +0530 Subject: [PATCH 28/33] fix(discount-amount): Print hide discount_amount if print without amount (#15704) --- erpnext/stock/doctype/delivery_note/delivery_note.js | 4 +++- erpnext/stock/doctype/delivery_note/delivery_note.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js index e0ee3708f4..d6a3c0ea0c 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.js +++ b/erpnext/stock/doctype/delivery_note/delivery_note.js @@ -255,13 +255,13 @@ erpnext.stock.delivery_note.set_print_hide = function(doc, cdt, cdn){ var dn_item_fields = frappe.meta.docfield_map['Delivery Note Item']; var dn_fields_copy = dn_fields; var dn_item_fields_copy = dn_item_fields; - if (doc.print_without_amount) { dn_fields['currency'].print_hide = 1; dn_item_fields['rate'].print_hide = 1; dn_item_fields['discount_percentage'].print_hide = 1; dn_item_fields['price_list_rate'].print_hide = 1; dn_item_fields['amount'].print_hide = 1; + dn_item_fields['discount_amount'].print_hide = 1; dn_fields['taxes'].print_hide = 1; } else { if (dn_fields_copy['currency'].print_hide != 1) @@ -270,6 +270,8 @@ erpnext.stock.delivery_note.set_print_hide = function(doc, cdt, cdn){ dn_item_fields['rate'].print_hide = 0; if (dn_item_fields_copy['amount'].print_hide != 1) dn_item_fields['amount'].print_hide = 0; + if (dn_item_fields_copy['discount_amount'].print_hide != 1) + dn_item_fields['discount_amount'].print_hide = 0; if (dn_fields_copy['taxes'].print_hide != 1) dn_fields['taxes'].print_hide = 0; } diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index 70a061208f..ccc6da4031 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -75,7 +75,7 @@ class DeliveryNote(SellingController): item_meta = frappe.get_meta("Delivery Note Item") print_hide_fields = { "parent": ["grand_total", "rounded_total", "in_words", "currency", "total", "taxes"], - "items": ["rate", "amount", "price_list_rate", "discount_percentage"] + "items": ["rate", "amount", "discount_amount", "price_list_rate", "discount_percentage"] } for key, fieldname in print_hide_fields.items(): From e45868a3c69cc5ea918b67a5022c07897734d5a1 Mon Sep 17 00:00:00 2001 From: Shreya Shah Date: Tue, 16 Oct 2018 14:34:56 +0530 Subject: [PATCH 29/33] fix(discount-amount): Print hide discount_amount if print without amount (#15705) --- erpnext/stock/doctype/delivery_note/delivery_note.js | 3 +++ erpnext/stock/doctype/delivery_note/delivery_note.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js index 75e7590d82..daa8318fda 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.js +++ b/erpnext/stock/doctype/delivery_note/delivery_note.js @@ -279,6 +279,7 @@ erpnext.stock.delivery_note.set_print_hide = function(doc, cdt, cdn){ dn_item_fields['discount_percentage'].print_hide = 1; dn_item_fields['price_list_rate'].print_hide = 1; dn_item_fields['amount'].print_hide = 1; + dn_item_fields['discount_amount'].print_hide = 1; dn_fields['taxes'].print_hide = 1; } else { if (dn_fields_copy['currency'].print_hide != 1) @@ -287,6 +288,8 @@ erpnext.stock.delivery_note.set_print_hide = function(doc, cdt, cdn){ dn_item_fields['rate'].print_hide = 0; if (dn_item_fields_copy['amount'].print_hide != 1) dn_item_fields['amount'].print_hide = 0; + if (dn_item_fields_copy['discount_amount'].print_hide != 1) + dn_item_fields['discount_amount'].print_hide = 0 if (dn_fields_copy['taxes'].print_hide != 1) dn_fields['taxes'].print_hide = 0; } diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index 6fec6121c8..ab624d17db 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -74,7 +74,7 @@ class DeliveryNote(SellingController): item_meta = frappe.get_meta("Delivery Note Item") print_hide_fields = { "parent": ["grand_total", "rounded_total", "in_words", "currency", "total", "taxes"], - "items": ["rate", "amount", "price_list_rate", "discount_percentage"] + "items": ["rate", "amount", "discount_amount", "price_list_rate", "discount_percentage"] } for key, fieldname in print_hide_fields.items(): From 8e71074e1cb95ebe07a4bdd3b7eadb171e676eab Mon Sep 17 00:00:00 2001 From: Shreya Shah Date: Tue, 16 Oct 2018 14:36:49 +0530 Subject: [PATCH 30/33] fix(report): Add column for Item Name (#15702) --- .../report/item_price_stock/item_price_stock.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/report/item_price_stock/item_price_stock.py b/erpnext/stock/report/item_price_stock/item_price_stock.py index ed010cd17a..3a72697b04 100644 --- a/erpnext/stock/report/item_price_stock/item_price_stock.py +++ b/erpnext/stock/report/item_price_stock/item_price_stock.py @@ -13,12 +13,18 @@ def execute(filters=None): def get_columns(): return [ { - "label": _("Item Name"), - "fieldname": "item_name", + "label": _("Item Code"), + "fieldname": "item_code", "fieldtype": "Link", "options": "Item", "width": 120 }, + { + "label": _("Item Name"), + "fieldname": "item_name", + "fieldtype": "Data", + "width": 120 + }, { "label": _("Warehouse"), "fieldname": "warehouse", @@ -70,7 +76,7 @@ def get_item_price_qty_data(filters): if filters.get("item_code"): conditions += "where a.item_code=%(item_code)s" - item_results = frappe.db.sql("""select a.item_code as item_name, a.name as price_list_name, + item_results = frappe.db.sql("""select a.item_code, a.item_name, a.name as price_list_name, b.warehouse as warehouse, b.actual_qty as actual_qty from `tabItem Price` a left join `tabBin` b ON a.item_code = b.item_code @@ -86,6 +92,7 @@ def get_item_price_qty_data(filters): if item_results: for item_dict in item_results: data = { + 'item_code': item_dict.item_code, 'item_name': item_dict.item_name, 'warehouse': item_dict.warehouse, 'stock_available': item_dict.actual_qty or 0, From 0cbb9b54fa1edb9809c43113caf680dfba88c8a2 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 <42651287+deepeshgarg007@users.noreply.github.com> Date: Tue, 16 Oct 2018 14:39:16 +0530 Subject: [PATCH 31/33] Deprecating subscriber doctype (#15695) * Depricating subscriber doctype * Removed naming series --- .../accounts/doctype/subscriber/__init__.py | 0 .../accounts/doctype/subscriber/subscriber.js | 2 - .../doctype/subscriber/subscriber.json | 129 ------------------ .../accounts/doctype/subscriber/subscriber.py | 9 -- .../subscriber/subscriber_dashboard.py | 14 -- .../doctype/subscriber/test_subscriber.js | 23 ---- .../doctype/subscriber/test_subscriber.py | 9 -- .../doctype/subscription/subscription.json | 11 +- .../doctype/subscription/subscription.py | 11 +- .../v11_0/remove_subscriber_doctype.py | 15 ++ .../doctype/customer/customer_dashboard.py | 4 + 11 files changed, 27 insertions(+), 200 deletions(-) delete mode 100644 erpnext/accounts/doctype/subscriber/__init__.py delete mode 100644 erpnext/accounts/doctype/subscriber/subscriber.js delete mode 100644 erpnext/accounts/doctype/subscriber/subscriber.json delete mode 100644 erpnext/accounts/doctype/subscriber/subscriber.py delete mode 100644 erpnext/accounts/doctype/subscriber/subscriber_dashboard.py delete mode 100644 erpnext/accounts/doctype/subscriber/test_subscriber.js delete mode 100644 erpnext/accounts/doctype/subscriber/test_subscriber.py create mode 100644 erpnext/patches/v11_0/remove_subscriber_doctype.py diff --git a/erpnext/accounts/doctype/subscriber/__init__.py b/erpnext/accounts/doctype/subscriber/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/accounts/doctype/subscriber/subscriber.js b/erpnext/accounts/doctype/subscriber/subscriber.js deleted file mode 100644 index f5ea8047c6..0000000000 --- a/erpnext/accounts/doctype/subscriber/subscriber.js +++ /dev/null @@ -1,2 +0,0 @@ -// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt diff --git a/erpnext/accounts/doctype/subscriber/subscriber.json b/erpnext/accounts/doctype/subscriber/subscriber.json deleted file mode 100644 index 3fb7fdb087..0000000000 --- a/erpnext/accounts/doctype/subscriber/subscriber.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "field:subscriber_name", - "beta": 0, - "creation": "2018-02-24 11:17:46.809140", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "customer", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Customer", - "length": 0, - "no_copy": 0, - "options": "Customer", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "customer.customer_name", - "fieldname": "subscriber_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Subscriber Name", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 1 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-07-11 15:13:30.056470", - "modified_by": "Administrator", - "module": "Accounts", - "name": "Subscriber", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0 -} \ No newline at end of file diff --git a/erpnext/accounts/doctype/subscriber/subscriber.py b/erpnext/accounts/doctype/subscriber/subscriber.py deleted file mode 100644 index 03eb0f5ebb..0000000000 --- a/erpnext/accounts/doctype/subscriber/subscriber.py +++ /dev/null @@ -1,9 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - -from __future__ import unicode_literals -from frappe.model.document import Document - -class Subscriber(Document): - pass diff --git a/erpnext/accounts/doctype/subscriber/subscriber_dashboard.py b/erpnext/accounts/doctype/subscriber/subscriber_dashboard.py deleted file mode 100644 index 3120384c6a..0000000000 --- a/erpnext/accounts/doctype/subscriber/subscriber_dashboard.py +++ /dev/null @@ -1,14 +0,0 @@ -from frappe import _ - -def get_data(): - return { - 'heatmap': True, - 'heatmap_message': _('This is based on transactions against this Subscriber. See timeline below for details'), - 'fieldname': 'subscriber', - 'transactions': [ - { - 'label': _('Subscriptions'), - 'items': ['Subscription'] - } - ] - } \ No newline at end of file diff --git a/erpnext/accounts/doctype/subscriber/test_subscriber.js b/erpnext/accounts/doctype/subscriber/test_subscriber.js deleted file mode 100644 index 1fd4a1e011..0000000000 --- a/erpnext/accounts/doctype/subscriber/test_subscriber.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Subscriber", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Subscriber - () => frappe.tests.make('Subscriber', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/subscriber/test_subscriber.py b/erpnext/accounts/doctype/subscriber/test_subscriber.py deleted file mode 100644 index 3e2fc07c7b..0000000000 --- a/erpnext/accounts/doctype/subscriber/test_subscriber.py +++ /dev/null @@ -1,9 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt -from __future__ import unicode_literals - -import unittest - -class TestSubscriber(unittest.TestCase): - pass diff --git a/erpnext/accounts/doctype/subscription/subscription.json b/erpnext/accounts/doctype/subscription/subscription.json index aa29907d06..c9305164f0 100644 --- a/erpnext/accounts/doctype/subscription/subscription.json +++ b/erpnext/accounts/doctype/subscription/subscription.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, @@ -20,7 +21,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "subscriber", + "fieldname": "customer", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, @@ -29,10 +30,10 @@ "in_global_search": 0, "in_list_view": 1, "in_standard_filter": 0, - "label": "Subscriber", + "label": "Customer", "length": 0, "no_copy": 0, - "options": "Subscriber", + "options": "Customer", "permlevel": 0, "precision": "", "print_hide": 0, @@ -846,7 +847,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-04 10:29:03.338893", + "modified": "2018-10-14 10:38:55.545540", "modified_by": "Administrator", "module": "Accounts", "name": "Subscription", @@ -922,4 +923,4 @@ "track_changes": 1, "track_seen": 0, "track_views": 0 -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py index 7fb6b7a096..2bb2c004af 100644 --- a/erpnext/accounts/doctype/subscription/subscription.py +++ b/erpnext/accounts/doctype/subscription/subscription.py @@ -239,7 +239,7 @@ class Subscription(Document): invoice = frappe.new_doc('Sales Invoice') invoice.set_posting_time = 1 invoice.posting_date = self.current_invoice_start - invoice.customer = self.get_customer(self.subscriber) + invoice.customer = self.customer # Subscription is better suited for service items. I won't update `update_stock` # for that reason @@ -282,13 +282,6 @@ class Subscription(Document): return invoice - @staticmethod - def get_customer(subscriber_name): - """ - Returns the `Customer` linked to the `Subscriber` - """ - return frappe.db.get_value('Subscriber', subscriber_name, 'customer') - def get_items_from_plans(self, plans, prorate=0): """ Returns the `Item`s linked to `Subscription Plan` @@ -297,7 +290,7 @@ class Subscription(Document): prorate_factor = get_prorata_factor(self.current_invoice_end, self.current_invoice_start) items = [] - customer = self.get_customer(self.subscriber) + customer = self.customer for plan in plans: item_code = frappe.db.get_value("Subscription Plan", plan.plan, "item") if not prorate: diff --git a/erpnext/patches/v11_0/remove_subscriber_doctype.py b/erpnext/patches/v11_0/remove_subscriber_doctype.py new file mode 100644 index 0000000000..4e50c35cd2 --- /dev/null +++ b/erpnext/patches/v11_0/remove_subscriber_doctype.py @@ -0,0 +1,15 @@ +import frappe +from frappe.model.utils.rename_field import rename_field + +def execute(): + """ copy subscribe field to customer """ + frappe.reload_doc("accounts","doctype","subscription") + + if frappe.db.exists("DocType", "Subscriber"): + if frappe.db.has_column('Subscription','subscriber'): + frappe.db.sql(""" + update `tabSubscription` s1 + set customer=(select customer from tabSubscriber where name=s1.subscriber) + """) + + frappe.delete_doc("DocType", "Subscriber") \ No newline at end of file diff --git a/erpnext/selling/doctype/customer/customer_dashboard.py b/erpnext/selling/doctype/customer/customer_dashboard.py index 9b905f8512..bf01363bd6 100644 --- a/erpnext/selling/doctype/customer/customer_dashboard.py +++ b/erpnext/selling/doctype/customer/customer_dashboard.py @@ -25,6 +25,10 @@ def get_data(): { 'label': _('Pricing'), 'items': ['Pricing Rule'] + }, + { + 'label': _('Subscriptions'), + 'items': ['Subscription'] } ] } \ No newline at end of file From bb1b6b42e2a4dcfb837a03c876b49ca213de5d90 Mon Sep 17 00:00:00 2001 From: Ameya Shenoy Date: Wed, 17 Oct 2018 09:04:11 +0000 Subject: [PATCH 32/33] bumped to version 10.1.60 --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index ccd8a19cf3..bae7915e31 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '10.1.59' +__version__ = '10.1.60' def get_default_company(user=None): '''Get default company for user''' From a7a32d74002b2e5ca3f6e9415cb96e074872bd15 Mon Sep 17 00:00:00 2001 From: Ameya Shenoy Date: Wed, 17 Oct 2018 09:44:11 +0000 Subject: [PATCH 33/33] bumped to version 11.0.3-beta.12 --- erpnext/hooks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index b980d68591..b26c37c23c 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -12,7 +12,7 @@ app_license = "GNU General Public License (v3)" source_link = "https://github.com/frappe/erpnext" develop_version = '11.x.x-develop' -staging_version = '11.0.3-beta.11' +staging_version = '11.0.3-beta.12' error_report_email = "support@erpnext.com"