Example #1
1
def get_transitions(doc, workflow = None):
	'''Return list of possible transitions for the given doc'''
	doc = frappe.get_doc(frappe.parse_json(doc))

	if doc.is_new():
		return []

	frappe.has_permission(doc, 'read', throw=True)
	roles = frappe.get_roles()

	if not workflow:
		workflow = get_workflow(doc.doctype)
	current_state = doc.get(workflow.workflow_state_field)

	if not current_state:
		frappe.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 frappe.db.get_value and frappe.db.get_list
				success = frappe.safe_eval(transition.condition,
					dict(frappe = frappe._dict(
						db = frappe._dict(get_value = frappe.db.get_value, get_list=frappe.db.get_list),
						session = frappe.session
					)),
					dict(doc = doc))
				if not success:
					continue
			transitions.append(transition.as_dict())

	return transitions
Example #2
0
def get_children(doctype, parent=None, is_root=False, **filters):
	if not parent or parent=="BOM":
		frappe.msgprint(_('Please select a BOM'))
		return

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

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

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

		items = frappe.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
Example #3
0
def get_batch_qty(batch_no=None, warehouse=None, item_code=None):
	'''Returns batch actual qty if warehouse is passed,
		or returns dict of qty by warehouse if warehouse is None

	The user must pass either batch_no or batch_no + warehouse or item_code + warehouse

	:param batch_no: Optional - give qty for this batch no
	:param warehouse: Optional - give qty for this warehouse
	:param item_code: Optional - give qty for this item'''
	frappe.has_permission('Batch', throw=True)
	out = 0
	if batch_no and warehouse:
		out = float(frappe.db.sql("""select sum(actual_qty)
			from `tabStock Ledger Entry`
			where warehouse=%s and batch_no=%s""",
			(warehouse, batch_no))[0][0] or 0)
	if batch_no and not warehouse:
		out = frappe.db.sql('''select warehouse, sum(actual_qty) as qty
			from `tabStock Ledger Entry`
			where batch_no=%s
			group by warehouse''', batch_no, as_dict=1)
	if not batch_no and item_code and warehouse:
		out = frappe.db.sql('''select batch_no, sum(actual_qty) as qty
			from `tabStock Ledger Entry`
			where item_code = %s and warehouse=%s
			group by batch_no''', (item_code, warehouse), as_dict=1)
	return out
Example #4
0
def get_account_details(account, date):
	frappe.has_permission('Payment Entry', throw=True)
	return frappe._dict({
		"account_currency": get_account_currency(account),
		"account_balance": get_balance_on(account, date),
		"account_type": frappe.db.get_value("Account", account, "account_type")
	})
Example #5
0
def check_file_permission(file_url):
	for file in frappe.get_all("File", filters={"file_url": file_url, "is_private": 1}, fields=["name", "attached_to_doctype", "attached_to_name"]):

		if (frappe.has_permission("File", ptype="read", doc=file.name)
			or frappe.has_permission(file.attached_to_doctype, ptype="read", doc=file.attached_to_name)):
			return True

	raise frappe.PermissionError
Example #6
0
def has_permission(doc, ptype, user):
	if ptype=="read":
		if doc.reference_doctype and doc.reference_name:
			if frappe.has_permission(doc.reference_doctype, ptype="read", doc=doc.reference_name):
				return True
		if doc.timeline_doctype and doc.timeline_name:
			if frappe.has_permission(doc.timeline_doctype, ptype="read", doc=doc.timeline_name):
				return True
Example #7
0
def get_dashboard_data(name):
	'''load dashboard related data'''
	frappe.has_permission(doc=frappe.get_doc('Item', name), throw=True)

	from frappe.desk.notifications import get_open_count
	return {
		'count': get_open_count('Item', name),
		'timeline_data': get_timeline_data(name),
	}
Example #8
0
def get_open_count(doctype, name, items=[]):
	'''Get open count for given transactions and filters

	:param doctype: Reference DocType
	:param name: Reference Name
	:param transactions: List of transactions (json/dict)
	:param filters: optional filters (json/list)'''

	if frappe.flags.in_migrate or frappe.flags.in_install:
		return {
			'count': []
		}

	frappe.has_permission(doc=frappe.get_doc(doctype, name), throw=True)

	meta = frappe.get_meta(doctype)
	links = meta.get_dashboard_data()

	# compile all items in a list
	if not items:
		for group in links.transactions:
			items.extend(group.get('items'))

	if not isinstance(items, list):
		items = json.loads(items)

	out = []
	for d in items:
		if d in links.get('internal_links', {}):
			# internal link
			continue

		filters = get_filters_for(d)
		fieldname = links.get('non_standard_fieldnames', {}).get(d, links.fieldname)
		data = {'name': d}
		if filters:
			# get the fieldname for the current document
			# we only need open documents related to the current document
			filters[fieldname] = name
			total = len(frappe.get_all(d, fields='name',
				filters=filters, limit=100, distinct=True, ignore_ifnull=True))
			data['open_count'] = total

		total = len(frappe.get_all(d, fields='name',
			filters={fieldname: name}, limit=100, distinct=True, ignore_ifnull=True))
		data['count'] = total
		out.append(data)

	out = {
		'count': out,
	}

	module = frappe.get_meta_module(doctype)
	if hasattr(module, 'get_timeline_data'):
		out['timeline_data'] = module.get_timeline_data(doctype, name)

	return out
def get_stock_balance_for(item_code, warehouse, posting_date, posting_time):
	frappe.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
	}
Example #10
0
	def sync(self):
		"""Create and execute Data Migration Run for Hub Sync plan"""
		frappe.has_permission('Hub Settings', throw=True)

		doc = frappe.get_doc({
			'doctype': 'Data Migration Run',
			'data_migration_plan': 'Hub Sync',
			'data_migration_connector': 'Hub Connector'
		}).insert()

		doc.run()
Example #11
0
def make_depreciation_entry(asset_name, date=None):
	frappe.has_permission('Journal Entry', throw=True)

	if not date:
		date = today()

	asset = frappe.get_doc("Asset", asset_name)
	fixed_asset_account, accumulated_depreciation_account, depreciation_expense_account = \
		get_depreciation_accounts(asset)

	depreciation_cost_center, depreciation_series = frappe.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 = frappe.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
Example #12
0
def send_reminder():
	frappe.has_permission('GST Settings', throw=True)

	last_sent = frappe.db.get_single_value('GST Settings', 'gstin_email_sent_on')
	if last_sent and date_diff(nowdate(), last_sent) < 3:
		frappe.throw("Please wait 3 days before resending the reminder.")

	frappe.db.set_value('GST Settings', 'GST Settings', 'gstin_email_sent_on', nowdate())

	# enqueue if large number of customers, suppliser
	frappe.enqueue('erpnext.regional.doctype.gst_settings.gst_settings.send_gstin_reminder_to_all_parties')
	frappe.msgprint('Email Reminders will be sent to all parties with email contacts')
Example #13
0
def make_depreciation_entry(asset_name, date=None):
    frappe.has_permission("Journal Entry", throw=True)

    if not date:
        date = today()

    asset = frappe.get_doc("Asset", asset_name)
    fixed_asset_account, accumulated_depreciation_account, depreciation_expense_account = get_depreciation_accounts(
        asset
    )

    depreciation_cost_center = frappe.db.get_value("Company", asset.company, "depreciation_cost_center")

    for d in asset.get("schedules"):
        if not d.journal_entry and getdate(d.schedule_date) <= getdate(date):
            je = frappe.new_doc("Journal Entry")
            je.voucher_type = "Depreciation Entry"
            je.posting_date = d.schedule_date
            je.company = asset.company
            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)
            asset.value_after_depreciation -= d.depreciation_amount

    asset.db_set("value_after_depreciation", asset.value_after_depreciation)
    asset.set_status()

    return asset
Example #14
0
def make_default(name):
	frappe.has_permission("Print Format", "write")

	print_format = frappe.get_doc("Print Format", name)

	frappe.make_property_setter({
		'doctype_or_field': "DocType",
		'doctype': print_format.doc_type,
		'property': "default_print_format",
		'value': name,
	})

	frappe.msgprint(frappe._("Done"))
Example #15
0
	def sync(self):
		"""Create and execute Data Migration Run for GCalendar Sync plan"""
		frappe.has_permission('GCalendar Settings', throw=True)


		accounts = frappe.get_all("GCalendar Account", filters={'enabled': 1})

		queued_jobs = get_jobs(site=frappe.local.site, key='job_name')[frappe.local.site]
		for account in accounts:
			job_name = 'google_calendar_sync|{0}'.format(account.name)
			if job_name not in queued_jobs:
				frappe.enqueue('frappe.integrations.doctype.gcalendar_settings.gcalendar_settings.run_sync', queue='long', timeout=1500, job_name=job_name, account=account)
				time.sleep(5)
Example #16
0
def can_subscribe_doc(doctype, docname, sid):
	from frappe.sessions import Session
	from frappe.exceptions import PermissionError
	session = Session(None).get_session_data()
	if not frappe.has_permission(user=session.user, doctype=doctype, doc=docname, ptype='read'):
		raise PermissionError()
	return True
Example #17
0
	def execute(self, query=None, filters=None, fields=None, or_filters=None,
		docstatus=None, group_by=None, order_by=None, limit_start=0,
		limit_page_length=20, as_list=False, with_childnames=False, debug=False,
		ignore_permissions=False, user=None):
		if not ignore_permissions and not frappe.has_permission(self.doctype, "read", user=user):
			raise frappe.PermissionError, self.doctype

		if fields:
			self.fields = fields
		self.filters = filters or []
		self.or_filters = or_filters or []
		self.docstatus = docstatus or []
		self.group_by = group_by
		self.order_by = order_by
		self.limit_start = limit_start
		self.limit_page_length = limit_page_length
		self.with_childnames = with_childnames
		self.debug = debug
		self.as_list = as_list
		self.ignore_permissions = ignore_permissions
		self.user = user or frappe.session.user

		if query:
			return self.run_custom_query(query)
		else:
			return self.build_and_run()
Example #18
0
def _get_party_details(party=None, account=None, party_type="Customer", company=None,
	posting_date=None, price_list=None, currency=None, doctype=None, ignore_permissions=False):

	out = frappe._dict(set_account_and_due_date(party, account, party_type, company, posting_date, doctype))

	party = out[party_type.lower()]

	if not ignore_permissions and not frappe.has_permission(party_type, "read", party):
		frappe.throw(_("Not permitted"), frappe.PermissionError)

	party = frappe.get_doc(party_type, party)

	set_address_details(out, party, party_type)
	set_contact_details(out, party, party_type)
	set_other_values(out, party, party_type)
	set_price_list(out, party, party_type, price_list)
	out["taxes_and_charges"] = set_taxes(party.name, party_type, posting_date, company, out.customer_group, out.supplier_type)

	if not out.get("currency"):
		out["currency"] = currency

	# sales team
	if party_type=="Customer":
		out["sales_team"] = [{
			"sales_person": d.sales_person,
			"allocated_percentage": d.allocated_percentage or None
		} for d in party.get("sales_team")]

	return out
Example #19
0
def stop_or_unstop_sales_orders(names, status):
	if not frappe.has_permission("Sales Order", "write"):
		frappe.throw(_("Not permitted"), frappe.PermissionError)

	names = json.loads(names)
	for name in names:
		so = frappe.get_doc("Sales Order", name)
		if so.docstatus == 1:
			if status=="Stop":
				if so.status not in ("Stopped", "Cancelled") and (so.per_delivered < 100 or so.per_billed < 100):
					so.stop_sales_order()
			else:
				if so.status == "Stopped":
					so.unstop_sales_order()

	frappe.local.message_log = []

	def before_recurring(self):
		super(SalesOrder, self).before_recurring()

		for field in ("delivery_status", "per_delivered", "billing_status", "per_billed"):
			self.set(field, None)

		for d in self.get("items"):
			for field in ("delivered_qty", "billed_amt", "planned_qty", "prevdoc_docname"):
				d.set(field, None)
Example #20
0
def get_account_balance_and_party_type(account, date, company, debit=None, credit=None, exchange_rate=None):
	"""Returns dict of account balance and party type to be set in Journal Entry on selection of account."""
	if not frappe.has_permission("Account"):
		frappe.msgprint(_("No Permission"), raise_exception=1)

	company_currency = get_company_currency(company)
	account_details = frappe.db.get_value("Account", account, ["account_type", "account_currency"], as_dict=1)

	if account_details.account_type == "Receivable":
		party_type = "Customer"
	elif account_details.account_type == "Payable":
		party_type = "Supplier"
	else:
		party_type = ""

	grid_values = {
		"balance": get_balance_on(account, date),
		"party_type": party_type,
		"account_type": account_details.account_type,
		"account_currency": account_details.account_currency or company_currency,
		"exchange_rate": get_exchange_rate(account, account_details.account_currency,
			company, debit=debit, credit=credit, exchange_rate=exchange_rate)
	}

	# un-set party if not party type
	if not party_type:
		grid_values["party"] = ""

	return grid_values
Example #21
0
def get_account_balance_and_party_type(account, date, company, debit=None, credit=None, exchange_rate=None):
	"""Returns dict of account balance and party type to be set in Journal Entry on selection of account."""
	if not frappe.has_permission("Account"):
		frappe.msgprint(_("No Permission"), raise_exception=1)

	company_currency = erpnext.get_company_currency(company)
	account_details = frappe.db.get_value("Account", account, ["account_type", "account_currency"], as_dict=1)

	if not account_details:
		return

	if account_details.account_type == "Receivable":
		party_type = "Customer"
	elif account_details.account_type == "Payable":
		party_type = "Supplier"
	else:
		party_type = ""

	grid_values = {
		"balance": get_balance_on(account, date),
		"party_type": party_type,
		"account_type": account_details.account_type,
		"account_currency": account_details.account_currency or company_currency,

		# The date used to retreive the exchange rate here is the date passed in
		# as an argument to this function. It is assumed to be the date on which the balance is sought
		"exchange_rate": get_exchange_rate(date, account, account_details.account_currency,
			company, debit=debit, credit=credit, exchange_rate=exchange_rate)
	}

	# un-set party if not party type
	if not party_type:
		grid_values["party"] = ""

	return grid_values
Example #22
0
def upload():
	if not frappe.has_permission("BRS Entries", "create"):
		raise frappe.PermissionError

	from frappe.utils.csvutils import read_csv_content_from_uploaded_file
	from frappe.modules import scrub

	rows = read_csv_content_from_uploaded_file()
	rows = filter(lambda x: x and any(x), rows)
	if not rows:
		msg = [_("Please select a csv file")]
		return {"messages": msg, "error": msg}

	#Columns located at 4th row
	columns = [scrub(f) for f in rows[2]]
	ret = []
	error = False

	from frappe.utils.csvutils import check_record, import_doc

	for i, row in enumerate(rows[3:]):
		if not row: continue
		row_idx = i + 3
		d = frappe._dict(zip(columns, row))
		d["doctype"] = "BRS Entries"

		try:
			check_record(d)
			ret.append(import_doc(d, "BRS Entries", 1, row_idx, submit=True))
		except Exception, e:
			error = True
			ret.append('Error for row (#%d) %s : %s' % (row_idx,
				len(row)>1 and row[1] or "", cstr(e)))
			frappe.errprint(frappe.get_traceback())
Example #23
0
def get_events(start, end, filters=None):
	from frappe.desk.reportview import build_match_conditions
	if not frappe.has_permission("Task"):
		frappe.msgprint(_("No Permission"), raise_exception=1)

	conditions = build_match_conditions("Task")
	conditions = conditions and (" and " + conditions) or ""

	if filters:
		filters = json.loads(filters)
		for key in filters:
			if filters[key]:
				conditions += " and " + key + ' = "' + filters[key].replace('"', '\"') + '"'

	data = frappe.db.sql("""select name, exp_start_date, exp_end_date,
		subject, status, project from `tabTask`
		where ((ifnull(exp_start_date, '0000-00-00')!= '0000-00-00') \
				and (exp_start_date between %(start)s and %(end)s) \
			or ((ifnull(exp_start_date, '0000-00-00')!= '0000-00-00') \
				and exp_end_date between %(start)s and %(end)s))
		{conditions}""".format(conditions=conditions), {
			"start": start,
			"end": end
		}, as_dict=True, update={"allDay": 0})

	return data
Example #24
0
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 frappe.is_table(doctype):
		check_parent_permission(parent, doctype)

	if not frappe.has_permission(doctype):
		frappe.throw(_("No permission for {0}".format(doctype)), frappe.PermissionError)

	try:
		filters = json.loads(filters)

		if isinstance(filters, (integer_types, float)):
			filters = frappe.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 frappe.db.get_value(doctype, filters, fieldname, as_dict=as_dict, debug=debug)
Example #25
0
	def get_reply(self):
		if self.startswith('where is', 'find item', 'locate'):
			if not frappe.has_permission('Warehouse'):
				raise frappe.PermissionError

			item = '%{0}%'.format(self.strip_words(self.query, 'where is', 'find item', 'locate'))
			items = frappe.db.sql('''select name from `tabItem` where item_code like %(txt)s
				or item_name like %(txt)s or description like %(txt)s''', dict(txt=item))

			if items:
				out = []
				warehouses = frappe.get_all("Warehouse")
				for item in items:
					found = False
					for warehouse in warehouses:
						qty = frappe.db.get_value("Bin", {'item_code': item[0], 'warehouse': warehouse.name}, 'actual_qty')
						if qty:
							out.append(_('{0} units of [{1}](#Form/Item/{1}) found in [{2}](#Form/Warehouse/{2})').format(qty,
								item[0], warehouse.name))
							found = True

					if not found:
						out.append(_('[{0}](#Form/Item/{0}) is out of stock').format(item[0]))

				return "\n\n".join(out)

			else:
				return _("Did not find any item called {0}".format(item))
Example #26
0
def get_event_conditions(doctype, filters=None):
	"""Returns SQL conditions with user permissions and filters for event queries"""
	from frappe.desk.reportview import get_filters_cond
	if not frappe.has_permission(doctype):
		frappe.throw(_("Not Permitted"), frappe.PermissionError)

	return get_filters_cond(doctype, filters, [], with_match_conditions = True)
Example #27
0
def insert_item_price(args):
	"""Insert Item Price if Price List and Price List Rate are specified and currency is the same"""
	if frappe.db.get_value("Price List", args.price_list, "currency") == args.currency \
		and cint(frappe.db.get_single_value("Stock Settings", "auto_insert_price_list_rate_if_missing")):
		if frappe.has_permission("Item Price", "write"):
			price_list_rate = args.rate / args.conversion_factor \
				if args.get("conversion_factor") else args.rate

			item_price = frappe.get_doc({
				"doctype": "Item Price",
				"price_list": args.price_list,
				"item_code": args.item_code,
				"currency": args.currency,
				"price_list_rate": price_list_rate
			})

			name = frappe.db.get_value('Item Price', {'item_code': args.item_code, 'price_list': args.price_list, 'currency': args.currency}, 'name')

			if name:
				item_price = frappe.get_doc('Item Price', name)
				item_price.price_list_rate = price_list_rate
				item_price.save()
				frappe.msgprint(_("Item Price updated for {0} in Price List {1}").format(args.item_code,
					args.price_list))
			else:
				item_price.insert()
				frappe.msgprint(_("Item Price added for {0} in Price List {1}").format(args.item_code,
					args.price_list))
Example #28
0
def create_meetings(data):
	"""
	No Need to send sms,push notification and email , it should be on attendence update on every user.
        Need to check validation/ duplication  etc
	"""
        dts=json.loads(data)
        qry="select user from __Auth where user='******'username'])+"' and password=password('"+cstr(dts['userpass'])+"') "
        valid=frappe.db.sql(qry)
        if not valid:
                return {
                  "status":"401",
                  "message":"User name or Password is incorrect"
                }

	if not frappe.has_permission(doctype="Attendance Record", ptype="create",user=dts['username']):
		        return {
				"status":"403",
				"message":"You have no permission to create Meeting Attendance Record"
		        }
	#return "hello"
        fdate=dts['from_date'].split(" ")
        f_date=fdate[0]
        tdate=dts['to_date'].split(" ")
        t_date=tdate[0]
        res=frappe.db.sql("select name from `tabAttendance Record` where (cell='%s' or church='%s') and from_date like '%s%%' and to_date like '%s%%'"%(dts['cell'],dts['church'],f_date,t_date))
        if res:
            return {
                "status":"401",
                "message":"Attendance Record is already created for same details on same date "
                }
        if dts['from_date'] and dts['to_date']:
            if dts['from_date'] >= dts['to_date']:
                return {
                "status":"402",
                "message":"To Date should be greater than From Date..!"
                }	
        #return "hello"
	print data
        obj=frappe.new_doc("Attendance Record")
        obj.meeting_category=dts['meeting_category']
	if dts['meeting_category']=="Cell Meeting":
		obj.meeting_subject=dts['meeting_sub']
	else:
	        obj.meeting_sub=dts['meeting_sub']
        obj.from_date=f_date
        obj.to_date=t_date
        obj.venue=dts['venue']
        obj.cell=dts['cell']
        obj.senior_cell=dts['senior_cell']
        obj.zone=dts['zone']
        obj.region=dts['region']
        obj.church_group=dts['church_group']
        obj.church=dts['church']
        obj.pcf=dts['pcf']
        obj.insert(ignore_permissions=True)
	print "Successfully created Cell '"+obj.name+"'"
        ret={
                        "message":"Successfully created Cell '"+obj.name+"'"
        }
        return ret
Example #29
0
def create_senior_cells(data):
	"""
	Need to check validation/ duplication  etc

	"""
	dts=json.loads(data)
	qry="select user from __Auth where user='******'username'])+"' and password=password('"+cstr(dts['userpass'])+"') "
	valid=frappe.db.sql(qry)
	if not valid:
		return {
		  "status":"401",
		  "message":"User name or Password is incorrect"
		}
        if not frappe.has_permission(doctype="Senior Cells", ptype="create",user=dts['username']):
                return {
                  "status":"403",
                  "message":"You have no permission to create Senior Cell"
                }
	else:
		obj=frappe.new_doc("Senior Cells")
		obj.senior_cell_name=dts['senior_cell_name']
		obj.senior_cell_code=dts['senior_cell_code']
		obj.meeting_location=dts['meeting_location']
		obj.zone=dts['zone']
		obj.region=dts['region']
		obj.church_group=dts['church_group']
		obj.church=dts['church']
		obj.pcf=dts['pcf']
		obj.contact_phone_no=dts['contact_phone_no']
		obj.contact_email_id=dts['contact_email_id']
		obj.insert(ignore_permissions=True)
		return "Successfully created senior Cell '"+obj.name+"'"
Example #30
0
def update_event(data):
        """
        Need to check validation/ duplication  etc
        """
        dts=json.loads(data)
        qry="select user from __Auth where user='******'username'])+"' and password=password('"+cstr(dts['userpass'])+"') "
        valid=frappe.db.sql(qry)
        if not valid:
                return {
                  "status":"401",
                  "message":"User name or Password is incorrect"
                }
        if not frappe.has_permission(doctype="Event", ptype="create",user=dts['username']):
                return {
                  "status":"403",
                  "message":"You have no permission to create Cell"
                }
        else:
                obj=frappe.get_doc("Event",dts['name'])
                obj.subject=dts['subject']
                obj.type=dts['type']
                obj.starts_on=dts['starts_on']
                obj.ends_on=dts['ends_on']
                obj.address=dts['address']
                obj.description=dts['description']
                obj.save(ignore_permissions=True)
                ret={
                        "message":"Successfully updated Event '"+obj.name+"'"
                }
                return ret
Example #31
0
def make(doctype=None,
         name=None,
         content=None,
         subject=None,
         sent_or_received="Sent",
         sender=None,
         sender_full_name=None,
         recipients=None,
         communication_medium="Email",
         send_email=False,
         print_html=None,
         print_format=None,
         attachments='[]',
         send_me_a_copy=False,
         cc=None,
         bcc=None,
         flags=None,
         read_receipt=None,
         print_letterhead=True,
         email_template=None,
         communication_type=None,
         ignore_permissions=False):
    """Make a new communication.

	:param doctype: Reference DocType.
	:param name: Reference Document name.
	:param content: Communication body.
	:param subject: Communication subject.
	:param sent_or_received: Sent or Received (default **Sent**).
	:param sender: Communcation sender (default current user).
	:param recipients: Communication recipients as list.
	:param communication_medium: Medium of communication (default **Email**).
	:param send_email: Send via email (default **False**).
	:param print_html: HTML Print format to be sent as attachment.
	:param print_format: Print Format name of parent document to be sent as attachment.
	:param attachments: List of attachments as list of files or JSON string.
	:param send_me_a_copy: Send a copy to the sender (default **False**).
	:param email_template: Template which is used to compose mail .
	"""
    is_error_report = (doctype == "User" and name == frappe.session.user
                       and subject == "Error Report")
    send_me_a_copy = cint(send_me_a_copy)

    if not ignore_permissions:
        if doctype and name and not is_error_report and not frappe.has_permission(
                doctype, "email",
                name) and not (flags or {}).get('ignore_doctype_permissions'):
            raise frappe.PermissionError(
                "You are not allowed to send emails related to: {doctype} {name}"
                .format(doctype=doctype, name=name))

    if not sender:
        sender = get_formatted_email(frappe.session.user)

    recipients = list_to_str(recipients) if isinstance(recipients,
                                                       list) else recipients
    cc = list_to_str(cc) if isinstance(cc, list) else cc
    bcc = list_to_str(bcc) if isinstance(bcc, list) else bcc

    comm = frappe.get_doc({
        "doctype": "Communication",
        "subject": subject,
        "content": content,
        "sender": sender,
        "sender_full_name": sender_full_name,
        "recipients": recipients,
        "cc": cc or None,
        "bcc": bcc or None,
        "communication_medium": communication_medium,
        "sent_or_received": sent_or_received,
        "reference_doctype": doctype,
        "reference_name": name,
        "email_template": email_template,
        "message_id": get_message_id().strip(" <>"),
        "read_receipt": read_receipt,
        "has_attachment": 1 if attachments else 0,
        "communication_type": communication_type
    }).insert(ignore_permissions=True)

    comm.save(ignore_permissions=True)

    if isinstance(attachments, str):
        attachments = json.loads(attachments)

    # if not committed, delayed task doesn't find the communication
    if attachments:
        add_attachments(comm.name, attachments)

    if cint(send_email):
        if not comm.get_outgoing_email_account():
            frappe.throw(msg=OUTGOING_EMAIL_ACCOUNT_MISSING,
                         exc=frappe.OutgoingEmailError)

        comm.send_email(print_html=print_html,
                        print_format=print_format,
                        send_me_a_copy=send_me_a_copy,
                        print_letterhead=print_letterhead)

    emails_not_sent_to = comm.exclude_emails_list(
        include_sender=send_me_a_copy)
    return {
        "name": comm.name,
        "emails_not_sent_to": ", ".join(emails_not_sent_to or [])
    }
Example #32
0
	def execute(self, query=None, fields=None, filters=None, or_filters=None,
		docstatus=None, group_by=None, order_by=None, limit_start=False,
		limit_page_length=None, as_list=False, with_childnames=False, debug=False,
		ignore_permissions=False, user=None, with_comment_count=False,
		join='left join', distinct=False, start=None, page_length=None, limit=None,
		ignore_ifnull=False, save_user_settings=False, save_user_settings_fields=False,
		update=None, add_total_row=None, user_settings=None):
		if not ignore_permissions and not frappe.has_permission(self.doctype, "read", user=user):
			frappe.flags.error_message = _('Insufficient Permission for {0}').format(frappe.bold(self.doctype))
			raise frappe.PermissionError(self.doctype)

		# fitlers and fields swappable
		# its hard to remember what comes first
		if (isinstance(fields, dict)
			or (isinstance(fields, list) and fields and isinstance(fields[0], list))):
			# if fields is given as dict/list of list, its probably filters
			filters, fields = fields, filters

		elif fields and isinstance(filters, list) \
			and len(filters) > 1 and isinstance(filters[0], string_types):
			# if `filters` is a list of strings, its probably fields
			filters, fields = fields, filters

		if fields:
			self.fields = fields
		else:
			self.fields =  ["`tab{0}`.`name`".format(self.doctype)]

		if start: limit_start = start
		if page_length: limit_page_length = page_length
		if limit: limit_page_length = limit

		self.filters = filters or []
		self.or_filters = or_filters or []
		self.docstatus = docstatus or []
		self.group_by = group_by
		self.order_by = order_by
		self.limit_start = 0 if (limit_start is False) else cint(limit_start)
		self.limit_page_length = cint(limit_page_length) if limit_page_length else None
		self.with_childnames = with_childnames
		self.debug = debug
		self.join = join
		self.distinct = distinct
		self.as_list = as_list
		self.ignore_ifnull = ignore_ifnull
		self.flags.ignore_permissions = ignore_permissions
		self.user = user or frappe.session.user
		self.update = update
		self.user_settings_fields = copy.deepcopy(self.fields)
		#self.debug = True

		if user_settings:
			self.user_settings = json.loads(user_settings)

		if query:
			result = self.run_custom_query(query)
		else:
			result = self.build_and_run()

		if with_comment_count and not as_list and self.doctype:
			self.add_comment_count(result)

		if save_user_settings:
			self.save_user_settings_fields = save_user_settings_fields
			self.update_user_settings()

		return result
Example #33
0
def run(report_name, filters=()):
    report = get_report_doc(report_name)

    if filters and isinstance(filters, basestring):
        filters = json.loads(filters)

    if not frappe.has_permission(report.ref_doctype, "report"):
        frappe.msgprint(
            _("Must have report permission to access this report."),
            raise_exception=True)

    columns, results = [], []
    if report.report_type == "Query Report":
        if not report.query:
            frappe.msgprint(_("Must specify a Query to run"),
                            raise_exception=True)

        if not report.query.lower().startswith("select"):
            frappe.msgprint(_("Query must be a SELECT"), raise_exception=True)

        result = [list(t) for t in frappe.db.sql(report.query, filters)]
        columns = [c[0] for c in frappe.db.get_description()]
    else:
        module = report.module or frappe.db.get_value(
            "DocType", report.ref_doctype, "module")
        if report.is_standard == "Yes":
            method_name = get_report_module_dotted_path(
                module, report.name) + ".execute"
            columns, result = frappe.get_attr(method_name)(
                frappe._dict(filters))

    if report.apply_user_permissions and result:
        result = get_filtered_data(report.ref_doctype, columns, result)

    if cint(report.add_total_row) and result:
        result = add_total_row(result, columns)

    #hotfix for data in report
    #find column first, if columns starts with:
    # Status, Source
    #then, the value need to be translated
    column_index = []
    i = 0
    for column_n in columns:
        if isinstance(column_n, dict) == False and isinstance(column_n,
                                                              tuple) == False:
            if column_n.find('Status') == 0 or column_n.find(
                    _("Status")) == 0 or column_n.find("status") == 0:
                column_index.append(i)
            if column_n.find('Source') == 0 or column_n.find(
                    _("Source")) == 0 or column_n.find("source") == 0:
                column_index.append(i)
            if column_n.find('Gender') == 0 or column_n.find(
                    _("Gender")) == 0 or column_n.find("gender") == 0:
                column_index.append(i)

        i = i + 1

    #translate value
    for index in column_index:
        for result_row in result:
            if isinstance(result_row, tuple) == False and isinstance(
                    column_n, tuple) == False:
                result_row[index] = _(result_row[index])

    return {"result": result, "columns": columns}
Example #34
0
def make(doctype=None,
         name=None,
         content=None,
         subject=None,
         sent_or_received="Sent",
         sender=None,
         recipients=None,
         communication_medium="Email",
         send_email=False,
         print_html=None,
         print_format=None,
         attachments='[]',
         ignore_doctype_permissions=False,
         send_me_a_copy=False,
         cc=None):
    """Make a new communication.

	:param doctype: Reference DocType.
	:param name: Reference Document name.
	:param content: Communication body.
	:param subject: Communication subject.
	:param sent_or_received: Sent or Received (default **Sent**).
	:param sender: Communcation sender (default current user).
	:param recipients: Communication recipients as list.
	:param communication_medium: Medium of communication (default **Email**).
	:param send_mail: Send via email (default **False**).
	:param print_html: HTML Print format to be sent as attachment.
	:param print_format: Print Format name of parent document to be sent as attachment.
	:param attachments: List of attachments as list of files or JSON string.
	:param send_me_a_copy: Send a copy to the sender (default **False**).
	"""

    is_error_report = (doctype == "User" and name == frappe.session.user
                       and subject == "Error Report")

    if doctype and name and not is_error_report and not frappe.has_permission(
            doctype, "email", name) and not ignore_doctype_permissions:
        raise frappe.PermissionError(
            "You are not allowed to send emails related to: {doctype} {name}".
            format(doctype=doctype, name=name))

    if not sender:
        sender = get_formatted_email(frappe.session.user)

    comm = frappe.get_doc({
        "doctype": "Communication",
        "subject": subject,
        "content": content,
        "sender": sender,
        "recipients": recipients,
        "cc": cc or None,
        "communication_medium": communication_medium,
        "sent_or_received": sent_or_received,
        "reference_doctype": doctype,
        "reference_name": name
    })
    comm.insert(ignore_permissions=True)

    # needed for communication.notify which uses celery delay
    # if not committed, delayed task doesn't find the communication
    frappe.db.commit()

    if send_email:
        comm.send_me_a_copy = send_me_a_copy
        comm.send(print_html,
                  print_format,
                  attachments,
                  send_me_a_copy=send_me_a_copy)

    return {
        "name":
        comm.name,
        "emails_not_sent_to":
        ", ".join(comm.emails_not_sent_to)
        if hasattr(comm, "emails_not_sent_to") else None
    }
Example #35
0
def has_permission(doc, user):
	return frappe.has_permission(doc.doc_type, "read", doc.doc_name, user=user)
def has_permission(doc, ptype, user):
    if ptype == "read" and doc.reference_doctype and doc.reference_name:
        if frappe.has_permission(doc.reference_doctype,
                                 ptype="read",
                                 doc=doc.reference_name):
            return True
Example #37
0
def _get_party_details(party=None,
                       account=None,
                       party_type="Customer",
                       company=None,
                       posting_date=None,
                       bill_date=None,
                       price_list=None,
                       currency=None,
                       doctype=None,
                       ignore_permissions=False,
                       fetch_payment_terms_template=True,
                       party_address=None,
                       company_address=None,
                       shipping_address=None,
                       pos_profile=None):

    party_details = frappe._dict(
        set_account_and_due_date(party, account, party_type, company,
                                 posting_date, bill_date, doctype))
    party = party_details[party_type.lower()]

    if not ignore_permissions and not frappe.has_permission(
            party_type, "read", party):
        frappe.throw(
            _("Not permitted for {0}").format(party), frappe.PermissionError)

    party = frappe.get_doc(party_type, party)
    currency = party.default_currency if party.get(
        "default_currency") else get_company_currency(company)

    party_address, shipping_address = set_address_details(
        party_details, party, party_type, doctype, company, party_address,
        company_address, shipping_address)
    set_contact_details(party_details, party, party_type)
    set_other_values(party_details, party, party_type)
    set_price_list(party_details, party, party_type, price_list, pos_profile)

    party_details["tax_category"] = get_address_tax_category(
        party.get("tax_category"), party_address,
        shipping_address if party_type != "Supplier" else party_address)

    if not party_details.get("taxes_and_charges"):
        party_details["taxes_and_charges"] = set_taxes(
            party.name,
            party_type,
            posting_date,
            company,
            customer_group=party_details.customer_group,
            supplier_group=party_details.supplier_group,
            tax_category=party_details.tax_category,
            billing_address=party_address,
            shipping_address=shipping_address)

    if fetch_payment_terms_template:
        party_details["payment_terms_template"] = get_pyt_term_template(
            party.name, party_type, company)

    if not party_details.get("currency"):
        party_details["currency"] = currency

    # sales team
    if party_type == "Customer":
        party_details["sales_team"] = [{
            "sales_person":
            d.sales_person,
            "allocated_percentage":
            d.allocated_percentage or None
        } for d in party.get("sales_team")]

    # supplier tax withholding category
    if party_type == "Supplier" and party:
        party_details["supplier_tds"] = frappe.get_value(
            party_type, party.name, "tax_withholding_category")

    return party_details
Example #38
0
def check_share_permission(doctype, name):
    """Check if the user can share with other users"""
    if not frappe.has_permission(doctype, ptype="share", doc=name):
        frappe.throw(
            _("No permission to {0} {1} {2}".format("share", doctype, name)),
            frappe.PermissionError)
Example #39
0
def validate_print_permission(doc):
    for ptype in ("read", "print"):
        if not frappe.has_permission(doc.doctype, ptype, doc):
            raise frappe.PermissionError(_("No {0} permission").format(ptype))
Example #40
0
def get_tagged_docs(doctype, tag):
    frappe.has_permission(doctype, throw=True)

    return frappe.db.sql("""SELECT name
		FROM `tab{0}`
		WHERE _user_tags LIKE '%{1}%'""".format(doctype, tag))
Example #41
0
 def test_allowed_public(self):
     frappe.set_user(self.test_user)
     doc = frappe.get_doc(
         "Event", frappe.db.get_value("Event",
                                      {"subject": "_Test Event 1"}))
     self.assertTrue(frappe.has_permission("Event", doc=doc))
Example #42
0
def get_single_value(doctype, field):
	if not frappe.has_permission(doctype):
		frappe.throw(_("No permission for {0}").format(doctype), frappe.PermissionError)
	value = frappe.db.get_single_value(doctype, field)
	return value
Example #43
0
def get_open_count(doctype, name, items=[]):
    '''Get open count for given transactions and filters

	:param doctype: Reference DocType
	:param name: Reference Name
	:param transactions: List of transactions (json/dict)
	:param filters: optional filters (json/list)'''

    if frappe.flags.in_migrate or frappe.flags.in_install:
        return {"count": []}

    frappe.has_permission(doc=frappe.get_doc(doctype, name), throw=True)

    meta = frappe.get_meta(doctype)
    links = meta.get_dashboard_data()

    # compile all items in a list
    if not items:
        for group in links.transactions:
            items.extend(group.get("items"))

    if not isinstance(items, list):
        items = json.loads(items)

    out = []
    for d in items:
        if d in links.get("internal_links", {}):
            # internal link
            continue

        filters = get_filters_for(d)
        fieldname = links.get("non_standard_fieldnames",
                              {}).get(d, links.fieldname)
        data = {"name": d}
        if filters:
            # get the fieldname for the current document
            # we only need open documents related to the current document
            filters[fieldname] = name
            total = len(
                frappe.get_all(d,
                               fields="name",
                               filters=filters,
                               limit=100,
                               distinct=True,
                               ignore_ifnull=True))
            data["open_count"] = total

        total = len(
            frappe.get_all(d,
                           fields="name",
                           filters={fieldname: name},
                           limit=100,
                           distinct=True,
                           ignore_ifnull=True))
        data["count"] = total
        out.append(data)

    out = {
        "count": out,
    }

    module = frappe.get_meta_module(doctype)
    if hasattr(module, "get_timeline_data"):
        out["timeline_data"] = module.get_timeline_data(doctype, name)

    return out
Example #44
0
			reference_doctype=Service Car Booking.doctype,
			reference_name=Service Car Booking.name,
			as_bulk=True
		)

		Service Car Booking.status = "Invitation Sent"
		Service Car Booking.save()

		frappe.msgprint(_("Invitation Sent"))

	else:
		frappe.msgprint(_("Service Car Booking Status must be 'Planned'"))

@frappe.whitelist()
def get_Service Car Bookings(start, end):
	if not frappe.has_permission("Service Car Booking", "read"):
		raise frappe.PermissionError

	return frappe.db.sql("""select
		timestamp(`date`, from_time) as start,
		timestamp(`date`, to_time) as end,
		name,
		title,
		status,
		0 as all_day
	from `tabService Car Booking`
	where `date` between %(start)s and %(end)s""", {
		"start": start,
		"end": end
	}, as_dict=True)
Example #45
0
def has_permission(doc):
    return frappe.has_permission(doc.doc_type, "read", doc.doc_name)
Example #46
0
	def test_allowed_private_if_in_event_user(self):
		frappe.set_user("*****@*****.**")
		doc = frappe.doc("Event", frappe.db.get_value("Event", {"subject":"_Test Event 3"}))
		self.assertTrue(frappe.has_permission("Event", refdoc=doc))
Example #47
0
def upload():
    if not frappe.has_permission("Shift Schedule", "create"):
        raise frappe.PermissionError

    print("in upload\n\n")
    from frappe.utils.csvutils import read_csv_content_from_uploaded_file
    from frappe.modules import scrub

    rows = read_csv_content_from_uploaded_file()
    rows = filter(lambda x: x and any(x), rows)
    if not rows:
        msg = [_("Please select a csv file")]
        return {"messages": msg, "error": msg}

    columns = []
    # columns = [scrub(f) for f in rows[1]]
    columns.append("name")
    # columns[1] = "date"
    ret = []
    error = False

    from frappe.utils.csvutils import check_record, import_doc

    for i, row in enumerate(rows[4:]):
        print("in for loop\n\n")
        print("row[1]", row[1])
        if not row: continue
        row_idx = i + 3
        d = frappe._dict(zip(columns, row))
        d["doctype"] = "Shift Schedule"
        d["employee"] = row[1]
        d["store"] = row[3]
        # d["attendance_date"] = rows[3][4]

        print("row\n")
        print(row)
        new_date_list = []
        new_shift_time_list = []
        print("new logic\n")
        for i in rows[3]:
            new_date_list.append(i)
        new_date_list = new_date_list[4:]

        new_shift_time_list = row[4:]
        print("\n new new_date_list", new_date_list)
        print("\n new new_shift_time_list", new_shift_time_list)
        print(len(new_shift_time_list), "new_shift_time_list\n")
        # print(row[1])
        # length_of_dates=len(new_shift_time_list)
        length_of_dates = 8

        for i in range(length_of_dates - 1):
            print("\n", i)
            print(new_shift_time_list[i])
            print(new_date_list[i])
            d["attendance_date"] = new_date_list[i]
            d["shift_time"] = new_shift_time_list[i]

            import datetime
            # new_date = datetime.datetime.strptime(row[11],'%d-%b-%y').strftime('%d-%m-%Y')
            # d["date"] = new_date

            if d.name:
                d["docstatus"] = frappe.db.get_value("Shift Schedule", d.name,
                                                     "docstatus")

            try:
                check_record(d)
                ret.append(
                    import_doc(d, "Shift Schedule", 1, row_idx, submit=True))
            except Exception, e:
                error = True
                ret.append('Error for row (#%d) %s : %s' %
                           (row_idx, len(row) > 1 and row[1] or "", cstr(e)))
                frappe.errprint(frappe.get_traceback())
Example #48
0
 def append_table(self, table_name):
     self.tables.append(table_name)
     doctype = table_name[4:-1]
     if (not self.flags.ignore_permissions) and (
             not frappe.has_permission(doctype)):
         raise frappe.PermissionError, doctype
Example #49
0
def get_mapped_doclist(from_doctype, from_docname, table_maps, target_doclist=None, 
		postprocess=None, ignore_permissions=False):
	if target_doclist is None:
		target_doclist = []
		
	if isinstance(target_doclist, basestring):
		target_doclist = json.loads(target_doclist)
	
	source = frappe.bean(from_doctype, from_docname)

	if not ignore_permissions and not frappe.has_permission(from_doctype, "read", source.doc):
		frappe.msgprint("No Permission", raise_exception=frappe.PermissionError)

	source_meta = frappe.get_doctype(from_doctype)
	target_meta = frappe.get_doctype(table_maps[from_doctype]["doctype"])
	
	# main
	if target_doclist:
		if isinstance(target_doclist[0], dict):
			target_doc = frappe.doc(fielddata=target_doclist[0])
		else:
			target_doc = target_doclist[0]
	else:
		target_doc = frappe.new_doc(table_maps[from_doctype]["doctype"])
	
	map_doc(source.doc, target_doc, table_maps[source.doc.doctype], source_meta, target_meta)
	if target_doclist:
		target_doclist[0] = target_doc
	else:
		target_doclist = [target_doc]
	
	target_doclist = frappe.doclist(target_doclist)
	
	row_exists_for_parentfield = {}
	
	# children
	for source_d in source.doclist[1:]:
		table_map = table_maps.get(source_d.doctype)
		if table_map:
			if "condition" in table_map:
				if not table_map["condition"](source_d):
					continue
			target_doctype = table_map["doctype"]
			parentfield = target_meta.get({
					"parent": target_doc.doctype, 
					"doctype": "DocField",
					"fieldtype": "Table", 
					"options": target_doctype
				})[0].fieldname
			
			# does row exist for a parentfield?
			if parentfield not in row_exists_for_parentfield:
				row_exists_for_parentfield[parentfield] = True if \
					frappe.doclist(target_doclist).get({"parentfield": parentfield}) else False
			
			if table_map.get("add_if_empty") and row_exists_for_parentfield.get(parentfield):
				continue
		
			target_d = frappe.new_doc(target_doctype, target_doc, parentfield)
			map_doc(source_d, target_d, table_map, source_meta, target_meta, source.doclist[0])
			target_d.idx = None
			target_doclist.append(target_d)

	target_doclist = frappe.doclist(target_doclist)
	
	if postprocess:
		new_target_doclist = postprocess(source, target_doclist)
		if new_target_doclist:
			target_doclist = new_target_doclist
	
	return target_doclist
Example #50
0
    def execute(self,
                fields=None,
                filters=None,
                or_filters=None,
                docstatus=None,
                group_by=None,
                order_by=None,
                limit_start=False,
                limit_page_length=None,
                as_list=False,
                with_childnames=False,
                debug=False,
                ignore_permissions=False,
                user=None,
                with_comment_count=False,
                join='left join',
                distinct=False,
                start=None,
                page_length=None,
                limit=None,
                ignore_ifnull=False,
                save_user_settings=False,
                save_user_settings_fields=False,
                update=None,
                add_total_row=None,
                user_settings=None,
                reference_doctype=None,
                return_query=False,
                strict=True,
                pluck=None,
                ignore_ddl=False):
        if not ignore_permissions and \
         not frappe.has_permission(self.doctype, "select", user=user) and \
         not frappe.has_permission(self.doctype, "read", user=user):

            frappe.flags.error_message = _(
                'Insufficient Permission for {0}').format(
                    frappe.bold(self.doctype))
            raise frappe.PermissionError(self.doctype)

        # filters and fields swappable
        # its hard to remember what comes first
        if (isinstance(fields, dict) or (isinstance(fields, list) and fields
                                         and isinstance(fields[0], list))):
            # if fields is given as dict/list of list, its probably filters
            filters, fields = fields, filters

        elif fields and isinstance(filters, list) \
         and len(filters) > 1 and isinstance(filters[0], string_types):
            # if `filters` is a list of strings, its probably fields
            filters, fields = fields, filters

        if fields:
            self.fields = fields
        else:
            if pluck:
                self.fields = ["`tab{0}`.`{1}`".format(self.doctype, pluck)]
            else:
                self.fields = ["`tab{0}`.`name`".format(self.doctype)]

        if start: limit_start = start
        if page_length: limit_page_length = page_length
        if limit: limit_page_length = limit

        self.filters = filters or []
        self.or_filters = or_filters or []
        self.docstatus = docstatus or []
        self.group_by = group_by
        self.order_by = order_by
        self.limit_start = 0 if (limit_start is False) else cint(limit_start)
        self.limit_page_length = cint(
            limit_page_length) if limit_page_length else None
        self.with_childnames = with_childnames
        self.debug = debug
        self.join = join
        self.distinct = distinct
        self.as_list = as_list
        self.ignore_ifnull = ignore_ifnull
        self.flags.ignore_permissions = ignore_permissions
        self.user = user or frappe.session.user
        self.update = update
        self.user_settings_fields = copy.deepcopy(self.fields)
        self.return_query = return_query
        self.strict = strict
        self.ignore_ddl = ignore_ddl

        # for contextual user permission check
        # to determine which user permission is applicable on link field of specific doctype
        self.reference_doctype = reference_doctype or self.doctype

        if user_settings:
            self.user_settings = json.loads(user_settings)

        self.columns = self.get_table_columns()

        # no table & ignore_ddl, return
        if not self.columns: return []

        result = self.build_and_run()
        if return_query:
            return result

        if with_comment_count and not as_list and self.doctype:
            self.add_comment_count(result)

        if save_user_settings:
            self.save_user_settings_fields = save_user_settings_fields
            self.update_user_settings()

        if pluck:
            return [d[pluck] for d in result]

        return result
Example #51
0
def sync(site_id=None):
    """
    Pulls the latest orders from eBay. Creates Sales Invoices for sold items.
    By default (site_id = None or -1), checks orders from all eBay sites.
    If site_id is specified, only orders from that site are used.

    We loop over each order in turn. First we extract customer
    details from eBay. If the customer does not exist, we then create
    a Customer. We update the Customer if it already exists.
    We create an Address for this customer, if one does not already exist,
    and link it to the Customer.

    Then we extract the order information from eBay, and create an
    eBay Order if it does not already exist.

    Finally we create or update a Sales Invoice based on the eBay
    transaction. This is only created if the order is completed (i.e. paid).

    If we raise an ErpnextEbaySyncError during processing of an
    order, then we rollback the database and continue to the next
    order. If a more serious exception occurs, then we rollback the
    database but we only continue if continue_on_error is true.
    """

    if site_id is None or int(site_id) == -1:
        ebay_site_id = None
    else:
        site_id = int(site_id)
        ebay_site_id = EBAY_TRANSACTION_SITE_IDS[site_id]

    # This is a whitelisted function; check permissions.
    if not frappe.has_permission('eBay Manager'):
        frappe.throw('You do not have permission to access the eBay Manager',
                     frappe.PermissionError)
    frappe.msgprint('Syncing eBay orders...')
    # Load orders from Ebay
    orders, num_days = get_orders(order_status='Completed')

    # Create a synchronization log
    log_dict = {"doctype": "eBay sync log",
                "ebay_sync_datetime": datetime.datetime.now(),
                "ebay_sync_days": num_days,
                "ebay_log_table": []}
    changes = []
    msgprint_log = []

    try:
        for order in orders:
            try:
                # Identify the eBay site on which the item was listed.
                try:
                    site_id_order = order[
                        'TransactionArray']['Transaction'][0]['Item']['Site']
                except (KeyError, TypeError) as e:
                    msgprint_log.append(
                        'WARNING: unable to identify site ID from:'
                        + '\n{}\n{}'.format(
                            order['TransactionArray'], str(e)))

                # Create/update Customer
                cust_details, address_details = extract_customer(order)
                create_customer(cust_details, address_details, changes)

                # Create/update eBay Order
                order_details = extract_order_info(order, changes)
                create_ebay_order(order_details, changes, order)

                # Create/update Sales Invoice
                create_sales_invoice(order_details, order, ebay_site_id,
                                     site_id_order, msgprint_log, changes)
            except ErpnextEbaySyncError as e:
                # Continue to next order
                frappe.db.rollback()
                msgprint_log.append(str(e))
                print(e)
            except Exception as e:
                # Continue to next order
                frappe.db.rollback()
                err_msg = traceback.format_exc()
                print(err_msg)
                if not continue_on_error:
                    msgprint('ORDER FAILED')
                    raise
                else:
                    msgprint_log.append('ORDER FAILED:\n{}'.format(err_msg))

    finally:
        # Save the log, regardless of how far we got
        frappe.db.commit()
        for change in changes:
            log_dict['ebay_log_table'].append(change)
        log = frappe.get_doc(log_dict)
        if use_sync_log:
            log.insert(ignore_permissions=True)
        else:
            del log
        frappe.db.commit()
    msgprint_log.append('Finished.')
    msgprint(msgprint_log)
Example #52
0
def has_permission(doctype, docname, perm_type="read"):
	# perm_type can be one of read, write, create, submit, cancel, report
	return {"has_permission": frappe.has_permission(doctype, perm_type.lower(), docname)}
Example #53
0
def add(args=None):
    """add in someone's to do list
		args = {
			"assign_to": [],
			"doctype": ,
			"name": ,
			"description": ,
			"assignment_rule":
		}

	"""
    if not args:
        args = frappe.local.form_dict

    users_with_duplicate_todo = []
    shared_with_users = []

    for assign_to in frappe.parse_json(args.get("assign_to")):
        filters = {
            "reference_type": args['doctype'],
            "reference_name": args['name'],
            "status": "Open",
            "owner": assign_to
        }

        if frappe.get_all("ToDo", filters=filters):
            users_with_duplicate_todo.append(assign_to)
        else:
            from frappe.utils import nowdate

            if not args.get('description'):
                args['description'] = _('Assignment for {0} {1}').format(
                    args['doctype'], args['name'])

            d = frappe.get_doc({
                "doctype":
                "ToDo",
                "owner":
                assign_to,
                "reference_type":
                args['doctype'],
                "reference_name":
                args['name'],
                "description":
                args.get('description'),
                "priority":
                args.get("priority", "Medium"),
                "status":
                "Open",
                "date":
                args.get('date', nowdate()),
                "assigned_by":
                args.get('assigned_by', frappe.session.user),
                'assignment_rule':
                args.get('assignment_rule')
            }).insert(ignore_permissions=True)

            # set assigned_to if field exists
            if frappe.get_meta(args['doctype']).get_field("assigned_to"):
                frappe.db.set_value(args['doctype'], args['name'],
                                    "assigned_to", assign_to)

            doc = frappe.get_doc(args['doctype'], args['name'])

            # if assignee does not have permissions, share
            if not frappe.has_permission(doc=doc, user=assign_to):
                frappe.share.add(doc.doctype, doc.name, assign_to)
                shared_with_users.append(assign_to)

            # make this document followed by assigned user
            follow_document(args['doctype'], args['name'], assign_to)

            # notify
            notify_assignment(d.assigned_by,
                              d.owner,
                              d.reference_type,
                              d.reference_name,
                              action='ASSIGN',
                              description=args.get("description"))

    if shared_with_users:
        user_list = format_message_for_assign_to(shared_with_users)
        frappe.msgprint(
            _("Shared with the following Users with Read access:{0}").format(
                user_list, alert=True))

    if users_with_duplicate_todo:
        user_list = format_message_for_assign_to(users_with_duplicate_todo)
        frappe.msgprint(
            _("Already in the following Users ToDo list:{0}").format(
                user_list, alert=True))

    return get(args)
Example #54
0
def make_depreciation_entry(asset_name, date=None):
    frappe.has_permission('Journal Entry', throw=True)

    if not date:
        date = today()

    asset = frappe.get_doc("Asset", asset_name)
    fixed_asset_account, accumulated_depreciation_account, depreciation_expense_account = \
     get_depreciation_accounts(asset)

    depreciation_cost_center, depreciation_series = frappe.get_cached_value(
        'Company', asset.company,
        ["depreciation_cost_center", "series_for_depreciation_entry"])

    depreciation_cost_center = asset.cost_center or depreciation_cost_center

    accounting_dimensions = get_checks_for_pl_and_bs_accounts()

    for d in asset.get("schedules"):
        if not d.journal_entry and getdate(d.schedule_date) <= getdate(date):
            je = frappe.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)

            credit_entry = {
                "account": accumulated_depreciation_account,
                "credit_in_account_currency": d.depreciation_amount,
                "reference_type": "Asset",
                "reference_name": asset.name
            }

            debit_entry = {
                "account": depreciation_expense_account,
                "debit_in_account_currency": d.depreciation_amount,
                "reference_type": "Asset",
                "reference_name": asset.name,
                "cost_center": depreciation_cost_center
            }

            for dimension in accounting_dimensions:
                if (asset.get(dimension['fieldname'])
                        or dimension.get('mandatory_for_bs')):
                    credit_entry.update({
                        dimension['fieldname']:
                        asset.get(dimension['fieldname'])
                        or dimension.get('default_dimension')
                    })

                if (asset.get(dimension['fieldname'])
                        or dimension.get('mandatory_for_pl')):
                    debit_entry.update({
                        dimension['fieldname']:
                        asset.get(dimension['fieldname'])
                        or dimension.get('default_dimension')
                    })

            je.append("accounts", credit_entry)

            je.append("accounts", debit_entry)

            je.flags.ignore_permissions = True
            je.save()
            if not je.meta.get_workflow():
                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
Example #55
0
def make(doctype=None,
         name=None,
         content=None,
         subject=None,
         sent_or_received="Sent",
         sender=None,
         sender_full_name=None,
         recipients=None,
         communication_medium="Email",
         send_email=False,
         print_html=None,
         print_format=None,
         attachments='[]',
         send_me_a_copy=False,
         cc=None,
         bcc=None,
         flags=None,
         read_receipt=None):
    """Make a new communication.

	:param doctype: Reference DocType.
	:param name: Reference Document name.
	:param content: Communication body.
	:param subject: Communication subject.
	:param sent_or_received: Sent or Received (default **Sent**).
	:param sender: Communcation sender (default current user).
	:param recipients: Communication recipients as list.
	:param communication_medium: Medium of communication (default **Email**).
	:param send_mail: Send via email (default **False**).
	:param print_html: HTML Print format to be sent as attachment.
	:param print_format: Print Format name of parent document to be sent as attachment.
	:param attachments: List of attachments as list of files or JSON string.
	:param send_me_a_copy: Send a copy to the sender (default **False**).
	"""

    is_error_report = (doctype == "User" and name == frappe.session.user
                       and subject == "Error Report")
    send_me_a_copy = cint(send_me_a_copy)

    if doctype and name and not is_error_report and not frappe.has_permission(
            doctype, "email",
            name) and not (flags or {}).get('ignore_doctype_permissions'):
        raise frappe.PermissionError(
            "You are not allowed to send emails related to: {doctype} {name}".
            format(doctype=doctype, name=name))

    if not sender:
        sender = get_formatted_email(frappe.session.user)

    comm = frappe.get_doc({
        "doctype": "Communication",
        "subject": subject,
        "content": content,
        "sender": sender,
        "sender_full_name": sender_full_name,
        "recipients": recipients,
        "cc": cc or None,
        "bcc": bcc or None,
        "communication_medium": communication_medium,
        "sent_or_received": sent_or_received,
        "reference_doctype": doctype,
        "reference_name": name,
        "message_id": get_message_id().strip(" <>"),
        "read_receipt": read_receipt,
        "has_attachment": 1 if attachments else 0
    })
    comm.insert(ignore_permissions=True)

    if not doctype:
        # if no reference given, then send it against the communication
        comm.db_set(
            dict(reference_doctype='Communication', reference_name=comm.name))

    if isinstance(attachments, string_types):
        attachments = json.loads(attachments)

    # if not committed, delayed task doesn't find the communication
    if attachments:
        add_attachments(comm.name, attachments)

    frappe.db.commit()

    if cint(send_email):
        comm.send(print_html,
                  print_format,
                  attachments,
                  send_me_a_copy=send_me_a_copy)

    return {
        "name":
        comm.name,
        "emails_not_sent_to":
        ", ".join(comm.emails_not_sent_to)
        if hasattr(comm, "emails_not_sent_to") else None
    }
Example #56
0
def add(args=None):
    """add in someone's to do list
		args = {
			"assign_to": ,
			"doctype": ,
			"name": ,
			"description":
		}

	"""
    if not args:
        args = frappe.local.form_dict

    if frappe.db.sql(
            """select owner from `tabToDo`
		where reference_type=%(doctype)s and reference_name=%(name)s and status in ("Open", "Overdue")
		and owner=%(assign_to)s""", args):
        frappe.throw(_("Already in user's To Do list"), DuplicateToDoError)

    else:
        from frappe.utils import nowdate

        # if args.get("re_assign"):
        # 	remove_from_todo_if_already_assigned(args['doctype'], args['name'])

        d = frappe.get_doc({
            "doctype":
            "ToDo",
            "owner":
            args['assign_to'],
            "reference_type":
            args['doctype'],
            "reference_name":
            args['name'],
            "description":
            args.get('description'),
            "priority":
            args.get("priority", "Medium"),
            "status":
            "Open",
            "date":
            args.get('date', nowdate()),
            "assigned_by":
            args.get('assigned_by', frappe.session.user),
        }).insert(ignore_permissions=True)

        # set assigned_to if field exists
        if frappe.get_meta(args['doctype']).get_field("assigned_to"):
            frappe.db.set_value(args['doctype'], args['name'], "assigned_to",
                                args['assign_to'])

        doc = frappe.get_doc(args['doctype'], args['name'])

        # if assignee does not have permissions, share
        if not frappe.has_permission(doc=doc, user=args['assign_to']):
            frappe.share.add(doc.doctype, doc.name, args['assign_to'])
            frappe.msgprint(_('Shared with user {0} with read access').format(
                args['assign_to']),
                            alert=True)

    # notify
    notify_assignment(d.assigned_by, d.owner, d.reference_type, d.reference_name, action='ASSIGN',\
       description=args.get("description"), notify=args.get('notify'))

    return get(args)
Example #57
0
def generate_single_invoice(docname):
    doc = frappe.get_doc("Sales Invoice", docname)
    frappe.has_permission("Sales Invoice", doc=doc, throw=True)

    e_invoice = prepare_and_attach_invoice(doc, True)
    return e_invoice.file_url
Example #58
0
	def append_table(self, table_name):
		self.tables.append(table_name)
		doctype = table_name[4:-1]
		if (not self.flags.ignore_permissions) and (not frappe.has_permission(doctype)):
			frappe.flags.error_message = _('Insufficient Permission for {0}').format(frappe.bold(doctype))
			raise frappe.PermissionError(doctype)
Example #59
0
 def test_not_allowed_private(self):
     frappe.set_user(self.test_user)
     doc = frappe.get_doc(
         "Event", frappe.db.get_value("Event",
                                      {"subject": "_Test Event 2"}))
     self.assertFalse(frappe.has_permission("Event", doc=doc))
Example #60
0
def get_item_attribute(parent, attribute_value=''):
	if not frappe.has_permission("Item"):
		frappe.msgprint(_("No Permission"), raise_exception=1)

	return frappe.get_all("Item Attribute Value", fields = ["attribute_value"],
		filters = {'parent': parent, 'attribute_value': ("like", "%%%s%%" % attribute_value)})