Merge branch 'develop' into patient-history-enhancements
This commit is contained in:
commit
004e51ed9f
@ -122,8 +122,10 @@ class TestBudget(unittest.TestCase):
|
||||
|
||||
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 @@ class TestBudget(unittest.TestCase):
|
||||
|
||||
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 @@ class TestBudget(unittest.TestCase):
|
||||
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 @@ def make_budget(**args):
|
||||
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"
|
||||
|
||||
|
@ -137,9 +137,10 @@ class GLEntry(Document):
|
||||
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)
|
||||
|
@ -160,7 +160,7 @@ class TestJournalEntry(unittest.TestCase):
|
||||
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 @@ class TestJournalEntry(unittest.TestCase):
|
||||
|
||||
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 @@ class TestJournalEntry(unittest.TestCase):
|
||||
|
||||
expected_values = {
|
||||
"_Test Cash - _TC": {
|
||||
"project": project.project_name
|
||||
"project": project_name
|
||||
},
|
||||
"_Test Bank - _TC": {
|
||||
"project": project.project_name
|
||||
"project": project_name
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -426,26 +426,31 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
)
|
||||
|
||||
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 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
})
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1573,17 +1573,17 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
})
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,23 +59,111 @@ def validate_filters(filters):
|
||||
|
||||
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):
|
||||
|
@ -48,7 +48,7 @@ class CropCycle(Document):
|
||||
|
||||
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({
|
||||
|
@ -71,4 +71,4 @@ def check_task_creation():
|
||||
|
||||
|
||||
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
|
||||
|
@ -35,9 +35,10 @@ def update_last_purchase_rate(doc, is_submit):
|
||||
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 = []
|
||||
|
@ -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",
|
||||
|
@ -8,6 +8,8 @@ import unittest
|
||||
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 @@ class TestInpatientRecord(unittest.TestCase):
|
||||
|
||||
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 @@ class TestInpatientRecord(unittest.TestCase):
|
||||
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 @@ def mark_invoiced_inpatient_occupancy(ip_record):
|
||||
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()
|
||||
|
||||
|
||||
|
@ -78,11 +78,13 @@ def get_appointments_to_invoice(patient, company):
|
||||
|
||||
|
||||
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 @@ def get_encounters_to_invoice(patient, company):
|
||||
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)
|
||||
|
||||
|
@ -38,7 +38,8 @@ class TestEmployeeOnboarding(unittest.TestCase):
|
||||
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)
|
||||
|
@ -20,35 +20,36 @@ class TestExpenseClaim(unittest.TestCase):
|
||||
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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ class TestProject(unittest.TestCase):
|
||||
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 @@ class TestProject(unittest.TestCase):
|
||||
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 get_project(name, template):
|
||||
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 @@ def make_project(args):
|
||||
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
|
||||
|
||||
|
@ -30,14 +30,16 @@ class TestTask(unittest.TestCase):
|
||||
})
|
||||
|
||||
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 @@ def create_task(subject, start=None, end=None, depends_on=None, project=None, pa
|
||||
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
|
||||
|
@ -89,10 +89,11 @@ class TestTimesheet(unittest.TestCase):
|
||||
|
||||
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)
|
||||
|
@ -134,7 +134,7 @@ frappe.ui.form.on("Timesheet", {
|
||||
});
|
||||
},
|
||||
|
||||
project: function(frm) {
|
||||
parent_project: function(frm) {
|
||||
set_project_in_timelog(frm);
|
||||
},
|
||||
|
||||
@ -168,8 +168,8 @@ frappe.ui.form.on("Timesheet Detail", {
|
||||
},
|
||||
|
||||
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 @@ const set_employee_and_company = function(frm) {
|
||||
};
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
@ -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",
|
||||
|
@ -7,7 +7,7 @@ import frappe, os, json
|
||||
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_salary_components(docs):
|
||||
|
||||
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 @@ def set_tax_withholding_category(company):
|
||||
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):
|
||||
|
@ -424,6 +424,7 @@ class TestMaterialRequest(unittest.TestCase):
|
||||
"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 @@ class TestMaterialRequest(unittest.TestCase):
|
||||
|
||||
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)
|
||||
|
@ -1333,9 +1333,6 @@ class StockEntry(StockController):
|
||||
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"]:
|
||||
|
Loading…
x
Reference in New Issue
Block a user