feat: Transaction Deletion Record (#25354)
Co-authored-by: Saqib <nextchamp.saqib@gmail.com>
This commit is contained in:
parent
6e179c3092
commit
f2eb8dd1d5
@ -100,6 +100,10 @@ status_map = {
|
|||||||
["Queued", "eval:self.status == 'Queued'"],
|
["Queued", "eval:self.status == 'Queued'"],
|
||||||
["Failed", "eval:self.status == 'Failed'"],
|
["Failed", "eval:self.status == 'Failed'"],
|
||||||
["Cancelled", "eval:self.docstatus == 2"],
|
["Cancelled", "eval:self.docstatus == 2"],
|
||||||
|
],
|
||||||
|
"Transaction Deletion Record": [
|
||||||
|
["Draft", None],
|
||||||
|
["Completed", "eval:self.docstatus == 1"],
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,9 +169,9 @@ frappe.ui.form.on("Company", {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.setup.doctype.company.delete_company_transactions.delete_company_transactions",
|
method: "erpnext.setup.doctype.company.company.create_transaction_deletion_request",
|
||||||
args: {
|
args: {
|
||||||
company_name: data.company_name
|
company: data.company_name
|
||||||
},
|
},
|
||||||
freeze: true,
|
freeze: true,
|
||||||
callback: function(r, rt) {
|
callback: function(r, rt) {
|
||||||
|
@ -613,4 +613,13 @@ def get_default_company_address(name, sort_key='is_primary_address', existing_ad
|
|||||||
if out:
|
if out:
|
||||||
return sorted(out, key = functools.cmp_to_key(lambda x,y: cmp(y[1], x[1])))[0][0]
|
return sorted(out, key = functools.cmp_to_key(lambda x,y: cmp(y[1], x[1])))[0][0]
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def create_transaction_deletion_request(company):
|
||||||
|
tdr = frappe.get_doc({
|
||||||
|
'doctype': 'Transaction Deletion Record',
|
||||||
|
'company': company
|
||||||
|
})
|
||||||
|
tdr.insert()
|
||||||
|
tdr.submit()
|
||||||
|
@ -1,117 +0,0 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
|
||||||
# License: GNU General Public License v3. See license.txt
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import frappe
|
|
||||||
|
|
||||||
from frappe.utils import cint
|
|
||||||
from frappe import _
|
|
||||||
from frappe.desk.notifications import clear_notifications
|
|
||||||
|
|
||||||
import functools
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
|
||||||
def delete_company_transactions(company_name):
|
|
||||||
frappe.only_for("System Manager")
|
|
||||||
doc = frappe.get_doc("Company", company_name)
|
|
||||||
|
|
||||||
if frappe.session.user != doc.owner and frappe.session.user != 'Administrator':
|
|
||||||
frappe.throw(_("Transactions can only be deleted by the creator of the Company"),
|
|
||||||
frappe.PermissionError)
|
|
||||||
|
|
||||||
delete_bins(company_name)
|
|
||||||
delete_lead_addresses(company_name)
|
|
||||||
|
|
||||||
for doctype in frappe.db.sql_list("""select parent from
|
|
||||||
tabDocField where fieldtype='Link' and options='Company'"""):
|
|
||||||
if doctype not in ("Account", "Cost Center", "Warehouse", "Budget",
|
|
||||||
"Party Account", "Employee", "Sales Taxes and Charges Template",
|
|
||||||
"Purchase Taxes and Charges Template", "POS Profile", "BOM",
|
|
||||||
"Company", "Bank Account", "Item Tax Template", "Mode Of Payment", "Mode of Payment Account",
|
|
||||||
"Item Default", "Customer", "Supplier", "GST Account"):
|
|
||||||
delete_for_doctype(doctype, company_name)
|
|
||||||
|
|
||||||
# reset company values
|
|
||||||
doc.total_monthly_sales = 0
|
|
||||||
doc.sales_monthly_history = None
|
|
||||||
doc.save()
|
|
||||||
# Clear notification counts
|
|
||||||
clear_notifications()
|
|
||||||
|
|
||||||
def delete_for_doctype(doctype, company_name):
|
|
||||||
meta = frappe.get_meta(doctype)
|
|
||||||
company_fieldname = meta.get("fields", {"fieldtype": "Link",
|
|
||||||
"options": "Company"})[0].fieldname
|
|
||||||
|
|
||||||
if not meta.issingle:
|
|
||||||
if not meta.istable:
|
|
||||||
# delete communication
|
|
||||||
delete_communications(doctype, company_name, company_fieldname)
|
|
||||||
|
|
||||||
# delete children
|
|
||||||
for df in meta.get_table_fields():
|
|
||||||
frappe.db.sql("""delete from `tab{0}` where parent in
|
|
||||||
(select name from `tab{1}` where `{2}`=%s)""".format(df.options,
|
|
||||||
doctype, company_fieldname), company_name)
|
|
||||||
|
|
||||||
#delete version log
|
|
||||||
frappe.db.sql("""delete from `tabVersion` where ref_doctype=%s and docname in
|
|
||||||
(select name from `tab{0}` where `{1}`=%s)""".format(doctype,
|
|
||||||
company_fieldname), (doctype, company_name))
|
|
||||||
|
|
||||||
# delete parent
|
|
||||||
frappe.db.sql("""delete from `tab{0}`
|
|
||||||
where {1}= %s """.format(doctype, company_fieldname), company_name)
|
|
||||||
|
|
||||||
# reset series
|
|
||||||
naming_series = meta.get_field("naming_series")
|
|
||||||
if naming_series and naming_series.options:
|
|
||||||
prefixes = sorted(naming_series.options.split("\n"),
|
|
||||||
key=functools.cmp_to_key(lambda a, b: len(b) - len(a)))
|
|
||||||
|
|
||||||
for prefix in prefixes:
|
|
||||||
if prefix:
|
|
||||||
last = frappe.db.sql("""select max(name) from `tab{0}`
|
|
||||||
where name like %s""".format(doctype), prefix + "%")
|
|
||||||
if last and last[0][0]:
|
|
||||||
last = cint(last[0][0].replace(prefix, ""))
|
|
||||||
else:
|
|
||||||
last = 0
|
|
||||||
|
|
||||||
frappe.db.sql("""update tabSeries set current = %s
|
|
||||||
where name=%s""", (last, prefix))
|
|
||||||
|
|
||||||
def delete_bins(company_name):
|
|
||||||
frappe.db.sql("""delete from tabBin where warehouse in
|
|
||||||
(select name from tabWarehouse where company=%s)""", company_name)
|
|
||||||
|
|
||||||
def delete_lead_addresses(company_name):
|
|
||||||
"""Delete addresses to which leads are linked"""
|
|
||||||
leads = frappe.get_all("Lead", filters={"company": company_name})
|
|
||||||
leads = [ "'%s'"%row.get("name") for row in leads ]
|
|
||||||
addresses = []
|
|
||||||
if leads:
|
|
||||||
addresses = frappe.db.sql_list("""select parent from `tabDynamic Link` where link_name
|
|
||||||
in ({leads})""".format(leads=",".join(leads)))
|
|
||||||
|
|
||||||
if addresses:
|
|
||||||
addresses = ["%s" % frappe.db.escape(addr) for addr in addresses]
|
|
||||||
|
|
||||||
frappe.db.sql("""delete from tabAddress where name in ({addresses}) and
|
|
||||||
name not in (select distinct dl1.parent from `tabDynamic Link` dl1
|
|
||||||
inner join `tabDynamic Link` dl2 on dl1.parent=dl2.parent
|
|
||||||
and dl1.link_doctype<>dl2.link_doctype)""".format(addresses=",".join(addresses)))
|
|
||||||
|
|
||||||
frappe.db.sql("""delete from `tabDynamic Link` where link_doctype='Lead'
|
|
||||||
and parenttype='Address' and link_name in ({leads})""".format(leads=",".join(leads)))
|
|
||||||
|
|
||||||
frappe.db.sql("""update tabCustomer set lead_name=NULL where lead_name in ({leads})""".format(leads=",".join(leads)))
|
|
||||||
|
|
||||||
def delete_communications(doctype, company_name, company_fieldname):
|
|
||||||
reference_docs = frappe.get_all(doctype, filters={company_fieldname:company_name})
|
|
||||||
reference_doc_names = [r.name for r in reference_docs]
|
|
||||||
|
|
||||||
communications = frappe.get_all("Communication", filters={"reference_doctype":doctype,"reference_name":["in", reference_doc_names]})
|
|
||||||
communication_names = [c.name for c in communications]
|
|
||||||
|
|
||||||
frappe.delete_doc("Communication", communication_names, ignore_permissions=True)
|
|
@ -86,15 +86,6 @@ class TestCompany(unittest.TestCase):
|
|||||||
self.delete_mode_of_payment(template)
|
self.delete_mode_of_payment(template)
|
||||||
frappe.delete_doc("Company", template)
|
frappe.delete_doc("Company", template)
|
||||||
|
|
||||||
def test_delete_communication(self):
|
|
||||||
from erpnext.setup.doctype.company.delete_company_transactions import delete_communications
|
|
||||||
company = create_child_company()
|
|
||||||
lead = create_test_lead_in_company(company)
|
|
||||||
communication = create_company_communication("Lead", lead)
|
|
||||||
delete_communications("Lead", "Test Company", "company")
|
|
||||||
self.assertFalse(frappe.db.exists("Communcation", communication))
|
|
||||||
self.assertFalse(frappe.db.exists({"doctype":"Comunication Link", "link_name": communication}))
|
|
||||||
|
|
||||||
def delete_mode_of_payment(self, company):
|
def delete_mode_of_payment(self, company):
|
||||||
frappe.db.sql(""" delete from `tabMode of Payment Account`
|
frappe.db.sql(""" delete from `tabMode of Payment Account`
|
||||||
where company =%s """, (company))
|
where company =%s """, (company))
|
||||||
|
@ -0,0 +1,68 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestTransactionDeletionRecord(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
create_company('Dunder Mifflin Paper Co')
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
frappe.db.rollback()
|
||||||
|
|
||||||
|
def test_doctypes_contain_company_field(self):
|
||||||
|
tdr = create_transaction_deletion_request('Dunder Mifflin Paper Co')
|
||||||
|
for doctype in tdr.doctypes:
|
||||||
|
contains_company = False
|
||||||
|
doctype_fields = frappe.get_meta(doctype.doctype_name).as_dict()['fields']
|
||||||
|
for doctype_field in doctype_fields:
|
||||||
|
if doctype_field['fieldtype'] == 'Link' and doctype_field['options'] == 'Company':
|
||||||
|
contains_company = True
|
||||||
|
break
|
||||||
|
self.assertTrue(contains_company)
|
||||||
|
|
||||||
|
def test_no_of_docs_is_correct(self):
|
||||||
|
for i in range(5):
|
||||||
|
create_task('Dunder Mifflin Paper Co')
|
||||||
|
tdr = create_transaction_deletion_request('Dunder Mifflin Paper Co')
|
||||||
|
for doctype in tdr.doctypes:
|
||||||
|
if doctype.doctype_name == 'Task':
|
||||||
|
self.assertEqual(doctype.no_of_docs, 5)
|
||||||
|
|
||||||
|
def test_deletion_is_successful(self):
|
||||||
|
create_task('Dunder Mifflin Paper Co')
|
||||||
|
create_transaction_deletion_request('Dunder Mifflin Paper Co')
|
||||||
|
tasks_containing_company = frappe.get_all('Task',
|
||||||
|
filters = {
|
||||||
|
'company' : 'Dunder Mifflin Paper Co'
|
||||||
|
})
|
||||||
|
self.assertEqual(tasks_containing_company, [])
|
||||||
|
|
||||||
|
def create_company(company_name):
|
||||||
|
company = frappe.get_doc({
|
||||||
|
'doctype': 'Company',
|
||||||
|
'company_name': company_name,
|
||||||
|
'default_currency': 'INR'
|
||||||
|
})
|
||||||
|
company.insert(ignore_if_duplicate = True)
|
||||||
|
|
||||||
|
def create_transaction_deletion_request(company):
|
||||||
|
tdr = frappe.get_doc({
|
||||||
|
'doctype': 'Transaction Deletion Record',
|
||||||
|
'company': company
|
||||||
|
})
|
||||||
|
tdr.insert()
|
||||||
|
tdr.submit()
|
||||||
|
return tdr
|
||||||
|
|
||||||
|
|
||||||
|
def create_task(company):
|
||||||
|
task = frappe.get_doc({
|
||||||
|
'doctype': 'Task',
|
||||||
|
'company': company,
|
||||||
|
'subject': 'Delete'
|
||||||
|
})
|
||||||
|
task.insert()
|
@ -0,0 +1,40 @@
|
|||||||
|
// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('Transaction Deletion Record', {
|
||||||
|
onload: function(frm) {
|
||||||
|
if (frm.doc.docstatus == 0) {
|
||||||
|
let doctypes_to_be_ignored_array;
|
||||||
|
frappe.call({
|
||||||
|
method: 'erpnext.setup.doctype.transaction_deletion_record.transaction_deletion_record.get_doctypes_to_be_ignored',
|
||||||
|
callback: function(r) {
|
||||||
|
doctypes_to_be_ignored_array = r.message;
|
||||||
|
populate_doctypes_to_be_ignored(doctypes_to_be_ignored_array, frm);
|
||||||
|
frm.fields_dict['doctypes_to_be_ignored'].grid.set_column_disp('no_of_docs', false);
|
||||||
|
frm.refresh_field('doctypes_to_be_ignored');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
frm.get_field('doctypes_to_be_ignored').grid.cannot_add_rows = true;
|
||||||
|
frm.fields_dict['doctypes_to_be_ignored'].grid.set_column_disp('no_of_docs', false);
|
||||||
|
frm.refresh_field('doctypes_to_be_ignored');
|
||||||
|
},
|
||||||
|
|
||||||
|
refresh: function(frm) {
|
||||||
|
frm.fields_dict['doctypes_to_be_ignored'].grid.set_column_disp('no_of_docs', false);
|
||||||
|
frm.refresh_field('doctypes_to_be_ignored');
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
function populate_doctypes_to_be_ignored(doctypes_to_be_ignored_array, frm) {
|
||||||
|
if (!(frm.doc.doctypes_to_be_ignored)) {
|
||||||
|
var i;
|
||||||
|
for (i = 0; i < doctypes_to_be_ignored_array.length; i++) {
|
||||||
|
frm.add_child('doctypes_to_be_ignored', {
|
||||||
|
doctype_name: doctypes_to_be_ignored_array[i]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"autoname": "TDL.####",
|
||||||
|
"creation": "2021-04-06 20:17:18.404716",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"company",
|
||||||
|
"doctypes",
|
||||||
|
"doctypes_to_be_ignored",
|
||||||
|
"amended_from",
|
||||||
|
"status"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "company",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Company",
|
||||||
|
"options": "Company",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "doctypes",
|
||||||
|
"fieldtype": "Table",
|
||||||
|
"label": "Summary",
|
||||||
|
"options": "Transaction Deletion Record Item",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "doctypes_to_be_ignored",
|
||||||
|
"fieldtype": "Table",
|
||||||
|
"label": "Excluded DocTypes",
|
||||||
|
"options": "Transaction Deletion Record Item"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "amended_from",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Amended From",
|
||||||
|
"no_copy": 1,
|
||||||
|
"options": "Transaction Deletion Record",
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "status",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"hidden": 1,
|
||||||
|
"label": "Status",
|
||||||
|
"options": "Draft\nCompleted"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"is_submittable": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2021-05-08 23:13:48.049879",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Setup",
|
||||||
|
"name": "Transaction Deletion Record",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "System Manager",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1
|
||||||
|
}
|
@ -0,0 +1,147 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from frappe.utils import cint
|
||||||
|
import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
from frappe import _
|
||||||
|
from frappe.desk.notifications import clear_notifications
|
||||||
|
|
||||||
|
class TransactionDeletionRecord(Document):
|
||||||
|
def validate(self):
|
||||||
|
frappe.only_for('System Manager')
|
||||||
|
company_obj = frappe.get_doc('Company', self.company)
|
||||||
|
if frappe.session.user != company_obj.owner and frappe.session.user != 'Administrator':
|
||||||
|
frappe.throw(_('Transactions can only be deleted by the creator of the Company or the Administrator.'),
|
||||||
|
frappe.PermissionError)
|
||||||
|
doctypes_to_be_ignored_list = get_doctypes_to_be_ignored()
|
||||||
|
for doctype in self.doctypes_to_be_ignored:
|
||||||
|
if doctype.doctype_name not in doctypes_to_be_ignored_list:
|
||||||
|
frappe.throw(_("DocTypes should not be added manually to the 'Excluded DocTypes' table. You are only allowed to remove entries from it. "), title=_("Not Allowed"))
|
||||||
|
|
||||||
|
def before_submit(self):
|
||||||
|
if not self.doctypes_to_be_ignored:
|
||||||
|
self.populate_doctypes_to_be_ignored_table()
|
||||||
|
|
||||||
|
self.delete_bins()
|
||||||
|
self.delete_lead_addresses()
|
||||||
|
|
||||||
|
company_obj = frappe.get_doc('Company', self.company)
|
||||||
|
# reset company values
|
||||||
|
company_obj.total_monthly_sales = 0
|
||||||
|
company_obj.sales_monthly_history = None
|
||||||
|
company_obj.save()
|
||||||
|
# Clear notification counts
|
||||||
|
clear_notifications()
|
||||||
|
|
||||||
|
singles = frappe.get_all('DocType', filters = {'issingle': 1}, pluck = 'name')
|
||||||
|
tables = frappe.get_all('DocType', filters = {'istable': 1}, pluck = 'name')
|
||||||
|
doctypes_to_be_ignored_list = singles
|
||||||
|
for doctype in self.doctypes_to_be_ignored:
|
||||||
|
doctypes_to_be_ignored_list.append(doctype.doctype_name)
|
||||||
|
|
||||||
|
docfields = frappe.get_all('DocField',
|
||||||
|
filters = {
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'options': 'Company',
|
||||||
|
'parent': ['not in', doctypes_to_be_ignored_list]},
|
||||||
|
fields=['parent', 'fieldname'])
|
||||||
|
|
||||||
|
for docfield in docfields:
|
||||||
|
if docfield['parent'] != self.doctype:
|
||||||
|
no_of_docs = frappe.db.count(docfield['parent'], {
|
||||||
|
docfield['fieldname'] : self.company
|
||||||
|
})
|
||||||
|
|
||||||
|
if no_of_docs > 0:
|
||||||
|
self.delete_version_log(docfield['parent'], docfield['fieldname'])
|
||||||
|
self.delete_communications(docfield['parent'], docfield['fieldname'])
|
||||||
|
|
||||||
|
# populate DocTypes table
|
||||||
|
if docfield['parent'] not in tables:
|
||||||
|
self.append('doctypes', {
|
||||||
|
'doctype_name' : docfield['parent'],
|
||||||
|
'no_of_docs' : no_of_docs
|
||||||
|
})
|
||||||
|
|
||||||
|
# delete the docs linked with the specified company
|
||||||
|
frappe.db.delete(docfield['parent'], {
|
||||||
|
docfield['fieldname'] : self.company
|
||||||
|
})
|
||||||
|
|
||||||
|
naming_series = frappe.db.get_value('DocType', docfield['parent'], 'autoname')
|
||||||
|
if naming_series:
|
||||||
|
if '#' in naming_series:
|
||||||
|
self.update_naming_series(naming_series, docfield['parent'])
|
||||||
|
|
||||||
|
def populate_doctypes_to_be_ignored_table(self):
|
||||||
|
doctypes_to_be_ignored_list = get_doctypes_to_be_ignored()
|
||||||
|
for doctype in doctypes_to_be_ignored_list:
|
||||||
|
self.append('doctypes_to_be_ignored', {
|
||||||
|
'doctype_name' : doctype
|
||||||
|
})
|
||||||
|
|
||||||
|
def update_naming_series(self, naming_series, doctype_name):
|
||||||
|
if '.' in naming_series:
|
||||||
|
prefix, hashes = naming_series.rsplit('.', 1)
|
||||||
|
else:
|
||||||
|
prefix, hashes = naming_series.rsplit('{', 1)
|
||||||
|
last = frappe.db.sql("""select max(name) from `tab{0}`
|
||||||
|
where name like %s""".format(doctype_name), prefix + '%')
|
||||||
|
if last and last[0][0]:
|
||||||
|
last = cint(last[0][0].replace(prefix, ''))
|
||||||
|
else:
|
||||||
|
last = 0
|
||||||
|
|
||||||
|
frappe.db.sql("""update tabSeries set current = %s where name=%s""", (last, prefix))
|
||||||
|
|
||||||
|
def delete_version_log(self, doctype, company_fieldname):
|
||||||
|
frappe.db.sql("""delete from `tabVersion` where ref_doctype=%s and docname in
|
||||||
|
(select name from `tab{0}` where `{1}`=%s)""".format(doctype,
|
||||||
|
company_fieldname), (doctype, self.company))
|
||||||
|
|
||||||
|
def delete_communications(self, doctype, company_fieldname):
|
||||||
|
reference_docs = frappe.get_all(doctype, filters={company_fieldname:self.company})
|
||||||
|
reference_doc_names = [r.name for r in reference_docs]
|
||||||
|
|
||||||
|
communications = frappe.get_all('Communication', filters={'reference_doctype':doctype,'reference_name':['in', reference_doc_names]})
|
||||||
|
communication_names = [c.name for c in communications]
|
||||||
|
|
||||||
|
frappe.delete_doc('Communication', communication_names, ignore_permissions=True)
|
||||||
|
|
||||||
|
def delete_bins(self):
|
||||||
|
frappe.db.sql("""delete from tabBin where warehouse in
|
||||||
|
(select name from tabWarehouse where company=%s)""", self.company)
|
||||||
|
|
||||||
|
def delete_lead_addresses(self):
|
||||||
|
"""Delete addresses to which leads are linked"""
|
||||||
|
leads = frappe.get_all('Lead', filters={'company': self.company})
|
||||||
|
leads = ["'%s'" % row.get("name") for row in leads]
|
||||||
|
addresses = []
|
||||||
|
if leads:
|
||||||
|
addresses = frappe.db.sql_list("""select parent from `tabDynamic Link` where link_name
|
||||||
|
in ({leads})""".format(leads=",".join(leads)))
|
||||||
|
|
||||||
|
if addresses:
|
||||||
|
addresses = ["%s" % frappe.db.escape(addr) for addr in addresses]
|
||||||
|
|
||||||
|
frappe.db.sql("""delete from tabAddress where name in ({addresses}) and
|
||||||
|
name not in (select distinct dl1.parent from `tabDynamic Link` dl1
|
||||||
|
inner join `tabDynamic Link` dl2 on dl1.parent=dl2.parent
|
||||||
|
and dl1.link_doctype<>dl2.link_doctype)""".format(addresses=",".join(addresses)))
|
||||||
|
|
||||||
|
frappe.db.sql("""delete from `tabDynamic Link` where link_doctype='Lead'
|
||||||
|
and parenttype='Address' and link_name in ({leads})""".format(leads=",".join(leads)))
|
||||||
|
|
||||||
|
frappe.db.sql("""update tabCustomer set lead_name=NULL where lead_name in ({leads})""".format(leads=",".join(leads)))
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_doctypes_to_be_ignored():
|
||||||
|
doctypes_to_be_ignored_list = ['Account', 'Cost Center', 'Warehouse', 'Budget',
|
||||||
|
'Party Account', 'Employee', 'Sales Taxes and Charges Template',
|
||||||
|
'Purchase Taxes and Charges Template', 'POS Profile', 'BOM',
|
||||||
|
'Company', 'Bank Account', 'Item Tax Template', 'Mode of Payment',
|
||||||
|
'Item Default', 'Customer', 'Supplier', 'GST Account']
|
||||||
|
return doctypes_to_be_ignored_list
|
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
// License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
frappe.listview_settings['Transaction Deletion Record'] = {
|
||||||
|
get_indicator: function(doc) {
|
||||||
|
if (doc.docstatus == 0) {
|
||||||
|
return [__("Draft"), "red"];
|
||||||
|
} else {
|
||||||
|
return [__("Completed"), "green"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"creation": "2021-04-07 07:34:00.124124",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"doctype_name",
|
||||||
|
"no_of_docs"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "doctype_name",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "DocType",
|
||||||
|
"options": "DocType",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "no_of_docs",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Number of Docs"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"istable": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2021-05-08 23:10:46.166744",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Setup",
|
||||||
|
"name": "Transaction Deletion Record Item",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [],
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class TransactionDeletionRecordItem(Document):
|
||||||
|
pass
|
Loading…
Reference in New Issue
Block a user