<?php

class BudgetController extends BaseController {

	protected $rules		 = array(
			'budgetNewOperationDate' => 'required|date_format:d.m.Y',
			'debPartnerAccountId'		 => 'required'
	);
	protected $messages	 = array(
			'debPartnerAccountId.required' => 'Выберите счет'
	);

	/**
	 * Constructor
	 */
	public function __construct() {
		// Establish Filters
		$this->beforeFilter('auth');

		if (Auth::check()) {
			$this->user			 = Auth::user();
			$this->projects	 = $this->user->budgetProjects;
		}
		$this->projectPrefix = 'budget';
		parent::__construct();

		$this->beforeFilter('csrf', array('only' => array('createOperation')));

		if ($this->user && $this->user->hasRole(Role::ROLE_BUDGET_VIEW_OPERATIONS)) {
			$this->beforeFilter('hasRole:' . Role::ROLE_BUDGET_VIEW_OPERATIONS, array('only' => 'index', 'operations', 'archiveOperations'));
		}
		elseif ($this->user && !$this->user->hasAnyRole(array(Role::ROLE_BUDGET, Role::ROLE_BUDGET_ACCOUNTANT))) {
			$this->beforeFilter('hasRole:' . Role::ROLE_BUDGET);
			$this->beforeFilter('hasRole:' . Role::ROLE_BUDGET_ACCOUNTANT);
		}
	}

	public function index() {
		$input = Input::all();

		if (!$this->user->budgetProjects->count()) {
			return Redirect::to('/');
		}
		if (Input::has('projectId')) {
			Session::put('work_projectId', $input['projectId']);
			return Redirect::to('budget');
		}

		$endDate = date('d.m.Y');
		if (Input::has('endDate')) {
			$endDate = $input['endDate'];
		}
		$date				 = explode('.', $endDate);
		$endDateRaw	 = "{$date[2]}-{$date[1]}-{$date[0]}";

		return $this->setupLayout('budget.index')
										->with('endDate', $endDate)
										->with('input', $input);
	}

	public function reports() {
		$input = Input::all();

		if (!$this->user->budgetProjects->count()) {
			return Redirect::to('/');
		}

		return $this->setupLayout('budget.reports')
										->with('input', $input);
	}

	public function totalCosts() {
		$input = Input::all();

		if (!$this->user->budgetProjects->count()) {
			return Redirect::to('/');
		}
		$endDate = date('d.m.Y');
		if (Input::has('endDate')) {
			$endDate = $input['endDate'];
		}
		$date				 = explode('.', $endDate);
		$endDateRaw	 = "{$date[2]}-{$date[1]}-{$date[0]}";

		return $this->setupLayout('budget.costs.totalcosts')
										->with('endDate', $endDate)
										->with('input', $input);
	}
  
	public function chartStat() {

		if (!$this->user->budgetProjects->count()) {
			return Redirect::to('/');
		}

		return $this->setupLayout('budget.reports.deb_cred_balance');
	}
  
  /**
	 * Приход/расход за незакрытый месяц.
	 * @return Array
	 */
	public function getCurrMonthStat() {
    $input = Input::all();
    $projectId = $input['projectId'];
            
    $deb = BudgetOperation::select(DB::raw('date, sum(amount)/100 as sumDeb, 0 as sumCred'))
																						->whereProjectId($projectId)
																						->whereIsnooutcome(0)
																						->whereIsnoincome(0)
																						->whereType(BudgetOperation::TYPE_OUTCOMING)
                                            ->groupBy(DB::raw('date'))
                                            ->get()
                                            ->keyBy('date');

    $cred = BudgetOperation::select(DB::raw('date, sum(amount)/100 as sumCred'))
																						->whereProjectId($projectId)
																						->whereIsnooutcome(0)
																						->whereIsnoincome(0)
																						->whereType(BudgetOperation::TYPE_INCOMING)
                                            ->groupBy(DB::raw('date'))
                                            ->get()
                                            ->keyBy('date');
    foreach ($cred as $c){
      if( isset($deb[ $c['date'] ]) ){
          $deb[ $c['date'] ]['sumCred'] = $c['sumCred'];         
      } 
      else {
          $deb[ $c['date'] ] = [ "date"=>$c['date'],"sumDeb"=>0,"sumCred"=>$c['sumCred'] ];         
      }
    }
    
		return $deb;
  }

  /**
	 * Приход/расход, закрытые месяцы текущего года с группировкой по дням.
	 * @return Array
	 */
	public function getCurrYearStat() {
    $input = Input::all();
    $projectId = $input['projectId'];
    $s_date = date('Y').'-01-01';
    $e_date = date('Y-m-d');
            
    $deb = BudgetOperation::withTrashed()
                            ->select(DB::raw('date, sum(amount)/100 as sumDeb, 0 as sumCred'))
                            ->whereIsarchived(1)
                            ->whereBetween('date', [$s_date,  $e_date])
                            ->whereProjectId($projectId)
                            ->whereIsnooutcome(0)
                            ->whereIsnoincome(0)
                            ->whereType(BudgetOperation::TYPE_OUTCOMING)
                            ->groupBy(DB::raw('date'))
                            ->get()
                            ->keyBy('date');

    $cred = BudgetOperation::withTrashed()
                            ->select(DB::raw('date, sum(amount)/100 as sumCred'))
                            ->whereIsarchived(1)
                            ->whereBetween('date', [$s_date,  $e_date])
                            ->whereProjectId($projectId)
                            ->whereIsnooutcome(0)
                            ->whereIsnoincome(0)
                            ->whereType(BudgetOperation::TYPE_INCOMING)
                            ->groupBy(DB::raw('date'))
                            ->get()
                            ->keyBy('date');
    foreach ($cred as $c){
      if( isset($deb[ $c['date'] ]) ){
          $deb[ $c['date'] ]['sumCred'] = $c['sumCred'];         
      } 
      else {
          $deb[ $c['date'] ] = [ "date"=>$c['date'],"sumDeb"=>0,"sumCred"=>$c['sumCred'] ];         
      }
    }
    
		return $deb;
  }
  
   /**
	 * Приход/расход за указанный период.
	 * @return Array
	 */
	public function getStatByMonth($projectId, $s_date, $e_date) {
    $deb = BudgetOperation::select(DB::raw('MONTH(date) as date, sum(amount)/100 as sumDeb, 0 as sumCred'))
																						->whereRaw(DB::raw("(deleted_at IS NULL OR isarchived=1)"))
																						->where('date', '>=', $s_date)
																						->where('date', '<=', $e_date)
																						->whereProjectId($projectId)
																						->whereIsnooutcome(0)
																						->whereIsnoincome(0)
																						->whereType(BudgetOperation::TYPE_OUTCOMING)
                                            ->groupBy(DB::raw('MONTH(date)'))
                                            ->withTrashed()
                                            ->get()
                                            ->keyBy('date');

    $cred = BudgetOperation::select(DB::raw('MONTH(date) as date, sum(amount)/100 as sumCred'))
                                            ->whereRaw(DB::raw("(deleted_at IS NULL OR isarchived=1)"))
																						->where('date', '>=', $s_date)
																						->where('date', '<=', $e_date)
																						->whereProjectId($projectId)
																						->whereIsnooutcome(0)
																						->whereIsnoincome(0)
																						->whereType(BudgetOperation::TYPE_INCOMING)
                                            ->groupBy(DB::raw('MONTH(date)'))
                                            ->withTrashed()
                                            ->get()
                                            ->keyBy('date');
    foreach ($cred as $c){
      if( isset($deb[ $c['date'] ]) ){
          $deb[ $c['date'] ]['sumCred'] = $c['sumCred'];         
      } 
      else {
          $deb[ $c['date'] ] = [ "date"=>$c['date'],"sumDeb"=>0,"sumCred"=>$c['sumCred'] ];         
      }
    }
    
		return $deb;
  }
  
   /**
	 * Сравнение прихода/расхода за месяцы текущего года с аналогичными месяцами прошлого.
	 * @return Array
	 */
	public function getYearByMonth() {
    $input = Input::all();
    $projectId = $input['projectId'];
            
    $result =
      [
        'currYear' => $this->getStatByMonth($projectId, date('Y').'-01-01', date('Y-m-d')),
        'prevYear' => $this->getStatByMonth($projectId, date( (date('Y')-1).'-01-01' ), date( (date('Y')-1).'-12-31' ))
      ];
    
		return $result;
  }
  
	public function totalCostsProject($projectId) {
		$input = Input::all();

		if (!$this->user->budgetProjects->count()) {
			return Redirect::to('/');
		}
		$endDate = date('d.m.Y');
		if (Input::has('endDate')) {
			$endDate = $input['endDate'];
		}

		if (!isset($input['startDate'])) {
			$startDate = date("d.m.Y", time() - 3600 * 24);
		}
		else if (Input::has('startDate')) {
			$startDate = $input['startDate'];
		}

		return $this->setupLayout('budget.reports.projectcosts')
										->with('endDate', $endDate)
										->with('startDate', $startDate)
										->with('input', $input);
	}

	public function totalCostsArchive() {
		$input = Input::all();

		if (!$this->user->budgetProjects->count()) {
			return Redirect::to('/');
		}
		$endDate = date('d.m.Y');
		if (Input::has('endDate')) {
			$endDate = $input['endDate'];
		}

		if (!isset($input['startDate'])) {
			$startDate = date("d.m.Y", time() - 3600 * 24);
		}
		else if (Input::has('startDate')) {
			$startDate = $input['startDate'];
		}

		return $this->setupLayout('budget.costs.totalcostsarchive')
										->with('startDate', $startDate)
										->with('endDate', $endDate)
										->with('input', $input);
	}

	public function operations() {
		$input = Input::all();

		if (!$this->user->budgetProjects->count()) {
			return Redirect::to('/');
		}
		if (Input::has('projectId')) {
			Session::put('work_projectId', $input['projectId']);
			return Redirect::to('budget/operations');
		}

		if (!Input::has('type')) {
			$input['type'] = '';
		}

		$accounts = array();
		foreach ($this->workProject->budgetAccounts as $budgetAccount) {
			$accounts[$budgetAccount->id] = $budgetAccount->name;
		}

		$accountsToSelect = array('0' => 'Все');
		foreach ($this->workProject->budgetAccounts as $budgetAccount) {
			$accountsToSelect[$budgetAccount->id] = $budgetAccount->name;
		}

		$partners = array();
		foreach ($this->workProject->budgetPartners as $budgetPartner) {
			$partners[$budgetPartner->id] = $budgetPartner->name;
		}

		$debtPartners = array();
		foreach ($this->workProject->budgetDebtPartners as $budgetDebtPartner) {
			$debtPartners[$budgetDebtPartner->id][]	 = $budgetDebtPartner->name ? $budgetDebtPartner->name : $budgetDebtPartner->deb_project['name'];
			$debtPartners[$budgetDebtPartner->id][]	 = $budgetDebtPartner->debet_project_id;
		}

    $costsToSelect = BudgetCost::whereIn('project_id', array($this->workProject->id, 0))
                              ->with('budgetCostGroup')
                              ->orderBy('budget_cost_group_id')
                              ->orderBy('name')
                              ->get(); 
    $groups = BudgetCostGroup::orderBy('name')->get();
    $costsArr = [];
    foreach ($costsToSelect as $cost){
      $costsArr[$cost->budget_cost_group_id][] = $cost;
    }
    
		$startDate = Session::get('budget_operation_startDate');
		if (!$startDate) {
			$startDate = date("d.m.Y", time() - 3600 * 24);
		}
		$endDate = Session::get('budget_operation_endDate');
		if (!$endDate) {
			$endDate = date('d.m.Y');
		}
		if (Input::has('startDate')) {
			$startDate = $input['startDate'];
			Session::put('budget_operation_startDate', $input['startDate']);
		}
		$date					 = explode('.', $startDate);
		$startDateRaw	 = "{$date[2]}-{$date[1]}-{$date[0]}";
		if (Input::has('endDate')) {
			$endDate = $input['endDate'];
			Session::put('budget_operation_endDate', $input['endDate']);
		}
		$date				 = explode('.', $endDate);
		$endDateRaw	 = "{$date[2]}-{$date[1]}-{$date[0]}";

		return $this->setupLayout('budget.operations.index')
										->with('input', $input)
										->with('accountsList', BudgetAccount::getAccountsList())
										->with('dualDebtPartners', BudgetDebtPartner::getDebtPartnersList())
										->with('accounts', $accounts)
										->with('accountsToSelect', $accountsToSelect)
										->with('partners', $partners)
										->with('costsArr', $costsArr)
										->with('groups', $groups)
										->with('debtPartners', $debtPartners)
										->with('startDate', $startDate)
										->with('endDate', $endDate)
										->with('budgetOperations', $this->workProject->budgetOperations()->where('date', '>=', $startDateRaw)->where('date', '<=', $endDateRaw)->with('cost')->orderBy('date', 'ASC')->orderBy('type', 'DESC')->get())
										->with('budgetOperationsIn', round($this->workProject->budgetOperations()->whereType(BudgetOperation::TYPE_INCOMING)->whereIsnoincome(0)->where('date', '>=', $startDateRaw)->where('date', '<=', $endDateRaw)->orderBy('date', 'ASC')->orderBy('type', 'DESC')->sum('amount') / 100, 0))
										->with('budgetOperationsOut', round($this->workProject->budgetOperations()->whereType(BudgetOperation::TYPE_OUTCOMING)->whereIsnooutcome(0)->where('date', '>=', $startDateRaw)->where('date', '<=', $endDateRaw)->orderBy('date', 'ASC')->orderBy('type', 'DESC')->sum('amount') / 100, 0));
	}

	public function archiveOperations() {
		$input = Input::all();

		if (!$this->user->budgetProjects->count()) {
			return Redirect::to('/');
		}
		if (Input::has('projectId')) {
			Session::put('work_projectId', $input['projectId']);
			return Redirect::to('budget/archive');
		}

		if (!Input::has('type')) {
			$input['type'] = '';
		}

		$accountsToSelect = array('0' => 'Все');
		foreach ($this->workProject->budgetAccounts as $budgetAccount) {
			$accountsToSelect[$budgetAccount->id] = $budgetAccount->name;
		}


		$startDate = Session::get('budget_operation_startDate');
		if (!$startDate) {
			$startDate = date("d.m.Y", time() - 3600 * 24);
		}
		$endDate = Session::get('budget_operation_endDate');
		if (!$endDate) {
			$endDate = date('d.m.Y');
		}
		if (Input::has('startDate')) {
			$startDate = $input['startDate'];
			Session::put('budget_operation_startDate', $input['startDate']);
		}
		$date					 = explode('.', $startDate);
		$startDateRaw	 = "{$date[2]}-{$date[1]}-{$date[0]}";
		if (Input::has('endDate')) {
			$endDate = $input['endDate'];
			Session::put('budget_operation_endDate', $input['endDate']);
		}
		$date				 = explode('.', $endDate);
		$endDateRaw	 = "{$date[2]}-{$date[1]}-{$date[0]}";

		return $this->setupLayout('budget.operations.archive')
										->with('input', $input)
										->with('startDate', $startDate)
										->with('endDate', $endDate)
										->with('accountsToSelect', $accountsToSelect)
										->with('budgetOperations', $this->workProject->budgetOperations()->withTrashed()->whereIsarchived(1)->where('date', '>=', $startDateRaw)->where('date', '<=', $endDateRaw)->orderBy('date', 'ASC')->orderBy('type', 'DESC')->get())
										->with('budgetOperationsIn', round($this->workProject->budgetOperations()->withTrashed()->whereIsarchived(1)->whereType(BudgetOperation::TYPE_INCOMING)->whereIsnoincome(0)->where('date', '>=', $startDateRaw)->where('date', '<=', $endDateRaw)->orderBy('date', 'ASC')->orderBy('type', 'DESC')->sum('amount') / 100, 0))
										->with('budgetOperationsOut', round($this->workProject->budgetOperations()->withTrashed()->whereIsarchived(1)->whereType(BudgetOperation::TYPE_OUTCOMING)->whereIsnooutcome(0)->where('date', '>=', $startDateRaw)->where('date', '<=', $endDateRaw)->orderBy('date', 'ASC')->orderBy('type', 'DESC')->sum('amount') / 100, 0));
	}

	public function updateCost() {
		$input = Input::all();

		if (!isset($input['pk']) || !isset($input['name'])) {
			$response = array('status' => 'fail');
			return Response::json($response);
		}

		$budgetCost = BudgetCost::find($input['pk']);
		if ($budgetCost == null || !is_numeric($input['pk'])) {
			$response = array('status' => 'fail', 'message' => 'Операция не найдена');
			return Response::json($response);
		}
		$budgetCost->plan_amount = $input['value'];
		$budgetCost->save();

		$response = array(
				'status'				 => 'success',
				'planAmountAll'	 => $this->workProject->getPlanAmountAll(),
				'profit'				 => $this->workProject->getProfit()
		);
		return Response::json($response);
	}

	public function updateMounthPlan() {
		$input = Input::all();

		if (!isset($input['pk'])) {
			$response = array('status' => 'fail');
			return Response::json($response);
		}
		$value = $input['value'];
		$value = str_replace(',', '.', $value);
		$value = str_replace(' ', '', $value);

		if (!is_numeric($value)) {
			$response = array('status' => 'fail', 'message' => 'Сумма бюджета - не число');
			return Response::json($response);
		}

		$project = Project::find($input['pk']);
		if ($project == null || !is_numeric($input['pk'])) {
			$response = array('status' => 'fail', 'message' => 'Проект не найден');
			return Response::json($response);
		}

		$budgetProjectMonthPlan = BudgetProjectMonthPlan::whereProjectId($input['pk'])
						->whereIsarchived(0)
						->first();
		if (!$budgetProjectMonthPlan) { // --> создание новой записи
			$budgetProjectMonthPlan	 = BudgetProjectMonthPlan::create(array(
									'project_id'	 => $project->id,
									'budget_date'	 => date('Y-m-d'),
									'month_plan'	 => $input['value'],
									'isarchived'	 => 0
			));
			$response								 = array(
					'status' => 'success'
			);
		}
		else {
			$budgetProjectMonthPlan->setMonthPlanAttribute($value);
			$budgetProjectMonthPlan->save();

			$response = array(
					'status' => 'success'
			);
		}
		return Response::json($response);
	}

	public function updateGroupPercent($endDate = null) {
		if (!$endDate) {
			$endDate = date('Y-m-d');
		}
		else {
			$date		 = explode('.', $endDate);
			$endDate = "{$date[2]}-{$date[1]}-{$date[0]}";
		}
		$input = Input::all();

		$value = $input['value'];
		$value = str_replace(',', '.', $value);
		$value = str_replace(' ', '', $value);

		// создание записи ->
		if ($input['pk'] == 0) {
			$name			 = explode('_', $input['name']);
			$projectId = $name[0];
			$groupId	 = $name[1];
			if (!is_numeric($projectId) || !is_numeric($groupId)) {
				$response = array('status' => 'fail');
				return Response::json($response);
			}
			$project = Project::find($projectId);
			if (!$project) {
				$response = array('status' => 'fail');
				return Response::json($response);
			}
			$group = BudgetCostGroup::find($groupId);
			if (!$group) {
				$response = array('status' => 'fail');
				return Response::json($response);
			} // проверка на наличие в таблице записи, т.к при изменении поля % 'pk' != 0 только после перезагрузки страницы
			// т.е. несколько изменений поля подряд, без перезагрузки, создают каждый раз запись в БД
			$budgetCostGroupProject = BudgetCostGroupProject::where('project_id', '=', $project->id)
							->where('budget_cost_group_id', '=', $group->id)
							->first();
			if (!$budgetCostGroupProject) {
				$projectPercent					 = BudgetCostGroupProject::create(array(
										'project_id'					 => $projectId,
										'amount'							 => $value * 100,
										'budget_cost_group_id' => $groupId,
				));
				$budgetCostGroupProject	 = BudgetCostGroupProject::find($projectPercent->id);
			}
			// <-
		}
		elseif (!is_numeric($input['pk'])) {
			$response = array('status' => 'fail');
			return Response::json($response);
		}
		if (!isset($budgetCostGroupProject)) { // если идет изменение существующей записи
			$budgetCostGroupProject = BudgetCostGroupProject::find($input['pk']);
		}
		if ($budgetCostGroupProject == null) {
			$response = array('status' => 'fail', 'message' => 'Запись не найдена');
			return Response::json($response);
		}

		$budgetCostGroupProject->amount = $value * 100;
		$budgetCostGroupProject->save();

		$workProject		 = Project::find($budgetCostGroupProject->project_id);
		$groupPercentSum = $workProject->getCurrentBudgetMonthPlan() * ($budgetCostGroupProject->amount) / 100;


		$operaionsOutAmount	 = BudgetOperation::whereProjectId($workProject->id)
						->whereIsdebt(0)
						->whereRaw('budget_cost_id IN (SELECT id FROM budget_costs WHERE budget_cost_group_id=' . $budgetCostGroupProject->budget_cost_group_id . ')')
						->whereType(BudgetOperation::TYPE_OUTCOMING)
						->whereRaw(DB::raw('DATE(date)<=?'), array($endDate))
						->sum('amount');
		$groupSumRest				 = $groupPercentSum - $operaionsOutAmount;
		$groupPercentTotal	 = BudgetCostGroupProject::whereProjectId($workProject->id)
						->where('budget_cost_group_id', '>', 0)
						->sum('amount');
		$response						 = array(
				'status'						 => 'success',
				'groupPercentSum'		 => round($groupPercentSum / 100, 2),
				'groupSumRest'			 => round($groupSumRest / 100, 2),
				'groupPercentTotal'	 => round($groupPercentTotal / 100, 2)
		);
		return Response::json($response);
	}

	public function createOperation() {
		$input = Input::all();
		$date	 = '';

    $operationType = $input['budgetNewOperationType'];
		if ($input['budgetNewOperationDate'] && $input['budgetNewOperationDate']) {
			$nextdate = explode('.', $input['budgetNewOperationDate']);
			if (checkdate($nextdate[1], $nextdate[0], $nextdate[2])) {
				$date = "{$nextdate[2]}-{$nextdate[1]}-{$nextdate[0]}";
			}
		}
		if (!isset($input['budgetNewOperationAmount']) || !$input['budgetNewOperationAmount'] || !isset($input['budgetNewOperationProjectId']) || !$input['budgetNewOperationProjectId']) {
			$response = array('status' => 'fail');
			return Response::json($response);
		}

		$isDebtOperation = 0;
		if (isset($input['budgetNewOperationIsDebt'])) {
			$isDebtOperation = 1;
		}

		$project = Project::find($input['budgetNewOperationProjectId']);
		if ($project == null || !is_numeric($input['budgetNewOperationProjectId'])) {
			$response = array('status' => 'fail', 'message' => 'Проект не найден');
			return Response::json($response);
		}
		
    $partnerId = isset($input['budgetNewOperationPartner'])? $input['budgetNewOperationPartner'] : 0;
		$costId = 0;
		if ($isDebtOperation == 0) {
			if (isset($input['budgetNewOperationCost'])) {
				$cost = BudgetCost::find($input['budgetNewOperationCost']);

				if ($cost) {
					$costId = $cost->id;
				}
				else if (!$cost) {
					$response = array('status' => 'fail', 'message' => 'Статья расходов не найдена');
					return Response::json($response);
				}
			}
      if($operationType == BudgetOperation::TYPE_INCOMING){
        // проверяем наличие отправителя денег, если это приход
        if( $partnerId == 0 || !is_numeric($partnerId) ){         
          $response = array(
                      'status'				 => 'fail',
                      'error_message'	 => 'Отсутствует или указан неверный контрагент',
                      'error_field'		 => 'budgetNewOperationPartnerError'
          );
          return Response::json($response);
          
        }
        $partner = BudgetPartner::where('id', '=', $partnerId)->whereProjectId($input['budgetNewOperationProjectId'])->first();
        if ($partner == null || !$partner || !is_numeric($input['budgetNewOperationProjectId'])) {
          $response = array(
                      'status'				 => 'fail',
                      'error_message'	 => 'Контрагент не найден',
                      'error_field'		 => 'budgetNewOperationPartnerError'
          );
          return Response::json($response);
        }
      }
		}

        $debtPartnerId = 0;
				$debtPartnerIsProject = 0; // является ли долговой агент проектом или это частное лицо
		if (isset($input['budgetNewOperationDebtPartnerId'])) {
          $debtPartner = BudgetDebtPartner::find($input['budgetNewOperationDebtPartnerId']);
          if ($debtPartner == null || !is_numeric($input['budgetNewOperationDebtPartnerId']) || $project->id != $debtPartner->project_id) {
              $response = array('status' => 'fail', 'message' => 'Долговой проект не найден');
              return Response::json($response);
          }
          $debtPartnerId = $debtPartner->id;
					$debtPartnerIsProject = $debtPartner->debet_project_id;
        }
		if ($isDebtOperation && $debtPartnerIsProject) {
			if ($input['debPartnerAccountId'] == 0) {
            $response = array(
                      'status'				 => 'fail',
                      'error_message'	 => 'Выберите счет',
                      'error_field'		 => 'debPartnerAccountIdError'
              );
              return Response::json($response);
          }
          $debPartnerAccount = BudgetAccount::find($input['debPartnerAccountId']);
          if ($debPartnerAccount == null || !is_numeric($input['debPartnerAccountId']) || $debPartnerAccount->project_id != $debtPartner->debet_project_id) {
              $response = array('status' => 'fail', 'message' => 'Счет не найден');
              return Response::json($response);
          }
				$dualDebPartnerId	 = 0;
				$dualDebPartner		 = BudgetDebtPartner::whereProjectId($debtPartner->debet_project_id)
                                                ->whereDebetProjectId($project->id)
                                                ->first();
          if ($dualDebPartner == null || !is_numeric($input['dualDebtPartnerId']) || $dualDebPartner->id != $input['dualDebtPartnerId']) {
              $response = array('status' => 'fail', 'message' => 'К выбранному долговому контрагенту не привязан текущий проект в качестве долгового партнера');
              return Response::json($response);
          }
          $dualDebPartnerId = $dualDebPartner->id;

				$dualBudgetOperation = new BudgetOperation([
                                  'date'									 => $date,
                                  'project_id'						 => $debtPartner->debet_project_id,
                                  'budget_cost_id'				 => 0,
                                  'budget_partner_id'			 => 0,
                                  'budget_in_account_id'	 => $debPartnerAccount->id,
                                  'budget_out_account_id'	 => $debPartnerAccount->id,
                                  'debt_partner_id'				 => $dualDebPartnerId,
                                  'isdebt'								 => $isDebtOperation,
                                  'debt_comment'					 => isset($input['budgetNewOperationIsDebt']) ? $input['budgetNewOperationComment'] : '',
                                  'comment'								 => isset($input['budgetNewOperationIsDebt']) ? '' : $input['budgetNewOperationComment']
          ]);
          if ($operationType == BudgetOperation::TYPE_INCOMING) { // приход
              $dualBudgetOperation->isnooutcome = 1;
              $dualBudgetOperation->type = BudgetOperation::TYPE_OUTCOMING; // расходная
          }elseif ($operationType == BudgetOperation::TYPE_OUTCOMING) { // расход
              $dualBudgetOperation->isnoincome = 1;
					$dualBudgetOperation->type			 = BudgetOperation::TYPE_INCOMING; // приходная
          }
          $dualBudgetOperation->user()->associate($this->user);
          $dualBudgetOperation->amount = $input['budgetNewOperationAmount'];
          
//          $dualBudgetOperation->save();
        }

    $budgetOperation = new BudgetOperation([
                        'date'									 => $date,
                        'project_id'						 => $project->id,
                        'type'									 => $operationType,
                        'budget_cost_id'				 => $costId,
                        'budget_partner_id'			 => $partnerId,
                        'budget_in_account_id'	 => $input['budgetNewOperationAccountIn'],
                        'budget_out_account_id'	 => $input['budgetNewOperationAccountOut'],
                        'debt_partner_id'				 => $debtPartnerId,
                        'isdebt'								 => $isDebtOperation,
                        'debt_comment'					 => isset($input['budgetNewOperationIsDebt']) ? $input['budgetNewOperationComment'] : '',
                        'comment'								 => isset($input['budgetNewOperationIsDebt']) ? '' : $input['budgetNewOperationComment']
                      ]);
    
		if (isset($dualBudgetOperation)) {
      $budgetOperation->save(); // нужно сохранить, чтобы получить id для долговой
			$dualBudgetOperation->debt_parent_id = $budgetOperation->id;
//			$dualBudgetOperation->save();

			$dualBudgetOperation->save();
			$budgetOperation->debt_parent_id = $dualBudgetOperation->id;
		}
		$budgetOperation->user()->associate($this->user);
		$budgetOperation->amount = $input['budgetNewOperationAmount'];
		if (isset($input['budgetNewOperationIsDebt'])) {
			if ($operationType == BudgetOperation::TYPE_INCOMING) {
				$budgetOperation->isnoincome = 1;
			}
			elseif ($operationType == BudgetOperation::TYPE_OUTCOMING) {
				$budgetOperation->isnooutcome = 1;
			}
		}
		$isSalary		 = 0;
		$salaryCosts = $budgetOperation->getSalaryCosts();
		if (in_array($costId, $salaryCosts) && $operationType == BudgetOperation::TYPE_OUTCOMING) {
		  $isSalary = 1;
		}
		$budgetOperation->is_salary = $isSalary;
		$budgetOperation->save();

		$response = array(
				'status'		 => 'success',
				'id'				 => $budgetOperation->id,
				'operation'	 => View::make('budget.operations.operation')->with('user', $this->user)->with('budgetOperation', $budgetOperation)->render(),
		);
		return Response::json($response);
	}

	public function updateOperation() {
		$input = Input::all();

		if (!isset($input['pk']) || !isset($input['name'])) {
			$response = array('status' => 'fail');
			return Response::json($response);
		}

		$budgetOperation = BudgetOperation::find($input['pk']);
		if ($budgetOperation == null || !is_numeric($input['pk'])) {
			$response = array('status' => 'fail', 'message' => 'Операция не найдена');
			return Response::json($response);
		}
    
		$costId = $budgetOperation->budget_cost_id;
		if ($input['name'] == 'budget_cost_id') {
			$costId = $input['value'];
		}
		$salaryCosts = $budgetOperation->getSalaryCosts();
		
		// тип операции
		if ($input['name'] == 'type') {
			$type							 = $input['value'];
			$debtOperationType = 0;

			if ($type == BudgetOperation::TYPE_OUTCOMING) { // если меняют на расход
				if ($budgetOperation->isnoincome) { // если до этого был Не приход
					$budgetOperation->isnoincome	 = 0; // сбрасываем Не приход
					$budgetOperation->isnooutcome	 = 1; // при смене на расход также ставим как Не расход
				}
				$debtOperationType = BudgetOperation::TYPE_INCOMING;
			}else if($type == BudgetOperation::TYPE_INCOMING){ // если меняют на приход
				if($budgetOperation->isnooutcome){
					$budgetOperation->isnooutcome = 0;
					$budgetOperation->isnoincome  = 1;
				}
				$debtOperationType = BudgetOperation::TYPE_OUTCOMING;
			}else{ // если другое, то сбрасываем все отметки
				$budgetOperation->isnooutcome = 0;
				$budgetOperation->isnoincome  = 0;
			}
			
			// если операция долговая и есть привязанная к ней по id
			// у операции из выгрузки тип Приходная НЕ поменяется
			if($budgetOperation->isdebt == 1 && $budgetOperation->debt_parent_id && $debtOperationType){
				$dualDebtOperation = BudgetOperation::find($budgetOperation->debt_parent_id);
				$dualDebtOperation->type = $debtOperationType;
				if($debtOperationType == BudgetOperation::TYPE_INCOMING){
					$dualDebtOperation->isnooutcome = 0;
				  $dualDebtOperation->isnoincome  = 1;
				}else{
					$dualDebtOperation->isnooutcome = 1;
				  $dualDebtOperation->isnoincome  = 0;
				}
				$dualDebtOperation->save();
			}

			if ($type != 1) { // если тип любой, но не расход
				$budgetOperation->is_salary = 0;
			}
			else if ($type == 1 && $budgetOperation->isnooutcome == 0 && $budgetOperation->isdebt == 0 && in_array($costId, $salaryCosts)) { // расход
				$budgetOperation->is_salary = 1;
			}
		}// статья расхода (информация)
		else if ($input['name'] == 'budget_cost_id') {
			if (in_array($costId, $salaryCosts) && $budgetOperation->type == 1 && $budgetOperation->isnooutcome == 0 && $budgetOperation->isdebt == 0) {
				$budgetOperation->is_salary = 1;
			}
			else {
				$budgetOperation->is_salary = 0;
			}
		}
		else if ($input['name'] == 'amount') {
			if ($budgetOperation->isdebt == 1 && $budgetOperation->debt_parent_id) {
				
				$whereDebtParentId = '';
				if ($budgetOperation->debt_parent_id > 0) {
					$whereDebtParentId = ' OR debt_parent_id = ' . $budgetOperation->debt_parent_id;
				}
				$dualDebtOperations = BudgetOperation::whereRaw('(debt_parent_id = '.$budgetOperation->id.$whereDebtParentId.')')->get();
        // в выборку $dualDebtOperations попадает и сама операция $budgetOperation
				foreach ($dualDebtOperations as $dualDebtOperation){
          if($dualDebtOperation->id != $budgetOperation->id){ // чтобы не дублировались записи в логе изменений
					  $dualDebtOperation->amount = $input['value'];
					  $dualDebtOperation->save();
          }
				}
			}
		}

		$budgetOperation->$input['name'] = $input['value'];
		$budgetOperation->save();

		$response = array(
				'status'		 => 'success',
				'id'				 => $budgetOperation->id,
				'name'			 => $input['name'],
				'operation'	 => View::make('budget.operations.operation')->with('user', $this->user)->with('budgetOperation', $budgetOperation)->render(),
		);
		return Response::json($response);
	}

	// связанные долговые операции удаляет парой, связка 2 долговых + 3ю приходной из выгрузки - удалит все вместе
	// при удалении пар долговых не удаляются операции из выгрузки
	public function deleteOperation() {
		$input = Input::all();

		if (!isset($input['operationId'])) {
			$response = array('status' => 'fail');
			return Response::json($response);
		}

		$budgetOperation = BudgetOperation::find($input['operationId']);
		if ($budgetOperation == null || !is_numeric($input['operationId'])) {
			$response = array('status' => 'fail', 'message' => 'Операция не найдена');
			return Response::json($response);
		}
//		if ($budgetOperation->isuploaded) {
//			$response = array('status' => 'fail', 'message' => 'Операцию нельзя удалить');
//			return Response::json($response);
//		}

		$budgetOperation->delete_user_id = $this->user->id;
		$budgetOperation->isarchived		 = 0;
		$budgetOperation->archived_at		 = DB::raw('NULL');
		$budgetOperation->save();
		$budgetOperation->delete();
		// чтобы удалить одну из связанных долговых операций нужно ее сначала отвязать, иначе будет удалять все связанные операции
		// операция из выгрузки НЕ будет удалена, если удаляют ее зеркальную долговую, или зеркальную приходную в другой проект. Она удалится только если будут удалять конкретно ее (две привязанные операции также удалятся)
		$whereDebtParentId = '';
			if($budgetOperation->debt_parent_id > 0){ // для получения операций с таким же debt_parent_id. нужно, чтобы видеть все связанные операции, если открывают не ту операцию из которой создавались остальные)
			  $whereDebtParentId = ' OR (debt_parent_id = '.$budgetOperation->debt_parent_id.' AND id <> '.$budgetOperation->id.')';
			}
		$operationsDelete = BudgetOperation::whereRaw('(debt_parent_id = '.$budgetOperation->id.$whereDebtParentId.')')->whereNull('budget_upload_id')->get();

		$childDeletedId = [];
		foreach ($operationsDelete as $operationDelete) {
			$childDeletedId[] = $operationDelete->id;
			$operationDelete->delete();
		}

		$response = array(
				'status'		       => 'success',
				'id'				       => $budgetOperation->id,
				'child_deleted_id' => $childDeletedId,
				'operation'	       => View::make('budget.operations.operation')->with('user', $this->user)->with('budgetOperation', $budgetOperation)->render(),
		);
		return Response::json($response);
	}

	public function restoreOperation() {
		$input = Input::all();

		if (!isset($input['operationId'])) {
			$response = array('status' => 'fail');
			return Response::json($response);
		}

		$budgetOperation = BudgetOperation::withTrashed()->find($input['operationId']);
		if ($budgetOperation == null || !is_numeric($input['operationId'])) {
			$response = array('status' => 'fail', 'message' => 'Операция не найдена');
			return Response::json($response);
		}

		$budgetOperation->restore();
		$budgetOperation->delete_user_id = null;
		$budgetOperation->save();

		$operationsRestore = null;
		if (isset($input['child_deleted_id']) && $input['child_deleted_id'] != null) {
			$operationsRestore = BudgetOperation::whereIn('id', $input['child_deleted_id'])->withTrashed()->get();
		}

		if($operationsRestore){
			foreach ($operationsRestore as $operationRestore) {
				$operationRestore->restore();
				$operationRestore->delete_user_id = null;
				$operationRestore->save();
			}
		}
		$response = array(
				'status'		 => 'success',
				'id'				 => $budgetOperation->id,
				'operation'	 => View::make('budget.operations.operation')->with('user', $this->user)->with('budgetOperation', $budgetOperation)->render(),
		);
		return Response::json($response);
	}

	public function noIncomeOperation() {
		$input = Input::all();

		if (!isset($input['operationId'])) {
			$response = array('status' => 'fail');
			return Response::json($response);
		}

		$budgetOperation = BudgetOperation::find($input['operationId']);
		if ($budgetOperation == null || !is_numeric($input['operationId'])) {
			$response = array('status' => 'fail', 'message' => 'Операция не найдена');
			return Response::json($response);
		}

		$budgetOperation->isnoincome = !$budgetOperation->isnoincome;
		$budgetOperation->save();

		$response = array(
				'status'		 => 'success',
				'id'				 => $budgetOperation->id,
				'operation'	 => View::make('budget.operations.operation')->with('user', $this->user)->with('budgetOperation', $budgetOperation)->render(),
		);
		return Response::json($response);
	}

	public function noOutcomeOperation() {
		$input = Input::all();

		if (!isset($input['operationId'])) {
			$response = array('status' => 'fail');
			return Response::json($response);
		}

		$budgetOperation = BudgetOperation::find($input['operationId']);
		if ($budgetOperation == null || !is_numeric($input['operationId'])) {
			$response = array('status' => 'fail', 'message' => 'Операция не найдена');
			return Response::json($response);
		}

		$budgetOperation->isnooutcome = !$budgetOperation->isnooutcome;
		
		$costId			 = $budgetOperation->budget_cost_id;
		$salaryCosts = $budgetOperation->getSalaryCosts();
		if ($budgetOperation->type == 1 && $budgetOperation->isnooutcome == 0 && $budgetOperation->isdebt == 0 && in_array($costId, $salaryCosts)) {
			$budgetOperation->is_salary = 1;
		}
		else {
			$budgetOperation->is_salary = 0;
		}
		
		$budgetOperation->save();

		$response = array(
				'status'		 => 'success',
				'id'				 => $budgetOperation->id,
				'operation'	 => View::make('budget.operations.operation')->with('user', $this->user)->with('budgetOperation', $budgetOperation)->render(),
		);
		return Response::json($response);
	}

	public function transitOperation() {
		$input = Input::all();

		if (!isset($input['operationId'])) {
			$response = array('status' => 'fail');
			return Response::json($response);
		}

		$budgetOperation = BudgetOperation::find($input['operationId']);
		if ($budgetOperation == null || !is_numeric($input['operationId']) || $budgetOperation->type != BudgetOperation::TYPE_INCOMING) {
			$response = array('status' => 'fail', 'message' => 'Операция не найдена');
			return Response::json($response);
		}

		if (!$budgetOperation->istransit) {
			$budgetOperation->istransit	 = 1;
			$budgetOperation->isdebt		 = 0;
			$budgetOperation->isnoincome = 0;
		}
		else {
			$budgetOperation->istransit = 0;
		}
		$budgetOperation->save();

		$response = array(
				'status'		 => 'success',
				'id'				 => $budgetOperation->id,
				'operation'	 => View::make('budget.operations.operation')->with('user', $this->user)->with('budgetOperation', $budgetOperation)->render(),
		);
		return Response::json($response);
	}
	
	// получение списка з/п записей к операции
	public function getSalaryOperation() {
		$input = Input::all();

		if (!isset($input['budgetOperationId'])) {
			$response = array('status' => 'fail');
			return Response::json($response);
		}

		$budgetOperation = BudgetOperation::find($input['budgetOperationId']);
		if ($budgetOperation == null || !is_numeric($input['budgetOperationId']) || $budgetOperation->is_salary != 1) {
			$response = array('status' => 'fail', 'message' => 'Операция не найдена или она не зарплатная');
			return Response::json($response);
		}
		
		$salaryOperations	 = BudgetSalary::select(DB::raw('budget_salary.*, (select sum(budget_salary.amount) from budget_salary where budget_salary.deleted_at is null AND budget_salary.budget_operation_id = ' . $budgetOperation->id . ') as salarySum'))
						                         ->whereBudgetOperationId($budgetOperation->id)
						                         ->get();
		$response					 = array(
				'status'								 => 'success',
				'budgetOperationAmount'	 => $budgetOperation->amount,
				'salaryOperations'			 => $salaryOperations
		);
		return Response::json($response);
	}
	
	// сохранение списка з/п записей к операции
	public function updateSalaryOperation() {
		$input = Input::all();

		if (!isset($input['budgetOperationId'])) {
			$response = array('status' => 'fail');
			return Response::json($response);
		}

		$budgetOperation = BudgetOperation::find($input['budgetOperationId']);
		if ($budgetOperation == null || !is_numeric($input['budgetOperationId']) || $budgetOperation->is_salary != 1) {
			$response = array('status' => 'fail', 'message' => 'Операция не найдена или она не зарплатная');
			return Response::json($response);
		}
/*  
		$validator = Validator::make($input, array(
				        'userForSignId'    => 'required_if:|date_format:d.m.Y'
		));

		if ($validator->fails()) {
			$messages = $validator->messages();
			
			if ($messages->has('requestedAmount')) {
				$message		 = 'Сумма расходов должна быть числом';
				$error_field = 'message-box-sum';
			}
			$response = array(
					'status'				 => 'fail',
					'error_message'	 => $message,
					'error_field'		 => $error_field
			);
			return Response::json($response);
		  } */

		$delete						 = $input['delete'];
		$salaryOperationId = $input['salaryOperationId'];
		$salaryAmount			 = $input['salaryAmount'];
		$salaryComment		 = $input['salaryComment'];
		$salaryPaidFor		 = $input['salaryPaidFor'];
		$salaryUserId			 = $input['salaryUserId'];
		
		$projectId				 = $budgetOperation->project_id;
		$userId						 = $this->user->id;
		$budgetOperationId = $budgetOperation->id;
		
		foreach ($salaryUserId as $key => $value) {
			if ($delete[$key] == 1) { // удаление з/п операций
				$operationToDelete = BudgetSalary::whereId($salaryOperationId[$key])
																				 ->whereProjectId($projectId)
																				 ->whereBudgetOperationId($budgetOperationId)
																				 ->first();
				if ($operationToDelete) {
					$operationToDelete->delete_user_id = $userId;
					$operationToDelete->deleted_at		 = DB::raw('NOW()');
					$operationToDelete->save();
				}
			}
			else {
				$amount	 = str_replace(',', '.', $salaryAmount[$key]);
				$amount	 = str_replace(' ', '', $amount) * 100;

				$salaryDate = '';
				if ($salaryPaidFor[$key]) {
					//$date				 = explode('.', $salaryPaidFor[$key]);
					//$salaryDate	 = "{$date[2]}-{$date[1]}-{$date[0]}";
					$salaryDate	 = $salaryPaidFor[$key].'-01';
				}
				
				//нет id и есть сумма - новая запись
				if ($salaryOperationId[$key] == 0 && $salaryAmount[$key] != 0) {
					BudgetSalary::create(array(
							'project_id'					 => $projectId,
							'budget_operation_id'	 => $budgetOperationId,
							'salary_user_id'			 => $salaryUserId[$key],
							'salary_date'					 => $salaryDate,
							'amount'							 => $amount,
							'comment'							 => $salaryComment[$key],
							'created_user_id'			 => $userId
					));
				}
				else if ($salaryOperationId[$key] != 0) { // есть id - старая запись
					$salaryOperation = BudgetSalary::find($salaryOperationId[$key]);
					if ($salaryOperation != null) {
						$salaryOperation->salary_user_id	 = $salaryUserId[$key];
						$salaryOperation->salary_date			 = $salaryDate;
						$salaryOperation->amount					 = $amount;
						$salaryOperation->comment					 = $salaryComment[$key];
						$salaryOperation->created_user_id	 = $userId;
						$salaryOperation->save();
					}
				}
			}
		}

		$response = array(
				'status' => 'success'
		);
		return Response::json($response);
	}

	public function getOperationDebt() {
		$input = Input::all();

		if (!isset($input['operationId'])) {
			$response = array('status' => 'fail');
			return Response::json($response);
		}

		$budgetOperation = BudgetOperation::find($input['operationId']);
		if ($budgetOperation == null || !is_numeric($input['operationId'])) {
			$response = array('status' => 'fail', 'message' => 'Операция не найдена');
			return Response::json($response);
		}
		
		$accountName = '';
		if ($budgetOperation->type == 1) { // 1 - расход
		  $account = BudgetAccount::find($budgetOperation->budget_out_account_id);
		}
		else if ($budgetOperation->type == 2) { // 2 - приход
			$account = BudgetAccount::find($budgetOperation->budget_in_account_id);
		}
		if ($account->iscache == 1) {
			$accountName = 'cache';
		}
		else if ($account->isbuffer == 1) {
			$accountName = 'buffer';
		}
		else {
			$accountName = $account->current_account;
		}
		
		$response = array(
				'status'					 => 'success',
				'accountName'			 => $accountName,
				'accountNameView'	 => $account->name,
				'operation'				 => $budgetOperation->toArray()
		);
		return Response::json($response);
	}
	
	// возвращает помимо долговых операций еще и связанную приходную операцию 
	// (она была создана, когда приходную операцию из выгрузки помечали как долговую)
	// для удобства, чтобы было видно всю группу связанных операций и можно было сверять их, если было что-то неправильно отредактировано
	public function getDualOperationDebt() {
		$input = Input::all();

		if (!isset($input['debt_operation_id'])) {
			$response = array('status' => 'fail');
			return Response::json($response);
		}

		$budgetOperation = BudgetOperation::find($input['debt_operation_id']);
		if ($budgetOperation == null || !is_numeric($input['debt_operation_id'])) {
			$response = array('status' => 'fail', 'message' => 'Операция не найдена');
			return Response::json($response);
		}
		$type = '';
		if ($budgetOperation->type == BudgetOperation::TYPE_OUTCOMING) {
			$type = BudgetOperation::TYPE_INCOMING;
		}
		elseif ($budgetOperation->type == BudgetOperation::TYPE_INCOMING) {
			$type = BudgetOperation::TYPE_OUTCOMING;
		}
		
		if ($input['debet-project-id'] == 'undefined' || $input['debet-project-id'] == null) {
			$operations					 = '';
			$isCheckedOperation	 = false; // факт привязки по id - нет привязанной операции, значит будет показан блок создания долговой операции в окне управления операцией
		}
		else {
      // чтобы привязать или создать новую зерк. операцию нужно сначала отвязать старую и сохранить
			$dualProjectId		 = $input['debet-project-id'];
			$whereDebtParentId = '';
			if ($budgetOperation->debt_parent_id > 0) { // для получения операций с таким же debt_parent_id. нужно, чтобы видеть все связанные операции, если открывают не ту операцию из которой создавались остальные)
				$whereDebtParentId = ' OR (debt_parent_id = ' . $budgetOperation->debt_parent_id . ' AND id <> ' . $budgetOperation->id . ')';
			}
			$budgetDualOperations	 = BudgetOperation::whereRaw('(debt_parent_id = ' . $budgetOperation->id . $whereDebtParentId.')')->get(); // операция, привязанная по id + 2я приходная, не долговая
			$isCheckedOperation		 = true; // факт привязки по id
			if (!count($budgetDualOperations)) { // набор операций для выбора и привязки
				$budgetDualOperations	 = BudgetOperation::whereRaw("(project_id = " . $dualProjectId . " AND amount = '" . ($budgetOperation->amount * 100) . "' AND type = " . $type.')')
																							 ->whereIsdebt(1)
																							 ->whereNull('debt_parent_id') // не включать уже привязанные операции
																							 ->get();
				$isCheckedOperation		 = false;
			}

			$operations = '';
			foreach ($budgetDualOperations as $budgetDualOperation) {
				$operations .= View::make('budget.operations.dual_operation')->with('user', $this->user)->with('budgetOperation', $budgetDualOperation);
			}
		}

		$response = array(
				'status'						 => 'success',
				'isCheckedOperation' => $isCheckedOperation,
				'operation'					 => $operations,
		);
		return Response::json($response);
	}

	public function updateOperationDebt() {
		$input = Input::all();

		if (!isset($input['debt_operation_id'])) {
			$response = array('status' => 'fail', 'message' => 'Отсутствует номер операции');
			return Response::json($response);
		}

		$budgetOperation	 = BudgetOperation::find($input['debt_operation_id']);
		$budgetDebtPartner = BudgetDebtPartner::find($input['debt_partner_id']);
		if ($budgetOperation == null || $budgetDebtPartner == null || !is_numeric($input['debt_operation_id']) || !is_numeric($input['debt_partner_id'])) {
			$response = array('status' => 'fail', 'message' => 'Операция не найдена');
			return Response::json($response);
		}

		$budgetOperation->isdebt			 = (isset($input['isdebt'])) ? 1 : 0;
		$budgetOperation->debt_comment = $input['debt_comment'];
		$budgetOperation->debtPartner()->associate($budgetDebtPartner);
		
		// обновление долгового комментария у связанных операций
		$whereDebtParentId = '';
		if ($budgetOperation->debt_parent_id > 0) {
			$whereDebtParentId = ' OR (debt_parent_id = '.$budgetOperation->debt_parent_id.' AND id <> '.$budgetOperation->id.')';
		}
		$dualDebtOperations = BudgetOperation::whereRaw('(debt_parent_id = '.$budgetOperation->id.$whereDebtParentId.')')->get();

		if($dualDebtOperations != null){
			foreach ($dualDebtOperations as $dualDebtOperation){
				$dualDebtOperation->debt_comment = $input['debt_comment'];
				$dualDebtOperation->save();
			}
		}
		/* Из трех связанных операций удалятся 2, останется операция из выгрузки.  
		   Из двух - вторая, останется - та, из которой зашли в окно управления долг. операцией */
		
		// удаление привязанных операций, если нет галочек (если есть привязанные операции, то в окне управления долг. покажет только их)
		// 1.были привязаны операции -- сняли галочки -- удалит всё привязанное
		// 2.не было ничего привязано -- открыли окно долг. операции и сохранили -- ничего не удалится
    $childDeletedId = [];
		if(!isset($input['is-checked-operation'])){
			// кол-во связанных операций - 2 или 3
			$where = '';
			if($budgetOperation->debt_parent_id > 0){
				$where = ' OR debt_parent_id = '.$budgetOperation->debt_parent_id;
			}
			$relatedOperationsCount = BudgetOperation::whereRaw('(debt_parent_id = '.$budgetOperation->id.$where.')')->count();
			
			if($relatedOperationsCount == 3 && $budgetOperation->debt_parent_id > 0){ // т.е. удалит и текущую операцию, если она не из выгрузки
				$whereDebtParentId = ' OR debt_parent_id = '.$budgetOperation->debt_parent_id;
			}
			$operationsDelete = BudgetOperation::whereRaw('(debt_parent_id = '.$budgetOperation->id.$whereDebtParentId.')')->whereNull('budget_upload_id')->get();
			foreach ($operationsDelete as $operationDelete) {
				$childDeletedId[] = $operationDelete->id;
				$operationDelete->delete();
			}
		}
		else{ // если есть галочка, то или выбрали 1й раз операцию для привязки или поменяли 
			    // Отвязать старую зерк. операцию. Если была выбрана другая операция - дальше привяжется она, 
		      // если не было выбрано - остановится на предыдущем условии. 
			$budgetOldDualOperation = BudgetOperation::where('debt_parent_id', '=', $budgetOperation->id)->whereIsdebt(1)->first();
			if(count($budgetOldDualOperation)){
				$budgetOldDualOperation->debt_parent_id = null;
				$budgetOldDualOperation->save();
			}
		}
		if (isset($input['isdebt'])) { // отмечен чекбокс Долговая операция
			if ($budgetOperation->type == BudgetOperation::TYPE_INCOMING) {
				$budgetOperation->isnoincome = 1;
				$budgetOperation->istransit	 = 0;
				$dualIsnoincome							 = 0;
				$dualIsnooutcome						 = 1;
				$type												 = BudgetOperation::TYPE_OUTCOMING;
			}
			elseif ($budgetOperation->type == BudgetOperation::TYPE_OUTCOMING) {
				$budgetOperation->isnooutcome	 = 1;
				$dualIsnoincome								 = 1;
				$dualIsnooutcome							 = 0;
				$type													 = BudgetOperation::TYPE_INCOMING;
			}

			if (isset($input['dualOperationCreate'])) { // отмечен чекбокс "Создать зеркальную долговую операцию"
        //--> проверка выбранного долгового агента на наличие у него соответственно текущего проекта в качестве долг. агента
				// если нет, то ни создать новую зеркальную операцию, ни привязать существующую у зеркального проекта не к чему
				$dualDebPartnerId	 = 0;
				$dualDebPartner		 = BudgetDebtPartner::whereProjectId($budgetDebtPartner->debet_project_id)
																							->whereDebetProjectId($budgetDebtPartner->project_id)
																							->first();
				if ($dualDebPartner == null) {
						$response = array('status' => 'fail', 'message' => 'К выбранному долговому контрагенту не привязан текущий проект в качестве долгового партнера');
						return Response::json($response);
				}
				$dualDebPartnerId = $dualDebPartner->id;
				//<--

				// создание зеркальной операции
				if ($input['debPartnerAccountId'] == 0) {
					$response = array(
										'status'				 => 'fail',
										'error_message'	 => 'Выберите счет',
										'error_field'		 => 'debPartnerAccountIdError'
						);
						return Response::json($response);
				} 
				$debPartnerAccount = BudgetAccount::find($input['debPartnerAccountId']);
				if ($debPartnerAccount == null || !is_numeric($input['debPartnerAccountId']) || $debPartnerAccount->project_id != $budgetDebtPartner->debet_project_id) {
						$response = array('status' => 'fail', 'message' => 'Счет не найден');
						return Response::json($response);
				}

				$dualBudgetPartner = BudgetPartner::whereProjectId($budgetDebtPartner->debet_project_id)->first(); // нужен любой не долговой партнер в этом проекте, т.к. если снять отметку "долговая", то понадобится id партнера, а он был бы 0. Но вообще это не правильно..
				$dualBudgetPartnerId = '';
        if($dualBudgetPartner){
          $dualBudgetPartnerId = $dualBudgetPartner->id;
        } 
        // создаем партнера, если ни одного не было
        else { // время шло, костыль эволюционировал..
          $newPartner = BudgetPartner::create(array(
									'name'						 => '!Частный клиент',
									'project_id'			 => $budgetDebtPartner->debet_project_id,
			    ));

          $dualBudgetPartnerId = $newPartner->id;
        }
            
        $dualBudgetOperation = BudgetOperation::create(array(
																'project_id'						 => $budgetDebtPartner->debet_project_id,
																'date'									 => date('Y-m-d'),
																'type'									 => $type,
																'amount'								 => $budgetOperation->amount,
																'budget_cost_id'				 => 0,
																'budget_partner_id'			 => $dualBudgetPartnerId,
																'budget_in_account_id'	 => $debPartnerAccount->id,
																'budget_out_account_id'	 => $debPartnerAccount->id,
										'comment'								 => $budgetOperation->comment,
																'debt_partner_id'				 => $dualDebPartnerId,
																'isdebt'								 => 1,
																'debt_comment'					 => $input['debt_comment'],
																'isnoincome'						 => $dualIsnoincome,
																'isnooutcome'						 => $dualIsnooutcome,
																'debt_parent_id'				 => $budgetOperation->id
				));
				$dualBudgetOperation->user()->associate($this->user);
				$dualBudgetOperation->save();
				
				$budgetOperation->debt_parent_id = $dualBudgetOperation->id;
				
				// отметка "долговая" для приходной операции из выгрузки
			if ($budgetOperation->isuploaded && $budgetOperation->type == BudgetOperation::TYPE_INCOMING) {
						// буферный счет
						$bufferAccount = BudgetAccount::whereIsbuffer(1)->whereProjectId($budgetDebtPartner->debet_project_id)->first();
				if ($bufferAccount == null) { // создать буферный счет, если не найден
							$bufferAccount = BudgetAccount::create(array(
																'project_id' => $budgetDebtPartner->debet_project_id,
											'name'			 => 'Буфер',
											'isbuffer'	 => 1
											));
						}
						$bufferAccountId = $bufferAccount->id;

						/* от кого поступили деньги */
							// партнер у операции из выгрузки
				$budgetPartner						 = BudgetPartner::find($budgetOperation->budget_partner_id);
							// партнер для новой операции
				$newOperationBudgetPartner = BudgetPartner::whereCurrentAccount($budgetOperation->current_account)->whereProjectId($budgetDebtPartner->debet_project_id)->first();
				if ($newOperationBudgetPartner == null) { // создать партнера, если не найден
							$newOperationBudgetPartner = BudgetPartner::create(array(
											'project_id'			 => $budgetDebtPartner->debet_project_id,
											'name'						 => $budgetPartner->name,
											'city'						 => $budgetPartner->city,
											'current_account'	 => $budgetPartner->current_account,
											'cost_id'					 => $budgetPartner->cost_id
											));
						}

						BudgetOperation::create(array(
						'user_id'								 => $this->user->id,
																		'project_id'						 => $budgetDebtPartner->debet_project_id,
																		'date'									 => $budgetOperation->date,
																		'type'									 => BudgetOperation::TYPE_INCOMING,
																		'amount'								 => $budgetOperation->amount,
																		'budget_cost_id'				 => 0,
																		'budget_partner_id'			 => $newOperationBudgetPartner->id,
																		'budget_in_account_id'	 => $bufferAccountId,
																		'budget_out_account_id'	 => $bufferAccountId,
						'comment'								 => $budgetOperation->comment,
																		'debt_partner_id'				 => 0,
																		'isdebt'								 => 0,
																		'debt_comment'					 => '',
																		'isnoincome'						 => 0,
																		'isnooutcome'						 => 0,
																		'debt_parent_id'				 => $budgetOperation->id
						));
				}
			}else if (isset($input['dualOperationAdd']) && isset($input['is-checked-operation'])) { // отмечен чекбокс "Привязать зеркальную долговую операцию"
				// привязка
				$dualBudgetOperation = BudgetOperation::find($input['is-checked-operation']);
				if(count($dualBudgetOperation)){
					$dualBudgetOperation->debt_parent_id = $budgetOperation->id;
					$dualBudgetOperation->save();

					$budgetOperation->debt_parent_id = $dualBudgetOperation->id;
				}
			}
		}
		$costId = $budgetOperation->budget_cost_id;
		$salaryCosts = $budgetOperation->getSalaryCosts();
		if ($budgetOperation->type == 1 && $budgetOperation->isnooutcome == 0 && $budgetOperation->isdebt == 0 && in_array($costId, $salaryCosts)) {
			$budgetOperation->is_salary = 1;
		}
		else {
			$budgetOperation->is_salary = 0;
		}
		
		$budgetOperation->save();

		$budgetOperation   = BudgetOperation::withTrashed()->find($input['debt_operation_id']);
		$response = array(
				'status'		     => 'success',
				'child_deleted_id' => $childDeletedId,
				'id'				     => $budgetOperation->id,
				'operation'	     => View::make('budget.operations.operation')->with('user', $this->user)->with('budgetOperation', $budgetOperation)->render(),
		);
		return Response::json($response);
	}

	public function showCloseMonth() {
		$input = Input::all();

    $workProject = $this->workProject;
    $budgetCloseDay = ($workProject->budget_close_day)? $workProject->budget_close_day : 1;
    
		if (!$this->user->hasRole(Role::ROLE_BUDGET) 
        || !$this->user->budgetProjects->count() 
        || !BudgetOperation::whereProjectId($workProject->id)
            ->whereRaw( DB::raw('DATE(date) < '.date("'Y-m-".$budgetCloseDay."'")) )
            ->count()
        || ! (date('d') >= $budgetCloseDay)
       ) {
			return Redirect::to('budget');
		}
		if (Input::has('projectId')) {
			Session::put('work_projectId', $input['projectId']);
			return Redirect::to('budget');
		}

    $closeDateInfo = '';
    $budgetCloseDay = ($budgetCloseDay > 10)? $budgetCloseDay : '0'.$budgetCloseDay;
    $closeDateInfo = date($budgetCloseDay.'.m.Y').' (не вкл. '.$budgetCloseDay.' число)';
    
		return $this->setupLayout('budget.closemonth')
										->with('input', $input)
										->with('user', $this->user)
										->with('closeDateInfo', $closeDateInfo)
										->with('workProject', $workProject);
	}

	public function closeMonth() {
    $workProject = $this->workProject;
    $budgetCloseDay = ($workProject->budget_close_day)? $workProject->budget_close_day : 1;
    
		if (!$this->user->hasRole(Role::ROLE_BUDGET)
        || !$this->user->budgetProjects->count() 
        || !BudgetOperation::whereProjectId($workProject->id)
            //->whereRaw(DB::raw('DATE(created_at)!=DATE(NOW())'))
            ->whereRaw( DB::raw('DATE(date) < '.date("'Y-m-".$budgetCloseDay."'")) )
            ->count()
       ) {
			return Redirect::to('budget');
		}
    
		foreach ($workProject->budgetAccounts as $budgetAccount) {
			$sum = $budgetAccount->getEndSum();
			if ($sum) {
				$budgetOperation				 = BudgetOperation::create(array(
										'date'								 => date('Y-m-'.$budgetCloseDay)/*DB::raw('DATE(NOW())')*/,
										'type'								 => BudgetOperation::TYPE_OPENING_BALANCE,
										'budget_in_account_id' => $budgetAccount->id
				));
				$budgetOperation->user()->associate($this->user);
				$budgetOperation->project()->associate($workProject);
				$budgetOperation->amount = $sum;
				$budgetOperation->save();
			}
		}

		foreach ($workProject->budgetDebtPartners as $debtPartner) {
			$sum = $debtPartner->getEndSum();
			if ($sum) {
				$budgetOperation				 = BudgetOperation::create(array(
										'date'						 => date('Y-m-'.$budgetCloseDay)/*DB::raw('DATE(NOW())')*/,
										'type'						 => ($sum > 0 ) ? BudgetOperation::TYPE_OPENING_DEBT_OUT : BudgetOperation::TYPE_OPENING_DEBT_IN,
										'debt_partner_id'	 => $debtPartner->id
				));
				$budgetOperation->user()->associate($this->user);
				$budgetOperation->project()->associate($workProject);
				$budgetOperation->amount = abs($sum);
				$budgetOperation->save();
			}
		}

		DB::table('budget_operations')->whereProjectId($workProject->id)
						->whereRaw(DB::raw("deleted_at IS NULL"))
            ->whereRaw( DB::raw( "DATE(`budget_operations`.`date`) < '".date('Y-m-'.$budgetCloseDay)."'" ) )
						->update(array('isarchived' => 1, 'archived_at' => DB::raw('DATE(NOW())')));
    
		BudgetOperation::whereProjectId($workProject->id)
						->whereIsarchived(1)
						->delete();

		$budgetMonthPlan = $workProject->budgetMonthPlan()->whereIsarchived(0)->first(); // текущий бюджет
		$oldBudget			 = 0;
		if ($budgetMonthPlan) {
			$oldBudget									 = $budgetMonthPlan->month_plan;
			$budgetMonthPlan->isarchived = 1;
			$budgetMonthPlan->save();
		}
		// --> создание бюджета на новый месяц

		$budgetProjectMonthPlan = $workProject->budgetMonthPlan()->whereIsarchived(0)->get();
		if ($budgetProjectMonthPlan) {//после закрытия текущего бюджета чистим таблицу от возможных незакрытых бюджетов
			foreach ($budgetProjectMonthPlan as $budget) {
				$budget->delete();
			}
		}

		$budgetProjectMonthPlan = BudgetProjectMonthPlan::create(array(
								'project_id'	 => $workProject->id,
								'budget_date'	 => date('Y-m-d'),
								'month_plan'	 => $oldBudget / 100,
								'isarchived'	 => 0
		));
		// <--

		$response = array(
				'status' => 'success'
		);
		return Response::json($response);
	}

	//Экспорт расходов по одному проекту в Excel
	public function costExport($projectId, $endDate) {
		$project = Project::find($projectId);
		if (!$project) {
			return Redirect::to('budget');
		}

		Session::set('budget_export_projectId', $projectId);
		Session::set('end_date', $endDate);
		$fileName = "CostExport-{$project->id}-" . date('d-m-Y');
		Excel::create($fileName, function($excel) {
			$excel->sheet('Лист1', function($sheet) {
				$projectId = Session::get('budget_export_projectId');
				$project	 = Project::find($projectId);
				$endDate	 = Session::get('end_date');
				if ($project) {
					$sheet->loadView('budget.export.cost')->with('workProject', $project)->with('endDate', $endDate);
				}
			});
		})->store('xlsx');

		return Response::download('../app/storage/exports/' . $fileName . '.xlsx');
	}

	//Экспорт общих расходов в Excel
	public function totalCostExport($endDate) {

		Session::set('end_date', $endDate);
		$fileName = "TotalCostExport-" . date('d-m-Y');
		Excel::create($fileName, function($excel) {
			$excel->sheet('Общие расходы', function($sheet) {
				$endDate = Session::get('end_date');
				$sheet->loadView('budget.export.totalcosts')->with('user', Auth::user())->with('endDate', $endDate);
			});
		})->store('xlsx');

		return Response::download('../app/storage/exports/' . $fileName . '.xlsx');
	}

	//Экспорт архива общих расходов в Excel
	public function totalArchiveCostExport($startDate, $endDate) {

		Session::set('end_date', $endDate);
		Session::set('start_date', $startDate);
		$fileName = "TotalArchiveCostExport-" . date('d-m-Y');
		Excel::create($fileName, function($excel) {
			$excel->sheet('Архив общих расходов', function($sheet) {
				$endDate	 = Session::get('end_date');
				$startDate = Session::get('start_date');
				$sheet->loadView('budget.export.totalcostsarchive')->with('user', Auth::user())->with('endDate', $endDate)->with('startDate', $startDate);
			});
		})->store('xlsx');

		return Response::download('../app/storage/exports/' . $fileName . '.xlsx');
	}

	//Отчет Движение денежных средств
	public function ddsReport($projectId, $endDate) {
		$project = Project::find($projectId);
		if (!$project) {
			return Redirect::to('budget');
		}

		Session::set('budget_export_projectId', $projectId);
		Session::set('end_date', $endDate);
		$fileName = "DdsReport-{$project->id}-" . date('d-m-Y');
		Excel::create($fileName, function($excel) {
			$excel->sheet('Помесячный контроль план-факта', function($sheet) {
				$projectId = Session::get('budget_export_projectId');
				$endDate	 = Session::get('end_date');
				$project	 = Project::find($projectId);
				if ($project) {
					$sheet->loadView('budget.export.dds2')->with('workProject', $project)->with('endDate', $endDate);
				}
			});
			$excel->sheet('План-фактный анализ', function($sheet) {
				$projectId = Session::get('budget_export_projectId');
				$endDate	 = Session::get('end_date');
				$project	 = Project::find($projectId);
				if ($project) {
					$sheet->loadView('budget.export.dds')->with('workProject', $project)->with('endDate', $endDate);
				}
			});
		})->store('xlsx');

		return Response::download('../app/storage/exports/' . $fileName . '.xlsx');
	}

	public function showDebtPartnersOperations() {
		$input = Input::all();

		$projectId = $input['projectId'];
		$project	 = Project::find($projectId);
		if (!$project) {
			return Redirect::to('budget');
		}
		$partnerId = $input['partnerId'];
		$partner	 = BudgetDebtPartner::find($partnerId);
		if (!$partner) {
			return Redirect::to('budget');
		}
		$limBegin	 = $input['limBegin'];
		$count		 = $input['count'];

		if (($limBegin || $count)) {
			$lim = ' limit ' . $limBegin . ', ' . $count;
		}
		else {
			unset($lim);
		}

		$debtOperation = BudgetOperation::withTrashed()->whereIn('type', array(1, 2))/* ->whereNull('delete_user_id') */->whereRaw('debt_partner_id = ' . $partnerId . ' and project_id = ' . $project->id . ' and isdebt = 1 AND (deleted_at IS NULL OR isarchived=1) order by date desc ' . $lim)->get();
		//$debtOperation = BudgetOperation::whereIn('type', array(1, 2) )->whereRaw('debt_partner_id = '.$partnerId.' and project_id = '.$project->id.' and isdebt = 1 order by date desc '.$lim)->get();
		if ($debtOperation == null || !is_numeric($partner->id)) {
			$response = array('status' => 'fail', 'message' => 'Операции не найдены.');
			return Response::json($response);
		}
		$debtOperationQuant	 = BudgetOperation::withTrashed()
						->where('debt_partner_id', '=', $partnerId)
						->where('project_id', '=', $project->id)
						->where('isdebt', '=', '1')
						//->whereNull('delete_user_id')
						->whereIn('type', array(1, 2))
						->whereRaw(DB::raw("(deleted_at IS NULL OR isarchived=1)"))
						->count();
		$response						 = array(
				'status'		 => 'success',
				'total'			 => $debtOperationQuant,
				'operation'	 => $debtOperation->toArray()
		);

		return Response::json($response);
	}

}
