mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-02 19:59:12 +00:00
Merge pull request #27299 from ankush/strict_linting_v13
chore: cleanup linting errors and introduce strict linting checks
This commit is contained in:
@@ -13,3 +13,4 @@
|
|||||||
|
|
||||||
# Whitespace trimming throughout codebase
|
# Whitespace trimming throughout codebase
|
||||||
9bb69e711a5da43aaf8c8ecb5601aeffd89dbe5a
|
9bb69e711a5da43aaf8c8ecb5601aeffd89dbe5a
|
||||||
|
f0bcb753fb7ebbb64bb0d6906d431d002f0f7d8f
|
||||||
|
|||||||
72
.github/helper/.flake8_strict
vendored
Normal file
72
.github/helper/.flake8_strict
vendored
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
[flake8]
|
||||||
|
ignore =
|
||||||
|
B007,
|
||||||
|
B950,
|
||||||
|
E101,
|
||||||
|
E111,
|
||||||
|
E114,
|
||||||
|
E116,
|
||||||
|
E117,
|
||||||
|
E121,
|
||||||
|
E122,
|
||||||
|
E123,
|
||||||
|
E124,
|
||||||
|
E125,
|
||||||
|
E126,
|
||||||
|
E127,
|
||||||
|
E128,
|
||||||
|
E131,
|
||||||
|
E201,
|
||||||
|
E202,
|
||||||
|
E203,
|
||||||
|
E211,
|
||||||
|
E221,
|
||||||
|
E222,
|
||||||
|
E223,
|
||||||
|
E224,
|
||||||
|
E225,
|
||||||
|
E226,
|
||||||
|
E228,
|
||||||
|
E231,
|
||||||
|
E241,
|
||||||
|
E242,
|
||||||
|
E251,
|
||||||
|
E261,
|
||||||
|
E262,
|
||||||
|
E265,
|
||||||
|
E266,
|
||||||
|
E271,
|
||||||
|
E272,
|
||||||
|
E273,
|
||||||
|
E274,
|
||||||
|
E301,
|
||||||
|
E302,
|
||||||
|
E303,
|
||||||
|
E305,
|
||||||
|
E306,
|
||||||
|
E401,
|
||||||
|
E402,
|
||||||
|
E501,
|
||||||
|
E502,
|
||||||
|
E701,
|
||||||
|
E702,
|
||||||
|
E703,
|
||||||
|
E741,
|
||||||
|
F401,
|
||||||
|
F403,
|
||||||
|
W191,
|
||||||
|
W291,
|
||||||
|
W292,
|
||||||
|
W293,
|
||||||
|
W391,
|
||||||
|
W503,
|
||||||
|
W504,
|
||||||
|
E711,
|
||||||
|
E129,
|
||||||
|
F841,
|
||||||
|
E713,
|
||||||
|
E712,
|
||||||
|
|
||||||
|
|
||||||
|
max-line-length = 200
|
||||||
|
exclude=.github/helper/semgrep_rules,test_*.py
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
name: Semgrep
|
name: Linters
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request: { }
|
pull_request: { }
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
semgrep:
|
|
||||||
name: Frappe Linter
|
linters:
|
||||||
|
name: linters
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -16,3 +17,11 @@ jobs:
|
|||||||
config: >-
|
config: >-
|
||||||
r/python.lang.correctness
|
r/python.lang.correctness
|
||||||
.github/helper/semgrep_rules
|
.github/helper/semgrep_rules
|
||||||
|
|
||||||
|
- name: Set up Python 3.8
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: 3.8
|
||||||
|
|
||||||
|
- name: Install and Run Pre-commit
|
||||||
|
uses: pre-commit/action@v2.0.0
|
||||||
29
.pre-commit-config.yaml
Normal file
29
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
exclude: 'node_modules|.git'
|
||||||
|
default_stages: [commit]
|
||||||
|
fail_fast: false
|
||||||
|
|
||||||
|
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: v4.0.1
|
||||||
|
hooks:
|
||||||
|
- id: trailing-whitespace
|
||||||
|
files: "erpnext.*"
|
||||||
|
exclude: ".*json$|.*txt$|.*csv|.*md"
|
||||||
|
- id: check-yaml
|
||||||
|
- id: no-commit-to-branch
|
||||||
|
args: ['--branch', 'develop']
|
||||||
|
- id: check-merge-conflict
|
||||||
|
- id: check-ast
|
||||||
|
|
||||||
|
- repo: https://gitlab.com/pycqa/flake8
|
||||||
|
rev: 3.9.2
|
||||||
|
hooks:
|
||||||
|
- id: flake8
|
||||||
|
args: ['--config', '.github/helper/.flake8_strict']
|
||||||
|
exclude: ".*setup.py$"
|
||||||
|
|
||||||
|
ci:
|
||||||
|
autoupdate_schedule: weekly
|
||||||
|
skip: []
|
||||||
|
submodules: false
|
||||||
@@ -31,7 +31,7 @@ class ERPNextAddress(Address):
|
|||||||
customers = frappe.db.get_all("Customer", filters=filters, as_list=True)
|
customers = frappe.db.get_all("Customer", filters=filters, as_list=True)
|
||||||
for customer_name in customers:
|
for customer_name in customers:
|
||||||
frappe.db.set_value("Customer", customer_name[0], "primary_address", address_display)
|
frappe.db.set_value("Customer", customer_name[0], "primary_address", address_display)
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_shipping_address(company, address = None):
|
def get_shipping_address(company, address = None):
|
||||||
filters = [
|
filters = [
|
||||||
|
|||||||
@@ -359,7 +359,7 @@ def make_gl_entries(doc, credit_account, debit_account, against,
|
|||||||
try:
|
try:
|
||||||
make_gl_entries(gl_entries, cancel=(doc.docstatus == 2), merge_entries=True)
|
make_gl_entries(gl_entries, cancel=(doc.docstatus == 2), merge_entries=True)
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
except:
|
except Exception:
|
||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
traceback = frappe.get_traceback()
|
traceback = frappe.get_traceback()
|
||||||
frappe.log_error(message=traceback)
|
frappe.log_error(message=traceback)
|
||||||
@@ -430,7 +430,7 @@ def book_revenue_via_journal_entry(doc, credit_account, debit_account, against,
|
|||||||
|
|
||||||
if submit:
|
if submit:
|
||||||
journal_entry.submit()
|
journal_entry.submit()
|
||||||
except:
|
except Exception:
|
||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
traceback = frappe.get_traceback()
|
traceback = frappe.get_traceback()
|
||||||
frappe.log_error(message=traceback)
|
frappe.log_error(message=traceback)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class BankTransaction(StatusUpdater):
|
|||||||
self.update_allocations()
|
self.update_allocations()
|
||||||
self.clear_linked_payment_entries()
|
self.clear_linked_payment_entries()
|
||||||
self.set_status(update=True)
|
self.set_status(update=True)
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
self.clear_linked_payment_entries(for_cancel=True)
|
self.clear_linked_payment_entries(for_cancel=True)
|
||||||
self.set_status(update=True)
|
self.set_status(update=True)
|
||||||
@@ -45,7 +45,7 @@ class BankTransaction(StatusUpdater):
|
|||||||
frappe.db.set_value(self.doctype, self.name, "status", "Reconciled")
|
frappe.db.set_value(self.doctype, self.name, "status", "Reconciled")
|
||||||
|
|
||||||
self.reload()
|
self.reload()
|
||||||
|
|
||||||
def clear_linked_payment_entries(self, for_cancel=False):
|
def clear_linked_payment_entries(self, for_cancel=False):
|
||||||
for payment_entry in self.payment_entries:
|
for payment_entry in self.payment_entries:
|
||||||
if payment_entry.payment_document in ["Payment Entry", "Journal Entry", "Purchase Invoice", "Expense Claim"]:
|
if payment_entry.payment_document in ["Payment Entry", "Journal Entry", "Purchase Invoice", "Expense Claim"]:
|
||||||
@@ -77,7 +77,7 @@ class BankTransaction(StatusUpdater):
|
|||||||
|
|
||||||
def get_reconciled_bank_transactions(payment_entry):
|
def get_reconciled_bank_transactions(payment_entry):
|
||||||
reconciled_bank_transactions = frappe.get_all(
|
reconciled_bank_transactions = frappe.get_all(
|
||||||
'Bank Transaction Payments',
|
'Bank Transaction Payments',
|
||||||
filters = {
|
filters = {
|
||||||
'payment_entry': payment_entry.payment_entry
|
'payment_entry': payment_entry.payment_entry
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ class PartyLink(Document):
|
|||||||
if self.primary_role not in ['Customer', 'Supplier']:
|
if self.primary_role not in ['Customer', 'Supplier']:
|
||||||
frappe.throw(_("Allowed primary roles are 'Customer' and 'Supplier'. Please select one of these roles only."),
|
frappe.throw(_("Allowed primary roles are 'Customer' and 'Supplier'. Please select one of these roles only."),
|
||||||
title=_("Invalid Primary Role"))
|
title=_("Invalid Primary Role"))
|
||||||
|
|
||||||
existing_party_link = frappe.get_all('Party Link', {
|
existing_party_link = frappe.get_all('Party Link', {
|
||||||
'primary_party': self.secondary_party
|
'primary_party': self.secondary_party
|
||||||
}, pluck="primary_role")
|
}, pluck="primary_role")
|
||||||
if existing_party_link:
|
if existing_party_link:
|
||||||
frappe.throw(_('{} {} is already linked with another {}')
|
frappe.throw(_('{} {} is already linked with another {}')
|
||||||
.format(self.secondary_role, self.secondary_party, existing_party_link[0]))
|
.format(self.secondary_role, self.secondary_party, existing_party_link[0]))
|
||||||
|
|
||||||
existing_party_link = frappe.get_all('Party Link', {
|
existing_party_link = frappe.get_all('Party Link', {
|
||||||
'secondary_party': self.primary_party
|
'secondary_party': self.primary_party
|
||||||
}, pluck="primary_role")
|
}, pluck="primary_role")
|
||||||
|
|||||||
@@ -484,7 +484,7 @@ class PaymentEntry(AccountsController):
|
|||||||
|
|
||||||
def validate_amounts(self):
|
def validate_amounts(self):
|
||||||
self.validate_received_amount()
|
self.validate_received_amount()
|
||||||
|
|
||||||
def validate_received_amount(self):
|
def validate_received_amount(self):
|
||||||
if self.paid_from_account_currency == self.paid_to_account_currency:
|
if self.paid_from_account_currency == self.paid_to_account_currency:
|
||||||
if self.paid_amount != self.received_amount:
|
if self.paid_amount != self.received_amount:
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class PeriodClosingVoucher(AccountsController):
|
|||||||
if gl_entries:
|
if gl_entries:
|
||||||
from erpnext.accounts.general_ledger import make_gl_entries
|
from erpnext.accounts.general_ledger import make_gl_entries
|
||||||
make_gl_entries(gl_entries)
|
make_gl_entries(gl_entries)
|
||||||
|
|
||||||
def get_gl_entries(self):
|
def get_gl_entries(self):
|
||||||
gl_entries = []
|
gl_entries = []
|
||||||
pl_accounts = self.get_pl_balances()
|
pl_accounts = self.get_pl_balances()
|
||||||
@@ -77,7 +77,7 @@ class PeriodClosingVoucher(AccountsController):
|
|||||||
gl_entries += gle_for_net_pl_bal
|
gl_entries += gle_for_net_pl_bal
|
||||||
|
|
||||||
return gl_entries
|
return gl_entries
|
||||||
|
|
||||||
def get_pnl_gl_entry(self, pl_accounts):
|
def get_pnl_gl_entry(self, pl_accounts):
|
||||||
company_cost_center = frappe.db.get_value("Company", self.company, "cost_center")
|
company_cost_center = frappe.db.get_value("Company", self.company, "cost_center")
|
||||||
gl_entries = []
|
gl_entries = []
|
||||||
|
|||||||
@@ -203,13 +203,13 @@ def apply_pricing_rule(args, doc=None):
|
|||||||
serialized_items = dict()
|
serialized_items = dict()
|
||||||
for item_code, val in query_items:
|
for item_code, val in query_items:
|
||||||
serialized_items.setdefault(item_code, val)
|
serialized_items.setdefault(item_code, val)
|
||||||
|
|
||||||
for item in item_list:
|
for item in item_list:
|
||||||
args_copy = copy.deepcopy(args)
|
args_copy = copy.deepcopy(args)
|
||||||
args_copy.update(item)
|
args_copy.update(item)
|
||||||
data = get_pricing_rule_for_item(args_copy, item.get('price_list_rate'), doc=doc)
|
data = get_pricing_rule_for_item(args_copy, item.get('price_list_rate'), doc=doc)
|
||||||
out.append(data)
|
out.append(data)
|
||||||
|
|
||||||
if serialized_items.get(item.get('item_code')) and not item.get("serial_no") and set_serial_nos_based_on_fifo and not args.get('is_return'):
|
if serialized_items.get(item.get('item_code')) and not item.get("serial_no") and set_serial_nos_based_on_fifo and not args.get('is_return'):
|
||||||
out[0].update(get_serial_no_for_item(args_copy))
|
out[0].update(get_serial_no_for_item(args_copy))
|
||||||
|
|
||||||
@@ -315,9 +315,8 @@ def update_args_for_pricing_rule(args):
|
|||||||
if not (args.item_group and args.brand):
|
if not (args.item_group and args.brand):
|
||||||
try:
|
try:
|
||||||
args.item_group, args.brand = frappe.get_cached_value("Item", args.item_code, ["item_group", "brand"])
|
args.item_group, args.brand = frappe.get_cached_value("Item", args.item_code, ["item_group", "brand"])
|
||||||
except TypeError:
|
except frappe.DoesNotExistError:
|
||||||
# invalid item_code
|
return
|
||||||
return item_details
|
|
||||||
if not args.item_group:
|
if not args.item_group:
|
||||||
frappe.throw(_("Item Group not mentioned in item master for item {0}").format(args.item_code))
|
frappe.throw(_("Item Group not mentioned in item master for item {0}").format(args.item_code))
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ def filter_pricing_rule_based_on_condition(pricing_rules, doc=None):
|
|||||||
try:
|
try:
|
||||||
if frappe.safe_eval(pricing_rule.condition, None, doc.as_dict()):
|
if frappe.safe_eval(pricing_rule.condition, None, doc.as_dict()):
|
||||||
filtered_pricing_rules.append(pricing_rule)
|
filtered_pricing_rules.append(pricing_rule)
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
filtered_pricing_rules.append(pricing_rule)
|
filtered_pricing_rules.append(pricing_rule)
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ def get_recipients_and_cc(customer, doc):
|
|||||||
if doc.cc_to != '':
|
if doc.cc_to != '':
|
||||||
try:
|
try:
|
||||||
cc=[frappe.get_value('User', doc.cc_to, 'email')]
|
cc=[frappe.get_value('User', doc.cc_to, 'email')]
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return recipients, cc
|
return recipients, cc
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ from erpnext.accounts.deferred_revenue import validate_service_stop_date
|
|||||||
from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import get_party_tax_withholding_details
|
from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import get_party_tax_withholding_details
|
||||||
from frappe.model.utils import get_fetch_values
|
from frappe.model.utils import get_fetch_values
|
||||||
from frappe.contacts.doctype.address.address import get_address_display
|
from frappe.contacts.doctype.address.address import get_address_display
|
||||||
from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import get_party_tax_withholding_details
|
|
||||||
|
|
||||||
from erpnext.healthcare.utils import manage_invoice_submit_cancel
|
from erpnext.healthcare.utils import manage_invoice_submit_cancel
|
||||||
|
|
||||||
@@ -933,7 +932,7 @@ class SalesInvoice(SellingController):
|
|||||||
|
|
||||||
if asset.calculate_depreciation:
|
if asset.calculate_depreciation:
|
||||||
self.reset_depreciation_schedule(asset)
|
self.reset_depreciation_schedule(asset)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset,
|
fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset,
|
||||||
item.base_net_amount, item.finance_book)
|
item.base_net_amount, item.finance_book)
|
||||||
@@ -947,7 +946,7 @@ class SalesInvoice(SellingController):
|
|||||||
gl_entries.append(self.get_gl_dict(gle, item=item))
|
gl_entries.append(self.get_gl_dict(gle, item=item))
|
||||||
|
|
||||||
self.set_asset_status(asset)
|
self.set_asset_status(asset)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Do not book income for transfer within same company
|
# Do not book income for transfer within same company
|
||||||
if not self.is_internal_transfer():
|
if not self.is_internal_transfer():
|
||||||
@@ -980,7 +979,7 @@ class SalesInvoice(SellingController):
|
|||||||
asset = frappe.get_doc("Asset", item.asset)
|
asset = frappe.get_doc("Asset", item.asset)
|
||||||
else:
|
else:
|
||||||
frappe.throw(_(
|
frappe.throw(_(
|
||||||
"Row #{0}: You must select an Asset for Item {1}.").format(item.idx, item.item_name),
|
"Row #{0}: You must select an Asset for Item {1}.").format(item.idx, item.item_name),
|
||||||
title=_("Missing Asset")
|
title=_("Missing Asset")
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -997,7 +996,7 @@ class SalesInvoice(SellingController):
|
|||||||
asset.flags.ignore_validate_update_after_submit = True
|
asset.flags.ignore_validate_update_after_submit = True
|
||||||
asset.prepare_depreciation_data(self.posting_date)
|
asset.prepare_depreciation_data(self.posting_date)
|
||||||
asset.save()
|
asset.save()
|
||||||
|
|
||||||
post_depreciation_entries(self.posting_date)
|
post_depreciation_entries(self.posting_date)
|
||||||
|
|
||||||
def reset_depreciation_schedule(self, asset):
|
def reset_depreciation_schedule(self, asset):
|
||||||
@@ -1037,7 +1036,7 @@ class SalesInvoice(SellingController):
|
|||||||
finance_book = schedule.finance_book
|
finance_book = schedule.finance_book
|
||||||
else:
|
else:
|
||||||
row += 1
|
row += 1
|
||||||
|
|
||||||
if schedule.schedule_date == posting_date_of_original_invoice:
|
if schedule.schedule_date == posting_date_of_original_invoice:
|
||||||
if not self.sale_was_made_on_original_schedule_date(asset, schedule, row, posting_date_of_original_invoice):
|
if not self.sale_was_made_on_original_schedule_date(asset, schedule, row, posting_date_of_original_invoice):
|
||||||
reverse_journal_entry = make_reverse_journal_entry(schedule.journal_entry)
|
reverse_journal_entry = make_reverse_journal_entry(schedule.journal_entry)
|
||||||
@@ -1047,13 +1046,13 @@ class SalesInvoice(SellingController):
|
|||||||
def get_posting_date_of_sales_invoice(self):
|
def get_posting_date_of_sales_invoice(self):
|
||||||
return frappe.db.get_value('Sales Invoice', self.return_against, 'posting_date')
|
return frappe.db.get_value('Sales Invoice', self.return_against, 'posting_date')
|
||||||
|
|
||||||
# if the invoice had been posted on the date the depreciation was initially supposed to happen, the depreciation shouldn't be undone
|
# if the invoice had been posted on the date the depreciation was initially supposed to happen, the depreciation shouldn't be undone
|
||||||
def sale_was_made_on_original_schedule_date(self, asset, schedule, row, posting_date_of_original_invoice):
|
def sale_was_made_on_original_schedule_date(self, asset, schedule, row, posting_date_of_original_invoice):
|
||||||
for finance_book in asset.get('finance_books'):
|
for finance_book in asset.get('finance_books'):
|
||||||
if schedule.finance_book == finance_book.finance_book:
|
if schedule.finance_book == finance_book.finance_book:
|
||||||
orginal_schedule_date = add_months(finance_book.depreciation_start_date,
|
orginal_schedule_date = add_months(finance_book.depreciation_start_date,
|
||||||
row * cint(finance_book.frequency_of_depreciation))
|
row * cint(finance_book.frequency_of_depreciation))
|
||||||
|
|
||||||
if orginal_schedule_date == posting_date_of_original_invoice:
|
if orginal_schedule_date == posting_date_of_original_invoice:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -1118,9 +1118,9 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
'qty': 1
|
'qty': 1
|
||||||
})
|
})
|
||||||
pi.set_missing_values()
|
pi.set_missing_values()
|
||||||
|
|
||||||
asset = create_asset(item_code="Macbook Pro")
|
asset = create_asset(item_code="Macbook Pro")
|
||||||
|
|
||||||
si = create_sales_invoice(item_code="Macbook Pro", asset=asset.name, qty=1, rate=90000)
|
si = create_sales_invoice(item_code="Macbook Pro", asset=asset.name, qty=1, rate=90000)
|
||||||
return_si = create_sales_invoice(is_return=1, return_against=si.name, item_code="Macbook Pro", asset=asset.name, qty=-1, rate=90000)
|
return_si = create_sales_invoice(is_return=1, return_against=si.name, item_code="Macbook Pro", asset=asset.name, qty=-1, rate=90000)
|
||||||
|
|
||||||
@@ -1128,7 +1128,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
# Asset value is 100,000 but it was sold for 90,000, so there should be a loss of 10,000
|
# Asset value is 100,000 but it was sold for 90,000, so there should be a loss of 10,000
|
||||||
loss_for_si = frappe.get_all(
|
loss_for_si = frappe.get_all(
|
||||||
"GL Entry",
|
"GL Entry",
|
||||||
filters = {
|
filters = {
|
||||||
"voucher_no": si.name,
|
"voucher_no": si.name,
|
||||||
"account": disposal_account
|
"account": disposal_account
|
||||||
@@ -1137,7 +1137,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
)[0]
|
)[0]
|
||||||
|
|
||||||
loss_for_return_si = frappe.get_all(
|
loss_for_return_si = frappe.get_all(
|
||||||
"GL Entry",
|
"GL Entry",
|
||||||
filters = {
|
filters = {
|
||||||
"voucher_no": return_si.name,
|
"voucher_no": return_si.name,
|
||||||
"account": disposal_account
|
"account": disposal_account
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ def get_deducted_tax(taxable_vouchers, fiscal_year, tax_details):
|
|||||||
def get_tds_amount(ldc, parties, inv, tax_details, fiscal_year_details, tax_deducted, vouchers):
|
def get_tds_amount(ldc, parties, inv, tax_details, fiscal_year_details, tax_deducted, vouchers):
|
||||||
tds_amount = 0
|
tds_amount = 0
|
||||||
invoice_filters = {
|
invoice_filters = {
|
||||||
'name': ('in', vouchers),
|
'name': ('in', vouchers),
|
||||||
'docstatus': 1,
|
'docstatus': 1,
|
||||||
'apply_tds': 1
|
'apply_tds': 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -648,7 +648,7 @@ def get_default_contact(doctype, name):
|
|||||||
if out:
|
if out:
|
||||||
try:
|
try:
|
||||||
return out[0][0]
|
return out[0][0]
|
||||||
except:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -339,7 +339,7 @@ def sort_accounts(accounts, is_root=False, key="name"):
|
|||||||
"""Sort root types as Asset, Liability, Equity, Income, Expense"""
|
"""Sort root types as Asset, Liability, Equity, Income, Expense"""
|
||||||
|
|
||||||
def compare_accounts(a, b):
|
def compare_accounts(a, b):
|
||||||
if re.split('\W+', a[key])[0].isdigit():
|
if re.split(r'\W+', a[key])[0].isdigit():
|
||||||
# if chart of accounts is numbered, then sort by number
|
# if chart of accounts is numbered, then sort by number
|
||||||
return cmp(a[key], b[key])
|
return cmp(a[key], b[key])
|
||||||
elif is_root:
|
elif is_root:
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe import _
|
|
||||||
|
|
||||||
class Disease(Document):
|
class Disease(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import frappe
|
|||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import flt, cint
|
from frappe.utils import flt, cint
|
||||||
from frappe import _
|
|
||||||
|
|
||||||
class SoilTexture(Document):
|
class SoilTexture(Document):
|
||||||
soil_edit_order = [2, 1, 0]
|
soil_edit_order = [2, 1, 0]
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe import _
|
|
||||||
|
|
||||||
class WaterAnalysis(Document):
|
class WaterAnalysis(Document):
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from frappe.model.document import Document
|
|||||||
from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
|
from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
|
||||||
from erpnext.assets.doctype.asset.depreciation \
|
from erpnext.assets.doctype.asset.depreciation \
|
||||||
import get_disposal_account_and_cost_center, get_depreciation_accounts
|
import get_disposal_account_and_cost_center, get_depreciation_accounts
|
||||||
from erpnext.accounts.general_ledger import make_gl_entries, make_reverse_gl_entries
|
from erpnext.accounts.general_ledger import make_reverse_gl_entries
|
||||||
from erpnext.accounts.utils import get_account_currency
|
from erpnext.accounts.utils import get_account_currency
|
||||||
from erpnext.controllers.accounts_controller import AccountsController
|
from erpnext.controllers.accounts_controller import AccountsController
|
||||||
|
|
||||||
@@ -321,10 +321,10 @@ class Asset(AccountsController):
|
|||||||
def get_from_date(self, finance_book):
|
def get_from_date(self, finance_book):
|
||||||
if not self.get('schedules'):
|
if not self.get('schedules'):
|
||||||
return self.available_for_use_date
|
return self.available_for_use_date
|
||||||
|
|
||||||
if len(self.finance_books) == 1:
|
if len(self.finance_books) == 1:
|
||||||
return self.schedules[-1].schedule_date
|
return self.schedules[-1].schedule_date
|
||||||
|
|
||||||
from_date = ""
|
from_date = ""
|
||||||
for schedule in self.get('schedules'):
|
for schedule in self.get('schedules'):
|
||||||
if schedule.finance_book == finance_book:
|
if schedule.finance_book == finance_book:
|
||||||
@@ -546,7 +546,7 @@ class Asset(AccountsController):
|
|||||||
cwip_account = None
|
cwip_account = None
|
||||||
try:
|
try:
|
||||||
cwip_account = get_asset_account("capital_work_in_progress_account", self.name, self.asset_category, self.company)
|
cwip_account = get_asset_account("capital_work_in_progress_account", self.name, self.asset_category, self.company)
|
||||||
except:
|
except Exception:
|
||||||
# if no cwip account found in category or company and "cwip is enabled" then raise else silently pass
|
# if no cwip account found in category or company and "cwip is enabled" then raise else silently pass
|
||||||
if cwip_enabled:
|
if cwip_enabled:
|
||||||
raise
|
raise
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ def validate_returned_items(doc):
|
|||||||
|
|
||||||
if doc.doctype in ("Delivery Note", "Sales Invoice"):
|
if doc.doctype in ("Delivery Note", "Sales Invoice"):
|
||||||
for d in frappe.db.sql("""select item_code, qty, serial_no, batch_no from `tabPacked Item`
|
for d in frappe.db.sql("""select item_code, qty, serial_no, batch_no from `tabPacked Item`
|
||||||
where parent = %s""".format(doc.doctype), doc.return_against, as_dict=1):
|
where parent = %s""", doc.return_against, as_dict=1):
|
||||||
valid_items = get_ref_item_dict(valid_items, d)
|
valid_items = get_ref_item_dict(valid_items, d)
|
||||||
|
|
||||||
already_returned_items = get_already_returned_items(doc)
|
already_returned_items = get_already_returned_items(doc)
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ class AppointmentBookingSettings(Document):
|
|||||||
to_time = datetime.datetime.strptime(
|
to_time = datetime.datetime.strptime(
|
||||||
self.min_date+record.to_time, self.format_string)
|
self.min_date+record.to_time, self.format_string)
|
||||||
timedelta = to_time-from_time
|
timedelta = to_time-from_time
|
||||||
self.validate_from_and_to_time(from_time, to_time)
|
self.validate_from_and_to_time(from_time, to_time, record)
|
||||||
self.duration_is_divisible(from_time, to_time)
|
self.duration_is_divisible(from_time, to_time)
|
||||||
|
|
||||||
def validate_from_and_to_time(self, from_time, to_time):
|
def validate_from_and_to_time(self, from_time, to_time, record):
|
||||||
if from_time > to_time:
|
if from_time > to_time:
|
||||||
err_msg = _('<b>From Time</b> cannot be later than <b>To Time</b> for {0}').format(record.day_of_week)
|
err_msg = _('<b>From Time</b> cannot be later than <b>To Time</b> for {0}').format(record.day_of_week)
|
||||||
frappe.throw(_(err_msg))
|
frappe.throw(_(err_msg))
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ class LinkedInSettings(Document):
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.api_error(response)
|
self.api_error(response)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def get_headers(self):
|
def get_headers(self):
|
||||||
@@ -168,7 +168,7 @@ class LinkedInSettings(Document):
|
|||||||
raise
|
raise
|
||||||
except Exception:
|
except Exception:
|
||||||
self.api_error(response)
|
self.api_error(response)
|
||||||
|
|
||||||
def get_post(self, post_id):
|
def get_post(self, post_id):
|
||||||
url = "https://api.linkedin.com/v2/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=urn:li:organization:{0}&shares[0]=urn:li:share:{1}".format(self.company_id, post_id)
|
url = "https://api.linkedin.com/v2/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=urn:li:organization:{0}&shares[0]=urn:li:share:{1}".format(self.company_id, post_id)
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ class LinkedInSettings(Document):
|
|||||||
response = requests.get(url=url, headers=self.get_headers())
|
response = requests.get(url=url, headers=self.get_headers())
|
||||||
if response.status_code !=200:
|
if response.status_code !=200:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
self.api_error(response)
|
self.api_error(response)
|
||||||
|
|
||||||
|
|||||||
@@ -80,10 +80,10 @@ frappe.ui.form.on('Social Media Post', {
|
|||||||
|
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
frm.trigger('text');
|
frm.trigger('text');
|
||||||
|
|
||||||
if (frm.doc.docstatus === 1) {
|
if (frm.doc.docstatus === 1) {
|
||||||
if (!['Posted', 'Deleted'].includes(frm.doc.post_status)) {
|
if (!['Posted', 'Deleted'].includes(frm.doc.post_status)) {
|
||||||
frm.trigger('add_post_btn');
|
frm.trigger('add_post_btn');
|
||||||
}
|
}
|
||||||
if (frm.doc.post_status !='Deleted') {
|
if (frm.doc.post_status !='Deleted') {
|
||||||
frm.add_custom_button(('Delete Post'), function() {
|
frm.add_custom_button(('Delete Post'), function() {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class SocialMediaPost(Document):
|
|||||||
if self.scheduled_time:
|
if self.scheduled_time:
|
||||||
self.post_status = "Scheduled"
|
self.post_status = "Scheduled"
|
||||||
super(SocialMediaPost, self).submit()
|
super(SocialMediaPost, self).submit()
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
self.db_set('post_status', 'Cancelled')
|
self.db_set('post_status', 'Cancelled')
|
||||||
|
|
||||||
@@ -35,11 +35,11 @@ class SocialMediaPost(Document):
|
|||||||
if self.twitter and self.twitter_post_id:
|
if self.twitter and self.twitter_post_id:
|
||||||
twitter = frappe.get_doc("Twitter Settings")
|
twitter = frappe.get_doc("Twitter Settings")
|
||||||
twitter.delete_tweet(self.twitter_post_id)
|
twitter.delete_tweet(self.twitter_post_id)
|
||||||
|
|
||||||
if self.linkedin and self.linkedin_post_id:
|
if self.linkedin and self.linkedin_post_id:
|
||||||
linkedin = frappe.get_doc("LinkedIn Settings")
|
linkedin = frappe.get_doc("LinkedIn Settings")
|
||||||
linkedin.delete_post(self.linkedin_post_id)
|
linkedin.delete_post(self.linkedin_post_id)
|
||||||
|
|
||||||
self.db_set('post_status', 'Deleted')
|
self.db_set('post_status', 'Deleted')
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@@ -51,7 +51,7 @@ class SocialMediaPost(Document):
|
|||||||
if self.twitter and self.twitter_post_id:
|
if self.twitter and self.twitter_post_id:
|
||||||
twitter = frappe.get_doc("Twitter Settings")
|
twitter = frappe.get_doc("Twitter Settings")
|
||||||
response['twitter'] = twitter.get_tweet(self.twitter_post_id)
|
response['twitter'] = twitter.get_tweet(self.twitter_post_id)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@@ -67,7 +67,7 @@ class SocialMediaPost(Document):
|
|||||||
self.db_set("linkedin_post_id", linkedin_post.headers['X-RestLi-Id'])
|
self.db_set("linkedin_post_id", linkedin_post.headers['X-RestLi-Id'])
|
||||||
self.db_set("post_status", "Posted")
|
self.db_set("post_status", "Posted")
|
||||||
|
|
||||||
except:
|
except Exception:
|
||||||
self.db_set("post_status", "Error")
|
self.db_set("post_status", "Error")
|
||||||
title = _("Error while POSTING {0}").format(self.name)
|
title = _("Error while POSTING {0}").format(self.name)
|
||||||
frappe.log_error(message=frappe.get_traceback(), title=title)
|
frappe.log_error(message=frappe.get_traceback(), title=title)
|
||||||
|
|||||||
@@ -53,10 +53,10 @@ class TwitterSettings(Document):
|
|||||||
frappe.throw(_('Invalid Consumer Key or Consumer Secret Key'))
|
frappe.throw(_('Invalid Consumer Key or Consumer Secret Key'))
|
||||||
|
|
||||||
def get_api(self):
|
def get_api(self):
|
||||||
# authentication of consumer key and secret
|
# authentication of consumer key and secret
|
||||||
auth = tweepy.OAuthHandler(self.consumer_key, self.get_password(fieldname="consumer_secret"))
|
auth = tweepy.OAuthHandler(self.consumer_key, self.get_password(fieldname="consumer_secret"))
|
||||||
# authentication of access token and secret
|
# authentication of access token and secret
|
||||||
auth.set_access_token(self.access_token, self.access_token_secret)
|
auth.set_access_token(self.access_token, self.access_token_secret)
|
||||||
|
|
||||||
return tweepy.API(auth)
|
return tweepy.API(auth)
|
||||||
|
|
||||||
@@ -90,20 +90,20 @@ class TwitterSettings(Document):
|
|||||||
|
|
||||||
def delete_tweet(self, tweet_id):
|
def delete_tweet(self, tweet_id):
|
||||||
api = self.get_api()
|
api = self.get_api()
|
||||||
try:
|
try:
|
||||||
api.destroy_status(tweet_id)
|
api.destroy_status(tweet_id)
|
||||||
except TweepError as e:
|
except TweepError as e:
|
||||||
self.api_error(e)
|
self.api_error(e)
|
||||||
|
|
||||||
def get_tweet(self, tweet_id):
|
def get_tweet(self, tweet_id):
|
||||||
api = self.get_api()
|
api = self.get_api()
|
||||||
try:
|
try:
|
||||||
response = api.get_status(tweet_id, trim_user=True, include_entities=True)
|
response = api.get_status(tweet_id, trim_user=True, include_entities=True)
|
||||||
except TweepError as e:
|
except TweepError as e:
|
||||||
self.api_error(e)
|
self.api_error(e)
|
||||||
|
|
||||||
return response._json
|
return response._json
|
||||||
|
|
||||||
def api_error(self, e):
|
def api_error(self, e):
|
||||||
content = json.loads(e.response.content)
|
content = json.loads(e.response.content)
|
||||||
content = content["errors"][0]
|
content = content["errors"][0]
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ def simulate(domain='Manufacturing', days=100):
|
|||||||
elif domain=='Education':
|
elif domain=='Education':
|
||||||
edu.work()
|
edu.work()
|
||||||
|
|
||||||
except:
|
except Exception:
|
||||||
frappe.db.set_global('demo_last_date', current_date)
|
frappe.db.set_global('demo_last_date', current_date)
|
||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ class CourseSchedulingTool(Document):
|
|||||||
if self.day == calendar.day_name[getdate(d.schedule_date).weekday()]:
|
if self.day == calendar.day_name[getdate(d.schedule_date).weekday()]:
|
||||||
frappe.delete_doc("Course Schedule", d.name)
|
frappe.delete_doc("Course Schedule", d.name)
|
||||||
rescheduled.append(d.name)
|
rescheduled.append(d.name)
|
||||||
except:
|
except Exception:
|
||||||
reschedule_errors.append(d.name)
|
reschedule_errors.append(d.name)
|
||||||
return rescheduled, reschedule_errors
|
return rescheduled, reschedule_errors
|
||||||
|
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ def get_quiz(quiz_name, course):
|
|||||||
try:
|
try:
|
||||||
quiz = frappe.get_doc("Quiz", quiz_name)
|
quiz = frappe.get_doc("Quiz", quiz_name)
|
||||||
questions = quiz.get_questions()
|
questions = quiz.get_questions()
|
||||||
except:
|
except Exception:
|
||||||
frappe.throw(_("Quiz {0} does not exist").format(quiz_name), frappe.DoesNotExistError)
|
frappe.throw(_("Quiz {0} does not exist").format(quiz_name), frappe.DoesNotExistError)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ class xml2dict(object):
|
|||||||
ns = http://cs.sfsu.edu/csc867/myscheduler
|
ns = http://cs.sfsu.edu/csc867/myscheduler
|
||||||
name = patients
|
name = patients
|
||||||
"""
|
"""
|
||||||
result = re.compile("\{(.*)\}(.*)").search(tag)
|
result = re.compile(r"\{(.*)\}(.*)").search(tag)
|
||||||
if result:
|
if result:
|
||||||
value.namespace, tag = result.groups()
|
value.namespace, tag = result.groups()
|
||||||
|
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ class TallyMigration(Document):
|
|||||||
|
|
||||||
self.is_master_data_processed = 1
|
self.is_master_data_processed = 1
|
||||||
|
|
||||||
except:
|
except Exception:
|
||||||
self.publish("Process Master Data", _("Process Failed"), -1, 5)
|
self.publish("Process Master Data", _("Process Failed"), -1, 5)
|
||||||
self.log()
|
self.log()
|
||||||
|
|
||||||
@@ -302,14 +302,14 @@ class TallyMigration(Document):
|
|||||||
try:
|
try:
|
||||||
party_doc = frappe.get_doc(party)
|
party_doc = frappe.get_doc(party)
|
||||||
party_doc.insert()
|
party_doc.insert()
|
||||||
except:
|
except Exception:
|
||||||
self.log(party_doc)
|
self.log(party_doc)
|
||||||
addresses_file = frappe.get_doc("File", {"file_url": addresses_file_url})
|
addresses_file = frappe.get_doc("File", {"file_url": addresses_file_url})
|
||||||
for address in json.loads(addresses_file.get_content()):
|
for address in json.loads(addresses_file.get_content()):
|
||||||
try:
|
try:
|
||||||
address_doc = frappe.get_doc(address)
|
address_doc = frappe.get_doc(address)
|
||||||
address_doc.insert(ignore_mandatory=True)
|
address_doc.insert(ignore_mandatory=True)
|
||||||
except:
|
except Exception:
|
||||||
self.log(address_doc)
|
self.log(address_doc)
|
||||||
|
|
||||||
def create_items_uoms(items_file_url, uoms_file_url):
|
def create_items_uoms(items_file_url, uoms_file_url):
|
||||||
@@ -319,7 +319,7 @@ class TallyMigration(Document):
|
|||||||
try:
|
try:
|
||||||
uom_doc = frappe.get_doc(uom)
|
uom_doc = frappe.get_doc(uom)
|
||||||
uom_doc.insert()
|
uom_doc.insert()
|
||||||
except:
|
except Exception:
|
||||||
self.log(uom_doc)
|
self.log(uom_doc)
|
||||||
|
|
||||||
items_file = frappe.get_doc("File", {"file_url": items_file_url})
|
items_file = frappe.get_doc("File", {"file_url": items_file_url})
|
||||||
@@ -327,7 +327,7 @@ class TallyMigration(Document):
|
|||||||
try:
|
try:
|
||||||
item_doc = frappe.get_doc(item)
|
item_doc = frappe.get_doc(item)
|
||||||
item_doc.insert()
|
item_doc.insert()
|
||||||
except:
|
except Exception:
|
||||||
self.log(item_doc)
|
self.log(item_doc)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -346,7 +346,7 @@ class TallyMigration(Document):
|
|||||||
self.is_master_data_imported = 1
|
self.is_master_data_imported = 1
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
except:
|
except Exception:
|
||||||
self.publish("Import Master Data", _("Process Failed"), -1, 5)
|
self.publish("Import Master Data", _("Process Failed"), -1, 5)
|
||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
self.log()
|
self.log()
|
||||||
@@ -370,7 +370,7 @@ class TallyMigration(Document):
|
|||||||
if processed_voucher:
|
if processed_voucher:
|
||||||
vouchers.append(processed_voucher)
|
vouchers.append(processed_voucher)
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
except:
|
except Exception:
|
||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
self.log(voucher)
|
self.log(voucher)
|
||||||
return vouchers
|
return vouchers
|
||||||
@@ -494,7 +494,7 @@ class TallyMigration(Document):
|
|||||||
|
|
||||||
self.is_day_book_data_processed = 1
|
self.is_day_book_data_processed = 1
|
||||||
|
|
||||||
except:
|
except Exception:
|
||||||
self.publish("Process Day Book Data", _("Process Failed"), -1, 5)
|
self.publish("Process Day Book Data", _("Process Failed"), -1, 5)
|
||||||
self.log()
|
self.log()
|
||||||
|
|
||||||
@@ -564,7 +564,7 @@ class TallyMigration(Document):
|
|||||||
is_last = True
|
is_last = True
|
||||||
frappe.enqueue_doc(self.doctype, self.name, "_import_vouchers", queue="long", timeout=3600, start=index+1, total=total, is_last=is_last)
|
frappe.enqueue_doc(self.doctype, self.name, "_import_vouchers", queue="long", timeout=3600, start=index+1, total=total, is_last=is_last)
|
||||||
|
|
||||||
except:
|
except Exception:
|
||||||
self.log()
|
self.log()
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
@@ -583,7 +583,7 @@ class TallyMigration(Document):
|
|||||||
voucher_doc.submit()
|
voucher_doc.submit()
|
||||||
self.publish("Importing Vouchers", _("{} of {}").format(index, total), index, total)
|
self.publish("Importing Vouchers", _("{} of {}").format(index, total), index, total)
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
except:
|
except Exception:
|
||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
self.log(voucher_doc)
|
self.log(voucher_doc)
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class LabTest(Document):
|
|||||||
if item.result_value and item.secondary_uom and item.conversion_factor:
|
if item.result_value and item.secondary_uom and item.conversion_factor:
|
||||||
try:
|
try:
|
||||||
item.secondary_uom_result = float(item.result_value) * float(item.conversion_factor)
|
item.secondary_uom_result = float(item.result_value) * float(item.conversion_factor)
|
||||||
except:
|
except Exception:
|
||||||
item.secondary_uom_result = ''
|
item.secondary_uom_result = ''
|
||||||
frappe.msgprint(_('Row #{0}: Result for Secondary UOM not calculated').format(item.idx), title = _('Warning'))
|
frappe.msgprint(_('Row #{0}: Result for Secondary UOM not calculated').format(item.idx), title = _('Warning'))
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import frappe
|
|||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import cstr, getdate, add_days
|
from frappe.utils import cstr, getdate, add_days
|
||||||
from frappe import _
|
|
||||||
from frappe.model.mapper import get_mapped_doc
|
from frappe.model.mapper import get_mapped_doc
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class TestTherapyPlan(unittest.TestCase):
|
|||||||
self.assertEqual(frappe.db.get_value('Therapy Plan', plan.name, 'status'), 'Completed')
|
self.assertEqual(frappe.db.get_value('Therapy Plan', plan.name, 'status'), 'Completed')
|
||||||
|
|
||||||
patient, practitioner = create_healthcare_docs()
|
patient, practitioner = create_healthcare_docs()
|
||||||
appointment = create_appointment(patient, practitioner, nowdate())
|
appointment = create_appointment(patient, practitioner, nowdate())
|
||||||
|
|
||||||
session = make_therapy_session(plan.name, plan.patient, 'Basic Rehab', '_Test Company', appointment.name)
|
session = make_therapy_session(plan.name, plan.patient, 'Basic Rehab', '_Test Company', appointment.name)
|
||||||
session = frappe.get_doc(session)
|
session = frappe.get_doc(session)
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class DailyWorkSummary(Document):
|
|||||||
crop=True
|
crop=True
|
||||||
)
|
)
|
||||||
d.image = thumbnail_image
|
d.image = thumbnail_image
|
||||||
except:
|
except Exception:
|
||||||
d.image = original_image
|
d.image = original_image
|
||||||
|
|
||||||
if d.sender in did_not_reply:
|
if d.sender in did_not_reply:
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class TestEmployeeReminders(unittest.TestCase):
|
|||||||
# Create a test holiday list
|
# Create a test holiday list
|
||||||
test_holiday_dates = cls.get_test_holiday_dates()
|
test_holiday_dates = cls.get_test_holiday_dates()
|
||||||
test_holiday_list = make_holiday_list(
|
test_holiday_list = make_holiday_list(
|
||||||
'TestHolidayRemindersList',
|
'TestHolidayRemindersList',
|
||||||
holiday_dates=[
|
holiday_dates=[
|
||||||
{'holiday_date': test_holiday_dates[0], 'description': 'test holiday1'},
|
{'holiday_date': test_holiday_dates[0], 'description': 'test holiday1'},
|
||||||
{'holiday_date': test_holiday_dates[1], 'description': 'test holiday2'},
|
{'holiday_date': test_holiday_dates[1], 'description': 'test holiday2'},
|
||||||
@@ -49,8 +49,8 @@ class TestEmployeeReminders(unittest.TestCase):
|
|||||||
def get_test_holiday_dates(cls):
|
def get_test_holiday_dates(cls):
|
||||||
today_date = getdate()
|
today_date = getdate()
|
||||||
return [
|
return [
|
||||||
today_date,
|
today_date,
|
||||||
today_date-timedelta(days=4),
|
today_date-timedelta(days=4),
|
||||||
today_date-timedelta(days=3),
|
today_date-timedelta(days=3),
|
||||||
today_date+timedelta(days=1),
|
today_date+timedelta(days=1),
|
||||||
today_date+timedelta(days=3),
|
today_date+timedelta(days=3),
|
||||||
@@ -63,7 +63,7 @@ class TestEmployeeReminders(unittest.TestCase):
|
|||||||
|
|
||||||
def test_is_holiday(self):
|
def test_is_holiday(self):
|
||||||
from erpnext.hr.doctype.employee.employee import is_holiday
|
from erpnext.hr.doctype.employee.employee import is_holiday
|
||||||
|
|
||||||
self.assertTrue(is_holiday(self.test_employee.name))
|
self.assertTrue(is_holiday(self.test_employee.name))
|
||||||
self.assertTrue(is_holiday(self.test_employee.name, date=self.test_holiday_dates[1]))
|
self.assertTrue(is_holiday(self.test_employee.name, date=self.test_holiday_dates[1]))
|
||||||
self.assertFalse(is_holiday(self.test_employee.name, date=getdate()-timedelta(days=1)))
|
self.assertFalse(is_holiday(self.test_employee.name, date=getdate()-timedelta(days=1)))
|
||||||
@@ -118,7 +118,7 @@ class TestEmployeeReminders(unittest.TestCase):
|
|||||||
|
|
||||||
email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True)
|
email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True)
|
||||||
self.assertTrue("Subject: Work Anniversary Reminder" in email_queue[0].message)
|
self.assertTrue("Subject: Work Anniversary Reminder" in email_queue[0].message)
|
||||||
|
|
||||||
def test_send_holidays_reminder_in_advance(self):
|
def test_send_holidays_reminder_in_advance(self):
|
||||||
from erpnext.hr.utils import get_holidays_for_employee
|
from erpnext.hr.utils import get_holidays_for_employee
|
||||||
from erpnext.hr.doctype.employee.employee_reminders import send_holidays_reminder_in_advance
|
from erpnext.hr.doctype.employee.employee_reminders import send_holidays_reminder_in_advance
|
||||||
@@ -133,10 +133,10 @@ class TestEmployeeReminders(unittest.TestCase):
|
|||||||
holidays = get_holidays_for_employee(
|
holidays = get_holidays_for_employee(
|
||||||
self.test_employee.get('name'),
|
self.test_employee.get('name'),
|
||||||
getdate(), getdate() + timedelta(days=3),
|
getdate(), getdate() + timedelta(days=3),
|
||||||
only_non_weekly=True,
|
only_non_weekly=True,
|
||||||
raise_exception=False
|
raise_exception=False
|
||||||
)
|
)
|
||||||
|
|
||||||
send_holidays_reminder_in_advance(
|
send_holidays_reminder_in_advance(
|
||||||
self.test_employee.get('name'),
|
self.test_employee.get('name'),
|
||||||
holidays
|
holidays
|
||||||
@@ -158,7 +158,7 @@ class TestEmployeeReminders(unittest.TestCase):
|
|||||||
|
|
||||||
email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True)
|
email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True)
|
||||||
self.assertTrue(len(email_queue) > 0)
|
self.assertTrue(len(email_queue) > 0)
|
||||||
|
|
||||||
def test_advance_holiday_reminders_weekly(self):
|
def test_advance_holiday_reminders_weekly(self):
|
||||||
from erpnext.hr.doctype.employee.employee_reminders import send_reminders_in_advance_weekly
|
from erpnext.hr.doctype.employee.employee_reminders import send_reminders_in_advance_weekly
|
||||||
# Get HR settings and enable advance holiday reminders
|
# Get HR settings and enable advance holiday reminders
|
||||||
|
|||||||
@@ -144,20 +144,20 @@ class TestExpenseClaim(unittest.TestCase):
|
|||||||
expense_claim = make_expense_claim(payable_account, 5500, 5500, "_Test Company", "Travel Expenses - _TC")
|
expense_claim = make_expense_claim(payable_account, 5500, 5500, "_Test Company", "Travel Expenses - _TC")
|
||||||
expense_claim.save()
|
expense_claim.save()
|
||||||
expense_claim.submit()
|
expense_claim.submit()
|
||||||
|
|
||||||
# Payment entry 1: paying 500
|
# Payment entry 1: paying 500
|
||||||
make_payment_entry(expense_claim, payable_account,500)
|
make_payment_entry(expense_claim, payable_account,500)
|
||||||
outstanding_amount, total_amount_reimbursed = get_outstanding_and_total_reimbursed_amounts(expense_claim)
|
outstanding_amount, total_amount_reimbursed = get_outstanding_and_total_reimbursed_amounts(expense_claim)
|
||||||
self.assertEqual(outstanding_amount, 5000)
|
self.assertEqual(outstanding_amount, 5000)
|
||||||
self.assertEqual(total_amount_reimbursed, 500)
|
self.assertEqual(total_amount_reimbursed, 500)
|
||||||
|
|
||||||
# Payment entry 1: paying 2000
|
# Payment entry 1: paying 2000
|
||||||
make_payment_entry(expense_claim, payable_account,2000)
|
make_payment_entry(expense_claim, payable_account,2000)
|
||||||
outstanding_amount, total_amount_reimbursed = get_outstanding_and_total_reimbursed_amounts(expense_claim)
|
outstanding_amount, total_amount_reimbursed = get_outstanding_and_total_reimbursed_amounts(expense_claim)
|
||||||
self.assertEqual(outstanding_amount, 3000)
|
self.assertEqual(outstanding_amount, 3000)
|
||||||
self.assertEqual(total_amount_reimbursed, 2500)
|
self.assertEqual(total_amount_reimbursed, 2500)
|
||||||
|
|
||||||
# Payment entry 1: paying 3000
|
# Payment entry 1: paying 3000
|
||||||
make_payment_entry(expense_claim, payable_account,3000)
|
make_payment_entry(expense_claim, payable_account,3000)
|
||||||
outstanding_amount, total_amount_reimbursed = get_outstanding_and_total_reimbursed_amounts(expense_claim)
|
outstanding_amount, total_amount_reimbursed = get_outstanding_and_total_reimbursed_amounts(expense_claim)
|
||||||
self.assertEqual(outstanding_amount, 0)
|
self.assertEqual(outstanding_amount, 0)
|
||||||
@@ -221,7 +221,7 @@ def get_outstanding_and_total_reimbursed_amounts(expense_claim):
|
|||||||
outstanding_amount = flt(frappe.db.get_value("Expense Claim", expense_claim.name, "total_sanctioned_amount")) - \
|
outstanding_amount = flt(frappe.db.get_value("Expense Claim", expense_claim.name, "total_sanctioned_amount")) - \
|
||||||
flt(frappe.db.get_value("Expense Claim", expense_claim.name, "total_amount_reimbursed"))
|
flt(frappe.db.get_value("Expense Claim", expense_claim.name, "total_amount_reimbursed"))
|
||||||
total_amount_reimbursed = flt(frappe.db.get_value("Expense Claim", expense_claim.name, "total_amount_reimbursed"))
|
total_amount_reimbursed = flt(frappe.db.get_value("Expense Claim", expense_claim.name, "total_amount_reimbursed"))
|
||||||
|
|
||||||
return outstanding_amount,total_amount_reimbursed
|
return outstanding_amount,total_amount_reimbursed
|
||||||
|
|
||||||
def make_payment_entry(expense_claim, payable_account, amt):
|
def make_payment_entry(expense_claim, payable_account, amt):
|
||||||
@@ -234,5 +234,5 @@ def make_payment_entry(expense_claim, payable_account, amt):
|
|||||||
pe.paid_to = payable_account
|
pe.paid_to = payable_account
|
||||||
pe.references[0].allocated_amount = amt
|
pe.references[0].allocated_amount = amt
|
||||||
pe.insert()
|
pe.insert()
|
||||||
pe.submit()
|
pe.submit()
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class LeaveControlPanel(Document):
|
|||||||
la.docstatus = 1
|
la.docstatus = 1
|
||||||
la.save()
|
la.save()
|
||||||
leave_allocated_for.append(d[0])
|
leave_allocated_for.append(d[0])
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
if leave_allocated_for:
|
if leave_allocated_for:
|
||||||
msgprint(_("Leaves Allocated Successfully for {0}").format(comma_and(leave_allocated_for)))
|
msgprint(_("Leaves Allocated Successfully for {0}").format(comma_and(leave_allocated_for)))
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import getdate, cstr, add_days, date_diff, getdate, ceil
|
from frappe.utils import getdate, cstr, add_days, date_diff, ceil
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from erpnext.hr.utils import validate_overlap
|
from erpnext.hr.utils import validate_overlap
|
||||||
from frappe.utils.background_jobs import enqueue
|
from frappe.utils.background_jobs import enqueue
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ def get_data(filters, leave_types):
|
|||||||
for leave_type in leave_types:
|
for leave_type in leave_types:
|
||||||
remaining = 0
|
remaining = 0
|
||||||
if leave_type in available_leave["leave_allocation"]:
|
if leave_type in available_leave["leave_allocation"]:
|
||||||
# opening balance
|
# opening balance
|
||||||
remaining = available_leave["leave_allocation"][leave_type]['remaining_leaves']
|
remaining = available_leave["leave_allocation"][leave_type]['remaining_leaves']
|
||||||
|
|
||||||
row += [remaining]
|
row += [remaining]
|
||||||
|
|||||||
@@ -96,8 +96,6 @@ def get_columns():
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
return columns
|
|
||||||
|
|
||||||
|
|
||||||
def get_vehicle_log_data(filters):
|
def get_vehicle_log_data(filters):
|
||||||
start_date, end_date = get_period_dates(filters)
|
start_date, end_date = get_period_dates(filters)
|
||||||
|
|||||||
@@ -450,9 +450,9 @@ def get_sal_slip_total_benefit_given(employee, payroll_period, component=False):
|
|||||||
|
|
||||||
def get_holiday_dates_for_employee(employee, start_date, end_date):
|
def get_holiday_dates_for_employee(employee, start_date, end_date):
|
||||||
"""return a list of holiday dates for the given employee between start_date and end_date"""
|
"""return a list of holiday dates for the given employee between start_date and end_date"""
|
||||||
# return only date
|
# return only date
|
||||||
holidays = get_holidays_for_employee(employee, start_date, end_date)
|
holidays = get_holidays_for_employee(employee, start_date, end_date)
|
||||||
|
|
||||||
return [cstr(h.holiday_date) for h in holidays]
|
return [cstr(h.holiday_date) for h in holidays]
|
||||||
|
|
||||||
|
|
||||||
@@ -465,7 +465,7 @@ def get_holidays_for_employee(employee, start_date, end_date, raise_exception=Tr
|
|||||||
`raise_exception` (bool)
|
`raise_exception` (bool)
|
||||||
`only_non_weekly` (bool)
|
`only_non_weekly` (bool)
|
||||||
|
|
||||||
return: list of dicts with `holiday_date` and `description`
|
return: list of dicts with `holiday_date` and `description`
|
||||||
"""
|
"""
|
||||||
holiday_list = get_holiday_list_for_employee(employee, raise_exception=raise_exception)
|
holiday_list = get_holiday_list_for_employee(employee, raise_exception=raise_exception)
|
||||||
|
|
||||||
@@ -481,11 +481,11 @@ def get_holidays_for_employee(employee, start_date, end_date, raise_exception=Tr
|
|||||||
filters['weekly_off'] = False
|
filters['weekly_off'] = False
|
||||||
|
|
||||||
holidays = frappe.get_all(
|
holidays = frappe.get_all(
|
||||||
'Holiday',
|
'Holiday',
|
||||||
fields=['description', 'holiday_date'],
|
fields=['description', 'holiday_date'],
|
||||||
filters=filters
|
filters=filters
|
||||||
)
|
)
|
||||||
|
|
||||||
return holidays
|
return holidays
|
||||||
|
|
||||||
@erpnext.allow_regional
|
@erpnext.allow_regional
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import frappe, erpnext
|
|||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import (nowdate, getdate, now_datetime, get_datetime, flt, date_diff, get_last_day, cint,
|
from frappe.utils import (nowdate, getdate, now_datetime, get_datetime, flt, date_diff, get_last_day, cint,
|
||||||
get_first_day, get_datetime, add_days)
|
get_first_day, add_days)
|
||||||
from erpnext.controllers.accounts_controller import AccountsController
|
from erpnext.controllers.accounts_controller import AccountsController
|
||||||
from erpnext.accounts.general_ledger import make_gl_entries
|
from erpnext.accounts.general_ledger import make_gl_entries
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,9 @@ from __future__ import unicode_literals
|
|||||||
import frappe, erpnext
|
import frappe, erpnext
|
||||||
import json
|
import json
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import flt, getdate, cint
|
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import date_diff, add_days, getdate, add_months, get_first_day, get_datetime
|
from frappe.utils import flt, cint, date_diff, add_days, getdate, add_months, get_first_day, get_datetime
|
||||||
from erpnext.controllers.accounts_controller import AccountsController
|
from erpnext.controllers.accounts_controller import AccountsController
|
||||||
from erpnext.accounts.general_ledger import make_gl_entries
|
from erpnext.accounts.general_ledger import make_gl_entries
|
||||||
from erpnext.loan_management.doctype.loan_security_shortfall.loan_security_shortfall import update_shortfall_status
|
from erpnext.loan_management.doctype.loan_security_shortfall.loan_security_shortfall import update_shortfall_status
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
class SanctionedLoanAmount(Document):
|
class SanctionedLoanAmount(Document):
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from frappe import _
|
|||||||
from frappe.utils.data import comma_and
|
from frappe.utils.data import comma_and
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
# if not filters: filters = {}
|
# if not filters: filters = {}
|
||||||
columns = get_columns()
|
columns = get_columns()
|
||||||
summ_data = []
|
summ_data = []
|
||||||
|
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ def get_member_based_on_subscription(subscription_id, email=None, customer_id=No
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
return frappe.get_doc("Member", members[0]["name"])
|
return frappe.get_doc("Member", members[0]["name"])
|
||||||
except:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@@ -393,7 +393,7 @@ def notify_failure(log):
|
|||||||
""".format(get_link_to_form("Error Log", log.name))
|
""".format(get_link_to_form("Error Log", log.name))
|
||||||
|
|
||||||
sendmail_to_system_managers("[Important] [ERPNext] Razorpay membership webhook failed , please check.", content)
|
sendmail_to_system_managers("[Important] [ERPNext] Razorpay membership webhook failed , please check.", content)
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@@ -402,7 +402,7 @@ def get_plan_from_razorpay_id(plan_id):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
return plan[0]["name"]
|
return plan[0]["name"]
|
||||||
except:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ def execute():
|
|||||||
buying_cost_center, selling_cost_center, expense_account, income_account, default_supplier
|
buying_cost_center, selling_cost_center, expense_account, income_account, default_supplier
|
||||||
FROM `tabItem`;
|
FROM `tabItem`;
|
||||||
''', companies[0].name)
|
''', companies[0].name)
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
item_details = frappe.db.sql(""" SELECT name, default_warehouse,
|
item_details = frappe.db.sql(""" SELECT name, default_warehouse,
|
||||||
|
|||||||
@@ -11,5 +11,5 @@ def execute():
|
|||||||
|
|
||||||
frappe.reload_doc("stock", "doctype", "stock_ledger_entry")
|
frappe.reload_doc("stock", "doctype", "stock_ledger_entry")
|
||||||
frappe.reload_doc("stock", "doctype", "serial_no")
|
frappe.reload_doc("stock", "doctype", "serial_no")
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ def execute():
|
|||||||
try:
|
try:
|
||||||
employee_other_income.submit()
|
employee_other_income.submit()
|
||||||
migrated.append([proof.employee, proof.payroll_period])
|
migrated.append([proof.employee, proof.payroll_period])
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if not frappe.db.table_exists("Employee Tax Exemption Declaration"):
|
if not frappe.db.table_exists("Employee Tax Exemption Declaration"):
|
||||||
@@ -108,5 +108,5 @@ def execute():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
employee_other_income.submit()
|
employee_other_income.submit()
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -7,17 +7,17 @@ def execute():
|
|||||||
try:
|
try:
|
||||||
# Rename the field
|
# Rename the field
|
||||||
rename_field('HR Settings', 'stop_birthday_reminders', 'send_birthday_reminders')
|
rename_field('HR Settings', 'stop_birthday_reminders', 'send_birthday_reminders')
|
||||||
|
|
||||||
# Reverse the value
|
# Reverse the value
|
||||||
old_value = frappe.db.get_single_value('HR Settings', 'send_birthday_reminders')
|
old_value = frappe.db.get_single_value('HR Settings', 'send_birthday_reminders')
|
||||||
|
|
||||||
frappe.db.set_value(
|
frappe.db.set_value(
|
||||||
'HR Settings',
|
'HR Settings',
|
||||||
'HR Settings',
|
'HR Settings',
|
||||||
'send_birthday_reminders',
|
'send_birthday_reminders',
|
||||||
1 if old_value == 0 else 0
|
1 if old_value == 0 else 0
|
||||||
)
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if e.args[0] != 1054:
|
if e.args[0] != 1054:
|
||||||
raise
|
raise
|
||||||
@@ -35,10 +35,10 @@ def get_reconciled_bank_transactions(intra_company_pe):
|
|||||||
|
|
||||||
for payment_entry in intra_company_pe:
|
for payment_entry in intra_company_pe:
|
||||||
reconciled_bank_transactions[payment_entry] = frappe.get_all(
|
reconciled_bank_transactions[payment_entry] = frappe.get_all(
|
||||||
'Bank Transaction Payments',
|
'Bank Transaction Payments',
|
||||||
filters = {
|
filters = {
|
||||||
'payment_entry': payment_entry
|
'payment_entry': payment_entry
|
||||||
},
|
},
|
||||||
pluck='parent'
|
pluck='parent'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.model import data_field_options
|
from frappe.model import data_field_options
|
||||||
|
|
||||||
def execute():
|
def execute():
|
||||||
|
|
||||||
for field in frappe.get_all('Custom Field',
|
for field in frappe.get_all('Custom Field',
|
||||||
fields = ['name'],
|
fields = ['name'],
|
||||||
filters = {
|
filters = {
|
||||||
'fieldtype': 'Data',
|
'fieldtype': 'Data',
|
||||||
@@ -16,7 +16,7 @@ def execute():
|
|||||||
|
|
||||||
if field not in data_field_options:
|
if field not in data_field_options:
|
||||||
frappe.db.sql("""
|
frappe.db.sql("""
|
||||||
UPDATE
|
UPDATE
|
||||||
`tabCustom Field`
|
`tabCustom Field`
|
||||||
SET
|
SET
|
||||||
options=NULL
|
options=NULL
|
||||||
|
|||||||
@@ -20,5 +20,5 @@ def execute():
|
|||||||
})
|
})
|
||||||
if count % 200 == 0:
|
if count % 200 == 0:
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
except:
|
except Exception:
|
||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
|
|||||||
@@ -86,9 +86,9 @@ $.extend(erpnext, {
|
|||||||
|
|
||||||
proceed_save_with_reminders_frequency_change: () => {
|
proceed_save_with_reminders_frequency_change: () => {
|
||||||
frappe.ui.hide_open_dialog();
|
frappe.ui.hide_open_dialog();
|
||||||
|
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: 'erpnext.hr.doctype.hr_settings.hr_settings.set_proceed_with_frequency_change',
|
method: 'erpnext.hr.doctype.hr_settings.hr_settings.set_proceed_with_frequency_change',
|
||||||
callback: () => {
|
callback: () => {
|
||||||
cur_frm.save();
|
cur_frm.save();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ def get_transactions(filters, as_dict=1):
|
|||||||
def run(params_method, filters):
|
def run(params_method, filters):
|
||||||
extra_fields, extra_joins, extra_filters = params_method(filters)
|
extra_fields, extra_joins, extra_filters = params_method(filters)
|
||||||
return run_query(filters, extra_fields, extra_joins, extra_filters, as_dict=as_dict)
|
return run_query(filters, extra_fields, extra_joins, extra_filters, as_dict=as_dict)
|
||||||
|
|
||||||
def sort_by(row):
|
def sort_by(row):
|
||||||
# "Belegdatum" is in the fifth column when list format is used
|
# "Belegdatum" is in the fifth column when list format is used
|
||||||
return row["Belegdatum" if as_dict else 5]
|
return row["Belegdatum" if as_dict else 5]
|
||||||
@@ -361,7 +361,7 @@ def run_query(filters, extra_fields, extra_joins, extra_filters, as_dict=1):
|
|||||||
FROM `tabGL Entry` gl
|
FROM `tabGL Entry` gl
|
||||||
|
|
||||||
/* Kontonummer */
|
/* Kontonummer */
|
||||||
LEFT JOIN `tabAccount` acc
|
LEFT JOIN `tabAccount` acc
|
||||||
ON gl.account = acc.name
|
ON gl.account = acc.name
|
||||||
|
|
||||||
LEFT JOIN `tabParty Account` par
|
LEFT JOIN `tabParty Account` par
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ def get_data(filters):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Regular expression set to remove all the special characters
|
# Regular expression set to remove all the special characters
|
||||||
special_characters = "[$%^*()+\\[\]{};':\"\\|<>.?]"
|
special_characters = r"[$%^*()+\\[\]{};':\"\\|<>.?]"
|
||||||
|
|
||||||
for row in data:
|
for row in data:
|
||||||
set_defaults(row)
|
set_defaults(row)
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ def get_result_as_list(data, filters):
|
|||||||
if d.get("voucher_no").startswith("{0}-".format(JournalCode)) or d.get("voucher_no").startswith("{0}/".format(JournalCode)):
|
if d.get("voucher_no").startswith("{0}-".format(JournalCode)) or d.get("voucher_no").startswith("{0}/".format(JournalCode)):
|
||||||
EcritureNum = re.split("-|/", d.get("voucher_no"))[1]
|
EcritureNum = re.split("-|/", d.get("voucher_no"))[1]
|
||||||
else:
|
else:
|
||||||
EcritureNum = re.search("{0}(\d+)".format(JournalCode), d.get("voucher_no"), re.IGNORECASE).group(1)
|
EcritureNum = re.search(r"{0}(\d+)".format(JournalCode), d.get("voucher_no"), re.IGNORECASE).group(1)
|
||||||
|
|
||||||
EcritureDate = format_datetime(d.get("GlPostDate"), "yyyyMMdd")
|
EcritureDate = format_datetime(d.get("GlPostDate"), "yyyyMMdd")
|
||||||
|
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ class VATAuditReport(object):
|
|||||||
row["posting_date"] = formatdate(inv_data.get("posting_date"), "dd-mm-yyyy")
|
row["posting_date"] = formatdate(inv_data.get("posting_date"), "dd-mm-yyyy")
|
||||||
row["voucher_type"] = doctype
|
row["voucher_type"] = doctype
|
||||||
row["voucher_no"] = inv
|
row["voucher_no"] = inv
|
||||||
row["party_type"] = "Customer" if doctype == "Sales Invoice" else "Supplier"
|
row["party_type"] = "Customer" if doctype == "Sales Invoice" else "Supplier"
|
||||||
row["party"] = inv_data.get("party")
|
row["party"] = inv_data.get("party")
|
||||||
row["remarks"] = inv_data.get("remarks")
|
row["remarks"] = inv_data.get("remarks")
|
||||||
row["gross_amount"]= item_details[0].get("gross_amount")
|
row["gross_amount"]= item_details[0].get("gross_amount")
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ def make_custom_fields(update=True):
|
|||||||
'Sales Invoice Item': is_zero_rated,
|
'Sales Invoice Item': is_zero_rated,
|
||||||
'Purchase Invoice Item': is_zero_rated
|
'Purchase Invoice Item': is_zero_rated
|
||||||
}
|
}
|
||||||
|
|
||||||
create_custom_fields(custom_fields, update=update)
|
create_custom_fields(custom_fields, update=update)
|
||||||
|
|
||||||
def add_permissions():
|
def add_permissions():
|
||||||
@@ -36,7 +36,7 @@ def add_permissions():
|
|||||||
add_permission(doctype, role, 0)
|
add_permission(doctype, role, 0)
|
||||||
update_permission_property(doctype, role, 0, 'write', 1)
|
update_permission_property(doctype, role, 0, 'write', 1)
|
||||||
update_permission_property(doctype, role, 0, 'create', 1)
|
update_permission_property(doctype, role, 0, 'create', 1)
|
||||||
|
|
||||||
|
|
||||||
if not frappe.db.get_value('Custom Role', dict(report="VAT Audit Report")):
|
if not frappe.db.get_value('Custom Role', dict(report="VAT Audit Report")):
|
||||||
frappe.get_doc(dict(
|
frappe.get_doc(dict(
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe, json
|
import json
|
||||||
|
import frappe
|
||||||
from frappe.utils.nestedset import get_root_of
|
from frappe.utils.nestedset import get_root_of
|
||||||
from frappe.utils import cint
|
from frappe.utils import cint
|
||||||
from erpnext.accounts.doctype.pos_profile.pos_profile import get_item_groups
|
from erpnext.accounts.doctype.pos_profile.pos_profile import get_item_groups
|
||||||
@@ -209,7 +210,6 @@ def check_opening_entry(user):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def create_opening_voucher(pos_profile, company, balance_details):
|
def create_opening_voucher(pos_profile, company, balance_details):
|
||||||
import json
|
|
||||||
balance_details = json.loads(balance_details)
|
balance_details = json.loads(balance_details)
|
||||||
|
|
||||||
new_pos_opening = frappe.get_doc({
|
new_pos_opening = frappe.get_doc({
|
||||||
|
|||||||
@@ -79,7 +79,8 @@ class NamingSeries(Document):
|
|||||||
options = self.scrub_options_list(ol)
|
options = self.scrub_options_list(ol)
|
||||||
|
|
||||||
# validate names
|
# validate names
|
||||||
for i in options: self.validate_series_name(i)
|
for i in options:
|
||||||
|
self.validate_series_name(i)
|
||||||
|
|
||||||
if options and self.user_must_always_select:
|
if options and self.user_must_always_select:
|
||||||
options = [''] + options
|
options = [''] + options
|
||||||
@@ -138,7 +139,7 @@ class NamingSeries(Document):
|
|||||||
|
|
||||||
def validate_series_name(self, n):
|
def validate_series_name(self, n):
|
||||||
import re
|
import re
|
||||||
if not re.match("^[\w\- /.#{}]*$", n, re.UNICODE):
|
if not re.match(r"^[\w\- \/.#{}]+$", n, re.UNICODE):
|
||||||
throw(_('Special Characters except "-", "#", ".", "/", "{" and "}" not allowed in naming series'))
|
throw(_('Special Characters except "-", "#", ".", "/", "{" and "}" not allowed in naming series'))
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ def fin(args):
|
|||||||
def make_sample_data(domains):
|
def make_sample_data(domains):
|
||||||
try:
|
try:
|
||||||
sample_data.make_sample_data(domains)
|
sample_data.make_sample_data(domains)
|
||||||
except:
|
except Exception:
|
||||||
# clear message
|
# clear message
|
||||||
if frappe.message_log:
|
if frappe.message_log:
|
||||||
frappe.message_log.pop()
|
frappe.message_log.pop()
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None, args=No
|
|||||||
value = response.json()["result"]
|
value = response.json()["result"]
|
||||||
cache.setex(name=key, time=21600, value=flt(value))
|
cache.setex(name=key, time=21600, value=flt(value))
|
||||||
return flt(value)
|
return flt(value)
|
||||||
except:
|
except Exception:
|
||||||
frappe.log_error(title="Get Exchange Rate")
|
frappe.log_error(title="Get Exchange Rate")
|
||||||
frappe.msgprint(_("Unable to find exchange rate for {0} to {1} for key date {2}. Please create a Currency Exchange record manually").format(from_currency, to_currency, transaction_date))
|
frappe.msgprint(_("Unable to find exchange rate for {0} to {1} for key date {2}. Please create a Currency Exchange record manually").format(from_currency, to_currency, transaction_date))
|
||||||
return 0.0
|
return 0.0
|
||||||
|
|||||||
@@ -331,7 +331,7 @@ class DeliveryNote(SellingController):
|
|||||||
credit_note_link = frappe.utils.get_link_to_form('Sales Invoice', return_invoice.name)
|
credit_note_link = frappe.utils.get_link_to_form('Sales Invoice', return_invoice.name)
|
||||||
|
|
||||||
frappe.msgprint(_("Credit Note {0} has been created automatically").format(credit_note_link))
|
frappe.msgprint(_("Credit Note {0} has been created automatically").format(credit_note_link))
|
||||||
except:
|
except Exception:
|
||||||
frappe.throw(_("Could not create Credit Note automatically, please uncheck 'Issue Credit Note' and submit again"))
|
frappe.throw(_("Could not create Credit Note automatically, please uncheck 'Issue Credit Note' and submit again"))
|
||||||
|
|
||||||
def update_billed_amount_based_on_so(so_detail, update_modified=True):
|
def update_billed_amount_based_on_so(so_detail, update_modified=True):
|
||||||
|
|||||||
@@ -573,7 +573,7 @@ def auto_fetch_serial_number(qty, item_code, warehouse, posting_date=None, batch
|
|||||||
if batch_nos:
|
if batch_nos:
|
||||||
try:
|
try:
|
||||||
filters["batch_no"] = json.loads(batch_nos) if (type(json.loads(batch_nos)) == list) else [json.loads(batch_nos)]
|
filters["batch_no"] = json.loads(batch_nos) if (type(json.loads(batch_nos)) == list) else [json.loads(batch_nos)]
|
||||||
except:
|
except Exception:
|
||||||
filters["batch_no"] = [batch_nos]
|
filters["batch_no"] = [batch_nos]
|
||||||
|
|
||||||
if posting_date:
|
if posting_date:
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ def create_material_request(material_requests):
|
|||||||
mr.submit()
|
mr.submit()
|
||||||
mr_list.append(mr)
|
mr_list.append(mr)
|
||||||
|
|
||||||
except:
|
except Exception:
|
||||||
_log_exception()
|
_log_exception()
|
||||||
|
|
||||||
if mr_list:
|
if mr_list:
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ def get_query_args(filters: Filters) -> QueryArgs:
|
|||||||
|
|
||||||
def run_query(query_args: QueryArgs) -> Data:
|
def run_query(query_args: QueryArgs) -> Data:
|
||||||
return frappe.db.sql("""
|
return frappe.db.sql("""
|
||||||
SELECT
|
SELECT
|
||||||
wo.name, wo.status, wo.production_item, wo.qty,
|
wo.name, wo.status, wo.production_item, wo.qty,
|
||||||
wo.produced_qty, wo.process_loss_qty,
|
wo.produced_qty, wo.process_loss_qty,
|
||||||
(wo.produced_qty - wo.process_loss_qty) as actual_produced_qty,
|
(wo.produced_qty - wo.process_loss_qty) as actual_produced_qty,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
|
from operator import itemgetter
|
||||||
from frappe.utils import date_diff, flt, cint
|
from frappe.utils import date_diff, flt, cint
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||||
@@ -12,7 +13,7 @@ def execute(filters=None):
|
|||||||
columns = get_columns(filters)
|
columns = get_columns(filters)
|
||||||
item_details = get_fifo_queue(filters)
|
item_details = get_fifo_queue(filters)
|
||||||
to_date = filters["to_date"]
|
to_date = filters["to_date"]
|
||||||
_func = lambda x: x[1]
|
_func = itemgetter(1)
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
for item, item_dict in iteritems(item_details):
|
for item, item_dict in iteritems(item_details):
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
from operator import itemgetter
|
||||||
import frappe, erpnext
|
import frappe, erpnext
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import flt, cint, getdate, now, date_diff
|
from frappe.utils import flt, cint, getdate, now, date_diff
|
||||||
@@ -44,7 +45,7 @@ def execute(filters=None):
|
|||||||
data = []
|
data = []
|
||||||
conversion_factors = {}
|
conversion_factors = {}
|
||||||
|
|
||||||
_func = lambda x: x[1]
|
_func = itemgetter(1)
|
||||||
|
|
||||||
for (company, item, warehouse) in sorted(iwb_map):
|
for (company, item, warehouse) in sorted(iwb_map):
|
||||||
if item_map.get(item):
|
if item_map.get(item):
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ def repost(only_actual=False, allow_negative_stock=False, allow_zero_rate=False,
|
|||||||
try:
|
try:
|
||||||
repost_stock(d[0], d[1], allow_zero_rate, only_actual, only_bin, allow_negative_stock)
|
repost_stock(d[0], d[1], allow_zero_rate, only_actual, only_bin, allow_negative_stock)
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
except:
|
except Exception:
|
||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
|
|
||||||
if allow_negative_stock:
|
if allow_negative_stock:
|
||||||
@@ -247,5 +247,5 @@ def reset_serial_no_status_and_warehouse(serial_nos=None):
|
|||||||
|
|
||||||
sr.via_stock_ledger = True
|
sr.via_stock_ledger = True
|
||||||
sr.save()
|
sr.save()
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -291,10 +291,6 @@ class Issue(Document):
|
|||||||
self.agreement_status = "Ongoing"
|
self.agreement_status = "Ongoing"
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def reset_issue_metrics(self):
|
|
||||||
self.db_set("resolution_time", None)
|
|
||||||
self.db_set("user_resolution_time", None)
|
|
||||||
|
|
||||||
|
|
||||||
def get_priority(issue):
|
def get_priority(issue):
|
||||||
service_level_agreement = frappe.get_doc("Service Level Agreement", issue.service_level_agreement)
|
service_level_agreement = frappe.get_doc("Service Level Agreement", issue.service_level_agreement)
|
||||||
@@ -533,7 +529,7 @@ def set_first_response_time(communication, method):
|
|||||||
|
|
||||||
def is_first_response(issue):
|
def is_first_response(issue):
|
||||||
responses = frappe.get_all('Communication', filters = {'reference_name': issue.name, 'sent_or_received': 'Sent'})
|
responses = frappe.get_all('Communication', filters = {'reference_name': issue.name, 'sent_or_received': 'Sent'})
|
||||||
if len(responses) == 1:
|
if len(responses) == 1:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -562,7 +558,7 @@ def calculate_first_response_time(issue, first_responded_on):
|
|||||||
# both issue creation and first response were after working hours
|
# both issue creation and first response were after working hours
|
||||||
else:
|
else:
|
||||||
return 1.0 # this should ideally be zero, but it gets reset when the next response is sent if the value is zero
|
return 1.0 # this should ideally be zero, but it gets reset when the next response is sent if the value is zero
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return 1.0
|
return 1.0
|
||||||
|
|
||||||
@@ -638,4 +634,4 @@ def is_before_working_hours(date, support_hours):
|
|||||||
time = get_time_in_seconds(date)
|
time = get_time_in_seconds(date)
|
||||||
if time < start_time:
|
if time < start_time:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ class TestIssue(TestSetUp):
|
|||||||
|
|
||||||
issue.reload()
|
issue.reload()
|
||||||
self.assertEqual(flt(issue.total_hold_time, 2), 2700)
|
self.assertEqual(flt(issue.total_hold_time, 2), 2700)
|
||||||
self.assertEqual(issue.resolution_by, get_datetime("2020-03-04 16:45"))
|
self.assertEqual(issue.resolution_by, get_datetime("2020-03-04 16:45"))
|
||||||
|
|
||||||
creation = get_datetime("2020-03-04 5:05")
|
creation = get_datetime("2020-03-04 5:05")
|
||||||
create_communication(issue.name, "test@admin.com", "Sent", creation)
|
create_communication(issue.name, "test@admin.com", "Sent", creation)
|
||||||
@@ -176,7 +176,7 @@ class TestFirstResponseTime(TestSetUp):
|
|||||||
# issue creation and first response are on consecutive days
|
# issue creation and first response are on consecutive days
|
||||||
def test_first_response_time_case6(self):
|
def test_first_response_time_case6(self):
|
||||||
"""
|
"""
|
||||||
Test frt when the issue was created before working hours and the first response is also sent before working hours, but on the next day.
|
Test frt when the issue was created before working hours and the first response is also sent before working hours, but on the next day.
|
||||||
"""
|
"""
|
||||||
issue = create_issue_and_communication(get_datetime("06-28-2021 6:00"), get_datetime("06-29-2021 6:00"))
|
issue = create_issue_and_communication(get_datetime("06-28-2021 6:00"), get_datetime("06-29-2021 6:00"))
|
||||||
self.assertEqual(issue.first_response_time, 28800.0)
|
self.assertEqual(issue.first_response_time, 28800.0)
|
||||||
@@ -198,7 +198,7 @@ class TestFirstResponseTime(TestSetUp):
|
|||||||
def test_first_response_time_case9(self):
|
def test_first_response_time_case9(self):
|
||||||
"""
|
"""
|
||||||
Test frt when the issue was created before working hours and the first response is sent on the next day, which is not a work day.
|
Test frt when the issue was created before working hours and the first response is sent on the next day, which is not a work day.
|
||||||
"""
|
"""
|
||||||
issue = create_issue_and_communication(get_datetime("06-25-2021 6:00"), get_datetime("06-26-2021 11:00"))
|
issue = create_issue_and_communication(get_datetime("06-25-2021 6:00"), get_datetime("06-26-2021 11:00"))
|
||||||
self.assertEqual(issue.first_response_time, 28800.0)
|
self.assertEqual(issue.first_response_time, 28800.0)
|
||||||
|
|
||||||
@@ -226,7 +226,7 @@ class TestFirstResponseTime(TestSetUp):
|
|||||||
def test_first_response_time_case13(self):
|
def test_first_response_time_case13(self):
|
||||||
"""
|
"""
|
||||||
Test frt when the issue was created during working hours and the first response is sent on the next day, which is not a work day.
|
Test frt when the issue was created during working hours and the first response is sent on the next day, which is not a work day.
|
||||||
"""
|
"""
|
||||||
issue = create_issue_and_communication(get_datetime("06-25-2021 12:00"), get_datetime("06-26-2021 11:00"))
|
issue = create_issue_and_communication(get_datetime("06-25-2021 12:00"), get_datetime("06-26-2021 11:00"))
|
||||||
self.assertEqual(issue.first_response_time, 21600.0)
|
self.assertEqual(issue.first_response_time, 21600.0)
|
||||||
|
|
||||||
@@ -342,7 +342,7 @@ class TestFirstResponseTime(TestSetUp):
|
|||||||
"""
|
"""
|
||||||
issue = create_issue_and_communication(get_datetime("06-25-2021 20:00"), get_datetime("06-27-2021 11:00"))
|
issue = create_issue_and_communication(get_datetime("06-25-2021 20:00"), get_datetime("06-27-2021 11:00"))
|
||||||
self.assertEqual(issue.first_response_time, 1.0)
|
self.assertEqual(issue.first_response_time, 1.0)
|
||||||
|
|
||||||
def create_issue_and_communication(issue_creation, first_responded_on):
|
def create_issue_and_communication(issue_creation, first_responded_on):
|
||||||
issue = make_issue(issue_creation, index=1)
|
issue = make_issue(issue_creation, index=1)
|
||||||
sender = create_user("test@admin.com")
|
sender = create_user("test@admin.com")
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ def get_price(item_code, price_list, customer_group, company, qty=1):
|
|||||||
return price_obj
|
return price_obj
|
||||||
|
|
||||||
def get_non_stock_item_status(item_code, item_warehouse_field):
|
def get_non_stock_item_status(item_code, item_warehouse_field):
|
||||||
#if item belongs to product bundle, check if bundle items are in stock
|
#if item belongs to product bundle, check if bundle items are in stock
|
||||||
if frappe.db.exists("Product Bundle", item_code):
|
if frappe.db.exists("Product Bundle", item_code):
|
||||||
items = frappe.get_doc("Product Bundle", item_code).get_all_children()
|
items = frappe.get_doc("Product Bundle", item_code).get_all_children()
|
||||||
bundle_warehouse = frappe.db.get_value('Item', item_code, item_warehouse_field)
|
bundle_warehouse = frappe.db.get_value('Item', item_code, item_warehouse_field)
|
||||||
|
|||||||
Reference in New Issue
Block a user