Merge branch 'develop' into patient-history-enhancements
diff --git a/erpnext/accounts/doctype/budget/test_budget.py b/erpnext/accounts/doctype/budget/test_budget.py
index cd88b11..c5ec23c 100644
--- a/erpnext/accounts/doctype/budget/test_budget.py
+++ b/erpnext/accounts/doctype/budget/test_budget.py
@@ -122,8 +122,10 @@
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
+ project = frappe.get_value("Project", {"project_name": "_Test Project"})
+
jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
- "_Test Bank - _TC", 40000, "_Test Cost Center - _TC", project="_Test Project", posting_date=nowdate())
+ "_Test Bank - _TC", 40000, "_Test Cost Center - _TC", project=project, posting_date=nowdate())
self.assertRaises(BudgetError, jv.submit)
@@ -147,8 +149,11 @@
budget = make_budget(budget_against="Project")
+ project = frappe.get_value("Project", {"project_name": "_Test Project"})
+
jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
- "_Test Bank - _TC", 250000, "_Test Cost Center - _TC", project="_Test Project", posting_date=nowdate())
+ "_Test Bank - _TC", 250000, "_Test Cost Center - _TC",
+ project=project, posting_date=nowdate())
self.assertRaises(BudgetError, jv.submit)
@@ -184,9 +189,11 @@
if month > 9:
month = 9
+ project = frappe.get_value("Project", {"project_name": "_Test Project"})
for i in range(month + 1):
jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
- "_Test Bank - _TC", 20000, "_Test Cost Center - _TC", posting_date=nowdate(), submit=True, project="_Test Project")
+ "_Test Bank - _TC", 20000, "_Test Cost Center - _TC", posting_date=nowdate(), submit=True,
+ project=project)
self.assertTrue(frappe.db.get_value("GL Entry",
{"voucher_type": "Journal Entry", "voucher_no": jv.name}))
@@ -289,7 +296,7 @@
budget = frappe.new_doc("Budget")
if budget_against == "Project":
- budget.project = "_Test Project"
+ budget.project = frappe.get_value("Project", {"project_name": "_Test Project"})
else:
budget.cost_center =cost_center or "_Test Cost Center - _TC"
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py
index c441274..288111b 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.py
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py
@@ -137,9 +137,10 @@
frappe.throw(_("{0} {1}: Cost Center {2} does not belong to Company {3}")
.format(self.voucher_type, self.voucher_no, self.cost_center, self.company))
- if self.cost_center and _check_is_group():
- frappe.throw(_("""{0} {1}: Cost Center {2} is a group cost center and group cost centers cannot be used in transactions""")
- .format(self.voucher_type, self.voucher_no, frappe.bold(self.cost_center)))
+ if not self.flags.from_repost and not self.voucher_type == 'Period Closing Voucher' \
+ and self.cost_center and _check_is_group():
+ frappe.throw(_("""{0} {1}: Cost Center {2} is a group cost center and group cost centers cannot
+ be used in transactions""").format(self.voucher_type, self.voucher_no, frappe.bold(self.cost_center)))
def validate_party(self):
validate_party_frozen_disabled(self.party_type, self.party)
diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
index b56f8e5..5f003e0 100644
--- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
@@ -160,7 +160,7 @@
self.assertFalse(gle)
def test_reverse_journal_entry(self):
- from erpnext.accounts.doctype.journal_entry.journal_entry import make_reverse_journal_entry
+ from erpnext.accounts.doctype.journal_entry.journal_entry import make_reverse_journal_entry
jv = make_journal_entry("_Test Bank USD - _TC",
"Sales - _TC", 100, exchange_rate=50, save=False)
@@ -299,15 +299,20 @@
def test_jv_with_project(self):
from erpnext.projects.doctype.project.test_project import make_project
- project = make_project({
- 'project_name': 'Journal Entry Project',
- 'project_template_name': 'Test Project Template',
- 'start_date': '2020-01-01'
- })
+
+ if not frappe.db.exists("Project", {"project_name": "Journal Entry Project"}):
+ project = make_project({
+ 'project_name': 'Journal Entry Project',
+ 'project_template_name': 'Test Project Template',
+ 'start_date': '2020-01-01'
+ })
+ project_name = project.name
+ else:
+ project_name = frappe.get_value("Project", {"project_name": "_Test Project"})
jv = make_journal_entry("_Test Cash - _TC", "_Test Bank - _TC", 100, save=False)
for d in jv.accounts:
- d.project = project.project_name
+ d.project = project_name
jv.voucher_type = "Bank Entry"
jv.multi_currency = 0
jv.cheque_no = "112233"
@@ -317,10 +322,10 @@
expected_values = {
"_Test Cash - _TC": {
- "project": project.project_name
+ "project": project_name
},
"_Test Bank - _TC": {
- "project": project.project_name
+ "project": project_name
}
}
diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
index c0506ba..2c088ce 100644
--- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -426,26 +426,31 @@
)
def test_total_purchase_cost_for_project(self):
- make_project({'project_name':'_Test Project'})
+ if not frappe.db.exists("Project", {"project_name": "_Test Project for Purchase"}):
+ project = make_project({'project_name':'_Test Project for Purchase'})
+ else:
+ project = frappe.get_doc("Project", {"project_name": "_Test Project for Purchase"})
existing_purchase_cost = frappe.db.sql("""select sum(base_net_amount)
- from `tabPurchase Invoice Item` where project = '_Test Project' and docstatus=1""")
+ from `tabPurchase Invoice Item`
+ where project = '{0}'
+ and docstatus=1""".format(project.name))
existing_purchase_cost = existing_purchase_cost and existing_purchase_cost[0][0] or 0
- pi = make_purchase_invoice(currency="USD", conversion_rate=60, project="_Test Project")
- self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"),
+ pi = make_purchase_invoice(currency="USD", conversion_rate=60, project=project.name)
+ self.assertEqual(frappe.db.get_value("Project", project.name, "total_purchase_cost"),
existing_purchase_cost + 15000)
- pi1 = make_purchase_invoice(qty=10, project="_Test Project")
- self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"),
+ pi1 = make_purchase_invoice(qty=10, project=project.name)
+ self.assertEqual(frappe.db.get_value("Project", project.name, "total_purchase_cost"),
existing_purchase_cost + 15500)
pi1.cancel()
- self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"),
+ self.assertEqual(frappe.db.get_value("Project", project.name, "total_purchase_cost"),
existing_purchase_cost + 15000)
pi.cancel()
- self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"), existing_purchase_cost)
+ self.assertEqual(frappe.db.get_value("Project", project.name, "total_purchase_cost"), existing_purchase_cost)
def test_return_purchase_invoice_with_perpetual_inventory(self):
pi = make_purchase_invoice(company = "_Test Company with perpetual inventory", warehouse= "Stores - TCP1",
@@ -860,17 +865,17 @@
})
pi = make_purchase_invoice(credit_to="Creditors - _TC" ,do_not_save=1)
- pi.items[0].project = item_project.project_name
- pi.project = project.project_name
+ pi.items[0].project = item_project.name
+ pi.project = project.name
pi.submit()
expected_values = {
"Creditors - _TC": {
- "project": project.project_name
+ "project": project.name
},
"_Test Account Cost for Goods Sold - _TC": {
- "project": item_project.project_name
+ "project": item_project.name
}
}
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index eb223ee..5435d3b 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -1573,17 +1573,17 @@
})
sales_invoice = create_sales_invoice(do_not_save=1)
- sales_invoice.items[0].project = item_project.project_name
- sales_invoice.project = project.project_name
+ sales_invoice.items[0].project = item_project.name
+ sales_invoice.project = project.name
sales_invoice.submit()
expected_values = {
"Debtors - _TC": {
- "project": project.project_name
+ "project": project.name
},
"Sales - _TC": {
- "project": item_project.project_name
+ "project": item_project.name
}
}
diff --git a/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py b/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py
index 57a1231..7195c7e 100644
--- a/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py
+++ b/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py
@@ -59,23 +59,111 @@
def get_columns(filters):
return [
- _("Payment Document") + ":: 100",
- _("Payment Entry") + ":Dynamic Link/"+_("Payment Document")+":140",
- _("Party Type") + "::100",
- _("Party") + ":Dynamic Link/Party Type:140",
- _("Posting Date") + ":Date:100",
- _("Invoice") + (":Link/Purchase Invoice:130" if filters.get("payment_type") == _("Outgoing") else ":Link/Sales Invoice:130"),
- _("Invoice Posting Date") + ":Date:130",
- _("Payment Due Date") + ":Date:130",
- _("Debit") + ":Currency:120",
- _("Credit") + ":Currency:120",
- _("Remarks") + "::150",
- _("Age") +":Int:40",
- "0-30:Currency:100",
- "30-60:Currency:100",
- "60-90:Currency:100",
- _("90-Above") + ":Currency:100",
- _("Delay in payment (Days)") + "::150"
+ {
+ "fieldname": "payment_document",
+ "label": _("Payment Document Type"),
+ "fieldtype": "Data",
+ "width": 100
+ },
+ {
+ "fieldname": "payment_entry",
+ "label": _("Payment Document"),
+ "fieldtype": "Dynamic Link",
+ "options": "payment_document",
+ "width": 160
+ },
+ {
+ "fieldname": "party_type",
+ "label": _("Party Type"),
+ "fieldtype": "Data",
+ "width": 100
+ },
+ {
+ "fieldname": "party",
+ "label": _("Party"),
+ "fieldtype": "Dynamic Link",
+ "options": "party_type",
+ "width": 160
+ },
+ {
+ "fieldname": "posting_date",
+ "label": _("Posting Date"),
+ "fieldtype": "Date",
+ "width": 100
+ },
+ {
+ "fieldname": "invoice",
+ "label": _("Invoice"),
+ "fieldtype": "Link",
+ "options": "Purchase Invoice" if filters.get("payment_type") == _("Outgoing") else "Sales Invoice",
+ "width": 160
+ },
+ {
+ "fieldname": "invoice_posting_date",
+ "label": _("Invoice Posting Date"),
+ "fieldtype": "Date",
+ "width": 100
+ },
+ {
+ "fieldname": "due_date",
+ "label": _("Payment Due Date"),
+ "fieldtype": "Date",
+ "width": 100
+ },
+ {
+ "fieldname": "debit",
+ "label": _("Debit"),
+ "fieldtype": "Currency",
+ "width": 140
+ },
+ {
+ "fieldname": "credit",
+ "label": _("Credit"),
+ "fieldtype": "Currency",
+ "width": 140
+ },
+ {
+ "fieldname": "remarks",
+ "label": _("Remarks"),
+ "fieldtype": "Data",
+ "width": 200
+ },
+ {
+ "fieldname": "age",
+ "label": _("Age"),
+ "fieldtype": "Int",
+ "width": 50
+ },
+ {
+ "fieldname": "range1",
+ "label": "0-30",
+ "fieldtype": "Currency",
+ "width": 140
+ },
+ {
+ "fieldname": "range2",
+ "label": "30-60",
+ "fieldtype": "Currency",
+ "width": 140
+ },
+ {
+ "fieldname": "range3",
+ "label": "60-90",
+ "fieldtype": "Currency",
+ "width": 140
+ },
+ {
+ "fieldname": "range4",
+ "label": _("90 Above"),
+ "fieldtype": "Currency",
+ "width": 140
+ },
+ {
+ "fieldname": "delay_in_payment",
+ "label": _("Delay in payment (Days)"),
+ "fieldtype": "Int",
+ "width": 100
+ }
]
def get_conditions(filters):
diff --git a/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py
index cae150c..afbd9b4 100644
--- a/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py
+++ b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py
@@ -48,7 +48,7 @@
def import_disease_tasks(self, disease, start_date):
disease_doc = frappe.get_doc('Disease', disease)
- self.create_task(disease_doc.treatment_task, self.name, start_date)
+ self.create_task(disease_doc.treatment_task, self.project, start_date)
def create_project(self, period, crop_tasks):
project = frappe.get_doc({
diff --git a/erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.py b/erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.py
index 5510d5a..763b403 100644
--- a/erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.py
+++ b/erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.py
@@ -71,4 +71,4 @@
def check_project_creation():
- return True if frappe.db.exists('Project', 'Basil from seed 2017') else False
+ return True if frappe.db.exists('Project', {'project_name': 'Basil from seed 2017'}) else False
diff --git a/erpnext/buying/utils.py b/erpnext/buying/utils.py
index 47b4866..a73cb0d 100644
--- a/erpnext/buying/utils.py
+++ b/erpnext/buying/utils.py
@@ -35,9 +35,10 @@
frappe.throw(_("UOM Conversion factor is required in row {0}").format(d.idx))
# update last purchsae rate
- if last_purchase_rate:
- frappe.db.sql("""update `tabItem` set last_purchase_rate = %s where name = %s""",
- (flt(last_purchase_rate), d.item_code))
+ frappe.db.set_value('Item', d.item_code, 'last_purchase_rate', flt(last_purchase_rate))
+
+
+
def validate_for_items(doc):
items = []
diff --git a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json
index b33c326..ddf1bce 100644
--- a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json
+++ b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json
@@ -19,6 +19,7 @@
"valid_days",
"inpatient_settings_section",
"allow_discharge_despite_unbilled_services",
+ "do_not_bill_inpatient_encounters",
"healthcare_service_items",
"inpatient_visit_charge_item",
"op_consulting_charge_item",
@@ -315,11 +316,17 @@
"fieldname": "allow_discharge_despite_unbilled_services",
"fieldtype": "Check",
"label": "Allow Discharge Despite Unbilled Healthcare Services"
+ },
+ {
+ "default": "0",
+ "fieldname": "do_not_bill_inpatient_encounters",
+ "fieldtype": "Check",
+ "label": "Do Not Bill Patient Encounters for Inpatients"
}
],
"issingle": 1,
"links": [],
- "modified": "2021-01-04 10:19:22.329272",
+ "modified": "2021-01-13 09:04:35.877700",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Healthcare Settings",
diff --git a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
index e8a9444..10990d4 100644
--- a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
+++ b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
@@ -8,6 +8,8 @@
from frappe.utils import now_datetime, today
from frappe.utils.make_random import get_random
from erpnext.healthcare.doctype.inpatient_record.inpatient_record import admit_patient, discharge_patient, schedule_discharge
+from erpnext.healthcare.doctype.lab_test.test_lab_test import create_patient_encounter
+from erpnext.healthcare.utils import get_encounters_to_invoice
class TestInpatientRecord(unittest.TestCase):
def test_admit_and_discharge(self):
@@ -42,7 +44,7 @@
def test_allow_discharge_despite_unbilled_services(self):
frappe.db.sql("""delete from `tabInpatient Record`""")
- setup_inpatient_settings()
+ setup_inpatient_settings(key="allow_discharge_despite_unbilled_services", value=1)
patient = create_patient()
# Schedule Admission
ip_record = create_inpatient(patient)
@@ -64,6 +66,35 @@
self.assertEqual(None, frappe.db.get_value("Patient", patient, "inpatient_record"))
self.assertEqual(None, frappe.db.get_value("Patient", patient, "inpatient_status"))
+ setup_inpatient_settings(key="allow_discharge_despite_unbilled_services", value=0)
+
+ def test_do_not_bill_patient_encounters_for_inpatients(self):
+ frappe.db.sql("""delete from `tabInpatient Record`""")
+ setup_inpatient_settings(key="do_not_bill_inpatient_encounters", value=1)
+ patient = create_patient()
+ # Schedule Admission
+ ip_record = create_inpatient(patient)
+ ip_record.expected_length_of_stay = 0
+ ip_record.save(ignore_permissions = True)
+
+ # Admit
+ service_unit = get_healthcare_service_unit()
+ admit_patient(ip_record, service_unit, now_datetime())
+
+ # Patient Encounter
+ patient_encounter = create_patient_encounter()
+ encounters = get_encounters_to_invoice(patient, "_Test Company")
+ encounter_ids = [entry.reference_name for entry in encounters]
+ self.assertFalse(patient_encounter.name in encounter_ids)
+
+ # Discharge
+ schedule_discharge(frappe.as_json({"patient": patient}))
+ self.assertEqual("Vacant", frappe.db.get_value("Healthcare Service Unit", service_unit, "occupancy_status"))
+
+ ip_record = frappe.get_doc("Inpatient Record", ip_record.name)
+ mark_invoiced_inpatient_occupancy(ip_record)
+ discharge_patient(ip_record)
+ setup_inpatient_settings(key="do_not_bill_inpatient_encounters", value=0)
def test_validate_overlap_admission(self):
frappe.db.sql("""delete from `tabInpatient Record`""")
@@ -89,9 +120,9 @@
ip_record.save(ignore_permissions = True)
-def setup_inpatient_settings():
+def setup_inpatient_settings(key, value):
settings = frappe.get_single("Healthcare Settings")
- settings.allow_discharge_despite_unbilled_services = 1
+ settings.set(key, value)
settings.save()
diff --git a/erpnext/healthcare/utils.py b/erpnext/healthcare/utils.py
index 6b495a4..40f7f9c 100644
--- a/erpnext/healthcare/utils.py
+++ b/erpnext/healthcare/utils.py
@@ -78,11 +78,13 @@
def get_encounters_to_invoice(patient, company):
+ if not isinstance(patient, str):
+ patient = patient.name
encounters_to_invoice = []
encounters = frappe.get_list(
'Patient Encounter',
fields=['*'],
- filters={'patient': patient.name, 'company': company, 'invoiced': False, 'docstatus': 1}
+ filters={'patient': patient, 'company': company, 'invoiced': False, 'docstatus': 1}
)
if encounters:
for encounter in encounters:
@@ -91,6 +93,10 @@
income_account = None
service_item = None
if encounter.practitioner:
+ if encounter.inpatient_record and \
+ frappe.db.get_single_value('Healthcare Settings', 'do_not_bill_inpatient_encounters'):
+ continue
+
service_item, practitioner_charge = get_service_item_and_practitioner_charge(encounter)
income_account = get_income_account(encounter.practitioner, encounter.company)
diff --git a/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.py b/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.py
index 4e9ee3b..336e13c 100644
--- a/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.py
+++ b/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.py
@@ -38,7 +38,8 @@
onboarding.insert()
onboarding.submit()
- self.assertEqual(onboarding.project, 'Employee Onboarding : Test Researcher - test@researcher.com')
+ project_name = frappe.db.get_value("Project", onboarding.project, "project_name")
+ self.assertEqual(project_name, 'Employee Onboarding : Test Researcher - test@researcher.com')
# don't allow making employee if onboarding is not complete
self.assertRaises(IncompleteTaskError, make_employee, onboarding.name)
diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.py b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
index 4a0908d..f9e3a44 100644
--- a/erpnext/hr/doctype/expense_claim/test_expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
@@ -20,35 +20,36 @@
frappe.db.sql("""delete from `tabProject` where name = "_Test Project 1" """)
frappe.db.sql("update `tabExpense Claim` set project = '', task = ''")
- frappe.get_doc({
+ project = frappe.get_doc({
"project_name": "_Test Project 1",
"doctype": "Project"
- }).save()
+ })
+ project.save()
task = frappe.get_doc(dict(
doctype = 'Task',
subject = '_Test Project Task 1',
status = 'Open',
- project = '_Test Project 1'
+ project = project.name
)).insert()
task_name = task.name
payable_account = get_payable_account(company_name)
- make_expense_claim(payable_account, 300, 200, company_name, "Travel Expenses - _TC4", "_Test Project 1", task_name)
+ make_expense_claim(payable_account, 300, 200, company_name, "Travel Expenses - _TC4", project.name, task_name)
self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 200)
- self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"), 200)
+ self.assertEqual(frappe.db.get_value("Project", project.name, "total_expense_claim"), 200)
- expense_claim2 = make_expense_claim(payable_account, 600, 500, company_name, "Travel Expenses - _TC4","_Test Project 1", task_name)
+ expense_claim2 = make_expense_claim(payable_account, 600, 500, company_name, "Travel Expenses - _TC4", project.name, task_name)
self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 700)
- self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"), 700)
+ self.assertEqual(frappe.db.get_value("Project", project.name, "total_expense_claim"), 700)
expense_claim2.cancel()
self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 200)
- self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"), 200)
+ self.assertEqual(frappe.db.get_value("Project", project.name, "total_expense_claim"), 200)
def test_expense_claim_status(self):
payable_account = get_payable_account(company_name)
diff --git a/erpnext/projects/doctype/project/project.json b/erpnext/projects/doctype/project/project.json
index f3cecd9..3cdfcb2 100644
--- a/erpnext/projects/doctype/project/project.json
+++ b/erpnext/projects/doctype/project/project.json
@@ -2,12 +2,13 @@
"actions": [],
"allow_import": 1,
"allow_rename": 1,
- "autoname": "field:project_name",
+ "autoname": "naming_series:",
"creation": "2013-03-07 11:55:07",
"doctype": "DocType",
"document_type": "Setup",
"engine": "InnoDB",
"field_order": [
+ "naming_series",
"project_name",
"status",
"project_type",
@@ -440,13 +441,24 @@
"fieldtype": "Text",
"label": "Message",
"mandatory_depends_on": "collect_progress"
+ },
+ {
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "label": "Series",
+ "no_copy": 1,
+ "options": "PROJ-.####",
+ "print_hide": 1,
+ "reqd": 1,
+ "set_only_once": 1
}
],
"icon": "fa fa-puzzle-piece",
"idx": 29,
+ "index_web_pages_for_search": 1,
"links": [],
"max_attachments": 4,
- "modified": "2020-04-08 22:11:14.552615",
+ "modified": "2020-09-02 11:54:01.223620",
"modified_by": "Administrator",
"module": "Projects",
"name": "Project",
@@ -488,5 +500,6 @@
"sort_field": "modified",
"sort_order": "DESC",
"timeline_field": "customer",
+ "title_field": "project_name",
"track_seen": 1
}
diff --git a/erpnext/projects/doctype/project/test_project.py b/erpnext/projects/doctype/project/test_project.py
index 97b67b3..d85c826 100644
--- a/erpnext/projects/doctype/project/test_project.py
+++ b/erpnext/projects/doctype/project/test_project.py
@@ -42,7 +42,7 @@
task2 = task_exists("Test Template Task Child 1")
if not task2:
task2 = create_task(subject="Test Template Task Child 1", parent_task=task1.name, is_template=1, begin=1, duration=3)
-
+
task3 = task_exists("Test Template Task Child 2")
if not task3:
task3 = create_task(subject="Test Template Task Child 2", parent_task=task1.name, is_template=1, begin=2, duration=3)
@@ -76,7 +76,7 @@
task2 = task_exists("Test Template Task with Dependency")
if not task2:
task2 = create_task(subject="Test Template Task with Dependency", depends_on=task1.name, is_template=1, begin=2, duration=2)
-
+
template = make_project_template("Test Project with Template - Dependent Tasks", [task1, task2])
project = get_project(project_name, template)
tasks = frappe.get_all('Task', ['subject','exp_end_date','depends_on_tasks', 'name'], dict(project=project.name), order_by='creation asc')
@@ -105,6 +105,9 @@
def make_project(args):
args = frappe._dict(args)
+ if args.project_name and frappe.db.exists("Project", {"project_name": args.project_name}):
+ return frappe.get_doc("Project", {"project_name": args.project_name})
+
project = frappe.get_doc(dict(
doctype = 'Project',
project_name = args.project_name,
@@ -116,8 +119,7 @@
template = make_project_template(args.project_template_name)
project.project_template = template.name
- if not frappe.db.exists("Project", args.project_name):
- project.insert()
+ project.insert()
return project
diff --git a/erpnext/projects/doctype/task/test_task.py b/erpnext/projects/doctype/task/test_task.py
index 25714f8..0fad5e8 100644
--- a/erpnext/projects/doctype/task/test_task.py
+++ b/erpnext/projects/doctype/task/test_task.py
@@ -30,14 +30,16 @@
})
def test_reschedule_dependent_task(self):
+ project = frappe.get_value("Project", {"project_name": "_Test Project"})
+
task1 = create_task("_Test Task 1", nowdate(), add_days(nowdate(), 10))
task2 = create_task("_Test Task 2", add_days(nowdate(), 11), add_days(nowdate(), 15), task1.name)
- task2.get("depends_on")[0].project = "_Test Project"
+ task2.get("depends_on")[0].project = project
task2.save()
task3 = create_task("_Test Task 3", add_days(nowdate(), 11), add_days(nowdate(), 15), task2.name)
- task3.get("depends_on")[0].project = "_Test Project"
+ task3.get("depends_on")[0].project = project
task3.save()
task1.update({
@@ -104,7 +106,7 @@
task.subject = subject
task.exp_start_date = start or nowdate()
task.exp_end_date = end or nowdate()
- task.project = project or None if is_template else "_Test Project"
+ task.project = project or None if is_template else frappe.get_value("Project", {"project_name": "_Test Project"})
task.is_template = is_template
task.start = begin
task.duration = duration
diff --git a/erpnext/projects/doctype/timesheet/test_timesheet.py b/erpnext/projects/doctype/timesheet/test_timesheet.py
index a5ce44d..4cb3804 100644
--- a/erpnext/projects/doctype/timesheet/test_timesheet.py
+++ b/erpnext/projects/doctype/timesheet/test_timesheet.py
@@ -89,10 +89,11 @@
def test_timesheet_billing_based_on_project(self):
emp = make_employee("test_employee_6@salary.com")
+ project = frappe.get_value("Project", {"project_name": "_Test Project"})
- timesheet = make_timesheet(emp, simulate=True, billable=1, project = '_Test Project', company='_Test Company')
+ timesheet = make_timesheet(emp, simulate=True, billable=1, project=project, company='_Test Company')
sales_invoice = create_sales_invoice(do_not_save=True)
- sales_invoice.project = '_Test Project'
+ sales_invoice.project = project
sales_invoice.submit()
ts = frappe.get_doc('Timesheet', timesheet.name)
diff --git a/erpnext/projects/doctype/timesheet/timesheet.js b/erpnext/projects/doctype/timesheet/timesheet.js
index b068245..b123af5 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.js
+++ b/erpnext/projects/doctype/timesheet/timesheet.js
@@ -134,7 +134,7 @@
});
},
- project: function(frm) {
+ parent_project: function(frm) {
set_project_in_timelog(frm);
},
@@ -168,8 +168,8 @@
},
time_logs_add: function(frm, cdt, cdn) {
- if(frm.doc.project) {
- frappe.model.set_value(cdt, cdn, 'project', frm.doc.project);
+ if(frm.doc.parent_project) {
+ frappe.model.set_value(cdt, cdn, 'project', frm.doc.parent_project);
}
var $trigger_again = $('.form-grid').find('.grid-row').find('.btn-open-row');
@@ -308,7 +308,9 @@
};
function set_project_in_timelog(frm) {
- if(frm.doc.project){
- erpnext.utils.copy_value_in_all_rows(frm.doc, frm.doc.doctype, frm.doc.name, "time_logs", "project");
+ if(frm.doc.parent_project) {
+ $.each(frm.doc.time_logs || [], function(i, item) {
+ frappe.model.set_value(item.doctype, item.name, "project", frm.doc.parent_project);
+ });
}
}
\ No newline at end of file
diff --git a/erpnext/projects/doctype/timesheet/timesheet.json b/erpnext/projects/doctype/timesheet/timesheet.json
index 4c2edf4..b286821 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.json
+++ b/erpnext/projects/doctype/timesheet/timesheet.json
@@ -15,7 +15,7 @@
"column_break_3",
"salary_slip",
"status",
- "project",
+ "parent_project",
"employee_detail",
"employee",
"employee_name",
@@ -261,7 +261,7 @@
"read_only": 1
},
{
- "fieldname": "project",
+ "fieldname": "parent_project",
"fieldtype": "Link",
"label": "Project",
"options": "Project"
@@ -271,7 +271,7 @@
"idx": 1,
"is_submittable": 1,
"links": [],
- "modified": "2020-10-29 07:50:35.938231",
+ "modified": "2021-01-08 20:51:14.590080",
"modified_by": "Administrator",
"module": "Projects",
"name": "Timesheet",
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index 5321a9a..5261984 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -7,7 +7,7 @@
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
from frappe.permissions import add_permission, update_permission_property
from erpnext.regional.india import states
-from erpnext.accounts.utils import get_fiscal_year
+from erpnext.accounts.utils import get_fiscal_year, FiscalYearError
from frappe.utils import today
def setup(company=None, patch=True):
@@ -629,15 +629,20 @@
def set_tax_withholding_category(company):
accounts = []
+ fiscal_year = None
abbr = frappe.get_value("Company", company, "abbr")
tds_account = frappe.get_value("Account", 'TDS Payable - {0}'.format(abbr), 'name')
if company and tds_account:
accounts = [dict(company=company, account=tds_account)]
- fiscal_year = get_fiscal_year(today(), company=company)[0]
- docs = get_tds_details(accounts, fiscal_year)
+ try:
+ fiscal_year = get_fiscal_year(today(), verbose=0, company=company)[0]
+ except FiscalYearError:
+ pass
+ docs = get_tds_details(accounts, fiscal_year)
+
for d in docs:
try:
doc = frappe.get_doc(d)
@@ -650,11 +655,14 @@
if accounts:
doc.append("accounts", accounts[0])
- # if fiscal year don't match with any of the already entered data, append rate row
- fy_exist = [k for k in doc.get('rates') if k.get('fiscal_year')==fiscal_year]
- if not fy_exist:
- doc.append("rates", d.get('rates')[0])
-
+ if fiscal_year:
+ # if fiscal year don't match with any of the already entered data, append rate row
+ fy_exist = [k for k in doc.get('rates') if k.get('fiscal_year')==fiscal_year]
+ if not fy_exist:
+ doc.append("rates", d.get('rates')[0])
+
+ doc.flags.ignore_permissions = True
+ doc.flags.ignore_mandatory = True
doc.save()
def set_tds_account(docs, company):
diff --git a/erpnext/stock/doctype/material_request/test_material_request.py b/erpnext/stock/doctype/material_request/test_material_request.py
index 0a29fa0..72a3a5e 100644
--- a/erpnext/stock/doctype/material_request/test_material_request.py
+++ b/erpnext/stock/doctype/material_request/test_material_request.py
@@ -424,6 +424,7 @@
"basic_rate": 1.0
})
se_doc.get("items")[1].update({
+ "item_code": "_Test Item Home Desktop 100",
"qty": 3.0,
"transfer_qty": 3.0,
"s_warehouse": "_Test Warehouse 1 - _TC",
@@ -534,7 +535,7 @@
mr = make_material_request(item_code='_Test FG Item', material_request_type='Manufacture',
uom="_Test UOM 1", conversion_factor=12)
-
+
requested_qty = self._get_requested_qty('_Test FG Item', '_Test Warehouse - _TC')
self.assertEqual(requested_qty, existing_requested_qty + 120)
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 2fc7da8..4782a9d 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -1333,9 +1333,6 @@
frappe.MappingMismatchError)
elif self.purpose == "Material Transfer" and self.add_to_transit:
continue
- elif mreq_item.warehouse != (item.s_warehouse if self.purpose == "Material Issue" else item.t_warehouse):
- frappe.throw(_("Warehouse for row {0} does not match Material Request").format(item.idx),
- frappe.MappingMismatchError)
def validate_batch(self):
if self.purpose in ["Material Transfer for Manufacture", "Manufacture", "Repack", "Send to Subcontractor"]: