refactor: set amended docname to original docname
This commit is contained in:
parent
75ea09f9df
commit
1c4e1bc1df
7 changed files with 105 additions and 16 deletions
|
|
@ -74,6 +74,7 @@ class DocType(Document):
|
|||
if not self.istable:
|
||||
validate_permissions(self)
|
||||
|
||||
self.make_cancellable()
|
||||
self.make_amendable()
|
||||
self.make_repeatable()
|
||||
self.validate_nestedset()
|
||||
|
|
@ -589,6 +590,21 @@ class DocType(Document):
|
|||
"no_copy": 1
|
||||
})
|
||||
|
||||
def make_cancellable(self):
|
||||
"""If is_submittable is set, add original_name docfield."""
|
||||
if self.is_submittable:
|
||||
if not frappe.db.sql("""select name from tabDocField
|
||||
where fieldname = 'original_name' and parent = %s""", self.name):
|
||||
self.append("fields", {
|
||||
"label": "Original Name",
|
||||
"fieldtype": "Text",
|
||||
"fieldname": "original_name",
|
||||
"read_only": 1,
|
||||
"hidden": 1,
|
||||
"print_hide": 1,
|
||||
"no_copy": 1
|
||||
})
|
||||
|
||||
def make_repeatable(self):
|
||||
"""If allow_auto_repeat is set, add auto_repeat custom field."""
|
||||
if self.allow_auto_repeat:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import time
|
|||
from frappe import _, msgprint, is_whitelisted
|
||||
from frappe.utils import flt, cstr, now, get_datetime_str, file_lock, date_diff
|
||||
from frappe.model.base_document import BaseDocument, get_controller
|
||||
from frappe.model.naming import set_new_name
|
||||
from frappe.model.naming import set_new_name, rename_cancelled_doc
|
||||
from six import iteritems, string_types
|
||||
from werkzeug.exceptions import NotFound, Forbidden
|
||||
import hashlib, json
|
||||
|
|
@ -919,6 +919,14 @@ class Document(BaseDocument):
|
|||
@whitelist.__func__
|
||||
def _cancel(self):
|
||||
"""Cancel the document. Sets `docstatus` = 2, then saves."""
|
||||
|
||||
# for backward compatibility
|
||||
if self.amended_from and not self.original_name:
|
||||
self.original_name = None
|
||||
else:
|
||||
self.original_name = self.name
|
||||
|
||||
self.name = rename_cancelled_doc(self)
|
||||
self.docstatus = 2
|
||||
self.save()
|
||||
|
||||
|
|
|
|||
|
|
@ -223,7 +223,16 @@ def revert_series_if_last(key, name, doc=None):
|
|||
* prefix = #### and hashes = 2021 (hash doesn't exist)
|
||||
* will search hash in key then accordingly get prefix = ""
|
||||
"""
|
||||
if ".#" in key:
|
||||
|
||||
# do not revert if doc is amended, since cancelled docs still exist
|
||||
if doc.docstatus != 2 and doc.amended_from:
|
||||
return
|
||||
|
||||
# for first cancelled doc
|
||||
if doc.docstatus == 2 and not doc.amended_from and doc.original_name:
|
||||
name = doc.original_name
|
||||
|
||||
if ".#" in key:
|
||||
prefix, hashes = key.rsplit(".", 1)
|
||||
if "#" not in hashes:
|
||||
# get the hash part from the key
|
||||
|
|
@ -306,14 +315,48 @@ def append_number_if_name_exists(doctype, value, fieldname="name", separator="-"
|
|||
|
||||
|
||||
def _set_amended_name(doc):
|
||||
if doc.original_name:
|
||||
doc.name = doc.original_name
|
||||
else:
|
||||
original_name = get_original_name(doc)
|
||||
doc.name = doc.amended_from
|
||||
|
||||
# rename original doc to next name in series, and set amended doc name as original name
|
||||
next_name_in_series = get_new_name_from_amended_from(doc)
|
||||
frappe.rename_doc(doc.doctype, original_name, next_name_in_series, force=True, show_alert=False)
|
||||
doc.name = original_name
|
||||
doc.amended_from = next_name_in_series
|
||||
doc.original_name = original_name
|
||||
|
||||
return doc.name
|
||||
|
||||
def get_original_name(doc):
|
||||
# get original doc name from chain of amended docs
|
||||
amended_from = original_name = doc.amended_from
|
||||
while amended_from:
|
||||
original_name = amended_from
|
||||
amended_from = frappe.db.get_value(doc.doctype, amended_from, "amended_from")
|
||||
|
||||
return original_name
|
||||
|
||||
def get_new_name_from_amended_from(doc):
|
||||
am_id = 1
|
||||
am_prefix = doc.amended_from
|
||||
if frappe.db.get_value(doc.doctype, doc.amended_from, "amended_from"):
|
||||
am_prefix = doc.name
|
||||
if frappe.db.get_value(doc.doctype, doc.name, "amended_from"):
|
||||
am_id = cint(doc.amended_from.split("-")[-1]) + 1
|
||||
am_prefix = "-".join(doc.amended_from.split("-")[:-1]) # except the last hyphen
|
||||
|
||||
doc.name = am_prefix + "-" + str(am_id)
|
||||
return doc.name
|
||||
new_name = am_prefix + "-" + str(am_id)
|
||||
if new_name == doc.name:
|
||||
am_id += 1
|
||||
new_name = am_prefix + "-" + str(am_id)
|
||||
return new_name
|
||||
|
||||
def rename_cancelled_doc(doc):
|
||||
doc = frappe.parse_json(doc)
|
||||
new_name = get_new_name_from_amended_from(doc)
|
||||
frappe.rename_doc(doc.doctype, doc.name, new_name, force=True, show_alert=False)
|
||||
return new_name
|
||||
|
||||
|
||||
def _field_autoname(autoname, doc, skip_slicing=None):
|
||||
|
|
|
|||
|
|
@ -337,3 +337,4 @@ frappe.patches.v12_0.rename_uploaded_files_with_proper_name
|
|||
frappe.patches.v13_0.queryreport_columns
|
||||
frappe.patches.v13_0.jinja_hook
|
||||
frappe.patches.v13_0.update_notification_channel_if_empty
|
||||
frappe.patches.v13_0.add_original_name_docfield_to_submittable_doctypes #######
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
import frappe
|
||||
from frappe.database.schema import add_column
|
||||
|
||||
def execute():
|
||||
for doctype in frappe.db.get_all('DocType'):
|
||||
doctype = frappe.get_doc("DocType", doctype.name)
|
||||
if doctype.is_submittable and frappe.db.table_exists(doctype.name):
|
||||
doctype.make_cancellable()
|
||||
if not frappe.db.has_column(doctype.name, 'original_name'):
|
||||
add_column(doctype.name, 'original_name', 'Text')
|
||||
doctype.db_update_all()
|
||||
|
|
@ -764,32 +764,36 @@ frappe.ui.form.Form = class FrappeForm {
|
|||
}
|
||||
|
||||
_cancel(btn, callback, on_error, skip_confirm) {
|
||||
const me = this;
|
||||
const cancel_doc = () => {
|
||||
frappe.validated = true;
|
||||
me.script_manager.trigger("before_cancel").then(() => {
|
||||
this.script_manager.trigger("before_cancel").then(() => {
|
||||
if (!frappe.validated) {
|
||||
return me.handle_save_fail(btn, on_error);
|
||||
return this.handle_save_fail(btn, on_error);
|
||||
}
|
||||
|
||||
var after_cancel = function(r) {
|
||||
const original_name = this.docname;
|
||||
const after_cancel = (r) => {
|
||||
if (r.exc) {
|
||||
me.handle_save_fail(btn, on_error);
|
||||
this.handle_save_fail(btn, on_error);
|
||||
} else {
|
||||
frappe.utils.play_sound("cancel");
|
||||
me.refresh();
|
||||
callback && callback();
|
||||
me.script_manager.trigger("after_cancel");
|
||||
this.script_manager.trigger("after_cancel");
|
||||
frappe.run_serially([
|
||||
() => this.rename_notify(this.doctype, original_name, r.docs[0].name),
|
||||
() => frappe.router.clear_re_route(this.doctype, original_name),
|
||||
() => this.refresh(),
|
||||
]);
|
||||
}
|
||||
};
|
||||
frappe.ui.form.save(me, "cancel", after_cancel, btn);
|
||||
frappe.ui.form.save(this, "cancel", after_cancel, btn);
|
||||
});
|
||||
}
|
||||
|
||||
if (skip_confirm) {
|
||||
cancel_doc();
|
||||
} else {
|
||||
frappe.confirm(__("Permanently Cancel {0}?", [this.docname]), cancel_doc, me.handle_save_fail(btn, on_error));
|
||||
frappe.confirm(__("Permanently Cancel {0}?", [this.docname]), cancel_doc, this.handle_save_fail(btn, on_error));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -811,7 +815,7 @@ frappe.ui.form.Form = class FrappeForm {
|
|||
'docname': this.doc.name
|
||||
}).then(is_amended => {
|
||||
if (is_amended) {
|
||||
frappe.throw(__('This document is already amended, you cannot ammend it again'));
|
||||
frappe.throw(__('This document is already amended, you cannot amend it again'));
|
||||
}
|
||||
this.validate_form_action("Amend");
|
||||
var me = this;
|
||||
|
|
|
|||
|
|
@ -235,6 +235,12 @@ frappe.router = {
|
|||
}
|
||||
},
|
||||
|
||||
clear_re_route(doctype, docname) {
|
||||
delete frappe.re_route[
|
||||
`${encodeURIComponent(frappe.router.slug(doctype))}/${encodeURIComponent(docname)}`
|
||||
];
|
||||
},
|
||||
|
||||
set_title(sub_path) {
|
||||
if (frappe.route_titles[sub_path]) {
|
||||
frappe.utils.set_title(frappe.route_titles[sub_path]);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue