Пример #1
0
    def get_overlapping_dates(self):
        if not self.name:
            self.name = "New Shift Request"

        shift = frappe.qb.DocType("Shift Request")
        query = (frappe.qb.from_(shift).select(
            shift.name,
            shift.shift_type).where((shift.employee == self.employee)
                                    & (shift.docstatus < 2)
                                    & (shift.name != self.name)))

        if self.to_date:
            query = query.where(
                Criterion.any([
                    Criterion.any([
                        shift.to_date.isnull(),
                        ((self.from_date >= shift.from_date) &
                         (self.from_date <= shift.to_date)),
                    ]),
                    Criterion.any([
                        ((self.to_date >= shift.from_date) &
                         (self.to_date <= shift.to_date)),
                        shift.from_date.between(self.from_date, self.to_date),
                    ]),
                ]))
        else:
            query = query.where(shift.to_date.isnull()
                                | ((self.from_date >= shift.from_date)
                                   & (self.from_date <= shift.to_date)))

        return query.run(as_dict=True)
Пример #2
0
def get_duplicate_attendance_record(employee,
                                    attendance_date,
                                    shift,
                                    name=None):
    attendance = frappe.qb.DocType("Attendance")
    query = (frappe.qb.from_(attendance).select(
        attendance.name).where((attendance.employee == employee)
                               & (attendance.docstatus < 2)))

    if shift:
        query = query.where(
            Criterion.any([
                Criterion.all([
                    ((attendance.shift.isnull()) | (attendance.shift == "")),
                    (attendance.attendance_date == attendance_date),
                ]),
                Criterion.all([
                    ((attendance.shift.isnotnull()) |
                     (attendance.shift != "")),
                    (attendance.attendance_date == attendance_date),
                    (attendance.shift == shift),
                ]),
            ]))
    else:
        query = query.where((attendance.attendance_date == attendance_date))

    if name:
        query = query.where(attendance.name != name)

    return query.run(as_dict=True)
Пример #3
0
def get_additional_salaries(employee, start_date, end_date, component_type):
    from frappe.query_builder import Criterion

    comp_type = "Earning" if component_type == "earnings" else "Deduction"

    additional_sal = frappe.qb.DocType("Additional Salary")
    component_field = additional_sal.salary_component.as_("component")
    overwrite_field = additional_sal.overwrite_salary_structure_amount.as_(
        "overwrite")

    additional_salary_list = (
        frappe.qb.from_(additional_sal).select(
            additional_sal.name,
            component_field,
            additional_sal.type,
            additional_sal.amount,
            additional_sal.is_recurring,
            overwrite_field,
            additional_sal.deduct_full_tax_on_selected_payroll_date,
        ).where((additional_sal.employee == employee)
                & (additional_sal.docstatus == 1)
                & (additional_sal.type == comp_type)).
        where(
            Criterion.any([
                Criterion.all(
                    [  # is recurring and additional salary dates fall within the payroll period
                        additional_sal.is_recurring == 1,
                        additional_sal.from_date <= end_date,
                        additional_sal.to_date >= end_date,
                    ]),
                Criterion.all(
                    [  # is not recurring and additional salary's payroll date falls within the payroll period
                        additional_sal.is_recurring == 0,
                        additional_sal.payroll_date[start_date:end_date],
                    ]),
            ])).run(as_dict=True))

    additional_salaries = []
    components_to_overwrite = []

    for d in additional_salary_list:
        if d.overwrite:
            if d.component in components_to_overwrite:
                frappe.throw(
                    _("Multiple Additional Salaries with overwrite property exist for Salary Component {0} between {1} and {2}."
                      ).format(frappe.bold(d.component), start_date, end_date),
                    title=_("Error"),
                )

            components_to_overwrite.append(d.component)

        additional_salaries.append(d)

    return additional_salaries
Пример #4
0
    def check_duplicates(self):

        item_price = frappe.qb.DocType("Item Price")

        query = (frappe.qb.from_(item_price).select(
            item_price.price_list_rate).where(
                (item_price.item_code == self.item_code)
                & (item_price.price_list == self.price_list)
                & (item_price.name != self.name)))
        data_fields = (
            "uom",
            "valid_from",
            "valid_upto",
            "customer",
            "supplier",
            "batch_no",
        )

        number_fields = ["packing_unit"]

        for field in data_fields:
            if self.get(field):
                query = query.where(item_price[field] == self.get(field))
            else:
                query = query.where(
                    Criterion.any([
                        item_price[field].isnull(),
                        Cast_(item_price[field], "varchar") == "",
                    ]))

        for field in number_fields:
            if self.get(field):
                query = query.where(item_price[field] == self.get(field))
            else:
                query = query.where(
                    Criterion.any([
                        item_price[field].isnull(),
                        item_price[field] == 0,
                    ]))

        price_list_rate = query.run(as_dict=True)

        if price_list_rate:
            frappe.throw(
                _("Item Price appears multiple times based on Price List, Supplier/Customer, Currency, Item, Batch, UOM, Qty, and Dates."
                  ),
                ItemPriceDuplicateItem,
            )
Пример #5
0
def get_so_with_invoices(filters):
    """
	Get Sales Order with payment terms template with their associated Invoices
	"""
    sorders = []

    so = qb.DocType("Sales Order")
    ps = qb.DocType("Payment Schedule")
    soi = qb.DocType("Sales Order Item")

    conditions = get_conditions(filters)
    filter_criterions = build_filter_criterions(filters)

    datediff = query_builder.CustomFunction("DATEDIFF",
                                            ["cur_date", "due_date"])
    ifelse = query_builder.CustomFunction("IF", ["condition", "then", "else"])

    query_so = (qb.from_(so).join(soi).on(soi.parent == so.name).join(ps).on(
        ps.parent == so.name).select(
            so.name,
            so.customer,
            so.transaction_date.as_("submitted"),
            ifelse(
                datediff(ps.due_date, functions.CurDate()) < 0, "Overdue",
                "Unpaid").as_("status"),
            ps.payment_term,
            ps.description,
            ps.due_date,
            ps.invoice_portion,
            ps.base_payment_amount,
            ps.paid_amount,
        ).where(
            (so.docstatus == 1)
            & (so.payment_terms_template != "NULL")
            & (so.company == conditions.company)
            & (so.transaction_date[conditions.start_date:conditions.end_date])
        ).where(Criterion.all(filter_criterions)).orderby(
            so.name, so.transaction_date, ps.due_date))

    sorders = query_so.run(as_dict=True)

    invoices = []
    if sorders != []:
        soi = qb.DocType("Sales Order Item")
        si = qb.DocType("Sales Invoice")
        sii = qb.DocType("Sales Invoice Item")
        query_inv = (qb.from_(sii).right_join(si).on(
            si.name == sii.parent).inner_join(soi).on(
                soi.name == sii.so_detail).select(
                    sii.sales_order, sii.parent.as_("invoice"),
                    si.base_grand_total.as_("invoice_amount")).where(
                        (sii.sales_order.isin([x.name for x in sorders]))
                        & (si.docstatus == 1)).groupby(sii.parent))
        invoices = query_inv.run(as_dict=True)

    return sorders, invoices
Пример #6
0
def get_shifts_for_date(employee: str, for_timestamp: datetime) -> List[Dict[str, str]]:
	"""Returns list of shifts with details for given date"""
	assignment = frappe.qb.DocType("Shift Assignment")

	return (
		frappe.qb.from_(assignment)
		.select(assignment.name, assignment.shift_type)
		.where(
			(assignment.employee == employee)
			& (assignment.docstatus == 1)
			& (assignment.status == "Active")
			& (assignment.start_date <= getdate(for_timestamp.date()))
			& (
				Criterion.any(
					[
						assignment.end_date.isnull(),
						(assignment.end_date.isnotnull() & (getdate(for_timestamp.date()) <= assignment.end_date)),
					]
				)
			)
		)
	).run(as_dict=True)
Пример #7
0
def get_cards_for_user(doctype, txt, searchfield, start, page_len, filters):
    meta = frappe.get_meta(doctype)
    searchfields = meta.get_search_fields()
    search_conditions = []

    if not frappe.db.exists("DocType", doctype):
        return

    numberCard = DocType("Number Card")

    if txt:
        search_conditions = [
            numberCard[field].like("%{txt}%".format(txt=txt))
            for field in searchfields
        ]

    condition_query = frappe.db.query.build_conditions(doctype, filters)

    return (condition_query.select(
        numberCard.name, numberCard.label, numberCard.document_type).where(
            (numberCard.owner == frappe.session.user)
            | (numberCard.is_public == 1)).where(
                Criterion.any(search_conditions))).run()