diff --git a/BookingSystem/api.py b/BookingSystem/api.py index cf153ab..e9064c6 100644 --- a/BookingSystem/api.py +++ b/BookingSystem/api.py @@ -170,6 +170,25 @@ def book_equipment() -> flask.Response: return flask.Response(f'Utstyret ble utlevert til {user.get(userid).get("name")}.', status=200) +@api.route('/book/postpone', methods=['POST']) +@login_required(admin_only=True) +@handle_api_exception +def postpone_due_date() -> flask.Response: + """Postpone the due date for an item.""" + # START: Validation + validation_map = { + 'item_id': VALIDATORS.ID, + 'days': VALIDATORS.INT, + 'days_minmax': MINMAX(MIN_DAYS, MAX_DAYS), + } + form = sanitize(validation_map, flask.request.form) + # END: Validation + item_id = form.get('item_id') + days = int(form.get('days')) + inventory.postpone_due_date(item_id=item_id, days=days) + return flask.Response(f'Fristen for {item_id} ble utsatt med {days} {"dager" if days > 1 else "dag"}.', status=200) + + @api.route('/return/', methods=['POST']) @login_required(admin_only=True) @handle_api_exception diff --git a/BookingSystem/inventory.py b/BookingSystem/inventory.py index 795cdf5..d2520ec 100644 --- a/BookingSystem/inventory.py +++ b/BookingSystem/inventory.py @@ -305,3 +305,24 @@ def register_in(item_id: str) -> None: con.close() _update_last_seen(item_id) audits.audit('REG_IN', f'{item_id} er nå tilgjengelig.') + + +def postpone_due_date(item_id: str, days: int) -> None: + """Postpone the due date of the item with the given ID by the given number of days.""" + item = get(item_id) + if item.available: + raise APIException(f'{item_id} er ikke utlånt.') + due_date = datetime.now() + timedelta(days=days) + + con = sqlite3.connect(DATABASE) + try: + sql = 'UPDATE inventory SET order_due_date=:order_due_date WHERE id=:id' + con.execute(sql, {'id': item_id, 'order_due_date': due_date}) + con.commit() + logger.info(f'{item_id} har fått utsatt frist til {due_date}.') + except sqlite3.IntegrityError: + logger.error(f'{item_id} eksisterer ikke. (postpone)') + raise APIException(f'{item_id} eksisterer ikke.') + finally: + con.close() + audits.audit('POSTPONE', f'{item_id} har fått utsatt frist til {due_date:%d.%m.%Y} ({item.lender}).') diff --git a/BookingSystem/sanitizer.py b/BookingSystem/sanitizer.py index bbb96c2..a11e9da 100644 --- a/BookingSystem/sanitizer.py +++ b/BookingSystem/sanitizer.py @@ -46,6 +46,7 @@ def __str__(self): def _sanitize_form(sanitization_map: dict[any: VALIDATORS | MINMAX], form, data: dict = dict) -> bool: """Sanitize a form based on a sanitization map.""" + def id_pattern(fkey: str) -> bool: # Check if the ID/name is valid r = re.compile(REGEX_ID) @@ -152,8 +153,8 @@ def groupname(text: str) -> bool: # Check if the value is between the min and max mn, mx = sanitizer if not mn <= int(form.get(key[:-7])) <= mx: - logger.debug(f'Invalid minmax for {key} ({form.get(key)})') - raise APIException(f'Tallverdien er ikke mellom {mn} og {mx} ({form.get(key)})') + logger.debug(f'Invalid minmax for {key} ({form.get(key[:-7])})') + raise APIException(f'Tallverdien er ikke mellom {mn} og {mx} ({form.get(key[:-7])})') # Passed all checks! logger.debug(f'Validated {key} ({sanitizer}, {form.get(key)})') diff --git a/BookingSystem/templates/audits.html b/BookingSystem/templates/audits.html index 996c2a6..0d773e4 100644 --- a/BookingSystem/templates/audits.html +++ b/BookingSystem/templates/audits.html @@ -34,6 +34,12 @@

Her kan du søke i loggen etter forlatt utstyr, hva skjedde med det?

+
  • + + +