@@ -43,11 +43,11 @@ def export_csv(doctype, path): | |||||
get_template(doctype=doctype, all_doctypes="Yes", with_data="Yes") | get_template(doctype=doctype, all_doctypes="Yes", with_data="Yes") | ||||
csvfile.write(frappe.response.result.encode("utf-8")) | csvfile.write(frappe.response.result.encode("utf-8")) | ||||
def export_json(doctype, path): | |||||
def export_json(doctype, path, filters=None): | |||||
from frappe.utils.response import json_handler | from frappe.utils.response import json_handler | ||||
out = [] | out = [] | ||||
for doc in frappe.get_all(doctype, fields=["name"], limit_page_length=None): | |||||
out.append(frappe.get_doc(doctype.doc.name).as_dict()) | |||||
for doc in frappe.get_all(doctype, fields=["name"], filters=filters, limit_page_length=0, order_by="creation asc"): | |||||
out.append(frappe.get_doc(doctype, doc.name).as_dict()) | |||||
with open(path, "w") as outfile: | with open(path, "w") as outfile: | ||||
outfile.write(json.dumps(out, default=json_handler, indent=1, sort_keys=True)) | outfile.write(json.dumps(out, default=json_handler, indent=1, sort_keys=True)) | ||||
@@ -308,6 +308,8 @@ class Database: | |||||
* ifnull(`fieldname`, default_value) = %(fieldname)s | * ifnull(`fieldname`, default_value) = %(fieldname)s | ||||
* `fieldname` [=, !=, >, >=, <, <=] %(fieldname)s | * `fieldname` [=, !=, >, >=, <, <=] %(fieldname)s | ||||
""" | """ | ||||
conditions = [] | |||||
values = {} | |||||
def _build_condition(key): | def _build_condition(key): | ||||
""" | """ | ||||
filter's key is passed by map function | filter's key is passed by map function | ||||
@@ -317,25 +319,38 @@ class Database: | |||||
""" | """ | ||||
_operator = "=" | _operator = "=" | ||||
value = filters.get(key) | value = filters.get(key) | ||||
values[key] = value | |||||
if isinstance(value, (list, tuple)): | if isinstance(value, (list, tuple)): | ||||
_operator = value[0] | _operator = value[0] | ||||
filters[key] = value[1] | |||||
values[key] = value[1] | |||||
if isinstance(value[1], (tuple, list)): | |||||
inner_list = [] | |||||
for i, v in enumerate(value[1]): | |||||
inner_key = "{0}_{1}".format(key, i) | |||||
values[inner_key] = v | |||||
inner_list.append("%({0})s".format(inner_key)) | |||||
if _operator not in ["=", "!=", ">", ">=", "<", "<=", "like"]: | |||||
values[key] = "({0})".format(", ".join(inner_list)) | |||||
if _operator not in ["=", "!=", ">", ">=", "<", "<=", "like", "in", "not in"]: | |||||
_operator = "=" | _operator = "=" | ||||
if "[" in key: | if "[" in key: | ||||
split_key = key.split("[") | split_key = key.split("[") | ||||
return "ifnull(`" + split_key[0] + "`, " + split_key[1][:-1] + ") " \ | |||||
condition = "ifnull(`" + split_key[0] + "`, " + split_key[1][:-1] + ") " \ | |||||
+ _operator + " %(" + key + ")s" | + _operator + " %(" + key + ")s" | ||||
else: | else: | ||||
return "`" + key + "` " + _operator + " %(" + key + ")s" | |||||
condition = "`" + key + "` " + _operator + " %(" + key + ")s" | |||||
conditions.append(condition) | |||||
if isinstance(filters, basestring): | if isinstance(filters, basestring): | ||||
filters = { "name": filters } | filters = { "name": filters } | ||||
conditions = map(_build_condition, filters) | |||||
return " and ".join(conditions), filters | |||||
for f in filters: | |||||
_build_condition(f) | |||||
return " and ".join(conditions), values | |||||
def get(self, doctype, filters=None, as_dict=True): | def get(self, doctype, filters=None, as_dict=True): | ||||
"""Returns `get_value` with fieldname='*'""" | """Returns `get_value` with fieldname='*'""" | ||||
@@ -487,12 +502,12 @@ class Database: | |||||
if fields=="*": | if fields=="*": | ||||
as_dict = True | as_dict = True | ||||
conditions, filters = self.build_conditions(filters) | |||||
conditions, values = self.build_conditions(filters) | |||||
order_by = ("order by " + order_by) if order_by else "" | order_by = ("order by " + order_by) if order_by else "" | ||||
r = self.sql("select %s from `tab%s` where %s %s" % (fl, doctype, | |||||
conditions, order_by), filters, as_dict=as_dict, debug=debug, update=update) | |||||
r = self.sql("select {0} from `tab{1}` where {2} {3}".format(fl, doctype, | |||||
conditions, order_by), values, as_dict=as_dict, debug=debug, update=update) | |||||
return r | return r | ||||
@@ -211,7 +211,8 @@ class BaseDocument(object): | |||||
return frappe._dict(doc) | return frappe._dict(doc) | ||||
def as_json(self): | def as_json(self): | ||||
return json.dumps(self.as_dict(), indent=1, sort_keys=True) | |||||
from frappe.utils.response import json_handler | |||||
return json.dumps(self.as_dict(), indent=1, sort_keys=True, default=json_handler) | |||||
def get_table_field_doctype(self, fieldname): | def get_table_field_doctype(self, fieldname): | ||||
return self.meta.get_field(fieldname).options | return self.meta.get_field(fieldname).options | ||||
@@ -19,6 +19,8 @@ def set_new_name(doc): | |||||
:param doc: Document to be named.""" | :param doc: Document to be named.""" | ||||
doc.run_method("before_naming") | |||||
autoname = frappe.get_meta(doc.doctype).autoname | autoname = frappe.get_meta(doc.doctype).autoname | ||||
if getattr(doc, "amended_from", None): | if getattr(doc, "amended_from", None): | ||||
_set_amended_name(doc) | _set_amended_name(doc) | ||||
@@ -1256,15 +1256,6 @@ frappe.ui.form.ControlTable = frappe.ui.form.Control.extend({ | |||||
this._super(); | this._super(); | ||||
// add title if prev field is not column / section heading or html | // add title if prev field is not column / section heading or html | ||||
var prev_fieldtype = ""; | |||||
if(this.df.idx > 1) { | |||||
var prev_fieldtype = cur_frm.meta.fields[this.df.idx - 2].fieldtype; | |||||
} | |||||
if(frappe.model.layout_fields.indexOf(prev_fieldtype)===-1) { | |||||
$("<label>" + __(this.df.label) + "<label>").appendTo(this.wrapper); | |||||
} | |||||
this.grid = new frappe.ui.form.Grid({ | this.grid = new frappe.ui.form.Grid({ | ||||
frm: this.frm, | frm: this.frm, | ||||
df: this.df, | df: this.df, | ||||
@@ -101,6 +101,10 @@ $.extend(frappe.datetime, { | |||||
return moment().format(); | return moment().format(); | ||||
}, | }, | ||||
nowdate: function() { | |||||
return frappe.datetime.get_today(); | |||||
}, | |||||
now_time: function() { | now_time: function() { | ||||
return moment().format("HH:mm:ss"); | return moment().format("HH:mm:ss"); | ||||
}, | }, | ||||
@@ -8,18 +8,21 @@ import frappe | |||||
import operator | import operator | ||||
import re, urllib, datetime, math | import re, urllib, datetime, math | ||||
import babel.dates | import babel.dates | ||||
from dateutil import parser | |||||
DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S.%f" | |||||
# datetime functions | # datetime functions | ||||
def getdate(string_date): | def getdate(string_date): | ||||
""" | """ | ||||
Coverts string date (yyyy-mm-dd) to datetime.date object | Coverts string date (yyyy-mm-dd) to datetime.date object | ||||
""" | """ | ||||
if isinstance(string_date, datetime.date): | |||||
return string_date | |||||
elif isinstance(string_date, datetime.datetime): | |||||
if isinstance(string_date, datetime.datetime): | |||||
return string_date.date() | return string_date.date() | ||||
elif isinstance(string_date, datetime.date): | |||||
return string_date | |||||
if " " in string_date: | if " " in string_date: | ||||
string_date = string_date.split(" ")[0] | string_date = string_date.split(" ")[0] | ||||
@@ -27,7 +30,15 @@ def getdate(string_date): | |||||
def add_to_date(date, years=0, months=0, days=0): | def add_to_date(date, years=0, months=0, days=0): | ||||
"""Adds `days` to the given date""" | """Adds `days` to the given date""" | ||||
format = isinstance(date, basestring) | |||||
# save time part | |||||
with_time = False | |||||
as_string = isinstance(date, basestring) | |||||
if as_string: | |||||
if " " in date: with_time = date.split()[1] | |||||
elif isinstance(date, datetime.datetime): | |||||
with_time = date.time().strftime(DATETIME_FORMAT.split()[1]) | |||||
if date: | if date: | ||||
date = getdate(date) | date = getdate(date) | ||||
else: | else: | ||||
@@ -36,8 +47,9 @@ def add_to_date(date, years=0, months=0, days=0): | |||||
from dateutil.relativedelta import relativedelta | from dateutil.relativedelta import relativedelta | ||||
date += relativedelta(years=years, months=months, days=days) | date += relativedelta(years=years, months=months, days=days) | ||||
if format: | |||||
return date.strftime("%Y-%m-%d") | |||||
if as_string: | |||||
date = date.strftime("%Y-%m-%d") | |||||
return (date + " " + with_time) if with_time else date | |||||
else: | else: | ||||
return date | return date | ||||
@@ -89,7 +101,7 @@ def now(): | |||||
return getdate(frappe.local.current_date).strftime("%Y-%m-%d") + " " + \ | return getdate(frappe.local.current_date).strftime("%Y-%m-%d") + " " + \ | ||||
now_datetime().strftime('%H:%M:%S.%f') | now_datetime().strftime('%H:%M:%S.%f') | ||||
else: | else: | ||||
return now_datetime().strftime('%Y-%m-%d %H:%M:%S.%f') | |||||
return now_datetime().strftime(DATETIME_FORMAT) | |||||
def nowdate(): | def nowdate(): | ||||
"""return current date as yyyy-mm-dd""" | """return current date as yyyy-mm-dd""" | ||||
@@ -124,7 +136,7 @@ def get_last_day(dt): | |||||
def get_datetime(datetime_str): | def get_datetime(datetime_str): | ||||
try: | try: | ||||
return datetime.datetime.strptime(datetime_str, '%Y-%m-%d %H:%M:%S.%f') | |||||
return datetime.datetime.strptime(datetime_str, DATETIME_FORMAT) | |||||
except TypeError: | except TypeError: | ||||
if isinstance(datetime_str, datetime.datetime): | if isinstance(datetime_str, datetime.datetime): | ||||
@@ -138,11 +150,19 @@ def get_datetime(datetime_str): | |||||
return datetime.datetime.strptime(datetime_str, '%Y-%m-%d %H:%M:%S') | return datetime.datetime.strptime(datetime_str, '%Y-%m-%d %H:%M:%S') | ||||
def get_time(time_str): | |||||
if isinstance(time_str, datetime.datetime): | |||||
return time_str.time() | |||||
elif isinstance(time_str, datetime.time): | |||||
return time_str | |||||
return parser.parse(time_str).time() | |||||
def get_datetime_str(datetime_obj): | def get_datetime_str(datetime_obj): | ||||
if isinstance(datetime_obj, basestring): | if isinstance(datetime_obj, basestring): | ||||
datetime_obj = get_datetime(datetime_obj) | datetime_obj = get_datetime(datetime_obj) | ||||
return datetime_obj.strftime('%Y-%m-%d %H:%M:%S.%f') | |||||
return datetime_obj.strftime(DATETIME_FORMAT) | |||||
def formatdate(string_date=None, format_string=None): | def formatdate(string_date=None, format_string=None): | ||||
""" | """ | ||||
@@ -453,8 +473,8 @@ def pretty_date(iso_datetime): | |||||
import math | import math | ||||
if isinstance(iso_datetime, basestring): | if isinstance(iso_datetime, basestring): | ||||
iso_datetime = datetime.datetime.strptime(iso_datetime, '%Y-%m-%d %H:%M:%S.%f') | |||||
now_dt = datetime.datetime.strptime(now(), '%Y-%m-%d %H:%M:%S.%f') | |||||
iso_datetime = datetime.datetime.strptime(iso_datetime, DATETIME_FORMAT) | |||||
now_dt = datetime.datetime.strptime(now(), DATETIME_FORMAT) | |||||
dt_diff = now_dt - iso_datetime | dt_diff = now_dt - iso_datetime | ||||
# available only in python 2.7+ | # available only in python 2.7+ | ||||