diff --git a/brewman/__init__.py b/brewman/__init__.py index 70e00b6a..a0484a65 100644 --- a/brewman/__init__.py +++ b/brewman/__init__.py @@ -52,6 +52,7 @@ def main(global_config, **settings): config.add_route('api_dashboard', '/api/Dashboard') config.add_route('dashboard', '/Dashboard') + config.add_route('api_db_integrity', '/api/DbIntegrity') config.add_route('api_login', '/api/login') config.add_route('login', '/login') config.add_route('logout', '/logout') diff --git a/brewman/static/partial/settings.html b/brewman/static/partial/settings.html index 694ae3b2..3965166b 100644 --- a/brewman/static/partial/settings.html +++ b/brewman/static/partial/settings.html @@ -128,4 +128,12 @@ class="glyphicon glyphicon-paperclip"> +
+ + +
+ +
+
diff --git a/brewman/static/scripts/settings.js b/brewman/static/scripts/settings.js index 9a2092d2..9adc9c9e 100644 --- a/brewman/static/scripts/settings.js +++ b/brewman/static/scripts/settings.js @@ -121,6 +121,16 @@ var SettingsController = ['$scope', '$http', 'asDateFilter', '$modal', 'lockInfo $scope.products = function ($viewValue) { return Product.autocomplete({term: $viewValue, count: 20}).$promise; }; + + $scope.checkDb = function () { + return $http.post('/api/DbIntegrity', {}). + success(function (data) { + $scope.toasts.push({Type: 'Success', Message: ''}); + }). + error(function (errorMessage) { + $scope.toasts.push({Type: 'Danger', Message: errorMessage}); + }); + }; }]; SettingsController.resolve = { diff --git a/brewman/views/Management/db_integrity.py b/brewman/views/Management/db_integrity.py new file mode 100644 index 00000000..5cb1e1b0 --- /dev/null +++ b/brewman/views/Management/db_integrity.py @@ -0,0 +1,35 @@ +from pyramid.view import view_config +from sqlalchemy import func, distinct, over, desc +import transaction +from brewman.models import DBSession + +from brewman.models.voucher import Attendance + + +@view_config(request_method='POST', route_name='api_db_integrity', renderer='json', permission='Authenticated') +def post_check_db(request): + info = {} + + duplicate_attendances = get_duplicate_attendances() + if duplicate_attendances > 0: + fix_duplicate_attendances(duplicate_attendances) + info['Duplicate Attendances Fixed'] = duplicate_attendances + transaction.commit() + return info + + +def get_duplicate_attendances(): + sub_query = DBSession.query( + over(distinct(func.first_value(Attendance.id)), partition_by=[Attendance.employee_id, Attendance.date]) + ).filter(Attendance.is_valid == True).subquery() + query = DBSession.query(func.count(Attendance.id)). \ + filter(~Attendance.id.in_(sub_query)). \ + filter(Attendance.is_valid == True) + return query.scalar() + + +def fix_duplicate_attendances(): + sub = DBSession.query(over(distinct(func.first_value(Attendance.id)), + partition_by=[Attendance.employee_id, Attendance.date], + order_by=desc(Attendance.creation_date))).filter(Attendance.is_valid == True).subquery() + DBSession.query(Attendance).filter(~Attendance.id.in_(sub)).filter(Attendance.is_valid == True).delete(False)