Example #1
0
def compare_expense_with_budget(args,
                                budget_amount,
                                action_for,
                                action,
                                budget_against,
                                amount=0):
    actual_expense = amount or get_actual_expense(args)
    if actual_expense > budget_amount:
        diff = actual_expense - budget_amount
        currency = dataent.get_cached_value('Company', args.company,
                                            'default_currency')

        msg = _(
            "{0} Budget for Account {1} against {2} {3} is {4}. It will exceed by {5}"
        ).format(_(action_for), dataent.bold(args.account),
                 args.budget_against_field, dataent.bold(budget_against),
                 dataent.bold(fmt_money(budget_amount, currency=currency)),
                 dataent.bold(fmt_money(diff, currency=currency)))

        if (dataent.flags.exception_approver_role
                and dataent.flags.exception_approver_role in dataent.get_roles(
                    dataent.session.user)):
            action = "Warn"

        if action == "Stop":
            dataent.throw(msg, BudgetError)
        else:
            dataent.msgprint(msg, indicator='orange')
Example #2
0
def return_success_page(doc):
    dataent.respond_as_web_page(_("Success"),
                                _("{0}: {1} is set to state {2}".format(
                                    doc.get('doctype'),
                                    dataent.bold(doc.get('name')),
                                    dataent.bold(
                                        get_doc_workflow_state(doc)))),
                                indicator_color='green')
Example #3
0
def return_link_expired_page(doc, doc_workflow_state):
    dataent.respond_as_web_page(
        _("Link Expired"),
        _("Document {0} has been set to state {1} by {2}".format(
            dataent.bold(doc.get('name')), dataent.bold(doc_workflow_state),
            dataent.bold(
                dataent.get_value('User', doc.get("modified_by"),
                                  'full_name')))),
        indicator_color='blue')
    def make_invoices(self):
        names = []
        mandatory_error_msg = _(
            "Row {0}: {1} is required to create the Opening {2} Invoices")
        if not self.company:
            dataent.throw(_("Please select the Company"))

        for row in self.invoices:
            if not row.qty:
                row.qty = 1.0

            # always mandatory fields for the invoices
            if not row.temporary_opening_account:
                row.temporary_opening_account = get_temporary_opening_account(
                    self.company)
            row.party_type = "Customer" if self.invoice_type == "Sales" else "Supplier"

            # Allow to create invoice even if no party present in customer or supplier.
            if not dataent.db.exists(row.party_type, row.party):
                if self.create_missing_party:
                    self.add_party(row.party_type, row.party)
                else:
                    dataent.throw(
                        _("{0} {1} does not exist.").format(
                            dataent.bold(row.party_type),
                            dataent.bold(row.party)))

            if not row.item_name:
                row.item_name = _("Opening Invoice Item")
            if not row.posting_date:
                row.posting_date = nowdate()
            if not row.due_date:
                row.due_date = nowdate()

            for d in ("Party", "Outstanding Amount",
                      "Temporary Opening Account"):
                if not row.get(scrub(d)):
                    dataent.throw(
                        mandatory_error_msg.format(row.idx, _(d),
                                                   self.invoice_type))

            args = self.get_invoice_dict(row=row)
            if not args:
                continue

            doc = dataent.get_doc(args).insert()
            doc.submit()
            names.append(doc.name)

            if len(self.invoices) > 5:
                dataent.publish_realtime(
                    "progress",
                    dict(progress=[row.idx, len(self.invoices)],
                         title=_('Creating {0}').format(doc.doctype)),
                    user=dataent.session.user)

        return names
Example #5
0
    def validate_report_format(self):
        """ check if user has select correct report format """
        valid_report_formats = ["HTML", "XLSX", "CSV"]
        if self.format not in valid_report_formats:
            dataent.throw(
                _("%s is not a valid report format. Report format should \
				one of the following %s" %
                  (dataent.bold(self.format),
                   dataent.bold(", ".join(valid_report_formats)))))
Example #6
0
    def validate_inspection(self):
        '''Checks if quality inspection is set for Items that require inspection.
		On submit, throw an exception'''
        inspection_required_fieldname = None
        if self.doctype in ["Purchase Receipt", "Purchase Invoice"]:
            inspection_required_fieldname = "inspection_required_before_purchase"
        elif self.doctype in ["Delivery Note", "Sales Invoice"]:
            inspection_required_fieldname = "inspection_required_before_delivery"

        if ((not inspection_required_fieldname
             and self.doctype != "Stock Entry") or
            (self.doctype == "Stock Entry" and not self.inspection_required)
                or (self.doctype in ["Sales Invoice", "Purchase Invoice"]
                    and not self.update_stock)):
            return

        for d in self.get('items'):
            qa_required = False
            if (inspection_required_fieldname
                    and not d.quality_inspection and dataent.db.get_value(
                        "Item", d.item_code, inspection_required_fieldname)):
                qa_required = True
            elif self.doctype == "Stock Entry" and not d.quality_inspection and d.t_warehouse:
                qa_required = True
            if self.docstatus == 1 and d.quality_inspection:
                qa_doc = dataent.get_doc("Quality Inspection",
                                         d.quality_inspection)
                if qa_doc.docstatus == 0:
                    link = dataent.utils.get_link_to_form(
                        'Quality Inspection', d.quality_inspection)
                    dataent.throw(
                        _("Quality Inspection: {0} is not submitted for the item: {1} in row {2}"
                          ).format(link, d.item_code, d.idx),
                        QualityInspectionNotSubmittedError)

                qa_failed = any(
                    [r.status == "Rejected" for r in qa_doc.readings])
                if qa_failed:
                    dataent.throw(
                        _("Row {0}: Quality Inspection rejected for item {1}"
                          ).format(d.idx, d.item_code),
                        QualityInspectionRejectedError)
            elif qa_required:
                action = dataent.get_doc(
                    'Stock Settings'
                ).action_if_quality_inspection_is_not_submitted
                if self.docstatus == 1 and action == 'Stop':
                    dataent.throw(
                        _("Quality Inspection required for Item {0} to submit"
                          ).format(dataent.bold(d.item_code)),
                        exc=QualityInspectionRequiredError)
                else:
                    dataent.msgprint(
                        _("Create Quality Inspection for Item {0}").format(
                            dataent.bold(d.item_code)))
Example #7
0
 def limits_crossed_error(self, args, item):
     '''Raise exception for limits crossed'''
     dataent.throw(_(
         'This document is over limit by {0} {1} for item {4}. Are you making another {3} against the same {2}?'
     ).format(
         dataent.bold(_(item["target_ref_field"].title())),
         dataent.bold(item["reduce_by"]),
         dataent.bold(_(args.get('target_dt'))),
         dataent.bold(_(self.doctype)), dataent.bold(item.get('item_code'))
     ) + '<br><br>' + _(
         'To allow over-billing or over-ordering, update "Allowance" in Stock Settings or the Item.'
     ),
                   title=_('Limit Crossed'))
Example #8
0
    def validate_for_subcontracting(self):
        if not self.is_subcontracted and self.sub_contracted_items:
            dataent.throw(_("Please enter 'Is Subcontracted' as Yes or No"))

        if self.is_subcontracted == "Yes":
            if self.doctype in ["Purchase Receipt", "Purchase Invoice"
                                ] and not self.supplier_warehouse:
                dataent.throw(
                    _("Supplier Warehouse mandatory for sub-contracted Purchase Receipt"
                      ))

            for item in self.get("items"):
                if item in self.sub_contracted_items and not item.bom:
                    dataent.throw(
                        _("Please select BOM in BOM field for Item {0}").
                        format(item.item_code))

            if self.doctype == "Purchase Order":
                for supplied_item in self.get("supplied_items"):
                    if not supplied_item.reserve_warehouse:
                        dataent.throw(
                            _("Reserved Warehouse is mandatory for Item {0} in Raw Materials supplied"
                              ).format(dataent.bold(
                                  supplied_item.rm_item_code)))

        else:
            for item in self.get("items"):
                if item.bom:
                    item.bom = None
Example #9
0
	def validate_with_parent_plan(self, staffing_plan_detail):
		if not dataent.get_cached_value('Company',  self.company,  "parent_company"):
			return # No parent, nothing to validate

		# Get staffing plan applicable for the company (Parent Company)
		parent_plan_details = get_active_staffing_plan_details(self.company, staffing_plan_detail.designation, self.from_date, self.to_date)
		if not parent_plan_details:
			return #no staffing plan for any parent Company in hierarchy

		# Fetch parent company which owns the staffing plan. NOTE: Parent could be higher up in the hierarchy
		parent_company = dataent.db.get_value("Staffing Plan", parent_plan_details[0].name, "company")
		# Parent plan available, validate with parent, siblings as well as children of staffing plan Company
		if cint(staffing_plan_detail.vacancies) > cint(parent_plan_details[0].vacancies) or \
			flt(staffing_plan_detail.total_estimated_cost) > flt(parent_plan_details[0].total_estimated_cost):
			dataent.throw(_("You can only plan for upto {0} vacancies and budget {1} \
				for {2} as per staffing plan {3} for parent company {4}."
				.format(cint(parent_plan_details[0].vacancies),
					parent_plan_details[0].total_estimated_cost,
					dataent.bold(staffing_plan_detail.designation),
					parent_plan_details[0].name,
					parent_company)), ParentCompanyError)

		#Get vacanices already planned for all companies down the hierarchy of Parent Company
		lft, rgt = dataent.get_cached_value('Company',  parent_company,  ["lft", "rgt"])
		all_sibling_details = dataent.db.sql("""select sum(spd.vacancies) as vacancies,
			sum(spd.total_estimated_cost) as total_estimated_cost
			from `tabStaffing Plan Detail` spd join `tabStaffing Plan` sp on spd.parent=sp.name
			where spd.designation=%s and sp.docstatus=1
			and sp.to_date >= %s and sp.from_date <=%s
			and sp.company in (select name from tabCompany where lft > %s and rgt < %s)
		""", (staffing_plan_detail.designation, self.from_date, self.to_date, lft, rgt), as_dict = 1)[0]

		if (cint(parent_plan_details[0].vacancies) < \
			(cint(staffing_plan_detail.vacancies) + cint(all_sibling_details.vacancies))) or \
			(flt(parent_plan_details[0].total_estimated_cost) < \
			(flt(staffing_plan_detail.total_estimated_cost) + flt(all_sibling_details.total_estimated_cost))):
			dataent.throw(_("{0} vacancies and {1} budget for {2} already planned for subsidiary companies of {3}. \
				You can only plan for upto {4} vacancies and and budget {5} as per staffing plan {6} for parent company {3}."
				.format(cint(all_sibling_details.vacancies),
					all_sibling_details.total_estimated_cost,
					dataent.bold(staffing_plan_detail.designation),
					parent_company,
					cint(parent_plan_details[0].vacancies),
					parent_plan_details[0].total_estimated_cost,
					parent_plan_details[0].name)))
Example #10
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 dataent.has_permission(doctype)):
         dataent.flags.error_message = _(
             'Insufficient Permission for {0}').format(
                 dataent.bold(doctype))
         raise dataent.PermissionError(doctype)
Example #11
0
	def validate_assessment_criteria(self):
		assessment_criteria_list = dataent.db.sql_list(''' select apc.assessment_criteria
			from `tabAssessment Plan` ap , `tabAssessment Plan Criteria` apc
			where ap.name = apc.parent and ap.course=%s and ap.student_group=%s and ap.assessment_group=%s
			and ap.name != %s and ap.docstatus=1''', (self.course, self.student_group, self.assessment_group, self.name))
		for d in self.assessment_criteria:
			if d.assessment_criteria in assessment_criteria_list:
				dataent.throw(_("You have already assessed for the assessment criteria {}.")
					.format(dataent.bold(d.assessment_criteria)))
Example #12
0
def validate_column_name(n):
    special_characters = re.findall("[\W]", n, re.UNICODE)
    if special_characters:
        special_characters = ", ".join('"{0}"'.format(c)
                                       for c in special_characters)
        dataent.throw(
            _("Fieldname {0} cannot have special characters like {1}").format(
                dataent.bold(cstr(n)), special_characters), InvalidColumnName)
    return n
Example #13
0
def validate_workflow(doc):
	'''Validate Workflow State and Transition for the current user.

	- Check if user is allowed to edit in current state
	- Check if user is allowed to transition to the next state (if changed)
	'''
	workflow = get_workflow(doc.doctype)

	current_state = None
	if getattr(doc, '_doc_before_save', None):
		current_state = doc._doc_before_save.get(workflow.workflow_state_field)
	next_state = doc.get(workflow.workflow_state_field)

	if not next_state:
		next_state = workflow.states[0].state
		doc.set(workflow.workflow_state_field, next_state)

	if not current_state:
		current_state = workflow.states[0].state

	state_row = [d for d in workflow.states if d.state == current_state]
	if not state_row:
		dataent.throw(_('{0} is not a valid Workflow State. Please update your Workflow and try again.'.format(dataent.bold(current_state))))
	state_row = state_row[0]

	# if transitioning, check if user is allowed to transition
	if current_state != next_state:
		bold_current = dataent.bold(current_state)
		bold_next = dataent.bold(next_state)

		if not doc._doc_before_save:
			# transitioning directly to a state other than the first
			# e.g from data import
			dataent.throw(_('Workflow State transition not allowed from {0} to {1}').format(bold_current, bold_next),
				WorkflowPermissionError)

		transitions = get_transitions(doc._doc_before_save)
		transition = [d for d in transitions if d.next_state == next_state]
		if not transition:
			dataent.throw(_('Workflow State transition not allowed from {0} to {1}').format(bold_current, bold_next),
				WorkflowPermissionError)
Example #14
0
def setup_user_email_inbox(email_account, awaiting_password, email_id,
                           enable_outgoing):
    """ setup email inbox for user """
    def add_user_email(user):
        user = dataent.get_doc("User", user)
        row = user.append("user_emails", {})

        row.email_id = email_id
        row.email_account = email_account
        row.awaiting_password = awaiting_password or 0
        row.enable_outgoing = enable_outgoing or 0

        user.save(ignore_permissions=True)

    udpate_user_email_settings = False
    if not all([email_account, email_id]):
        return

    user_names = dataent.db.get_values("User", {"email": email_id},
                                       as_dict=True)
    if not user_names:
        return

    for user in user_names:
        user_name = user.get("name")

        # check if inbox is alreay configured
        user_inbox = dataent.db.get_value("User Email", {
            "email_account": email_account,
            "parent": user_name
        }, ["name"]) or None

        if not user_inbox:
            add_user_email(user_name)
        else:
            # update awaiting password for email account
            udpate_user_email_settings = True

    if udpate_user_email_settings:
        dataent.db.sql(
            """UPDATE `tabUser Email` SET awaiting_password = %(awaiting_password)s,
			enable_outgoing = %(enable_outgoing)s WHERE email_account = %(email_account)s""",
            {
                "email_account": email_account,
                "enable_outgoing": enable_outgoing,
                "awaiting_password": awaiting_password or 0
            })
    else:
        users = " and ".join(
            [dataent.bold(user.get("name")) for user in user_names])
        dataent.msgprint(_("Enabled email inbox for user {0}").format(users))

    ask_pass_update()
Example #15
0
        def get_msg(df):
            if df.fieldtype == "Table":
                return "{}: {}: {}".format(_("Error"),
                                           _("Data missing in table"),
                                           _(df.label))

            elif self.parentfield:
                return "{}: {} {} #{}: {}: {}".format(
                    _("Error"), dataent.bold(_(self.doctype)), _("Row"),
                    self.idx, _("Value missing for"), _(df.label))

            else:
                return _("Error: Value missing for {0}: {1}").format(
                    _(df.parent), _(df.label))
Example #16
0
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)))
Example #17
0
	def validate(self):
		"""Validate Email Address and check POP3/IMAP and SMTP connections is enabled."""
		if self.email_id:
			validate_email_add(self.email_id, True)

		if self.login_id_is_different:
			if not self.login_id:
				dataent.throw(_("Login Id is required"))
		else:
			self.login_id = None

		duplicate_email_account = dataent.get_all("Email Account", filters={
			"email_id": self.email_id,
			"name": ("!=", self.name)
		})
		if duplicate_email_account:
			dataent.throw(_("Email ID must be unique, Email Account already exists \
				for {0}".format(dataent.bold(self.email_id))))

		if dataent.local.flags.in_patch or dataent.local.flags.in_test:
			return

		#if self.enable_incoming and not self.append_to:
		#	dataent.throw(_("Append To is mandatory for incoming mails"))

		if (not self.awaiting_password and not dataent.local.flags.in_install
			and not dataent.local.flags.in_patch):
			if self.password or self.smtp_server in ('127.0.0.1', 'localhost'):
				if self.enable_incoming:
					self.get_incoming_server()
					self.no_failed = 0


				if self.enable_outgoing:
					self.check_smtp()
			else:
				if self.enable_incoming or (self.enable_outgoing and not self.no_smtp_authentication):
					dataent.throw(_("Password is required or select Awaiting Password"))

		if self.notify_if_unreplied:
			if not self.send_notification_to:
				dataent.throw(_("{0} is mandatory").format(self.meta.get_label("send_notification_to")))
			for e in self.get_unreplied_notification_emails():
				validate_email_add(e, True)

		if self.enable_incoming and self.append_to:
			valid_doctypes = [d[0] for d in get_append_to()]
			if self.append_to not in valid_doctypes:
				dataent.throw(_("Append To can be one of {0}").format(comma_or(valid_doctypes)))
Example #18
0
    def set_component_amounts_based_on_payment_days(self):
        joining_date, relieving_date = dataent.get_cached_value(
            "Employee", self.employee, ["date_of_joining", "relieving_date"])

        if not relieving_date:
            relieving_date = getdate(self.end_date)

        if not joining_date:
            dataent.throw(
                _("Please set the Date Of Joining for employee {0}").format(
                    dataent.bold(self.employee_name)))

        for component_type in ("earnings", "deductions"):
            for d in self.get(component_type):
                d.amount = self.get_amount_based_on_payment_days(
                    d, joining_date, relieving_date)[0]
Example #19
0
    def get_taxable_earnings(self, based_on_payment_days=0):
        joining_date, relieving_date = dataent.get_cached_value(
            "Employee", self.employee, ["date_of_joining", "relieving_date"])

        if not relieving_date:
            relieving_date = getdate(self.end_date)

        if not joining_date:
            dataent.throw(
                _("Please set the Date Of Joining for employee {0}").format(
                    dataent.bold(self.employee_name)))

        taxable_earnings = 0
        additional_income = 0
        additional_income_with_full_tax = 0
        flexi_benefits = 0

        for earning in self.earnings:
            if based_on_payment_days:
                amount, additional_amount = self.get_amount_based_on_payment_days(
                    earning, joining_date, relieving_date)
            else:
                amount, additional_amount = earning.amount, earning.additional_amount

            if earning.is_tax_applicable:
                if additional_amount:
                    taxable_earnings += (amount - additional_amount)
                    additional_income += additional_amount
                    if earning.deduct_full_tax_on_selected_payroll_date:
                        additional_income_with_full_tax += additional_amount
                    continue

                if earning.is_flexible_benefit:
                    flexi_benefits += amount
                else:
                    taxable_earnings += amount

        return dataent._dict({
            "taxable_earnings": taxable_earnings,
            "additional_income": additional_income,
            "additional_income_with_full_tax": additional_income_with_full_tax,
            "flexi_benefits": flexi_benefits
        })
Example #20
0
	def validate_with_subsidiary_plans(self, staffing_plan_detail):
		#Valdate this plan with all child company plan
		children_details = dataent.db.sql("""select sum(spd.vacancies) as vacancies,
			sum(spd.total_estimated_cost) as total_estimated_cost
			from `tabStaffing Plan Detail` spd join `tabStaffing Plan` sp on spd.parent=sp.name
			where spd.designation=%s and sp.docstatus=1
			and sp.to_date >= %s and sp.from_date <=%s
			and sp.company in (select name from tabCompany where parent_company = %s)
		""", (staffing_plan_detail.designation, self.from_date, self.to_date, self.company), as_dict = 1)[0]

		if children_details and \
			cint(staffing_plan_detail.vacancies) < cint(children_details.vacancies) or \
			flt(staffing_plan_detail.total_estimated_cost) < flt(children_details.total_estimated_cost):
			dataent.throw(_("Subsidiary companies have already planned for {1} vacancies at a budget of {2}. \
				Staffing Plan for {0} should allocate more vacancies and budget for {3} than planned for its subsidiary companies"
				.format(self.company,
					cint(children_details.vacancies),
					children_details.total_estimated_cost,
					dataent.bold(staffing_plan_detail.designation))), SubsidiaryCompanyError)
Example #21
0
def getdoc(doctype, name, user=None):
    """
	Loads a doclist for a given document. This method is called directly from the client.
	Requries "doctype", "name" as form variables.
	Will also call the "onload" method on the document.
	"""

    if not (doctype and name):
        raise Exception('doctype and name required!')

    if not name:
        name = doctype

    if not dataent.db.exists(doctype, name):
        return []

    try:
        doc = dataent.get_doc(doctype, name)
        run_onload(doc)

        if not doc.has_permission("read"):
            dataent.flags.error_message = _(
                'Insufficient Permission for {0}').format(
                    dataent.bold(doctype + ' ' + name))
            raise dataent.PermissionError(("read", doctype, name))

        doc.apply_fieldlevel_read_permissions()

        # add file list
        doc.add_viewed()
        get_docinfo(doc)

    except Exception:
        dataent.errprint(dataent.utils.get_traceback())
        raise

    if doc and not name.startswith('_'):
        dataent.get_user().update_recent(doctype, name)

    doc.add_seen()

    dataent.response.docs.append(doc)
        def get_item_dict():
            default_uom = dataent.db.get_single_value("Stock Settings",
                                                      "stock_uom") or _("Nos")
            cost_center = dataent.get_cached_value('Company', self.company,
                                                   "cost_center")
            if not cost_center:
                dataent.throw(
                    _("Please set the Default Cost Center in {0} company.").
                    format(dataent.bold(self.company)))
            rate = flt(row.outstanding_amount) / flt(row.qty)

            return dataent._dict({
                "uom": default_uom,
                "rate": rate or 0.0,
                "qty": row.qty,
                "conversion_factor": 1.0,
                "item_name": row.item_name or "Opening Invoice Item",
                "description": row.item_name or "Opening Invoice Item",
                income_expense_account_field: row.temporary_opening_account,
                "cost_center": cost_center
            })
Example #23
0
def rename_doc(doctype, old, new, force=False, merge=False, ignore_permissions=False, ignore_if_exists=False):
	"""
		Renames a doc(dt, old) to doc(dt, new) and
		updates all linked fields of type "Link"
	"""
	if not dataent.db.exists(doctype, old):
		return

	if ignore_if_exists and dataent.db.exists(doctype, new):
		return

	if old==new:
		dataent.msgprint(_('Please select a new name to rename'))
		return

	force = cint(force)
	merge = cint(merge)

	meta = dataent.get_meta(doctype)

	# call before_rename
	old_doc = dataent.get_doc(doctype, old)
	out = old_doc.run_method("before_rename", old, new, merge) or {}
	new = (out.get("new") or new) if isinstance(out, dict) else (out or new)

	if doctype != "DocType":
		new = validate_rename(doctype, new, meta, merge, force, ignore_permissions)

	if not merge:
		rename_parent_and_child(doctype, old, new, meta)

	# update link fields' values
	link_fields = get_link_fields(doctype)
	update_link_field_values(link_fields, old, new, doctype)

	rename_dynamic_links(doctype, old, new)

	# save the user settings in the db
	update_user_settings(old, new, link_fields)

	if doctype=='DocType':
		rename_doctype(doctype, old, new, force)

	update_attachments(doctype, old, new)

	rename_versions(doctype, old, new)

	# call after_rename
	new_doc = dataent.get_doc(doctype, new)

	# copy any flags if required
	new_doc._local = getattr(old_doc, "_local", None)

	new_doc.run_method("after_rename", old, new, merge)

	if not merge:
		rename_password(doctype, old, new)

	# update user_permissions
	dataent.db.sql("""update tabDefaultValue set defvalue=%s where parenttype='User Permission'
		and defkey=%s and defvalue=%s""", (new, doctype, old))

	if merge:
		new_doc.add_comment('Edit', _("merged {0} into {1}").format(dataent.bold(old), dataent.bold(new)))
	else:
		new_doc.add_comment('Edit', _("renamed from {0} to {1}").format(dataent.bold(old), dataent.bold(new)))

	if merge:
		dataent.delete_doc(doctype, old)

	dataent.clear_cache()
	dataent.enqueue('dataent.utils.global_search.rebuild_for_doctype', doctype=doctype)

	return new
Example #24
0
def validate_student_belongs_to_group(student, student_group):
	groups = dataent.db.get_all('Student Group Student', ['parent'], dict(student = student, active=1))
	if not student_group in [d.parent for d in groups]:
		dataent.throw(_('Student {0} does not belong to group {1}').format(dataent.bold(student), dataent.bold(student_group)),
			StudentNotInGroupError)
Example #25
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,
                reference_doctype=None):
        if not ignore_permissions and not dataent.has_permission(
                self.doctype, "read", user=user):
            dataent.flags.error_message = _(
                'Insufficient Permission for {0}').format(
                    dataent.bold(self.doctype))
            raise dataent.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:
            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 dataent.session.user
        self.update = update
        self.user_settings_fields = copy.deepcopy(self.fields)

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

        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 #26
0
def logout_feed(user, reason):
    if user and user != "Guest":
        subject = _("{0} logged out: {1}").format(get_fullname(user),
                                                  dataent.bold(reason))
        add_authentication_log(subject, user, operation="Logout")
Example #27
0
def get_batch_no(item_code, warehouse, qty=1, throw=False):
	"""
	Get batch number using First Expiring First Out method.
	:param item_code: `item_code` of Item Document
	:param warehouse: name of Warehouse to check
	:param qty: quantity of Items
	:return: String represent batch number of batch with sufficient quantity else an empty String
	"""

	batch_no = None
	batches = get_batches(item_code, warehouse, qty, throw)

	for batch in batches:
		if cint(qty) <= cint(batch.qty):
			batch_no = batch.batch_id
			break

	if not batch_no:
		dataent.msgprint(_('Please select a Batch for Item {0}. Unable to find a single batch that fulfills this requirement').format(dataent.bold(item_code)))
		if throw:
			raise UnableToSelectBatchError

	return batch_no
Example #28
0
    def validate(self):
        """Check if change in varchar length isn't truncating the columns"""
        if self.is_new():
            return

        self.get_columns_from_db()

        columns = [
            dataent._dict({
                "fieldname": f,
                "fieldtype": "Data"
            }) for f in standard_varchar_columns
        ]
        columns += self.columns.values()

        for col in columns:
            if len(col.fieldname) >= 64:
                dataent.throw(
                    _("Fieldname is limited to 64 characters ({0})").format(
                        dataent.bold(col.fieldname)))

            if col.fieldtype in type_map and type_map[
                    col.fieldtype][0] == "varchar":

                # validate length range
                new_length = cint(col.length) or cint(varchar_len)
                if not (1 <= new_length <= 1000):
                    dataent.throw(
                        _("Length of {0} should be between 1 and 1000").format(
                            col.fieldname))

                current_col = self.current_columns.get(col.fieldname, {})
                if not current_col:
                    continue
                current_type = self.current_columns[col.fieldname]["type"]
                current_length = re.findall('varchar\(([\d]+)\)', current_type)
                if not current_length:
                    # case when the field is no longer a varchar
                    continue
                current_length = current_length[0]
                if cint(current_length) != cint(new_length):
                    try:
                        # check for truncation
                        max_length = dataent.db.sql("""select max(char_length(`{fieldname}`)) from `tab{doctype}`"""\
                         .format(fieldname=col.fieldname, doctype=self.doctype))

                    except pymysql.InternalError as e:
                        if e.args[0] == ER.BAD_FIELD_ERROR:
                            # Unknown column 'column_name' in 'field list'
                            continue

                        else:
                            raise

                    if max_length and max_length[0][
                            0] and max_length[0][0] > new_length:
                        if col.fieldname in self.columns:
                            self.columns[col.fieldname].length = current_length

                        dataent.msgprint(_("Reverting length to {0} for '{1}' in '{2}'; Setting the length as {3} will cause truncation of data.")\
                         .format(current_length, col.fieldname, self.doctype, new_length))