def create_remarks(self): r = [] if self.cheque_no: if self.cheque_date: r.append(_('Reference #{0} dated {1}').format(self.cheque_no, formatdate(self.cheque_date))) else: msgprint(_("Please enter Reference date"), raise_exception=1) for d in self.get('entries'): if d.against_invoice and d.credit: currency = frappe.db.get_value("Sales Invoice", d.against_invoice, "currency") r.append(_("{0} {1} against Invoice {1}").format(currency, fmt_money(flt(d.credit)), d.against_invoice)) if d.against_voucher and d.debit: bill_no = frappe.db.sql("""select bill_no, bill_date, currency from `tabPurchase Invoice` where name=%s""", d.against_voucher) if bill_no and bill_no[0][0] and bill_no[0][0].lower().strip() \ not in ['na', 'not applicable', 'none']: r.append(_('{0} {1} against Bill {2} dated {3}').format(bill_no[0][2], fmt_money(flt(d.debit)), bill_no[0][0], bill_no[0][1] and formatdate(bill_no[0][1].strftime('%Y-%m-%d')))) if self.user_remark: r.append(_("Note: {0}").format(self.user_remark)) if r: self.remark = ("\n").join(r) else: frappe.msgprint(_("User Remarks is mandatory"), raise_exception=1)
def validate_salary_processed_days(self): last_processed_pay_slip = frappe.db.sql("""select start_date, end_date from `tabSalary Slip` where docstatus != 2 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: frappe.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 get_msg_html(self, out, send_only_if_updates=True): with_value = [o[1] for o in out if o[0]] if with_value: has_updates = True with_value = "\n".join(with_value) else: has_updates = False with_value = "<p>" + _("There were no updates in the items selected for this digest.") + "</p><hr>" if not has_updates and send_only_if_updates: return # seperate out no value items no_value = [o[1] for o in out if not o[0]] if no_value: no_value = """<h4>""" + _("No Updates For") + """:</h4>""" + "\n".join(no_value) date = self.frequency == "Daily" and formatdate(self.from_date) or \ "%s to %s" % (formatdate(self.from_date), formatdate(self.to_date)) msg = digest_template % { "digest": self.frequency + " Digest", "date": date, "company": self.company, "with_value": with_value, "no_value": no_value or "", "name": self.name } return msg
def get_columns(filters): columns = [_(filters.get("budget_against")) + ":Link/%s:80"%(filters.get("budget_against")), _("Account") + ":Link/Account:80"] 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:80") 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:80") if filters["period"] != "Yearly" : return columns + [_("Total Budget") + ":Float:80", _("Total Actual") + ":Float:80", _("Total Variance") + ":Float:80"] else: return columns
def validate_filters(filters): filters.year_start_date, filters.year_end_date = frappe.db.get_value("Fiscal Year", filters.fiscal_year, ["year_start_date", "year_end_date"]) filters.year_start_date = getdate(filters.year_start_date) filters.year_end_date = getdate(filters.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: frappe.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): frappe.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): frappe.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 create_remarks(self): r = [] if self.cheque_no: if self.cheque_date: r.append(_('Reference #{0} dated {1}').format(self.cheque_no, formatdate(self.cheque_date))) else: msgprint(_("Please enter Reference date"), raise_exception=frappe.MandatoryError) for d in self.get('accounts'): if d.reference_type=="Sales Invoice" and d.credit: r.append(_("{0} against Sales Invoice {1}").format(fmt_money(flt(d.credit), currency = self.company_currency), \ d.reference_name)) if d.reference_type=="Sales Order" and d.credit: r.append(_("{0} against Sales Order {1}").format(fmt_money(flt(d.credit), currency = self.company_currency), \ d.reference_name)) if d.reference_type == "Purchase Invoice" and d.debit: bill_no = frappe.db.sql("""select bill_no, bill_date from `tabPurchase Invoice` where name=%s""", d.reference_name) if bill_no and bill_no[0][0] and bill_no[0][0].lower().strip() \ not in ['na', 'not applicable', 'none']: r.append(_('{0} against Bill {1} dated {2}').format(fmt_money(flt(d.debit), currency=self.company_currency), bill_no[0][0], bill_no[0][1] and formatdate(bill_no[0][1].strftime('%Y-%m-%d')))) if d.reference_type == "Purchase Order" and d.debit: r.append(_("{0} against Purchase Order {1}").format(fmt_money(flt(d.credit), currency = self.company_currency), \ d.reference_name)) if self.user_remark: r.append(_("Note: {0}").format(self.user_remark)) if r: self.remark = ("\n").join(r) #User Remarks is not mandatory
def validate_filters(filters): if not filters.fiscal_year: frappe.throw(_("Fiscal Year {0} is required").format(filters.fiscal_year)) fiscal_year = frappe.db.get_value("Fiscal Year", filters.fiscal_year, ["year_start_date", "year_end_date"], as_dict=True) if not fiscal_year: frappe.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: frappe.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): frappe.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): frappe.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_leave_application(doc, method): year_start_date, year_end_date = get_fiscal_year_dates(doc.fiscal_year) from_date = getdate(doc.from_date) to_date = getdate(doc.to_date) if not (year_start_date <= from_date <= to_date <= year_end_date): throw(_("From Date and To Date should be within the selected Fiscal Year's period: {0} to {1}").format( formatdate(year_start_date), formatdate(year_end_date)), LeaveApplicationPeriodError)
def create_remarks(self): r = [] if self.cheque_no: if self.cheque_date: r.append(_("Reference #{0} dated {1}").format(self.cheque_no, formatdate(self.cheque_date))) else: msgprint(_("Please enter Reference date"), raise_exception=frappe.MandatoryError) for d in self.get("entries"): if d.against_invoice and d.credit: currency = frappe.db.get_value("Sales Invoice", d.against_invoice, "currency") r.append( _("{0} against Sales Invoice {1}").format( fmt_money(flt(d.credit), currency=currency), d.against_invoice ) ) if d.against_sales_order and d.credit: currency = frappe.db.get_value("Sales Order", d.against_sales_order, "currency") r.append( _("{0} against Sales Order {1}").format( fmt_money(flt(d.credit), currency=currency), d.against_sales_order ) ) if d.against_voucher and d.debit: bill_no = frappe.db.sql( """select bill_no, bill_date, currency from `tabPurchase Invoice` where name=%s""", d.against_voucher, ) if bill_no and bill_no[0][0] and bill_no[0][0].lower().strip() not in ["na", "not applicable", "none"]: r.append( _("{0} {1} against Bill {2} dated {3}").format( bill_no[0][2], fmt_money(flt(d.debit)), bill_no[0][0], bill_no[0][1] and formatdate(bill_no[0][1].strftime("%Y-%m-%d")), ) ) if d.against_purchase_order and d.debit: currency = frappe.db.get_value("Purchase Order", d.against_purchase_order, "currency") r.append( _("{0} against Purchase Order {1}").format( fmt_money(flt(d.credit), currency=currency), d.against_purchase_order ) ) if self.user_remark: r.append(_("Note: {0}").format(self.user_remark)) if r: self.remark = ("\n").join(r) # User Remarks is not mandatory
def check_reference_date(self): if self.cheque_date: for d in self.get("entries"): due_date = None if d.against_invoice and flt(d.credit) > 0: due_date = frappe.db.get_value("Sales Invoice", d.against_invoice, "due_date") elif d.against_voucher and flt(d.debit) > 0: due_date = frappe.db.get_value("Purchase Invoice", d.against_voucher, "due_date") if due_date and getdate(self.cheque_date) > getdate(due_date): msgprint(_("Note: Reference Date {0} is after invoice due date {1}") .format(formatdate(self.cheque_date), formatdate(due_date)))
def validate_allocation_overlap(self): leave_allocation = frappe.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: frappe.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))) frappe.throw(_('Reference') + ': <a href="#Form/Leave Allocation/{0}">{0}</a>' .format(leave_allocation[0][0]), OverlapError)
def get_label(periodicity,to_date): if periodicity=="Yearly": months_to_add=-11 elif periodicity=="Half-yearly": months_to_add=-5 elif periodicity=="Quarterly": months_to_add=-2 from_date = add_months(to_date, months_to_add) if periodicity=="Yearly": label = formatdate(from_date, "YYYY")+"-"+formatdate(to_date, "YYYY") else: label = from_date.strftime("%b")+"-"+formatdate(to_date, "MMM YYYY") return label
def format_value(value, df, doc=None, currency=None): # Convert dict to object if necessary if (isinstance(df, dict)): df = frappe._dict(df) if df.get("fieldtype")=="Date": return formatdate(value) elif df.get("fieldtype") == "Currency" or (df.get("fieldtype")=="Float" and (df.options or "").strip()): return fmt_money(value, precision=get_field_precision(df, doc), currency=currency if currency else (get_field_currency(df, doc) if doc else None)) elif df.get("fieldtype") == "Float": precision = get_field_precision(df, doc) # show 1.000000 as 1 # options should not specified if not df.options and value is not None: temp = cstr(value).split(".") if len(temp)==1 or cint(temp[1])==0: precision = 0 return fmt_money(value, precision=precision) elif df.get("fieldtype") == "Percent": return "{}%".format(flt(value, 2)) if value is None: value = "" if df.get("fieldtype") in ("Text", "Small Text"): if not re.search("(\<br|\<div|\<p)", value): return value.replace("\n", "<br>") return value
def validate_fiscal_year(date, fiscal_year, label=_("Date"), doc=None): years = [f[0] for f in get_fiscal_years(date, label=label)] 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 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 (self.from_date <= day.holiday_date <= self.to_date): frappe.throw(_("The holiday on {0} is not between From Date and To Date").format(formatdate(day.holiday_date)))
def get_summary_message(self): '''Return summary of replies as HTML''' settings = frappe.get_doc('Daily Work Summary Settings') replies = frappe.get_all('Communication', fields=['content', 'text_content', 'sender'], filters=dict(reference_doctype=self.doctype, reference_name=self.name, communication_type='Communication', sent_or_received='Received'), order_by='creation asc') did_not_reply = self.email_sent_to.split() for d in replies: d.sender_name = frappe.db.get_value("Employee", {"user_id": d.sender}, "employee_name") or d.sender if d.sender in did_not_reply: did_not_reply.remove(d.sender) if d.text_content: d.content = markdown(EmailReplyParser.parse_reply(d.text_content)) did_not_reply = [(frappe.db.get_value("Employee", {"user_id": email}, "employee_name") or email) for email in did_not_reply] return frappe.render_template(self.get_summary_template(), dict(replies=replies, original_message=settings.message, title=_('Daily Work Summary for {0}'.format(formatdate(self.creation))), did_not_reply= ', '.join(did_not_reply) or '', did_not_reply_title = _('No replies from')))
def datetime_in_user_format(date_time): if not date_time: return "" if isinstance(date_time, basestring): date_time = get_datetime(date_time) from frappe.utils import formatdate return formatdate(date_time.date()) + " " + date_time.strftime("%H:%M")
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 get_fiscal_years(transaction_date=None, fiscal_year=None, label="Date", verbose=1, company=None, as_dict=False): # if year start date is 2012-04-01, year end date should be 2013-03-31 (hence subdate) cond = " disabled = 0" if fiscal_year: cond += " and fy.name = %(fiscal_year)s" else: cond += " and %(transaction_date)s >= fy.year_start_date and %(transaction_date)s <= fy.year_end_date" 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 ))""" fy = frappe.db.sql( """select fy.name, fy.year_start_date, fy.year_end_date from `tabFiscal Year` fy where %s order by fy.year_start_date desc""" % cond, {"fiscal_year": fiscal_year, "transaction_date": transaction_date, "company": company}, as_dict=as_dict, ) if not fy: error_msg = _("""{0} {1} not in any active Fiscal Year. For more details check {2}.""").format( label, formatdate(transaction_date), "https://frappe.github.io/erpnext/user/manual/en/accounts/articles/fiscal-year-error", ) if verbose == 1: frappe.msgprint(error_msg) raise FiscalYearError, error_msg return fy
def validate_leave_overlap(self): if not self.name: self.name = "New Leave Application" for d in frappe.db.sql( """select name, leave_type, posting_date, from_date, to_date from `tabLeave Application` where employee = %(employee)s and docstatus < 2 and status in ("Open", "Approved") and (from_date between %(from_date)s and %(to_date)s or to_date between %(from_date)s and %(to_date)s or %(from_date)s between from_date and to_date) and name != %(name)s""", {"employee": self.employee, "from_date": self.from_date, "to_date": self.to_date, "name": self.name}, as_dict=1, ): frappe.msgprint( _("Employee {0} has already applied for {1} between {2} and {3}").format( self.employee, cstr(d["leave_type"]), formatdate(d["from_date"]), formatdate(d["to_date"]) ) ) frappe.throw('<a href="#Form/Leave Application/{0}">{0}</a>'.format(d["name"]), OverlapError)
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 validate_end_of_life(item_code, end_of_life=None, verbose=1): if not end_of_life: end_of_life = frappe.db.get_value("Item", item_code, "end_of_life") 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)
def convert_to_simple_type(self, v, formatted=0): """Format date, time, longint values.""" return v from frappe.utils import formatdate, fmt_money if isinstance(v, (datetime.date, datetime.timedelta, datetime.datetime, long)): if isinstance(v, datetime.date): v = unicode(v) if formatted: v = formatdate(v) # time elif isinstance(v, (datetime.timedelta, datetime.datetime)): v = unicode(v) # long elif isinstance(v, long): v=int(v) # convert to strings... (if formatted) if formatted: if isinstance(v, float): v=fmt_money(v) elif isinstance(v, int): v = unicode(v) return v
def get_columns(filters): columns = [_("Cost Center") + ":Link/Cost Center:120", _("Account") + ":Link/Account:120"] group_months = False if filters["period"] == "Monthly" else True for from_date, to_date in get_period_date_ranges(filters["period"], filters["fiscal_year"]): for label in [_("Target") + " (%s)", _("Actual") + " (%s)", _("Variance") + " (%s)"]: 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:120") return columns + [_("Total Target") + ":Float:120", _("Total Actual") + ":Float:120", _("Total Variance") + ":Float:120"]
def get_transaction_list(doctype, start, additional_fields=None): # find customer id customer = frappe.db.get_value("Contact", {"email_id": frappe.session.user}, "customer") if customer: if additional_fields: additional_fields = ", " + ", ".join(("`%s`" % f for f in additional_fields)) else: additional_fields = "" transactions = frappe.db.sql("""select name, creation, currency, grand_total_export %s from `tab%s` where customer=%s and docstatus=1 order by creation desc limit %s, 20""" % (additional_fields, doctype, "%s", "%s"), (customer, cint(start)), as_dict=True) for doc in transactions: items = frappe.db.sql_list("""select item_name from `tab%s Item` where parent=%s limit 6""" % (doctype, "%s"), doc.name) doc.items = ", ".join(items[:5]) + ("..." if (len(items) > 5) else "") doc.creation = formatdate(doc.creation) return transactions else: return []
def set_actual_qty(self): allow_negative_stock = cint(frappe.db.get_value("Stock Settings", None, "allow_negative_stock")) for d in self.get("items"): previous_sle = get_previous_sle( { "item_code": d.item_code, "warehouse": d.s_warehouse or d.t_warehouse, "posting_date": self.posting_date, "posting_time": self.posting_time, } ) # get actual stock at source warehouse d.actual_qty = previous_sle.get("qty_after_transaction") or 0 # validate qty during submit if d.docstatus == 1 and d.s_warehouse and not allow_negative_stock and d.actual_qty < d.transfer_qty: frappe.throw( _( "Row {0}: Qty not available for {4} in warehouse {1} at posting time of the entry ({2} {3})".format( d.idx, frappe.bold(d.s_warehouse), formatdate(self.posting_date), format_time(self.posting_time), frappe.bold(d.item_code), ) ) + "<br><br>" + _("Available qty is {0}, you need {1}").format( frappe.bold(d.actual_qty), frappe.bold(d.transfer_qty) ), NegativeStockError, title=_("Insufficient Stock"), )
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: frappe.msgprint(_("Warning: Leave application contains following block dates") + ":") for d in block_dates: frappe.msgprint(formatdate(d.block_date) + ": " + d.reason)
def validate_back_dated_application(self): future_allocation = frappe.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: frappe.throw(_("Leave cannot be applied/cancelled 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))
def get_tickets(start=0): tickets = frappe.db.sql("""select name, subject, status, creation from `tabIssue` where raised_by=%s order by modified desc limit %s, 20""", (frappe.session.user, cint(start)), as_dict=True) for t in tickets: t.creation = formatdate(t.creation) return tickets
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 = frappe.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_fiscal_years(transaction_date=None, fiscal_year=None, label="Date", verbose=1, company=None, as_dict=False): fiscal_years = frappe.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(frappe.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 = frappe.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) frappe.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: frappe.msgprint(error_msg) raise FiscalYearError(error_msg)
def test_formatdate_forced(self): # Test with forced date formats self.assertEqual(formatdate(test_date, 'dd-yyyy-mm'), test_date_obj.strftime('%d-%Y-%m')) self.assertEqual(formatdate(test_date, 'dd-yyyy-MM'), test_date_obj.strftime('%d-%Y-%m'))
def senddailytask(allow_guest=True): projects = frappe.db.get_list( "Project", fields=['project_name', 'status', 'name', 'priority'], filters={'status': "Open"}, limit_page_length=200) for x in projects: opentasks = frappe.db.get_list("Task", fields=['name'], filters={ 'project': x.name, 'status': ["!=", "Closed"] }, limit_page_length=200) if opentasks: x.opentasks = len(opentasks) else: x.opentasks = 0 closedtasks = frappe.db.get_list("Task", fields=['name'], filters={ 'project': x.name, 'status': 'Closed' }, limit_page_length=200) if closedtasks: x.closedtasks = len(closedtasks) else: x.closedtasks = 0 openbugs = frappe.db.get_list("Bug Sheet", fields=['name'], filters={ 'project': x.name, 'status': ["in", "Closed"] }, limit_page_length=200) if openbugs: x.openbugs = len(openbugs) else: x.openbugs = 0 closedbugs = frappe.db.get_list("Bug Sheet", fields=['name'], filters={ 'project': x.name, 'status': 'Closed' }, limit_page_length=200) if closedbugs: x.closedbugs = len(closedbugs) else: x.closedbugs = 0 table = '<table cellpadding="5" style="border-collapse: collapse;" border="1"><tr><th>Project Name</th><th>Open Tasks</th><th>Closed Tasks</th><th>Open Bugs</th><th>Closed Bugs</th></tr>' for y in projects: table = table + '<tr><td>' + str(y.project_name) + '</td><td>' + str( y.opentasks) + '</td><td>' + str( y.closedtasks) + '</td><td>' + str( y.openbugs) + '</td><td>' + str( y.closedbugs) + '</td></tr>' table = table + '</table>' data = 'Daily Project summary @ ' + formatdate(nowdate(), "dd-MM-yyyy") frappe.sendmail(recipients=['*****@*****.**'], sender="Testing Valiant2 <*****@*****.**>", message=table, subject=data) return None
def throw_overlap_error(doc, exists_for, overlap_doc, from_date, to_date): msg = (_("A {0} exists between {1} and {2} (").format( doc.doctype, formatdate(from_date), formatdate(to_date)) + """ <b><a href="/app/Form/{0}/{1}">{1}</a></b>""".format( doc.doctype, overlap_doc) + _(") for {0}").format(exists_for)) frappe.throw(msg)
def throw_overlap_error(self, d): msg = _("Employee {0} has already applied for {1} between {2} and {3} : ").format(self.employee, d['leave_type'], formatdate(d['from_date']), formatdate(d['to_date'])) \ + """ <b><a href="#Form/Leave Application/{0}">{0}</a></b>""".format(d["name"]) frappe.throw(msg, OverlapError)
def get_monthly_goal_graph_data(title, doctype, docname, goal_value_field, goal_total_field, goal_history_field, goal_doctype, goal_doctype_link, goal_field, date_field, filter_str, aggregation="sum"): ''' Get month-wise graph data for a doctype based on aggregation values of a field in the goal doctype :param title: Graph title :param doctype: doctype of graph doc :param docname: of the doc to set the graph in :param goal_value_field: goal field of doctype :param goal_total_field: current month value field of doctype :param goal_history_field: cached history field :param goal_doctype: doctype the goal is based on :param goal_doctype_link: doctype link field in goal_doctype :param goal_field: field from which the goal is calculated :param filter_str: where clause condition :param aggregation: a value like 'count', 'sum', 'avg' :return: dict of graph data ''' from frappe.utils.formatters import format_value import json meta = frappe.get_meta(doctype) doc = frappe.get_doc(doctype, docname) goal = doc.get(goal_value_field) formatted_goal = format_value(goal, meta.get_field(goal_value_field), doc) current_month_value = doc.get(goal_total_field) formatted_value = format_value(current_month_value, meta.get_field(goal_total_field), doc) from frappe.utils import today, getdate, formatdate, add_months current_month_year = formatdate(today(), "MM-yyyy") history = doc.get(goal_history_field) try: month_to_value_dict = json.loads( history) if history and '{' in history else None except ValueError: month_to_value_dict = None if month_to_value_dict is None: doc_filter = (goal_doctype_link + ' = "' + docname + '"') if doctype != goal_doctype else '' if filter_str: doc_filter += ' and ' + filter_str if doc_filter else filter_str month_to_value_dict = get_monthly_results(goal_doctype, goal_field, date_field, doc_filter, aggregation) frappe.db.set_value(doctype, docname, goal_history_field, json.dumps(month_to_value_dict)) month_to_value_dict[current_month_year] = current_month_value months = [] values = [] for i in xrange(0, 12): month_value = formatdate(add_months(today(), -i), "MM-yyyy") month_word = getdate(month_value).strftime('%b') months.insert(0, month_word) if month_value in month_to_value_dict: values.insert(0, month_to_value_dict[month_value]) else: values.insert(0, 0) specific_values = [] summary_values = [{ 'name': "This month", 'color': 'green', 'value': formatted_value }] if float(goal) > 0: specific_values = [ { 'name': "Goal", 'line_type': "dashed", 'value': goal }, ] summary_values += [{ 'name': "Goal", 'color': 'blue', 'value': formatted_goal }, { 'name': "Completed", 'color': 'green', 'value': str(int(round(float(current_month_value) / float(goal) * 100))) + "%" }] data = { 'title': title, # 'subtitle': 'y_values': values, 'x_points': months, 'specific_values': specific_values, 'summary_values': summary_values } return data
def throw_overlap_error(self, d): msg = _("Employee {0} has already applied for {1} on {2} : ").format(self.employee, d['shift_type'], formatdate(d['date'])) \ + """ <b><a href="#Form/Shift Assignment/{0}">{0}</a></b>""".format(d["name"]) frappe.throw(msg, OverlapError)
except Exception, e: if frappe.message_log: frappe.message_log.pop() return 0, 0 #print page if page.status_code == 200: #Json reading num = 0 registo = page.json() for reg in page.json()['items']: #for reg in registo.keys(): print reg['id'] #print registo['items'][num] #print registo['items'][num]['contractid'] print formatdate(reg['creationdate'], "dd-MM-YYYY") #Deve filtrar somente os dados do DIA CORRENTE # # Id int `json:"id"` # Contractid int `json:"contractid"` # Code string `json:"code"` # Amount float64 `json:"amount"` # Description string `json:"description"` # Creationdate time.Time `json:"creationdate"` # Relatedcontractcode string `json:"relatedcontract"` #id user_id contract_id code amount description deleted creation_date cancelable is_fired related_contract_code fees is_exported savings_method pending pending_event_id teller_id loan_event_id cancel_date doc1 parent_event_id #1 1 1 SVDE 10000.0000 Initial deposit False 2017-06-22 10:58:21.110 True True NULL NULL False 1 False NULL NULL NULL NULL NULL NULL #SAVING EVENTS GetbyID
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 frappe.utils import today, formatdate self.assertEqual(result_dict.get(formatdate(today(), "MM-yyyy")), 2)
def check_freezing_date(posting_date, adv_adj=False): """ Nobody can do GL Entries where posting date is before freezing date except authorized person """ if not adv_adj: acc_frozen_upto = frappe.db.get_value('Accounts Settings', None, 'acc_frozen_upto') if acc_frozen_upto: frozen_accounts_modifier = frappe.db.get_value( 'Accounts Settings', None,'frozen_accounts_modifier') if getdate(posting_date) <= getdate(acc_frozen_upto) \ and not frozen_accounts_modifier in frappe.get_roles(): frappe.throw(_("You are not authorized to add or update entries before {0}").format(formatdate(acc_frozen_upto)))
def check_freezing_date(posting_date, adv_adj=False): """ Nobody can do GL Entries where posting date is before freezing date except authorized person Administrator has all the roles so this check will be bypassed if any role is allowed to post Hence stop admin to bypass if accounts are freezed """ if not adv_adj: acc_frozen_upto = frappe.db.get_value('Accounts Settings', None, 'acc_frozen_upto') if acc_frozen_upto: frozen_accounts_modifier = frappe.db.get_value( 'Accounts Settings', None,'frozen_accounts_modifier') if getdate(posting_date) <= getdate(acc_frozen_upto) \ and (frozen_accounts_modifier not in frappe.get_roles() or frappe.session.user == 'Administrator'): frappe.throw(_("You are not authorized to add or update entries before {0}").format(formatdate(acc_frozen_upto)))
def senddailytimesheet(allow_guest=True): google = '<div style="border: 1px solid black; "> <img src="https://cdn-images-1.medium.com/max/1200/0*pAdZLfSqNrMZAAPA.jpg" \ alt="Avatar" style="width:70px; border-radius: 50%; float:left; padding-right: 23px; padding-left: 14px; padding-top: 8px;"> \ <h4><b>John Doe</b></h4> <p>Architect & Engineer</p> </div><div style="border: 1px solid black;"> \ <div class="m_8588087096502089317header-section" style="box-sizing:border-box;margin:0;padding:0">\ <div class="m_8588087096502089317logo-container" style="box-sizing:border-box;text-align:left;display:inline-block;width:40%;margin:0; padding-left: 45px" align="left">\ <p style="box-sizing:border-box;font-weight:normal;line-height:1.6;font-size:20px;color:#4a4a4c;margin:0 0 13.33333px;padding:0">\ <strong style="box-sizing:border-box;margin:0;padding:0"><span style="text-transform:uppercase;color:#141c3a;box-sizing:border-box;margin:0;padding:0">Task Title</span>\ </strong></p> </div> <div class="m_8588087096502089317newsletter-info" style="margin-left: 15px !important; box-sizing:border-box;float:right;text-align:right;margin:0;" align="right">\ <p style="background-color: #e44646; box-sizing:border-box;font-weight:normal;line-height:1.6;font-size:14px;color:#4a4a4c;margin:0 0 13.33333px;padding:5px;"><strong style="box-sizing:border-box;margin:0;padding:0"><span style="text-transform:uppercase;color:#141c3a;box-sizing:border-box;margin:0;padding:0">Status</span></strong></p> </div> <div class="m_8588087096502089317newsletter-info" style="box-sizing:border-box;float:right;text-align:right;margin:0;" align="right"> <p style="background-color: #e44646; box-sizing:border-box;font-weight:normal;line-height:1.6;font-size:14px;color:#4a4a4c;margin:0 0 13.33333px;padding:5px;"><strong style="box-sizing:border-box;margin:0;padding:0"><span style="text-transform:uppercase;color:#141c3a;box-sizing:border-box;margin:0;padding:0">Status</span></strong></p> </div> </div><div id="m_8588087096502089317main-story-2" style="box-sizing:border-box;margin:0;padding:0px 48px"> <p style="box-sizing:border-box;font-weight:normal;line-height:1.6;font-size:14px;color:#4a4a4c;margin:0 0 13.33333px;padding:0">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p> </div> </div><div style="border: 1px solid black;"> <h3 style="text-align: right; margin-right: 20px;">Total Working Hours : 9</h3> </div> </div>' Employee = frappe.db.get_list("Employee", fields=['employee_name', 'name'], filters={'status': "Active"}, limit_page_length=200) table = '<table cellpadding="5" style="border-collapse: collapse;" border="1"><tr><th>Employee Name</th><th>Project</th><th>Task</th><th>Task Description</th><th>status</th><th>Total Hours</th></tr>' for x in Employee: x.Timesheet = frappe.db.get_list("Timesheet", fields=['name', 'total_hours'], filters={ 'employee': x.name, 'start_date': ["=", nowdate()] }, limit_page_length=200) for y in x.Timesheet: y.tasks = frappe.db.get_list("Timesheet Detail", fields=[ 'name', 'project', 'task', 'hours', 'from_time', 'to_time' ], filters={'parent': y.name}, limit_page_length=200) for q in y.tasks: q.tasks_details = frappe.db.get_list("Task", fields=[ 'subject', 'status', 'priority', 'description', 'name', 'project' ], filters={'name': q.task}, limit_page_length=200) for e in Employee: tar = '' for x in e.Timesheet: for y in x.tasks: if y.tasks_details[0].description: va = y.tasks_details[0].description else: va = "none" if tar == '': table += "<tr><td>"+str(e.employee_name)+"</td><td>"+y.tasks_details[0].project+"</td><td>"+str(y.tasks_details[0].subject)+"</td><td>"\ +str(va)+"</td><td>"+y.tasks_details[0].status+"</td><td>"+str(y.hours)+"</td></tr>" tar = e.employee_name else: table += "<tr><td></td><td>"+y.tasks_details[0].project+"</td><td>"+str(y.tasks_details[0].subject)+"</td><td>"\ +str(va)+"</td><td>"+y.tasks_details[0].status+"</td><td>"+str(y.hours)+"</td></tr>" table += "</table>" data = 'Daily task summary @ ' + formatdate(nowdate(), "dd-MM-yyyy") frappe.sendmail(recipients=['*****@*****.**'], sender="Testing Valiant2 <*****@*****.**>", message=google, subject=data) return Employee
def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_values=False, company=None, reset_period_on_fy_change=True): """Get a list of dict {"from_date": from_date, "to_date": to_date, "key": key, "label": label} Periodicity can be (Yearly, Quarterly, Monthly)""" fiscal_year = get_fiscal_year_data(from_fiscal_year, to_fiscal_year) validate_fiscal_year(fiscal_year, from_fiscal_year, to_fiscal_year) # start with first day, so as to avoid year to_dates like 2-April if ever they occur] year_start_date = getdate(fiscal_year.year_start_date) year_end_date = getdate(fiscal_year.year_end_date) months_to_add = { "Yearly": 12, "Half-Yearly": 6, "Quarterly": 3, "Monthly": 1 }[periodicity] period_list = [] start_date = year_start_date months = get_months(year_start_date, year_end_date) for i in xrange(months / months_to_add): period = frappe._dict({ "from_date": start_date }) to_date = add_months(start_date, months_to_add) start_date = to_date if to_date == get_first_day(to_date): # if to_date is the first day, get the last day of previous month to_date = add_days(to_date, -1) if to_date <= year_end_date: # the normal case period.to_date = to_date else: # if a fiscal year ends before a 12 month period period.to_date = year_end_date period.to_date_fiscal_year = get_fiscal_year(period.to_date, company=company)[0] period.from_date_fiscal_year_start_date = get_fiscal_year(period.from_date, company=company)[1] period_list.append(period) if period.to_date == year_end_date: break # common processing for opts in period_list: key = opts["to_date"].strftime("%b_%Y").lower() if periodicity == "Monthly" and not accumulated_values: label = formatdate(opts["to_date"], "MMM YYYY") else: if not accumulated_values: label = get_label(periodicity, opts["from_date"], opts["to_date"]) else: if reset_period_on_fy_change: label = get_label(periodicity, opts.from_date_fiscal_year_start_date, opts["to_date"]) else: label = get_label(periodicity, period_list[0].from_date, opts["to_date"]) opts.update({ "key": key.replace(" ", "_").replace("-", "_"), "label": label, "year_start_date": year_start_date, "year_end_date": year_end_date }) return period_list
def get_columns(filters): return [{ "label": _("Asset Category"), "fieldname": "asset_category", "fieldtype": "Link", "options": "Asset Category", "width": 120 }, { "label": _("Cost as on") + " " + formatdate(filters.day_before_from_date), "fieldname": "cost_as_on_from_date", "fieldtype": "Currency", "width": 140 }, { "label": _("Cost of New Purchase"), "fieldname": "cost_of_new_purchase", "fieldtype": "Currency", "width": 140 }, { "label": _("Cost of Sold Asset"), "fieldname": "cost_of_sold_asset", "fieldtype": "Currency", "width": 140 }, { "label": _("Cost of Scrapped Asset"), "fieldname": "cost_of_scrapped_asset", "fieldtype": "Currency", "width": 140 }, { "label": _("Cost as on") + " " + formatdate(filters.to_date), "fieldname": "cost_as_on_to_date", "fieldtype": "Currency", "width": 140 }, { "label": _("Accumulated Depreciation as on") + " " + formatdate(filters.day_before_from_date), "fieldname": "accumulated_depreciation_as_on_from_date", "fieldtype": "Currency", "width": 270 }, { "label": _("Depreciation Amount during the period"), "fieldname": "depreciation_amount_during_the_period", "fieldtype": "Currency", "width": 240 }, { "label": _("Depreciation Eliminated due to disposal of assets"), "fieldname": "depreciation_eliminated_during_the_period", "fieldtype": "Currency", "width": 300 }, { "label": _("Accumulated Depreciation as on") + " " + formatdate(filters.to_date), "fieldname": "accumulated_depreciation_as_on_to_date", "fieldtype": "Currency", "width": 270 }, { "label": _("Net Asset value as on") + " " + formatdate(filters.day_before_from_date), "fieldname": "net_asset_value_as_on_from_date", "fieldtype": "Currency", "width": 200 }, { "label": _("Net Asset value as on") + " " + formatdate(filters.to_date), "fieldname": "net_asset_value_as_on_to_date", "fieldtype": "Currency", "width": 200 }]
def create_checkin(self): emp = frappe.get_doc("Employee", self.employee) if not emp.default_shift: frappe.throw(_("""Employee should to have Default Shift""")) shift = frappe.get_doc("Shift Type", emp.default_shift) if self.enable_two_period_in_ecr == 1: if self.period_type == 'First': if self.log_type == 'ALL': ec = frappe.get_doc( frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "IN", "time": get_datetime( formatdate(self.date, 'YYYY-mm-dd') + ' ' + format_time(shift.start_time)), "employee_checkin_request": self.name })) ec.insert() ec = frappe.get_doc( frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "OUT", "time": get_datetime( formatdate(self.date, 'YYYY-mm-dd') + ' ' + format_time(shift.end_first_period)), "employee_checkin_request": self.name })) ec.insert() else: ec = frappe.get_doc( frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": self.log_type, "time": get_datetime( formatdate(self.date, 'YYYY-mm-dd') + ' ' + format_time( shift.start_time if self.log_type == 'IN' else shift.end_first_period)), "employee_checkin_request": self.name })) ec.insert() elif self.period_type == 'Second': if self.log_type == 'ALL': ec = frappe.get_doc( frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "IN", "time": get_datetime( formatdate(self.date, 'YYYY-mm-dd') + ' ' + format_time(shift.start_second_period)), "employee_checkin_request": self.name })) ec.insert() ec = frappe.get_doc( frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "OUT", "time": get_datetime( formatdate(self.date, 'YYYY-mm-dd') + ' ' + format_time(shift.end_time)), "employee_checkin_request": self.name })) ec.insert() else: ec = frappe.get_doc( frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": self.log_type, "time": get_datetime( formatdate(self.date, 'YYYY-mm-dd') + ' ' + format_time(shift.start_second_period if self. log_type == 'IN' else shift.end_time)), "employee_checkin_request": self.name })) ec.insert() elif self.period_type == 'ALL': if self.log_type == 'ALL': ec = frappe.get_doc( frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "IN", "time": get_datetime( formatdate(self.date, 'YYYY-mm-dd') + ' ' + format_time(shift.start_time)), "employee_checkin_request": self.name })) ec.insert() ec = frappe.get_doc( frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "OUT", "time": get_datetime( formatdate(self.date, 'YYYY-mm-dd') + ' ' + format_time(shift.end_first_period)), "employee_checkin_request": self.name })) ec.insert() ec = frappe.get_doc( frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "IN", "time": get_datetime( formatdate(self.date, 'YYYY-mm-dd') + ' ' + format_time(shift.start_second_period)), "employee_checkin_request": self.name })) ec.insert() ec = frappe.get_doc( frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "OUT", "time": get_datetime( formatdate(self.date, 'YYYY-mm-dd') + ' ' + format_time(shift.end_time)), "employee_checkin_request": self.name })) ec.insert() else: frappe.throw( _("""If the Period Type equal ALL, the Log Type should to be ALL""" )) else: if self.log_type == 'ALL': ec = frappe.get_doc( frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "IN", "time": get_datetime( formatdate(self.date, 'YYYY-mm-dd') + ' ' + format_time(shift.start_time)), "employee_checkin_request": self.name })) ec.insert() ec = frappe.get_doc( frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "OUT", "time": get_datetime( formatdate(self.date, 'YYYY-mm-dd') + ' ' + format_time(shift.end_time)), "employee_checkin_request": self.name })) ec.insert() else: ec = frappe.get_doc( frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": self.log_type, "time": get_datetime( formatdate(self.date, 'YYYY-mm-dd') + ' ' + format_time(shift.start_time if self.log_type == 'IN' else shift.end_time)), "employee_checkin_request": self.name })) ec.insert()
def get_period_list(from_fiscal_year, to_fiscal_year, period_start_date, period_end_date, filter_based_on, periodicity, accumulated_values=False, company=None, reset_period_on_fy_change=True, ignore_fiscal_year=False): """Get a list of dict {"from_date": from_date, "to_date": to_date, "key": key, "label": label} Periodicity can be (Yearly, Quarterly, Monthly)""" if filter_based_on == 'Fiscal Year': fiscal_year = get_fiscal_year_data(from_fiscal_year, to_fiscal_year) validate_fiscal_year(fiscal_year, from_fiscal_year, to_fiscal_year) year_start_date = getdate(fiscal_year.year_start_date) year_end_date = getdate(fiscal_year.year_end_date) else: validate_dates(period_start_date, period_end_date) year_start_date = getdate(period_start_date) year_end_date = getdate(period_end_date) months_to_add = { "Yearly": 12, "Half-Yearly": 6, "Quarterly": 3, "Monthly": 1 }[periodicity] period_list = [] start_date = year_start_date months = get_months(year_start_date, year_end_date) for i in range(cint(math.ceil(months / months_to_add))): period = frappe._dict({"from_date": start_date}) to_date = add_months(start_date, months_to_add) start_date = to_date # Subtract one day from to_date, as it may be first day in next fiscal year or month to_date = add_days(to_date, -1) if to_date <= year_end_date: # the normal case period.to_date = to_date else: # if a fiscal year ends before a 12 month period period.to_date = year_end_date if not ignore_fiscal_year: period.to_date_fiscal_year = get_fiscal_year(period.to_date, company=company)[0] period.from_date_fiscal_year_start_date = get_fiscal_year( period.from_date, company=company)[1] period_list.append(period) if period.to_date == year_end_date: break # common processing for opts in period_list: key = opts["to_date"].strftime("%b_%Y").lower() if periodicity == "Monthly" and not accumulated_values: label = formatdate(opts["to_date"], "MMM YYYY") else: if not accumulated_values: label = get_label(periodicity, opts["from_date"], opts["to_date"]) else: if reset_period_on_fy_change: label = get_label(periodicity, opts.from_date_fiscal_year_start_date, opts["to_date"]) else: label = get_label(periodicity, period_list[0].from_date, opts["to_date"]) opts.update({ "key": key.replace(" ", "_").replace("-", "_"), "label": label, "year_start_date": year_start_date, "year_end_date": year_end_date }) return period_list
def format_value(value, df=None, doc=None, currency=None, translated=False, format=None): '''Format value based on given fieldtype, document reference, currency reference. If docfield info (df) is not given, it will try and guess based on the datatype of the value''' if isinstance(df, string_types): df = frappe._dict(fieldtype=df) if not df: df = frappe._dict() if isinstance(value, datetime.datetime): df.fieldtype = 'Datetime' elif isinstance(value, datetime.date): df.fieldtype = 'Date' elif isinstance(value, datetime.timedelta): df.fieldtype = 'Time' elif isinstance(value, int): df.fieldtype = 'Int' elif isinstance(value, float): df.fieldtype = 'Float' else: df.fieldtype = 'Data' elif (isinstance(df, dict)): # Convert dict to object if necessary df = frappe._dict(df) if value is None: value = "" elif translated: value = frappe._(value) if not df: return value elif df.get("fieldtype") == "Date": return formatdate(value) elif df.get("fieldtype") == "Datetime": return format_datetime(value) elif df.get("fieldtype") == "Time": return format_time(value) elif value == 0 and df.get("fieldtype") in ( "Int", "Float", "Currency", "Percent") and df.get("print_hide_if_no_value"): # this is required to show 0 as blank in table columns return "" elif df.get("fieldtype") == "Currency": default_currency = frappe.db.get_default("currency") currency = currency or get_field_currency(df, doc) or default_currency return fmt_money(value, precision=get_field_precision(df, doc), currency=currency, format=format) elif df.get("fieldtype") == "Float": precision = get_field_precision(df, doc) # I don't know why we support currency option for float currency = currency or get_field_currency(df, doc) # show 1.000000 as 1 # options should not specified if not df.options and value is not None: temp = cstr(value).split(".") if len(temp) == 1 or cint(temp[1]) == 0: precision = 0 return fmt_money(value, precision=precision, currency=currency) elif df.get("fieldtype") == "Percent": return "{}%".format(flt(value, 2)) elif df.get("fieldtype") in ("Text", "Small Text"): if not re.search(r"(<br|<div|<p)", value): return frappe.safe_decode(value).replace("\n", "<br>") elif df.get("fieldtype") == "Markdown Editor": return frappe.utils.markdown(value) elif df.get("fieldtype") == "Table MultiSelect": meta = frappe.get_meta(df.options) link_field = [df for df in meta.fields if df.fieldtype == 'Link'][0] values = [v.get(link_field.fieldname, 'asdf') for v in value] return ', '.join(values) elif df.get("fieldtype") == "Duration": hide_days = df.hide_days return format_duration(value, hide_days) elif df.get("fieldtype") == "Text Editor": return "<div class='ql-snow'>{}</div>".format(value) return value
def get_fiscal_years(transaction_date=None, fiscal_year=None, label="Date", verbose=1, company=None): # if year start date is 2012-04-01, year end date should be 2013-03-31 (hence subdate) cond = " disabled = 0" if fiscal_year: cond += " and fy.name = %(fiscal_year)s" else: cond += " and %(transaction_date)s >= fy.year_start_date and %(transaction_date)s <= fy.year_end_date" 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 ))""" fy = frappe.db.sql("""select fy.name, fy.year_start_date, fy.year_end_date from `tabFiscal Year` fy where %s order by fy.year_start_date desc""" % cond, { "fiscal_year": fiscal_year, "transaction_date": transaction_date, "company": company }) if not fy: error_msg = _("""{0} {1} not in any active Fiscal Year. For more details check {2}.""").format(label, formatdate(transaction_date), "https://erpnext.com/kb/accounts/fiscal-year-error") if verbose==1: frappe.msgprint(error_msg) raise FiscalYearError, error_msg return fy