-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow to cancel draft transactions #21515
Comments
Let's figure something out in Framework only 😔 Probable design:
Alternates:
Basically, the problem is that apps have treated these docstatus numbers as if they have some ordinality. In reality, it's just an enum. In the worst case we can treat this as breaking change and push in next version only if required. |
What made you change your mind from favouring the application-level approach? |
15 upvotes lol |
That's what we have in Dokos (French fork of ERPNext): a name after submit feature.
class Document:
...
def _save(self):
...
if self._action == "submit" and self.meta.name_after_submit and not self.flags.name_set:
self._draft_name = self.name # Client-side rename
self.set_new_name(set_child_names=False) # Magic happens here tooo
from frappe.model.rename_doc import rename_doc
rename_doc( # Destroys cache 😢
self.doctype,
self._draft_name,
self.name,
ignore_permissions=True,
force=True,
show_alert=False,
)
With Dokos' system, drafts don't lead to gaps because they don't use the Naming Series, and cancelled transactions can't be deleted (for legal reasons). We also have an archiving feature thanks to an Archived Document doctype (basically a JSON snapshot of the document), which means that it's not possible to delete a submitted document. And we ensure "immutability/fraud detection" by using a chain of hashes (what we call a seal). class ArchivedDocument(Document):
...
data: DF.JSON
hash: DF.Data
reference_docname: DF.DynamicLink
reference_doctype: DF.Link # Link to document -> prevents deleting linked doc!
def on_trash(self):
raise frappe.PermissionError
def on_cancel(self):
raise frappe.PermissionError
def before_insert(self):
...
self.hash = chained_seal
self.data = frappe.as_json(sealed_doc) |
I've considered rename_doc before, rename doc is dangerous on large databases because it tries to rename every link field everywhere on submit. It's a big no no from performance POV. One unindexed field on large table is all it takes to severly slow down submissions. We'd have to write a stripped down variant of rename doc to use it for draft->submit documents. |
Yes, so maybe we can't touch the primary key.
Could be shown in place of the
|
Maybe a backwards compatible way of handling this dual naming scheme would be to have the "Transaction ID" field be an alternate name for the document? There would be two ways to access a document on the desk:
Listview and Pros: nicer for the users / Cons: … |
Is your feature request related to a problem? Please describe.
For sales transactions, many companies prefer consecutive numbering, e.g. Sales Invoice 1, 2, 3, 4, 5 without any gaps.
Gaps arise when draft or cancelled transactions get deleted. A simple solution is to disallow deletion of transactions. Cancelled transactions are clearly marked as such and do not confuse the user.
However, draft transactions appear to be open forever. We don't want to submit them, we cannot cancel them and we disallowed deletion to achieve consecutive numbering. Unused drafts are accumulating and there is no way to distinguish them from drafts that are being actively worked on.
Describe the solution you'd like
Allow to cancel draft transactions. There are no GL Entries or similar to take care of yet. So this might be as simple as
doc.db_set("docstatus", 2)
. The only effect this should have is to mark the transaction as cancelled, no longer needed.Describe alternatives you've considered
Use hash naming for the transactions and store the transaction number as per naming series in a separate field that is populated on submit. Draft transactions don't get a number yet, so they cannot cause gaps.
Alternative suggested by @ankush: have an additional status "Discarded" (docstatus stays at 0) at the application layer (erpnext or equivalent) to avoid confusion with the current cancel functionality
Related: #14708
The text was updated successfully, but these errors were encountered: