Merge branch 'develop' into feat/add-login-user-to-driver

This commit is contained in:
David Arnold
2024-03-29 10:51:30 +01:00
committed by GitHub
1163 changed files with 145040 additions and 63348 deletions

View File

@@ -150,7 +150,6 @@ def convert_order_to_invoices():
document, filters={"docstatus": 1}, fields=["name", "transaction_date"], limit=6
)
):
if document == "Purchase Order":
invoice = make_purchase_invoice(order.name)
elif document == "Sales Order":
@@ -181,8 +180,10 @@ def get_random_date(start_date, start_range, end_range):
def create_transaction_deletion_record(company):
transaction_deletion_record = frappe.new_doc("Transaction Deletion Record")
transaction_deletion_record.company = company
transaction_deletion_record.process_in_single_transaction = True
transaction_deletion_record.save(ignore_permissions=True)
transaction_deletion_record.submit()
transaction_deletion_record.start_deletion_tasks()
def clear_masters():
@@ -215,7 +216,7 @@ def delete_company(company):
def read_data_file_using_hooks(doctype):
path = os.path.join(os.path.dirname(__file__), "demo_data")
with open(os.path.join(path, doctype + ".json"), "r") as f:
with open(os.path.join(path, doctype + ".json")) as f:
data = f.read()
return data

View File

@@ -4,6 +4,7 @@
"item_group": "Demo Item Group",
"item_code": "SKU001",
"item_name": "T-shirt",
"valuation_rate": 400.0,
"gst_hsn_code": "999512",
"image": "https://images.pexels.com/photos/1484808/pexels-photo-1484808.jpeg"
},
@@ -11,6 +12,7 @@
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU002",
"valuation_rate": 300.0,
"item_name": "Laptop",
"gst_hsn_code": "999512",
"image": "https://images.pexels.com/photos/3999538/pexels-photo-3999538.jpeg"
@@ -19,6 +21,7 @@
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU003",
"valuation_rate": 523.0,
"item_name": "Book",
"gst_hsn_code": "999512",
"image": "https://images.pexels.com/photos/2422178/pexels-photo-2422178.jpeg"
@@ -27,6 +30,7 @@
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU004",
"valuation_rate": 725.0,
"item_name": "Smartphone",
"gst_hsn_code": "999512",
"image": "https://images.pexels.com/photos/1647976/pexels-photo-1647976.jpeg"
@@ -35,6 +39,7 @@
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU005",
"valuation_rate": 222.0,
"item_name": "Sneakers",
"gst_hsn_code": "999512",
"image": "https://images.pexels.com/photos/1598505/pexels-photo-1598505.jpeg"
@@ -43,6 +48,7 @@
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU006",
"valuation_rate": 420.0,
"item_name": "Coffee Mug",
"gst_hsn_code": "999512",
"image": "https://images.pexels.com/photos/585753/pexels-photo-585753.jpeg"
@@ -51,6 +57,7 @@
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU007",
"valuation_rate": 375.0,
"item_name": "Television",
"gst_hsn_code": "999512",
"image": "https://images.pexels.com/photos/8059376/pexels-photo-8059376.jpeg"
@@ -59,6 +66,7 @@
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU008",
"valuation_rate": 333.0,
"item_name": "Backpack",
"gst_hsn_code": "999512",
"image": "https://images.pexels.com/photos/3731256/pexels-photo-3731256.jpeg"
@@ -67,6 +75,7 @@
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU009",
"valuation_rate": 700.0,
"item_name": "Headphones",
"gst_hsn_code": "999512",
"image": "https://images.pexels.com/photos/3587478/pexels-photo-3587478.jpeg"
@@ -75,6 +84,7 @@
"doctype": "Item",
"item_group": "Demo Item Group",
"item_code": "SKU010",
"valuation_rate": 500.0,
"item_name": "Camera",
"gst_hsn_code": "999512",
"image": "https://images.pexels.com/photos/51383/photo-camera-subject-photographer-51383.jpeg"

View File

@@ -1,26 +1,20 @@
{
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"creation": "2012-03-27 14:36:18",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"fields": [],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"in_create": 0,
"is_submittable": 0,
"issingle": 1,
"istable": 0,
"modified": "2013-12-20 19:22:54",
"modified_by": "Administrator",
"module": "Setup",
"name": "Authorization Control",
"owner": "Administrator",
"permissions": [],
"read_only": 0,
"read_only_onload": 0
"actions": [],
"creation": "2012-03-27 14:36:18",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [],
"fields": [],
"idx": 1,
"issingle": 1,
"links": [],
"modified": "2024-03-27 13:06:36.513715",
"modified_by": "Administrator",
"module": "Setup",
"name": "Authorization Control",
"owner": "Administrator",
"permissions": [],
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}

View File

@@ -22,7 +22,7 @@ class AuthorizationControl(TransactionBase):
def get_appr_user_role(self, det, doctype_name, total, based_on, condition, master_name, company):
amt_list, appr_users, appr_roles = [], [], []
users, roles = "", ""
_users, _roles = "", ""
if det:
for x in det:
amt_list.append(flt(x[0]))
@@ -30,18 +30,20 @@ class AuthorizationControl(TransactionBase):
app_dtl = frappe.db.sql(
"""select approving_user, approving_role from `tabAuthorization Rule`
where transaction = %s and (value = %s or value > %s)
and docstatus != 2 and based_on = %s and company = %s %s"""
% ("%s", "%s", "%s", "%s", "%s", condition),
where transaction = {} and (value = {} or value > {})
and docstatus != 2 and based_on = {} and company = {} {}""".format(
"%s", "%s", "%s", "%s", "%s", condition
),
(doctype_name, flt(max_amount), total, based_on, company),
)
if not app_dtl:
app_dtl = frappe.db.sql(
"""select approving_user, approving_role from `tabAuthorization Rule`
where transaction = %s and (value = %s or value > %s) and docstatus != 2
and based_on = %s and ifnull(company,'') = '' %s"""
% ("%s", "%s", "%s", "%s", condition),
where transaction = {} and (value = {} or value > {}) and docstatus != 2
and based_on = {} and ifnull(company,'') = '' {}""".format(
"%s", "%s", "%s", "%s", condition
),
(doctype_name, flt(max_amount), total, based_on),
)
@@ -64,18 +66,20 @@ class AuthorizationControl(TransactionBase):
add_cond1 += " and master_name = " + frappe.db.escape(cstr(master_name))
itemwise_exists = frappe.db.sql(
"""select value from `tabAuthorization Rule`
where transaction = %s and value <= %s
and based_on = %s and company = %s and docstatus != 2 %s %s"""
% ("%s", "%s", "%s", "%s", cond, add_cond1),
where transaction = {} and value <= {}
and based_on = {} and company = {} and docstatus != 2 {} {}""".format(
"%s", "%s", "%s", "%s", cond, add_cond1
),
(doctype_name, total, based_on, company),
)
if not itemwise_exists:
itemwise_exists = frappe.db.sql(
"""select value from `tabAuthorization Rule`
where transaction = %s and value <= %s and based_on = %s
and ifnull(company,'') = '' and docstatus != 2 %s %s"""
% ("%s", "%s", "%s", cond, add_cond1),
where transaction = {} and value <= {} and based_on = {}
and ifnull(company,'') = '' and docstatus != 2 {} {}""".format(
"%s", "%s", "%s", cond, add_cond1
),
(doctype_name, total, based_on),
)
@@ -90,18 +94,18 @@ class AuthorizationControl(TransactionBase):
appr = frappe.db.sql(
"""select value from `tabAuthorization Rule`
where transaction = %s and value <= %s and based_on = %s
and company = %s and docstatus != 2 %s %s"""
% ("%s", "%s", "%s", "%s", cond, add_cond2),
where transaction = {} and value <= {} and based_on = {}
and company = {} and docstatus != 2 {} {}""".format("%s", "%s", "%s", "%s", cond, add_cond2),
(doctype_name, total, based_on, company),
)
if not appr:
appr = frappe.db.sql(
"""select value from `tabAuthorization Rule`
where transaction = %s and value <= %s and based_on = %s
and ifnull(company,'') = '' and docstatus != 2 %s %s"""
% ("%s", "%s", "%s", cond, add_cond2),
where transaction = {} and value <= {} and based_on = {}
and ifnull(company,'') = '' and docstatus != 2 {} {}""".format(
"%s", "%s", "%s", cond, add_cond2
),
(doctype_name, total, based_on),
)
@@ -128,7 +132,7 @@ class AuthorizationControl(TransactionBase):
customer = doc_obj.customer
else:
customer = doc_obj.customer_name
add_cond = " and master_name = {}".format(frappe.db.escape(customer))
add_cond = f" and master_name = {frappe.db.escape(customer)}"
if based_on == "Itemwise Discount":
if doc_obj:
for t in doc_obj.get("items"):
@@ -197,11 +201,10 @@ class AuthorizationControl(TransactionBase):
for x in frappe.db.sql(
"""select based_on
from `tabAuthorization Rule`
where transaction = %s and system_role IN (%s) and based_on IN (%s)
and (company = %s or ifnull(company,'')='')
where transaction = {} and system_role IN ({}) and based_on IN ({})
and (company = {} or ifnull(company,'')='')
and docstatus != 2
"""
% (
""".format(
"%s",
"'" + "','".join(frappe.get_roles()) + "'",
"'" + "','".join(final_based_on) + "'",

View File

@@ -162,7 +162,7 @@
"icon": "fa fa-shield",
"idx": 1,
"links": [],
"modified": "2023-09-11 10:29:02.863193",
"modified": "2024-03-27 13:06:36.613880",
"modified_by": "Administrator",
"module": "Setup",
"name": "Authorization Rule",
@@ -183,7 +183,7 @@
],
"search_fields": "transaction,based_on,system_user,system_role,approving_user,approving_role",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}

View File

@@ -88,9 +88,7 @@ class AuthorizationRule(Document):
"Itemwise Discount",
"Item Group wise Discount",
]:
frappe.throw(
_("Cannot set authorization on basis of Discount for {0}").format(self.transaction)
)
frappe.throw(_("Cannot set authorization on basis of Discount for {0}").format(self.transaction))
elif self.based_on == "Average Discount" and flt(self.value) > 100.00:
frappe.throw(_("Discount must be less than 100"))
elif self.based_on == "Customerwise Discount" and not self.master_name:

View File

@@ -1,103 +1,61 @@
{
"allow_copy": 0,
"actions": [],
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:branch",
"beta": 0,
"creation": "2013-01-10 16:34:13",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 0,
"engine": "InnoDB",
"field_order": [
"branch"
],
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "branch",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Branch",
"length": 0,
"no_copy": 0,
"oldfieldname": "branch",
"oldfieldtype": "Data",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"unique": 1
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-code-fork",
"idx": 1,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-07-25 05:24:26.534086",
"links": [],
"modified": "2024-03-27 13:06:42.370664",
"modified_by": "Administrator",
"module": "Setup",
"name": "Branch",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "HR User",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "HR Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
}
],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"track_seen": 0
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}

View File

@@ -56,7 +56,7 @@
"idx": 1,
"image_field": "image",
"links": [],
"modified": "2021-03-01 15:57:30.005783",
"modified": "2024-03-27 13:06:42.500721",
"modified_by": "Administrator",
"module": "Setup",
"name": "Brand",
@@ -106,6 +106,7 @@
],
"quick_entry": 1,
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "ASC"
"sort_field": "creation",
"sort_order": "ASC",
"states": []
}

View File

@@ -168,7 +168,7 @@ frappe.ui.form.on("Company", {
delete_company_transactions: function (frm) {
frappe.call({
method: "erpnext.setup.doctype.company.company.is_deletion_job_running",
method: "erpnext.setup.doctype.transaction_deletion_record.transaction_deletion_record.is_deletion_doc_running",
args: {
company: frm.doc.name,
},

View File

@@ -766,7 +766,7 @@
"image_field": "company_logo",
"is_tree": 1,
"links": [],
"modified": "2023-10-23 10:19:24.322898",
"modified": "2024-03-27 13:06:45.374715",
"modified_by": "Administrator",
"module": "Setup",
"name": "Company",
@@ -825,7 +825,7 @@
}
],
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "ASC",
"states": [],
"track_changes": 1

View File

@@ -12,7 +12,6 @@ from frappe.contacts.address_and_contact import load_address_and_contact
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
from frappe.desk.page.setup_wizard.setup_wizard import make_records
from frappe.utils import cint, formatdate, get_link_to_form, get_timestamp, today
from frappe.utils.background_jobs import get_job, is_job_enqueued
from frappe.utils.nestedset import NestedSet, rebuild_tree
from erpnext.accounts.doctype.account.account import get_account_currency
@@ -123,9 +122,8 @@ class Company(NestedSet):
"Supplier Quotation",
]:
if frappe.db.sql(
"""select name from `tab%s` where company=%s and docstatus=1
limit 1"""
% (doctype, "%s"),
"""select name from `tab{}` where company={} and docstatus=1
limit 1""".format(doctype, "%s"),
self.name,
):
exists = True
@@ -158,9 +156,7 @@ class Company(NestedSet):
if not self.abbr.strip():
frappe.throw(_("Abbreviation is mandatory"))
if frappe.db.sql(
"select abbr from tabCompany where name!=%s and abbr=%s", (self.name, self.abbr)
):
if frappe.db.sql("select abbr from tabCompany where name!=%s and abbr=%s", (self.name, self.abbr)):
frappe.throw(_("Abbreviation already used for another company"))
@frappe.whitelist()
@@ -184,7 +180,9 @@ class Company(NestedSet):
for_company = frappe.db.get_value("Account", self.get(account[1]), "company")
if for_company != self.name:
frappe.throw(
_("Account {0} does not belong to company: {1}").format(self.get(account[1]), self.name)
_("Account {0} does not belong to company: {1}").format(
self.get(account[1]), self.name
)
)
if get_account_currency(self.get(account[1])) != self.default_currency:
@@ -196,9 +194,7 @@ class Company(NestedSet):
def validate_currency(self):
if self.is_new():
return
self.previous_default_currency = frappe.get_cached_value(
"Company", self.name, "default_currency"
)
self.previous_default_currency = frappe.get_cached_value("Company", self.name, "default_currency")
if (
self.default_currency
and self.previous_default_currency
@@ -262,17 +258,14 @@ class Company(NestedSet):
{"warehouse_name": _("Finished Goods"), "is_group": 0},
{"warehouse_name": _("Goods In Transit"), "is_group": 0, "warehouse_type": "Transit"},
]:
if not frappe.db.exists(
"Warehouse", "{0} - {1}".format(wh_detail["warehouse_name"], self.abbr)
):
if not frappe.db.exists("Warehouse", "{} - {}".format(wh_detail["warehouse_name"], self.abbr)):
warehouse = frappe.get_doc(
{
"doctype": "Warehouse",
"warehouse_name": wh_detail["warehouse_name"],
"is_group": wh_detail["is_group"],
"company": self.name,
"parent_warehouse": "{0} - {1}".format(_("All Warehouses"), self.abbr)
"parent_warehouse": "{} - {}".format(_("All Warehouses"), self.abbr)
if not wh_detail["is_group"]
else "",
"warehouse_type": wh_detail.get("warehouse_type"),
@@ -297,9 +290,7 @@ class Company(NestedSet):
self.db_set(
"default_payable_account",
frappe.db.get_value(
"Account", {"company": self.name, "account_type": "Payable", "is_group": 0}
),
frappe.db.get_value("Account", {"company": self.name, "account_type": "Payable", "is_group": 0}),
)
def create_default_departments(self):
@@ -426,7 +417,9 @@ class Company(NestedSet):
and not self.default_provisional_account
):
frappe.throw(
_("Set default {0} account for non stock items").format(frappe.bold("Provisional Account"))
_("Set default {0} account for non stock items").format(
frappe.bold("Provisional Account")
)
)
make_property_setter(
@@ -441,9 +434,7 @@ class Company(NestedSet):
def check_country_change(self):
frappe.flags.country_change = False
if not self.is_new() and self.country != frappe.get_cached_value(
"Company", self.name, "country"
):
if not self.is_new() and self.country != frappe.get_cached_value("Company", self.name, "country"):
frappe.flags.country_change = True
def set_chart_of_accounts(self):
@@ -610,14 +601,14 @@ class Company(NestedSet):
)
for doctype in ["Account", "Cost Center", "Budget", "Party Account"]:
frappe.db.sql("delete from `tab{0}` where company = %s".format(doctype), self.name)
frappe.db.sql(f"delete from `tab{doctype}` where company = %s", self.name)
if not frappe.db.get_value("Stock Ledger Entry", {"company": self.name}):
frappe.db.sql("""delete from `tabWarehouse` where company=%s""", self.name)
frappe.defaults.clear_default("company", value=self.name)
for doctype in ["Mode of Payment Account", "Item Default"]:
frappe.db.sql("delete from `tab{0}` where company = %s".format(doctype), self.name)
frappe.db.sql(f"delete from `tab{doctype}` where company = %s", self.name)
# clear default accounts, warehouses from item
warehouses = frappe.db.sql_list("select name from tabWarehouse where company=%s", self.name)
@@ -650,7 +641,7 @@ class Company(NestedSet):
frappe.db.sql("delete from tabBOM where company=%s", self.name)
for dt in ("BOM Operation", "BOM Item", "BOM Scrap Item", "BOM Explosion Item"):
frappe.db.sql(
"delete from `tab%s` where parent in (%s)" "" % (dt, ", ".join(["%s"] * len(boms))),
"delete from `tab{}` where parent in ({})" "".format(dt, ", ".join(["%s"] * len(boms))),
tuple(boms),
)
@@ -706,7 +697,7 @@ def update_company_current_month_sales(company):
current_month_year = formatdate(today(), "MM-yyyy")
results = frappe.db.sql(
"""
f"""
SELECT
SUM(base_grand_total) AS total,
DATE_FORMAT(`posting_date`, '%m-%Y') AS month_year
@@ -715,12 +706,10 @@ def update_company_current_month_sales(company):
WHERE
DATE_FORMAT(`posting_date`, '%m-%Y') = '{current_month_year}'
AND docstatus = 1
AND company = {company}
AND company = {frappe.db.escape(company)}
GROUP BY
month_year
""".format(
current_month_year=current_month_year, company=frappe.db.escape(company)
),
""",
as_dict=True,
)
@@ -735,9 +724,7 @@ def update_company_monthly_sales(company):
from frappe.utils.goal import get_monthly_results
filter_str = "company = {0} and status != 'Draft' and docstatus=1".format(
frappe.db.escape(company)
)
filter_str = f"company = {frappe.db.escape(company)} and status != 'Draft' and docstatus=1"
month_to_value_dict = get_monthly_results(
"Sales Invoice", "base_grand_total", "posting_date", filter_str, "sum"
)
@@ -747,9 +734,7 @@ def update_company_monthly_sales(company):
def update_transactions_annual_history(company, commit=False):
transactions_history = get_all_transactions_annual_history(company)
frappe.db.set_value(
"Company", company, "transactions_annual_history", json.dumps(transactions_history)
)
frappe.db.set_value("Company", company, "transactions_annual_history", json.dumps(transactions_history))
if commit:
frappe.db.commit()
@@ -765,21 +750,19 @@ def cache_companies_monthly_sales_history():
@frappe.whitelist()
def get_children(doctype, parent=None, company=None, is_root=False):
if parent == None or parent == "All Companies":
if parent is None or parent == "All Companies":
parent = ""
return frappe.db.sql(
"""
f"""
select
name as value,
is_group as expandable
from
`tabCompany` comp
where
ifnull(parent_company, "")={parent}
""".format(
parent=frappe.db.escape(parent)
),
ifnull(parent_company, "")={frappe.db.escape(parent)}
""",
as_dict=1,
)
@@ -855,7 +838,6 @@ def get_all_transactions_annual_history(company):
def get_timeline_data(doctype, name):
"""returns timeline data based on linked records in dashboard"""
out = {}
date_to_value_dict = {}
history = frappe.get_cached_value("Company", name, "transactions_annual_history")
@@ -880,14 +862,13 @@ def get_default_company_address(name, sort_key="is_primary_address", existing_ad
out = frappe.db.sql(
""" SELECT
addr.name, addr.%s
addr.name, addr.{}
FROM
`tabAddress` addr, `tabDynamic Link` dl
WHERE
dl.parent = addr.name and dl.link_doctype = 'Company' and
dl.link_name = %s and ifnull(addr.disabled, 0) = 0
"""
% (sort_key, "%s"),
dl.link_name = {} and ifnull(addr.disabled, 0) = 0
""".format(sort_key, "%s"),
(name),
) # nosec
@@ -901,37 +882,21 @@ def get_default_company_address(name, sort_key="is_primary_address", existing_ad
return None
def generate_id_for_deletion_job(company):
return "delete_company_transactions_" + company
@frappe.whitelist()
def is_deletion_job_running(company):
job_id = generate_id_for_deletion_job(company)
if is_job_enqueued(job_id):
job_name = get_job(job_id).get_id() # job name will have site prefix
frappe.throw(
_("A Transaction Deletion Job: {0} is already running for {1}").format(
frappe.bold(get_link_to_form("RQ Job", job_name)), frappe.bold(company)
)
)
@frappe.whitelist()
def create_transaction_deletion_request(company):
is_deletion_job_running(company)
job_id = generate_id_for_deletion_job(company)
from erpnext.setup.doctype.transaction_deletion_record.transaction_deletion_record import (
is_deletion_doc_running,
)
is_deletion_doc_running(company)
tdr = frappe.get_doc({"doctype": "Transaction Deletion Record", "company": company})
tdr.insert()
tdr.submit()
tdr.start_deletion_tasks()
frappe.enqueue(
"frappe.utils.background_jobs.run_doc_method",
doctype=tdr.doctype,
name=tdr.name,
doc_method="submit",
job_id=job_id,
queue="long",
enqueue_after_commit=True,
frappe.msgprint(
_("A Transaction Deletion Document: {0} is triggered for {0}").format(
get_link_to_form("Transaction Deletion Record", tdr.name)
),
frappe.bold(company),
)
frappe.msgprint(_("A Transaction Deletion Job is triggered for {0}").format(frappe.bold(company)))

View File

@@ -38,7 +38,7 @@ class CurrencyExchange(Document):
if cint(self.for_buying) == 1 and cint(self.for_selling) == 0:
purpose = "Buying"
self.name = "{0}-{1}-{2}{3}".format(
self.name = "{}-{}-{}{}".format(
formatdate(get_datetime_str(self.date), "yyyy-MM-dd"),
self.from_currency,
self.to_currency,

View File

@@ -49,6 +49,7 @@ def save_new_records(test_records):
test_exchange_values = {"2015-12-15": "66.999", "2016-01-15": "65.1"}
# Removing API call from get_exchange_rate
def patched_requests_get(*args, **kwargs):
class PatchResponse:
@@ -83,7 +84,7 @@ class TestCurrencyExchange(unittest.TestCase):
def clear_cache(self):
cache = frappe.cache()
for date in test_exchange_values.keys():
key = "currency_exchange_rate_{0}:{1}:{2}".format(date, "USD", "INR")
key = "currency_exchange_rate_{}:{}:{}".format(date, "USD", "INR")
cache.delete(key)
def tearDown(self):

View File

@@ -139,7 +139,7 @@
"idx": 1,
"is_tree": 1,
"links": [],
"modified": "2023-06-02 13:40:34.435822",
"modified": "2024-03-27 13:06:48.550415",
"modified_by": "Administrator",
"module": "Setup",
"name": "Customer Group",
@@ -210,7 +210,7 @@
],
"search_fields": "parent_customer_group",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}

View File

@@ -41,7 +41,7 @@ class CustomerGroup(NestedSet):
def on_update(self):
self.validate_name_with_customer()
super(CustomerGroup, self).on_update()
super().on_update()
self.validate_one_root()
def validate_name_with_customer(self):

View File

@@ -90,7 +90,7 @@
"idx": 1,
"is_tree": 1,
"links": [],
"modified": "2023-08-28 17:26:46.826501",
"modified": "2024-03-27 13:06:50.845700",
"modified_by": "Administrator",
"module": "Setup",
"name": "Department",
@@ -135,7 +135,7 @@
}
],
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "ASC",
"states": []
}

View File

@@ -51,10 +51,10 @@ class Department(NestedSet):
def on_update(self):
if not (frappe.local.flags.ignore_update_nsm or frappe.flags.in_setup_wizard):
super(Department, self).on_update()
super().on_update()
def on_trash(self):
super(Department, self).on_trash()
super().on_trash()
delete_events(self.doctype, self.name)
@@ -64,7 +64,7 @@ def on_doctype_update():
def get_abbreviated_name(name, company):
abbr = frappe.get_cached_value("Company", company, "abbr")
new_name = "{0} - {1}".format(name, abbr)
new_name = f"{name} - {abbr}"
return new_name

View File

@@ -31,7 +31,7 @@
"icon": "fa fa-bookmark",
"idx": 1,
"links": [],
"modified": "2023-02-10 01:53:41.319386",
"modified": "2024-03-27 13:06:51.361961",
"modified_by": "Administrator",
"module": "Setup",
"name": "Designation",
@@ -56,7 +56,7 @@
],
"quick_entry": 1,
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "ASC",
"states": [],
"translated_doctype": 1

View File

@@ -129,11 +129,10 @@
],
"icon": "fa fa-user",
"links": [],
"modified": "2024-01-23 21:47:12.507540",
"modified": "2024-03-27 13:08:18.825438",
"modified_by": "Administrator",
"module": "Setup",
"name": "Driver",
"naming_rule": "By \"Naming Series\" field",
"owner": "Administrator",
"permissions": [
{
@@ -189,7 +188,7 @@
"quick_entry": 1,
"search_fields": "full_name",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"title_field": "full_name",

View File

@@ -38,14 +38,15 @@
],
"istable": 1,
"links": [],
"modified": "2022-06-27 10:40:55.209022",
"modified": "2024-03-27 13:08:19.062758",
"modified_by": "Administrator",
"module": "Setup",
"name": "Driving License Category",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -310,7 +310,7 @@
"idx": 1,
"index_web_pages_for_search": 1,
"links": [],
"modified": "2020-08-24 23:49:00.081695",
"modified": "2024-03-27 13:09:36.439936",
"modified_by": "Administrator",
"module": "Setup",
"name": "Email Digest",
@@ -333,6 +333,7 @@
"role": "System Manager"
}
],
"sort_field": "modified",
"sort_order": "DESC"
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}

View File

@@ -75,7 +75,7 @@ class EmailDigest(Document):
# end: auto-generated types
def __init__(self, *args, **kwargs):
super(EmailDigest, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.from_date, self.to_date = self.get_from_to_date()
self.set_dates()
@@ -90,9 +90,7 @@ class EmailDigest(Document):
select name, enabled from tabUser
where name not in ({})
and user_type != "Website User"
order by enabled desc, name asc""".format(
", ".join(["%s"] * len(STANDARD_USERS))
),
order by enabled desc, name asc""".format(", ".join(["%s"] * len(STANDARD_USERS))),
STANDARD_USERS,
as_dict=1,
)
@@ -195,15 +193,11 @@ class EmailDigest(Document):
context.text_color = "#36414C"
context.h1 = "margin-bottom: 30px; margin-top: 40px; font-weight: 400; font-size: 30px;"
context.h2 = "margin-bottom: 30px; margin-top: -20px; font-weight: 400; font-size: 20px;"
context.label_css = """display: inline-block; color: {text_muted};
padding: 3px 7px; margin-right: 7px;""".format(
text_muted=context.text_muted
)
context.label_css = f"""display: inline-block; color: {context.text_muted};
padding: 3px 7px; margin-right: 7px;"""
context.section_head = "margin-top: 60px; font-size: 16px;"
context.line_item = "padding: 5px 0px; margin: 0; border-bottom: 1px solid #d1d8dd;"
context.link_css = "color: {text_color}; text-decoration: none;".format(
text_color=context.text_color
)
context.link_css = f"color: {context.text_color}; text-decoration: none;"
def get_notifications(self):
"""Get notifications for user"""
@@ -226,7 +220,7 @@ class EmailDigest(Document):
events = get_events(from_date, to_date)
event_count = 0
for i, e in enumerate(events):
for _i, e in enumerate(events):
e.starts_on_label = format_time(e.starts_on)
e.ends_on_label = format_time(e.ends_on) if e.ends_on else None
e.date = formatdate(e.starts)
@@ -277,7 +271,7 @@ class EmailDigest(Document):
issue_list = frappe.db.sql(
"""select *
from `tabIssue` where status in ("Replied","Open")
order by modified asc limit 10""",
order by creation asc limit 10""",
as_dict=True,
)
@@ -301,7 +295,7 @@ class EmailDigest(Document):
project_list = frappe.db.sql(
"""select *
from `tabProject` where status='Open' and project_type='External'
order by modified asc limit 10""",
order by creation asc limit 10""",
as_dict=True,
)
@@ -342,11 +336,8 @@ class EmailDigest(Document):
"new_quotations",
"pending_quotations",
):
if self.get(key):
cache_key = "email_digest:card:{0}:{1}:{2}:{3}".format(
self.company, self.frequency, key, self.from_date
)
cache_key = f"email_digest:card:{self.company}:{self.frequency}:{key}:{self.from_date}"
card = cache.get(cache_key)
if card:
@@ -465,9 +456,7 @@ class EmailDigest(Document):
return self.get_type_balance("invoiced_amount", "Receivable")
def get_expenses_booked(self):
expenses, past_expenses, count = self.get_period_amounts(
self.get_roots("expense"), "expenses_booked"
)
expenses, past_expenses, count = self.get_period_amounts(self.get_roots("expense"), "expenses_booked")
expense_account = frappe.db.get_all(
"Account",
@@ -603,7 +592,6 @@ class EmailDigest(Document):
return {"label": label, "value": value, "count": count}
def get_type_balance(self, fieldname, account_type, root_type=None):
if root_type:
accounts = [
d.name
@@ -693,53 +681,43 @@ class EmailDigest(Document):
self._accounts[root_type] = [
d.name
for d in frappe.db.get_all(
"Account", filters={"root_type": root_type.title(), "company": self.company, "is_group": 0}
"Account",
filters={"root_type": root_type.title(), "company": self.company, "is_group": 0},
)
]
return self._accounts[root_type]
def get_purchase_order(self):
return self.get_summary_of_doc("Purchase Order", "purchase_order")
def get_sales_order(self):
return self.get_summary_of_doc("Sales Order", "sales_order")
def get_pending_purchase_orders(self):
return self.get_summary_of_pending("Purchase Order", "pending_purchase_orders", "per_received")
def get_pending_sales_orders(self):
return self.get_summary_of_pending("Sales Order", "pending_sales_orders", "per_delivered")
def get_sales_invoice(self):
return self.get_summary_of_doc("Sales Invoice", "sales_invoice")
def get_purchase_invoice(self):
return self.get_summary_of_doc("Purchase Invoice", "purchase_invoice")
def get_new_quotations(self):
return self.get_summary_of_doc("Quotation", "new_quotations")
def get_pending_quotations(self):
return self.get_summary_of_pending_quotations("pending_quotations")
def get_summary_of_pending(self, doc_type, fieldname, getfield):
value, count, billed_value, delivered_value = frappe.db.sql(
"""select ifnull(sum(grand_total),0), count(*),
ifnull(sum(grand_total*per_billed/100),0), ifnull(sum(grand_total*{0}/100),0) from `tab{1}`
ifnull(sum(grand_total*per_billed/100),0), ifnull(sum(grand_total*{}/100),0) from `tab{}`
where (transaction_date <= %(to_date)s)
and status not in ('Closed','Cancelled', 'Completed')
and company = %(company)s """.format(
getfield, doc_type
),
and company = %(company)s """.format(getfield, doc_type),
{"to_date": self.future_to_date, "company": self.company},
)[0]
@@ -752,7 +730,6 @@ class EmailDigest(Document):
}
def get_summary_of_pending_quotations(self, fieldname):
value, count = frappe.db.sql(
"""select ifnull(sum(grand_total),0), count(*) from `tabQuotation`
where (transaction_date <= %(to_date)s)
@@ -785,19 +762,14 @@ class EmailDigest(Document):
return {"label": label, "value": value, "last_value": last_value, "count": count}
def get_summary_of_doc(self, doc_type, fieldname):
date_field = (
"posting_date" if doc_type in ["Sales Invoice", "Purchase Invoice"] else "transaction_date"
)
value = flt(
self.get_total_on(doc_type, self.future_from_date, self.future_to_date)[0].grand_total
)
value = flt(self.get_total_on(doc_type, self.future_from_date, self.future_to_date)[0].grand_total)
count = self.get_total_on(doc_type, self.future_from_date, self.future_to_date)[0].count
last_value = flt(
self.get_total_on(doc_type, self.past_from_date, self.past_to_date)[0].grand_total
)
last_value = flt(self.get_total_on(doc_type, self.past_from_date, self.past_to_date)[0].grand_total)
filters = {
date_field: [[">=", self.future_from_date], ["<=", self.future_to_date]],
@@ -816,7 +788,6 @@ class EmailDigest(Document):
return {"label": label, "value": value, "last_value": last_value, "count": count}
def get_total_on(self, doc_type, from_date, to_date):
date_field = (
"posting_date" if doc_type in ["Sales Invoice", "Purchase Invoice"] else "transaction_date"
)
@@ -897,20 +868,16 @@ class EmailDigest(Document):
"received_qty, qty - received_qty as missing_qty, rate, amount"
)
sql_po = """select {fields} from `tabPurchase Order Item`
sql_po = f"""select {fields_po} from `tabPurchase Order Item`
left join `tabPurchase Order` on `tabPurchase Order`.name = `tabPurchase Order Item`.parent
where status<>'Closed' and `tabPurchase Order Item`.docstatus=1 and CURRENT_DATE > `tabPurchase Order Item`.schedule_date
and received_qty < qty order by `tabPurchase Order Item`.parent DESC,
`tabPurchase Order Item`.schedule_date DESC""".format(
fields=fields_po
)
`tabPurchase Order Item`.schedule_date DESC"""
sql_poi = """select {fields} from `tabPurchase Order Item`
sql_poi = f"""select {fields_poi} from `tabPurchase Order Item`
left join `tabPurchase Order` on `tabPurchase Order`.name = `tabPurchase Order Item`.parent
where status<>'Closed' and `tabPurchase Order Item`.docstatus=1 and CURRENT_DATE > `tabPurchase Order Item`.schedule_date
and received_qty < qty order by `tabPurchase Order Item`.idx""".format(
fields=fields_poi
)
and received_qty < qty order by `tabPurchase Order Item`.idx"""
purchase_order_list = frappe.db.sql(sql_po, as_dict=True)
purchase_order_items_overdue_list = frappe.db.sql(sql_poi, as_dict=True)

View File

@@ -20,14 +20,15 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2020-08-24 23:10:23.217572",
"modified": "2024-03-27 13:09:36.733439",
"modified_by": "Administrator",
"module": "Setup",
"name": "Email Digest Recipient",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -824,7 +824,7 @@
"image_field": "image",
"is_tree": 1,
"links": [],
"modified": "2024-01-24 02:20:26.145996",
"modified": "2024-03-27 13:09:36.900706",
"modified_by": "Administrator",
"module": "Setup",
"name": "Employee",
@@ -868,7 +868,7 @@
],
"search_fields": "employee_name",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"title_field": "employee_name"

View File

@@ -241,16 +241,12 @@ def validate_employee_role(doc, method=None, ignore_emp_check=False):
user_roles = [d.role for d in doc.get("roles")]
if "Employee" in user_roles:
frappe.msgprint(
_("User {0}: Removed Employee role as there is no mapped employee.").format(doc.name)
)
frappe.msgprint(_("User {0}: Removed Employee role as there is no mapped employee.").format(doc.name))
doc.get("roles").remove(doc.get("roles", {"role": "Employee"})[0])
if "Employee Self Service" in user_roles:
frappe.msgprint(
_("User {0}: Removed Employee Self Service role as there is no mapped employee.").format(
doc.name
)
_("User {0}: Removed Employee Self Service role as there is no mapped employee.").format(doc.name)
)
doc.get("roles").remove(doc.get("roles", {"role": "Employee Self Service"})[0])
@@ -266,17 +262,13 @@ def update_user_permissions(doc, method):
def get_employee_email(employee_doc):
return (
employee_doc.get("user_id")
or employee_doc.get("personal_email")
or employee_doc.get("company_email")
employee_doc.get("user_id") or employee_doc.get("personal_email") or employee_doc.get("company_email")
)
def get_holiday_list_for_employee(employee, raise_exception=True):
if employee:
holiday_list, company = frappe.get_cached_value(
"Employee", employee, ["holiday_list", "company"]
)
holiday_list, company = frappe.get_cached_value("Employee", employee, ["holiday_list", "company"])
else:
holiday_list = ""
company = frappe.db.get_single_value("Global Defaults", "default_company")
@@ -292,9 +284,7 @@ def get_holiday_list_for_employee(employee, raise_exception=True):
return holiday_list
def is_holiday(
employee, date=None, raise_exception=True, only_non_weekly=False, with_description=False
):
def is_holiday(employee, date=None, raise_exception=True, only_non_weekly=False, with_description=False):
"""
Returns True if given Employee has an holiday on the given date
:param employee: Employee `name`
@@ -404,7 +394,6 @@ def get_employee_emails(employee_list):
@frappe.whitelist()
def get_children(doctype, parent=None, company=None, is_root=False, is_tree=False):
filters = [["status", "=", "Active"]]
if company and company != "All Companies":
filters.append(["company", "=", company])

View File

@@ -1,192 +1,80 @@
{
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"actions": [],
"creation": "2013-02-22 01:27:45",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"school_univ",
"qualification",
"level",
"year_of_passing",
"class_per",
"maj_opt_subj"
],
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "school_univ",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "School/University",
"length": 0,
"no_copy": 0,
"oldfieldname": "school_univ",
"oldfieldtype": "Small Text",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"oldfieldtype": "Small Text"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "qualification",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Qualification",
"length": 0,
"no_copy": 0,
"oldfieldname": "qualification",
"oldfieldtype": "Data",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": "100px",
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "100px"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "level",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Level",
"length": 0,
"no_copy": 0,
"oldfieldname": "level",
"oldfieldtype": "Select",
"options": "Graduate\nPost Graduate\nUnder Graduate",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"options": "Graduate\nPost Graduate\nUnder Graduate"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "year_of_passing",
"fieldtype": "Int",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Year of Passing",
"length": 0,
"no_copy": 0,
"oldfieldname": "year_of_passing",
"oldfieldtype": "Int",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"oldfieldtype": "Int"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "class_per",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Class / Percentage",
"length": 0,
"no_copy": 0,
"oldfieldname": "class_per",
"oldfieldtype": "Data",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"oldfieldtype": "Data"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "maj_opt_subj",
"fieldtype": "Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Major/Optional Subjects",
"length": 0,
"no_copy": 0,
"oldfieldname": "maj_opt_subj",
"oldfieldtype": "Text",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"oldfieldtype": "Text"
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2016-07-11 03:27:59.995464",
"links": [],
"modified": "2024-03-27 13:09:38.507746",
"modified_by": "Administrator",
"module": "Setup",
"name": "Employee Education",
"owner": "Administrator",
"permissions": [],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"track_seen": 0
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}

View File

@@ -1,190 +1,78 @@
{
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"actions": [],
"creation": "2013-02-22 01:27:45",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"company_name",
"designation",
"salary",
"address",
"contact",
"total_experience"
],
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "company_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Company",
"length": 0,
"no_copy": 0,
"oldfieldname": "company_name",
"oldfieldtype": "Data",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"oldfieldtype": "Data"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "designation",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Designation",
"length": 0,
"no_copy": 0,
"oldfieldname": "designation",
"oldfieldtype": "Data",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"oldfieldtype": "Data"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "salary",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Salary",
"length": 0,
"no_copy": 0,
"oldfieldname": "salary",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"options": "Company:company:default_currency"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "address",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Address",
"length": 0,
"no_copy": 0,
"oldfieldname": "address",
"oldfieldtype": "Small Text",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"oldfieldtype": "Small Text"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "contact",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Contact",
"length": 0,
"no_copy": 0,
"oldfieldname": "contact",
"oldfieldtype": "Data",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"oldfieldtype": "Data"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "total_experience",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Total Experience",
"length": 0,
"no_copy": 0,
"oldfieldname": "total_experience",
"oldfieldtype": "Data",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"oldfieldtype": "Data"
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2016-07-11 03:28:00.088980",
"links": [],
"modified": "2024-03-27 13:09:38.624280",
"modified_by": "Administrator",
"module": "Setup",
"name": "Employee External Work History",
"owner": "Administrator",
"permissions": [],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"track_seen": 0
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}

View File

@@ -1,162 +1,59 @@
{
"allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"actions": [],
"autoname": "field:employee_group_name",
"beta": 0,
"creation": "2018-11-19 12:33:31.351364",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"employee_group_name",
"section_break_00",
"employee_list"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "employee_group_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Name",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_00",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Employee",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"label": "Employee"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "employee_list",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Employee",
"length": 0,
"no_copy": 0,
"options": "Employee Group Table",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"options": "Employee Group Table"
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-12-27 19:52:34.791538",
"links": [],
"modified": "2024-03-27 13:09:39.303885",
"modified_by": "Administrator",
"module": "Setup",
"name": "Employee Group",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
}
],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0,
"track_views": 0
"states": [],
"track_changes": 1
}

View File

@@ -1,4 +1,5 @@
{
"actions": [],
"creation": "2018-11-19 12:39:46.153061",
"doctype": "DocType",
"editable_grid": 1,
@@ -33,14 +34,16 @@
}
],
"istable": 1,
"modified": "2022-02-13 19:44:21.302938",
"links": [],
"modified": "2024-03-27 13:09:39.428291",
"modified_by": "Administrator",
"module": "Setup",
"name": "Employee Group Table",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
}

View File

@@ -1,168 +1,71 @@
{
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"actions": [],
"creation": "2013-02-22 01:27:45",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"branch",
"department",
"designation",
"from_date",
"to_date"
],
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "branch",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Branch",
"length": 0,
"no_copy": 0,
"oldfieldname": "branch",
"oldfieldtype": "Select",
"options": "Branch",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"options": "Branch"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "department",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Department",
"length": 0,
"no_copy": 0,
"oldfieldname": "department",
"oldfieldtype": "Select",
"options": "Department",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"options": "Department"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "designation",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Designation",
"length": 0,
"no_copy": 0,
"oldfieldname": "designation",
"oldfieldtype": "Select",
"options": "Designation",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"options": "Designation"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "from_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "From Date",
"length": 0,
"no_copy": 0,
"oldfieldname": "from_date",
"oldfieldtype": "Date",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"oldfieldtype": "Date"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "to_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "To Date",
"length": 0,
"no_copy": 0,
"oldfieldname": "to_date",
"oldfieldtype": "Date",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"oldfieldtype": "Date"
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2016-07-11 03:28:00.195130",
"links": [],
"modified": "2024-03-27 13:09:39.822645",
"modified_by": "Administrator",
"module": "Setup",
"name": "Employee Internal Work History",
"owner": "Administrator",
"permissions": [],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"track_seen": 0
"states": []
}

View File

@@ -87,7 +87,7 @@
"in_create": 1,
"issingle": 1,
"links": [],
"modified": "2023-07-01 19:45:00.323953",
"modified": "2024-03-27 13:09:45.400219",
"modified_by": "Administrator",
"module": "Setup",
"name": "Global Defaults",
@@ -102,7 +102,7 @@
}
],
"read_only": 1,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}

View File

@@ -49,12 +49,13 @@
"idx": 1,
"istable": 1,
"links": [],
"modified": "2020-04-18 19:03:23.507845",
"modified": "2024-03-27 13:09:49.810408",
"modified_by": "Administrator",
"module": "Setup",
"name": "Holiday",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_order": "ASC"
"sort_field": "creation",
"sort_order": "ASC",
"states": []
}

View File

@@ -141,7 +141,7 @@
"icon": "fa fa-calendar",
"idx": 1,
"links": [],
"modified": "2023-07-14 13:28:53.156421",
"modified": "2024-03-27 13:09:49.920245",
"modified_by": "Administrator",
"module": "Setup",
"name": "Holiday List",
@@ -160,7 +160,7 @@
"write": 1
}
],
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}

View File

@@ -193,9 +193,7 @@ def is_holiday(holiday_list, date=None):
if date is None:
date = today()
if holiday_list:
return bool(
frappe.db.exists("Holiday", {"parent": holiday_list, "holiday_date": date}, cache=True)
)
return bool(frappe.db.exists("Holiday", {"parent": holiday_list, "holiday_date": date}, cache=True))
else:
return False

View File

@@ -112,9 +112,13 @@ class TestHolidayList(unittest.TestCase):
frappe.local.lang = lang
def make_holiday_list(
name, from_date=getdate() - timedelta(days=10), to_date=getdate(), holiday_dates=None
):
def make_holiday_list(name, from_date=None, to_date=None, holiday_dates=None):
if from_date is None:
from_date = getdate() - timedelta(days=10)
if to_date is None:
to_date = getdate()
frappe.delete_doc_if_exists("Holiday List", name, force=1)
doc = frappe.get_doc(
{

View File

@@ -27,7 +27,7 @@ def create_incoterms():
import os
from csv import DictReader
with open(os.path.join(os.path.dirname(__file__), "incoterms.csv"), "r") as f:
with open(os.path.join(os.path.dirname(__file__), "incoterms.csv")) as f:
for incoterm in DictReader(f):
if frappe.db.exists("Incoterm", incoterm["code"]):
continue

View File

@@ -135,7 +135,7 @@
"is_tree": 1,
"links": [],
"max_attachments": 3,
"modified": "2024-01-30 14:08:38.485616",
"modified": "2024-03-27 13:09:54.588785",
"modified_by": "Administrator",
"module": "Setup",
"name": "Item Group",
@@ -204,7 +204,7 @@
],
"search_fields": "parent_item_group",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}

View File

@@ -47,7 +47,7 @@ class ItemGroup(NestedSet):
frappe.throw(
_("{0} entered twice {1} in Item Taxes").format(
frappe.bold(d.item_tax_template),
"for tax category {0}".format(frappe.bold(d.tax_category)) if d.tax_category else "",
f"for tax category {frappe.bold(d.tax_category)}" if d.tax_category else "",
)
)
else:

View File

@@ -124,9 +124,7 @@ class TestItem(unittest.TestCase):
def print_tree(self):
import json
print(
json.dumps(frappe.db.sql("select name, lft, rgt from `tabItem Group` order by lft"), indent=1)
)
print(json.dumps(frappe.db.sql("select name, lft, rgt from `tabItem Group` order by lft"), indent=1))
def test_move_leaf_into_another_group(self):
# before move
@@ -156,17 +154,13 @@ class TestItem(unittest.TestCase):
def test_delete_leaf(self):
# for checking later
parent_item_group = frappe.db.get_value(
"Item Group", "_Test Item Group B - 3", "parent_item_group"
)
rgt = frappe.db.get_value("Item Group", parent_item_group, "rgt")
parent_item_group = frappe.db.get_value("Item Group", "_Test Item Group B - 3", "parent_item_group")
frappe.db.get_value("Item Group", parent_item_group, "rgt")
ancestors = get_ancestors_of("Item Group", "_Test Item Group B - 3")
ancestors = frappe.db.sql(
"""select name, rgt from `tabItem Group`
where name in ({})""".format(
", ".join(["%s"] * len(ancestors))
),
where name in ({})""".format(", ".join(["%s"] * len(ancestors))),
tuple(ancestors),
as_dict=True,
)
@@ -188,9 +182,7 @@ class TestItem(unittest.TestCase):
def test_delete_group(self):
# cannot delete group with child, but can delete leaf
self.assertRaises(
NestedSetChildExistsError, frappe.delete_doc, "Item Group", "_Test Item Group B"
)
self.assertRaises(NestedSetChildExistsError, frappe.delete_doc, "Item Group", "_Test Item Group B")
def test_merge_groups(self):
frappe.rename_doc("Item Group", "_Test Item Group B", "_Test Item Group C", merge=True)
@@ -207,7 +199,6 @@ class TestItem(unittest.TestCase):
"""select name from `tabItem Group`
where parent_item_group='_Test Item Group C'"""
):
doc = frappe.get_doc("Item Group", name)
doc.parent_item_group = "_Test Item Group B"
doc.save()

View File

@@ -1,164 +1,72 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "field:party_type",
"beta": 0,
"creation": "2016-12-26 11:26:51.508286",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"actions": [],
"autoname": "field:party_type",
"creation": "2016-12-26 11:26:51.508286",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"party_type",
"account_type"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "party_type",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Party Type",
"length": 0,
"no_copy": 0,
"options": "DocType",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "party_type",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Party Type",
"options": "DocType",
"reqd": 1,
"unique": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "account_type",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Account Type",
"length": 0,
"no_copy": 0,
"options": "Payable\nReceivable",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"fieldname": "account_type",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Account Type",
"options": "Payable\nReceivable",
"reqd": 1
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 1,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-04-26 13:00:49.457439",
"modified_by": "Administrator",
"module": "Setup",
"name": "Party Type",
"name_case": "",
"owner": "Administrator",
],
"in_create": 1,
"links": [],
"modified": "2024-03-27 13:10:08.874345",
"modified_by": "Administrator",
"module": "Setup",
"name": "Party Type",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 0
},
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts User",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 0
},
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts User",
"share": 1
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 0
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts Manager",
"share": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0
],
"show_name_in_global_search": 1,
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -31,10 +31,8 @@ def get_party_type(doctype, txt, searchfield, start, page_len, filters):
cond = "and account_type = '%s'" % account_type
return frappe.db.sql(
"""select name from `tabParty Type`
where `{key}` LIKE %(txt)s {cond}
order by name limit %(page_len)s offset %(start)s""".format(
key=searchfield, cond=cond
),
f"""select name from `tabParty Type`
where `{searchfield}` LIKE %(txt)s {cond}
order by name limit %(page_len)s offset %(start)s""",
{"txt": "%" + txt + "%", "start": start, "page_len": page_len},
)

View File

@@ -37,7 +37,7 @@
"icon": "fa fa-font",
"idx": 1,
"links": [],
"modified": "2023-08-28 22:17:42.041255",
"modified": "2024-03-27 13:10:18.334668",
"modified_by": "Administrator",
"module": "Setup",
"name": "Print Heading",
@@ -62,7 +62,7 @@
],
"quick_entry": 1,
"search_fields": "print_heading",
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}

View File

@@ -32,7 +32,7 @@
"table_fieldname": "lost_reasons"
}
],
"modified": "2023-11-23 19:31:02.743353",
"modified": "2024-03-27 13:10:31.419151",
"modified_by": "Administrator",
"module": "Setup",
"name": "Quotation Lost Reason",
@@ -52,7 +52,7 @@
}
],
"quick_entry": 1,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}

View File

@@ -18,14 +18,15 @@
],
"istable": 1,
"links": [],
"modified": "2020-07-26 17:58:56.373775",
"modified": "2024-03-27 13:10:31.568485",
"modified_by": "Administrator",
"module": "Setup",
"name": "Quotation Lost Reason Detail",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

File diff suppressed because it is too large Load Diff

View File

@@ -49,30 +49,35 @@ class SalesPartner(WebsiteGenerator):
def validate(self):
if not self.route:
self.route = "partners/" + self.scrub(self.partner_name)
super(SalesPartner, self).validate()
super().validate()
if self.partner_website and not self.partner_website.startswith("http"):
self.partner_website = "http://" + self.partner_website
def get_context(self, context):
address = frappe.db.get_value(
"Address", {"sales_partner": self.name, "is_primary_address": 1}, "*", as_dict=True
address_names = frappe.db.get_all(
"Dynamic Link",
filters={"link_doctype": "Sales Partner", "link_name": self.name, "parenttype": "Address"},
pluck=["parent"],
)
if address:
city_state = ", ".join(filter(None, [address.city, address.state]))
address_rows = [
address.address_line1,
address.address_line2,
city_state,
address.pincode,
address.country,
]
context.update(
addresses = []
for address_name in address_names:
address_doc = frappe.get_doc("Address", address_name)
city_state = ", ".join([item for item in [address_doc.city, address_doc.state] if item])
address_rows = [
address_doc.address_line1,
address_doc.address_line2,
city_state,
address_doc.pincode,
address_doc.country,
]
addresses.append(
{
"email": address.email_id,
"email": address_doc.email_id,
"partner_address": filter_strip_join(address_rows, "\n<br>"),
"phone": filter_strip_join(cstr(address.phone).split(","), "\n<br>"),
"phone": filter_strip_join(cstr(address_doc.phone).split(","), "\n<br>"),
}
)
context["addresses"] = addresses
return context

View File

@@ -145,7 +145,7 @@
"idx": 1,
"is_tree": 1,
"links": [],
"modified": "2024-01-30 13:57:26.436991",
"modified": "2024-03-27 13:10:37.891377",
"modified_by": "Administrator",
"module": "Setup",
"name": "Sales Person",
@@ -181,7 +181,7 @@
],
"search_fields": "parent_sales_person",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "ASC",
"states": []
}

View File

@@ -80,7 +80,7 @@ class SalesPerson(NestedSet):
self.set_onload("dashboard_info", info)
def on_update(self):
super(SalesPerson, self).on_update()
super().on_update()
self.validate_one_root()
def get_email_id(self):

View File

@@ -107,7 +107,7 @@
"idx": 1,
"is_tree": 1,
"links": [],
"modified": "2022-12-24 11:16:12.486719",
"modified": "2024-03-27 13:10:48.734325",
"modified_by": "Administrator",
"module": "Setup",
"name": "Supplier Group",
@@ -139,7 +139,6 @@
"read": 1,
"report": 1,
"role": "Purchase Master Manager",
"set_user_permissions": 1,
"share": 1,
"write": 1
},
@@ -169,7 +168,7 @@
}
],
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "ASC",
"states": []
}

View File

@@ -1,213 +1,77 @@
{
"allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2013-02-22 01:27:58",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"editable_grid": 1,
"actions": [],
"creation": "2013-02-22 01:27:58",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"item_group",
"fiscal_year",
"target_qty",
"target_amount",
"distribution_id"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fetch_if_empty": 0,
"fieldname": "item_group",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Item Group",
"length": 0,
"no_copy": 0,
"oldfieldname": "item_group",
"oldfieldtype": "Link",
"options": "Item Group",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "item_group",
"fieldtype": "Link",
"in_filter": 1,
"in_list_view": 1,
"label": "Item Group",
"oldfieldname": "item_group",
"oldfieldtype": "Link",
"options": "Item Group",
"search_index": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "fiscal_year",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Fiscal Year",
"length": 0,
"no_copy": 0,
"oldfieldname": "fiscal_year",
"oldfieldtype": "Select",
"options": "Fiscal Year",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 1,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "fiscal_year",
"fieldtype": "Link",
"in_filter": 1,
"in_list_view": 1,
"label": "Fiscal Year",
"oldfieldname": "fiscal_year",
"oldfieldtype": "Select",
"options": "Fiscal Year",
"reqd": 1,
"search_index": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "target_qty",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Target Qty",
"length": 0,
"no_copy": 0,
"oldfieldname": "target_qty",
"oldfieldtype": "Currency",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "target_qty",
"fieldtype": "Float",
"in_list_view": 1,
"label": "Target Qty",
"oldfieldname": "target_qty",
"oldfieldtype": "Currency"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "target_amount",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Target Amount",
"length": 0,
"no_copy": 0,
"oldfieldname": "target_amount",
"oldfieldtype": "Currency",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "target_amount",
"fieldtype": "Float",
"in_filter": 1,
"in_list_view": 1,
"label": "Target Amount",
"oldfieldname": "target_amount",
"oldfieldtype": "Currency",
"search_index": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "distribution_id",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Target Distribution",
"length": 0,
"no_copy": 0,
"options": "Monthly Distribution",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"fieldname": "distribution_id",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Target Distribution",
"options": "Monthly Distribution",
"reqd": 1
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2019-03-20 16:59:03.578274",
"modified_by": "Administrator",
"module": "Setup",
"name": "Target Detail",
"owner": "Administrator",
"permissions": [],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 0,
"track_seen": 0,
"track_views": 0
],
"idx": 1,
"istable": 1,
"links": [],
"modified": "2024-03-27 13:10:51.347225",
"modified_by": "Administrator",
"module": "Setup",
"name": "Target Detail",
"owner": "Administrator",
"permissions": [],
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}

View File

@@ -77,7 +77,7 @@
"icon": "icon-legal",
"idx": 1,
"links": [],
"modified": "2024-01-30 12:47:52.325531",
"modified": "2024-03-27 13:10:53.065872",
"modified_by": "Administrator",
"module": "Setup",
"name": "Terms and Conditions",
@@ -134,7 +134,7 @@
],
"quick_entry": 1,
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "ASC",
"states": []
}

View File

@@ -30,12 +30,7 @@ class TermsandConditions(Document):
def validate(self):
if self.terms:
validate_template(self.terms)
if (
not cint(self.buying)
and not cint(self.selling)
and not cint(self.hr)
and not cint(self.disabled)
):
if not cint(self.buying) and not cint(self.selling) and not cint(self.hr) and not cint(self.disabled):
throw(_("At least one of the Applicable Modules should be selected"))

View File

@@ -123,11 +123,10 @@
"idx": 1,
"is_tree": 1,
"links": [],
"modified": "2022-12-24 11:16:39.964956",
"modified": "2024-03-27 13:10:53.240951",
"modified_by": "Administrator",
"module": "Setup",
"name": "Territory",
"name_case": "Title Case",
"naming_rule": "By fieldname",
"nsm_parent_field": "parent_territory",
"owner": "Administrator",
@@ -142,7 +141,6 @@
"read": 1,
"report": 1,
"role": "Sales Master Manager",
"set_user_permissions": 1,
"share": 1,
"write": 1
},
@@ -188,7 +186,7 @@
],
"search_fields": "parent_territory,territory_manager",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}

View File

@@ -40,7 +40,7 @@ class Territory(NestedSet):
frappe.throw(_("Either target qty or target amount is mandatory"))
def on_update(self):
super(Territory, self).on_update()
super().on_update()
self.validate_one_root()

View File

@@ -1,7 +1,6 @@
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests.utils import FrappeTestCase
@@ -26,9 +25,10 @@ class TestTransactionDeletionRecord(FrappeTestCase):
self.assertTrue(contains_company)
def test_no_of_docs_is_correct(self):
for i in range(5):
for _i in range(5):
create_task("Dunder Mifflin Paper Co")
tdr = create_transaction_deletion_doc("Dunder Mifflin Paper Co")
tdr.reload()
for doctype in tdr.doctypes:
if doctype.doctype_name == "Task":
self.assertEqual(doctype.no_of_docs, 5)
@@ -51,16 +51,16 @@ class TestTransactionDeletionRecord(FrappeTestCase):
def create_company(company_name):
company = frappe.get_doc(
{"doctype": "Company", "company_name": company_name, "default_currency": "INR"}
)
company = frappe.get_doc({"doctype": "Company", "company_name": company_name, "default_currency": "INR"})
company.insert(ignore_if_duplicate=True)
def create_transaction_deletion_doc(company):
tdr = frappe.get_doc({"doctype": "Transaction Deletion Record", "company": company})
tdr.insert()
tdr.process_in_single_transaction = True
tdr.submit()
tdr.start_deletion_tasks()
return tdr

View File

@@ -10,20 +10,24 @@ frappe.ui.form.on("Transaction Deletion Record", {
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");
if (frm.doc.docstatus == 1 && ["Queued", "Failed"].find((x) => x == frm.doc.status)) {
let execute_btn = frm.doc.status == "Queued" ? __("Start Deletion") : __("Retry");
frm.add_custom_button(execute_btn, () => {
// Entry point for chain of events
frm.call({
method: "start_deletion_tasks",
doc: frm.doc,
});
});
}
},
});

View File

@@ -7,10 +7,21 @@
"engine": "InnoDB",
"field_order": [
"company",
"section_break_qpwb",
"status",
"error_log",
"tasks_section",
"delete_bin_data",
"delete_leads_and_addresses",
"reset_company_default_values",
"clear_notifications",
"initialize_doctypes_table",
"delete_transactions",
"section_break_tbej",
"doctypes",
"doctypes_to_be_ignored",
"amended_from",
"status"
"process_in_single_transaction"
],
"fields": [
{
@@ -25,14 +36,16 @@
"fieldname": "doctypes",
"fieldtype": "Table",
"label": "Summary",
"options": "Transaction Deletion Record Item",
"no_copy": 1,
"options": "Transaction Deletion Record Details",
"read_only": 1
},
{
"fieldname": "doctypes_to_be_ignored",
"fieldtype": "Table",
"label": "Excluded DocTypes",
"options": "Transaction Deletion Record Item"
"options": "Transaction Deletion Record Item",
"read_only": 1
},
{
"fieldname": "amended_from",
@@ -46,18 +59,96 @@
{
"fieldname": "status",
"fieldtype": "Select",
"hidden": 1,
"label": "Status",
"options": "Draft\nCompleted"
"no_copy": 1,
"options": "Queued\nRunning\nFailed\nCompleted\nCancelled",
"read_only": 1
},
{
"fieldname": "section_break_tbej",
"fieldtype": "Section Break"
},
{
"fieldname": "tasks_section",
"fieldtype": "Section Break",
"label": "Tasks"
},
{
"default": "0",
"fieldname": "delete_bin_data",
"fieldtype": "Check",
"label": "Delete Bins",
"no_copy": 1,
"read_only": 1
},
{
"default": "0",
"fieldname": "delete_leads_and_addresses",
"fieldtype": "Check",
"label": "Delete Leads and Addresses",
"no_copy": 1,
"read_only": 1
},
{
"default": "0",
"fieldname": "clear_notifications",
"fieldtype": "Check",
"label": "Clear Notifications",
"no_copy": 1,
"read_only": 1
},
{
"default": "0",
"fieldname": "reset_company_default_values",
"fieldtype": "Check",
"label": "Reset Company Default Values",
"no_copy": 1,
"read_only": 1
},
{
"default": "0",
"fieldname": "delete_transactions",
"fieldtype": "Check",
"label": "Delete Transactions",
"no_copy": 1,
"read_only": 1
},
{
"default": "0",
"fieldname": "initialize_doctypes_table",
"fieldtype": "Check",
"label": "Initialize Summary Table",
"no_copy": 1,
"read_only": 1
},
{
"depends_on": "eval: doc.error_log",
"fieldname": "error_log",
"fieldtype": "Long Text",
"label": "Error Log"
},
{
"fieldname": "section_break_qpwb",
"fieldtype": "Section Break"
},
{
"default": "0",
"fieldname": "process_in_single_transaction",
"fieldtype": "Check",
"hidden": 1,
"label": "Process in Single Transaction",
"no_copy": 1,
"read_only": 1
}
],
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2021-08-04 20:15:59.071493",
"modified": "2024-03-27 13:10:54.828051",
"modified_by": "Administrator",
"module": "Setup",
"name": "Transaction Deletion Record",
"naming_rule": "Expression (old style)",
"owner": "Administrator",
"permissions": [
{
@@ -74,7 +165,8 @@
"write": 1
}
],
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -1,12 +1,14 @@
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from collections import OrderedDict
import frappe
from frappe import _, qb
from frappe.desk.notifications import clear_notifications
from frappe.model.document import Document
from frappe.utils import cint, create_batch
from frappe.utils import cint, comma_and, create_batch, get_link_to_form
from frappe.utils.background_jobs import get_job, is_job_enqueued
class TransactionDeletionRecord(Document):
@@ -18,20 +20,42 @@ class TransactionDeletionRecord(Document):
if TYPE_CHECKING:
from frappe.types import DF
from erpnext.accounts.doctype.transaction_deletion_record_details.transaction_deletion_record_details import (
TransactionDeletionRecordDetails,
)
from erpnext.setup.doctype.transaction_deletion_record_item.transaction_deletion_record_item import (
TransactionDeletionRecordItem,
)
amended_from: DF.Link | None
clear_notifications: DF.Check
company: DF.Link
doctypes: DF.Table[TransactionDeletionRecordItem]
delete_bin_data: DF.Check
delete_leads_and_addresses: DF.Check
delete_transactions: DF.Check
doctypes: DF.Table[TransactionDeletionRecordDetails]
doctypes_to_be_ignored: DF.Table[TransactionDeletionRecordItem]
status: DF.Literal["Draft", "Completed"]
error_log: DF.LongText | None
initialize_doctypes_table: DF.Check
process_in_single_transaction: DF.Check
reset_company_default_values: DF.Check
status: DF.Literal["Queued", "Running", "Failed", "Completed", "Cancelled"]
# end: auto-generated types
def __init__(self, *args, **kwargs):
super(TransactionDeletionRecord, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.batch_size = 5000
# Tasks are listed by their execution order
self.task_to_internal_method_map = OrderedDict(
{
"Delete Bins": "delete_bins",
"Delete Leads and Addresses": "delete_lead_addresses",
"Reset Company Values": "reset_company_values",
"Clear Notifications": "delete_notifications",
"Initialize Summary Table": "initialize_doctypes_to_be_deleted_table",
"Delete Transactions": "delete_company_transactions",
}
)
def validate(self):
frappe.only_for("System Manager")
@@ -48,104 +72,264 @@ class TransactionDeletionRecord(Document):
title=_("Not Allowed"),
)
def generate_job_name_for_task(self, task=None):
method = self.task_to_internal_method_map[task]
return f"{self.name}_{method}"
def generate_job_name_for_next_tasks(self, task=None):
job_names = []
current_task_idx = list(self.task_to_internal_method_map).index(task)
for idx, task in enumerate(self.task_to_internal_method_map.keys(), 0):
# generate job_name for next tasks
if idx > current_task_idx:
job_names.append(self.generate_job_name_for_task(task))
return job_names
def generate_job_name_for_all_tasks(self):
job_names = []
for task in self.task_to_internal_method_map.keys():
job_names.append(self.generate_job_name_for_task(task))
return job_names
def before_submit(self):
if queued_docs := frappe.db.get_all(
"Transaction Deletion Record",
filters={"company": self.company, "status": ("in", ["Running", "Queued"]), "docstatus": 1},
pluck="name",
):
frappe.throw(
_(
"Cannot enqueue multi docs for one company. {0} is already queued/running for company: {1}"
).format(
comma_and([get_link_to_form("Transaction Deletion Record", x) for x in queued_docs]),
frappe.bold(self.company),
)
)
if not self.doctypes_to_be_ignored:
self.populate_doctypes_to_be_ignored_table()
self.delete_bins()
self.delete_lead_addresses()
self.reset_company_values()
clear_notifications()
self.delete_company_transactions()
def reset_task_flags(self):
self.clear_notifications = 0
self.delete_bin_data = 0
self.delete_leads_and_addresses = 0
self.delete_transactions = 0
self.initialize_doctypes_table = 0
self.reset_company_default_values = 0
def before_save(self):
self.status = ""
self.doctypes.clear()
self.reset_task_flags()
def on_submit(self):
self.db_set("status", "Queued")
def on_cancel(self):
self.db_set("status", "Cancelled")
def enqueue_task(self, task: str | None = None):
if task and task in self.task_to_internal_method_map:
# make sure that none of next tasks are already running
job_names = self.generate_job_name_for_next_tasks(task=task)
self.validate_running_task_for_doc(job_names=job_names)
# Generate Job Id to uniquely identify each task for this document
job_id = self.generate_job_name_for_task(task)
if self.process_in_single_transaction:
self.execute_task(task_to_execute=task)
else:
frappe.enqueue(
"frappe.utils.background_jobs.run_doc_method",
doctype=self.doctype,
name=self.name,
doc_method="execute_task",
job_id=job_id,
queue="long",
enqueue_after_commit=True,
task_to_execute=task,
)
def execute_task(self, task_to_execute: str | None = None):
if task_to_execute:
method = self.task_to_internal_method_map[task_to_execute]
if task := getattr(self, method, None):
try:
task()
except Exception:
frappe.db.rollback()
traceback = frappe.get_traceback(with_context=True)
if traceback:
message = "Traceback: <br>" + traceback
frappe.db.set_value(self.doctype, self.name, "error_log", message)
frappe.db.set_value(self.doctype, self.name, "status", "Failed")
def delete_notifications(self):
self.validate_doc_status()
if not self.clear_notifications:
clear_notifications()
self.db_set("clear_notifications", 1)
self.enqueue_task(task="Initialize Summary Table")
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 validate_running_task_for_doc(self, job_names: list | None = None):
# at most only one task should be runnning
running_tasks = []
for x in job_names:
if is_job_enqueued(x):
running_tasks.append(get_job(x).get_id())
if running_tasks:
frappe.throw(
_("{0} is already running for {1}").format(
comma_and([get_link_to_form("RQ Job", x) for x in running_tasks]), self.name
)
)
def validate_doc_status(self):
if self.status != "Running":
frappe.throw(
_("{0} is not running. Cannot trigger events for this Document").format(
get_link_to_form("Transaction Deletion Record", self.name)
)
)
@frappe.whitelist()
def start_deletion_tasks(self):
# This method is the entry point for the chain of events that follow
self.db_set("status", "Running")
self.enqueue_task(task="Delete Bins")
def delete_bins(self):
frappe.db.sql(
"""delete from `tabBin` where warehouse in
(select name from tabWarehouse where company=%s)""",
self.company,
)
self.validate_doc_status()
if not self.delete_bin_data:
frappe.db.sql(
"""delete from `tabBin` where warehouse in
(select name from tabWarehouse where company=%s)""",
self.company,
)
self.db_set("delete_bin_data", 1)
self.enqueue_task(task="Delete Leads and Addresses")
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)
self.validate_doc_status()
if not self.delete_leads_and_addresses:
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]
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 `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(
"""delete from `tabDynamic Link` where link_doctype='Lead'
and parenttype='Address' and link_name in ({leads})""".format(
"""update `tabCustomer` set lead_name=NULL where lead_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)
)
)
self.db_set("delete_leads_and_addresses", 1)
self.enqueue_task(task="Reset Company Values")
def reset_company_values(self):
company_obj = frappe.get_doc("Company", self.company)
company_obj.total_monthly_sales = 0
company_obj.sales_monthly_history = None
company_obj.save()
self.validate_doc_status()
if not self.reset_company_default_values:
company_obj = frappe.get_doc("Company", self.company)
company_obj.total_monthly_sales = 0
company_obj.sales_monthly_history = None
company_obj.save()
self.db_set("reset_company_default_values", 1)
self.enqueue_task(task="Clear Notifications")
def initialize_doctypes_to_be_deleted_table(self):
self.validate_doc_status()
if not self.initialize_doctypes_table:
doctypes_to_be_ignored_list = self.get_doctypes_to_be_ignored_list()
docfields = self.get_doctypes_with_company_field(doctypes_to_be_ignored_list)
tables = self.get_all_child_doctypes()
for docfield in docfields:
if docfield["parent"] != self.doctype:
no_of_docs = self.get_number_of_docs_linked_with_specified_company(
docfield["parent"], docfield["fieldname"]
)
if no_of_docs > 0:
# Initialize
self.populate_doctypes_table(tables, docfield["parent"], docfield["fieldname"], 0)
self.db_set("initialize_doctypes_table", 1)
self.enqueue_task(task="Delete Transactions")
def delete_company_transactions(self):
doctypes_to_be_ignored_list = self.get_doctypes_to_be_ignored_list()
docfields = self.get_doctypes_with_company_field(doctypes_to_be_ignored_list)
self.validate_doc_status()
if not self.delete_transactions:
doctypes_to_be_ignored_list = self.get_doctypes_to_be_ignored_list()
self.get_doctypes_with_company_field(doctypes_to_be_ignored_list)
tables = self.get_all_child_doctypes()
for docfield in docfields:
if docfield["parent"] != self.doctype:
no_of_docs = self.get_number_of_docs_linked_with_specified_company(
docfield["parent"], docfield["fieldname"]
)
if no_of_docs > 0:
self.delete_version_log(docfield["parent"], docfield["fieldname"])
reference_docs = frappe.get_all(
docfield["parent"], filters={docfield["fieldname"]: self.company}
self.get_all_child_doctypes()
for docfield in self.doctypes:
if docfield.doctype_name != self.doctype and not docfield.done:
no_of_docs = self.get_number_of_docs_linked_with_specified_company(
docfield.doctype_name, docfield.docfield_name
)
reference_doc_names = [r.name for r in reference_docs]
if no_of_docs > 0:
reference_docs = frappe.get_all(
docfield.doctype_name,
filters={docfield.docfield_name: self.company},
limit=self.batch_size,
)
reference_doc_names = [r.name for r in reference_docs]
self.delete_communications(docfield["parent"], reference_doc_names)
self.delete_comments(docfield["parent"], reference_doc_names)
self.unlink_attachments(docfield["parent"], reference_doc_names)
self.delete_version_log(docfield.doctype_name, reference_doc_names)
self.delete_communications(docfield.doctype_name, reference_doc_names)
self.delete_comments(docfield.doctype_name, reference_doc_names)
self.unlink_attachments(docfield.doctype_name, reference_doc_names)
self.delete_child_tables(docfield.doctype_name, reference_doc_names)
self.delete_docs_linked_with_specified_company(
docfield.doctype_name, reference_doc_names
)
processed = int(docfield.no_of_docs) + len(reference_doc_names)
frappe.db.set_value(docfield.doctype, docfield.name, "no_of_docs", processed)
else:
# reset naming series
naming_series = frappe.db.get_value("DocType", docfield.doctype_name, "autoname")
if naming_series:
if "#" in naming_series:
self.update_naming_series(naming_series, docfield.doctype_name)
frappe.db.set_value(docfield.doctype, docfield.name, "done", 1)
self.populate_doctypes_table(tables, docfield["parent"], no_of_docs)
self.delete_child_tables(docfield["parent"], docfield["fieldname"])
self.delete_docs_linked_with_specified_company(docfield["parent"], docfield["fieldname"])
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"])
pending_doctypes = frappe.db.get_all(
"Transaction Deletion Record Details",
filters={"parent": self.name, "done": 0},
pluck="doctype_name",
)
if pending_doctypes:
# as method is enqueued after commit, calling itself will not make validate_doc_status to throw
# recursively call this task to delete all transactions
self.enqueue_task(task="Delete Transactions")
else:
self.db_set("status", "Completed")
self.db_set("delete_transactions", 1)
self.db_set("error_log", None)
def get_doctypes_to_be_ignored_list(self):
singles = frappe.get_all("DocType", filters={"issingle": 1}, pluck="name")
@@ -174,25 +358,24 @@ class TransactionDeletionRecord(Document):
def get_number_of_docs_linked_with_specified_company(self, doctype, company_fieldname):
return frappe.db.count(doctype, {company_fieldname: self.company})
def populate_doctypes_table(self, tables, doctype, no_of_docs):
def populate_doctypes_table(self, tables, doctype, fieldname, no_of_docs):
self.flags.ignore_validate_update_after_submit = True
if doctype not in tables:
self.append("doctypes", {"doctype_name": doctype, "no_of_docs": no_of_docs})
def delete_child_tables(self, doctype, company_fieldname):
parent_docs_to_be_deleted = frappe.get_all(
doctype, {company_fieldname: self.company}, pluck="name"
)
self.append(
"doctypes", {"doctype_name": doctype, "docfield_name": fieldname, "no_of_docs": no_of_docs}
)
self.save(ignore_permissions=True)
def delete_child_tables(self, doctype, reference_doc_names):
child_tables = frappe.get_all(
"DocField", filters={"fieldtype": "Table", "parent": doctype}, pluck="options"
)
for batch in create_batch(parent_docs_to_be_deleted, self.batch_size):
for table in child_tables:
frappe.db.delete(table, {"parent": ["in", batch]})
for table in child_tables:
frappe.db.delete(table, {"parent": ["in", reference_doc_names]})
def delete_docs_linked_with_specified_company(self, doctype, company_fieldname):
frappe.db.delete(doctype, {company_fieldname: self.company})
def delete_docs_linked_with_specified_company(self, doctype, reference_doc_names):
frappe.db.delete(doctype, {"name": ("in", reference_doc_names)})
def update_naming_series(self, naming_series, doctype_name):
if "." in naming_series:
@@ -200,10 +383,8 @@ class TransactionDeletionRecord(Document):
else:
prefix, hashes = naming_series.rsplit("{", 1)
last = frappe.db.sql(
"""select max(name) from `tab{0}`
where name like %s""".format(
doctype_name
),
f"""select max(name) from `tab{doctype_name}`
where name like %s""",
prefix + "%",
)
if last and last[0][0]:
@@ -213,17 +394,11 @@ class TransactionDeletionRecord(Document):
frappe.db.sql("""update `tabSeries` set current = %s where name=%s""", (last, prefix))
def delete_version_log(self, doctype, company_fieldname):
dt = qb.DocType(doctype)
names = qb.from_(dt).select(dt.name).where(dt[company_fieldname] == self.company).run(as_list=1)
names = [x[0] for x in names]
if names:
versions = qb.DocType("Version")
for batch in create_batch(names, self.batch_size):
qb.from_(versions).delete().where(
(versions.ref_doctype == doctype) & (versions.docname.isin(batch))
).run()
def delete_version_log(self, doctype, docnames):
versions = qb.DocType("Version")
qb.from_(versions).delete().where(
(versions.ref_doctype == doctype) & (versions.docname.isin(docnames))
).run()
def delete_communications(self, doctype, reference_doc_names):
communications = frappe.get_all(
@@ -239,17 +414,11 @@ class TransactionDeletionRecord(Document):
frappe.delete_doc("Communication", batch, ignore_permissions=True)
def delete_comments(self, doctype, reference_doc_names):
comments = frappe.get_all(
"Comment",
filters={"reference_doctype": doctype, "reference_name": ["in", reference_doc_names]},
)
comment_names = [c.name for c in comments]
if not comment_names:
return
for batch in create_batch(comment_names, self.batch_size):
frappe.delete_doc("Comment", batch, ignore_permissions=True)
if reference_doc_names:
comment = qb.DocType("Comment")
qb.from_(comment).delete().where(
(comment.reference_doctype == doctype) & (comment.reference_name.isin(reference_doc_names))
).run()
def unlink_attachments(self, doctype, reference_doc_names):
files = frappe.get_all(
@@ -295,3 +464,29 @@ def get_doctypes_to_be_ignored():
doctypes_to_be_ignored.extend(frappe.get_hooks("company_data_to_be_ignored") or [])
return doctypes_to_be_ignored
@frappe.whitelist()
def is_deletion_doc_running(company: str | None = None, err_msg: str | None = None):
if company:
if running_deletion_jobs := frappe.db.get_all(
"Transaction Deletion Record",
filters={"docstatus": 1, "company": company, "status": "Running"},
):
if not err_msg:
err_msg = ""
frappe.throw(
title=_("Deletion in Progress!"),
msg=_("Transaction Deletion Document: {0} is running for this Company. {1}").format(
get_link_to_form("Transaction Deletion Record", running_deletion_jobs[0].name), err_msg
),
)
def check_for_running_deletion_job(doc, method=None):
# Check if DocType has 'company' field
df = qb.DocType("DocField")
if qb.from_(df).select(df.parent).where((df.fieldname == "company") & (df.parent == doc.doctype)).run():
is_deletion_doc_running(
doc.company, _("Cannot make any transactions until the deletion job is completed")
)

View File

@@ -2,11 +2,15 @@
// License: GNU General Public License v3. See license.txt
frappe.listview_settings["Transaction Deletion Record"] = {
add_fields: ["status"],
get_indicator: function (doc) {
if (doc.docstatus == 0) {
return [__("Draft"), "red"];
} else {
return [__("Completed"), "green"];
}
let colors = {
Queued: "orange",
Completed: "green",
Running: "blue",
Failed: "red",
};
let status = doc.status;
return [__(status), colors[status], "status,=," + status];
},
};

View File

@@ -5,8 +5,7 @@
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"doctype_name",
"no_of_docs"
"doctype_name"
],
"fields": [
{
@@ -16,24 +15,19 @@
"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": "2024-03-27 13:10:55.128861",
"modified_by": "Administrator",
"module": "Setup",
"name": "Transaction Deletion Record Item",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -16,7 +16,6 @@ class TransactionDeletionRecordItem(Document):
from frappe.types import DF
doctype_name: DF.Link
no_of_docs: DF.Data | None
parent: DF.Data
parentfield: DF.Data
parenttype: DF.Data

View File

@@ -8,8 +8,12 @@
"document_type": "Setup",
"engine": "InnoDB",
"field_order": [
"enabled",
"uom_name",
"symbol",
"common_code",
"description",
"column_break_obth",
"enabled",
"must_be_whole_number"
],
"fields": [
@@ -35,12 +39,33 @@
"fieldname": "enabled",
"fieldtype": "Check",
"label": "Enabled"
},
{
"fieldname": "symbol",
"fieldtype": "Data",
"label": "Symbol"
},
{
"description": "According to CEFACT/ICG/2010/IC013 or CEFACT/ICG/2010/IC010",
"fieldname": "common_code",
"fieldtype": "Data",
"label": "Common Code",
"length": 3
},
{
"fieldname": "description",
"fieldtype": "Small Text",
"label": "Description"
},
{
"fieldname": "column_break_obth",
"fieldtype": "Column Break"
}
],
"icon": "fa fa-compass",
"idx": 1,
"links": [],
"modified": "2021-10-18 14:07:43.722144",
"modified": "2024-03-27 13:10:57.375141",
"modified_by": "Administrator",
"module": "Setup",
"name": "UOM",
@@ -77,6 +102,8 @@
],
"quick_entry": 1,
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "ASC"
"sort_field": "creation",
"sort_order": "ASC",
"states": [],
"translated_doctype": 1
}

View File

@@ -14,8 +14,11 @@ class UOM(Document):
if TYPE_CHECKING:
from frappe.types import DF
common_code: DF.Data | None
description: DF.SmallText | None
enabled: DF.Check
must_be_whole_number: DF.Check
symbol: DF.Data | None
uom_name: DF.Data
# end: auto-generated types

View File

@@ -1,225 +1,81 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "MAT-UOM-CNV-.#####",
"beta": 0,
"creation": "2018-04-30 17:37:02.347217",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"actions": [],
"autoname": "MAT-UOM-CNV-.#####",
"creation": "2018-04-30 17:37:02.347217",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"category",
"section_break_2",
"from_uom",
"to_uom",
"value"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "category",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Category",
"length": 0,
"no_copy": 0,
"options": "UOM Category",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "category",
"fieldtype": "Link",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Category",
"options": "UOM Category",
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_2",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "section_break_2",
"fieldtype": "Section Break"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "from_uom",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "From",
"length": 0,
"no_copy": 0,
"options": "UOM",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "from_uom",
"fieldtype": "Link",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "From",
"options": "UOM",
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "to_uom",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "To",
"length": 0,
"no_copy": 0,
"options": "UOM",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "to_uom",
"fieldtype": "Link",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "To",
"options": "UOM",
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "value",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Value",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "9",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"fieldname": "value",
"fieldtype": "Float",
"in_list_view": 1,
"label": "Value",
"precision": "9",
"reqd": 1
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-08-21 16:15:50.213986",
"modified_by": "Administrator",
"module": "Setup",
"name": "UOM Conversion Factor",
"name_case": "",
"owner": "Administrator",
],
"links": [],
"modified": "2024-03-27 13:10:57.756872",
"modified_by": "Administrator",
"module": "Setup",
"name": "UOM Conversion Factor",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0,
"track_views": 0
],
"quick_entry": 1,
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -1,864 +1,216 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"actions": [],
"autoname": "field:license_plate",
"beta": 0,
"creation": "2016-09-03 03:33:27.680331",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Document",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"license_plate",
"make",
"column_break_3",
"model",
"vehicle_details",
"last_odometer",
"acquisition_date",
"location",
"column_break_8",
"chassis_no",
"vehicle_value",
"employee",
"insurance_details",
"insurance_company",
"policy_no",
"column_break_15",
"start_date",
"end_date",
"additional_details",
"fuel_type",
"uom",
"carbon_check_date",
"column_break_21",
"color",
"wheels",
"doors",
"amended_from"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "license_plate",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "License Plate",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "make",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Manufacturer",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"fieldtype": "Column Break"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "model",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Model",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "vehicle_details",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Details",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"label": "Details"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "last_odometer",
"fieldtype": "Int",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Odometer Value (Last)",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 1,
"unique": 0
"set_only_once": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "acquisition_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Acquisition Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"label": "Acquisition Date"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "location",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Location",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"label": "Location"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_8",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"fieldtype": "Column Break"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "chassis_no",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Chassis No",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"label": "Chassis No"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "vehicle_value",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Vehicle Value",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 1,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"print_hide_if_no_value": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "employee",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Employee",
"length": 0,
"no_copy": 0,
"options": "Employee",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"options": "Employee"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "insurance_details",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Insurance Details",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"label": "Insurance Details"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "insurance_company",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Insurance Company",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"label": "Insurance Company"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "policy_no",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Policy No",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"label": "Policy No"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_15",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"fieldtype": "Column Break"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "start_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Start Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"label": "Start Date"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "end_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "End Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"label": "End Date"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "additional_details",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Additional Details",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"label": "Additional Details"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "fuel_type",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Fuel Type",
"length": 0,
"no_copy": 0,
"options": "Petrol\nDiesel\nNatural Gas\nElectric",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "",
"fieldname": "uom",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Fuel UOM",
"length": 0,
"no_copy": 0,
"options": "UOM",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "carbon_check_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Last Carbon Check",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"label": "Last Carbon Check"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_21",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"fieldtype": "Column Break"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "color",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Color",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"label": "Color"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "wheels",
"fieldtype": "Int",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Wheels",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"label": "Wheels"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "doors",
"fieldtype": "Int",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Doors",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"label": "Doors"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Amended From",
"length": 0,
"no_copy": 1,
"options": "Vehicle",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"read_only": 1
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2022-06-27 14:48:30.813359",
"links": [],
"modified": "2024-03-27 13:10:58.133410",
"modified_by": "Administrator",
"module": "Setup",
"name": "Vehicle",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Fleet Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
},
{
@@ -879,13 +231,9 @@
}
],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"search_fields": "license_plate,location,model",
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_field": "creation",
"sort_order": "DESC",
"title_field": "",
"track_changes": 1,
"track_seen": 0
}
"states": [],
"track_changes": 1
}

View File

@@ -1,61 +1,34 @@
{
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2013-02-22 01:28:09",
"custom": 0,
"description": "Cross Listing of Item in multiple groups",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Other",
"editable_grid": 1,
"actions": [],
"creation": "2013-02-22 01:28:09",
"description": "Cross Listing of Item in multiple groups",
"doctype": "DocType",
"document_type": "Other",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"item_group"
],
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"description": "",
"fieldname": "item_group",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Item Group",
"length": 0,
"no_copy": 0,
"options": "Item Group",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"fieldname": "item_group",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Item Group",
"options": "Item Group",
"reqd": 1
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2016-07-11 03:28:09.919314",
"modified_by": "Administrator",
"module": "Setup",
"name": "Website Item Group",
"owner": "Administrator",
"permissions": [],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"track_seen": 0
],
"idx": 1,
"istable": 1,
"links": [],
"modified": "2024-03-27 13:11:00.011403",
"modified_by": "Administrator",
"module": "Setup",
"name": "Website Item Group",
"owner": "Administrator",
"permissions": [],
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}

View File

@@ -122,7 +122,6 @@ def create_default_success_action():
def create_default_energy_point_rules():
for rule in get_default_energy_point_rules():
# check if any rule for ref. doctype exists
rule_exists = frappe.db.exists(

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,6 @@
# License: GNU General Public License v3. See license.txt
import frappe
from frappe import _
from frappe.utils import cstr, getdate

View File

@@ -30,10 +30,8 @@ def set_default_settings(args):
stock_settings = frappe.get_doc("Stock Settings")
stock_settings.item_naming_by = "Item Code"
stock_settings.valuation_method = "FIFO"
stock_settings.default_warehouse = frappe.db.get_value(
"Warehouse", {"warehouse_name": _("Stores")}
)
stock_settings.stock_uom = _("Nos")
stock_settings.default_warehouse = frappe.db.get_value("Warehouse", {"warehouse_name": _("Stores")})
stock_settings.stock_uom = "Nos"
stock_settings.auto_indent = 1
stock_settings.auto_insert_price_list_rate_if_missing = 1
stock_settings.set_qty_in_transactions_based_on_serial_no_input = 1

View File

@@ -276,9 +276,7 @@ def install(country=None):
records += [{"doctype": doctype, title_field: title} for title in read_lines(filename)]
base_path = frappe.get_app_path("erpnext", "stock", "doctype")
response = frappe.read_file(
os.path.join(base_path, "delivery_trip/dispatch_notification_template.html")
)
response = frappe.read_file(os.path.join(base_path, "delivery_trip/dispatch_notification_template.html"))
records += [
{
@@ -336,16 +334,10 @@ def add_uom_data():
open(frappe.get_app_path("erpnext", "setup", "setup_wizard", "data", "uom_data.json")).read()
)
for d in uoms:
if not frappe.db.exists("UOM", _(d.get("uom_name"))):
frappe.get_doc(
{
"doctype": "UOM",
"uom_name": _(d.get("uom_name")),
"name": _(d.get("uom_name")),
"must_be_whole_number": d.get("must_be_whole_number"),
"enabled": 1,
}
).db_insert()
if not frappe.db.exists("UOM", d.get("uom_name")):
doc = frappe.new_doc("UOM")
doc.update(d)
doc.save()
# bootstrap uom conversion factors
uom_conversions = json.loads(
@@ -359,14 +351,14 @@ def add_uom_data():
if not frappe.db.exists(
"UOM Conversion Factor",
{"from_uom": _(d.get("from_uom")), "to_uom": _(d.get("to_uom"))},
{"from_uom": d.get("from_uom"), "to_uom": d.get("to_uom")},
):
frappe.get_doc(
{
"doctype": "UOM Conversion Factor",
"category": _(d.get("category")),
"from_uom": _(d.get("from_uom")),
"to_uom": _(d.get("to_uom")),
"from_uom": d.get("from_uom"),
"to_uom": d.get("to_uom"),
"value": d.get("value"),
}
).db_insert()
@@ -477,10 +469,9 @@ def update_stock_settings():
stock_settings = frappe.get_doc("Stock Settings")
stock_settings.item_naming_by = "Item Code"
stock_settings.valuation_method = "FIFO"
stock_settings.default_warehouse = frappe.db.get_value(
"Warehouse", {"warehouse_name": _("Stores")}
)
stock_settings.default_warehouse = frappe.db.get_value("Warehouse", {"warehouse_name": _("Stores")})
stock_settings.stock_uom = _("Nos")
stock_settings.stock_uom = "Nos"
stock_settings.auto_indent = 1
stock_settings.auto_insert_price_list_rate_if_missing = 1
stock_settings.set_qty_in_transactions_based_on_serial_no_input = 1

View File

@@ -14,7 +14,7 @@ def setup_taxes_and_charges(company_name: str, country: str):
frappe.throw(_("Company {} does not exist yet. Taxes setup aborted.").format(company_name))
file_path = os.path.join(os.path.dirname(__file__), "..", "data", "country_wise_tax.json")
with open(file_path, "r") as json_file:
with open(file_path) as json_file:
tax_data = json.load(json_file)
country_wise_tax = tax_data.get(country)
@@ -54,7 +54,12 @@ def simple_to_detailed(templates):
{
"title": title,
"taxes": [
{"tax_type": {"account_name": data.get("account_name"), "tax_rate": data.get("tax_rate")}}
{
"tax_type": {
"account_name": data.get("account_name"),
"tax_rate": data.get("tax_rate"),
}
}
],
}
for title, data in templates.items()
@@ -110,9 +115,7 @@ def update_regional_tax_settings(country, company):
path = frappe.get_app_path("erpnext", "regional", frappe.scrub(country))
if os.path.exists(path.encode("utf-8")):
try:
module_name = "erpnext.regional.{0}.setup.update_regional_tax_settings".format(
frappe.scrub(country)
)
module_name = f"erpnext.regional.{frappe.scrub(country)}.setup.update_regional_tax_settings"
frappe.get_attr(module_name)(country, company)
except (ImportError, AttributeError):
pass
@@ -141,7 +144,7 @@ def make_taxes_and_charges_template(company_name, doctype, template):
# if account_head is a dict, search or create the account and get it's name
if isinstance(account_data, dict):
tax_row_defaults["description"] = "{0} @ {1}".format(
tax_row_defaults["description"] = "{} @ {}".format(
account_data.get("account_name"), account_data.get("tax_rate")
)
tax_row_defaults["rate"] = account_data.get("tax_rate")

View File

@@ -5,7 +5,7 @@ import frappe
from frappe import _
from frappe.utils import add_days, flt, get_datetime_str, nowdate
from frappe.utils.data import now_datetime
from frappe.utils.nestedset import get_ancestors_of, get_root_of # noqa
from frappe.utils.nestedset import get_root_of
from erpnext import get_default_company
@@ -81,14 +81,12 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None, args=No
if entries:
return flt(entries[0].exchange_rate)
if frappe.get_cached_value(
"Currency Exchange Settings", "Currency Exchange Settings", "disabled"
):
if frappe.get_cached_value("Currency Exchange Settings", "Currency Exchange Settings", "disabled"):
return 0.00
try:
cache = frappe.cache()
key = "currency_exchange_rate_{0}:{1}:{2}".format(transaction_date, from_currency, to_currency)
key = f"currency_exchange_rate_{transaction_date}:{from_currency}:{to_currency}"
value = cache.get(key)
if not value: