<?php

  // Build on top of reports module
  AngieApplication::useController('reports', REPORTS_FRAMEWORK_INJECT_INTO);

  /**
   * Tracking reports controller implementation
   *
   * @package activeCollab.modules.tracking
   * @subpackage controllers
   */
  class TrackingReportsController extends ReportsController {
    
    /**
     * Active tracking report
     *
     * @var TrackingReport
     */
    protected $active_tracking_report;
    
    /**
     * Invoice controller delegate
     * 
     * @var InvoiceBasedOnController
     */
    protected $invoice_delegate;
    
    /**
     * Construct controller
     *
     * @param Request $parent
     * @param mixed $context
     */
    function __construct($parent, $context = null) {
      parent::__construct($parent, $context);
      
      if(AngieApplication::isModuleLoaded('invoicing') && $this->getControllerName() == 'tracking_reports') {
        $this->invoice_delegate = $this->__delegate('invoice_based_on', INVOICING_MODULE, 'tracking_report');
      } // if
    } // __construct
    
    /**
     * Prepare controller
     */
    function __before() {
      parent::__before();
      
      if($this->logged_user->isProjectManager() || $this->logged_user->isPeopleManager() || $this->logged_user->isFinancialManager()) {
        $report_id = $this->request->getId('tracking_report_id');
        if($report_id) {
          $this->active_tracking_report = TrackingReports::findById($report_id);
        } // if
        
        if($this->active_tracking_report instanceof TrackingReport) {
          $this->wireframe->breadcrumbs->add('tracking_report', $this->active_tracking_report->getName(), $this->active_tracking_report->getViewUrl());
        } else {
          $this->active_tracking_report = new TrackingReport();
        } // if
        
        if(AngieApplication::isModuleLoaded('invoicing') && $this->invoice_delegate instanceof InvoiceBasedOnController) {
          $this->invoice_delegate->__setProperties(array(
      			'active_object' => &$this->active_tracking_report
      	  ));
        } // if
        
        $this->response->assign('active_tracking_report', $this->active_tracking_report);
      } else {
        $this->response->forbidden();
      } // if
    } // __construct
    
    /**
     * Show tracking report form and options
     */
    function index() {
      $report = new TrackingReport();
      
      $this->response->assign(array(
        'tracking_reports' => TrackingReports::find(), 
        'users' => Users::getForSelect($this->logged_user),
        'companies' => Companies::getIdNameMap(null, STATE_VISIBLE),
        'projects' => Projects::getIdNameMap($this->logged_user, STATE_ARCHIVED, null, null, true),
        'project_categories' => Categories::getIdNameMap(null, 'ProjectCategory'), 
        'job_types' => JobTypes::getIdNameMap(), 
        'expense_categories' => ExpenseCategories::getIdNameMap(), 
        'currencies' => Currencies::getIdDetailsMap(),
      ));
      
      if(AngieApplication::isModuleLoaded('invoicing') && Invoices::canAdd($this->logged_user)) {
        $this->response->assign('invoice_based_on_url', $report->invoice()->getUrl());
      } else {
        $this->response->assign('invoice_based_on_url', false);
      } // if
    } // index
    
    /**
     * Prepare and run a report based on attributes provided
     */
    function run() {
      if ($this->request->isPrintCall() || $this->request->isWebBrowser()) {
        $records = null;

        try {
          $report = new TrackingReport();
          $report->setAttributes($this->request->get('filter'));
          
          $records = $report->run($this->logged_user);
        } catch(DataFilterConditionsError $e) {
          $records = null;
        } catch(Exception $e) {
          $this->response->exception($e);
        } // try
        
        // Printer
        if ($this->request->isPrintCall()) {
          $this->response->assign(array(
            'report' => $report, 
            'records' => $records,
            'currencies' => Currencies::getIdDetailsMap(),
          ));
          
        // Web browser
        } elseif($this->request->isWebBrowser() && $this->request->isAsyncCall()) {
          $this->response->respondWithData($records);
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // run
    
    /**
     * Run a report and export it to file
     */
    function export() {
      if($this->request->isAsyncCall()) {
        $report = new TrackingReport();
        $report->setAttributes($this->request->get('filter'));
        
        try {
          $csv = $report->runToCsv($this->logged_user);
          
          if($csv) {
            $this->response->respondWithFileDownload($csv, BaseHttpResponse::CSV, 'report-result.csv', true);
          } else {
            $this->response->respondWithContentDownload('', BaseHttpResponse::CSV, 'report-result.csv');
          } // if
        } catch(Exception $e) {
          $this->response->exception($e);
        } // try
      } else {
        $this->response->badRequest();
      } // if
    } // export
    
    /**
     * Show single report
     */
    function report() {
      if($this->request->isApiCall()) {
        if($this->active_tracking_report->isLoaded()) {
          if($this->active_tracking_report->canView($this->logged_user)) {
            $this->response->respondWithData($this->active_tracking_report->run($this->logged_user));
          } else {
            $this->response->forbidden();
          } // if
        } else {
          $this->response->notFound();
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // report
    
    /**
     * Create new report
     */
    function add() {
      if(($this->request->isAsyncCall() || $this->request->isApiCall()) && $this->request->isSubmitted()) {
        if(TrackingReports::canAdd($this->logged_user)) {
          try {
            $this->active_tracking_report->setAttributes($this->request->post('filter'));
            $this->active_tracking_report->save();
            
            $this->response->respondWithData($this->active_tracking_report, array('as' => 'report'));
          } catch(Exception $e) {
            $this->response->exception($e);
          } // try
        } else {
          $this->response->forbidden();
        } // if
      } else {
        $this->response->notFound();
      } // if
    } // add
    
    /**
     * Update existing report
     */
    function edit() {
      if(($this->request->isAsyncCall() || $this->request->isApiCall()) && $this->request->isSubmitted()) {
        if($this->active_tracking_report->isLoaded()) {
          if($this->active_tracking_report->canEdit($this->logged_user)) {
            try {
              $this->active_tracking_report->setAttributes($this->request->post('filter'));
              $this->active_tracking_report->save();
              
              $this->response->respondWithData($this->active_tracking_report, array('as' => 'report'));
            } catch(Exception $e) {
              $this->response->exception($e);
            } // try
          } else {
            $this->response->forbidden();
          } // if
        } else {
          $this->response->notFound();
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // edit
    
    /**
     * Delete existing report
     */
    function delete() {
      if(($this->request->isAsyncCall() || $this->request->isApiCall()) && $this->request->isSubmitted()) {
        if($this->active_tracking_report->isLoaded()) {
          if($this->active_tracking_report->canDelete($this->logged_user)) {
            try {
              $this->active_tracking_report->delete();
              $this->response->ok();
            } catch(Exception $e) {
              $this->response->exception($e);
            } // try
          } else {
            $this->response->forbidden();
          } // if
        } else {
          $this->response->notFound();
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // delete
    
    /**
     * Displays a chart with tracked time  
     */
    function time_report() {
    	$this->response->assign(array(
    		'records' => TimeRecords::find(array('order' => 'record_date ASC')),
    	));
    } // time_report
    
    /**
     * Displays a chart with expenses  
     */
    function expenses_report() {
    	$this->response->assign(array(
    		'records' => Expenses::find()
    	));
    } // expenses_report
    
    /**
     * Show budget vs cost report
     */
    function budget_vs_cost() {
      $this->response->assign('projects', Projects::findActiveByUserWithBudget($this->logged_user, true));
    } // budget_vs_cost

    /**
     * Estiamted vs tracked time report
     */
    function estimated_vs_tracked_time() {
      $this->response->assign('projects_exist', count($this->logged_user->projects()->getIds()));
    } // estimated_vs_tracked_time

    /**
     * Run estimated vs tracked time report
     */
    function estimated_vs_tracked_time_run() {
      if($this->request->isAsyncCall()) {
        $project = $this->request->get('project_id') ? Projects::findById($this->request->get('project_id')) : null;

        if($project instanceof Project) {
          $assignments = null;

          try {
            $filter = new AssignmentFilter();
            $filter->filterByProjects(array($project->getId()));
            $filter->setIncludeTrackingData(true);
            $filter->setGroupBy($this->request->get('group_by'));

            $assignments = $filter->run($this->logged_user);
          } catch(DataFilterConditionsError $e) {
            $assignments = null;
          } catch(Exception $e) {
            $this->response->exception($e);
          } // try

          $this->response->assign(array(
            'assignments' => $assignments,
            'labels' => Labels::getIdDetailsMap('AssignmentLabel'),
            'project_slugs' => Projects::getIdSlugMap(),
            'task_url' => Router::assemble('project_task', array('project_slug' => '--PROJECT_SLUG--', 'task_id' => '--TASK_ID--')),
            'job_types' => JobTypes::getIdNameMap(),
          ));
        } else {
          $this->response->notFound();
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // estimated_vs_tracked_time_run
    
  }