Compare commits

..

23 Commits

Author SHA1 Message Date
Frappe PR Bot
cfbd9af100 chore(release): Bumped to Version 13.52.11
## [13.52.11](https://github.com/frappe/erpnext/compare/v13.52.10...v13.52.11) (2023-08-17)

### Bug Fixes

* disallow mulitple SO with same PO No ([bdaae81](bdaae81171))
2023-08-17 10:12:01 +00:00
ruthra kumar
966c296872 Merge pull request #36680 from frappe/mergify/bp/version-13/pr-36590
fix: disallow mulitple SO with same Purchase Order No if not enabled in Settings (backport #36590)
2023-08-17 15:40:34 +05:30
ruthra kumar
0ff871e38e chore: resolve conflict 2023-08-17 09:11:47 +05:30
ruthra kumar
9df10dbc40 refactor(test): don't set po_no by default
(cherry picked from commit 64614cd915)

# Conflicts:
#	erpnext/stock/doctype/delivery_note/test_delivery_note.py
2023-08-17 03:33:56 +00:00
ruthra kumar
bdaae81171 fix: disallow mulitple SO with same PO No
(cherry picked from commit dbd3fdbb41)
2023-08-17 03:33:56 +00:00
Frappe PR Bot
8f977f40f0 chore(release): Bumped to Version 13.52.10
## [13.52.10](https://github.com/frappe/erpnext/compare/v13.52.9...v13.52.10) (2023-08-16)

### Bug Fixes

* Allow backdated repayment cancels for term loans ([c417365](c417365e03))
* payment allocation in invoice payment schedule ([#36440](https://github.com/frappe/erpnext/issues/36440)) ([e5b3860](e5b38607ce))

### Performance Improvements

* **invoice:** Faster return amount query (backport [#36556](https://github.com/frappe/erpnext/issues/36556)) ([#36558](https://github.com/frappe/erpnext/issues/36558)) ([a801bba](a801bba83e))
2023-08-16 02:46:48 +00:00
Deepesh Garg
3bc7c88133 Merge pull request #36657 from frappe/version-13-hotfix
chore: release v13
2023-08-16 08:15:05 +05:30
mergify[bot]
84b6f68108 chore: add validation for depreciation expense account in asset category (backport #36659) (#36662)
chore: add validation for depreciation expense account in asset category (#36659)

(cherry picked from commit e0c79d3b53)

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
2023-08-15 18:26:33 +05:30
mergify[bot]
e5b38607ce fix: payment allocation in invoice payment schedule (#36440)
fix: payment allocation in invoice payment schedule (#36440)
2023-08-13 13:21:04 +05:30
Deepesh Garg
b3c9d0d910 Merge pull request #36624 from frappe/mergify/bp/version-13-hotfix/pr-36614
fix: Allow backdated repayment cancels for term loans (#36614)
2023-08-13 13:20:02 +05:30
Deepesh Garg
c417365e03 fix: Allow backdated repayment cancels for term loans
(cherry picked from commit 1377cf4cf1)
2023-08-13 06:28:38 +00:00
mergify[bot]
b2a4175d43 chore: set default filter dates if missing (backport #36597) (#36599)
chore: set default filter dates if missing (#36597)

(cherry picked from commit 98e82e0d99)

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
2023-08-11 09:17:08 +00:00
mergify[bot]
a801bba83e perf(invoice): Faster return amount query (backport #36556) (#36558)
perf(invoice): Faster return amount query (#36556)

perf: Faster return amount query
(cherry picked from commit b0c79a0467)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2023-08-09 14:07:52 +05:30
Frappe PR Bot
3ccb511e25 chore(release): Bumped to Version 13.52.9
## [13.52.9](https://github.com/frappe/erpnext/compare/v13.52.8...v13.52.9) (2023-08-08)

### Bug Fixes

* Tax withholding against order via Payment Entry ([#36493](https://github.com/frappe/erpnext/issues/36493)) ([5dbca09](5dbca09899))
2023-08-08 18:37:46 +00:00
Deepesh Garg
8c51f2e5a1 Merge pull request #36545 from frappe/version-13-hotfix
chore: release v13
2023-08-09 00:05:16 +05:30
mergify[bot]
5dbca09899 fix: Tax withholding against order via Payment Entry (#36493)
* fix: Tax withholding against order via Payment Entry (#36493)

* fix: Tax withholding against order via Payment Entry

* test: Add test case

* fix: Nonetype exceptions

(cherry picked from commit 93767eb7fc)

# Conflicts:
#	erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py

* chore: resolve conflicts

---------

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-08-07 17:15:22 +05:30
mergify[bot]
9ec7bb9be3 chore: better cost center validation for assets (backport #36477) (#36478)
chore: better cost center validation for assets (#36477)

(cherry picked from commit 38a612c62e)

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
2023-08-03 17:19:05 +05:30
Frappe PR Bot
0281afcead chore(release): Bumped to Version 13.52.8
## [13.52.8](https://github.com/frappe/erpnext/compare/v13.52.7...v13.52.8) (2023-08-01)

### Bug Fixes

* added validation for unique serial numbers in pos invoice ([#36302](https://github.com/frappe/erpnext/issues/36302)) ([a165b37](a165b37fd7))
* only publish repost progress to doc subscriber (backport [#36400](https://github.com/frappe/erpnext/issues/36400)) ([#36403](https://github.com/frappe/erpnext/issues/36403)) ([e9df064](e9df06406f))
* removed "fetch_from" (backport [#36365](https://github.com/frappe/erpnext/issues/36365)) ([#36387](https://github.com/frappe/erpnext/issues/36387)) ([c574494](c574494ddd))

### Performance Improvements

* use `LEFT JOIN` instead of `NOT EXISTS` (backport [#36221](https://github.com/frappe/erpnext/issues/36221)) ([#36384](https://github.com/frappe/erpnext/issues/36384)) ([cdc86bd](cdc86bd76c))
2023-08-01 18:04:50 +00:00
Deepesh Garg
348e4616cb Merge pull request #36441 from frappe/version-13-hotfix
chore: release v13
2023-08-01 23:33:11 +05:30
RitvikSardana
a165b37fd7 fix: added validation for unique serial numbers in pos invoice (#36302)
* fix: added validation for unique serial numbers in pos invoice

* fix: updated title of validation

* fix: removed extra whitespace

* fix: added validation for duplicate batch numbers

---------

Co-authored-by: Ritvik Sardana <ritviksardana@Ritviks-MacBook-Air.local>
2023-07-31 23:28:10 +05:30
mergify[bot]
cdc86bd76c perf: use LEFT JOIN instead of NOT EXISTS (backport #36221) (#36384)
* perf: use `LEFT JOIN` instead of `NOT EXISTS`

(cherry picked from commit 58d867503b)

# Conflicts:
#	erpnext/manufacturing/doctype/bom_update_log/bom_updation_utils.py

* fix: long queue `process_boms_cost_level_wise`

(cherry picked from commit 148d466ae5)

* chore: `conflicts`

* fix: failing test case

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-07-31 17:39:31 +05:30
mergify[bot]
e9df06406f fix: only publish repost progress to doc subscriber (backport #36400) (#36403)
* fix: only publish repost progress to doc subscriber (#36400)

Huge size of string gets blasted to everyone on site. Due to some memory
leak (cause unknown) till sockets are open the strings are also in
process' memory.

related https://github.com/frappe/frappe/issues/21863

(cherry picked from commit c0642cf528)

# Conflicts:
#	erpnext/stock/stock_ledger.py

* chore: conflicts

---------

Co-authored-by: Ankush Menat <ankush@frappe.io>
2023-07-29 18:14:26 +05:30
mergify[bot]
c574494ddd fix: removed "fetch_from" (backport #36365) (#36387)
fix: removed "fetch_from"

* fix: removed ("fetch_from": "goal.objective")
The field ended up being disabled because of this.

(cherry picked from commit 1c687a4afd)

Co-authored-by: xdlumertz <alexandrelumertz@gmail.com>
2023-07-28 18:15:24 +05:30
19 changed files with 258 additions and 43 deletions

View File

@@ -4,7 +4,7 @@ import frappe
from erpnext.hooks import regional_overrides
__version__ = "13.52.7"
__version__ = "13.52.11"
def get_default_company(user=None):

View File

@@ -616,7 +616,9 @@ class PaymentEntry(AccountsController):
if not self.apply_tax_withholding_amount:
return
net_total = self.paid_amount
order_amount = self.get_order_net_total()
net_total = flt(order_amount) + flt(self.unallocated_amount)
# Adding args as purchase invoice to get TDS amount
args = frappe._dict(
@@ -661,6 +663,20 @@ class PaymentEntry(AccountsController):
for d in to_remove:
self.remove(d)
def get_order_net_total(self):
if self.party_type == "Supplier":
doctype = "Purchase Order"
else:
doctype = "Sales Order"
docnames = [d.reference_name for d in self.references if d.reference_doctype == doctype]
tax_withholding_net_total = frappe.db.get_value(
doctype, {"name": ["in", docnames]}, ["sum(base_net_total)"]
)
return tax_withholding_net_total
def apply_taxes(self):
self.initialize_taxes()
self.determine_exclusive_rate()

View File

@@ -1,6 +1,6 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and contributors
# For license information, please see license.txt
import collections
import frappe
from frappe import _
@@ -44,6 +44,7 @@ class POSInvoice(SalesInvoice):
self.validate_debit_to_acc()
self.validate_write_off_account()
self.validate_change_amount()
self.validate_duplicate_serial_and_batch_no()
self.validate_change_account()
self.validate_item_cost_centers()
self.validate_warehouse()
@@ -154,6 +155,27 @@ class POSInvoice(SalesInvoice):
title=_("Item Unavailable"),
)
def validate_duplicate_serial_and_batch_no(self):
serial_nos = []
batch_nos = []
for row in self.get("items"):
if row.serial_no:
serial_nos = row.serial_no.split("\n")
if row.batch_no and not row.serial_no:
batch_nos.append(row.batch_no)
if serial_nos:
for key, value in collections.Counter(serial_nos).items():
if value > 1:
frappe.throw(_("Duplicate Serial No {0} found").format("key"))
if batch_nos:
for key, value in collections.Counter(batch_nos).items():
if value > 1:
frappe.throw(_("Duplicate Batch No {0} found").format("key"))
def validate_pos_reserved_batch_qty(self, item):
filters = {"item_code": item.item_code, "warehouse": item.warehouse, "batch_no": item.batch_no}

View File

@@ -1580,6 +1580,52 @@ class TestPurchaseInvoice(unittest.TestCase, StockTestMixin):
self.assertTrue(return_pi.docstatus == 1)
def test_payment_allocation_for_payment_terms(self):
from erpnext.buying.doctype.purchase_order.test_purchase_order import (
create_pr_against_po,
create_purchase_order,
)
from erpnext.selling.doctype.sales_order.test_sales_order import (
automatically_fetch_payment_terms,
)
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (
make_purchase_invoice as make_pi_from_pr,
)
automatically_fetch_payment_terms()
frappe.db.set_value(
"Payment Terms Template",
"_Test Payment Term Template",
"allocate_payment_based_on_payment_terms",
0,
)
po = create_purchase_order(do_not_save=1)
po.payment_terms_template = "_Test Payment Term Template"
po.save()
po.submit()
pr = create_pr_against_po(po.name, received_qty=4)
pi = make_pi_from_pr(pr.name)
self.assertEqual(pi.payment_schedule[0].payment_amount, 1000)
frappe.db.set_value(
"Payment Terms Template",
"_Test Payment Term Template",
"allocate_payment_based_on_payment_terms",
1,
)
pi = make_pi_from_pr(pr.name)
self.assertEqual(pi.payment_schedule[0].payment_amount, 2500)
automatically_fetch_payment_terms(enable=0)
frappe.db.set_value(
"Payment Terms Template",
"_Test Payment Term Template",
"allocate_payment_based_on_payment_terms",
0,
)
def check_gl_entries(doc, voucher_no, expected_gle, posting_date):
gl_entries = frappe.db.sql(

View File

@@ -1580,15 +1580,13 @@ class SalesInvoice(SellingController):
frappe.db.set_value("Customer", self.customer, "loyalty_program_tier", lp_details.tier_name)
def get_returned_amount(self):
from frappe.query_builder.functions import Coalesce, Sum
from frappe.query_builder.functions import Sum
doc = frappe.qb.DocType(self.doctype)
returned_amount = (
frappe.qb.from_(doc)
.select(Sum(doc.grand_total))
.where(
(doc.docstatus == 1) & (doc.is_return == 1) & (Coalesce(doc.return_against, "") == self.name)
)
.where((doc.docstatus == 1) & (doc.is_return == 1) & (doc.return_against == self.name))
).run()
return abs(returned_amount[0][0]) if returned_amount[0][0] else 0

View File

@@ -186,6 +186,42 @@ class TestTaxWithholdingCategory(unittest.TestCase):
for d in reversed(invoices):
d.cancel()
def test_tds_deduction_for_po_via_payment_entry(self):
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
frappe.db.set_value(
"Supplier", "Test TDS Supplier8", "tax_withholding_category", "Cumulative Threshold TDS"
)
order = create_purchase_order(supplier="Test TDS Supplier8", rate=40000, do_not_save=True)
# Add some tax on the order
order.append(
"taxes",
{
"category": "Total",
"charge_type": "Actual",
"account_head": "_Test Account VAT - _TC",
"cost_center": "Main - _TC",
"tax_amount": 8000,
"description": "Test",
"add_deduct_tax": "Add",
},
)
order.save()
order.apply_tds = 1
order.tax_withholding_category = "Cumulative Threshold TDS"
order.submit()
self.assertEqual(order.taxes[0].tax_amount, 4000)
payment = get_payment_entry(order.doctype, order.name)
payment.apply_tax_withholding_amount = 1
payment.tax_withholding_category = "Cumulative Threshold TDS"
payment.submit()
self.assertEqual(payment.taxes[0].tax_amount, 4000)
def test_multi_category_single_supplier(self):
frappe.db.set_value(
"Supplier", "Test TDS Supplier5", "tax_withholding_category", "Test Service Category"
@@ -275,6 +311,37 @@ def cancel_invoices():
frappe.get_doc("Sales Invoice", d).cancel()
def create_purchase_order(**args):
# return purchase order doc object
item = frappe.db.get_value("Item", {"item_name": "TDS Item"}, "name")
args = frappe._dict(args)
po = frappe.get_doc(
{
"doctype": "Purchase Order",
"transaction_date": today(),
"schedule_date": today(),
"apply_tds": 0 if args.do_not_apply_tds else 1,
"supplier": args.supplier,
"company": "_Test Company",
"taxes_and_charges": "",
"currency": "INR",
"taxes": [],
"items": [
{
"doctype": "Purchase Order Item",
"item_code": item,
"qty": args.qty or 1,
"rate": args.rate or 10000,
"cost_center": "Main - _TC",
"expense_account": "Stock Received But Not Billed - _TC",
}
],
}
)
po.save()
return po
def create_purchase_invoice(**args):
# return sales invoice doc object
item = frappe.db.get_value("Item", {"item_name": "TDS Item"}, "name")
@@ -351,6 +418,8 @@ def create_records():
"Test TDS Supplier4",
"Test TDS Supplier5",
"Test TDS Supplier6",
"Test TDS Supplier7",
"Test TDS Supplier8",
]:
if frappe.db.exists("Supplier", name):
continue

View File

@@ -148,17 +148,33 @@ class Asset(AccountsController):
frappe.throw(_("Item {0} must be a non-stock item").format(self.item_code))
def validate_cost_center(self):
if not self.cost_center:
return
cost_center_company = frappe.db.get_value("Cost Center", self.cost_center, "company")
if cost_center_company != self.company:
frappe.throw(
_("Selected Cost Center {} doesn't belongs to {}").format(
frappe.bold(self.cost_center), frappe.bold(self.company)
),
title=_("Invalid Cost Center"),
if self.cost_center:
cost_center_company, cost_center_is_group = frappe.db.get_value(
"Cost Center", self.cost_center, ["company", "is_group"]
)
if cost_center_company != self.company:
frappe.throw(
_("Cost Center {} doesn't belong to Company {}").format(
frappe.bold(self.cost_center), frappe.bold(self.company)
),
title=_("Invalid Cost Center"),
)
if cost_center_is_group:
frappe.throw(
_(
"Cost Center {} is a group cost center and group cost centers cannot be used in transactions"
).format(frappe.bold(self.cost_center)),
title=_("Invalid Cost Center"),
)
else:
if not frappe.get_cached_value("Company", self.company, "depreciation_cost_center"):
frappe.throw(
_(
"Please set a Cost Center for the Asset or set an Asset Depreciation Cost Center for the Company {}"
).format(frappe.bold(self.company)),
title=_("Missing Cost Center"),
)
def validate_in_use_date(self):
if not self.available_for_use_date:

View File

@@ -33,6 +33,7 @@ frappe.ui.form.on('Asset Category', {
var d = locals[cdt][cdn];
return {
"filters": {
"account_type": "Depreciation",
"root_type": ["in", ["Expense", "Income"]],
"is_group": 0,
"company": d.company_name

View File

@@ -53,7 +53,7 @@ class AssetCategory(Document):
account_type_map = {
"fixed_asset_account": {"account_type": ["Fixed Asset"]},
"accumulated_depreciation_account": {"account_type": ["Accumulated Depreciation"]},
"depreciation_expense_account": {"root_type": ["Expense", "Income"]},
"depreciation_expense_account": {"account_type": ["Depreciation"]},
"capital_work_in_progress_account": {"account_type": ["Capital Work in Progress"]},
}
for d in self.accounts:

View File

@@ -7,13 +7,14 @@ from itertools import chain
import frappe
from frappe import _
from frappe.query_builder.functions import IfNull, Sum
from frappe.utils import cstr, flt, formatdate, getdate
from frappe.utils import add_months, cstr, flt, formatdate, getdate, nowdate, today
from erpnext.accounts.report.financial_statements import (
get_fiscal_year_data,
get_period_list,
validate_fiscal_year,
)
from erpnext.accounts.utils import get_fiscal_year
from erpnext.assets.doctype.asset.asset import get_asset_value_after_depreciation
@@ -37,15 +38,26 @@ def get_conditions(filters):
if filters.get("company"):
conditions["company"] = filters.company
if filters.filter_based_on == "Date Range":
if not filters.from_date and not filters.to_date:
filters.from_date = add_months(nowdate(), -12)
filters.to_date = nowdate()
conditions[date_field] = ["between", [filters.from_date, filters.to_date]]
if filters.filter_based_on == "Fiscal Year":
elif filters.filter_based_on == "Fiscal Year":
if not filters.from_fiscal_year and not filters.to_fiscal_year:
default_fiscal_year = get_fiscal_year(today())[0]
filters.from_fiscal_year = default_fiscal_year
filters.to_fiscal_year = default_fiscal_year
fiscal_year = get_fiscal_year_data(filters.from_fiscal_year, filters.to_fiscal_year)
validate_fiscal_year(fiscal_year, filters.from_fiscal_year, filters.to_fiscal_year)
filters.year_start_date = getdate(fiscal_year.year_start_date)
filters.year_end_date = getdate(fiscal_year.year_end_date)
conditions[date_field] = ["between", [filters.year_start_date, filters.year_end_date]]
if filters.get("only_existing_assets"):
conditions["is_existing_asset"] = filters.get("only_existing_assets")
if filters.get("asset_category"):

View File

@@ -1635,8 +1635,13 @@ class AccountsController(TransactionBase):
)
self.append("payment_schedule", data)
allocate_payment_based_on_payment_terms = frappe.db.get_value(
"Payment Terms Template", self.payment_terms_template, "allocate_payment_based_on_payment_terms"
)
if not (
automatically_fetch_payment_terms
and allocate_payment_based_on_payment_terms
and self.linked_order_has_payment_terms(po_or_so, fieldname, doctype)
):
for d in self.get("payment_schedule"):

View File

@@ -250,6 +250,9 @@ class LoanRepayment(AccountsController):
)
def check_future_accruals(self):
if self.is_term_loan:
return
future_accrual_date = frappe.db.get_value(
"Loan Interest Accrual",
{"posting_date": (">", self.posting_date), "docstatus": 1, "loan": self.against_loan},

View File

@@ -79,6 +79,7 @@ class BOMUpdateLog(Document):
else:
frappe.enqueue(
method="erpnext.manufacturing.doctype.bom_update_log.bom_update_log.process_boms_cost_level_wise",
queue="long",
update_doc=self,
now=frappe.flags.in_test,
)

View File

@@ -157,12 +157,21 @@ def get_next_higher_level_boms(
def get_leaf_boms() -> List[str]:
"Get BOMs that have no dependencies."
return frappe.db.sql_list(
"""select name from `tabBOM` bom
where docstatus=1 and is_active=1
and not exists(select bom_no from `tabBOM Item`
where parent=bom.name and ifnull(bom_no, '')!='')"""
)
bom = frappe.qb.DocType("BOM")
bom_item = frappe.qb.DocType("BOM Item")
boms = (
frappe.qb.from_(bom)
.left_join(bom_item)
.on((bom.name == bom_item.parent) & (bom_item.bom_no != ""))
.select(bom.name)
.where((bom.docstatus == 1) & (bom.is_active == 1) & (bom_item.bom_no.isnull()))
.distinct()
).run(as_list=True)
boms = [bom[0] for bom in boms]
return boms
def _generate_dependence_map() -> defaultdict:

View File

@@ -1,4 +1,5 @@
{
"actions": [],
"autoname": "format:{####}",
"creation": "2019-05-26 15:03:43.996455",
"doctype": "DocType",
@@ -12,7 +13,6 @@
],
"fields": [
{
"fetch_from": "goal.objective",
"fieldname": "objective",
"fieldtype": "Text",
"in_list_view": 1,
@@ -38,14 +38,17 @@
}
],
"istable": 1,
"modified": "2019-05-26 16:12:54.832058",
"links": [],
"modified": "2023-07-28 18:10:23.351246",
"modified_by": "Administrator",
"module": "Quality Management",
"name": "Quality Goal Objective",
"naming_rule": "Expression",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -96,18 +96,26 @@ class SalesOrder(SellingController):
and customer = %s",
(self.po_no, self.name, self.customer),
)
if (
so
and so[0][0]
and not cint(
if so and so[0][0]:
if cint(
frappe.db.get_single_value("Selling Settings", "allow_against_multiple_purchase_orders")
)
):
frappe.msgprint(
_("Warning: Sales Order {0} already exists against Customer's Purchase Order {1}").format(
so[0][0], self.po_no
):
frappe.msgprint(
_("Warning: Sales Order {0} already exists against Customer's Purchase Order {1}").format(
frappe.bold(so[0][0]), frappe.bold(self.po_no)
)
)
else:
frappe.throw(
_(
"Sales Order {0} already exists against Customer's Purchase Order {1}. To allow multiple Sales Orders, Enable {2} in {3}"
).format(
frappe.bold(so[0][0]),
frappe.bold(self.po_no),
frappe.bold(_("'Allow Multiple Sales Orders Against a Customer's Purchase Order'")),
get_link_to_form("Selling Settings", "Selling Settings"),
)
)
)
def validate_for_items(self):
for d in self.get("items"):

View File

@@ -1741,7 +1741,7 @@ def make_sales_order(**args):
so.company = args.company or "_Test Company"
so.customer = args.customer or "_Test Customer"
so.currency = args.currency or "INR"
so.po_no = args.po_no or "12345"
so.po_no = args.po_no or ""
if args.selling_price_list:
so.selling_price_list = args.selling_price_list

View File

@@ -697,7 +697,7 @@ class TestDeliveryNote(FrappeTestCase):
def test_dn_billing_status_case1(self):
# SO -> DN -> SI
so = make_sales_order()
so = make_sales_order(po_no="12345")
dn = create_dn_against_so(so.name, delivered_qty=2)
self.assertEqual(dn.status, "To Bill")
@@ -724,7 +724,7 @@ class TestDeliveryNote(FrappeTestCase):
make_sales_invoice,
)
so = make_sales_order()
so = make_sales_order(po_no="12345")
si = make_sales_invoice(so.name)
si.get("items")[0].qty = 5
@@ -768,7 +768,7 @@ class TestDeliveryNote(FrappeTestCase):
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1)
so = make_sales_order()
so = make_sales_order(po_no="12345")
dn1 = make_delivery_note(so.name)
dn1.get("items")[0].qty = 2
@@ -814,7 +814,7 @@ class TestDeliveryNote(FrappeTestCase):
from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_delivery_note
from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
so = make_sales_order()
so = make_sales_order(po_no="12345")
si = make_sales_invoice(so.name)
si.submit()
@@ -1180,6 +1180,10 @@ class TestDeliveryNote(FrappeTestCase):
self.assertTrue(return_dn.docstatus == 1)
def tearDown(self):
frappe.db.rollback()
frappe.db.set_single_value("Selling Settings", "dont_reserve_sales_order_qty_on_sales_return", 0)
def create_delivery_note(**args):
dn = frappe.new_doc("Delivery Note")

View File

@@ -278,6 +278,8 @@ def update_args_in_repost_item_valuation(
frappe.publish_realtime(
"item_reposting_progress",
{"name": doc.name, "items_to_be_repost": json.dumps(args, default=str), "current_index": index},
doctype=doc.doctype,
docname=doc.name,
)