# Path: core/validation/validation.py
# class TSValidationError(Exception):
#     pass
# 
# def validate_request(collection, json_in):
#     validator(requests_schema[collection], format_checker=jsonschema.FormatChecker()).validate(json_in)
# 
# def sanitize_objectify_json(json_in):
#     """Sanitize string and convert _ids to ObjectId in JSON"""
#     return recursive_replace(json_in, _replace_function_sanitize_objectify_json)
# 
# def stringify_objectid_cursor(cursor_in):
#     """Convert ObjectId to string in JSON"""
#     
#     stringified = []
#     for json_in in cursor_in:
#         stringified.append(recursive_replace(json_in, _replace_function_stringify_objectid_json))
#     return stringified
# 
# Path: core/api/crud.py
# def get(collection, criteria_projection_order):
# def remove(collection, criterias = []):
# def add(collection, documents_list):
# def update(collection, document):
# 
# Path: core/validation/permissions.py
# def get_role_approval_step(group):
# 
#     # Approvation roles 
#     approvation_roles = [ s['approver'] if 'approver' in s else '' for s in conf_approval_flow ]
# 
#     # Administrator can see every expence, return 0
#     if group == 'administrator':
#         return 0
#     # Roles that can approves can see only expences >= owned step.
#     elif group in approvation_roles[1:-1]:
#         return approvation_roles.index(group)
#     # Else, return draft step 
#     else:
#         return len(approvation_roles)-1
# 
# def check_datamine_permissions(action, document):
#     # Get datamine permissions
#     
#     try:
#         restrictions = cherrypy.session['_ts_user']['restrictions'][action]
#     except (KeyError, TypeError):
#         restrictions = None
#         
#     if not restrictions:
#         raise TSValidationError("Access to '%s' is restricted for current user" % (action))
#     elif restrictions != True:
#         validator(restrictions, format_checker=jsonschema.FormatChecker()).validate(document)
# 
# Path: core/notifications/notifications.py
# def _get_recipients_of_expences_responsibles(expence_user_id, project_id, expence_id, expence_type, recipients_roles ):
# def notify_expence(project_expence, expence_type, approver):
# def get_pending():
# 
# Path: core/config.py



from core.validation.validation import TSValidationError, validate_request, sanitize_objectify_json, stringify_objectid_cursor
from core.api.crud import db
from bson.objectid import ObjectId
from core.validation.permissions import get_role_approval_step, check_datamine_permissions
from core.notifications import notifications
from core.config import schema 
import cherrypy, logging
                match_project_status = { '%s.status' % aggregation_type : { '$lt' : 0 } }
            else:
                match_project_status = { '$or' : [  { '%s.status' % aggregation_type : owner_status }, 
                                                    { '%s.status' % aggregation_type : 0 },
                                                    { '%s.status' % aggregation_type : { '$lt' : 0 } }
                                                ] } 

        # If project_id is not set, allows only managed_projects
        projects_requested = [ ObjectId(p) for p in sanified_criteria.get('projects_id', cherrypy.session['_ts_user']['managed_projects']) ]
        if projects_requested:
            match_project_status.update({ '_id' : { '$in' : projects_requested } })

        user_id = sanified_criteria.get('user_id')
        if user_id:
            match_project_status.update({ '%s.user_id' % aggregation_type : user_id })

        project_rename = { '%s.project_id' % aggregation_type : '$_id' }
        for key in schema['project']['properties'][aggregation_type]['items']['properties'].keys():
            project_rename['%s.%s' % (aggregation_type, key)] = 1

        aggregation_pipe = [  
                            { '$unwind' : '$%s' % aggregation_type },
                            { '$match' : match_project_status },
                            { '$project' : project_rename },
                            { '$group' : { '_id' : '$%s' % (aggregation_type) } },
                            { '$sort' : { '_id.start' : 1, '_id.date' : 1 } }
        ]

        cherrypy.log('%s' % (aggregation_pipe), context = 'TS.SEARCH_APPROVALS.aggregation_pipe', severity = logging.INFO)


# Path: core/validation/validation.py
# class TSValidationError(Exception):
#     pass
# 
# def validate_request(collection, json_in):
#     validator(requests_schema[collection], format_checker=jsonschema.FormatChecker()).validate(json_in)
# 
# def sanitize_objectify_json(json_in):
#     """Sanitize string and convert _ids to ObjectId in JSON"""
#     return recursive_replace(json_in, _replace_function_sanitize_objectify_json)
# 
# def stringify_objectid_cursor(cursor_in):
#     """Convert ObjectId to string in JSON"""
#     
#     stringified = []
#     for json_in in cursor_in:
#         stringified.append(recursive_replace(json_in, _replace_function_stringify_objectid_json))
#     return stringified
# 
# Path: core/api/crud.py
# def get(collection, criteria_projection_order):
# def remove(collection, criterias = []):
# def add(collection, documents_list):
# def update(collection, document):
# 
# Path: core/validation/permissions.py
# def get_role_approval_step(group):
# 
#     # Approvation roles 
#     approvation_roles = [ s['approver'] if 'approver' in s else '' for s in conf_approval_flow ]
# 
#     # Administrator can see every expence, return 0
#     if group == 'administrator':
#         return 0
#     # Roles that can approves can see only expences >= owned step.
#     elif group in approvation_roles[1:-1]:
#         return approvation_roles.index(group)
#     # Else, return draft step 
#     else:
#         return len(approvation_roles)-1
# 
# def check_datamine_permissions(action, document):
#     # Get datamine permissions
#     
#     try:
#         restrictions = cherrypy.session['_ts_user']['restrictions'][action]
#     except (KeyError, TypeError):
#         restrictions = None
#         
#     if not restrictions:
#         raise TSValidationError("Access to '%s' is restricted for current user" % (action))
#     elif restrictions != True:
#         validator(restrictions, format_checker=jsonschema.FormatChecker()).validate(document)
# 
# Path: core/notifications/notifications.py
# def _get_recipients_of_expences_responsibles(expence_user_id, project_id, expence_id, expence_type, recipients_roles ):
# def notify_expence(project_expence, expence_type, approver):
# def get_pending():
# 
# Path: core/config.py



# Path: core/api/approvals.py
from core.validation.validation import TSValidationError, validate_request, sanitize_objectify_json, stringify_objectid_cursor
from core.api.crud import db
from bson.objectid import ObjectId
from core.validation.permissions import get_role_approval_step, check_datamine_permissions
from core.notifications import notifications
from core.config import schema 
import cherrypy, logging

                match_project_status = { '%s.status' % aggregation_type : { '$lt' : 0 } }
            else:
                match_project_status = { '$or' : [  { '%s.status' % aggregation_type : owner_status }, 
                                                    { '%s.status' % aggregation_type : 0 },
                                                    { '%s.status' % aggregation_type : { '$lt' : 0 } }
                                                ] } 

        # If project_id is not set, allows only managed_projects
        projects_requested = [ ObjectId(p) for p in sanified_criteria.get('projects_id', cherrypy.session['_ts_user']['managed_projects']) ]
        if projects_requested:
            match_project_status.update({ '_id' : { '$in' : projects_requested } })

        user_id = sanified_criteria.get('user_id')
        if user_id:
            match_project_status.update({ '%s.user_id' % aggregation_type : user_id })

        project_rename = { '%s.project_id' % aggregation_type : '$_id' }
        for key in schema['project']['properties'][aggregation_type]['items']['properties'].keys():
            project_rename['%s.%s' % (aggregation_type, key)] = 1

        aggregation_pipe = [  
                            { '$unwind' : '$%s' % aggregation_type },
                            { '$match' : match_project_status },
                            { '$project' : project_rename },
                            { '$group' : { '_id' : '$%s' % (aggregation_type) } },
                            { '$sort' : { '_id.start' : 1, '_id.date' : 1 } }
        ]

        cherrypy.log('%s' % (aggregation_pipe), context = 'TS.SEARCH_APPROVALS.aggregation_pipe', severity = logging.INFO)


        aggregation_result = db.project.aggregate(aggregation_pipe)