@@ -26,9 +26,9 @@ def startup(): | |||
webnotes.response.update(webnotes.session_cache.get()) | |||
def cleanup_docs(): | |||
import webnotes.model.doclist | |||
import webnotes.model.utils | |||
if webnotes.response.get('docs') and type(webnotes.response['docs'])!=dict: | |||
webnotes.response['docs'] = webnotes.model.doclist.compress(webnotes.response['docs']) | |||
webnotes.response['docs'] = webnotes.model.utils.compress(webnotes.response['docs']) | |||
# server calls | |||
# ------------------------------------------------------------------------------------ | |||
@@ -45,22 +45,22 @@ def logout(): | |||
def dt_map(): | |||
import webnotes | |||
import webnotes.model.doclist | |||
import webnotes.model.utils | |||
from webnotes.model.code import get_obj | |||
from webnotes.model.doc import Document | |||
form_dict = webnotes.form_dict | |||
dt_list = webnotes.model.doclist.expand(form_dict.get('docs')) | |||
dt_list = webnotes.model.utils.expand(form_dict.get('docs')) | |||
from_doctype = form_dict.get('from_doctype') | |||
to_doctype = form_dict.get('to_doctype') | |||
from_docname = form_dict.get('from_docname') | |||
from_to_list = form_dict.get('from_to_list') | |||
dm = get_obj('DocType Mapper', from_doctype +'-' + to_doctype) | |||
doclist = dm.dt_map(from_doctype, to_doctype, from_docname, Document(fielddata = dt_list[0]), [], from_to_list) | |||
dl = dm.dt_map(from_doctype, to_doctype, from_docname, Document(fielddata = dt_list[0]), [], from_to_list) | |||
webnotes.response['docs'] = doclist | |||
webnotes.response['docs'] = dl | |||
# Load Month Events | |||
# ------------------------------------------------------------------------------------ | |||
@@ -18,7 +18,7 @@ import webnotes | |||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add | |||
from webnotes.model import db_exists | |||
from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType | |||
from webnotes.model.doclist import getlist, copy_doclist | |||
from webnotes.model.utils import getlist | |||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax | |||
from webnotes import session, form, is_testing, msgprint, errprint | |||
@@ -48,9 +48,9 @@ def execute(code, doc=None, doclist=[]): | |||
# -------------------------------------------------- | |||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add | |||
from webnotes.model import db_exists | |||
from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType | |||
from webnotes.model.doclist import getlist, copy_doclist | |||
from webnotes import session, form, is_testing, msgprint, errprint | |||
from webnotes.model.doc import Document, addchild, removechild, getchildren | |||
from webnotes.model.utils import getlist | |||
from webnotes import session, form, msgprint, errprint | |||
import webnotes | |||
@@ -59,6 +59,7 @@ def execute(code, doc=None, doclist=[]): | |||
get_value = webnotes.conn.get_value | |||
in_transaction = webnotes.conn.in_transaction | |||
convert_to_lists = webnotes.conn.convert_to_lists | |||
if webnotes.user: | |||
get_roles = webnotes.user.get_roles | |||
locals().update({'get_obj':get_obj, 'get_server_obj':get_server_obj, 'run_server_obj':run_server_obj, 'updatedb':updatedb, 'check_syntax':check_syntax}) | |||
@@ -446,9 +446,9 @@ class Document: | |||
""" | |||
Clears the child records from the given `doclist` for a particular `tablefield` | |||
""" | |||
import webnotes.model.doclist | |||
from webnotes.model.utils import getlist | |||
for d in webnotes.model.doclist.getlist(doclist, tablefield): | |||
for d in getlist(doclist, tablefield): | |||
d.fields['__oldparent'] = d.parent | |||
d.parent = 'old_parent:' + d.parent # for client to send it back while saving | |||
d.docstatus = 2 | |||
@@ -1,191 +1,225 @@ | |||
import webnotes | |||
import webnotes.model | |||
import webnotes.model.doc | |||
def xzip(a,b): | |||
d = {} | |||
for i in range(len(a)): | |||
d[a[i]] = b[i] | |||
return d | |||
def expand(docs): | |||
""" | |||
Expand a doclist sent from the client side. (Internally used by the request handler) | |||
""" | |||
from webnotes.utils import load_json | |||
""" | |||
Transactions are defined as collection of classes, a DocList represents collection of Document | |||
objects for a transaction with main and children. | |||
docs = load_json(docs) | |||
clist = [] | |||
for d in docs['_vl']: | |||
doc = xzip(docs['_kl'][d[0]], d); | |||
clist.append(doc) | |||
return clist | |||
Group actions like save, etc are performed on doclists | |||
""" | |||
def compress(doclist): | |||
""" | |||
Compress a doclist before sending it to the client side. (Internally used by the request handler) | |||
import webnotes | |||
from webnotes.utils import cint | |||
""" | |||
if doclist and hasattr(doclist[0],'fields'): | |||
docs = [d.fields for d in doclist] | |||
else: | |||
docs = doclist | |||
kl, vl = {}, [] | |||
for d in docs: | |||
dt = d['doctype'] | |||
if not (dt in kl.keys()): | |||
fl = d.keys() | |||
forbidden = ['server_code_compiled'] | |||
nl = ['doctype','localname','__oldparent','__unsaved'] | |||
# add client script for doctype, doctype due to ambiguity | |||
if dt=='DocType': nl.append('__client_script') | |||
for f in fl: | |||
if not (f in nl) and not (f in forbidden): | |||
nl.append(f) | |||
kl[dt] = nl | |||
## values | |||
fl = kl[dt] | |||
nl = [] | |||
for f in fl: | |||
v = d.get(f) | |||
if type(v)==long: | |||
v=int(v) | |||
nl.append(v) | |||
vl.append(nl) | |||
#errprint(str({'_vl':vl,'_kl':kl})) | |||
return {'_vl':vl,'_kl':kl} | |||
# Get Children List (for scripts utility) | |||
# --------------------------------------- | |||
def getlist(doclist, field): | |||
class DocList: | |||
""" | |||
Filter a list of records for a specific field from the full doclist | |||
Example:: | |||
# find all phone call details | |||
dl = getlist(self.doclist, 'contact_updates') | |||
pl = [] | |||
for d in dl: | |||
if d.type=='Phone': | |||
pl.append(d) | |||
Collection of Documents with one parent and multiple children | |||
""" | |||
def __init__(self, dt=None, dn=None): | |||
self.docs = [] | |||
self.obj = None | |||
self.to_docstatus = 0 | |||
l = [] | |||
for d in doclist: | |||
if d.parent and (not d.parent.lower().startswith('old_parent:')) and d.parentfield == field: | |||
l.append(d) | |||
return l | |||
# Copy doclist | |||
# ------------ | |||
def copy_doclist(doclist, no_copy = []): | |||
""" | |||
Save & return a copy of the given doclist | |||
Pass fields that are not to be copied in `no_copy` | |||
""" | |||
from webnotes.model.doc import Document | |||
cl = [] | |||
def __iter__(self): | |||
""" | |||
Make this iterable | |||
""" | |||
return self.docs.__iter__() | |||
# main doc | |||
c = Document(fielddata = doclist[0].fields.copy()) | |||
def from_compressed(self, data, docname): | |||
""" | |||
Expand called from client | |||
""" | |||
from webnotes.model.utils import expand | |||
self.docs = expand(data) | |||
self.objectify(docname) | |||
# clear no_copy fields | |||
for f in no_copy: | |||
if c.fields.has_key(f): | |||
c.fields[f] = None | |||
def objectify(self, docname): | |||
""" | |||
Converts self.docs from a list of dicts to list of Documents | |||
""" | |||
from webnotes.model.doc import Document | |||
self.docs = [Document(fielddata=d) for d in self.docs] | |||
self.children = [] | |||
for d in self.docs: | |||
if d.name == docname: | |||
self.doc = d | |||
else: | |||
self.children.append(d) | |||
c.name = None | |||
c.save(1) | |||
cl.append(c) | |||
def make_obj(self): | |||
""" | |||
Create a DocType object | |||
""" | |||
if self.obj: return self.obj | |||
from webnotes.model.code import get_obj | |||
self.obj = get_obj(doc=self.doc, doclist=self.children) | |||
return self.obj | |||
def next(self): | |||
""" | |||
Next doc | |||
""" | |||
return self.docs.next() | |||
def to_dict(self): | |||
""" | |||
return as a list of dictionaries | |||
""" | |||
return [d.fields for d in self.docs] | |||
def check_if_latest(self): | |||
""" | |||
Raises exception if the modified time is not the same as in the database | |||
""" | |||
from webnotes.model.meta import is_single | |||
if (not is_single(self.doc.doctype)) and (not self.doc.fields.get('__islocal')): | |||
tmp = webnotes.conn.sql(""" | |||
SELECT modified FROM `tab%s` WHERE name="%s" for update""" | |||
% (self.doc.doctype, self.doc.name)) | |||
if tmp and str(tmp[0][0]) != str(self.doc.modified): | |||
webnotes.msgprint(""" | |||
Document has been modified after you have opened it. | |||
To maintain the integrity of the data, you will not be able to save your changes. | |||
Please refresh this document. [%s/%s]""" % (tmp[0][0], self.doc.modified), raise_exception=1) | |||
def check_permission(self): | |||
""" | |||
Raises exception if permission is not valid | |||
""" | |||
if not self.doc.check_perm(verbose=1): | |||
webnotes.msgprint("Not enough permission to save %s" % self.doc.doctype, raise_exception=1) | |||
# new parent name | |||
parent = c.name | |||
def check_links(self): | |||
""" | |||
Checks integrity of links (throws exception if links are invalid) | |||
""" | |||
ref, err_list = {}, [] | |||
for d in self.docs: | |||
if not ref.get(d.doctype): | |||
ref[d.doctype] = d.make_link_list() | |||
err_list += d.validate_links(ref[d.doctype]) | |||
# children | |||
for d in doclist[1:]: | |||
c = Document(fielddata = d.fields.copy()) | |||
c.name = None | |||
# clear no_copy fields | |||
for f in no_copy: | |||
if c.fields.has_key(f): | |||
c.fields[f] = None | |||
c.parent = parent | |||
c.save(1) | |||
cl.append(c) | |||
return cl | |||
# Validate Multiple Links | |||
# ----------------------- | |||
def validate_links_doclist(doclist): | |||
""" | |||
Validate link fields and return link fields that are not correct. | |||
Calls the `validate_links` function on the Document object | |||
""" | |||
ref, err_list = {}, [] | |||
for d in doclist: | |||
if not ref.get(d.doctype): | |||
ref[d.doctype] = d.make_link_list() | |||
err_list += d.validate_links(ref[d.doctype]) | |||
return ', '.join(err_list) | |||
if err_list: | |||
webnotes.msgprint("""[Link Validation] Could not find the following values: %s. | |||
Please correct and resave. Document Not Saved.""" % ', '.join(err_list), raise_exception=1) | |||
# Get list of field values | |||
# ------------------------ | |||
def getvaluelist(doclist, fieldname): | |||
""" | |||
Returns a list of values of a particualr fieldname from all Document object in a doclist | |||
""" | |||
l = [] | |||
for d in doclist: | |||
l.append(d.fields[fieldname]) | |||
return l | |||
def _make_html(doc, link_list): | |||
from webnotes.utils import cstr | |||
out = '<table class="simpletable">' | |||
for k in doc.fields.keys(): | |||
if k!='server_code_compiled': | |||
v = cstr(doc.fields[k]) | |||
def update_timestamps(self): | |||
""" | |||
Update owner, creation, modified_by, modified, docstatus | |||
""" | |||
from webnotes.utils import now | |||
ts = now() | |||
user = webnotes.__dict__.get('session', {}).get('user') or 'Administrator' | |||
for d in self.docs: | |||
if self.doc.__islocal: | |||
d.owner = user | |||
d.creation = ts | |||
# link field | |||
if v and (k in link_list.keys()): | |||
dt = link_list[k] | |||
if type(dt)==str and dt.startswith('link:'): | |||
dt = dt[5:] | |||
v = '<a href="index.cgi?page=Form/%s/%s">%s</a>' % (dt, v, v) | |||
d.modified_by = user | |||
d.modified = ts | |||
d.docstatus = self.to_docstatus | |||
def prepare_for_save(self, check_links): | |||
""" | |||
Set owner, modified etc before saving | |||
""" | |||
self.check_if_latest() | |||
self.check_permission() | |||
if check_links: | |||
self.check_links() | |||
self.update_timestamps() | |||
def run_method(self, method): | |||
""" | |||
Run a method and custom_method | |||
""" | |||
self.make_obj() | |||
if hasattr(self.obj, method): | |||
getattr(self.obj, method)() | |||
if hasattr(self.obj, 'custom_' + method): | |||
getattr(self.obj, 'custom_' + method)() | |||
from webnotes.model.triggers import fire_event | |||
fire_event(self.doc, method) | |||
out += '\t<tr><td>%s</td><td>%s</td></tr>\n' % (cstr(k), v) | |||
def save_main(self): | |||
""" | |||
Save the main doc | |||
""" | |||
try: | |||
self.doc.save(cint(self.doc.__islocal)) | |||
except NameError, e: | |||
webnotes.msgprint('%s "%s" already exists' % (doc.doctype, doc.name)) | |||
# prompt if cancelled | |||
if webnotes.conn.get_value(doc.doctype, doc.name, 'docstatus')==2: | |||
webnotes.msgprint('[%s "%s" has been cancelled]' % (doc.doctype, doc.name)) | |||
webnotes.errprint(webnotes.utils.getTraceback()) | |||
raise e | |||
def save_children(self): | |||
""" | |||
Save Children, with the new parent name | |||
""" | |||
for d in self.children: | |||
deleted, local = d.fields.get('__deleted',0), d.fields.get('__islocal',0) | |||
if cint(local) and cint(deleted): | |||
pass | |||
elif d.fields.has_key('parent'): | |||
if d.parent and (not d.parent.startswith('old_parent:')): | |||
d.parent = self.doc.name # rename if reqd | |||
d.parenttype = self.doc.doctype | |||
d.save(new = cint(local)) | |||
def save(self, check_links=1): | |||
""" | |||
Save the list | |||
""" | |||
self.prepare_for_save(check_links) | |||
self.run_method('validate') | |||
self.save_main() | |||
self.save_children() | |||
self.run_method('on_update') | |||
out += '</table>' | |||
return out | |||
def to_html(doclist): | |||
def submit(self): | |||
""" | |||
Save & Submit - set docstatus = 1, run "on_submit" | |||
""" | |||
self.to_docstatus = 1 | |||
self.save() | |||
self.run_method('on_submit') | |||
def cancel(self): | |||
""" | |||
Cancel - set docstatus 2, run "on_cancel" | |||
""" | |||
self.to_docstatus = 2 | |||
self.save_main() | |||
self.save_children() | |||
self.run_method('on_cancel') | |||
def update_after_submit(self): | |||
""" | |||
Update after submit - some values changed after submit | |||
""" | |||
self.to_docstatus = 1 | |||
self.save_main() | |||
self.save_children() | |||
self.run_method('on_update_after_submit') | |||
# for bc | |||
def getlist(doclist, parentfield): | |||
""" | |||
Return a simple HTML format of the doclist | |||
Return child records of a particular type | |||
""" | |||
out = '' | |||
link_lists = {} | |||
for d in doclist: | |||
if not link_lists.get(d.doctype): | |||
link_lists[d.doctype] = d.make_link_list() | |||
out += _make_html(d, link_lists[d.doctype]) | |||
return out | |||
import webnotes.model.utils | |||
return webnotes.model.utils.getlist(doclist, parentfield) |
@@ -0,0 +1,169 @@ | |||
""" | |||
Model utilities, unclassified functions | |||
""" | |||
def expand(docs): | |||
""" | |||
Expand a doclist sent from the client side. (Internally used by the request handler) | |||
""" | |||
def xzip(a,b): | |||
d = {} | |||
for i in range(len(a)): | |||
d[a[i]] = b[i] | |||
return d | |||
from webnotes.utils import load_json | |||
docs = load_json(docs) | |||
clist = [] | |||
for d in docs['_vl']: | |||
doc = xzip(docs['_kl'][d[0]], d); | |||
clist.append(doc) | |||
return clist | |||
def compress(doclist): | |||
""" | |||
Compress a doclist before sending it to the client side. (Internally used by the request handler) | |||
""" | |||
if doclist and hasattr(doclist[0],'fields'): | |||
docs = [d.fields for d in doclist] | |||
else: | |||
docs = doclist | |||
kl, vl = {}, [] | |||
for d in docs: | |||
dt = d['doctype'] | |||
if not (dt in kl.keys()): | |||
fl = d.keys() | |||
forbidden = ['server_code_compiled'] | |||
nl = ['doctype','localname','__oldparent','__unsaved'] | |||
# add client script for doctype, doctype due to ambiguity | |||
if dt=='DocType': nl.append('__client_script') | |||
for f in fl: | |||
if not (f in nl) and not (f in forbidden): | |||
nl.append(f) | |||
kl[dt] = nl | |||
## values | |||
fl = kl[dt] | |||
nl = [] | |||
for f in fl: | |||
v = d.get(f) | |||
if type(v)==long: | |||
v=int(v) | |||
nl.append(v) | |||
vl.append(nl) | |||
#errprint(str({'_vl':vl,'_kl':kl})) | |||
return {'_vl':vl,'_kl':kl} | |||
def getlist(doclist, field): | |||
""" | |||
Filter a list of records for a specific field from the full doclist | |||
Example:: | |||
# find all phone call details | |||
dl = getlist(self.doclist, 'contact_updates') | |||
pl = [] | |||
for d in dl: | |||
if d.type=='Phone': | |||
pl.append(d) | |||
""" | |||
l = [] | |||
for d in doclist: | |||
if d.parent and (not d.parent.lower().startswith('old_parent:')) and d.parentfield == field: | |||
l.append(d) | |||
return l | |||
# Copy doclist | |||
# ------------ | |||
def copy_doclist(doclist, no_copy = []): | |||
""" | |||
Save & return a copy of the given doclist | |||
Pass fields that are not to be copied in `no_copy` | |||
""" | |||
from webnotes.model.doc import Document | |||
cl = [] | |||
# main doc | |||
c = Document(fielddata = doclist[0].fields.copy()) | |||
# clear no_copy fields | |||
for f in no_copy: | |||
if c.fields.has_key(f): | |||
c.fields[f] = None | |||
c.name = None | |||
c.save(1) | |||
cl.append(c) | |||
# new parent name | |||
parent = c.name | |||
# children | |||
for d in doclist[1:]: | |||
c = Document(fielddata = d.fields.copy()) | |||
c.name = None | |||
# clear no_copy fields | |||
for f in no_copy: | |||
if c.fields.has_key(f): | |||
c.fields[f] = None | |||
c.parent = parent | |||
c.save(1) | |||
cl.append(c) | |||
return cl | |||
def getvaluelist(doclist, fieldname): | |||
""" | |||
Returns a list of values of a particualr fieldname from all Document object in a doclist | |||
""" | |||
l = [] | |||
for d in doclist: | |||
l.append(d.fields[fieldname]) | |||
return l | |||
def _make_html(doc, link_list): | |||
from webnotes.utils import cstr | |||
out = '<table class="simpletable">' | |||
for k in doc.fields.keys(): | |||
if k!='server_code_compiled': | |||
v = cstr(doc.fields[k]) | |||
# link field | |||
if v and (k in link_list.keys()): | |||
dt = link_list[k] | |||
if type(dt)==str and dt.startswith('link:'): | |||
dt = dt[5:] | |||
v = '<a href="index.cgi?page=Form/%s/%s">%s</a>' % (dt, v, v) | |||
out += '\t<tr><td>%s</td><td>%s</td></tr>\n' % (cstr(k), v) | |||
out += '</table>' | |||
return out | |||
def to_html(doclist): | |||
""" | |||
Return a simple HTML format of the doclist | |||
""" | |||
out = '' | |||
link_lists = {} | |||
for d in doclist: | |||
if not link_lists.get(d.doctype): | |||
link_lists[d.doctype] = d.make_link_list() | |||
out += _make_html(d, link_lists[d.doctype]) | |||
return out |
@@ -11,21 +11,20 @@ def export_to_files(record_list=[], record_module=None, verbose=0): | |||
doclist = [d.fields for d in webnotes.model.doc.get(record[0], record[1])] | |||
write_document_file(doclist, record_module) | |||
def create_init_py(modules_path, module, dt, dn): | |||
def create_init_py(modules_path, dt, dn): | |||
""" | |||
Creates __init__.py in the module directory structure | |||
""" | |||
import os | |||
from webnotes.modules import scrub | |||
def create_if_not_exists(path): | |||
initpy = os.path.join(path, '__init__.py') | |||
if not os.path.exists(initpy): | |||
open(initpy, 'w').close() | |||
create_if_not_exists(os.path.join(modules_path, module)) | |||
create_if_not_exists(os.path.join(modules_path, module, dt)) | |||
create_if_not_exists(os.path.join(modules_path, module, dt, dn)) | |||
create_if_not_exists(os.path.join(modules_path)) | |||
create_if_not_exists(os.path.join(modules_path, dt)) | |||
create_if_not_exists(os.path.join(modules_path, dt, dn)) | |||
def create_folder(module, dt, dn): | |||
""" | |||
@@ -45,7 +44,7 @@ def create_folder(module, dt, dn): | |||
# create init_py_files | |||
if code_type: | |||
create_init_py(modules_path, module, scrub(dt), scrub(dn)) | |||
create_init_py(modules_path, scrub(dt), scrub(dn)) | |||
return folder | |||
@@ -87,10 +87,10 @@ def make_cache_table(): | |||
def dump(sd, country): | |||
import webnotes | |||
import webnotes.model.doclist | |||
import webnotes.model.utils | |||
if sd.get('docs'): | |||
sd['docs'] = webnotes.model.doclist.compress(sd['docs']) | |||
sd['docs'] = webnotes.model.utils.compress(sd['docs']) | |||
# delete earlier (?) | |||
webnotes.conn.sql("delete from __SessionCache where user=%s and country=%s", (webnotes.session['user'], country)) | |||
@@ -174,15 +174,17 @@ def check_guest_access(doc): | |||
#=========================================================================================== | |||
def runserverobj(): | |||
""" | |||
Run server objects | |||
""" | |||
import webnotes.model.code | |||
import webnotes.model.doclist | |||
from webnotes.model.doclist import DocList | |||
from webnotes.utils import cint | |||
form = webnotes.form | |||
doclist = None | |||
method = form.getvalue('method') | |||
doclist, clientlist = [], [] | |||
arg = form.getvalue('arg') | |||
dt = form.getvalue('doctype') | |||
dn = form.getvalue('docname') | |||
@@ -192,46 +194,23 @@ def runserverobj(): | |||
so = webnotes.model.code.get_obj(dt, dn) | |||
else: | |||
clientlist = webnotes.model.doclist.expand(form.getvalue('docs')) | |||
# find main doc | |||
for d in clientlist: | |||
if cint(d.get('docstatus')) != 2 and not d.get('parent'): | |||
main_doc = webnotes.model.doc.Document(fielddata = d) | |||
# find child docs | |||
for d in clientlist: | |||
doc = webnotes.model.doc.Document(fielddata = d) | |||
if doc.fields.get('parent'): | |||
doclist.append(doc) | |||
so = webnotes.model.code.get_server_obj(main_doc, doclist) | |||
# check integrity | |||
if not check_integrity(so.doc): | |||
return | |||
doclist = DocList() | |||
doclist.from_compressed(form.getvalue('docs'), form.getvalue('docname')) | |||
so = doclist.make_obj() | |||
check_guest_access(so.doc) | |||
if so: | |||
r = webnotes.model.code.run_server_obj(so, method, arg) | |||
doclist = so.doclist # reference back [in case of null] | |||
if r: | |||
try: | |||
if r['doclist']: | |||
clientlist += r['doclist'] | |||
except: | |||
pass | |||
if r: | |||
#build output as csv | |||
if cint(webnotes.form.getvalue('as_csv')): | |||
make_csv_output(r, so.doc.doctype) | |||
else: | |||
webnotes.response['message'] = r | |||
if clientlist: | |||
doclist.append(main_doc) | |||
webnotes.response['docs'] = doclist | |||
if doclist: | |||
webnotes.response['docs'] = doclist.docs | |||
def make_csv_output(res, dt): | |||
import webnotes | |||
@@ -252,169 +231,29 @@ def make_csv_output(res, dt): | |||
webnotes.response['doctype'] = dt.replace(' ','') | |||
# Document Save | |||
#=========================================================================================== | |||
def _get_doclist(clientlist): | |||
# converts doc dictionaries into Document objects | |||
from webnotes.model.doc import Document | |||
form = webnotes.form | |||
midx = 0 | |||
for i in range(len(clientlist)): | |||
if clientlist[i]['name'] == form.getvalue('docname'): | |||
main_doc = Document(fielddata = clientlist[i]) | |||
midx = i | |||
else: | |||
clientlist[i] = Document(fielddata = clientlist[i]) | |||
del clientlist[midx] | |||
return main_doc, clientlist | |||
def _do_action(doc, doclist, so, method_name, docstatus=0): | |||
from webnotes.model.code import run_server_obj | |||
set = webnotes.conn.set | |||
if so and hasattr(so, method_name): | |||
errmethod = method_name | |||
run_server_obj(so, method_name) | |||
if hasattr(so, 'custom_'+method_name): | |||
run_server_obj(so, 'custom_'+method_name) | |||
errmethod = '' | |||
# fire triggers observers (if any) | |||
fire_event(doc, method_name) | |||
# set docstatus for all children records | |||
if docstatus: | |||
for d in [doc] + doclist: | |||
if int(d.docstatus or 0) != 2: | |||
set(d, 'docstatus', docstatus) | |||
def check_integrity(doc): | |||
import webnotes | |||
if (not webnotes.model.meta.is_single(doc.doctype)) and (not doc.fields.get('__islocal')): | |||
tmp = webnotes.conn.sql('SELECT modified FROM `tab%s` WHERE name="%s" for update' % (doc.doctype, doc.name)) | |||
if tmp and str(tmp[0][0]) != str(doc.modified): | |||
webnotes.msgprint('Document has been modified after you have opened it. To maintain the integrity of the data, you will not be able to save your changes. Please refresh this document. [%s/%s]' % (tmp[0][0], doc.modified)) | |||
return 0 | |||
return 1 | |||
#=========================================================================================== | |||
def savedocs(): | |||
import webnotes.model.doclist | |||
from webnotes.model.code import get_server_obj | |||
from webnotes.model.code import run_server_obj | |||
import webnotes.utils | |||
from webnotes.widgets.auto_master import update_auto_masters | |||
from webnotes.utils import cint | |||
sql = webnotes.conn.sql | |||
form = webnotes.form | |||
# action | |||
action = form.getvalue('action') | |||
# get docs | |||
doc, doclist = _get_doclist(webnotes.model.doclist.expand(form.getvalue('docs'))) | |||
# get server object | |||
server_obj = get_server_obj(doc, doclist) | |||
try: | |||
from webnotes.model.doclist import DocList | |||
form = webnotes.form_dict | |||
# check integrity | |||
if not check_integrity(doc): | |||
return | |||
if not doc.check_perm(verbose=1): | |||
webnotes.msgprint("Not enough permission to save %s" % doc.doctype) | |||
return | |||
# validate links | |||
ret = webnotes.model.doclist.validate_links_doclist([doc] + doclist) | |||
if ret: | |||
webnotes.msgprint("[Link Validation] Could not find the following values: %s. Please correct and resave. Document Not Saved." % ret) | |||
return | |||
doclist = DocList() | |||
doclist.from_compressed(form.get('docs'), form.get('docname')) | |||
# saving & post-saving | |||
try: | |||
# validate befor saving and submitting | |||
if action in ('Save', 'Submit') and server_obj: | |||
if hasattr(server_obj, 'validate'): | |||
t = run_server_obj(server_obj, 'validate') | |||
if hasattr(server_obj, 'custom_validate'): | |||
t = run_server_obj(server_obj, 'custom_validate') | |||
# set owner and modified times | |||
is_new = cint(doc.fields.get('__islocal')) | |||
if is_new and not doc.owner: | |||
doc.owner = form.getvalue('user') | |||
doc.modified, doc.modified_by = webnotes.utils.now(), webnotes.session['user'] | |||
# save main doc | |||
try: | |||
t = doc.save(is_new) | |||
update_auto_masters(doc) | |||
except NameError, e: | |||
webnotes.msgprint('%s "%s" already exists' % (doc.doctype, doc.name)) | |||
if webnotes.conn.sql("select docstatus from `tab%s` where name=%s" % (doc.doctype, '%s'), doc.name)[0][0]==2: | |||
webnotes.msgprint('[%s "%s" has been cancelled]' % (doc.doctype, doc.name)) | |||
webnotes.errprint(webnotes.utils.getTraceback()) | |||
raise e | |||
# save child docs | |||
for d in doclist: | |||
deleted, local = d.fields.get('__deleted',0), d.fields.get('__islocal',0) | |||
if cint(local) and cint(deleted): | |||
pass | |||
elif d.fields.has_key('parent'): | |||
if d.parent and (not d.parent.startswith('old_parent:')): | |||
d.parent = doc.name # rename if reqd | |||
d.parenttype = doc.doctype | |||
d.modified, d.modified_by = webnotes.utils.now(), webnotes.session['user'] | |||
d.save(new = cint(local)) | |||
update_auto_masters(d) | |||
# on_update | |||
if action in ('Save','Submit') and server_obj: | |||
if hasattr(server_obj, 'on_update'): | |||
t = run_server_obj(server_obj, 'on_update') | |||
if t: webnotes.msgprint(t) | |||
if hasattr(server_obj, 'custom_on_update'): | |||
t = run_server_obj(server_obj, 'custom_on_update') | |||
if t: webnotes.msgprint(t) | |||
# action | |||
action = form.get('action') | |||
fire_event(doc, 'on_update') | |||
# on_submit | |||
if action == 'Submit': | |||
_do_action(doc, doclist, server_obj, 'on_submit', 1) | |||
if action=='Update': action='update_after_submit' | |||
# for allow_on_submit type | |||
if action == 'Update': | |||
_do_action(doc, doclist, server_obj, 'on_update_after_submit', 0) | |||
# on_cancel | |||
if action == 'Cancel': | |||
_do_action(doc, doclist, server_obj, 'on_cancel', 2) | |||
getattr(doclist, action.lower())() | |||
# update recent documents | |||
webnotes.user.update_recent(doc.doctype, doc.name) | |||
webnotes.user.update_recent(doclist.doc.doctype, doclist.doc.name) | |||
# send updated docs | |||
webnotes.response['saved'] = '1' | |||
webnotes.response['main_doc_name'] = doc.name | |||
webnotes.response['docname'] = doc.name | |||
webnotes.response['docs'] = [doc] + doclist | |||
webnotes.response['main_doc_name'] = doclist.doc.name | |||
webnotes.response['docname'] = doclist.doc.name | |||
webnotes.response['docs'] = [doclist.doc] + doclist.children | |||
except Exception, e: | |||
webnotes.msgprint('Did not save') | |||
@@ -4,8 +4,7 @@ Documentation Help: | |||
1. To rebuild documentation | |||
--------------------------- | |||
(set webnotes path in conf.py in this folder) | |||
make html | |||
make html | |||
2. Install | |||
----------- | |||