fix: option to limit reposting in certain timeslot (#27725)

This commit is contained in:
Ankush Menat 2021-10-01 13:05:36 +05:30 committed by GitHub
parent 9e08229b7b
commit a04f9c904e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 210 additions and 6 deletions

View File

@ -7,7 +7,7 @@ from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import cint, get_link_to_form, now, today
from frappe.utils import cint, get_link_to_form, get_weekday, now, nowtime, today
from frappe.utils.user import get_users_with_role
from rq.timeouts import JobTimeoutException
@ -126,6 +126,9 @@ def notify_error_to_stock_managers(doc, traceback):
frappe.sendmail(recipients=recipients, subject=subject, message=message)
def repost_entries():
if not in_configured_timeslot():
return
riv_entries = get_repost_item_valuation_entries()
for row in riv_entries:
@ -144,3 +147,26 @@ def get_repost_item_valuation_entries():
WHERE status in ('Queued', 'In Progress') and creation <= %s and docstatus = 1
ORDER BY timestamp(posting_date, posting_time) asc, creation asc
""", now(), as_dict=1)
def in_configured_timeslot(repost_settings=None, current_time=None):
"""Check if current time is in configured timeslot for reposting."""
if repost_settings is None:
repost_settings = frappe.get_cached_doc("Stock Reposting Settings")
if not repost_settings.limit_reposting_timeslot:
return True
if get_weekday() == repost_settings.limits_dont_apply_on:
return True
start_time = repost_settings.start_time
end_time = repost_settings.end_time
now_time = current_time or nowtime()
if start_time < end_time:
return end_time >= now_time >= start_time
else:
return now_time >= start_time or now_time <= end_time

View File

@ -1,11 +1,72 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
from __future__ import unicode_literals
# import frappe
import unittest
import frappe
from erpnext.stock.doctype.repost_item_valuation.repost_item_valuation import (
in_configured_timeslot,
)
class TestRepostItemValuation(unittest.TestCase):
pass
def test_repost_time_slot(self):
repost_settings = frappe.get_doc("Stock Reposting Settings")
positive_cases = [
{"limit_reposting_timeslot": 0},
{
"limit_reposting_timeslot": 1,
"start_time": "18:00:00",
"end_time": "09:00:00",
"current_time": "20:00:00",
},
{
"limit_reposting_timeslot": 1,
"start_time": "09:00:00",
"end_time": "18:00:00",
"current_time": "12:00:00",
},
{
"limit_reposting_timeslot": 1,
"start_time": "23:00:00",
"end_time": "09:00:00",
"current_time": "2:00:00",
},
]
for case in positive_cases:
repost_settings.update(case)
self.assertTrue(
in_configured_timeslot(repost_settings, case.get("current_time")),
msg=f"Exepcted true from : {case}",
)
negative_cases = [
{
"limit_reposting_timeslot": 1,
"start_time": "18:00:00",
"end_time": "09:00:00",
"current_time": "09:01:00",
},
{
"limit_reposting_timeslot": 1,
"start_time": "09:00:00",
"end_time": "18:00:00",
"current_time": "19:00:00",
},
{
"limit_reposting_timeslot": 1,
"start_time": "23:00:00",
"end_time": "09:00:00",
"current_time": "22:00:00",
},
]
for case in negative_cases:
repost_settings.update(case)
self.assertFalse(
in_configured_timeslot(repost_settings, case.get("current_time")),
msg=f"Exepcted false from : {case}",
)

View File

@ -0,0 +1,8 @@
// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('Stock Reposting Settings', {
// refresh: function(frm) {
// }
});

View File

@ -0,0 +1,72 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2021-10-01 10:56:30.814787",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"scheduling_section",
"limit_reposting_timeslot",
"start_time",
"end_time",
"limits_dont_apply_on"
],
"fields": [
{
"fieldname": "scheduling_section",
"fieldtype": "Section Break",
"label": "Scheduling"
},
{
"depends_on": "limit_reposting_timeslot",
"fieldname": "start_time",
"fieldtype": "Time",
"label": "Start Time",
"mandatory_depends_on": "limit_reposting_timeslot"
},
{
"depends_on": "limit_reposting_timeslot",
"fieldname": "end_time",
"fieldtype": "Time",
"label": "End Time",
"mandatory_depends_on": "limit_reposting_timeslot"
},
{
"depends_on": "limit_reposting_timeslot",
"fieldname": "limits_dont_apply_on",
"fieldtype": "Select",
"label": "Limits don't apply on",
"options": "\nMonday\nTuesday\nWednesday\nThursday\nFriday\nSaturday\nSunday"
},
{
"default": "0",
"fieldname": "limit_reposting_timeslot",
"fieldtype": "Check",
"label": "Limit timeslot for Stock Reposting"
}
],
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2021-10-01 11:27:28.981594",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock Reposting Settings",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"print": 1,
"read": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@ -0,0 +1,28 @@
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from frappe.model.document import Document
from frappe.utils import add_to_date, get_datetime, get_time_str, time_diff_in_hours
class StockRepostingSettings(Document):
def validate(self):
self.set_minimum_reposting_time_slot()
def set_minimum_reposting_time_slot(self):
"""Ensure that timeslot for reposting is at least 12 hours."""
if not self.limit_reposting_timeslot:
return
start_time = get_datetime(self.start_time)
end_time = get_datetime(self.end_time)
if start_time > end_time:
end_time = add_to_date(end_time, days=1, as_datetime=True)
diff = time_diff_in_hours(end_time, start_time)
if diff < 10:
self.end_time = get_time_str(add_to_date(self.start_time, hours=10, as_datetime=True))

View File

@ -0,0 +1,9 @@
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
# import frappe
import unittest
class TestStockRepostingSettings(unittest.TestCase):
pass