Skip to content

Commit

Permalink
change: add revenue report
Browse files Browse the repository at this point in the history
  • Loading branch information
mueller-berlus committed May 28, 2018
1 parent 5bb6114 commit 8834104
Show file tree
Hide file tree
Showing 14 changed files with 1,141 additions and 217 deletions.
123 changes: 123 additions & 0 deletions app/Http/Controllers/Api/v1/Modules/ReportController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?php

namespace App\Http\Controllers\Api\v1\Modules;

use App;
use App\Http\Controllers\Controller;
use App\Models\Einheiten;
use App\Models\Objekte;
use App\Models\RentDefinition;
use Carbon\Carbon;
use Illuminate\Http\Request;
use XLSXWriter;

class ReportController extends Controller
{
/**
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function revenue(Request $request, Objekte $object)
{
$file = tempnam(sys_get_temp_dir(), 'revenue_report_');
$start = Carbon::today()->firstOfYear();
$end = $start->copy()->lastOfYear();

if ($request->has('date')) {
$start = Carbon::parse($request->input('date'));
$end = Carbon::parse($request->input('date'));
}
if ($request->has('period')) {
$period = $request->input('period');
switch ($period) {
case 'year':
$start->firstOfYear();
$end->lastOfYear();
break;
case 'quarter':
$start->firstOfQuarter();
$end->lastOfQuarter();
break;
case 'month':
$start->firstOfMonth();
$end->lastOfMonth();
break;
}
}

$header = [
'Apartment No.' => 'string',
'Space' => '0.00',
'Occupant Name' => 'string',
'Contract Start' => 'date',
'Contract End' => 'date',
'Days Occupied' => 'integer',
'Basic Rent' => 'euro',
'Operating Costs' => 'euro',
'Heating Costs' => 'euro',
'Actual Payments' => 'euro'
];

$sheet = 'Revenue';

$writer = new XLSXWriter();

$writer->writeSheetHeader($sheet, $header);

$units = Einheiten::whereHas('haus.objekt', function ($query) use ($object) {
$query->where('OBJEKT_ID', $object->OBJEKT_ID);
})->with(['haus.objekt', 'mietvertraege.mieter'])->defaultOrder()->get();
$rows = 1;

foreach ($units as $unit) {
$rentalContracts = $unit->mietvertraege()
->where(function ($query) use ($start, $end) {
$query->where(function ($query) use ($start, $end) {
$query->active('>=', $start)
->active('<=', $end);
})->orWhere(function ($query) use ($start, $end) {
$query->whereHas('postings', function ($query) use ($start, $end) {
$query->where('KONTENRAHMEN_KONTO', 80001)
->where('KOSTENTRAEGER_TYP', 'Mietvertrag')
->whereDate('DATUM', '>=', $start)
->whereDate('DATUM', '<=', $end);
});
});
})->defaultOrder()->get();
if ($rentalContracts->isEmpty()) {
$writer->writeSheetRow($sheet, [$unit->EINHEIT_KURZNAME, $unit->EINHEIT_QM, '', '', '', 0, 0, 0, 0, 0]);
$rows++;
} else {
foreach ($rentalContracts as $index => $rentalContract) {
$basicRent = RentDefinition::sumDefinitions($rentalContract->basicRentDefinitions($start, $end), $start, $end);
$heatingCosts = RentDefinition::sumDefinitions($rentalContract->heatingExpenseDefinitions($start, $end), $start, $end);
$operatingCosts = RentDefinition::sumDefinitions($rentalContract->operatingCostDefinitions($start, $end), $start, $end);
$postings = $rentalContract->postings($start, $end)->where('KONTENRAHMEN_KONTO', 80001)->sum('BETRAG');
$occupantName = $rentalContract->mieter->implode('full_name', '; ');
$to = $rentalContract->MIETVERTRAG_BIS === '0000-00-00' ? '' : $rentalContract->MIETVERTRAG_BIS;
$row = ['', '', $occupantName, $rentalContract->MIETVERTRAG_VON, $to, $rentalContract->overlaps($start, $end), $basicRent, $operatingCosts, $heatingCosts, $postings];
if ($index === 0) {
$row[0] = $unit->EINHEIT_KURZNAME;
$row[1] = $unit->EINHEIT_QM;
}
$writer->writeSheetRow($sheet, $row);
$rows++;
}
}
}
$row = ['Total', "=SUM(B2:B$rows)", '', '', '', '', "=SUM(G2:G$rows)", "=SUM(H2:H$rows)", "=SUM(I2:I$rows)", "=SUM(J2:J$rows)"];
$writer->writeSheetRow($sheet, $row);
$writer->writeSheetRow($sheet, ['', '', '', '', '', '', '', '', '', '']);
$writer->writeSheetRow($sheet, ['', '', 'Query Period:', $start->toDateString(), $end->toDateString(), '', '', '', '', '']);

$writer->writeToFile($file);

$filename = 'revenue_report_'
. $object->OBJEKT_KURZNAME . '_'
. $start->toDateString() . '_'
. $end->toDateString() . '_created_at_'
. Carbon::today()->toDateString();

return response()->file($file, ['Content-Disposition' => 'inline; filename="' . $filename . '.xlsx'])->deleteFileAfterSend(true);
}
}
80 changes: 80 additions & 0 deletions app/Models/Mietvertraege.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use App\Models\Traits\Active;
use App\Models\Traits\DefaultOrder;
use App\Models\Traits\Searchable;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

Expand Down Expand Up @@ -74,4 +75,83 @@ public function scopeSearch($query, $tokens)
});
return $query;
}

public function basicRentDefinitions($from = null, $to = null)
{
return $this->rentDefinitions($from, $to)
->where(function ($query) {
$query->where('KOSTENKATEGORIE', '=', 'Miete kalt')
->orWhere('KOSTENKATEGORIE', '=', 'MHG')
->orWhere('KOSTENKATEGORIE', '=', 'Mietminderung')
->orWhere('KOSTENKATEGORIE', '=', 'MOD')
->orWhere('KOSTENKATEGORIE', '=', 'Stellplatzmiete')
->orWhere('KOSTENKATEGORIE', '=', 'Untermieter Zuschlag');
});
}

public function rentDefinitions($from = null, $to = null)
{
if (is_string($from)) {
$from = Carbon::parse($from);
}
if (is_string($to)) {
$to = Carbon::parse($to);
}
$rentDefinitions = $this->morphMany(RentDefinition::class, 'rentDefinitions', 'KOSTENTRAEGER_TYP', 'KOSTENTRAEGER_ID');
if ($from) {
$rentDefinitions->whereDate('ANFANG', '<=', $to);
}
if ($to) {
$rentDefinitions->where(function ($query) use ($from) {
$query->whereDate('ENDE', '>=', $from)
->orWhere('ENDE', '0000-00-00');
});
}
return $rentDefinitions;
}

public function heatingExpenseDefinitions($from = null, $to = null)
{
return $this->rentDefinitions($from, $to)
->where(function ($query) {
$query->where('KOSTENKATEGORIE', 'LIKE', 'Heizkostenabrechnung%')
->orWhere('KOSTENKATEGORIE', '=', 'Heizkosten Vorauszahlung');
});
}

public function operatingCostDefinitions($from = null, $to = null)
{
return $this->rentDefinitions($from, $to)
->where(function ($query) {
$query->where('KOSTENKATEGORIE', 'LIKE', 'Betriebskostenabrechnung%')
->orWhere('KOSTENKATEGORIE', 'LIKE', 'Kabel TV%')
->orWhere('KOSTENKATEGORIE', 'LIKE', 'Kaltwasserabrechnung%')
->orWhere('KOSTENKATEGORIE', '=', 'Nebenkosten Vorauszahlung')
->orWhere('KOSTENKATEGORIE', 'LIKE', 'Thermenwartung%');
});
}

public function openingBalanceDefinitions($from = null, $to = null)
{
return $this->rentDefinitions($from, $to)
->where('KOSTENKATEGORIE', '=', 'Saldo Vortrag Vorverwaltung');
}

public function postings($from = null, $to = null)
{
if (is_string($from)) {
$from = Carbon::parse($from);
}
if (is_string($to)) {
$to = Carbon::parse($to);
}
$rentDefinitions = $this->morphMany(Posting::class, 'postings', 'KOSTENTRAEGER_TYP', 'KOSTENTRAEGER_ID');
if ($from) {
$rentDefinitions->whereDate('DATUM', '>=', $from);
}
if ($to) {
$rentDefinitions->whereDate('DATUM', '<=', $to);
}
return $rentDefinitions;
}
}
33 changes: 33 additions & 0 deletions app/Models/Posting.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace App\Models;

use App\Models\Scopes\AktuellScope;
use Illuminate\Database\Eloquent\Model;

class Posting extends Model
{
protected $table = 'GELD_KONTO_BUCHUNGEN';
protected $primaryKey = 'GELD_KONTO_BUCHUNGEN_ID';

/**
* The attributes that are not mass assignable.
*
* @var array
*/
protected $guarded = [];

/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [];

protected static function boot()
{
parent::boot();

static::addGlobalScope(new AktuellScope());
}
}
85 changes: 85 additions & 0 deletions app/Models/RentDefinition.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

class RentDefinition extends Model
{
protected $table = 'MIETENTWICKLUNG';
protected $primaryKey = 'MIETENTWICKLUNG_ID';

/**
* The attributes that are not mass assignable.
*
* @var array
*/
protected $guarded = [];

/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [];

public static function sumDefinitions($query, $from = null, $to = null)
{
return $query->get()->reduce(function ($carry, $item) use ($from, $to) {
return $carry + $item->value($from, $to);
}, 0);
}

protected static function boot()
{
parent::boot();

static::addGlobalScope('aktuell', function (Builder $builder) {
$builder->where('MIETENTWICKLUNG_AKTUELL', '1');
});
}

public function value($from = null, $to = null)
{
$definition_from = Carbon::parse($this->ANFANG);
$definition_to = $this->ENDE === '0000-00-00' ? Carbon::maxValue() : Carbon::parse($this->ENDE);
if (is_null($from)) {
$from = $definition_from;
}
if (is_null($to)) {
$to = $definition_to;
}
if (is_string($from)) {
$from = Carbon::parse($from);
}
if (is_string($to)) {
$to = Carbon::parse($to);
}
$from = $definition_from->max($from);
$to = $definition_to->min($to);
$diffInMonths = $from->diffInMonths($to);
$value = 0;
if ($definition_from->diffInMonths($definition_to) == 0) {
$value = $this->BETRAG;
} else {
if ($diffInMonths == 0) {
$value = (($from->diffInDays($to) + 1) / $from->daysInMonth) * $this->BETRAG;
} else {
if ($from->day == 1) {
$value += $this->BETRAG;
} else {
$value += ($from->day / $from->daysInMonth) * $this->BETRAG;
}
if ($to->day == $to->daysInMonth) {
$value += $this->BETRAG;
} else {
$value += ($to->day / $to->daysInMonth) * $this->BETRAG;
}
$value += $this->BETRAG * ($diffInMonths - 1);
}
}
return $value;
}
}
14 changes: 13 additions & 1 deletion app/Models/Traits/Active.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public function scopeActive($query, $comparator = '=', $date = null)
{
if (is_null($date)) {
$date = Carbon::today();
} else {
} elseif (is_string($date)) {
$date = Carbon::parse($date);
}
$start = $this->getStartDateFieldName();
Expand Down Expand Up @@ -123,4 +123,16 @@ public function isActive($comparator = '=', Carbon $date = null)
return false;
}
}

public function overlaps(Carbon $start, Carbon $end)
{
$start = Carbon::parse($this->{$this->getStartDateFieldName()})->max($start);
$end_field = $this->{$this->getEndDateFieldName()} === '0000-00-00' ? Carbon::maxValue()
: Carbon::parse($this->{$this->getEndDateFieldName()});
$end = $end_field->min($end);
if ($start->lte($end)) {
return $start->diffInDays($end) + 1;
}
return 0;
}
}
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
"php": ">=5.6.4",
"barryvdh/laravel-debugbar": "^2.3",
"barryvdh/laravel-ide-helper": "v2.*",
"damienlagae/xlsxwriter": "^1.0",
"doctrine/dbal": "^2.5",
"kingsquare/php-mt940": "dev-berlussimo",
"laravel/framework": "5.4.*",
"laravel/passport": "^3.0",
"laravel/tinker": "~1.0",
Expand All @@ -20,8 +22,7 @@
"propaganistas/laravel-phone": "^2.8",
"rospdf/pdf-php": "0.12.40",
"smarty/smarty-lexer": "3.1.29",
"spatie/laravel-permission": "^1.4",
"kingsquare/php-mt940": "dev-berlussimo"
"spatie/laravel-permission": "^1.4"
},
"require-dev": {
"fzaninotto/faker": "~1.4",
Expand Down
Loading

0 comments on commit 8834104

Please sign in to comment.