Пример #1
0
def get_employees(date, department = None, branch = None, company = None):
	attendance_not_marked = []
	attendance_marked = []
	filters = {"status": "Active", "date_of_joining": ["<=", date]}

	for field, value in {'department': department,
		'branch': branch, 'company': company}.items():
		if value:
			filters[field] = value

	employee_list = dataent.get_list("Employee", fields=["employee", "employee_name"], filters=filters, order_by="employee_name")
	marked_employee = {}
	for emp in dataent.get_list("Attendance", fields=["employee", "status"],
							   filters={"attendance_date": date}):
		marked_employee[emp['employee']] = emp['status']

	for employee in employee_list:
		employee['status'] = marked_employee.get(employee['employee'])
		if employee['employee'] not in marked_employee:
			attendance_not_marked.append(employee)
		else:
			attendance_marked.append(employee)
	return {
		"marked": attendance_marked,
		"unmarked": attendance_not_marked
	}
Пример #2
0
def get_customers_suppliers(doctype, user):
    customers = []
    suppliers = []
    meta = dataent.get_meta(doctype)

    if has_common(["Supplier", "Customer"], dataent.get_roles(user)):
        contacts = dataent.db.sql("""
			select 
				`tabContact`.email_id,
				`tabDynamic Link`.link_doctype,
				`tabDynamic Link`.link_name
			from 
				`tabContact`, `tabDynamic Link`
			where
				`tabContact`.name=`tabDynamic Link`.parent and `tabContact`.email_id =%s
			""",
                                  user,
                                  as_dict=1)
        customers = [c.link_name for c in contacts if c.link_doctype == 'Customer'] \
         if meta.get_field("customer") else None
        suppliers = [c.link_name for c in contacts if c.link_doctype == 'Supplier'] \
         if meta.get_field("supplier") else None
    elif dataent.has_permission(doctype, 'read', user=user):
        customers = [customer.name for customer in dataent.get_list("Customer")] \
         if meta.get_field("customer") else None
        suppliers = [supplier.name for supplier in dataent.get_list("Customer")] \
         if meta.get_field("supplier") else None

    return customers, suppliers
Пример #3
0
def remove_app(app_name, dry_run=False, yes=False):
    """Delete app and all linked to the app's module with the app."""

    if not dry_run and not yes:
        confirm = input(
            "All doctypes (including custom), modules related to this app will be deleted. Are you sure you want to continue (y/n) ? "
        )
        if confirm != "y":
            return

    from dataent.utils.backups import scheduled_backup
    print("Backing up...")
    scheduled_backup(ignore_files=True)

    drop_doctypes = []

    # remove modules, doctypes, roles
    for module_name in dataent.get_module_list(app_name):
        for doctype in dataent.get_list("DocType",
                                        filters={"module": module_name},
                                        fields=["name", "issingle"]):
            print("removing DocType {0}...".format(doctype.name))

            if not dry_run:
                dataent.delete_doc("DocType", doctype.name)

                if not doctype.issingle:
                    drop_doctypes.append(doctype.name)

        # remove reports, pages and web forms
        for doctype in ("Report", "Page", "Web Form"):
            for record in dataent.get_list(doctype,
                                           filters={"module": module_name}):
                print("removing {0} {1}...".format(doctype, record.name))
                if not dry_run:
                    dataent.delete_doc(doctype, record.name)

        print("removing Module {0}...".format(module_name))
        if not dry_run:
            dataent.delete_doc("Module Def", module_name)

    # delete desktop icons
    dataent.db.sql('delete from `tabDesktop Icon` where app=%s', app_name)

    remove_from_installed_apps(app_name)

    if not dry_run:
        # drop tables after a commit
        dataent.db.commit()

        for doctype in set(drop_doctypes):
            dataent.db.sql("drop table `tab{0}`".format(doctype))
Пример #4
0
    def get_reply(self):
        if self.startswith('open', 'show open', 'list open', 'get open'):
            if self.tables:
                doctype = self.get_doctype()
                from dataent.desk.notifications import get_notification_config
                filters = get_notification_config().get('for_doctype').get(
                    doctype, None)
                if filters:
                    if isinstance(filters, dict):
                        data = dataent.get_list(doctype, filters=filters)
                    else:
                        data = [{
                            'name': d[0],
                            'title': d[1]
                        } for d in dataent.get_attr(filters)(as_list=True)]

                    return ", ".join(
                        '[{title}](#Form/{doctype}/{name})'.format(
                            doctype=doctype,
                            name=d.get('name'),
                            title=d.get('title') or d.get('name'))
                        for d in data)
                else:
                    return _("Can't identify open {0}. Try something else."
                             ).format(doctype)
Пример #5
0
    def get_reply(self):
        if self.query.endswith(' ' + _('list')) and self.startswith(_('list')):
            self.query = _('list') + ' ' + self.query.replace(
                ' ' + _('list'), '')
        if self.startswith(_('list'), _('show')):
            like = None
            if ' ' + _('like') + ' ' in self.query:
                self.query, like = self.query.split(' ' + _('like') + ' ')

            self.tables = self.reply.identify_tables(
                self.query.split(None, 1)[1])
            if self.tables:
                doctype = self.get_doctype()
                meta = dataent.get_meta(doctype)
                fields = ['name']
                if meta.title_field:
                    fields.append('`{0}` as title'.format(meta.title_field))

                filters = {}
                if like:
                    filters = {
                        meta.title_field or 'name': ('like', '%' + like + '%')
                    }
                return self.format_list(
                    dataent.get_list(self.get_doctype(),
                                     fields=fields,
                                     filters=filters))
Пример #6
0
def get_next(doctype, value, prev, filters=None, order_by="modified desc"):

    prev = not int(prev)
    sort_field, sort_order = order_by.split(" ")

    if not filters: filters = []
    if isinstance(filters, string_types):
        filters = json.loads(filters)

    # condition based on sort order
    condition = ">" if sort_order.lower() == "desc" else "<"

    # switch the condition
    if prev:
        condition = "<" if condition == ">" else "<"
    else:
        sort_order = "asc" if sort_order.lower() == "desc" else "desc"

    # add condition for next or prev item
    if not order_by[0] in [f[1] for f in filters]:
        filters.append([doctype, sort_field, condition, value])

    res = dataent.get_list(doctype,
                           fields=["name"],
                           filters=filters,
                           order_by=sort_field + " " + sort_order,
                           limit_start=0,
                           limit_page_length=1,
                           as_list=True)

    if not res:
        dataent.msgprint(_("No further records"))
        return None
    else:
        return res[0][0]
Пример #7
0
def get_children(doctype,
                 parent=None,
                 company=None,
                 is_root=False,
                 is_tree=False):
    filters = [['company', '=', company]]
    fields = ['name as value', 'employee_name as title']

    if is_root:
        parent = ''
    if parent and company and parent != company:
        filters.append(['reports_to', '=', parent])
    else:
        filters.append(['reports_to', '=', ''])

    employees = dataent.get_list(doctype,
                                 fields=fields,
                                 filters=filters,
                                 order_by='name')

    for employee in employees:
        is_expandable = dataent.get_all(
            doctype, filters=[['reports_to', '=',
                               employee.get('value')]])
        employee.expandable = 1 if is_expandable else 0

    return employees
Пример #8
0
def get_students(doctype, txt, searchfield, start, page_len, filters):
	if not filters.get("academic_term"):
		filters["academic_term"] = dataent.defaults.get_defaults().academic_term

	if not filters.get("academic_year"):
		filters["academic_year"] = dataent.defaults.get_defaults().academic_year

	enrolled_students = dataent.get_list("Program Enrollment", filters={
		"academic_term": filters.get('academic_term'),
		"academic_year": filters.get('academic_year')
	}, fields=["student"])

	students = [d.student for d in enrolled_students] if enrolled_students else [""]

	return dataent.db.sql("""select
			name, title from tabStudent
		where 
			name not in (%s)
		and 
			`%s` LIKE %s
		order by 
			idx desc, name
		limit %s, %s"""%(
			", ".join(['%s']*len(students)), searchfield, "%s", "%s", "%s"),
			tuple(students + ["%%%s%%" % txt, start, page_len]
		)
	)
Пример #9
0
def get_assessment_details(assessment_plan):
    """Returns Assessment Criteria  and Maximum Score from Assessment Plan Master.

	:param Assessment Plan: Assessment Plan
	"""
    return dataent.get_list("Assessment Plan Criteria", \
     fields=["assessment_criteria", "maximum_score", "docstatus"], filters={"parent": assessment_plan}, order_by= "idx")
Пример #10
0
def get_list(doctype,
             fields=None,
             filters=None,
             order_by=None,
             limit_start=None,
             limit_page_length=20,
             parent=None):
    '''Returns a list of records by filters, fields, ordering and limit

	:param doctype: DocType of the data to be queried
	:param fields: fields to be returned. Default is `name`
	:param filters: filter list by this dict
	:param order_by: Order by this fieldname
	:param limit_start: Start at this index
	:param limit_page_length: Number of records to be returned (default 20)'''
    if dataent.is_table(doctype):
        check_parent_permission(parent, doctype)

    return dataent.get_list(doctype,
                            fields=fields,
                            filters=filters,
                            order_by=order_by,
                            limit_start=limit_start,
                            limit_page_length=limit_page_length,
                            ignore_permissions=False)
Пример #11
0
def get_events(start, end, filters=None):
    """Returns events for Gantt / Calendar view rendering.

	:param start: Start date-time.
	:param end: End date-time.
	:param filters: Filters (JSON).
	"""
    if filters:
        filters = json.loads(filters)
    else:
        filters = []

    if start:
        filters.append(['Holiday', 'holiday_date', '>', getdate(start)])
    if end:
        filters.append(['Holiday', 'holiday_date', '<', getdate(end)])

    return dataent.get_list('Holiday List',
                            fields=[
                                'name', '`tabHoliday`.holiday_date',
                                '`tabHoliday`.description',
                                '`tabHoliday List`.color'
                            ],
                            filters=filters,
                            update={"allDay": 1})
Пример #12
0
    def get_message_details(self):
        '''Return args for template'''
        dws_group = dataent.get_doc('Daily Work Summary Group',
                                    self.daily_work_summary_group)

        replies = dataent.get_all('Communication',
                                  fields=['content', 'text_content', 'sender'],
                                  filters=dict(
                                      reference_doctype=self.doctype,
                                      reference_name=self.name,
                                      communication_type='Communication',
                                      sent_or_received='Received'),
                                  order_by='creation asc')

        did_not_reply = self.email_sent_to.split()

        for d in replies:
            user = dataent.db.get_values("User", {"email": d.sender},
                                         ["full_name", "user_image"],
                                         as_dict=True)

            d.sender_name = user[0].full_name if user else d.sender
            d.image = user[0].image if user and user[0].image else None

            original_image = d.image
            # make thumbnail image
            try:
                if original_image:
                    file_name = dataent.get_list('File',
                                                 {'file_url': original_image})

                    if file_name:
                        file_name = file_name[0].name
                        file_doc = dataent.get_doc('File', file_name)
                        thumbnail_image = file_doc.make_thumbnail(
                            set_as_thumbnail=False,
                            width=100,
                            height=100,
                            crop=True)
                        d.image = thumbnail_image
            except:
                d.image = original_image

            if d.sender in did_not_reply:
                did_not_reply.remove(d.sender)
            if d.text_content:
                d.content = dataent.utils.md_to_html(
                    EmailReplyParser.parse_reply(d.text_content))

        did_not_reply = [
            (dataent.db.get_value("User", {"email": email}, "full_name")
             or email) for email in did_not_reply
        ]

        return dict(replies=replies,
                    original_message=dws_group.message,
                    title=_('Work Summary for {0}'.format(
                        global_date_format(self.creation))),
                    did_not_reply=', '.join(did_not_reply) or '',
                    did_not_reply_title=_('No replies from'))
Пример #13
0
    def test_template_works(self):
        if not dataent.db.exists('Address Template', 'India'):
            dataent.get_doc({
                "doctype": "Address Template",
                "country": 'India',
                "is_default": 1
            }).insert()

        if not dataent.db.exists('Address', '_Test Address-Office'):
            dataent.get_doc({
                "address_line1": "_Test Address Line 1",
                "address_title": "_Test Address",
                "address_type": "Office",
                "city": "_Test City",
                "state": "Test State",
                "country": "India",
                "doctype": "Address",
                "is_primary_address": 1,
                "phone": "+91 0000000000"
            }).insert()

        address = dataent.get_list("Address")[0].name
        display = get_address_display(
            dataent.get_doc("Address", address).as_dict())
        self.assertTrue(display)
Пример #14
0
def before_tests():
    dataent.clear_cache()
    # complete setup if missing
    from dataent.desk.page.setup_wizard.setup_wizard import setup_complete
    if not dataent.get_list("Company"):
        setup_complete({
            "currency": "USD",
            "full_name": "Test User",
            "company_name": "Wind Power LLC",
            "timezone": "America/New_York",
            "company_abbr": "WP",
            "industry": "Manufacturing",
            "country": "United States",
            "fy_start_date": "2011-01-01",
            "fy_end_date": "2011-12-31",
            "language": "english",
            "company_tagline": "Testing",
            "email": "*****@*****.**",
            "password": "******",
            "chart_of_accounts": "Standard",
            "domains": ["Manufacturing"],
        })

    dataent.db.sql("delete from `tabLeave Allocation`")
    dataent.db.sql("delete from `tabLeave Application`")
    dataent.db.sql("delete from `tabSalary Slip`")
    dataent.db.sql("delete from `tabItem Price`")

    dataent.db.set_value("Stock Settings", None,
                         "auto_insert_price_list_rate_if_missing", 0)
    enable_all_roles_and_domains()

    dataent.db.commit()
Пример #15
0
def get_events(doctype, start, end, field_map, filters=None, fields=None):

    field_map = dataent._dict(json.loads(field_map))

    doc_meta = dataent.get_meta(doctype)
    for d in doc_meta.fields:
        if d.fieldtype == "Color":
            field_map.update({"color": d.fieldname})

    if filters:
        filters = json.loads(filters or '')

    if not fields:
        fields = [field_map.start, field_map.end, field_map.title, 'name']

    if field_map.color:
        fields.append(field_map.color)

    start_date = "ifnull(%s, '0000-00-00 00:00:00')" % field_map.start
    end_date = "ifnull(%s, '2199-12-31 00:00:00')" % field_map.end

    filters += [
        [doctype, start_date, '<=', end],
        [doctype, end_date, '>=', start],
    ]

    return dataent.get_list(doctype, fields=fields, filters=filters)
Пример #16
0
 def on_update_after_submit(self):
     student = dataent.get_list("Student",
                                filters={"student_applicant": self.name})
     if student:
         dataent.throw(
             _("Cannot change status as student {0} is linked with student application {1}"
               ).format(student[0].name, self.name))
Пример #17
0
def get_assessment_criteria(course):
    """Returns Assessmemt Criteria and their Weightage from Course Master.

	:param Course: Course
	"""
    return dataent.get_list("Course Assessment Criteria", \
     fields=["assessment_criteria", "weightage"], filters={"parent": course}, order_by= "idx")
def execute():
    if not dataent.db.table_exists('Daily Work Summary Group'):
        dataent.reload_doc("hr", "doctype", "daily_work_summary_group")
        dataent.reload_doc("hr", "doctype", "daily_work_summary_group_user")

        # check if Daily Work Summary Settings Company table exists
        try:
            dataent.db.sql('DESC `tabDaily Work Summary Settings Company`')
        except Exception:
            return

        # get the previously saved settings
        previous_setting = get_previous_setting()
        if previous_setting["companies"]:
            for d in previous_setting["companies"]:
                users = dataent.get_list(
                    "Employee", dict(company=d.company, user_id=("!=", " ")),
                    "user_id as user")
                if (len(users)):
                    # create new group entry for each company entry
                    new_group = dataent.get_doc(
                        dict(doctype="Daily Work Summary Group",
                             name="Daily Work Summary for " + d.company,
                             users=users,
                             send_emails_at=d.send_emails_at,
                             subject=previous_setting["subject"],
                             message=previous_setting["message"]))
                    new_group.flags.ignore_permissions = True
                    new_group.flags.ignore_validate = True
                    new_group.insert(ignore_if_duplicate=True)

    dataent.delete_doc("DocType", "Daily Work Summary Settings")
    dataent.delete_doc("DocType", "Daily Work Summary Settings Company")
Пример #19
0
def get_children(doctype, parent=None, is_root=False, **filters):
	if not parent or parent=="BOM":
		dataent.msgprint(_('Please select a BOM'))
		return

	if dataent.form_dict.parent:
		bom_doc = dataent.get_doc("BOM", dataent.form_dict.parent)
		dataent.has_permission("BOM", doc=bom_doc, throw=True)

		bom_items = dataent.get_all('BOM Item',
			fields=['item_code', 'bom_no as value', 'stock_qty'],
			filters=[['parent', '=', dataent.form_dict.parent]],
			order_by='idx')

		item_names = tuple(d.get('item_code') for d in bom_items)

		items = dataent.get_list('Item',
			fields=['image', 'description', 'name'],
			filters=[['name', 'in', item_names]]) # to get only required item dicts

		for bom_item in bom_items:
			# extend bom_item dict with respective item dict
			bom_item.update(
				# returns an item dict from items list which matches with item_code
				next(item for item in items if item.get('name')
					== bom_item.get('item_code'))
			)
			bom_item.expandable = 0 if bom_item.value in ('', None)  else 1

		return bom_items
Пример #20
0
def get_children(doctype, parent, company, is_root=False):
	from epaas.accounts.report.financial_statements import sort_accounts

	parent_fieldname = 'parent_' + doctype.lower().replace(' ', '_')
	fields = [
		'name as value',
		'is_group as expandable'
	]
	filters = [['docstatus', '<', 2]]

	filters.append(['ifnull(`{0}`,"")'.format(parent_fieldname), '=', '' if is_root else parent])

	if is_root:
		fields += ['root_type', 'report_type', 'account_currency'] if doctype == 'Account' else []
		filters.append(['company', '=', company])

	else:
		fields += ['account_currency'] if doctype == 'Account' else []
		fields += [parent_fieldname + ' as parent']

	acc = dataent.get_list(doctype, fields=fields, filters=filters)

	if doctype == 'Account':
		sort_accounts(acc, is_root, key="value")
		company_currency = dataent.get_cached_value('Company',  company,  "default_currency")
		for each in acc:
			each["company_currency"] = company_currency
			each["balance"] = flt(get_balance_on(each.get("value"), in_account_currency=False))

			if each.account_currency != company_currency:
				each["balance_in_account_currency"] = flt(get_balance_on(each.get("value")))

	return acc
def execute(filters=None):
    user, doctype, show_permissions = filters.get("user"), filters.get(
        "doctype"), filters.get("show_permissions")
    if not validate(user, doctype): return [], []

    columns, fields = get_columns_and_fields(doctype)
    data = dataent.get_list(doctype, fields=fields, as_list=True, user=user)

    if show_permissions:
        columns = columns + [
            "Read", "Write", "Create", "Delete", "Submit", "Cancel", "Amend",
            "Print", "Email", "Report", "Import", "Export", "Share"
        ]
        data = list(data)
        for i, item in enumerate(data):
            temp = dataent.permissions.get_doc_permissions(
                dataent.get_doc(doctype, item[0]), False, user)
            data[i] = item + (
                temp.get("read"),
                temp.get("write"),
                temp.get("create"),
                temp.get("delete"),
                temp.get("submit"),
                temp.get("cancel"),
                temp.get("amend"),
                temp.get("print"),
                temp.get("email"),
                temp.get("report"),
                temp.get("import"),
                temp.get("export"),
                temp.get("share"),
            )

    return columns, data
Пример #22
0
    def test_contextual_user_permission(self):
        # should be applicable for across all doctypes
        add_user_permission('Blogger', '_Test Blogger', '*****@*****.**')
        # should be applicable only while accessing Blog Post
        add_user_permission('Blogger',
                            '_Test Blogger 1',
                            '*****@*****.**',
                            applicable_for='Blog Post')
        # should be applicable only while accessing User
        add_user_permission('Blogger',
                            '_Test Blogger 2',
                            '*****@*****.**',
                            applicable_for='User')

        posts = dataent.get_all('Blog Post', fields=['name', 'blogger'])

        # Get all posts for admin
        self.assertEqual(len(posts), 4)

        dataent.set_user('*****@*****.**')

        posts = dataent.get_list('Blog Post', fields=['name', 'blogger'])

        # Should get only posts with allowed blogger via user permission
        # only '_Test Blogger', '_Test Blogger 1' are allowed in Blog Post
        self.assertEqual(len(posts), 3)

        for post in posts:
            self.assertIn(
                post.blogger, ['_Test Blogger', '_Test Blogger 1'],
                'A post from {} is not expected.'.format(post.blogger))
Пример #23
0
def execute():
    '''Update company monthly sales history based on sales invoices'''
    dataent.reload_doctype("Company")
    companies = [d['name'] for d in dataent.get_list("Company")]

    for company in companies:
        update_company_current_month_sales(company)
        update_company_monthly_sales(company)
Пример #24
0
	def load_kanban_column_fields(self):
		values = dataent.get_list(
			'Kanban Board', fields=['field_name'],
			filters={'reference_doctype': self.name})

		fields = [x['field_name'] for x in values]
		fields = list(set(fields))
		self.set("__kanban_column_fields", fields, as_value=True)
Пример #25
0
	def test_run(self):
		create_plan()

		description = 'data migration todo'
		new_todo = dataent.get_doc({
			'doctype': 'ToDo',
			'description': description
		}).insert()

		event_subject = 'data migration event'
		dataent.get_doc(dict(
			doctype='Event',
			subject=event_subject,
			repeat_on='Every Month',
			starts_on=dataent.utils.now_datetime()
		)).insert()

		run = dataent.get_doc({
			'doctype': 'Data Migration Run',
			'data_migration_plan': 'ToDo Sync',
			'data_migration_connector': 'Local Connector'
		}).insert()

		run.run()
		self.assertEqual(run.db_get('status'), 'Success')

		self.assertEqual(run.db_get('push_insert'), 1)
		self.assertEqual(run.db_get('pull_insert'), 1)

		todo = dataent.get_doc('ToDo', new_todo.name)
		self.assertTrue(todo.todo_sync_id)

		# Pushed Event
		event = dataent.get_doc('Event', todo.todo_sync_id)
		self.assertEqual(event.subject, description)

		# Pulled ToDo
		created_todo = dataent.get_doc('ToDo', {'description': event_subject})
		self.assertEqual(created_todo.description, event_subject)

		todo_list = dataent.get_list('ToDo', filters={'description': 'Data migration todo'}, fields=['name'])
		todo_name = todo_list[0].name

		todo = dataent.get_doc('ToDo', todo_name)
		todo.description = 'Data migration todo updated'
		todo.save()

		run = dataent.get_doc({
			'doctype': 'Data Migration Run',
			'data_migration_plan': 'ToDo Sync',
			'data_migration_connector': 'Local Connector'
		}).insert()

		run.run()

		# Update
		self.assertEqual(run.db_get('status'), 'Success')
		self.assertEqual(run.db_get('pull_update'), 1)
Пример #26
0
 def get_shareholder_doc(self, shareholder):
     # Get Shareholder doc based on the Shareholder title
     doc = dataent.get_list('Shareholder',
                            filters=[('Shareholder', 'title', '=',
                                      shareholder)])
     if len(doc) == 1:
         return dataent.get_doc('Shareholder', doc[0]['name'])
     else:  #It will necessarily by 0 indicating it doesn't exist
         return False
Пример #27
0
def get_student_guardians(student):
    """Returns List of Guardians of a Student.

	:param student: Student.
	"""
    guardians = dataent.get_list("Student Guardian",
                                 fields=["guardian"],
                                 filters={"parent": student})
    return guardians
Пример #28
0
def check_attendance_records_exist(course_schedule=None,
                                   student_group=None,
                                   date=None):
    """Check if Attendance Records are made against the specified Course Schedule or Student Group for given date.

	:param course_schedule: Course Schedule.
	:param student_group: Student Group.
	:param date: Date.
	"""
    if course_schedule:
        return dataent.get_list("Student Attendance",
                                filters={"course_schedule": course_schedule})
    else:
        return dataent.get_list("Student Attendance",
                                filters={
                                    "student_group": student_group,
                                    "date": date
                                })
Пример #29
0
def get_student_group_students(student_group, include_inactive=0):
    """Returns List of student, student_name in Student Group.

	:param student_group: Student Group.
	"""
    if include_inactive:
        students = dataent.get_list("Student Group Student",
                                    fields=["student", "student_name"],
                                    filters={"parent": student_group},
                                    order_by="group_roll_number")
    else:
        students = dataent.get_list("Student Group Student",
                                    fields=["student", "student_name"],
                                    filters={
                                        "parent": student_group,
                                        "active": 1
                                    },
                                    order_by="group_roll_number")
    return students
Пример #30
0
 def on_cancel(self):
     attendance_list = dataent.get_list("Attendance", {
         'employee': self.employee,
         'attendance_request': self.name
     })
     if attendance_list:
         for attendance in attendance_list:
             attendance_obj = dataent.get_doc("Attendance",
                                              attendance['name'])
             attendance_obj.cancel()