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
def get_transitions(doc, workflow = None): '''Return list of possible transitions for the given doc''' doc = dataent.get_doc(dataent.parse_json(doc)) if doc.is_new(): return [] dataent.has_permission(doc, 'read', throw=True) roles = dataent.get_roles() if not workflow: workflow = get_workflow(doc.doctype) current_state = doc.get(workflow.workflow_state_field) if not current_state: dataent.throw(_('Workflow State not set'), WorkflowStateError) transitions = [] for transition in workflow.transitions: if transition.state == current_state and transition.allowed in roles: if transition.condition: # if condition, evaluate # access to dataent.db.get_value and dataent.db.get_list success = dataent.safe_eval(transition.condition, dict(dataent = dataent._dict( db = dataent._dict(get_value = dataent.db.get_value, get_list=dataent.db.get_list), session = dataent.session )), dict(doc = doc)) if not success: continue transitions.append(transition.as_dict()) return transitions
def send_gstin_reminder(party_type, party): '''Send GSTIN reminder to one party (called from Customer, Supplier form)''' dataent.has_permission(party_type, throw=True) email = _send_gstin_reminder(party_type, party) if email: dataent.msgprint(_('Reminder to update GSTIN Sent'), title='Reminder sent', indicator='green')
def get_stock_balance_for(item_code, warehouse, posting_date, posting_time): dataent.has_permission("Stock Reconciliation", "write", throw=True) qty, rate = get_stock_balance(item_code, warehouse, posting_date, posting_time, with_valuation_rate=True) return {'qty': qty, 'rate': rate}
def make_depreciation_entry(asset_name, date=None): dataent.has_permission('Journal Entry', throw=True) if not date: date = today() asset = dataent.get_doc("Asset", asset_name) fixed_asset_account, accumulated_depreciation_account, depreciation_expense_account = \ get_depreciation_accounts(asset) depreciation_cost_center, depreciation_series = dataent.get_cached_value('Company', asset.company, ["depreciation_cost_center", "series_for_depreciation_entry"]) depreciation_cost_center = asset.cost_center or depreciation_cost_center for d in asset.get("schedules"): if not d.journal_entry and getdate(d.schedule_date) <= getdate(date): je = dataent.new_doc("Journal Entry") je.voucher_type = "Depreciation Entry" je.naming_series = depreciation_series je.posting_date = d.schedule_date je.company = asset.company je.finance_book = d.finance_book je.remark = "Depreciation Entry against {0} worth {1}".format(asset_name, d.depreciation_amount) je.append("accounts", { "account": accumulated_depreciation_account, "credit_in_account_currency": d.depreciation_amount, "reference_type": "Asset", "reference_name": asset.name }) je.append("accounts", { "account": depreciation_expense_account, "debit_in_account_currency": d.depreciation_amount, "reference_type": "Asset", "reference_name": asset.name, "cost_center": depreciation_cost_center }) je.flags.ignore_permissions = True je.submit() d.db_set("journal_entry", je.name) idx = cint(d.finance_book_id) finance_books = asset.get('finance_books')[idx - 1] finance_books.value_after_depreciation -= d.depreciation_amount finance_books.db_update() asset.set_status() return asset
def sync(self): """Create and execute Data Migration Run for GCalendar Sync plan""" dataent.has_permission('GCalendar Settings', throw=True) accounts = dataent.get_all("GCalendar Account", filters={'enabled': 1}) queued_jobs = get_jobs(site=dataent.local.site, key='job_name')[dataent.local.site] for account in accounts: job_name = 'google_calendar_sync|{0}'.format(account.name) if job_name not in queued_jobs: dataent.enqueue('dataent.integrations.doctype.gcalendar_settings.gcalendar_settings.run_sync', queue='long', timeout=1500, job_name=job_name, account=account) time.sleep(5)
def check_share_permission(self): if (not self.flags.ignore_share_permission and not dataent.has_permission(self.share_doctype, "share", self.get_doc())): dataent.throw(_('You need to have "Share" permission'), dataent.PermissionError)
def insert_item_price(args): """Insert Item Price if Price List and Price List Rate are specified and currency is the same""" if dataent.db.get_value("Price List", args.price_list, "currency", cache=True) == args.currency \ and cint(dataent.db.get_single_value("Stock Settings", "auto_insert_price_list_rate_if_missing")): if dataent.has_permission("Item Price", "write"): price_list_rate = (args.rate / args.get('conversion_factor') if args.get("conversion_factor") else args.rate) item_price = dataent.db.get_value('Item Price', {'item_code': args.item_code, 'price_list': args.price_list, 'currency': args.currency}, ['name', 'price_list_rate'], as_dict=1) if item_price and item_price.name: if item_price.price_list_rate != price_list_rate: dataent.db.set_value('Item Price', item_price.name, "price_list_rate", price_list_rate) dataent.msgprint(_("Item Price updated for {0} in Price List {1}").format(args.item_code, args.price_list), alert=True) else: item_price = dataent.get_doc({ "doctype": "Item Price", "price_list": args.price_list, "item_code": args.item_code, "currency": args.currency, "price_list_rate": price_list_rate }) item_price.insert() dataent.msgprint(_("Item Price added for {0} in Price List {1}").format(args.item_code, args.price_list), alert=True)
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
def get_single_value(doctype, field): if not dataent.has_permission(doctype): dataent.throw( _("No permission for {0}").format(doctype), dataent.PermissionError) value = dataent.db.get_single_value(doctype, field) return value
def get_report_doc(report_name): doc = dataent.get_doc("Report", report_name) doc.custom_columns = [] if doc.report_type == 'Custom Report': custom_report_doc = doc reference_report = custom_report_doc.reference_report doc = dataent.get_doc("Report", reference_report) doc.custom_report = report_name doc.custom_columns = custom_report_doc.json doc.is_custom_report = True if not doc.is_permitted(): dataent.throw( _("You don't have access to Report: {0}").format(report_name), dataent.PermissionError) if not dataent.has_permission(doc.ref_doctype, "report"): dataent.throw( _("You don't have permission to get a report on: {0}").format( doc.ref_doctype), dataent.PermissionError) if doc.disabled: dataent.throw(_("Report {0} is disabled").format(report_name)) return doc
def run(report_name, filters=None, user=None): report = get_report_doc(report_name) if not user: user = dataent.session.user if not dataent.has_permission(report.ref_doctype, "report"): dataent.msgprint( _("Must have report permission to access this report."), raise_exception=True) result = None if report.prepared_report and not report.disable_prepared_report: if filters: if isinstance(filters, string_types): filters = json.loads(filters) dn = filters.get("prepared_report_name") filters.pop("prepared_report_name", None) else: dn = "" result = get_prepared_report_result(report, filters, dn, user) else: result = generate_report_result(report, filters, user) result["add_total_row"] = report.add_total_row return result
def has_permission(doc, ptype, user): if ptype == "read": if (doc.reference_doctype == "Communication" and doc.reference_name == doc.name) \ or (doc.timeline_doctype == "Communication" and doc.timeline_name == doc.name): return if doc.reference_doctype and doc.reference_name: if dataent.has_permission(doc.reference_doctype, ptype="read", doc=doc.reference_name): return True if doc.timeline_doctype and doc.timeline_name: if dataent.has_permission(doc.timeline_doctype, ptype="read", doc=doc.timeline_name): return True
def check_file_permission(file_url): for file in dataent.get_all( "File", filters={ "file_url": file_url, "is_private": 1 }, fields=["name", "attached_to_doctype", "attached_to_name"]): if (dataent.has_permission("File", ptype="read", doc=file.name) or dataent.has_permission(file.attached_to_doctype, ptype="read", doc=file.attached_to_name)): return True raise dataent.PermissionError
def get_event_conditions(doctype, filters=None): """Returns SQL conditions with user permissions and filters for event queries""" from dataent.desk.reportview import get_filters_cond if not dataent.has_permission(doctype): dataent.throw(_("Not Permitted"), dataent.PermissionError) return get_filters_cond(doctype, filters, [], with_match_conditions=True)
def send_reminder(): dataent.has_permission('GST Settings', throw=True) last_sent = dataent.db.get_single_value('GST Settings', 'gstin_email_sent_on') if last_sent and date_diff(nowdate(), last_sent) < 3: dataent.throw(_("Please wait 3 days before resending the reminder.")) dataent.db.set_value('GST Settings', 'GST Settings', 'gstin_email_sent_on', nowdate()) # enqueue if large number of customers, suppliser dataent.enqueue( 'epaas.regional.doctype.gst_settings.gst_settings.send_gstin_reminder_to_all_parties' ) dataent.msgprint( _('Email Reminders will be sent to all parties with email contacts'))
def test_allowed_private_if_in_event_user(self): name = dataent.db.get_value("Event", {"subject": "_Test Event 3"}) dataent.share.add("Event", name, self.test_user, "read") dataent.set_user(self.test_user) doc = dataent.get_doc("Event", name) self.assertTrue(dataent.has_permission("Event", doc=doc)) dataent.set_user("Administrator") dataent.share.remove("Event", name, self.test_user)
def append_table(self, table_name): self.tables.append(table_name) doctype = table_name[4:-1] if (not self.flags.ignore_permissions) and ( not dataent.has_permission(doctype)): dataent.flags.error_message = _( 'Insufficient Permission for {0}').format( dataent.bold(doctype)) raise dataent.PermissionError(doctype)
def validate_print_permission(doc): if dataent.form_dict.get("key"): if dataent.form_dict.key == doc.get_signature(): return for ptype in ("read", "print"): if (not dataent.has_permission(doc.doctype, ptype, doc) and not dataent.has_website_permission(doc)): raise dataent.PermissionError(_("No {0} permission").format(ptype))
def can_subscribe_doc(doctype, docname, sid): if os.environ.get('CI'): return True from dataent.sessions import Session from dataent.exceptions import PermissionError session = Session(None, resume=True).get_session_data() if not dataent.has_permission( user=session.user, doctype=doctype, doc=docname, ptype='read'): raise PermissionError() return True
def has_permission(self, permtype="read", verbose=False): """Call `dataent.has_permission` if `self.flags.ignore_permissions` is not set. :param permtype: one of `read`, `write`, `submit`, `cancel`, `delete`""" if self.flags.ignore_permissions: return True return dataent.has_permission(self.doctype, permtype, self, verbose=verbose)
def has_permission(doctype, docname, perm_type="read"): '''Returns a JSON with data whether the document has the requested permission :param doctype: DocType of the document to be checked :param docname: `name` of the document to be checked :param perm_type: one of `read`, `write`, `create`, `submit`, `cancel`, `report`. Default is `read`''' # perm_type can be one of read, write, create, submit, cancel, report return { "has_permission": dataent.has_permission(doctype, perm_type.lower(), docname) }
def get_item_attribute(parent, attribute_value=''): if not dataent.has_permission("Item"): dataent.msgprint(_("No Permission"), raise_exception=1) return dataent.get_all("Item Attribute Value", fields=["attribute_value"], filters={ 'parent': parent, 'attribute_value': ("like", "%%%s%%" % attribute_value) })
def upload(select_doctype=None, rows=None): from dataent.utils.csvutils import read_csv_content_from_attached_file if not select_doctype: select_doctype = dataent.form_dict.select_doctype if not dataent.has_permission(select_doctype, "write"): raise dataent.PermissionError rows = read_csv_content_from_attached_file( dataent.get_doc("Rename Tool", "Rename Tool")) return bulk_rename(select_doctype, rows=rows)
def stop_unstop(production_order, status): """ Called from client side on Stop/Unstop event""" if not dataent.has_permission("Production Order", "write"): dataent.throw(_("Not permitted"), dataent.PermissionError) pro_order = dataent.get_doc("Production Order", production_order) pro_order.update_status(status) pro_order.update_planned_qty() dataent.msgprint(_("Production Order has been {0}").format(status)) pro_order.notify_update() return pro_order.status
def make_default(name): """Set print format as default""" dataent.has_permission("Print Format", "write") print_format = dataent.get_doc("Print Format", name) if (dataent.conf.get('developer_mode') or 0) == 1: # developer mode, set it default in doctype doctype = dataent.get_doc("DocType", print_format.doc_type) doctype.default_print_format = name doctype.save() else: # customization dataent.make_property_setter({ 'doctype_or_field': "DocType", 'doctype': print_format.doc_type, 'property': "default_print_format", 'value': name, }) dataent.msgprint( dataent._("{0} is now default print format for {1} doctype").format( dataent.bold(name), dataent.bold(print_format.doc_type)))
def get_template(): if not dataent.has_permission("Attendance", "create"): raise dataent.PermissionError args = dataent.local.form_dict w = UnicodeWriter() w = add_header(w) w = add_data(w, args) # write out response as a type csv dataent.response['result'] = cstr(w.getvalue()) dataent.response['type'] = 'csv' dataent.response['doctype'] = "Attendance"
def make_raw_material_request(items, company, sales_order, project=None): if not dataent.has_permission("Sales Order", "write"): dataent.throw(_("Not permitted"), dataent.PermissionError) if isinstance(items, string_types): items = dataent._dict(json.loads(items)) for item in items.get('items'): item["include_exploded_items"] = items.get('include_exploded_items') item["ignore_existing_ordered_qty"] = items.get( 'ignore_existing_ordered_qty') item["include_raw_materials_from_sales_order"] = items.get( 'include_raw_materials_from_sales_order') raw_materials = get_items_for_material_requests(items, sales_order, company) if not raw_materials: dataent.msgprint( _("Material Request not created, as quantity for Raw Materials already available." )) return material_request = dataent.new_doc('Material Request') material_request.update( dict(doctype='Material Request', transaction_date=nowdate(), company=company, requested_by=dataent.session.user, material_request_type='Purchase')) for item in raw_materials: item_doc = dataent.get_cached_doc('Item', item.get('item_code')) schedule_date = add_days(nowdate(), cint(item_doc.lead_time_days)) material_request.append( 'items', { 'item_code': item.get('item_code'), 'qty': item.get('quantity'), 'schedule_date': schedule_date, 'warehouse': item.get('warehouse'), 'sales_order': sales_order, 'project': project }) material_request.insert() material_request.flags.ignore_permissions = 1 material_request.run_method("set_missing_values") material_request.submit() return material_request
def upload(): if not dataent.has_permission("Attendance", "create"): raise dataent.PermissionError from dataent.utils.csvutils import read_csv_content_from_uploaded_file from dataent.modules import scrub rows = read_csv_content_from_uploaded_file() rows = list(filter(lambda x: x and any(x), rows)) if not rows: msg = [_("Please select a csv file")] return {"messages": msg, "error": msg} columns = [scrub(f) for f in rows[4]] columns[0] = "name" columns[3] = "attendance_date" ret = [] error = False from dataent.utils.csvutils import check_record, import_doc for i, row in enumerate(rows[5:]): if not row: continue row_idx = i + 5 d = dataent._dict(zip(columns, row)) d["doctype"] = "Attendance" if d.name: d["docstatus"] = dataent.db.get_value("Attendance", d.name, "docstatus") try: check_record(d) ret.append(import_doc(d, "Attendance", 1, row_idx, submit=True)) except AttributeError: pass except Exception as e: error = True ret.append('Error for row (#%d) %s : %s' % (row_idx, len(row) > 1 and row[1] or "", cstr(e))) dataent.errprint(dataent.get_traceback()) if error: dataent.db.rollback() else: dataent.db.commit() return {"messages": ret, "error": error}
def get_value(doctype, fieldname, filters=None, as_dict=True, debug=False, parent=None): '''Returns a value form a document :param doctype: DocType to be queried :param fieldname: Field to be returned (default `name`) :param filters: dict or string for identifying the record''' if dataent.is_table(doctype): check_parent_permission(parent, doctype) if not dataent.has_permission(doctype): dataent.throw(_("No permission for {0}".format(doctype)), dataent.PermissionError) try: filters = json.loads(filters) if isinstance(filters, (integer_types, float)): filters = dataent.as_unicode(filters) except (TypeError, ValueError): # filters are not passesd, not json pass try: fieldname = json.loads(fieldname) except (TypeError, ValueError): # name passed, not json pass # check whether the used filters were really parseable and usable # and did not just result in an empty string or dict if not filters: filters = None return dataent.db.get_value(doctype, filters, fieldname, as_dict=as_dict, debug=debug)