Merge branch 'version-13-hotfix' into version-13-pre-release
This commit is contained in:
commit
67768faaef
@ -19,7 +19,7 @@ class AccountingDimension(Document):
|
||||
|
||||
def validate(self):
|
||||
if self.document_type in core_doctypes_list + ('Accounting Dimension', 'Project',
|
||||
'Cost Center', 'Accounting Dimension Detail', 'Company') :
|
||||
'Cost Center', 'Accounting Dimension Detail', 'Company', 'Account') :
|
||||
|
||||
msg = _("Not allowed to create accounting dimension for {0}").format(self.document_type)
|
||||
frappe.throw(msg)
|
||||
|
@ -690,7 +690,7 @@
|
||||
"options": "Account"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.received_amount",
|
||||
"depends_on": "eval:doc.received_amount && doc.payment_type != 'Internal Transfer'",
|
||||
"fieldname": "received_amount_after_tax",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Received Amount After Tax",
|
||||
@ -707,7 +707,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-06-09 11:55:04.215050",
|
||||
"modified": "2021-06-22 20:37:06.154206",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Entry",
|
||||
|
@ -706,7 +706,7 @@ class PaymentEntry(AccountsController):
|
||||
if account_currency != self.company_currency:
|
||||
frappe.throw(_("Currency for {0} must be {1}").format(d.account_head, self.company_currency))
|
||||
|
||||
if self.payment_type == 'Pay':
|
||||
if self.payment_type in ('Pay', 'Internal Transfer'):
|
||||
dr_or_cr = "debit" if d.add_deduct_tax == "Add" else "credit"
|
||||
elif self.payment_type == 'Receive':
|
||||
dr_or_cr = "credit" if d.add_deduct_tax == "Add" else "debit"
|
||||
@ -761,7 +761,7 @@ class PaymentEntry(AccountsController):
|
||||
return self.advance_tax_account
|
||||
elif self.payment_type == 'Receive':
|
||||
return self.paid_from
|
||||
elif self.payment_type == 'Pay':
|
||||
elif self.payment_type in ('Pay', 'Internal Transfer'):
|
||||
return self.paid_to
|
||||
|
||||
def update_advance_paid(self):
|
||||
|
@ -966,7 +966,7 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
update_tax_witholding_category('_Test Company', 'TDS Payable - _TC', nowdate())
|
||||
|
||||
# Create Purchase Order with TDS applied
|
||||
po = create_purchase_order(do_not_save=1, supplier=supplier.name, rate=3000)
|
||||
po = create_purchase_order(do_not_save=1, supplier=supplier.name, rate=3000, item='_Test Non Stock Item')
|
||||
po.apply_tds = 1
|
||||
po.tax_withholding_category = 'TDS - 194 - Dividends - Individual'
|
||||
po.save()
|
||||
@ -1002,6 +1002,7 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
# Create Purchase Invoice against Purchase Order
|
||||
purchase_invoice = get_mapped_purchase_invoice(po.name)
|
||||
purchase_invoice.allocate_advances_automatically = 1
|
||||
purchase_invoice.items[0].item_code = '_Test Non Stock Item'
|
||||
purchase_invoice.items[0].expense_account = '_Test Account Cost for Goods Sold - _TC'
|
||||
purchase_invoice.save()
|
||||
purchase_invoice.submit()
|
||||
|
@ -222,7 +222,7 @@ def get_gl_entries(filters, accounting_dimensions):
|
||||
def get_conditions(filters):
|
||||
conditions = []
|
||||
|
||||
if filters.get("account") and not filters.get("include_dimensions"):
|
||||
if filters.get("account"):
|
||||
filters.account = get_accounts_with_children(filters.account)
|
||||
conditions.append("account in %(account)s")
|
||||
|
||||
|
@ -270,11 +270,14 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
|
||||
let me = this;
|
||||
let item_codes = [];
|
||||
let item_rates = {};
|
||||
let item_tax_templates = {};
|
||||
|
||||
$.each(this.frm.doc.items || [], function(i, item) {
|
||||
if (item.item_code) {
|
||||
// Use combination of name and item code in case same item is added multiple times
|
||||
item_codes.push([item.item_code, item.name]);
|
||||
item_rates[item.name] = item.net_rate;
|
||||
item_tax_templates[item.name] = item.item_tax_template;
|
||||
}
|
||||
});
|
||||
|
||||
@ -285,18 +288,16 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
|
||||
company: me.frm.doc.company,
|
||||
tax_category: cstr(me.frm.doc.tax_category),
|
||||
item_codes: item_codes,
|
||||
item_rates: item_rates
|
||||
item_rates: item_rates,
|
||||
item_tax_templates: item_tax_templates
|
||||
},
|
||||
callback: function(r) {
|
||||
if (!r.exc) {
|
||||
$.each(me.frm.doc.items || [], function(i, item) {
|
||||
if (item.name && r.message.hasOwnProperty(item.name)) {
|
||||
if (item.name && r.message.hasOwnProperty(item.name) && r.message[item.name].item_tax_template) {
|
||||
item.item_tax_template = r.message[item.name].item_tax_template;
|
||||
item.item_tax_rate = r.message[item.name].item_tax_rate;
|
||||
me.add_taxes_from_item_tax_template(item.item_tax_rate);
|
||||
} else {
|
||||
item.item_tax_template = "";
|
||||
item.item_tax_rate = "{}";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -407,8 +407,6 @@ def replace_abbr(company, old, new):
|
||||
|
||||
frappe.only_for("System Manager")
|
||||
|
||||
frappe.db.set_value("Company", company, "abbr", new)
|
||||
|
||||
def _rename_record(doc):
|
||||
parts = doc[0].rsplit(" - ", 1)
|
||||
if len(parts) == 1 or parts[1].lower() == old.lower():
|
||||
@ -419,11 +417,18 @@ def replace_abbr(company, old, new):
|
||||
doc = (d for d in frappe.db.sql("select name from `tab%s` where company=%s" % (dt, '%s'), company))
|
||||
for d in doc:
|
||||
_rename_record(d)
|
||||
try:
|
||||
frappe.db.auto_commit_on_many_writes = 1
|
||||
frappe.db.set_value("Company", company, "abbr", new)
|
||||
for dt in ["Warehouse", "Account", "Cost Center", "Department",
|
||||
"Sales Taxes and Charges Template", "Purchase Taxes and Charges Template"]:
|
||||
_rename_records(dt)
|
||||
frappe.db.commit()
|
||||
|
||||
for dt in ["Warehouse", "Account", "Cost Center", "Department",
|
||||
"Sales Taxes and Charges Template", "Purchase Taxes and Charges Template"]:
|
||||
_rename_records(dt)
|
||||
frappe.db.commit()
|
||||
except Exception:
|
||||
frappe.log_error(title=_('Abbreviation Rename Error'))
|
||||
finally:
|
||||
frappe.db.auto_commit_on_many_writes = 0
|
||||
|
||||
|
||||
def get_name_with_abbr(name, company):
|
||||
|
@ -226,9 +226,9 @@ def split_batch(batch_no, item_code, warehouse, qty, new_batch_id=None):
|
||||
return batch.name
|
||||
|
||||
|
||||
def set_batch_nos(doc, warehouse_field, throw=False):
|
||||
def set_batch_nos(doc, warehouse_field, throw=False, child_table="items"):
|
||||
"""Automatically select `batch_no` for outgoing items in item table"""
|
||||
for d in doc.items:
|
||||
for d in doc.get(child_table):
|
||||
qty = d.get('stock_qty') or d.get('transfer_qty') or d.get('qty') or 0
|
||||
has_batch_no = frappe.db.get_value('Item', d.item_code, 'has_batch_no')
|
||||
warehouse = d.get(warehouse_field, None)
|
||||
|
@ -78,6 +78,9 @@ frappe.ui.form.on("Delivery Note", {
|
||||
});
|
||||
|
||||
erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype);
|
||||
|
||||
frm.set_df_property('packed_items', 'cannot_add_rows', true);
|
||||
frm.set_df_property('packed_items', 'cannot_delete_rows', true);
|
||||
},
|
||||
|
||||
print_without_amount: function(frm) {
|
||||
|
@ -554,8 +554,7 @@
|
||||
"oldfieldname": "packing_details",
|
||||
"oldfieldtype": "Table",
|
||||
"options": "Packed Item",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "product_bundle_help",
|
||||
@ -1289,7 +1288,7 @@
|
||||
"idx": 146,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-04-15 23:55:49.620641",
|
||||
"modified": "2021-06-11 19:27:30.901112",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Delivery Note",
|
||||
|
@ -129,12 +129,13 @@ class DeliveryNote(SellingController):
|
||||
self.validate_uom_is_integer("uom", "qty")
|
||||
self.validate_with_previous_doc()
|
||||
|
||||
if self._action != 'submit' and not self.is_return:
|
||||
set_batch_nos(self, 'warehouse', True)
|
||||
|
||||
from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
|
||||
make_packing_list(self)
|
||||
|
||||
if self._action != 'submit' and not self.is_return:
|
||||
set_batch_nos(self, 'warehouse', throw=True)
|
||||
set_batch_nos(self, 'warehouse', throw=True, child_table="packed_items")
|
||||
|
||||
self.update_current_stock()
|
||||
|
||||
if not self.installation_status: self.installation_status = 'Not Installed'
|
||||
|
@ -7,7 +7,7 @@ import unittest
|
||||
import frappe
|
||||
import json
|
||||
import frappe.defaults
|
||||
from frappe.utils import cint, nowdate, nowtime, cstr, add_days, flt, today
|
||||
from frappe.utils import nowdate, nowtime, cstr, flt
|
||||
from erpnext.stock.stock_ledger import get_previous_sle
|
||||
from erpnext.accounts.utils import get_balance_on
|
||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import get_gl_entries
|
||||
@ -18,9 +18,11 @@ from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos, SerialNoWa
|
||||
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation \
|
||||
import create_stock_reconciliation, set_valuation_method
|
||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order, create_dn_against_so
|
||||
from erpnext.accounts.doctype.account.test_account import get_inventory_account, create_account
|
||||
from erpnext.accounts.doctype.account.test_account import get_inventory_account
|
||||
from erpnext.stock.doctype.warehouse.test_warehouse import get_warehouse
|
||||
from erpnext.stock.doctype.item.test_item import create_item
|
||||
from erpnext.stock.doctype.item.test_item import make_item
|
||||
from erpnext.selling.doctype.product_bundle.test_product_bundle import make_product_bundle
|
||||
|
||||
|
||||
class TestDeliveryNote(unittest.TestCase):
|
||||
def test_over_billing_against_dn(self):
|
||||
@ -277,8 +279,6 @@ class TestDeliveryNote(unittest.TestCase):
|
||||
dn.cancel()
|
||||
|
||||
def test_sales_return_for_non_bundled_items_full(self):
|
||||
from erpnext.stock.doctype.item.test_item import make_item
|
||||
|
||||
company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company')
|
||||
|
||||
make_item("Box", {'is_stock_item': 1})
|
||||
@ -741,6 +741,25 @@ class TestDeliveryNote(unittest.TestCase):
|
||||
self.assertEqual(si2.items[0].qty, 2)
|
||||
self.assertEqual(si2.items[1].qty, 1)
|
||||
|
||||
|
||||
def test_delivery_note_bundle_with_batched_item(self):
|
||||
batched_bundle = make_item("_Test Batched bundle", {"is_stock_item": 0})
|
||||
batched_item = make_item("_Test Batched Item",
|
||||
{"is_stock_item": 1, "has_batch_no": 1, "create_new_batch": 1, "batch_number_series": "TESTBATCH.#####"}
|
||||
)
|
||||
make_product_bundle(parent=batched_bundle.name, items=[batched_item.name])
|
||||
make_stock_entry(item_code=batched_item.name, target="_Test Warehouse - _TC", qty=10, basic_rate=42)
|
||||
|
||||
try:
|
||||
dn = create_delivery_note(item_code=batched_bundle.name, qty=1)
|
||||
except frappe.ValidationError as e:
|
||||
if "batch" in str(e).lower():
|
||||
self.fail("Batch numbers not getting added to bundled items in DN.")
|
||||
raise e
|
||||
|
||||
self.assertTrue("TESTBATCH" in dn.packed_items[0].batch_no, "Batch number not added in packed item")
|
||||
|
||||
|
||||
def create_delivery_note(**args):
|
||||
dn = frappe.new_doc("Delivery Note")
|
||||
args = frappe._dict(args)
|
||||
|
@ -436,20 +436,28 @@ def get_barcode_data(items_list):
|
||||
return itemwise_barcode
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_item_tax_info(company, tax_category, item_codes, item_rates=None):
|
||||
def get_item_tax_info(company, tax_category, item_codes, item_rates=None, item_tax_templates=None):
|
||||
out = {}
|
||||
if isinstance(item_codes, string_types):
|
||||
if isinstance(item_codes, (str,)):
|
||||
item_codes = json.loads(item_codes)
|
||||
|
||||
if isinstance(item_rates, string_types):
|
||||
if isinstance(item_rates, (str,)):
|
||||
item_rates = json.loads(item_rates)
|
||||
|
||||
if isinstance(item_tax_templates, (str,)):
|
||||
item_tax_templates = json.loads(item_tax_templates)
|
||||
|
||||
for item_code in item_codes:
|
||||
if not item_code or item_code[1] in out:
|
||||
if not item_code or item_code[1] in out or not item_tax_templates.get(item_code[1]):
|
||||
continue
|
||||
|
||||
out[item_code[1]] = {}
|
||||
item = frappe.get_cached_doc("Item", item_code[0])
|
||||
args = {"company": company, "tax_category": tax_category, "net_rate": item_rates[item_code[1]]}
|
||||
|
||||
if item_tax_templates:
|
||||
args.update({"item_tax_template": item_tax_templates.get(item_code[1])})
|
||||
|
||||
get_item_tax_template(args, item, out[item_code[1]])
|
||||
out[item_code[1]]["item_tax_rate"] = get_item_tax_map(company, out[item_code[1]].get("item_tax_template"), as_json=True)
|
||||
|
||||
@ -463,9 +471,7 @@ def get_item_tax_template(args, item, out):
|
||||
}
|
||||
"""
|
||||
item_tax_template = args.get("item_tax_template")
|
||||
|
||||
if not item_tax_template:
|
||||
item_tax_template = _get_item_tax_template(args, item.taxes, out)
|
||||
item_tax_template = _get_item_tax_template(args, item.taxes, out)
|
||||
|
||||
if not item_tax_template:
|
||||
item_group = item.item_group
|
||||
@ -508,7 +514,8 @@ def _get_item_tax_template(args, taxes, out=None, for_validate=False):
|
||||
return None
|
||||
|
||||
# do not change if already a valid template
|
||||
if args.get('item_tax_template') in taxes:
|
||||
if args.get('item_tax_template') in {t.item_tax_template for t in taxes}:
|
||||
out["item_tax_template"] = args.get('item_tax_template')
|
||||
return args.get('item_tax_template')
|
||||
|
||||
for tax in taxes:
|
||||
|
Loading…
x
Reference in New Issue
Block a user