Browse Source

Merge branch 'develop' of github.com:frappe/frappe into develop

version-14
Rushabh Mehta 11 years ago
parent
commit
cc5816ed5a
24 changed files with 387 additions and 92 deletions
  1. +2
    -1
      frappe/__init__.py
  2. +3
    -3
      frappe/boot.py
  3. +8
    -1
      frappe/core/doctype/docfield/docfield.txt
  4. +2
    -3
      frappe/core/doctype/doctype/doctype.py
  5. +4
    -4
      frappe/core/page/permission_manager/permission_manager.py
  6. +10
    -9
      frappe/core/report/todo/todo.py
  7. +246
    -3
      frappe/country_info.json
  8. +1
    -0
      frappe/data/Framework.sql
  9. +2
    -1
      frappe/defaults.py
  10. +1
    -0
      frappe/exceptions.py
  11. +1
    -3
      frappe/model/__init__.py
  12. +3
    -3
      frappe/model/bean.py
  13. +16
    -14
      frappe/model/db_schema.py
  14. +1
    -1
      frappe/model/delete_doc.py
  15. +31
    -23
      frappe/model/doc.py
  16. +6
    -6
      frappe/model/meta.py
  17. +2
    -2
      frappe/patches.txt
  18. +5
    -0
      frappe/public/js/frappe/model/perm.js
  19. +1
    -0
      frappe/public/js/frappe/views/grid_report.js
  20. +2
    -2
      frappe/sessions.py
  21. +12
    -6
      frappe/utils/nestedset.py
  22. +9
    -0
      frappe/website/doctype/blog_post/test_blog_post.py
  23. +16
    -5
      frappe/widgets/event.py
  24. +3
    -2
      frappe/widgets/query_builder.py

+ 2
- 1
frappe/__init__.py View File

@@ -510,10 +510,11 @@ def make_property_setter(args):


def get_application_home_page(user='Guest'): def get_application_home_page(user='Guest'):
"""get home page for user""" """get home page for user"""
roles = get_roles(user)
hpl = db.sql("""select home_page hpl = db.sql("""select home_page
from `tabDefault Home Page` from `tabDefault Home Page`
where parent='Control Panel' where parent='Control Panel'
and role in ('%s') order by idx asc limit 1""" % "', '".join(get_roles(user)))
and role in (%s) order by idx asc limit 1""" % ", ".join(['%s']*len(roles)), roles)
if hpl: if hpl:
return hpl[0][0] return hpl[0][0]
else: else:


+ 3
- 3
frappe/boot.py View File

@@ -83,9 +83,9 @@ def load_conf_settings(bootinfo):
if key in conf: bootinfo[key] = conf.get(key) if key in conf: bootinfo[key] = conf.get(key)


def add_allowed_pages(bootinfo): def add_allowed_pages(bootinfo):
bootinfo.page_info = dict(frappe.db.sql("""select distinct
parent, modified from `tabPage Role`
where role in ('%s')""" % "', '".join(frappe.get_roles())))
roles = frappe.get_roles()
bootinfo.page_info = dict(frappe.db.sql("""select distinct parent, modified from `tabPage Role`
where role in (%s)""" % ', '.join(['%s']*len(roles)), roles))
# pages where role is not set are also allowed # pages where role is not set are also allowed
bootinfo.page_info.update(dict(frappe.db.sql("""select parent, modified bootinfo.page_info.update(dict(frappe.db.sql("""select parent, modified


+ 8
- 1
frappe/core/doctype/docfield/docfield.txt View File

@@ -2,7 +2,7 @@
{ {
"creation": "2013-02-22 01:27:33", "creation": "2013-02-22 01:27:33",
"docstatus": 0, "docstatus": 0,
"modified": "2014-01-02 10:50:02",
"modified": "2014-03-05 14:58:43",
"modified_by": "Administrator", "modified_by": "Administrator",
"owner": "Administrator" "owner": "Administrator"
}, },
@@ -178,6 +178,13 @@
"print_width": "50px", "print_width": "50px",
"width": "50px" "width": "50px"
}, },
{
"doctype": "DocField",
"fieldname": "set_only_once",
"fieldtype": "Check",
"label": "Set Only Once",
"description": "Do not allow user to change after set the first time"
},
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "column_break_13", "fieldname": "column_break_13",


+ 2
- 3
frappe/core/doctype/doctype/doctype.py View File

@@ -33,10 +33,9 @@ class DocType:
if frappe.flags.in_import: if frappe.flags.in_import:
return return
parent_list = frappe.db.sql("""SELECT parent parent_list = frappe.db.sql("""SELECT parent
from tabDocField where fieldtype="Table" and options="%s" """ % self.doc.name)
from tabDocField where fieldtype="Table" and options=%s""", self.doc.name)
for p in parent_list: for p in parent_list:
frappe.db.sql('''UPDATE tabDocType SET modified="%s"
WHERE `name`="%s"''' % (now(), p[0]))
frappe.db.sql('UPDATE tabDocType SET modified=%s WHERE `name`=%s', (now(), p[0]))


def scrub_field_names(self): def scrub_field_names(self):
restricted = ('name','parent','idx','owner','creation','modified','modified_by', restricted = ('name','parent','idx','owner','creation','modified','modified_by',


+ 4
- 4
frappe/core/page/permission_manager/permission_manager.py View File

@@ -22,10 +22,10 @@ def get_roles_and_doctypes():
def get_permissions(doctype=None, role=None): def get_permissions(doctype=None, role=None):
frappe.only_for("System Manager") frappe.only_for("System Manager")
return frappe.db.sql("""select * from tabDocPerm return frappe.db.sql("""select * from tabDocPerm
where %s%s order by parent, permlevel, role""" % (\
doctype and (" parent='%s'" % doctype) or "",
role and ((doctype and " and " or "") + " role='%s'" % role) or "",
), as_dict=True)
where %s%s order by parent, permlevel, role""" %
(doctype and (" parent='%s'" % doctype.replace("'", "\'")) or "",
role and ((doctype and " and " or "") + " role='%s'" % role.replace("'", "\'")) or ""),
as_dict=True)
@frappe.whitelist() @frappe.whitelist()
def remove(doctype, name): def remove(doctype, name):


+ 10
- 9
frappe/core/report/todo/todo.py View File

@@ -18,18 +18,19 @@ def execute(filters=None):
todo.date and getdate(todo.date) or getdate("1900-01-01")), reverse=True) todo.date and getdate(todo.date) or getdate("1900-01-01")), reverse=True)
columns = [_("ID")+":Link/ToDo:90", _("Priority")+"::60", _("Date")+ ":Date", columns = [_("ID")+":Link/ToDo:90", _("Priority")+"::60", _("Date")+ ":Date",
_("Description")+"::150", _("Assigned To/Owner") + ":Link/User:120",
_("Assigned By")+":Link/User:120", _("Reference")+"::200"]
_("Description")+"::150", _("Assigned To/Owner") + ":Data:120",
_("Assigned By")+":Data:120", _("Reference")+"::200"]


result = [] result = []
for todo in todo_list: for todo in todo_list:
if todo.reference_type:
todo.reference = """<a href="#Form/%s/%s">%s: %s</a>""" % \
(todo.reference_type, todo.reference_name, todo.reference_type, todo.reference_name)
else:
todo.reference = None
result.append([todo.name, todo.priority, todo.date, todo.description,
todo.owner, todo.assigned_by, todo.reference])
if todo.owner==frappe.session.user or todo.assigned_by==frappe.session.user:
if todo.reference_type:
todo.reference = """<a href="#Form/%s/%s">%s: %s</a>""" % (todo.reference_type,
todo.reference_name, todo.reference_type, todo.reference_name)
else:
todo.reference = None
result.append([todo.name, todo.priority, todo.date, todo.description,
todo.owner, todo.assigned_by, todo.reference])
return columns, result return columns, result

+ 246
- 3
frappe/country_info.json
File diff suppressed because it is too large
View File


+ 1
- 0
frappe/data/Framework.sql View File

@@ -26,6 +26,7 @@ CREATE TABLE `tabDocField` (
`options` text, `options` text,
`search_index` int(1) DEFAULT NULL, `search_index` int(1) DEFAULT NULL,
`hidden` int(1) DEFAULT NULL, `hidden` int(1) DEFAULT NULL,
`set_only_once` int(1) DEFAULT NULL,
`print_hide` int(1) DEFAULT NULL, `print_hide` int(1) DEFAULT NULL,
`report_hide` int(1) DEFAULT NULL, `report_hide` int(1) DEFAULT NULL,
`reqd` int(1) DEFAULT NULL, `reqd` int(1) DEFAULT NULL,


+ 2
- 1
frappe/defaults.py View File

@@ -128,7 +128,8 @@ def clear_default(key=None, value=None, parent=None, name=None, parenttype=None)
if not conditions: if not conditions:
raise Exception, "[clear_default] No key specified." raise Exception, "[clear_default] No key specified."
frappe.db.sql("""delete from tabDefaultValue where %s""" % " and ".join(conditions), values)
frappe.db.sql("""delete from tabDefaultValue where {0}""".format(" and ".join(conditions)),
tuple(values))
_clear_cache(parent) _clear_cache(parent)
def get_defaults_for(parent="Control Panel"): def get_defaults_for(parent="Control Panel"):


+ 1
- 0
frappe/exceptions.py View File

@@ -33,3 +33,4 @@ class InvalidStatusError(ValidationError): pass
class MandatoryError(ValidationError): pass class MandatoryError(ValidationError): pass
class InvalidSignatureError(ValidationError): pass class InvalidSignatureError(ValidationError): pass
class RateLimitExceededError(ValidationError): pass class RateLimitExceededError(ValidationError): pass
class CannotChangeConstantError(ValidationError): pass

+ 1
- 3
frappe/model/__init__.py View File

@@ -70,9 +70,7 @@ def delete_fields(args_dict, delete=0):
# Delete the data / column only if delete is specified # Delete the data / column only if delete is specified
if not delete: continue if not delete: continue
is_single = frappe.db.sql("select issingle from tabDocType where name = '%s'" % dt)
is_single = is_single and frappe.utils.cint(is_single[0][0]) or 0
if is_single:
if frappe.db.get_value("DocType", dt, "issingle"):
frappe.db.sql("""\ frappe.db.sql("""\
DELETE FROM `tabSingles` DELETE FROM `tabSingles`
WHERE doctype=%s AND field IN (%s) WHERE doctype=%s AND field IN (%s)


+ 3
- 3
frappe/model/bean.py View File

@@ -89,7 +89,7 @@ class Bean:
self.doclist = frappe.doclist(doclist) self.doclist = frappe.doclist(doclist)
self.doc = self.doclist[0] self.doc = self.doclist[0]
if self.doc.get_meta().issingle:
if self.doc.meta.issingle:
self.doc.cast_floats_and_ints() self.doc.cast_floats_and_ints()
if self.obj: if self.obj:
@@ -128,8 +128,8 @@ class Bean:
conflict = True conflict = True
else: else:
tmp = frappe.db.sql("""select modified, docstatus from `tab%s` tmp = frappe.db.sql("""select modified, docstatus from `tab%s`
where name="%s" for update"""
% (self.doc.doctype, self.doc.name), as_dict=True)
where name=%s for update"""
% (self.doc.doctype, '%s'), self.doc.name, as_dict=True)


if not tmp: if not tmp:
frappe.msgprint("""This record does not exist. Please refresh.""", raise_exception=1) frappe.msgprint("""This record does not exist. Please refresh.""", raise_exception=1)


+ 16
- 14
frappe/model/db_schema.py View File

@@ -26,12 +26,12 @@ type_map = {
,'datetime': ('datetime', '') ,'datetime': ('datetime', '')
,'time': ('time', '') ,'time': ('time', '')
,'text': ('text', '') ,'text': ('text', '')
,'data': ('varchar', '180')
,'link': ('varchar', '180')
,'password': ('varchar', '180')
,'select': ('varchar', '180')
,'read only': ('varchar', '180')
,'attach': ('varchar', '180')
,'data': ('varchar', '255')
,'link': ('varchar', '255')
,'password': ('varchar', '255')
,'select': ('varchar', '255')
,'read only': ('varchar', '255')
,'attach': ('varchar', '255')
} }


default_columns = ['name', 'creation', 'modified', 'modified_by', 'owner', 'docstatus', 'parent',\ default_columns = ['name', 'creation', 'modified', 'modified_by', 'owner', 'docstatus', 'parent',\
@@ -77,15 +77,15 @@ class DbTable:
# create table # create table
frappe.db.sql("""create table `%s` ( frappe.db.sql("""create table `%s` (
name varchar(120) not null primary key,
name varchar(255) not null primary key,
creation datetime, creation datetime,
modified datetime, modified datetime,
modified_by varchar(40), modified_by varchar(40),
owner varchar(40),
owner varchar(60),
docstatus int(1) default '0', docstatus int(1) default '0',
parent varchar(120),
parentfield varchar(120),
parenttype varchar(120),
parent varchar(255),
parentfield varchar(255),
parenttype varchar(255),
idx int(8), idx int(8),
%sindex parent(parent)) %sindex parent(parent))
ENGINE=InnoDB ENGINE=InnoDB
@@ -95,7 +95,7 @@ class DbTable:
""" """
get columns from docfields and custom fields get columns from docfields and custom fields
""" """
fl = frappe.db.sql("SELECT * FROM tabDocField WHERE parent = '%s'" % self.doctype, as_dict = 1)
fl = frappe.db.sql("SELECT * FROM tabDocField WHERE parent = %s", self.doctype, as_dict = 1)
try: try:
custom_fl = frappe.db.sql("""\ custom_fl = frappe.db.sql("""\
@@ -185,13 +185,15 @@ class DbTable:


for col in self.add_index: for col in self.add_index:
# if index key not exists # if index key not exists
if not frappe.db.sql("show index from `%s` where key_name = '%s'" % (self.name, col.fieldname)):
if not frappe.db.sql("show index from `%s` where key_name = %s" %
(self.name, '%s'), col.fieldname):
frappe.db.sql("alter table `%s` add index `%s`(`%s`)" % (self.name, col.fieldname, col.fieldname)) frappe.db.sql("alter table `%s` add index `%s`(`%s`)" % (self.name, col.fieldname, col.fieldname))


for col in self.drop_index: for col in self.drop_index:
if col.fieldname != 'name': # primary key if col.fieldname != 'name': # primary key
# if index key exists # if index key exists
if frappe.db.sql("show index from `%s` where key_name = '%s'" % (self.name, col.fieldname)):
if frappe.db.sql("show index from `%s` where key_name = %s" %
(self.name, '%s'), col.fieldname):
frappe.db.sql("alter table `%s` drop index `%s`" % (self.name, col.fieldname)) frappe.db.sql("alter table `%s` drop index `%s`" % (self.name, col.fieldname))


for col in self.set_default: for col in self.set_default:


+ 1
- 1
frappe/model/delete_doc.py View File

@@ -89,7 +89,7 @@ def check_if_doc_is_linked(dt, dn, method="Delete"):
item = frappe.db.get_value(link_dt, {link_field:dn}, item = frappe.db.get_value(link_dt, {link_field:dn},
["name", "parent", "parenttype", "docstatus"], as_dict=True) ["name", "parent", "parenttype", "docstatus"], as_dict=True)
if item and item.parent != dn and (method=="Delete" or
if item and item.parent != dn and ((method=="Delete" and item.docstatus<2) or
(method=="Cancel" and item.docstatus==1)): (method=="Cancel" and item.docstatus==1)):
frappe.msgprint(method + " " + _("Error") + ":"+\ frappe.msgprint(method + " " + _("Error") + ":"+\
("%s (%s) " % (dn, dt)) + _("is linked in") + (" %s (%s)") % ("%s (%s) " % (dn, dt)) + _("is linked in") + (" %s (%s)") %


+ 31
- 23
frappe/model/doc.py View File

@@ -9,6 +9,7 @@ Contains the Document class representing an object / record
_toc = ["frappe.model.doc.Document"] _toc = ["frappe.model.doc.Document"]


import frappe import frappe
from frappe import _
import frappe.model.meta import frappe.model.meta
from frappe.utils import * from frappe.utils import *


@@ -131,7 +132,8 @@ class Document:
self._loadsingle() self._loadsingle()
else: else:
try: try:
dataset = frappe.db.sql('select * from `tab%s` where name="%s"' % (self.doctype, self.name.replace('"', '\"')))
dataset = frappe.db.sql('select * from `tab%s` where name=%s' %
(self.doctype, "%s"), self.name)
except frappe.SQLError, e: except frappe.SQLError, e:
if e.args[0]==1146: if e.args[0]==1146:
dataset = None dataset = None
@@ -215,8 +217,6 @@ class Document:
def save(self, new=0, check_links=1, ignore_fields=0, make_autoname=1, def save(self, new=0, check_links=1, ignore_fields=0, make_autoname=1,
keep_timestamps=False): keep_timestamps=False):
self.get_meta()

if new: if new:
self.fields["__islocal"] = 1 self.fields["__islocal"] = 1


@@ -228,7 +228,7 @@ class Document:
self.set_idx() self.set_idx()


# if required, make new # if required, make new
if not self._meta.issingle:
if not self.meta.issingle:
if self.is_new(): if self.is_new():
r = self._insert(make_autoname=make_autoname, keep_timestamps = keep_timestamps) r = self._insert(make_autoname=make_autoname, keep_timestamps = keep_timestamps)
if r: if r:
@@ -240,7 +240,7 @@ class Document:
# save the values # save the values
self._update_values(self._meta.issingle,
self._update_values(self.meta.issingle,
check_links and self.make_link_list() or {}, ignore_fields=ignore_fields, check_links and self.make_link_list() or {}, ignore_fields=ignore_fields,
keep_timestamps=keep_timestamps) keep_timestamps=keep_timestamps)
self._clear_temp_fields() self._clear_temp_fields()
@@ -249,7 +249,7 @@ class Document:
def _get_amended_name(self): def _get_amended_name(self):
am_id = 1 am_id = 1
am_prefix = self.amended_from am_prefix = self.amended_from
if frappe.db.sql('select amended_from from `tab%s` where name = "%s"' % (self.doctype, self.amended_from))[0][0] or '':
if frappe.db.get_value(self.doctype, self.amended_from, "amended_from"):
am_id = cint(self.amended_from.split('-')[-1]) + 1 am_id = cint(self.amended_from.split('-')[-1]) + 1
am_prefix = '-'.join(self.amended_from.split('-')[:-1]) # except the last hyphen am_prefix = '-'.join(self.amended_from.split('-')[:-1]) # except the last hyphen
@@ -262,8 +262,7 @@ class Document:


self._new_name_set = True self._new_name_set = True


self.get_meta()
autoname = self._meta.autoname
autoname = self.meta.autoname
self.localname = self.name self.localname = self.name


@@ -304,7 +303,7 @@ class Document:
self.name = self.fields['__newname'] self.name = self.fields['__newname']


# default name for table # default name for table
elif self._meta.istable:
elif self.meta.istable:
self.name = make_autoname('#########', self.doctype) self.name = make_autoname('#########', self.doctype)
# unable to determine a name, use global series # unable to determine a name, use global series
@@ -341,7 +340,7 @@ class Document:
self.set_new_name() self.set_new_name()
# validate name # validate name
self.name = validate_name(self.doctype, self.name, self._meta.name_case)
self.name = validate_name(self.doctype, self.name, self.meta.name_case)
# insert! # insert!
if not keep_timestamps: if not keep_timestamps:
@@ -362,7 +361,7 @@ class Document:
self.modified = now() self.modified = now()
update_str, values = [], [] update_str, values = [], []
frappe.db.sql("delete from tabSingles where doctype='%s'" % self.doctype)
frappe.db.sql("delete from tabSingles where doctype=%s", self.doctype)
for f in self.fields.keys(): for f in self.fields.keys():
if not (f in ('modified', 'doctype', 'name', 'perm', 'localname', 'creation'))\ if not (f in ('modified', 'doctype', 'name', 'perm', 'localname', 'creation'))\
and (not f.startswith('__')): # fields not saved and (not f.startswith('__')): # fields not saved
@@ -421,6 +420,7 @@ class Document:
return tmp and tmp[0][0] or ''# match case return tmp and tmp[0][0] or ''# match case
def _update_values(self, issingle, link_list, ignore_fields=0, keep_timestamps=False): def _update_values(self, issingle, link_list, ignore_fields=0, keep_timestamps=False):
self.validate_constants()
if issingle: if issingle:
self._update_single(link_list) self._update_single(link_list)
else: else:
@@ -457,12 +457,10 @@ class Document:
if getattr(frappe.local, "valid_fields_map", None) is None: if getattr(frappe.local, "valid_fields_map", None) is None:
frappe.local.valid_fields_map = {} frappe.local.valid_fields_map = {}
self.get_meta()
valid_fields_map = frappe.local.valid_fields_map valid_fields_map = frappe.local.valid_fields_map
if not valid_fields_map.get(self.doctype): if not valid_fields_map.get(self.doctype):
if cint( self._meta.issingle):
if cint(self.meta.issingle):
doctypelist = frappe.model.doctype.get(self.doctype) doctypelist = frappe.model.doctype.get(self.doctype)
valid_fields_map[self.doctype] = doctypelist.get_fieldnames({ valid_fields_map[self.doctype] = doctypelist.get_fieldnames({
"fieldtype": ["not in", frappe.model.no_value_fields]}) "fieldtype": ["not in", frappe.model.no_value_fields]})
@@ -472,12 +470,27 @@ class Document:
return valid_fields_map.get(self.doctype) return valid_fields_map.get(self.doctype)


def get_meta(self):
def validate_constants(self):
if frappe.flags.in_import:
return
meta = frappe.get_doctype(self.doctype)
constants = [d.fieldname for d in meta.get({"set_only_once": 1})]
if constants:
values = frappe.db.get_value(self.doctype, self.name, constants, as_dict=True)

for fieldname in constants:
if self.fields.get(fieldname) != values.get(fieldname):
frappe.throw("{0}: {1}".format(_("Value cannot be changed for"),
_(meta.get_field(fieldname).label)), frappe.CannotChangeConstantError)
@property
def meta(self):
if not self._meta: if not self._meta:
self._meta = frappe.db.get_value("DocType", self.doctype, ["autoname", "issingle",
"istable", "name_case"], as_dict=True) or frappe._dict()
self._meta = frappe.db.get_value("DocType", self.doctype, "*", as_dict=True) \
or frappe._dict()
return self._meta return self._meta

def update_parentinfo(self): def update_parentinfo(self):
"""update parent type and parent field, if not explicitly specified""" """update parent type and parent field, if not explicitly specified"""
@@ -748,11 +761,6 @@ def validate_name(doctype, name, case=None, merge=False):
name = name.strip() # no leading and trailing blanks name = name.strip() # no leading and trailing blanks


forbidden = ['%', "'", '"', '#', '*', '?', '`']
for f in forbidden:
if f in name:
frappe.msgprint('%s not allowed in ID (name)' % f, raise_exception =1)
return name return name
def get_default_naming_series(doctype): def get_default_naming_series(doctype):


+ 6
- 6
frappe/model/meta.py View File

@@ -15,8 +15,8 @@ def is_single(doctype):


def get_parent_dt(dt): def get_parent_dt(dt):
parent_dt = frappe.db.sql("""select parent from tabDocField parent_dt = frappe.db.sql("""select parent from tabDocField
where fieldtype="Table" and options="%s" and (parent not like "old_parent:%%")
limit 1""" % dt)
where fieldtype="Table" and options=%s and (parent not like "old_parent:%%")
limit 1""", dt)
return parent_dt and parent_dt[0][0] or '' return parent_dt and parent_dt[0][0] or ''


def set_fieldname(field_id, fieldname): def set_fieldname(field_id, fieldname):
@@ -40,12 +40,12 @@ def get_link_fields(doctype):
] ]


def get_table_fields(doctype): def get_table_fields(doctype):
child_tables = [[d[0], d[1]] for d in frappe.db.sql("select options, fieldname from tabDocField \
where parent='%s' and fieldtype='Table'" % doctype, as_list=1)]
child_tables = [[d[0], d[1]] for d in frappe.db.sql("""select options, fieldname
from tabDocField where parent=%s and fieldtype='Table'""", doctype, as_list=1)]
try: try:
custom_child_tables = [[d[0], d[1]] for d in frappe.db.sql("select options, fieldname from `tabCustom Field` \
where dt='%s' and fieldtype='Table'" % doctype, as_list=1)]
custom_child_tables = [[d[0], d[1]] for d in frappe.db.sql("""select options, fieldname
from `tabCustom Field` where dt=%s and fieldtype='Table'""", doctype, as_list=1)]
except Exception, e: except Exception, e:
if e.args[0]!=1146: if e.args[0]!=1146:
raise raise


+ 2
- 2
frappe/patches.txt View File

@@ -1,7 +1,7 @@
execute:import inlinestyler # new requirement execute:import inlinestyler # new requirement


execute:frappe.reload_doc('core', 'doctype', 'doctype', force=True) #2014-01-24 execute:frappe.reload_doc('core', 'doctype', 'doctype', force=True) #2014-01-24
execute:frappe.reload_doc('core', 'doctype', 'docfield', force=True) #2013-13-26
execute:frappe.reload_doc('core', 'doctype', 'docfield', force=True) #2014-03-01
execute:frappe.reload_doc('core', 'doctype', 'docperm') #2013-13-26 execute:frappe.reload_doc('core', 'doctype', 'docperm') #2013-13-26
execute:frappe.reload_doc('core', 'doctype', 'page') #2013-13-26 execute:frappe.reload_doc('core', 'doctype', 'page') #2013-13-26
execute:frappe.reload_doc('core', 'doctype', 'report') #2013-13-26 execute:frappe.reload_doc('core', 'doctype', 'report') #2013-13-26
@@ -21,4 +21,4 @@ execute:import frappe.installer;frappe.installer.make_site_dirs() #2014-02-19
frappe.patches.4_0.private_backups frappe.patches.4_0.private_backups
frappe.patches.4_0.set_module_in_report frappe.patches.4_0.set_module_in_report
frappe.patches.4_0.remove_old_parent frappe.patches.4_0.remove_old_parent
frappe.patches.4_0.rename_profile_to_user
frappe.patches.4_0.rename_profile_to_user

+ 5
- 0
frappe/public/js/frappe/model/perm.js View File

@@ -190,6 +190,11 @@ $.extend(frappe.perm, {
} }
if(explain) console.log("By Read Only:" + status); if(explain) console.log("By Read Only:" + status);
if(status==="Write" && df.set_only_once && !doc.__islocal) {
status = "Read";
}
if(explain) console.log("By Set Only Once:" + status);
return status; return status;
}, },
}); });

+ 1
- 0
frappe/public/js/frappe/views/grid_report.js View File

@@ -589,6 +589,7 @@ frappe.views.GridReport = Class.extend({
var date_diff = dateutil.get_diff(this.to_date, this.from_date); var date_diff = dateutil.get_diff(this.to_date, this.from_date);
me.column_map = {}; me.column_map = {};
me.last_date = null;
var add_column = function(date) { var add_column = function(date) {
me.columns.push({ me.columns.push({


+ 2
- 2
frappe/sessions.py View File

@@ -133,8 +133,8 @@ class Session:
self.insert_session_record() self.insert_session_record()


# update user # update user
frappe.db.sql("""UPDATE tabUser SET last_login = '%s', last_ip = '%s'
where name='%s'""" % (frappe.utils.now(), frappe.get_request_header('REMOTE_ADDR'), self.data['user']))
frappe.db.sql("""UPDATE tabUser SET last_login = %s, last_ip = %s
where name=%s""", (frappe.utils.now(), frappe.get_request_header('REMOTE_ADDR'), self.data['user']))
frappe.db.commit() frappe.db.commit()


def insert_session_record(self): def insert_session_record(self):


+ 12
- 6
frappe/utils/nestedset.py View File

@@ -70,19 +70,23 @@ def update_add_node(doc, parent, parent_field):
% (doctype, "%s"), parent)[0] % (doctype, "%s"), parent)[0]
validate_loop(doc.doctype, doc.name, left, right) validate_loop(doc.doctype, doc.name, left, right)
else: # root else: # root
right = frappe.db.sql("select ifnull(max(rgt),0)+1 from `tab%s` where ifnull(`%s`,'') =''" % (doctype, parent_field))[0][0]
right = frappe.db.sql("select ifnull(max(rgt),0)+1 from `tab%s` \
where ifnull(`%s`,'') =''" % (doctype, parent_field))[0][0]
right = right or 1 right = right or 1
# update all on the right # update all on the right
frappe.db.sql("update `tab%s` set rgt = rgt+2, modified='%s' where rgt >= %s" %(doctype,n,right))
frappe.db.sql("update `tab%s` set lft = lft+2, modified='%s' where lft >= %s" %(doctype,n,right))
frappe.db.sql("update `tab%s` set rgt = rgt+2, modified=%s where rgt >= %s" %
(doctype, '%s', '%s'), (n, right))
frappe.db.sql("update `tab%s` set lft = lft+2, modified=%s where lft >= %s" %
(doctype, '%s', '%s'), (n, right))
# update index of new node # update index of new node
if frappe.db.sql("select * from `tab%s` where lft=%s or rgt=%s"% (doctype, right, right+1)): if frappe.db.sql("select * from `tab%s` where lft=%s or rgt=%s"% (doctype, right, right+1)):
frappe.msgprint("Nested set error. Please send mail to support") frappe.msgprint("Nested set error. Please send mail to support")
raise Exception raise Exception


frappe.db.sql("update `tab%s` set lft=%s, rgt=%s, modified='%s' where name='%s'" % (doctype,right,right+1,n,name))
frappe.db.sql("update `tab{0}` set lft=%s, rgt=%s, modified=%s where name=%s".format(doctype),
(right,right+1,n,name))
return right return right




@@ -164,13 +168,15 @@ def rebuild_node(doctype, parent, left, parent_field):
right = left+1 right = left+1


# get all children of this node # get all children of this node
result = frappe.db.sql("SELECT name FROM `tab%s` WHERE `%s`='%s'" % (doctype, parent_field, parent))
result = frappe.db.sql("SELECT name FROM `tab%s` WHERE `%s`=%s" %
(doctype, parent_field, '%s'), (parent))
for r in result: for r in result:
right = rebuild_node(doctype, r[0], right, parent_field) right = rebuild_node(doctype, r[0], right, parent_field)


# we've got the left value, and now that we've processed # we've got the left value, and now that we've processed
# the children of this node we also know the right value # the children of this node we also know the right value
frappe.db.sql("UPDATE `tab%s` SET lft=%s, rgt=%s, modified='%s' WHERE name='%s'" % (doctype,left,right,n,parent))
frappe.db.sql("""UPDATE `tab{0}` SET lft=%s, rgt=%s, modified=%s
WHERE name=%s""".format(doctype), (left,right,n,parent))


#return the right value of this node + 1 #return the right value of this node + 1
return right+1 return right+1


+ 9
- 0
frappe/website/doctype/blog_post/test_blog_post.py View File

@@ -161,3 +161,12 @@ class TestBlogPost(unittest.TestCase):
bean = frappe.bean("Blog Post", "_test-blog-post-1") bean = frappe.bean("Blog Post", "_test-blog-post-1")


self.assertTrue(bean.has_read_perm()) self.assertTrue(bean.has_read_perm())
def test_set_only_once(self):
blog_post = frappe.get_doctype("Blog Post")
blog_post.get_field("title").set_only_once = 1
bean = frappe.bean("Blog Post", "_test-blog-post-1")
bean.doc.title = "New"
self.assertRaises(frappe.CannotChangeConstantError, bean.save)
blog_post.get_field("title").set_only_once = 0

+ 16
- 5
frappe/widgets/event.py View File

@@ -11,19 +11,30 @@ def get_cal_events(m_st, m_end):
import frappe.model.doc import frappe.model.doc
# load owned events # load owned events
res1 = frappe.db.sql("select name from `tabEvent` WHERE ifnull(event_date,'2000-01-01') between '%s' and '%s' and owner = '%s' and event_type != 'Public' and event_type != 'Cancel'" % (m_st, m_end, frappe.user.name))
res1 = frappe.db.sql("""select name from `tabEvent`
WHERE ifnull(event_date,'2000-01-01') between %s and %s and owner = %s
and event_type != 'Public' and event_type != 'Cancel'""",
(m_st, m_end, frappe.user.name))


# load individual events # load individual events
res2 = frappe.db.sql("select t1.name from `tabEvent` t1, `tabEvent User` t2 where ifnull(t1.event_date,'2000-01-01') between '%s' and '%s' and t2.person = '%s' and t1.name = t2.parent and t1.event_type != 'Cancel'" % (m_st, m_end, frappe.user.name))
res2 = frappe.db.sql("""select t1.name from `tabEvent` t1, `tabEvent User` t2
where ifnull(t1.event_date,'2000-01-01') between %s and %s and t2.person = %s
and t1.name = t2.parent and t1.event_type != 'Cancel'""",
(m_st, m_end, frappe.user.name))


# load role events # load role events
roles = frappe.user.get_roles() roles = frappe.user.get_roles()
myroles = ['t2.role = "%s"' % r for r in roles]
myroles = ['t2.role = "%s"' % r.replace('"', '\"') for r in roles]
myroles = '(' + (' OR '.join(myroles)) + ')' myroles = '(' + (' OR '.join(myroles)) + ')'
res3 = frappe.db.sql("select t1.name from `tabEvent` t1, `tabEvent Role` t2 where ifnull(t1.event_date,'2000-01-01') between '%s' and '%s' and t1.name = t2.parent and t1.event_type != 'Cancel' and %s" % (m_st, m_end, myroles))
res3 = frappe.db.sql("""select t1.name from `tabEvent` t1, `tabEvent Role` t2
where ifnull(t1.event_date,'2000-01-01') between %s and %s
and t1.name = t2.parent and t1.event_type != 'Cancel' and %s""" %
('%s', '%s', myroles), (m_st, m_end))
# load public events # load public events
res4 = frappe.db.sql("select name from `tabEvent` where ifnull(event_date,'2000-01-01') between '%s' and '%s' and event_type='Public'" % (m_st, m_end))
res4 = frappe.db.sql("select name from `tabEvent` \
where ifnull(event_date,'2000-01-01') between %s and %s and event_type='Public'",
(m_st, m_end))
doclist, rl = [], [] doclist, rl = [], []
for r in res1 + res2 + res3 + res4: for r in res1 + res2 + res3 + res4:


+ 3
- 2
frappe/widgets/query_builder.py View File

@@ -20,7 +20,7 @@ def get_sql_tables(q):


def get_parent_dt(dt): def get_parent_dt(dt):
pdt = '' pdt = ''
if frappe.db.sql('select name from `tabDocType` where istable=1 and name="%s"' % dt):
if frappe.db.sql('select name from `tabDocType` where istable=1 and name=%s', dt):
import frappe.model.meta import frappe.model.meta
return frappe.model.meta.get_parent_dt(dt) return frappe.model.meta.get_parent_dt(dt)
return pdt return pdt
@@ -44,7 +44,8 @@ def get_sql_meta(tl):
meta[dt]['parent'] = ('ID', 'Link', pdt, '200') meta[dt]['parent'] = ('ID', 'Link', pdt, '200')


# get the field properties from DocField # get the field properties from DocField
res = frappe.db.sql("select fieldname, label, fieldtype, options, width from tabDocField where parent='%s'" % dt)
res = frappe.db.sql("select fieldname, label, fieldtype, options, width \
from tabDocField where parent=%s", dt)
for r in res: for r in res:
if r[0]: if r[0]:
meta[dt][r[0]] = (r[1], r[2], r[3], r[4]); meta[dt][r[0]] = (r[1], r[2], r[3], r[4]);


Loading…
Cancel
Save