Merge branch 'develop' into manual_depr_entries_develop
This commit is contained in:
commit
f8270f093d
@ -550,7 +550,7 @@ def get_due_date_from_template(template_name, posting_date, bill_date):
|
|||||||
elif term.due_date_based_on == "Day(s) after the end of the invoice month":
|
elif term.due_date_based_on == "Day(s) after the end of the invoice month":
|
||||||
due_date = max(due_date, add_days(get_last_day(due_date), term.credit_days))
|
due_date = max(due_date, add_days(get_last_day(due_date), term.credit_days))
|
||||||
else:
|
else:
|
||||||
due_date = max(due_date, add_months(get_last_day(due_date), term.credit_months))
|
due_date = max(due_date, get_last_day(add_months(due_date, term.credit_months)))
|
||||||
return due_date
|
return due_date
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@ from frappe.utils import add_days, flt, getdate, nowdate
|
|||||||
from frappe.utils.data import today
|
from frappe.utils.data import today
|
||||||
|
|
||||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
||||||
|
from erpnext.accounts.party import get_due_date_from_template
|
||||||
from erpnext.buying.doctype.purchase_order.purchase_order import make_inter_company_sales_order
|
from erpnext.buying.doctype.purchase_order.purchase_order import make_inter_company_sales_order
|
||||||
from erpnext.buying.doctype.purchase_order.purchase_order import (
|
from erpnext.buying.doctype.purchase_order.purchase_order import (
|
||||||
make_purchase_invoice as make_pi_from_po,
|
make_purchase_invoice as make_pi_from_po,
|
||||||
@ -685,6 +686,12 @@ class TestPurchaseOrder(FrappeTestCase):
|
|||||||
else:
|
else:
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
|
def test_default_payment_terms(self):
|
||||||
|
due_date = get_due_date_from_template(
|
||||||
|
"_Test Payment Term Template 1", "2023-02-03", None
|
||||||
|
).strftime("%Y-%m-%d")
|
||||||
|
self.assertEqual(due_date, "2023-03-31")
|
||||||
|
|
||||||
def test_terms_are_not_copied_if_automatically_fetch_payment_terms_is_unchecked(self):
|
def test_terms_are_not_copied_if_automatically_fetch_payment_terms_is_unchecked(self):
|
||||||
po = create_purchase_order(do_not_save=1)
|
po = create_purchase_order(do_not_save=1)
|
||||||
po.payment_terms_template = "_Test Payment Term Template"
|
po.payment_terms_template = "_Test Payment Term Template"
|
||||||
|
|||||||
@ -42,7 +42,7 @@ erpnext.stock.ItemDashboard = class ItemDashboard {
|
|||||||
let warehouse = unescape(element.attr('data-warehouse'));
|
let warehouse = unescape(element.attr('data-warehouse'));
|
||||||
let actual_qty = unescape(element.attr('data-actual_qty'));
|
let actual_qty = unescape(element.attr('data-actual_qty'));
|
||||||
let disable_quick_entry = Number(unescape(element.attr('data-disable_quick_entry')));
|
let disable_quick_entry = Number(unescape(element.attr('data-disable_quick_entry')));
|
||||||
let entry_type = action === "Move" ? "Material Transfer" : null;
|
let entry_type = action === "Move" ? "Material Transfer" : "Material Receipt";
|
||||||
|
|
||||||
if (disable_quick_entry) {
|
if (disable_quick_entry) {
|
||||||
open_stock_entry(item, warehouse, entry_type);
|
open_stock_entry(item, warehouse, entry_type);
|
||||||
@ -63,11 +63,19 @@ erpnext.stock.ItemDashboard = class ItemDashboard {
|
|||||||
function open_stock_entry(item, warehouse, entry_type) {
|
function open_stock_entry(item, warehouse, entry_type) {
|
||||||
frappe.model.with_doctype('Stock Entry', function () {
|
frappe.model.with_doctype('Stock Entry', function () {
|
||||||
var doc = frappe.model.get_new_doc('Stock Entry');
|
var doc = frappe.model.get_new_doc('Stock Entry');
|
||||||
if (entry_type) doc.stock_entry_type = entry_type;
|
if (entry_type) {
|
||||||
|
doc.stock_entry_type = entry_type;
|
||||||
|
}
|
||||||
|
|
||||||
var row = frappe.model.add_child(doc, 'items');
|
var row = frappe.model.add_child(doc, 'items');
|
||||||
row.item_code = item;
|
row.item_code = item;
|
||||||
|
|
||||||
|
if (entry_type === "Material Transfer") {
|
||||||
row.s_warehouse = warehouse;
|
row.s_warehouse = warehouse;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
row.t_warehouse = warehouse;
|
||||||
|
}
|
||||||
|
|
||||||
frappe.set_route('Form', doc.doctype, doc.name);
|
frappe.set_route('Form', doc.doctype, doc.name);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1662,6 +1662,48 @@ class TestStockEntry(FrappeTestCase):
|
|||||||
|
|
||||||
self.assertRaises(BatchExpiredError, se.save)
|
self.assertRaises(BatchExpiredError, se.save)
|
||||||
|
|
||||||
|
def test_negative_stock_reco(self):
|
||||||
|
from erpnext.controllers.stock_controller import BatchExpiredError
|
||||||
|
from erpnext.stock.doctype.batch.test_batch import make_new_batch
|
||||||
|
|
||||||
|
frappe.db.set_single_value("Stock Settings", "allow_negative_stock", 0)
|
||||||
|
|
||||||
|
item_code = "Test Negative Item - 001"
|
||||||
|
item_doc = create_item(item_code=item_code, is_stock_item=1, valuation_rate=10)
|
||||||
|
|
||||||
|
make_stock_entry(
|
||||||
|
item_code=item_code,
|
||||||
|
posting_date=add_days(today(), -3),
|
||||||
|
posting_time="00:00:00",
|
||||||
|
purpose="Material Receipt",
|
||||||
|
qty=10,
|
||||||
|
to_warehouse="_Test Warehouse - _TC",
|
||||||
|
do_not_save=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
make_stock_entry(
|
||||||
|
item_code=item_code,
|
||||||
|
posting_date=today(),
|
||||||
|
posting_time="00:00:00",
|
||||||
|
purpose="Material Receipt",
|
||||||
|
qty=8,
|
||||||
|
from_warehouse="_Test Warehouse - _TC",
|
||||||
|
do_not_save=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
sr_doc = create_stock_reconciliation(
|
||||||
|
purpose="Stock Reconciliation",
|
||||||
|
posting_date=add_days(today(), -3),
|
||||||
|
posting_time="00:00:00",
|
||||||
|
item_code=item_code,
|
||||||
|
warehouse="_Test Warehouse - _TC",
|
||||||
|
valuation_rate=10,
|
||||||
|
qty=7,
|
||||||
|
do_not_submit=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertRaises(frappe.ValidationError, sr_doc.submit)
|
||||||
|
|
||||||
|
|
||||||
def make_serialized_item(**args):
|
def make_serialized_item(**args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
|
|||||||
@ -1050,7 +1050,7 @@ class update_entries_after(object):
|
|||||||
frappe.db.set_value("Bin", bin_name, updated_values, update_modified=True)
|
frappe.db.set_value("Bin", bin_name, updated_values, update_modified=True)
|
||||||
|
|
||||||
|
|
||||||
def get_previous_sle_of_current_voucher(args, exclude_current_voucher=False):
|
def get_previous_sle_of_current_voucher(args, operator="<", exclude_current_voucher=False):
|
||||||
"""get stock ledger entries filtered by specific posting datetime conditions"""
|
"""get stock ledger entries filtered by specific posting datetime conditions"""
|
||||||
|
|
||||||
args["time_format"] = "%H:%i:%s"
|
args["time_format"] = "%H:%i:%s"
|
||||||
@ -1076,13 +1076,13 @@ def get_previous_sle_of_current_voucher(args, exclude_current_voucher=False):
|
|||||||
posting_date < %(posting_date)s or
|
posting_date < %(posting_date)s or
|
||||||
(
|
(
|
||||||
posting_date = %(posting_date)s and
|
posting_date = %(posting_date)s and
|
||||||
time_format(posting_time, %(time_format)s) < time_format(%(posting_time)s, %(time_format)s)
|
time_format(posting_time, %(time_format)s) {operator} time_format(%(posting_time)s, %(time_format)s)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
order by timestamp(posting_date, posting_time) desc, creation desc
|
order by timestamp(posting_date, posting_time) desc, creation desc
|
||||||
limit 1
|
limit 1
|
||||||
for update""".format(
|
for update""".format(
|
||||||
voucher_condition=voucher_condition
|
operator=operator, voucher_condition=voucher_condition
|
||||||
),
|
),
|
||||||
args,
|
args,
|
||||||
as_dict=1,
|
as_dict=1,
|
||||||
@ -1375,7 +1375,7 @@ def get_stock_reco_qty_shift(args):
|
|||||||
stock_reco_qty_shift = flt(args.actual_qty)
|
stock_reco_qty_shift = flt(args.actual_qty)
|
||||||
else:
|
else:
|
||||||
# reco is being submitted
|
# reco is being submitted
|
||||||
last_balance = get_previous_sle_of_current_voucher(args, exclude_current_voucher=True).get(
|
last_balance = get_previous_sle_of_current_voucher(args, "<=", exclude_current_voucher=True).get(
|
||||||
"qty_after_transaction"
|
"qty_after_transaction"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user