# 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 update_password_salt_user_list(collection, list_in):
#     
#     if collection == 'user':
#         for json_in in list_in:
#             update_password_salt_user_json(json_in)
#         
#     return list_in
# 
# def validate_json_list(collection, list_in):
#     
#     for json_in in list_in:    
#         # Validate json schema
#         validator(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
# 
# def stringify_objectid_list(list_in):
#     """Convert an ObjectId list to string list"""
#     return recursive_replace(list_in, _replace_function_stringify_objectid_list)
# 
# Path: core/validation/permissions.py
# 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/config.py

# 
# Path: core/api/crud.py
# def get(collection, criteria_projection_order):
# def remove(collection, criterias = []):
# def add(collection, documents_list):
# def update(collection, document):


from core.validation.validation import TSValidationError, validate_request, update_password_salt_user_list, validate_json_list, sanitize_objectify_json, stringify_objectid_cursor, stringify_objectid_list
from core.validation.permissions import check_datamine_permissions
from core.config import conf_reports, conf_approved
from bson.objectid import ObjectId
from core.api.crud import db
import cherrypy, logging
                                         'date' : '$date',
                                         'project' : '$users.hours.project',
                                         'isextra' : '$users.hours.isextra'
                                         }, 
                               'hours' : { '$sum' : '$users.hours.amount'  } 
                               } 
                              } 
                            ]
                           
        cherrypy.log(aggregation_pipe.__repr__(), context = 'TS.REPORT_PROJECTS.days_aggregation', severity = logging.INFO)
        
        return db.day.aggregate(aggregation_pipe)

    def _find_salaries_by_date_users(days_ids_list, end, start):
        # TODO: misure if _id filter now is superflous due to filter check during merge
        aggregation_pipe = [ { '$match' : { 'salary.cost' : { '$gt' : 0 }, '_id' : { '$in' : days_ids_list } } }, { '$project' : { 'salary.from' : 1, 'salary.to' : 1, 'salary.cost' : 1, '_id' : 1 } } ]
        cherrypy.log(aggregation_pipe.__repr__(), context = 'TS.REPORT_PROJECTS.salaries_aggregation', severity = logging.INFO)
        return db.user.aggregate(aggregation_pipe)

    def _find_incomes_by_project_date(projects_input, end, start):

        objectified_projects_input = [ ObjectId(p) for p in projects_input ]

        if projects_input:
            match_projects = { '_id' : { '$in' : objectified_projects_input }  }
        else:
            match_projects = {}

        aggregation_pipe = [ { '$match' : match_projects }, { '$unwind' : '$economics'}, { '$match' : { 'economics.period' : { '$gte' : start, '$lte' : end } } }, { '$group' : { '_id' : { 'project_id' : '$_id', 'period' : '$economics.period', 'budget' : '$economics.budget', 'extra' : '$economics.extra'   } } } ]
        cherrypy.log(aggregation_pipe.__repr__(), context = 'TS.REPORT_PROJECTS.incomes_aggregation', 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 update_password_salt_user_list(collection, list_in):
#     
#     if collection == 'user':
#         for json_in in list_in:
#             update_password_salt_user_json(json_in)
#         
#     return list_in
# 
# def validate_json_list(collection, list_in):
#     
#     for json_in in list_in:    
#         # Validate json schema
#         validator(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
# 
# def stringify_objectid_list(list_in):
#     """Convert an ObjectId list to string list"""
#     return recursive_replace(list_in, _replace_function_stringify_objectid_list)
# 
# Path: core/validation/permissions.py
# 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/config.py

# 
# 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/api/report_projects.py
from core.validation.validation import TSValidationError, validate_request, update_password_salt_user_list, validate_json_list, sanitize_objectify_json, stringify_objectid_cursor, stringify_objectid_list
from core.validation.permissions import check_datamine_permissions
from core.config import conf_reports, conf_approved
from bson.objectid import ObjectId
from core.api.crud import db
import cherrypy, logging

                                         'date' : '$date',
                                         'project' : '$users.hours.project',
                                         'isextra' : '$users.hours.isextra'
                                         }, 
                               'hours' : { '$sum' : '$users.hours.amount'  } 
                               } 
                              } 
                            ]
                           
        cherrypy.log(aggregation_pipe.__repr__(), context = 'TS.REPORT_PROJECTS.days_aggregation', severity = logging.INFO)
        
        return db.day.aggregate(aggregation_pipe)

    def _find_salaries_by_date_users(days_ids_list, end, start):
        # TODO: misure if _id filter now is superflous due to filter check during merge
        aggregation_pipe = [ { '$match' : { 'salary.cost' : { '$gt' : 0 }, '_id' : { '$in' : days_ids_list } } }, { '$project' : { 'salary.from' : 1, 'salary.to' : 1, 'salary.cost' : 1, '_id' : 1 } } ]
        cherrypy.log(aggregation_pipe.__repr__(), context = 'TS.REPORT_PROJECTS.salaries_aggregation', severity = logging.INFO)
        return db.user.aggregate(aggregation_pipe)

    def _find_incomes_by_project_date(projects_input, end, start):

        objectified_projects_input = [ ObjectId(p) for p in projects_input ]

        if projects_input:
            match_projects = { '_id' : { '$in' : objectified_projects_input }  }
        else:
            match_projects = {}

        aggregation_pipe = [ { '$match' : match_projects }, { '$unwind' : '$economics'}, { '$match' : { 'economics.period' : { '$gte' : start, '$lte' : end } } }, { '$group' : { '_id' : { 'project_id' : '$_id', 'period' : '$economics.period', 'budget' : '$economics.budget', 'extra' : '$economics.extra'   } } } ]
        cherrypy.log(aggregation_pipe.__repr__(), context = 'TS.REPORT_PROJECTS.incomes_aggregation', severity = logging.INFO)

        return db.project.aggregate(aggregation_pipe)