Beispiel #1
0
def get_data(module):
	"""Get module data for the module view `desk/#Module/[name]`"""
	doctype_info = get_doctype_info(module)
	data = build_config_from_file(module)

	if not data:
		data = build_standard_config(module, doctype_info)
	else:
		add_custom_doctypes(data, doctype_info)

	add_section(data, _("Custom Reports"), "fa fa-list-alt",
		get_report_list(module))

	data = combine_common_sections(data)
	data = apply_permissions(data)

	#set_last_modified(data)

	return data
Beispiel #2
0
    def calculate_total_and_program(self):
        no_of_students = 0
        for d in self.student_groups:
            # if not d.total_students:
            d.total_students = get_total_students(d.student_group,
                                                  self.academic_year,
                                                  self.academic_term,
                                                  self.student_category)
            no_of_students += cint(d.total_students)

            # validate the program of fee structure and student groups
            student_group_program = dataent.db.get_value(
                "Student Group", d.student_group, "program")
            if self.program and student_group_program and self.program != student_group_program:
                dataent.msgprint(
                    _("Program in the Fee Structure and Student Group {0} are different."
                      ).format(d.student_group))
        self.grand_total = no_of_students * self.total_amount
        self.grand_total_in_words = money_in_words(self.grand_total)
Beispiel #3
0
    def validate(self):
        super(WebForm, self).validate()

        if not self.module:
            self.module = dataent.db.get_value('DocType', self.doc_type,
                                               'module')

        if (not (dataent.flags.in_install or dataent.flags.in_patch
                 or dataent.flags.in_test or dataent.flags.in_fixtures)
                and self.is_standard and not dataent.conf.developer_mode):
            dataent.throw(
                _("You need to be in developer mode to edit a Standard Web Form"
                  ))

        if not dataent.flags.in_import:
            self.validate_fields()

        if self.accept_payment:
            self.validate_payment_amount()
Beispiel #4
0
def close_or_unclose_sales_orders(names, status):
    if not dataent.has_permission("Sales Order", "write"):
        dataent.throw(_("Not permitted"), dataent.PermissionError)

    names = json.loads(names)
    for name in names:
        so = dataent.get_doc("Sales Order", name)
        if so.docstatus == 1:
            if status == "Closed":
                if so.status not in ("Cancelled",
                                     "Closed") and (so.per_delivered < 100
                                                    or so.per_billed < 100):
                    so.update_status(status)
            else:
                if so.status == "Closed":
                    so.update_status('Draft')
            so.update_blanket_order()

    dataent.local.message_log = []
Beispiel #5
0
def get_pipeline_data(from_date, to_date, company):
    opportunities = dataent.get_all(
        "Opportunity",
        filters=[['status', 'in', ['Open', 'Quotation', 'Replied']],
                 ['company', '=', company],
                 ['transaction_date', 'Between', [from_date, to_date]]],
        fields=[
            'currency', 'sales_stage', 'opportunity_amount', 'probability'
        ])

    if opportunities:
        default_currency = dataent.get_cached_value('Global Defaults', 'None',
                                                    'default_currency')

        cp_opportunities = [
            dict(
                x, **{
                    'compound_amount':
                    (convert(x['opportunity_amount'], x['currency'],
                             default_currency, to_date) * x['probability'] /
                     100)
                }) for x in opportunities
        ]

        df = pd.DataFrame(cp_opportunities).groupby(['sales_stage'],
                                                    as_index=True).agg({
                                                        'compound_amount':
                                                        'sum'
                                                    }).to_dict()

        result = {}
        result['labels'] = df['compound_amount'].keys()
        result['datasets'] = []
        result['datasets'].append({
            'name': _("Total Amount"),
            'values': df['compound_amount'].values(),
            'chartType': 'bar'
        })

        return result

    else:
        return 'empty'
Beispiel #6
0
def execute(filters=None):
    if not filters: filters = {}

    days_since_last_order = filters.get("days_since_last_order")
    doctype = filters.get("doctype")

    if cint(days_since_last_order) <= 0:
        dataent.throw(
            _("'Days Since Last Order' must be greater than or equal to zero"))

    columns = get_columns()
    customers = get_sales_details(doctype)

    data = []
    for cust in customers:
        if cint(cust[8]) >= cint(days_since_last_order):
            cust.insert(7, get_last_sales_amt(cust[0], doctype))
            data.append(cust)
    return columns, data
Beispiel #7
0
def close_or_unclose_purchase_orders(names, status):
    if not dataent.has_permission("Purchase Order", "write"):
        dataent.throw(_("Not permitted"), dataent.PermissionError)

    names = json.loads(names)
    for name in names:
        po = dataent.get_doc("Purchase Order", name)
        if po.docstatus == 1:
            if status == "Closed":
                if po.status not in ("Cancelled",
                                     "Closed") and (po.per_received < 100
                                                    or po.per_billed < 100):
                    po.update_status(status)
            else:
                if po.status == "Closed":
                    po.update_status("Draft")
            po.update_blanket_order()

    dataent.local.message_log = []
Beispiel #8
0
    def get_transactions(self, arg=None):
        doctypes = list(
            set(
                dataent.db.sql_list("""select parent
				from `tabDocField` df where fieldname='naming_series'""") +
                dataent.db.sql_list("""select dt from `tabCustom Field`
				where fieldname='naming_series'""")))

        doctypes = list(
            set(get_doctypes_with_read()).intersection(set(doctypes)))
        prefixes = ""
        for d in doctypes:
            options = ""
            try:
                options = self.get_options(d)
            except dataent.DoesNotExistError:
                dataent.msgprint(_('Unable to find DocType {0}').format(d))
                #dataent.pass_does_not_exist_error()
                continue

            if options:
                prefixes = prefixes + "\n" + options
        prefixes.replace("\n\n", "\n")
        prefixes = prefixes.split("\n")

        custom_prefixes = dataent.get_all('DocType',
                                          fields=["autoname"],
                                          filters={
                                              "name": ('not in', doctypes),
                                              "autoname": ('like', '%.#%'),
                                              'module': ('not in', ['Core'])
                                          })
        if custom_prefixes:
            prefixes = prefixes + [
                d.autoname.rsplit('.', 1)[0] for d in custom_prefixes
            ]

        prefixes = "\n".join(sorted(prefixes))

        return {
            "transactions": "\n".join([''] + sorted(doctypes)),
            "prefixes": prefixes
        }
Beispiel #9
0
def make_gl_entries(gl_map,
                    cancel=False,
                    adv_adj=False,
                    merge_entries=True,
                    update_outstanding='Yes',
                    from_repost=False):
    if gl_map:
        if not cancel:
            gl_map = process_gl_map(gl_map, merge_entries)
            if gl_map and len(gl_map) > 1:
                save_entries(gl_map, adv_adj, update_outstanding, from_repost)
            else:
                dataent.throw(
                    _("Incorrect number of General Ledger Entries found. You might have selected a wrong Account in the transaction."
                      ))
        else:
            delete_gl_entries(gl_map,
                              adv_adj=adv_adj,
                              update_outstanding=update_outstanding)
Beispiel #10
0
def get(doctype, name=None, filters=None, parent=None):
    '''Returns a document by name or filters

	:param doctype: DocType of the document to be returned
	:param name: return document of this `name`
	:param filters: If name is not set, filter by these values and return the first match'''
    if dataent.is_table(doctype):
        check_parent_permission(parent, doctype)

    if filters and not name:
        name = dataent.db.get_value(doctype, json.loads(filters))
        if not name:
            dataent.throw(_("No document found for given filters"))

    doc = dataent.get_doc(doctype, name)
    if not doc.has_permission("read"):
        raise dataent.PermissionError

    return dataent.get_doc(doctype, name).as_dict()
Beispiel #11
0
    def validate(self):
        user = dataent.get_all(
            'POS Closing Voucher',
            filters={
                'user': self.user,
                'docstatus': 1
            },
            or_filters={
                'period_start_date':
                ('between', [self.period_start_date, self.period_end_date]),
                'period_end_date':
                ('between', [self.period_start_date, self.period_end_date])
            })

        if user:
            dataent.throw(
                _("POS Closing Voucher alreday exists for {0} between date {1} and {2}"
                  .format(self.user, self.period_start_date,
                          self.period_end_date)))
Beispiel #12
0
 def update_variants(self):
     if self.flags.dont_update_variants or \
         dataent.db.get_single_value('Item Variant Settings', 'do_not_update_variants'):
         return
     if self.has_variants:
         variants = dataent.db.get_all("Item",
                                       fields=["item_code"],
                                       filters={"variant_of": self.name})
         if variants:
             if len(variants) <= 30:
                 update_variants(variants, self, publish_progress=False)
                 dataent.msgprint(_("Item Variants updated"))
             else:
                 dataent.enqueue(
                     "epaas.stock.doctype.item.item.update_variants",
                     variants=variants,
                     template=self,
                     now=dataent.flags.in_test,
                     timeout=600)
Beispiel #13
0
    def validate_duplicate_entry(self):
        if not self.flags.ignore_duplicate_entry_error and not self.is_folder:
            # check duplicate name

            # check duplicate assignement
            n_records = dataent.db.sql(
                """select name from `tabFile`
				where content_hash=%s
				and name!=%s
				and attached_to_doctype=%s
				and attached_to_name=%s""",
                (self.content_hash, self.name, self.attached_to_doctype,
                 self.attached_to_name))
            if len(n_records) > 0:
                self.duplicate_entry = n_records[0][0]
                dataent.throw(
                    dataent._(
                        "Same file has already been attached to the record"),
                    dataent.DuplicateEntryError)
Beispiel #14
0
	def validate(self):
		end_time = datetime.datetime.combine(getdate(self.appointment_date), get_time(self.appointment_time)) + datetime.timedelta(minutes=float(self.duration))
		overlaps = dataent.db.sql("""
		select
			name, practitioner, patient, appointment_time, duration
		from
			`tabPatient Appointment`
		where
			appointment_date=%s and name!=%s and status NOT IN ("Closed", "Cancelled")
			and (practitioner=%s or patient=%s) and
			((appointment_time<%s and appointment_time + INTERVAL duration MINUTE>%s) or
			(appointment_time>%s and appointment_time<%s) or
			(appointment_time=%s))
		""", (self.appointment_date, self.name, self.practitioner, self.patient,
		self.appointment_time, end_time.time(), self.appointment_time, end_time.time(), self.appointment_time))

		if overlaps:
			dataent.throw(_("""Appointment overlaps with {0}.<br> {1} has appointment scheduled
			with {2} at {3} having {4} minute(s) duration.""").format(overlaps[0][0], overlaps[0][1], overlaps[0][2], overlaps[0][3], overlaps[0][4]))
Beispiel #15
0
def get_holiday_list_for_employee(employee, raise_exception=True):
    if employee:
        holiday_list, company = dataent.db.get_value(
            "Employee", employee, ["holiday_list", "company"])
    else:
        holiday_list = ''
        company = dataent.db.get_value("Global Defaults", None,
                                       "default_company")

    if not holiday_list:
        holiday_list = dataent.get_cached_value('Company', company,
                                                "default_holiday_list")

    if not holiday_list and raise_exception:
        dataent.throw(
            _('Please set a default Holiday List for Employee {0} or Company {1}'
              ).format(employee, company))

    return holiday_list
Beispiel #16
0
    def validate_dates_with_periodicity(self):
        for d in self.get("items"):
            if d.start_date and d.end_date and d.periodicity and d.periodicity != "Random":
                date_diff = (getdate(d.end_date) -
                             getdate(d.start_date)).days + 1
                days_in_period = {
                    "Weekly": 7,
                    "Monthly": 30,
                    "Quarterly": 90,
                    "Half Yearly": 180,
                    "Yearly": 365
                }

                if date_diff < days_in_period[d.periodicity]:
                    throw(
                        _("Row {0}: To set {1} periodicity, difference between from and to date \
						must be greater than or equal to {2}").format(
                            d.idx, d.periodicity,
                            days_in_period[d.periodicity]))
Beispiel #17
0
	def check_recursion(self):
		""" Check whether recursion occurs in any bom"""
		bom_list = self.traverse_tree()
		bom_nos = dataent.get_all('BOM Item', fields=["bom_no"],
			filters={'parent': ('in', bom_list), 'parenttype': 'BOM'})

		raise_exception = False
		if bom_nos and self.name in [d.bom_no for d in bom_nos]:
			raise_exception = True

		if not raise_exception:
			bom_nos = dataent.get_all('BOM Item', fields=["parent"],
				filters={'bom_no': self.name, 'parenttype': 'BOM'})

			if self.name in [d.parent for d in bom_nos]:
				raise_exception = True

		if raise_exception:
			dataent.throw(_("BOM recursion: {0} cannot be parent or child of {2}").format(self.name, self.name))
Beispiel #18
0
    def check_recursion(self):
        if self.flags.ignore_recursion_check: return
        check_list = [['task', 'parent'], ['parent', 'task']]
        for d in check_list:
            task_list, count = [self.name], 0
            while (len(task_list) > count):
                tasks = dataent.db.sql(
                    " select %s from `tabTask Depends On` where %s = %s " %
                    (d[0], d[1], '%s'), cstr(task_list[count]))
                count = count + 1
                for b in tasks:
                    if b[0] == self.name:
                        dataent.throw(_("Circular Reference Error"),
                                      CircularReferenceError)
                    if b[0]:
                        task_list.append(b[0])

                if count == 15:
                    break
Beispiel #19
0
    def validate(self):
        if (self.standard == "Yes"
                and not dataent.local.conf.get("developer_mode")
                and not (dataent.flags.in_import or dataent.flags.in_test)):

            dataent.throw(dataent._("Standard Print Format cannot be updated"))

        # old_doc_type is required for clearing item cache
        self.old_doc_type = dataent.db.get_value('Print Format', self.name,
                                                 'doc_type')

        self.extract_images()

        if not self.module:
            self.module = dataent.db.get_value('DocType', self.doc_type,
                                               'module')

        if self.html and self.print_format_type != 'Js':
            validate_template(self.html)
Beispiel #20
0
    def validate(self):
        if not self.template:
            self.template = get_default_address_template()

        self.defaults = dataent.db.get_values("Address Template", {
            "is_default": 1,
            "name": ("!=", self.name)
        })
        if not self.is_default:
            if not self.defaults:
                self.is_default = 1
                if cint(
                        dataent.db.get_single_value('System Settings',
                                                    'setup_complete')):
                    dataent.msgprint(
                        _("Setting this Address Template as default as there is no other default"
                          ))

        validate_template(self.template)
Beispiel #21
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)
Beispiel #22
0
def create_suppliers(args_data):
    args = json.loads(args_data)
    defaults = dataent.defaults.get_defaults()
    for i in range(1, 4):
        supplier = args.get("supplier_" + str(i))
        if supplier:
            try:
                doc = dataent.get_doc({
                    "doctype": "Supplier",
                    "supplier_name": supplier,
                    "supplier_group": _("Local"),
                    "company": defaults.get("company")
                }).insert()

                if args.get("supplier_contact_" + str(i)):
                    create_contact(args.get("supplier_contact_" + str(i)),
                                   "Supplier", doc.name)
            except dataent.NameError:
                pass
Beispiel #23
0
def get_list(doctype, *args, **kwargs):
    '''wrapper for DatabaseQuery'''
    kwargs.pop('cmd', None)
    kwargs.pop('ignore_permissions', None)

    # If doctype is child table
    if dataent.is_table(doctype):
        # Example dataent.db.get_list('Purchase Receipt Item', {'parent': 'Purchase Receipt'})
        # Here purchase receipt is the parent doctype of the child doctype Purchase Receipt Item

        if not kwargs.get('parent'):
            dataent.flags.error_message = _(
                'Parent is required to get child table data')
            raise dataent.PermissionError(doctype)

        check_parent_permission(kwargs.get('parent'), doctype)
        del kwargs['parent']

    return DatabaseQuery(doctype).execute(None, *args, **kwargs)
Beispiel #24
0
def update_disbursement_status(doc):
    disbursement = dataent.db.sql(
        """select posting_date, ifnull(sum(credit_in_account_currency), 0) as disbursed_amount
		from `tabGL Entry` where account = %s and against_voucher_type = 'Loan' and against_voucher = %s""",
        (doc.payment_account, doc.name),
        as_dict=1)[0]
    if disbursement.disbursed_amount == doc.loan_amount:
        dataent.db.set_value("Loan", doc.name, "status", "Disbursed")
    if disbursement.disbursed_amount == 0:
        dataent.db.set_value("Loan", doc.name, "status", "Sanctioned")
    if disbursement.disbursed_amount > doc.loan_amount:
        dataent.throw(
            _("Disbursed Amount cannot be greater than Loan Amount {0}").
            format(doc.loan_amount))
    if disbursement.disbursed_amount > 0:
        dataent.db.set_value("Loan", doc.name, "disbursement_date",
                             disbursement.posting_date)
        dataent.db.set_value("Loan", doc.name, "repayment_start_date",
                             disbursement.posting_date)
Beispiel #25
0
	def getinforow(docfield):
		"""make info comment for options, links etc."""
		if docfield.fieldtype == 'Select':
			if not docfield.options:
				return ''
			else:
				return _("One of") + ': %s' % ', '.join(filter(None, docfield.options.split('\n')))
		elif docfield.fieldtype == 'Link':
			return 'Valid %s' % docfield.options
		elif docfield.fieldtype == 'Int':
			return 'Integer'
		elif docfield.fieldtype == "Check":
			return "0 or 1"
		elif docfield.fieldtype in ["Date", "Datetime"]:
			return cstr(dataent.defaults.get_defaults().date_format)
		elif hasattr(docfield, "info"):
			return docfield.info
		else:
			return ''
Beispiel #26
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
        })
Beispiel #27
0
 def get_label(self, fieldname):
     '''Get label of the given fieldname'''
     df = self.get_field(fieldname)
     if df:
         label = df.label
     else:
         label = {
             'name': _('ID'),
             'owner': _('Created By'),
             'modified_by': _('Modified By'),
             'creation': _('Created On'),
             'modified': _('Last Modified On')
         }.get(fieldname) or _('No Label')
     return label
Beispiel #28
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)
Beispiel #29
0
def get_context(context):
    context.no_cache = 1
    context.show_sidebar = True
    context.doc = dataent.get_doc(dataent.form_dict.doctype,
                                  dataent.form_dict.name)
    if hasattr(context.doc, "set_indicator"):
        context.doc.set_indicator()

    if show_attachments():
        context.attachments = get_attachments(dataent.form_dict.doctype,
                                              dataent.form_dict.name)

    context.parents = dataent.form_dict.parents
    context.title = dataent.form_dict.name
    context.payment_ref = dataent.db.get_value(
        "Payment Request", {"reference_name": dataent.form_dict.name}, "name")

    context.enabled_checkout = dataent.get_doc(
        "Shopping Cart Settings").enable_checkout

    default_print_format = dataent.db.get_value(
        'Property Setter',
        dict(property='default_print_format',
             doc_type=dataent.form_dict.doctype), "value")
    if default_print_format:
        context.print_format = default_print_format
    else:
        context.print_format = "Standard"

    if not dataent.has_website_permission(context.doc):
        dataent.throw(_("Not Permitted"), dataent.PermissionError)

    # check for the loyalty program of the customer
    customer_loyalty_program = dataent.db.get_value("Customer",
                                                    context.doc.customer,
                                                    "loyalty_program")
    if customer_loyalty_program:
        from epaas.accounts.doctype.loyalty_program.loyalty_program import get_loyalty_program_details_with_points
        loyalty_program_details = get_loyalty_program_details_with_points(
            context.doc.customer, customer_loyalty_program)
        context.available_loyalty_points = int(
            loyalty_program_details.get("loyalty_points"))
Beispiel #30
0
def make_gl_entries(doc, credit_account, debit_account, against,
	amount, base_amount, posting_date, project, account_currency, cost_center, voucher_detail_no):
	# GL Entry for crediting the amount in the deferred expense
	from epaas.accounts.general_ledger import make_gl_entries

	gl_entries = []
	gl_entries.append(
		doc.get_gl_dict({
			"account": credit_account,
			"against": against,
			"credit": base_amount,
			"credit_in_account_currency": amount,
			"cost_center": cost_center,
			"voucher_detail_no": voucher_detail_no,
			'posting_date': posting_date,
			'project': project
		}, account_currency)
	)
	# GL Entry to debit the amount from the expense
	gl_entries.append(
		doc.get_gl_dict({
			"account": debit_account,
			"against": against,
			"debit": base_amount,
			"debit_in_account_currency": amount,
			"cost_center": cost_center,
			"voucher_detail_no": voucher_detail_no,
			'posting_date': posting_date,
			'project': project
		}, account_currency)
	)

	if gl_entries:
		try:
			make_gl_entries(gl_entries, cancel=(doc.docstatus == 2), merge_entries=True)
			dataent.db.commit()
		except:
			dataent.db.rollback()
			title = _("Error while processing deferred accounting for {0}").format(doc.name)
			traceback = dataent.get_traceback()
			dataent.log_error(message=traceback , title=title)
			sendmail_to_system_managers(title, traceback)