Merge branch 'develop' into patient-history-enhancements

This commit is contained in:
Rucha Mahabal 2021-01-15 12:09:53 +05:30 committed by GitHub
commit 004e51ed9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 278 additions and 99 deletions

View File

@ -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"

View File

@ -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)

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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):

View File

@ -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({

View File

@ -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

View File

@ -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 = []

View File

@ -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",

View File

@ -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()

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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);
});
}
}

View File

@ -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",

View File

@ -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):

View File

@ -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)

View File

@ -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"]: