company->db); App::forgetInstance('translator'); App::setLocale($this->company->locale()); $t = app('translator'); $t->replace(Ninja::transformTranslations($this->company->settings)); $this->csv = Writer::createFromString(); $this->csv->insertOne([]); $this->csv->insertOne([]); $this->csv->insertOne([]); $this->csv->insertOne([]); $this->csv->insertOne([ctrans('texts.aged_receivable_summary_report')]); $this->csv->insertOne([ctrans('texts.created_on'),' ',$this->translateDate(now()->format('Y-m-d'), $this->company->date_format(), $this->company->locale())]); if (count($this->input['report_keys']) == 0) { $this->input['report_keys'] = $this->report_keys; } $this->csv->insertOne($this->buildHeader()); Client::query() ->where('company_id', $this->company->id) ->where('is_deleted', 0) ->orderBy('balance', 'desc') ->cursor() ->each(function ($client) { $this->csv->insertOne($this->buildRow($client)); }); return $this->csv->toString(); } private function buildRow(Client $client): array { $this->client = $client; return [ $this->client->present()->name(), $this->client->number, $this->client->id_number, $this->getCurrent(), $this->getAgingAmount('30'), $this->getAgingAmount('60'), $this->getAgingAmount('90'), $this->getAgingAmount('120'), $this->getAgingAmount('120+'), ]; } private function getCurrent(): string { $amount = Invoice::withTrashed() ->where('client_id', $this->client->id) ->where('company_id', $this->client->company_id) ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) ->where('balance', '>', 0) ->where('is_deleted', 0) ->where(function ($query){ $query->where('due_date', '>', now()->startOfDay()) ->orWhereNull('due_date'); }) ->sum('balance'); return Number::formatMoney($amount, $this->client); } /** * Generate aging amount. * * @param mixed $range * @return string */ private function getAgingAmount($range) { $ranges = $this->calculateDateRanges($range); $from = $ranges[0]; $to = $ranges[1]; $amount = Invoice::withTrashed() ->where('client_id', $this->client->id) ->where('company_id', $this->client->company_id) ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) ->where('balance', '>', 0) ->where('is_deleted', 0) ->whereBetween('due_date', [$to, $from]) ->sum('balance'); return Number::formatMoney($amount, $this->client); } /** * Calculate date ranges for aging. * * @param mixed $range * @return array */ private function calculateDateRanges($range) { $ranges = []; switch ($range) { case '30': $ranges[0] = now()->startOfDay(); $ranges[1] = now()->startOfDay()->subDays(30); return $ranges; case '60': $ranges[0] = now()->startOfDay()->subDays(31); $ranges[1] = now()->startOfDay()->subDays(60); return $ranges; case '90': $ranges[0] = now()->startOfDay()->subDays(61); $ranges[1] = now()->startOfDay()->subDays(90); return $ranges; case '120': $ranges[0] = now()->startOfDay()->subDays(91); $ranges[1] = now()->startOfDay()->subDays(120); return $ranges; case '120+': $ranges[0] = now()->startOfDay()->subDays(121); $ranges[1] = now()->startOfDay()->subYears(20); return $ranges; default: $ranges[0] = now()->startOfDay()->subDays(0); $ranges[1] = now()->subDays(30); return $ranges; } } public function buildHeader() :array { $header = []; foreach ($this->input['report_keys'] as $value) { $header[] = ctrans("texts.{$value}"); } return $header; } }