fix: Dependant sle logic fixes (#24489)
* fix: Dependant sle logic fixes * fix: negative qty validation * fix: Travis fixes
This commit is contained in:
parent
7d64a291b8
commit
7177579051
@ -544,7 +544,7 @@ class TestWorkOrder(unittest.TestCase):
|
||||
expected_qty = {"_Test Item": 2, "_Test Item Home Desktop 100": 4}
|
||||
for row in ste3.items:
|
||||
self.assertEquals(row.qty, expected_qty.get(row.item_code))
|
||||
|
||||
ste_cancel_list.reverse()
|
||||
for ste_doc in ste_cancel_list:
|
||||
ste_doc.cancel()
|
||||
|
||||
@ -586,7 +586,7 @@ class TestWorkOrder(unittest.TestCase):
|
||||
for ste_row in ste2.items:
|
||||
if itemwise_qty.get(ste_row.item_code) and ste_row.s_warehouse:
|
||||
self.assertEquals(ste_row.qty, itemwise_qty.get(ste_row.item_code) / 2)
|
||||
|
||||
ste_cancel_list.reverse()
|
||||
for ste_doc in ste_cancel_list:
|
||||
ste_doc.cancel()
|
||||
|
||||
|
@ -26,7 +26,6 @@ class TestUnitedStates(unittest.TestCase):
|
||||
make_payment_entry_to_irs_1099_supplier()
|
||||
filters = frappe._dict({"fiscal_year": "_Test Fiscal Year 2016", "company": "_Test Company 1"})
|
||||
columns, data = execute_1099_report(filters)
|
||||
print(columns, data)
|
||||
expected_row = {'supplier': '_US 1099 Test Supplier',
|
||||
'supplier_group': 'Services',
|
||||
'payments': 100.0,
|
||||
|
@ -98,8 +98,6 @@ class ItemGroup(NestedSet, WebsiteGenerator):
|
||||
context.field_filters = filter_engine.get_field_filters()
|
||||
context.attribute_filters = filter_engine.get_attribute_fitlers()
|
||||
|
||||
print(context.field_filters, context.attribute_filters)
|
||||
|
||||
context.update({
|
||||
"parents": get_parent_item_groups(self.parent_item_group),
|
||||
"title": self.name
|
||||
|
@ -16,7 +16,6 @@ class ProductFiltersBuilder:
|
||||
|
||||
def get_field_filters(self):
|
||||
filter_fields = [row.fieldname for row in self.doc.filter_fields]
|
||||
print('FILTERS', self.doc.filter_fields)
|
||||
|
||||
meta = frappe.get_meta('Item')
|
||||
fields = [df for df in meta.fields if df.fieldname in filter_fields]
|
||||
@ -53,7 +52,6 @@ class ProductFiltersBuilder:
|
||||
|
||||
def get_attribute_fitlers(self):
|
||||
attributes = [row.attribute for row in self.doc.filter_attributes]
|
||||
print('ATTRIBUTES', attributes)
|
||||
attribute_docs = [
|
||||
frappe.get_doc('Item Attribute', attribute) for attribute in attributes
|
||||
]
|
||||
|
@ -17,7 +17,7 @@ class Bin(Document):
|
||||
'''Called from erpnext.stock.utils.update_bin'''
|
||||
self.update_qty(args)
|
||||
if args.get("actual_qty") or args.get("voucher_type") == "Stock Reconciliation":
|
||||
from erpnext.stock.stock_ledger import update_entries_after, update_qty_in_future_sle
|
||||
from erpnext.stock.stock_ledger import update_entries_after, validate_negative_qty_in_future_sle
|
||||
|
||||
if not args.get("posting_date"):
|
||||
args["posting_date"] = nowdate()
|
||||
@ -37,8 +37,8 @@ class Bin(Document):
|
||||
"sle_id": args.name
|
||||
}, allow_negative_stock=allow_negative_stock, via_landed_cost_voucher=via_landed_cost_voucher)
|
||||
|
||||
# Update qty_after_transaction in future SLEs of this item and warehouse
|
||||
update_qty_in_future_sle(args)
|
||||
# Validate negative qty in future transactions
|
||||
validate_negative_qty_in_future_sle(args)
|
||||
|
||||
def update_qty(self, args):
|
||||
# update the stock values (for current quantities)
|
||||
|
@ -31,7 +31,7 @@ frappe.ui.form.on('Repost Item Valuation', {
|
||||
}
|
||||
},
|
||||
refresh: function(frm) {
|
||||
if (frm.doc.status == "Failed") {
|
||||
if (frm.doc.status == "Failed" && frm.doc.docstatus==1) {
|
||||
frm.add_custom_button(__('Restart'), function () {
|
||||
frm.trigger("restart_reposting");
|
||||
}).addClass("btn-primary");
|
||||
|
@ -62,7 +62,7 @@ def make_entry(args, allow_negative_stock=False, via_landed_cost_voucher=False):
|
||||
sle.submit()
|
||||
return sle
|
||||
|
||||
def repost_future_sle(args=None, voucher_type=None, voucher_no=None, allow_negative_stock=False, via_landed_cost_voucher=False):
|
||||
def repost_future_sle(args=None, voucher_type=None, voucher_no=None, allow_negative_stock=None, via_landed_cost_voucher=False):
|
||||
if not args and voucher_type and voucher_no:
|
||||
args = get_args_for_voucher(voucher_type, voucher_no)
|
||||
|
||||
@ -181,7 +181,7 @@ class update_entries_after(object):
|
||||
self.process_sle(sle)
|
||||
|
||||
if sle.dependant_sle_voucher_detail_no:
|
||||
self.get_dependent_entries_to_fix(entries_to_fix, sle)
|
||||
entries_to_fix = self.get_dependent_entries_to_fix(entries_to_fix, sle)
|
||||
|
||||
if self.exceptions:
|
||||
self.raise_exceptions()
|
||||
@ -221,13 +221,15 @@ class update_entries_after(object):
|
||||
excluded_sle=sle.name)
|
||||
|
||||
if not dependant_sle:
|
||||
return
|
||||
return entries_to_fix
|
||||
elif dependant_sle.item_code == self.item_code and dependant_sle.warehouse == self.args.warehouse:
|
||||
return
|
||||
elif dependant_sle.item_code != self.item_code \
|
||||
and (dependant_sle.item_code, dependant_sle.warehouse) not in self.new_items:
|
||||
self.new_items[(dependant_sle.item_code, dependant_sle.warehouse)] = dependant_sle
|
||||
return
|
||||
return entries_to_fix
|
||||
elif dependant_sle.item_code != self.item_code:
|
||||
if (dependant_sle.item_code, dependant_sle.warehouse) not in self.new_items:
|
||||
self.new_items[(dependant_sle.item_code, dependant_sle.warehouse)] = dependant_sle
|
||||
return entries_to_fix
|
||||
elif dependant_sle.item_code == self.item_code and dependant_sle.warehouse in self.data:
|
||||
return entries_to_fix
|
||||
|
||||
self.initialize_previous_data(dependant_sle)
|
||||
|
||||
@ -236,7 +238,7 @@ class update_entries_after(object):
|
||||
future_sle_for_dependant = list(self.get_sle_after_datetime(args))
|
||||
|
||||
entries_to_fix.extend(future_sle_for_dependant)
|
||||
entries_to_fix = sorted(entries_to_fix, key=lambda k: k['timestamp'])
|
||||
return sorted(entries_to_fix, key=lambda k: k['timestamp'])
|
||||
|
||||
def process_sle(self, sle):
|
||||
# previous sle data for this warehouse
|
||||
@ -612,11 +614,11 @@ class update_entries_after(object):
|
||||
frappe.local.flags.currently_saving):
|
||||
|
||||
msg = _("{0} units of {1} needed in {2} to complete this transaction.").format(
|
||||
abs(deficiency), frappe.get_desk_link('Item', self.item_code),
|
||||
abs(deficiency), frappe.get_desk_link('Item', exceptions[0]["item_code"]),
|
||||
frappe.get_desk_link('Warehouse', warehouse))
|
||||
else:
|
||||
msg = _("{0} units of {1} needed in {2} on {3} {4} for {5} to complete this transaction.").format(
|
||||
abs(deficiency), frappe.get_desk_link('Item', self.item_code),
|
||||
abs(deficiency), frappe.get_desk_link('Item', exceptions[0]["item_code"]),
|
||||
frappe.get_desk_link('Warehouse', warehouse),
|
||||
exceptions[0]["posting_date"], exceptions[0]["posting_time"],
|
||||
frappe.get_desk_link(exceptions[0]["voucher_type"], exceptions[0]["voucher_no"]))
|
||||
@ -761,25 +763,6 @@ def get_valuation_rate(item_code, warehouse, voucher_type, voucher_no,
|
||||
|
||||
return valuation_rate
|
||||
|
||||
def update_qty_in_future_sle(args, allow_negative_stock=None):
|
||||
frappe.db.sql("""
|
||||
update `tabStock Ledger Entry`
|
||||
set qty_after_transaction = qty_after_transaction + {qty}
|
||||
where
|
||||
item_code = %(item_code)s
|
||||
and warehouse = %(warehouse)s
|
||||
and voucher_no != %(voucher_no)s
|
||||
and is_cancelled = 0
|
||||
and (timestamp(posting_date, posting_time) > timestamp(%(posting_date)s, %(posting_time)s)
|
||||
or (
|
||||
timestamp(posting_date, posting_time) = timestamp(%(posting_date)s, %(posting_time)s)
|
||||
and creation > %(creation)s
|
||||
)
|
||||
)
|
||||
""".format(qty=args.actual_qty), args)
|
||||
|
||||
validate_negative_qty_in_future_sle(args, allow_negative_stock)
|
||||
|
||||
def validate_negative_qty_in_future_sle(args, allow_negative_stock=None):
|
||||
allow_negative_stock = allow_negative_stock \
|
||||
or cint(frappe.db.get_single_value("Stock Settings", "allow_negative_stock"))
|
||||
@ -808,6 +791,7 @@ def get_future_sle_with_negative_qty(args):
|
||||
and voucher_no != %(voucher_no)s
|
||||
and timestamp(posting_date, posting_time) >= timestamp(%(posting_date)s, %(posting_time)s)
|
||||
and is_cancelled = 0
|
||||
and qty_after_transaction < 0
|
||||
and qty_after_transaction + {0} < 0
|
||||
order by timestamp(posting_date, posting_time) asc
|
||||
limit 1
|
||||
""", args, as_dict=1)
|
||||
""".format(args.actual_qty), args, as_dict=1)
|
@ -147,8 +147,7 @@ class IssueAnalytics(object):
|
||||
|
||||
self.entries = frappe.db.get_all('Issue',
|
||||
fields=[self.field_map.get(self.filters.based_on), 'name', 'opening_date'],
|
||||
filters=filters,
|
||||
debug=1
|
||||
filters=filters
|
||||
)
|
||||
|
||||
def get_common_filters(self):
|
||||
|
@ -17,9 +17,12 @@ class TestIssueAnalytics(unittest.TestCase):
|
||||
|
||||
current_month_date = getdate()
|
||||
last_month_date = add_months(current_month_date, -1)
|
||||
self.current_month = str(months[current_month_date.month - 1]).lower() + '_' + str(current_month_date.year)
|
||||
self.last_month = str(months[last_month_date.month - 1]).lower() + '_' + str(last_month_date.year)
|
||||
|
||||
self.current_month = str(months[current_month_date.month - 1]).lower()
|
||||
self.last_month = str(months[last_month_date.month - 1]).lower()
|
||||
if current_month_date.year != last_month_date.year:
|
||||
self.current_month += '_' + str(current_month_date.year)
|
||||
self.last_month += '_' + str(last_month_date.year)
|
||||
|
||||
def test_issue_analytics(self):
|
||||
create_service_level_agreements_for_issues()
|
||||
create_issue_types()
|
||||
|
@ -12,7 +12,6 @@ def get_context(context):
|
||||
search = frappe.form_dict.search
|
||||
field_filters = frappe.parse_json(frappe.form_dict.field_filters)
|
||||
attribute_filters = frappe.parse_json(frappe.form_dict.attribute_filters)
|
||||
print(field_filters, attribute_filters)
|
||||
start = frappe.parse_json(frappe.form_dict.start)
|
||||
else:
|
||||
search = field_filters = attribute_filters = None
|
||||
@ -30,8 +29,6 @@ def get_context(context):
|
||||
context.field_filters = filter_engine.get_field_filters()
|
||||
context.attribute_filters = filter_engine.get_attribute_fitlers()
|
||||
|
||||
print(context.field_filters, context.attribute_filters)
|
||||
|
||||
context.product_settings = product_settings
|
||||
context.body_class = "product-page"
|
||||
context.page_length = product_settings.products_per_page or 20
|
||||
|
Loading…
Reference in New Issue
Block a user