mirror of
https://github.com/frappe/erpnext.git
synced 2026-07-01 06:48:36 +00:00
Compare commits
43 Commits
v14.92.8
...
version-14
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd7e5b3e05 | ||
|
|
adf92a8292 | ||
|
|
df6dc540f8 | ||
|
|
12b27883f6 | ||
|
|
5bbfb79cdc | ||
|
|
266ac2d5be | ||
|
|
7a98e13d7d | ||
|
|
aeee42e857 | ||
|
|
e1674d2017 | ||
|
|
65d7c6b882 | ||
|
|
966f262e38 | ||
|
|
44f81092b6 | ||
|
|
6f1616bc95 | ||
|
|
07ac93d06a | ||
|
|
34499d7f77 | ||
|
|
2967de1999 | ||
|
|
824beaa893 | ||
|
|
b4dc1be5ed | ||
|
|
cf49c32b94 | ||
|
|
d54f45469a | ||
|
|
ad5181c52f | ||
|
|
6e03d45034 | ||
|
|
7a18f86dd5 | ||
|
|
39e1bddce6 | ||
|
|
d09de53d1d | ||
|
|
8035940263 | ||
|
|
c69f3d330a | ||
|
|
90d88b1c26 | ||
|
|
22eec09175 | ||
|
|
dbfd4ea4d3 | ||
|
|
8d28dcb18b | ||
|
|
3f186b24f3 | ||
|
|
4b0ddbf73a | ||
|
|
cddf1e1ee5 | ||
|
|
22e5aba02b | ||
|
|
21d13859a0 | ||
|
|
18fbe69892 | ||
|
|
f2043baf36 | ||
|
|
6267b9aea5 | ||
|
|
6499a1dae0 | ||
|
|
478992812f | ||
|
|
634dd11d72 | ||
|
|
55d2a54785 |
2
.github/helper/install.sh
vendored
2
.github/helper/install.sh
vendored
@@ -4,8 +4,6 @@ set -e
|
||||
|
||||
cd ~ || exit
|
||||
|
||||
export BENCH_DISABLE_UV=1
|
||||
|
||||
sudo apt update && sudo apt install redis-server libcups2-dev
|
||||
|
||||
pip install frappe-bench
|
||||
|
||||
@@ -3,7 +3,7 @@ import inspect
|
||||
|
||||
import frappe
|
||||
|
||||
__version__ = "14.92.8"
|
||||
__version__ = "14.92.14"
|
||||
|
||||
|
||||
def get_default_company(user=None):
|
||||
|
||||
@@ -11,9 +11,9 @@ frappe.ui.form.on("Period Closing Voucher", {
|
||||
return {
|
||||
filters: [
|
||||
["Account", "company", "=", frm.doc.company],
|
||||
["Account", "is_group", "=", "0"],
|
||||
["Account", "is_group", "=", 0],
|
||||
["Account", "freeze_account", "=", "No"],
|
||||
["Account", "root_type", "in", "Liability, Equity"],
|
||||
["Account", "root_type", "in", ["Liability", "Equity"]],
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
@@ -2828,6 +2828,60 @@ class TestSalesInvoice(FrappeTestCase):
|
||||
self.assertEqual(sales_invoice.items[0].item_tax_template, "_Test Account Excise Duty @ 10 - _TC")
|
||||
self.assertEqual(sales_invoice.items[0].item_tax_rate, item_tax_map)
|
||||
|
||||
def test_item_tax_template_change_with_grand_total_discount(self):
|
||||
"""
|
||||
Test that when item tax template changes due to discount on Grand Total,
|
||||
the tax calculations are consistent.
|
||||
"""
|
||||
item = create_item("Test Item With Multiple Tax Templates")
|
||||
|
||||
item.set("taxes", [])
|
||||
item.append(
|
||||
"taxes",
|
||||
{
|
||||
"item_tax_template": "_Test Account Excise Duty @ 10 - _TC",
|
||||
"minimum_net_rate": 0,
|
||||
"maximum_net_rate": 500,
|
||||
},
|
||||
)
|
||||
|
||||
item.append(
|
||||
"taxes",
|
||||
{
|
||||
"item_tax_template": "_Test Account Excise Duty @ 12 - _TC",
|
||||
"minimum_net_rate": 501,
|
||||
"maximum_net_rate": 1000,
|
||||
},
|
||||
)
|
||||
|
||||
item.save()
|
||||
|
||||
si = create_sales_invoice(item=item.name, rate=700, do_not_save=True)
|
||||
si.append(
|
||||
"taxes",
|
||||
{
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": "_Test Account Excise Duty - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Excise Duty",
|
||||
"rate": 0,
|
||||
},
|
||||
)
|
||||
si.insert()
|
||||
|
||||
self.assertEqual(si.items[0].item_tax_template, "_Test Account Excise Duty @ 12 - _TC")
|
||||
|
||||
si.apply_discount_on = "Grand Total"
|
||||
si.discount_amount = 300
|
||||
si.save()
|
||||
|
||||
# Verify template changed to 10%
|
||||
self.assertEqual(si.items[0].item_tax_template, "_Test Account Excise Duty @ 10 - _TC")
|
||||
self.assertEqual(si.taxes[0].tax_amount, 70) # 10% of 700
|
||||
self.assertEqual(si.grand_total, 470) # 700 + 70 - 300
|
||||
|
||||
si.submit()
|
||||
|
||||
@change_settings("Selling Settings", {"enable_discount_accounting": 1})
|
||||
def test_sales_invoice_with_discount_accounting_enabled(self):
|
||||
discount_account = create_account(
|
||||
|
||||
@@ -52,28 +52,25 @@ def group_by_party_and_category(data, filters):
|
||||
party_category_wise_map = {}
|
||||
|
||||
for row in data:
|
||||
key = (row.get("party_type"), row.get("party"), row.get("tax_withholding_category"))
|
||||
party_category_wise_map.setdefault(
|
||||
(row.get("party"), row.get("section_code")),
|
||||
key,
|
||||
{
|
||||
"pan": row.get("pan"),
|
||||
"tax_id": row.get("tax_id"),
|
||||
"party": row.get("party"),
|
||||
"party_type": row.get("party_type"),
|
||||
"party_name": row.get("party_name"),
|
||||
"section_code": row.get("section_code"),
|
||||
"entity_type": row.get("entity_type"),
|
||||
"tax_withholding_category": row.get("tax_withholding_category"),
|
||||
"party_entity_type": row.get("party_entity_type"),
|
||||
"rate": row.get("rate"),
|
||||
"total_amount": 0.0,
|
||||
"tax_amount": 0.0,
|
||||
},
|
||||
)
|
||||
|
||||
party_category_wise_map.get((row.get("party"), row.get("section_code")))["total_amount"] += row.get(
|
||||
"total_amount", 0.0
|
||||
)
|
||||
|
||||
party_category_wise_map.get((row.get("party"), row.get("section_code")))["tax_amount"] += row.get(
|
||||
"tax_amount", 0.0
|
||||
)
|
||||
party_category_wise_map.get(key)["total_amount"] += row.get("total_amount", 0.0)
|
||||
party_category_wise_map.get(key)["tax_amount"] += row.get("tax_amount", 0.0)
|
||||
|
||||
final_result = get_final_result(party_category_wise_map)
|
||||
|
||||
@@ -114,13 +111,18 @@ def get_columns(filters):
|
||||
columns.extend(
|
||||
[
|
||||
{
|
||||
"label": _("Section Code"),
|
||||
"label": _("Tax Withholding Category"),
|
||||
"options": "Tax Withholding Category",
|
||||
"fieldname": "section_code",
|
||||
"fieldname": "tax_withholding_category",
|
||||
"fieldtype": "Link",
|
||||
"width": 180,
|
||||
},
|
||||
{"label": _("Entity Type"), "fieldname": "entity_type", "fieldtype": "Data", "width": 180},
|
||||
{
|
||||
"label": _("{0} Type").format(_(filters.get("party_type", "Party"))),
|
||||
"fieldname": "party_entity_type",
|
||||
"fieldtype": "Data",
|
||||
"width": 180,
|
||||
},
|
||||
{
|
||||
"label": _("TDS Rate %") if filters.get("party_type") == "Supplier" else _("TCS Rate %"),
|
||||
"fieldname": "rate",
|
||||
|
||||
@@ -106,8 +106,8 @@ def get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_
|
||||
|
||||
row.update(
|
||||
{
|
||||
"section_code": tax_withholding_category or "",
|
||||
"entity_type": party_map.get(party, {}).get(party_type),
|
||||
"tax_withholding_category": tax_withholding_category or "",
|
||||
"party_entity_type": party_map.get(party, {}).get(party_type),
|
||||
"rate": rate,
|
||||
"total_amount": total_amount,
|
||||
"grand_total": grand_total,
|
||||
@@ -127,7 +127,7 @@ def get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_
|
||||
else:
|
||||
entries[key] = row
|
||||
out = list(entries.values())
|
||||
out.sort(key=lambda x: (x["section_code"], x["transaction_date"]))
|
||||
out.sort(key=lambda x: (x["tax_withholding_category"], x["transaction_date"], x["ref_no"]))
|
||||
|
||||
return out
|
||||
|
||||
@@ -177,9 +177,9 @@ def get_columns(filters):
|
||||
pan = "pan" if frappe.db.has_column(filters.party_type, "pan") else "tax_id"
|
||||
columns = [
|
||||
{
|
||||
"label": _("Section Code"),
|
||||
"label": _("Tax Withholding Category"),
|
||||
"options": "Tax Withholding Category",
|
||||
"fieldname": "section_code",
|
||||
"fieldname": "tax_withholding_category",
|
||||
"fieldtype": "Link",
|
||||
"width": 90,
|
||||
},
|
||||
@@ -208,7 +208,12 @@ def get_columns(filters):
|
||||
|
||||
columns.extend(
|
||||
[
|
||||
{"label": _("Entity Type"), "fieldname": "entity_type", "fieldtype": "Data", "width": 100},
|
||||
{
|
||||
"label": _("{0} Type").format(_(filters.get("party_type", "Party"))),
|
||||
"fieldname": "party_entity_type",
|
||||
"fieldtype": "Data",
|
||||
"width": 100,
|
||||
},
|
||||
]
|
||||
)
|
||||
if filters.party_type == "Supplier":
|
||||
|
||||
@@ -118,7 +118,7 @@ class TestTdsPayableMonthly(AccountsTestMixin, FrappeTestCase):
|
||||
voucher_expected_values = expected_values[i]
|
||||
voucher_actual_values = (
|
||||
voucher.ref_no,
|
||||
voucher.section_code,
|
||||
voucher.tax_withholding_category,
|
||||
voucher.rate,
|
||||
voucher.base_total,
|
||||
voucher.tax_amount,
|
||||
|
||||
11
erpnext/change_log/v14/v14_92_13.md
Normal file
11
erpnext/change_log/v14/v14_92_13.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# End of Life reached
|
||||
|
||||
With the release of ERPNext version 16, version 14 has reached its end of life.
|
||||
|
||||
This means that version 14 of ERPNext (which is running on this site) will no longer receive critical bug fixes and is no longer covered under Frappe Support.
|
||||
|
||||
We highly recommend that you update to version 16 to get the latest bug fixes, features and other improvements.
|
||||
|
||||
[Click here to know more about version 16](https://frappe.io/erpnext/version-16)
|
||||
|
||||
If you're on [Frappe Cloud](https://frappe.io/cloud), [click here to learn how to update to v16](https://docs.frappe.io/cloud/sites/version-upgrade)
|
||||
@@ -728,7 +728,16 @@ class SellingController(StockController):
|
||||
|
||||
|
||||
def set_default_income_account_for_item(obj):
|
||||
for d in obj.get("items"):
|
||||
if d.item_code:
|
||||
if getattr(d, "income_account", None):
|
||||
set_item_default(d.item_code, obj.company, "income_account", d.income_account)
|
||||
"""Set income account as default for items in the transaction.
|
||||
|
||||
Updates the item default income account for each item in the transaction
|
||||
if it differs from the company's default income account.
|
||||
|
||||
Args:
|
||||
obj: Transaction document containing items table with income_account field
|
||||
"""
|
||||
company_default = frappe.get_cached_value("Company", obj.company, "default_income_account")
|
||||
for d in obj.get("items", default=[]):
|
||||
income_account = getattr(d, "income_account", None)
|
||||
if d.item_code and income_account and income_account != company_default:
|
||||
set_item_default(d.item_code, obj.company, "income_account", income_account)
|
||||
|
||||
@@ -42,17 +42,23 @@ class calculate_taxes_and_totals:
|
||||
items = list(filter(lambda item: not item.get("is_alternative"), self.doc.get("items")))
|
||||
return items
|
||||
|
||||
def calculate(self):
|
||||
def calculate(self, ignore_tax_template_validation=False):
|
||||
if not len(self._items):
|
||||
return
|
||||
|
||||
self.discount_amount_applied = False
|
||||
self.need_recomputation = False
|
||||
self.ignore_tax_template_validation = ignore_tax_template_validation
|
||||
|
||||
self._calculate()
|
||||
|
||||
if self.doc.meta.get_field("discount_amount"):
|
||||
self.set_discount_amount()
|
||||
self.apply_discount_amount()
|
||||
|
||||
if not ignore_tax_template_validation and self.need_recomputation:
|
||||
return self.calculate(ignore_tax_template_validation=True)
|
||||
|
||||
# Update grand total as per cash and non trade discount
|
||||
if self.doc.apply_discount_on == "Grand Total" and self.doc.get("is_cash_or_non_trade_discount"):
|
||||
self.doc.grand_total -= self.doc.discount_amount
|
||||
@@ -96,6 +102,9 @@ class calculate_taxes_and_totals:
|
||||
self.doc.base_tax_withholding_net_total = sum_base_net_amount
|
||||
|
||||
def validate_item_tax_template(self):
|
||||
if self.ignore_tax_template_validation:
|
||||
return
|
||||
|
||||
if self.doc.get("is_return") and self.doc.get("return_against"):
|
||||
return
|
||||
|
||||
@@ -136,6 +145,10 @@ class calculate_taxes_and_totals:
|
||||
)
|
||||
)
|
||||
|
||||
# For correct tax_amount calculation re-computation is required
|
||||
if self.discount_amount_applied and self.doc.apply_discount_on == "Grand Total":
|
||||
self.need_recomputation = True
|
||||
|
||||
def update_item_tax_map(self):
|
||||
for item in self.doc.items:
|
||||
item.item_tax_rate = get_item_tax_map(
|
||||
|
||||
@@ -1089,9 +1089,12 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
plc_conversion_rate() {
|
||||
if(this.frm.doc.price_list_currency === this.get_company_currency()) {
|
||||
this.frm.set_value("plc_conversion_rate", 1.0);
|
||||
} else if(this.frm.doc.price_list_currency === this.frm.doc.currency
|
||||
&& this.frm.doc.plc_conversion_rate && cint(this.frm.doc.plc_conversion_rate) != 1 &&
|
||||
cint(this.frm.doc.plc_conversion_rate) != cint(this.frm.doc.conversion_rate)) {
|
||||
} else if (
|
||||
this.frm.doc.price_list_currency === this.frm.doc.currency &&
|
||||
this.frm.doc.plc_conversion_rate &&
|
||||
flt(this.frm.doc.plc_conversion_rate) != 1 &&
|
||||
flt(this.frm.doc.plc_conversion_rate) != flt(this.frm.doc.conversion_rate)
|
||||
) {
|
||||
this.frm.set_value("conversion_rate", this.frm.doc.plc_conversion_rate);
|
||||
}
|
||||
|
||||
|
||||
@@ -1507,6 +1507,23 @@ class TestDeliveryNote(FrappeTestCase):
|
||||
|
||||
self.assertEqual(stock_value_difference, 100.0 * 5)
|
||||
|
||||
def test_negative_stock_with_higher_precision(self):
|
||||
original_flt_precision = frappe.db.get_default("float_precision")
|
||||
frappe.db.set_single_value("System Settings", "float_precision", 7)
|
||||
|
||||
item_code = make_item(
|
||||
"Test Negative Stock High Precision Item", properties={"is_stock_item": 1, "valuation_rate": 1}
|
||||
).name
|
||||
dn = create_delivery_note(
|
||||
item_code=item_code,
|
||||
qty=0.0000010,
|
||||
do_not_submit=True,
|
||||
)
|
||||
|
||||
self.assertRaises(frappe.ValidationError, dn.submit)
|
||||
|
||||
frappe.db.set_single_value("System Settings", "float_precision", original_flt_precision)
|
||||
|
||||
|
||||
def create_delivery_note(**args):
|
||||
dn = frappe.new_doc("Delivery Note")
|
||||
|
||||
@@ -686,18 +686,14 @@ def get_available_item_locations(
|
||||
locations = get_available_item_locations_for_batched_item(
|
||||
item_code,
|
||||
from_warehouses,
|
||||
required_qty,
|
||||
company,
|
||||
total_picked_qty,
|
||||
consider_rejected_warehouses=consider_rejected_warehouses,
|
||||
)
|
||||
else:
|
||||
locations = get_available_item_locations_for_other_item(
|
||||
item_code,
|
||||
from_warehouses,
|
||||
required_qty,
|
||||
company,
|
||||
total_picked_qty,
|
||||
consider_rejected_warehouses=consider_rejected_warehouses,
|
||||
)
|
||||
|
||||
@@ -790,9 +786,7 @@ def get_available_item_locations_for_serialized_item(
|
||||
def get_available_item_locations_for_batched_item(
|
||||
item_code,
|
||||
from_warehouses,
|
||||
required_qty,
|
||||
company,
|
||||
total_picked_qty=0,
|
||||
consider_rejected_warehouses=False,
|
||||
):
|
||||
sle = frappe.qb.DocType("Stock Ledger Entry")
|
||||
@@ -813,7 +807,6 @@ def get_available_item_locations_for_batched_item(
|
||||
.groupby(sle.warehouse, sle.batch_no, sle.item_code)
|
||||
.having(Sum(sle.actual_qty) > 0)
|
||||
.orderby(IfNull(batch.expiry_date, "2200-01-01"), batch.creation, sle.batch_no, sle.warehouse)
|
||||
.limit(ceil(required_qty + total_picked_qty))
|
||||
)
|
||||
|
||||
if from_warehouses:
|
||||
@@ -838,7 +831,6 @@ def get_available_item_locations_for_serial_and_batched_item(
|
||||
locations = get_available_item_locations_for_batched_item(
|
||||
item_code,
|
||||
from_warehouses,
|
||||
required_qty,
|
||||
company,
|
||||
consider_rejected_warehouses=consider_rejected_warehouses,
|
||||
)
|
||||
@@ -872,9 +864,7 @@ def get_available_item_locations_for_serial_and_batched_item(
|
||||
def get_available_item_locations_for_other_item(
|
||||
item_code,
|
||||
from_warehouses,
|
||||
required_qty,
|
||||
company,
|
||||
total_picked_qty=0,
|
||||
consider_rejected_warehouses=False,
|
||||
):
|
||||
bin = frappe.qb.DocType("Bin")
|
||||
@@ -883,7 +873,6 @@ def get_available_item_locations_for_other_item(
|
||||
.select(bin.warehouse, bin.actual_qty.as_("qty"))
|
||||
.where((bin.item_code == item_code) & (bin.actual_qty > 0))
|
||||
.orderby(bin.creation)
|
||||
.limit(ceil(required_qty + total_picked_qty))
|
||||
)
|
||||
|
||||
if from_warehouses:
|
||||
|
||||
@@ -41,9 +41,37 @@ def get_data(report_filters):
|
||||
gl_data = voucher_wise_gl_data.get(key) or {}
|
||||
d.account_value = gl_data.get("account_value", 0)
|
||||
d.difference_value = d.stock_value - d.account_value
|
||||
d.ledger_type = "Stock Ledger Entry"
|
||||
if abs(d.difference_value) > 0.1:
|
||||
data.append(d)
|
||||
|
||||
if key in voucher_wise_gl_data:
|
||||
del voucher_wise_gl_data[key]
|
||||
|
||||
if voucher_wise_gl_data:
|
||||
data += get_gl_ledgers_with_no_stock_ledger_entries(voucher_wise_gl_data)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def get_gl_ledgers_with_no_stock_ledger_entries(voucher_wise_gl_data):
|
||||
data = []
|
||||
|
||||
for key in voucher_wise_gl_data:
|
||||
gl_data = voucher_wise_gl_data.get(key) or {}
|
||||
data.append(
|
||||
{
|
||||
"name": gl_data.get("name"),
|
||||
"ledger_type": "GL Entry",
|
||||
"voucher_type": gl_data.get("voucher_type"),
|
||||
"voucher_no": gl_data.get("voucher_no"),
|
||||
"posting_date": gl_data.get("posting_date"),
|
||||
"stock_value": 0,
|
||||
"account_value": gl_data.get("account_value", 0),
|
||||
"difference_value": gl_data.get("account_value", 0) * -1,
|
||||
}
|
||||
)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
@@ -88,6 +116,7 @@ def get_gl_data(report_filters, filters):
|
||||
"voucher_type",
|
||||
"voucher_no",
|
||||
"sum(debit_in_account_currency) - sum(credit_in_account_currency) as account_value",
|
||||
"posting_date",
|
||||
],
|
||||
group_by="voucher_type, voucher_no",
|
||||
)
|
||||
@@ -105,10 +134,15 @@ def get_columns(filters):
|
||||
{
|
||||
"label": _("Stock Ledger ID"),
|
||||
"fieldname": "name",
|
||||
"fieldtype": "Link",
|
||||
"options": "Stock Ledger Entry",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"options": "ledger_type",
|
||||
"width": "80",
|
||||
},
|
||||
{
|
||||
"label": _("Ledger Type"),
|
||||
"fieldname": "ledger_type",
|
||||
"fieldtype": "Data",
|
||||
},
|
||||
{"label": _("Posting Date"), "fieldname": "posting_date", "fieldtype": "Date"},
|
||||
{"label": _("Posting Time"), "fieldname": "posting_time", "fieldtype": "Time"},
|
||||
{"label": _("Voucher Type"), "fieldname": "voucher_type", "width": "110"},
|
||||
|
||||
@@ -715,7 +715,11 @@ class update_entries_after:
|
||||
diff = self.wh_data.qty_after_transaction + flt(sle.actual_qty)
|
||||
diff = flt(diff, self.flt_precision) # respect system precision
|
||||
|
||||
if diff < 0 and abs(diff) > 0.0001:
|
||||
diff_threshold = 0.0001
|
||||
if self.flt_precision > 4:
|
||||
diff_threshold = 10 ** (-1 * self.flt_precision)
|
||||
|
||||
if diff < 0 and abs(diff) > diff_threshold:
|
||||
# negative stock!
|
||||
exc = sle.copy().update({"diff": diff})
|
||||
self.exceptions.setdefault(sle.warehouse, []).append(exc)
|
||||
@@ -987,7 +991,7 @@ class update_entries_after:
|
||||
# else it remains the same as that of previous entry
|
||||
self.wh_data.valuation_rate = new_stock_value / new_stock_qty
|
||||
|
||||
if not self.wh_data.valuation_rate and sle.voucher_detail_no:
|
||||
if self.wh_data.valuation_rate is None and sle.voucher_detail_no:
|
||||
allow_zero_rate = self.check_if_allow_zero_valuation_rate(sle.voucher_type, sle.voucher_detail_no)
|
||||
if not allow_zero_rate:
|
||||
self.wh_data.valuation_rate = self.get_fallback_rate(sle)
|
||||
|
||||
@@ -449,10 +449,16 @@ def get_documents_with_active_service_level_agreement():
|
||||
|
||||
|
||||
def set_documents_with_active_service_level_agreement():
|
||||
active = [
|
||||
sla.document_type for sla in frappe.get_all("Service Level Agreement", fields=["document_type"])
|
||||
]
|
||||
frappe.cache().hset("service_level_agreement", "active", active)
|
||||
try:
|
||||
active = frozenset(
|
||||
sla.document_type for sla in frappe.get_all("Service Level Agreement", fields=["document_type"])
|
||||
)
|
||||
frappe.cache().hset("service_level_agreement", "active", active)
|
||||
except (frappe.DoesNotExistError, frappe.db.TableMissingError):
|
||||
# This happens during install / uninstall when wildcard hook for SLA intercepts some doc action.
|
||||
# In both cases, the error can be safely ignored.
|
||||
active = frozenset()
|
||||
|
||||
return active
|
||||
|
||||
|
||||
|
||||
@@ -23,9 +23,6 @@ dependencies = [
|
||||
"python-youtube~=0.8.0",
|
||||
"taxjar~=1.9.2",
|
||||
"tweepy~=3.10.0",
|
||||
|
||||
# Pin for compatibility, v2 has breaking changes
|
||||
"urllib3>=1.26.4,<2",
|
||||
]
|
||||
|
||||
[build-system]
|
||||
|
||||
Reference in New Issue
Block a user