def validate_filters(filters): if not filters.fiscal_year: dataent.throw(_("Fiscal Year {0} is required").format(filters.fiscal_year)) fiscal_year = dataent.db.get_value("Fiscal Year", filters.fiscal_year, ["year_start_date", "year_end_date"], as_dict=True) if not fiscal_year: dataent.throw(_("Fiscal Year {0} does not exist").format(filters.fiscal_year)) else: filters.year_start_date = getdate(fiscal_year.year_start_date) filters.year_end_date = getdate(fiscal_year.year_end_date) if not filters.from_date: filters.from_date = filters.year_start_date if not filters.to_date: filters.to_date = filters.year_end_date filters.from_date = getdate(filters.from_date) filters.to_date = getdate(filters.to_date) if filters.from_date > filters.to_date: dataent.throw(_("From Date cannot be greater than To Date")) if (filters.from_date < filters.year_start_date) or (filters.from_date > filters.year_end_date): dataent.msgprint(_("From Date should be within the Fiscal Year. Assuming From Date = {0}")\ .format(formatdate(filters.year_start_date))) filters.from_date = filters.year_start_date if (filters.to_date < filters.year_start_date) or (filters.to_date > filters.year_end_date): dataent.msgprint(_("To Date should be within the Fiscal Year. Assuming To Date = {0}")\ .format(formatdate(filters.year_end_date))) filters.to_date = filters.year_end_date
def validate_overlap(self): query = """ select name from `tab{0}` where name != %(name)s and company = %(company)s and (start_date between %(start_date)s and %(end_date)s \ or end_date between %(start_date)s and %(end_date)s \ or (start_date < %(start_date)s and end_date > %(end_date)s)) """ if not self.name: # hack! if name is null, it could cause problems with != self.name = "New " + self.doctype overlap_doc = dataent.db.sql(query.format(self.doctype), { "start_date": self.start_date, "end_date": self.end_date, "name": self.name, "company": self.company }, as_dict=1) if overlap_doc: msg = _("A {0} exists between {1} and {2} (").format(self.doctype, formatdate(self.start_date), formatdate(self.end_date)) \ + """ <b><a href="#Form/{0}/{1}">{1}</a></b>""".format(self.doctype, overlap_doc[0].name) \ + _(") for {0}").format(self.company) dataent.throw(msg)
def sync_transactions(bank, bank_account): last_sync_date = dataent.db.get_value("Bank Account", bank_account, "last_integration_date") if last_sync_date: start_date = formatdate(last_sync_date, "YYYY-MM-dd") else: start_date = formatdate(add_months(today(), -12), "YYYY-MM-dd") end_date = formatdate(today(), "YYYY-MM-dd") try: transactions = get_transactions(bank=bank, bank_account=bank_account, start_date=start_date, end_date=end_date) result = [] if transactions: for transaction in transactions: result.append(new_bank_transaction(transaction)) dataent.db.set_value("Bank Account", bank_account, "last_integration_date", getdate(end_date)) return result except Exception: dataent.log_error(dataent.get_traceback(), _("Plaid transactions sync error"))
def validate_allocation_overlap(self): leave_allocation = dataent.db.sql(""" select name from `tabLeave Allocation` where employee=%s and leave_type=%s and docstatus=1 and to_date >= %s and from_date <= %s""", (self.employee, self.leave_type, self.from_date, self.to_date)) if leave_allocation: dataent.msgprint(_("{0} already allocated for Employee {1} for period {2} to {3}") .format(self.leave_type, self.employee, formatdate(self.from_date), formatdate(self.to_date))) dataent.throw(_('Reference') + ': <a href="#Form/Leave Allocation/{0}">{0}</a>' .format(leave_allocation[0][0]), OverlapError)
def get_row_data_for_invoice(self, invoice, invoice_details, tax_rate, items): row = [] for fieldname in self.invoice_fields: if self.filters.get("type_of_business" ) == "CDNR" and fieldname == "invoice_value": row.append( abs(invoice_details.base_rounded_total) or abs(invoice_details.base_grand_total)) elif fieldname == "invoice_value": row.append(invoice_details.base_rounded_total or invoice_details.base_grand_total) elif fieldname in ('posting_date', 'shipping_bill_date'): row.append( formatdate(invoice_details.get(fieldname), 'dd-MMM-YY')) elif fieldname == "export_type": export_type = "WPAY" if invoice_details.get( fieldname) == "With Payment of Tax" else "WOPAY" row.append(export_type) else: row.append(invoice_details.get(fieldname)) taxable_value = sum([ abs(net_amount) for item_code, net_amount in self.invoice_items.get(invoice).items() if item_code in items ]) row += [tax_rate or 0, taxable_value] return row, taxable_value
def validate_due_date(posting_date, due_date, party_type, party, company=None, bill_date=None, template_name=None): if getdate(due_date) < getdate(posting_date): dataent.throw( _("Due Date cannot be before Posting / Supplier Invoice Date")) else: if not template_name: return default_due_date = get_due_date_from_template( template_name, posting_date, bill_date).strftime("%Y-%m-%d") if not default_due_date: return if default_due_date != posting_date and getdate(due_date) > getdate( default_due_date): is_credit_controller = dataent.db.get_single_value( "Accounts Settings", "credit_controller") in dataent.get_roles() if is_credit_controller: msgprint( _("Note: Due / Reference Date exceeds allowed customer credit days by {0} day(s)" ).format(date_diff(due_date, default_due_date))) else: dataent.throw( _("Due / Reference Date cannot be after {0}").format( formatdate(default_due_date)))
def convert_to_simple_type(self, v, formatted=0): """Format date, time, longint values.""" return v from dataent.utils import formatdate, fmt_money if isinstance(v, (datetime.date, datetime.timedelta, datetime.datetime, integer_types)): if isinstance(v, datetime.date): v = text_type(v) if formatted: v = formatdate(v) # time elif isinstance(v, (datetime.timedelta, datetime.datetime)): v = text_type(v) # long elif isinstance(v, integer_types): v = int(v) # convert to strings... (if formatted) if formatted: if isinstance(v, float): v = fmt_money(v) elif isinstance(v, int): v = text_type(v) return v
def test_get_monthly_results(self): '''Test monthly aggregation values of a field''' result_dict = get_monthly_results('Event', 'subject', 'creation', 'event_type="Private"', 'count') from dataent.utils import today, formatdate self.assertEqual(result_dict[formatdate(today(), "MM-yyyy")], 2)
def get_currency(filters): """ Returns a dictionary containing currency information. The keys of the dict are - company: The company for which we are fetching currency information. if no company is specified, it will fallback to the default company. - company currency: The functional currency of the said company. - presentation currency: The presentation currency to use. Only currencies that have been used for transactions will be allowed. - report date: The report date. :param filters: Report filters :type filters: dict :return: str - Currency """ company = get_appropriate_company(filters) company_currency = get_company_currency(company) presentation_currency = filters['presentation_currency'] if filters.get( 'presentation_currency') else company_currency report_date = filters.get('to_date') if not report_date: fiscal_year_to_date = get_from_and_to_date( filters.get('to_fiscal_year'))["to_date"] report_date = formatdate(get_datetime_str(fiscal_year_to_date), "dd-MM-yyyy") currency_map = dict(company=company, company_currency=company_currency, presentation_currency=presentation_currency, report_date=report_date) return currency_map
def check_stock_frozen_date(self): stock_frozen_upto = dataent.db.get_value('Stock Settings', None, 'stock_frozen_upto') or '' if stock_frozen_upto: stock_auth_role = dataent.db.get_value('Stock Settings', None, 'stock_auth_role') if getdate(self.posting_date) <= getdate( stock_frozen_upto ) and not stock_auth_role in dataent.get_roles(): dataent.throw( _("Stock transactions before {0} are frozen").format( formatdate(stock_frozen_upto)), StockFreezeError) stock_frozen_upto_days = int( dataent.db.get_value('Stock Settings', None, 'stock_frozen_upto_days') or 0) if stock_frozen_upto_days: stock_auth_role = dataent.db.get_value('Stock Settings', None, 'stock_auth_role') older_than_x_days_ago = (add_days(getdate( self.posting_date), stock_frozen_upto_days) <= date.today()) if older_than_x_days_ago and not stock_auth_role in dataent.get_roles( ): dataent.throw( _("Not allowed to update stock transactions older than {0}" ).format(stock_frozen_upto_days), StockFreezeError)
def datetime_in_user_format(date_time): if not date_time: return "" if isinstance(date_time, string_types): date_time = get_datetime(date_time) from dataent.utils import formatdate return formatdate(date_time.date()) + " " + date_time.strftime("%H:%M")
def create_remarks(self): if not self.remarks: if self.bill_no and self.bill_date: self.remarks = _("Against Supplier Invoice {0} dated {1}").format(self.bill_no, formatdate(self.bill_date)) else: self.remarks = _("No Remarks")
def add_data_row(self, rows, dt, parentfield, doc, rowidx): d = doc.copy() meta = dataent.get_meta(dt) if self.all_doctypes: d.name = '"' + d.name + '"' if len(rows) < rowidx + 1: rows.append([""] * (len(self.columns) + 1)) row = rows[rowidx] _column_start_end = self.column_start_end.get((dt, parentfield)) if _column_start_end: for i, c in enumerate(self.columns[_column_start_end. start:_column_start_end.end]): df = meta.get_field(c) fieldtype = df.fieldtype if df else "Data" value = d.get(c, "") if value: if fieldtype == "Date": value = formatdate(value) elif fieldtype == "Datetime": value = format_datetime(value) row[_column_start_end.start + i + 1] = value
def validate_fiscal_year(date, fiscal_year, company, label="Date", doc=None): years = [f[0] for f in get_fiscal_years(date, label=_(label), company=company)] if fiscal_year not in years: if doc: doc.fiscal_year = years[0] else: throw(_("{0} '{1}' not in Fiscal Year {2}").format(label, formatdate(date), fiscal_year))
def get_columns(filters): columns = [ _(filters.get("budget_against")) + ":Link/%s:150" % (filters.get("budget_against")), _("Account") + ":Link/Account:150" ] group_months = False if filters["period"] == "Monthly" else True fiscal_year = get_fiscal_years(filters) for year in fiscal_year: for from_date, to_date in get_period_date_ranges( filters["period"], year[0]): if filters["period"] == "Yearly": labels = [ _("Budget") + " " + str(year[0]), _("Actual ") + " " + str(year[0]), _("Varaiance ") + " " + str(year[0]) ] for label in labels: columns.append(label + ":Float:150") else: for label in [ _("Budget") + " (%s)" + " " + str(year[0]), _("Actual") + " (%s)" + " " + str(year[0]), _("Variance") + " (%s)" + " " + str(year[0]) ]: if group_months: label = label % ( formatdate(from_date, format_string="MMM") + "-" + formatdate(to_date, format_string="MMM")) else: label = label % formatdate(from_date, format_string="MMM") columns.append(label + ":Float:150") if filters["period"] != "Yearly": return columns + [ _("Total Budget") + ":Float:150", _("Total Actual") + ":Float:150", _("Total Variance") + ":Float:150" ] else: return columns
def validate_salary_processed_days(self): if not dataent.db.get_value("Leave Type", self.leave_type, "is_lwp"): return last_processed_pay_slip = dataent.db.sql( """ select start_date, end_date from `tabSalary Slip` where docstatus = 1 and employee = %s and ((%s between start_date and end_date) or (%s between start_date and end_date)) order by modified desc limit 1 """, (self.employee, self.to_date, self.from_date)) if last_processed_pay_slip: dataent.throw( _("Salary already processed for period between {0} and {1}, Leave application period cannot be between this date range." ).format(formatdate(last_processed_pay_slip[0][0]), formatdate(last_processed_pay_slip[0][1])))
def validate_back_dated_allocation(self): future_allocation = dataent.db.sql("""select name, from_date from `tabLeave Allocation` where employee=%s and leave_type=%s and docstatus=1 and from_date > %s and carry_forward=1""", (self.employee, self.leave_type, self.to_date), as_dict=1) if future_allocation: dataent.throw(_("Leave cannot be allocated before {0}, as leave balance has already been carry-forwarded in the future leave allocation record {1}") .format(formatdate(future_allocation[0].from_date), future_allocation[0].name), BackDatedAllocationError)
def validate_days(self): if self.from_date > self.to_date: throw(_("To Date cannot be before From Date")) for day in self.get("holidays"): if not (getdate(self.from_date) <= getdate(day.holiday_date) <= getdate(self.to_date)): dataent.throw( _("The holiday on {0} is not between From Date and To Date" ).format(formatdate(day.holiday_date)))
def get_fiscal_years(transaction_date=None, fiscal_year=None, label="Date", verbose=1, company=None, as_dict=False): fiscal_years = dataent.cache().hget("fiscal_years", company) or [] if not fiscal_years: # if year start date is 2012-04-01, year end date should be 2013-03-31 (hence subdate) cond = "" if fiscal_year: cond += " and fy.name = {0}".format(dataent.db.escape(fiscal_year)) if company: cond += """ and (not exists (select name from `tabFiscal Year Company` fyc where fyc.parent = fy.name) or exists(select company from `tabFiscal Year Company` fyc where fyc.parent = fy.name and fyc.company=%(company)s) ) """ fiscal_years = dataent.db.sql(""" select fy.name, fy.year_start_date, fy.year_end_date from `tabFiscal Year` fy where disabled = 0 {0} order by fy.year_start_date desc""".format(cond), { "company": company }, as_dict=True) dataent.cache().hset("fiscal_years", company, fiscal_years) if transaction_date: transaction_date = getdate(transaction_date) for fy in fiscal_years: matched = False if fiscal_year and fy.name == fiscal_year: matched = True if (transaction_date and getdate(fy.year_start_date) <= transaction_date and getdate(fy.year_end_date) >= transaction_date): matched = True if matched: if as_dict: return (fy,) else: return ((fy.name, fy.year_start_date, fy.year_end_date),) error_msg = _("""{0} {1} not in any active Fiscal Year.""").format(label, formatdate(transaction_date)) if verbose==1: dataent.msgprint(error_msg) raise FiscalYearError(error_msg)
def show_block_day_warning(self): block_dates = get_applicable_block_dates(self.from_date, self.to_date, self.employee, self.company, all_lists=True) if block_dates: dataent.msgprint( _("Warning: Leave application contains following block dates") + ":") for d in block_dates: dataent.msgprint(formatdate(d.block_date) + ": " + d.reason)
def get_label(periodicity, from_date, to_date): if periodicity == "Yearly": if formatdate(from_date, "YYYY") == formatdate(to_date, "YYYY"): label = formatdate(from_date, "YYYY") else: label = formatdate(from_date, "YYYY") + "-" + formatdate( to_date, "YYYY") else: label = formatdate(from_date, "MMM YY") + "-" + formatdate( to_date, "MMM YY") return label
def allocate_pdc_amount_in_fifo(self, gle, row_outstanding): pdc_list = self.pdc_details.get((gle.voucher_no, gle.party), []) pdc_details = [] pdc_amount = 0 for pdc in pdc_list: if row_outstanding <= pdc.pdc_amount: pdc_amount += row_outstanding pdc.pdc_amount -= row_outstanding if row_outstanding and pdc.pdc_ref and pdc.pdc_date: pdc_details.append( cstr(pdc.pdc_ref) + "/" + formatdate(pdc.pdc_date)) row_outstanding = 0 else: pdc_amount = pdc.pdc_amount if pdc.pdc_amount and pdc.pdc_ref and pdc.pdc_date: pdc_details.append( cstr(pdc.pdc_ref) + "/" + formatdate(pdc.pdc_date)) pdc.pdc_amount = 0 row_outstanding -= pdc_amount return pdc_details, pdc_amount
def get_next_sending(self): from_date, to_date = self.get_from_to_date() send_date = to_date + timedelta(days=1) if self.frequency == "Daily": next_send_date = send_date + timedelta(days=1) elif self.frequency == "Weekly": next_send_date = send_date + timedelta(weeks=1) else: next_send_date = send_date + relativedelta(months=1) self.next_send = formatdate(next_send_date) + " at midnight" return send_date
def get_calendar_events(self): """Get calendar events for given user""" from dataent.desk.doctype.event.event import get_events events = get_events(self.future_from_date.strftime("%Y-%m-%d"), self.future_to_date.strftime("%Y-%m-%d")) or [] event_count = 0 for i, e in enumerate(events): e.starts_on_label = format_time(e.starts_on) e.ends_on_label = format_time(e.ends_on) if e.ends_on else None e.date = formatdate(e.starts) e.link = get_url_to_form("Event", e.name) event_count += 1 return events, event_count
def validate_end_of_life(item_code, end_of_life=None, disabled=None, verbose=1): if (not end_of_life) or (disabled is None): end_of_life, disabled = dataent.db.get_value( "Item", item_code, ["end_of_life", "disabled"]) if end_of_life and end_of_life != "0000-00-00" and getdate( end_of_life) <= now_datetime().date(): msg = _("Item {0} has reached its end of life on {1}").format( item_code, formatdate(end_of_life)) _msgprint(msg, verbose) if disabled: _msgprint(_("Item {0} is disabled").format(item_code), verbose)
def get_employee_field_property(employee, fieldname): if employee and fieldname: field = dataent.get_meta("Employee").get_field(fieldname) value = dataent.db.get_value("Employee", employee, fieldname) options = field.options if field.fieldtype == "Date": value = formatdate(value) elif field.fieldtype == "Datetime": value = format_datetime(value) return { "value": value, "datatype": field.fieldtype, "label": field.label, "options": options } else: return False
def get_link_quotation(supplier, rfq): quotation = dataent.db.sql( """ select distinct `tabSupplier Quotation Item`.parent as name, `tabSupplier Quotation`.status, `tabSupplier Quotation`.transaction_date from `tabSupplier Quotation Item`, `tabSupplier Quotation` where `tabSupplier Quotation`.docstatus < 2 and `tabSupplier Quotation Item`.request_for_quotation =%(name)s and `tabSupplier Quotation Item`.parent = `tabSupplier Quotation`.name and `tabSupplier Quotation`.supplier = %(supplier)s order by `tabSupplier Quotation`.creation desc""", { 'name': rfq, 'supplier': supplier }, as_dict=1) for data in quotation: data.transaction_date = formatdate(data.transaction_date) return quotation or None
def update_company_current_month_sales(company): current_month_year = formatdate(today(), "MM-yyyy") results = dataent.db.sql(''' select sum(base_grand_total) as total, date_format(posting_date, '%m-%Y') as month_year from `tabSales Invoice` where date_format(posting_date, '%m-%Y')="{0}" and docstatus = 1 and company = "{1}" group by month_year '''.format(current_month_year, dataent.db.escape(company)), as_dict = True) monthly_total = results[0]['total'] if len(results) > 0 else 0 dataent.db.set_value("Company", company, "total_monthly_sales", monthly_total)
def prepare_row_without_payment_terms(self, party_naming_by, args, gle, outstanding_amount, credit_note_amount): pdc_list = self.pdc_details.get((gle.voucher_no, gle.party), []) pdc_amount = 0 pdc_details = [] for d in pdc_list: pdc_amount += flt(d.pdc_amount) if pdc_amount and d.pdc_ref and d.pdc_date: pdc_details.append( cstr(d.pdc_ref) + "/" + formatdate(d.pdc_date)) row = self.prepare_row(party_naming_by, args, gle, outstanding_amount, credit_note_amount, pdc_amount=pdc_amount, pdc_details=pdc_details) return row
def validate_optional_leave(self): leave_period = get_leave_period(self.from_date, self.to_date, self.company) if not leave_period: dataent.throw(_("Cannot find active Leave Period")) optional_holiday_list = dataent.db.get_value("Leave Period", leave_period[0]["name"], "optional_holiday_list") if not optional_holiday_list: dataent.throw( _("Optional Holiday List not set for leave period {0}").format( leave_period[0]["name"])) day = getdate(self.from_date) while day <= getdate(self.to_date): if not dataent.db.exists({ "doctype": "Holiday", "parent": optional_holiday_list, "holiday_date": day }): dataent.throw( _("{0} is not in Optional Holiday List").format( formatdate(day)), NotAnOptionalHoliday) day = add_days(day, 1)