<?php
namespace App\Services;
use App\Entity\Bill;
use App\Entity\BillPayment;
use App\Entity\Building;
use App\Entity\Company;
use App\Entity\Flat;
use App\Entity\User;
use App\Enums\BillPaymentTypeEnum;
use App\Enums\BuildingTypeEnum;
use App\Enums\CompanyActionEnum;
use App\Enums\CompanyRoleEnum;
use App\Helpers\CommonHelper;
use App\Repository\BillPaymentRepository;
use App\Repository\BillRepository;
use App\Repository\BuildingRepository;
use App\Repository\CompanyRepository;
use App\Repository\FlatRepository;
use App\Repository\GenerateBillsNotificationRepository;
use App\Repository\PartnersRepository;
use App\Repository\UserRepository;
use App\Utils\ApiV2\ListItemsOptions;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use Exception;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx\Worksheet;
use Symfony\Component\Form\FormInterface;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
class BuildingService
{
private EntityManagerInterface $entityManager;
private string $qrCode;
private PartnersService $partnersService;
private QRCodeService $QRCodeService;
private UserRepository $userRepository;
private BuildingRepository $buildingRepository;
private BillRepository $billRepository;
private GenerateBillsNotificationRepository $generateBillsNotificationRepository;
private JobQueueService $jobQueueService;
private PartnersRepository $partnersRepository;
private DefaultService $defaultService;
private CompanyRepository $companyRepository;
private FlatRepository $flatRepository;
private BillPaymentRepository $billPaymentRepository;
private FlatParserService $flatParserService;
private BuildingParserService $buildingParserService;
private string $projectDir;
private MoneyLogService $moneyLogService;
private HashIdService $hashIdService;
/**
* @param EntityManagerInterface $entityManager
* @param PartnersService $partnersService
* @param QRCodeService $QRCodeService
* @param UserRepository $userRepository
* @param BuildingRepository $buildingRepository
* @param PartnersRepository $partnersRepository
* @param BillRepository $billRepository
* @param GenerateBillsNotificationRepository $generateBillsNotificationRepository
* @param JobQueueService $jobQueueService
* @param string $qrCode
* @param DefaultService $defaultService
* @param CompanyRepository $companyRepository
* @param FlatRepository $flatRepository
* @param BillPaymentRepository $billPaymentRepository
* @param FlatParserService $flatParserService
* @param BuildingParserService $buildingParserService
* @param string $projectDir
* @param MoneyLogService $moneyLogService
* @param HashIdService $hashIdService
*/
public function __construct(
EntityManagerInterface $entityManager,
PartnersService $partnersService,
QRCodeService $QRCodeService,
UserRepository $userRepository,
BuildingRepository $buildingRepository,
PartnersRepository $partnersRepository,
BillRepository $billRepository,
GenerateBillsNotificationRepository $generateBillsNotificationRepository,
JobQueueService $jobQueueService,
string $qrCode,
DefaultService $defaultService,
CompanyRepository $companyRepository,
FlatRepository $flatRepository,
BillPaymentRepository $billPaymentRepository,
FlatParserService $flatParserService,
BuildingParserService $buildingParserService,
string $projectDir,
MoneyLogService $moneyLogService,
HashIdService $hashIdService
) {
$this->entityManager = $entityManager;
$this->qrCode = $qrCode;
$this->partnersService = $partnersService;
$this->QRCodeService = $QRCodeService;
$this->userRepository = $userRepository;
$this->buildingRepository = $buildingRepository;
$this->billRepository = $billRepository;
$this->generateBillsNotificationRepository = $generateBillsNotificationRepository;
$this->jobQueueService = $jobQueueService;
$this->partnersRepository = $partnersRepository;
$this->defaultService = $defaultService;
$this->companyRepository = $companyRepository;
$this->flatRepository = $flatRepository;
$this->billPaymentRepository = $billPaymentRepository;
$this->flatParserService = $flatParserService;
$this->buildingParserService = $buildingParserService;
$this->projectDir = $projectDir;
$this->moneyLogService = $moneyLogService;
$this->hashIdService = $hashIdService;
}
/**
* @param Building $building
* @param FormInterface $form
* @param int $type
*
* @return void
* @throws NonUniqueResultException
*/
public function createBuilding(Building $building, FormInterface $form, int $type): void
{
if ($type === BuildingTypeEnum::TYPE_BUSINESS_SPACE->value) {
$address = $form->getData()->getBuildingIdBs()->getAddress();
$matId = $form->getData()->getBuildingIdBs()->getMatId();
$pib = $form->getData()->getBuildingIdBs()->getPib();
$bankAccount = $form->getData()->getBuildingIdBs()->getBankAccount();
$building->setAddress($address);
$building->setMatId($matId);
$building->setPib($pib);
$building->setBankAccount($bankAccount);
}
$building->setCreatedAt(new DateTime('now'));
$building->setUpdatedAt(new DateTime('now'));
$building->setType($type);
$this->entityManager->persist($building);
$startAmountsData = $form->get('start_amounts')->getData();
$this->createStartAmounts($startAmountsData, $building);
$this->entityManager->flush();
$this->partnersService->createNewPartnerIfNotExist($building);
$this->QRCodeService->createQRCodeForBuilding($building->getId(), $this->qrCode);
}
/**
* @param User $user
*
* @return array<mixed>
* @throws NonUniqueResultException
* @throws Exception
*/
public function getBuildingNotificationList(User $user): array
{
$companyUsers = $this->userRepository->findUsersByMain($user);
$buildings = $this->buildingRepository->getAllBuildingsByCompanyUsers($companyUsers, 1);
$lastBillMonth = new DateTime('2000-01-01');
foreach ($buildings as $building) {
/** @var Bill $lastBill */
$lastBill = $this->billRepository->findLastBillByBuilding($building);
if ($lastBill !== null && $lastBill->getMonth() > $lastBillMonth) {
$lastBillMonth = $lastBill->getMonth();
}
}
$lastBillMonth = CommonHelper::getMonth($lastBillMonth->modify("-1MONTH"));
$notifications = $this->generateBillsNotificationRepository->getBuildingsNotificationByUserAndMonth(
$user,
$lastBillMonth
);
return [
'buildings' => $buildings,
'notifications' => $notifications,
];
}
/**
* @param array<Building> $buildings
*
* @return array<mixed>
* @throws NonUniqueResultException
*/
public function getBuildingForChoiceAndMonths(array $buildings): array
{
$buildingForMonths = new Building();
$lastBillMonth = new DateTime('2000-01-01');
$buildingsForChoice = [];
$buildingsForChoice['Stambene zajednice'] = [];
if (!empty($buildings)) {
$buildingsForChoice['Stambene zajednice']['Selektuj sve stambene zajednice'] = "All";
}
/** @var Building $building */
foreach ($buildings as $building) {
$buildingsForChoice['Stambene zajednice'][$building->getAddress()] = $building->getAddress();
/** @var Bill $lastBill */
$lastBill = $this->billRepository->findLastBillByBuilding($building);
if ($lastBill !== null && $lastBill->getMonth() > $lastBillMonth) {
$lastBillMonth = $lastBill->getMonth();
$buildingForMonths = $building;
}
}
return [
'buildingsForChoice' => $buildingsForChoice,
'buildingForMonths' => $buildingForMonths
];
}
/**
* @param FormInterface $form
* @param User $user
* @param array<Building> $buildings
*
* @return void
*/
public function createNewBillForBuildings(FormInterface $form, User $user, array $buildings): void
{
$month = $form->getData()['month']->format('Y-m-01');
$createBillDate = $form->getData()['createBillDate']->format('Y-m-d');
$dueDate = $form->getData()['dueDate']->format('Y-m-d');
$title = $form->getData()['title'];
$buildingsAddresses = $form->getData()['buildings'];
$exclusion = $form->getData()['buildingExclusion'];
$buildingsIds = [];
if ($buildingsAddresses[0] === "All") {
foreach ($buildings as $building) {
$buildingsIds[] = $building->getId();
}
} else {
$allBuildingsIds = [];
foreach ($buildings as $building) {
$allBuildingsIds[] = $building->getId();
}
foreach ($buildingsAddresses as $buildingAddress) {
$buildingId = ($this->buildingRepository->findOneBy(['address' => $buildingAddress]))->getId();
if ($exclusion) {
$buildingsIds[] = $buildingId;
} else {
foreach ($allBuildingsIds as $key => $id) {
if ($buildingId === $id) {
array_splice($allBuildingsIds, $key, 1);
}
}
$buildingsIds = $allBuildingsIds;
}
}
}
$this->jobQueueService->generateBillsJob(
$user->getId(),
$month,
$createBillDate,
$dueDate,
$title,
$buildingsIds
);
$this->jobQueueService->moneyLogFlatCalculationAfterBillGeneratingJob($user);
}
/**
* @param array<int> $buildingsIds
*
* @return array<Building>
*/
public function getBuildingsObj(array $buildingsIds): array
{
$buildingsArray = [];
$i = 0;
foreach ($buildingsIds as $buildingId) {
$buildingsArray[$i] = $this->buildingRepository->find(['id' => $buildingId]);
$i = $i + 1;
}
return $buildingsArray;
}
/**
* @param array<User> $users
*
* @return array<int, string>
*/
public function getBuildingCountByUsers(array $users): array
{
$ids = array_map(function ($user) {
return $user->getId();
}, $users);
$retArray = $this->buildingRepository->getBuildingCountByUserIds($ids);
$assocArrayWithCounts = [];
foreach ($retArray as $item) {
$assocArrayWithCounts[$item['userId']] = $item['buildingsCount'];
}
return $assocArrayWithCounts;
}
/**
* @param array<Company> $assignedBuildings
*
* @return array<mixed>
*/
public function getAssignedBuildingsData(array $assignedBuildings): array
{
$actionData = [];
/** @var Company $record */
foreach ($assignedBuildings as $record) {
$data = json_decode($record->getActionData(), true);
$data['assignedAt'] = $record->getCreatedAt();
$data['buildingId'] = $record->getBuildingId();
$data['deleted'] = $this->buildingRepository->find($record->getBuildingId()) === null;
$actionData[] = $data;
}
return $actionData;
}
/**
* @param array<Company> $deletedBuildings
*
* @return array<mixed>
*/
public function getDeletedBuildingsData(array $deletedBuildings): array
{
$actionData = [];
/** @var Company $record */
foreach ($deletedBuildings as $record) {
$data = json_decode($record->getActionData(), true);
$data['deletedAt'] = $record->getCreatedAt();
$actionData[] = $data;
}
return $actionData;
}
/**
* @param Building $building
*
* @return array<mixed>
*/
public function makeBuildingArrayForCompanyRecord(Building $building): array
{
$actionDataArray = [];
$actionDataArray['createdAt'] = $building->getCreatedAt();
$actionDataArray['updatedAt'] = $building->getUpdatedAt();
$actionDataArray['code'] = $building->getCode();
$actionDataArray['address'] = $building->getAddress();
$actionDataArray['city'] = $building->getCity();
$actionDataArray['flats'] = $building->getFlats();
$actionDataArray['buildingSize'] = $building->getBuildingSize();
$actionDataArray['population'] = $building->getPopulation();
$actionDataArray['pib'] = $building->getPib();
$actionDataArray['bankAccount'] = $building->getBankAccount();
$actionDataArray['matId'] = $building->getMatId();
$actionDataArray['email'] = $building->getEmail();
return $actionDataArray;
}
/**
* @param User $user
* @param int $type
*
* @return array<mixed>
*/
public function getBuildingListPdf(User $user, int $type): array
{
$companyUsers = $this->userRepository->findUsersByMain($user);
/** @var array<Building> $buildings */
$buildings = $this->buildingRepository->getActiveBuildingsByUserObj($companyUsers, $type);
$view = '@views/Building/PDF/List/buildingListPDF.html.twig';
if ($user->isUserCyrillic()) {
$view = '@views/Building/PDF/List/buildingListCyrillicPDF.html.twig';
}
return [
'buildings' => $buildings,
'view' => $view
];
}
/**
* @param FormInterface $form
* @param Building $building
* @param User $user
* @param bool $lastBill
*
* @return void
* @throws NoResultException
* @throws NonUniqueResultException
*/
public function updateBuilding(FormInterface $form, Building $building, User $user, bool $lastBill): void
{
$building->setUpdatedAt(new DateTime('now'));
if ($building->getType() === BuildingTypeEnum::TYPE_BUSINESS_SPACE->value) {
$address = $form->getData()->getBuildingIdBs()->getAddress();
$matId = $form->getData()->getBuildingIdBs()->getMatId();
$pib = $form->getData()->getBuildingIdBs()->getPib();
$bankAccount = $form->getData()->getBuildingIdBs()->getBankAccount();
$building->setAddress($address);
$building->setMatId($matId);
$building->setPib($pib);
$building->setBankAccount($bankAccount);
}
if ($building->getType() === BuildingTypeEnum::TYPE_BUILDING->value) {
$address = $form->getData()->getAddress();
$matId = $form->getData()->getMatId();
$pib = $form->getData()->getPib();
$bankAccount = $form->getData()->getBankAccount();
$this->buildingRepository->updateBusinessSpaceInformationByBuilding(
$user,
$building,
$address,
$matId,
$pib,
$bankAccount
);
}
// if (!$lastBill) {
$lastPayments = $this->billPaymentRepository->findAllStartDataPaymentsForBuilding($building, $user);
foreach ($lastPayments as $payment) {
$this->billPaymentRepository->remove($payment);
}
$startAmountsData = $form->get('start_amounts')->getData();
$this->createStartAmounts($startAmountsData, $building);
// }
$partner = $this->partnersRepository->getPartnerAsBuilding($user, $building);
if ($partner) {
$this->partnersService->updatePartnerData($partner, $building);
}
$this->buildingRepository->flush();
}
public function deleteBuilding(FormInterface $form, User $user): void
{
$id = $form->getData()['id'];
/** @var Building $building */
$building = $this->buildingRepository->find($id);
$building->setBuildingIdBs(null);
$this->defaultService->checkEntity($building, $user);
if (count($this->userRepository->findUsersByMain($user)) !== 1 || $user->getMainUser()) {
$companyAction = new Company();
$companyAction->setMainUser($user->getSharedCompanyUser());
if ($user->getCompanyRole() === CompanyRoleEnum::RADNIK->value) {
$companyAction->setMainUser($user->getMainUser()->getSharedCompanyUser());
}
$companyAction->setAction(CompanyActionEnum::DELETE_COMPANY_BUILDING->value);
$actionDataArray = $this->makeBuildingArrayForCompanyRecord($building);
$actionDataArray['deletedBy'] = $user->getFullName();
$actionData = json_encode($actionDataArray);
$companyAction->setActionData($actionData);
$companyAction->setBuildingId($building->getId());
$this->companyRepository->save($companyAction);
}
$this->buildingRepository->remove($building);
}
/**
* @param User $user
*
* @return array<Building>
*/
public function getBuildingsThatAreNotPartners(User $user): array
{
$companyUsers = $this->userRepository->findUsersByMain($user);
$allBuildingsIds = $this->buildingRepository->getBuildingsIdsForUser($companyUsers);
$allBuildingsIdsArray = [];
foreach ($allBuildingsIds as $buildingId) {
$allBuildingsIdsArray[] = $buildingId['id'];
}
$buildingsThatArePartners = $this->partnersRepository->getPartnersThatAreBuildings(
$companyUsers,
$user->getMainUser()
);
$partnersIdsArray = [];
foreach ($buildingsThatArePartners as $buildingId) {
$partnersIdsArray[] = $buildingId['id'];
}
return array_diff($allBuildingsIdsArray, $partnersIdsArray);
}
/**
* @param User $user
* @param Building $building
*
* @return array<mixed>
*/
public function getOldDebitByFlat(User $user, Building $building): array
{
$flats = $this->flatRepository->getFlatsByBuilding($user, $building);
$oldDebits = [];
foreach ($flats as $index => $flat) {
$oldDebits[$flat['displayFlatId']] = $flat['oldDebit'];
}
return $oldDebits;
}
/**
* @param array<mixed> $billOptions
* @param array<mixed> $optionNames
* @param array<mixed> $logsArray
* @param bool $period
*
* @return array<mixed>
*/
public function getArrayForTable(
array $billOptions,
array $optionNames,
array $logsArray,
bool $period = false
): array {
$columns = [];
$columns[] = 'Br. stana';
$columns[] = 'Ime vlasnika';
foreach ($billOptions as $option) {
if (array_key_exists($option, $optionNames)) {
$columns[] = $optionNames[$option];
}
}
$columns[] = 'Ukupno obračunato za period';
$columns[] = 'Ukupno naplaćeno za period';
if (!$period) {
$columns[] = 'Preostali dug za pariod';
} else {
$columns[] = 'Ukupan dug';
}
$list = [];
$list[0] = $columns;
$loop = 1;
$billSaldo = 0;
$paidSaldo = 0;
$leftSaldo = 0;
foreach ($logsArray as $month) {
foreach ($month as $displayFlatId => $flat) {
$list[$loop][] = $displayFlatId;
if (
array_key_exists('companyName', $flat['monthlyBill']['details']) &&
$flat['monthlyBill']['details']['companyName']
) {
$list[$loop][] = $flat['monthlyBill']['details']['companyName'];
} else {
$list[$loop][] = explode(",", $flat['monthlyBill']['vlasnik_data'])[0];
}
foreach ($billOptions as $option) {
if (array_key_exists($option, $flat)) {
$list[$loop][] = $flat[$option];
} else {
$list[$loop][] = 0;
}
}
$list[$loop][] = $flat['sum'];
$billSaldo += $flat['sum'];
$list[$loop][] = $flat['paid'];
$paidSaldo += $flat['paid'];
$list[$loop][] = $flat['leftDebit'];
$leftSaldo += $flat['leftDebit'];
$loop += 1;
}
}
$i = 1;
while ($i < count($columns) - 3) {
$list[$loop][] = '';
$i += 1;
}
$list[$loop][] = 'Ukupno:';
$list[$loop]['billSaldo'] = $billSaldo;
$list[$loop]['paidSaldo'] = $paidSaldo;
$list[$loop]['leftSaldo'] = $leftSaldo;
return $list;
}
/**
* @param Building|array<string, string> $buildingObject
*
* @return Building
*/
public function createBuildingAction(Building|array $buildingObject): Building
{
$building = new Building();
$building->setAddress($buildingObject['address']);
$building->setEmail($buildingObject['email'] ?? null);
$building->setActiveStatus(1);
$this->entityManager->persist($building);
return $building;
}
/**
* @param Building $building
* @param array<mixed> $buildingObject
*
* @return Building
*/
public function updateBuildingAction(Building $building, array $buildingObject): Building
{
$building->setAddress($buildingObject['address']);
return $building;
}
/**
* @param User $user
* @param ListItemsOptions $listItemsOptions
* @param int $status
*
* @return array<string, mixed>
* @throws NoResultException
* @throws NonUniqueResultException
*/
public function getBuildingsPaginatedApi(User $user, ListItemsOptions $listItemsOptions, int $status): array
{
return [
'data' => $this->buildingRepository->getBuildingAddressesByUserPaginatedApi(
$user,
$status,
$listItemsOptions
),
'count' => $this->buildingRepository->countBuildingAddressesByUserPaginatedApi($user, $status)
];
}
/**
* @param array<mixed> $startAmountsData
* @param Building $building
* @return void
*/
public function createStartAmounts(array $startAmountsData, Building $building): void
{
foreach ($startAmountsData as $startAmount) {
if (empty($startAmount['option'])) {
continue;
}
if (!empty($startAmount['value'])) {
$payment = new BillPayment();
$payment->setBuilding($building);
$payment->setUser($building->getUser());
$payment->setValue($startAmount['value']);
$payment->setType((string)$startAmount['option']);
$payment->setIncome(BillPaymentTypeEnum::POCETNO_STANJE->value);
$payment->setCreatedAt($startAmount['date'] ?? new DateTime('now'));
$this->entityManager->persist($payment);
}
if (!empty($startAmount['valueDebit'])) {
$payment = new BillPayment();
$payment->setBuilding($building);
$payment->setUser($building->getUser());
$payment->setValue($startAmount['valueDebit']);
$payment->setType((string)$startAmount['option']);
$payment->setIncome(BillPaymentTypeEnum::POCETNI_DUG->value);
$payment->setCreatedAt($startAmount['date'] ?? new DateTime('now'));
$this->entityManager->persist($payment);
}
}
}
/**
* @param Building $building
* @return array<mixed>
*/
public function getStartAmountInitialDataForBuilding(Building $building): array
{
$startAmounts = $this->billPaymentRepository
->getBillPaymentsByIncome(BillPaymentTypeEnum::POCETNO_STANJE->value, $building, $building->getUser());
$startDebits = $this->billPaymentRepository
->getBillPaymentsByIncome(BillPaymentTypeEnum::POCETNI_DUG->value, $building, $building->getUser());
$data = [];
foreach ($startAmounts as $payment) {
$data[$payment['type']]['value'] = $payment['value'];
$data[$payment['type']]['option'] = $payment['type'];
$data[$payment['type']]['date'] = $payment['createdAt'];
}
/** @var BillPayment $payment */
foreach ($startDebits as $payment) {
$data[$payment['type']]['valueDebit'] = $payment['value'];
$data[$payment['type']]['option'] = $payment['type'];
$data[$payment['type']]['date'] = $payment['createdAt'];
}
return array_values($data);
}
/**
* @param array<mixed> $data
* @param array<mixed> $errors
* @return void
*/
public function handleBuildingImport(
array $data,
array &$errors
): void {
$id = $data['userId'];
$user = $this->userRepository->find($id);
$file = $data['file'];
$reader = $this->buildingParserService->parseFile($file);
$buildings = $reader['building'];
foreach ($buildings as $index => $building) {
if (!$reader['valid'][$index]) {
$errors[] = $index;
continue;
}
$foundBuilding = $this->buildingRepository->findOneBy(['user' => $user, 'code' => $building['code']]);
if ($foundBuilding != null) {
continue;
}
$newBuilding = new Building();
$newBuilding->setUser($user);
$newBuilding->setActiveStatus(1);
$newBuilding->setAddress($building['address']);
$newBuilding->setBankAccount($building['bankAccount']);
$newBuilding->setPostCode($building['postCode']);
$newBuilding->setCity($building['city']);
$newBuilding->setMunicipality($building['municipality']);
$newBuilding->setComment($building['comment']);
$newBuilding->setCode($building['code']);
$newBuilding->setEmail($building['email']);
$newBuilding->setConstructionYear($building['constructionYear']);
$newBuilding->setStartingMoney($building['startingMoney']);
$newBuilding->setType(1);
$newBuilding->setCreatedAt(new \DateTime('now'));
$newBuilding->setUpdatedAt(new \DateTime('now'));
$newBuilding->setMatId($building['matId']);
$newBuilding->setPib($building['pib']);
$this->buildingRepository->save($newBuilding);
$this->QRCodeService->createQRCodeForBuilding($newBuilding->getId(), $this->projectDir);
}
}
/**
* @param array<mixed> $data
* @param array<mixed> $errors
* @return void
*/
public function handleFlatsImport(array $data, array &$errors): void
{
$file = $data['file'];
$reader = $this->flatParserService->parseFile($file);
$buildingAddress = $reader['building'];
$building = $this->buildingRepository->findOneBy(['address' => $buildingAddress]);
$flats = $reader['flats'];
if (!$building) {
$errors[] = 'Building not found';
return;
}
foreach ($flats as $index => $flat) {
if (!$reader['valid'][$index]) {
$errors[] = $index;
continue;
}
$newFlat = new Flat();
$newFlat->setBuilding($building);
$newFlat->setUser($building->getUser());
$building->incrementFlatsNumber();
$newFlat->setArchived(0);
$newFlat->setCreatedAt(new \DateTime('now'));
$newFlat->setUpdatedAt(new \DateTime('now'));
$newFlat->setMatId($flat['matId']);
$newFlat->setType($flat['type']);
$newFlat->setSubType($flat['subtype']);
$newFlat->setSize($flat['size']);
$newFlat->setPib($flat['pib']);
$newFlat->setDisplayFlatId($flat['flat_display_id']);
$newFlat->setOwnerName($flat['owner_name']);
$newFlat->setOwnerLastname($flat['owner_lastname']);
$newFlat->setCompanyName($flat['company_name']);
$newFlat->setCompanyPlace($flat['company_address']);
$newFlat->setComment($flat['comment']);
$newFlat->setMembers($flat['members'] ?: 1);
$newFlat->setOwnerEmail($flat['owner_email']);
$newFlat->setEmailCanBeUsed(false);
if (isset($flat['owner_email'])) {
$newFlat->setEmailCanBeUsed(true);
}
$newFlat->setOldDebit($flat['old_debt']);
$newFlat->setRent($flat['sub_occupants']);
$newFlat->setBankAccount($flat['bank_account']);
$this->flatRepository->save($newFlat);
}
}
/**
* @param array<mixed> $mergedArray
* @param string $startDate
* @param string $endDate
* @param float $saldo
* @return Xlsx
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws Exception
*/
public function getArrayForFinalReport(array $mergedArray, string $startDate, string $endDate, float $saldo): Xlsx
{
$spreadsheet = new Spreadsheet();
$activeWorksheet = $spreadsheet->getActiveSheet();
$activeWorksheet->mergeCells('B1:F1');
$activeWorksheet->setCellValue('B1', sprintf('FINANSIJSKI IZVEŠTAJ ZA PERIOD %s - %s', $startDate, $endDate));
$startDateNew = new DateTime($startDate);
$activeWorksheet->mergeCells('B2:F2');
$activeWorksheet->setCellValue(
'B2',
sprintf(
'RASPOLOŽIVA SREDSTVA NA DAN: %s - %s',
$startDateNew->modify('-1day')->format('d.m.Y'),
number_format($saldo, 2, ',', '.')
)
);
$activeWorksheet->mergeCells('B3:C3');
$activeWorksheet->setCellValue('B3', 'TEKUĆI RAČUN');
$activeWorksheet->setCellValue('D3', 'DATUM');
$activeWorksheet->setCellValue('E3', 'PRIHODI');
$activeWorksheet->setCellValue('F3', 'RASHODI');
$i = 4;
$num = 1;
$income = 0;
$outcome = 0;
foreach ($mergedArray as $item) {
$activeWorksheet->setCellValue(sprintf('A%s', $i), $num);
$activeWorksheet->setCellValue(sprintf('B%s', $i), $item['partnerName']);
$activeWorksheet->setCellValue(sprintf('C%s', $i), $item['comment']);
if (isset($item['endDate'])) {
$activeWorksheet->setCellValue(
sprintf('D%s', $i),
sprintf('%s - %s', $item['createdAt']->format('d.m.'), $item['endDate']->format('d.m.Y'))
);
} else {
$activeWorksheet->setCellValue(sprintf('D%s', $i), $item['createdAt']->format('d.m.Y'));
}
if ($item['income'] == 1 || $item['income'] == 3) {
$activeWorksheet->setCellValue(sprintf('E%s', $i), $item['value']);
$income = $income + $item['value'];
} else {
$activeWorksheet->setCellValue(sprintf('F%s', $i), $item['value']);
$outcome = $outcome + $item['value'];
}
$i++;
$num++;
}
$activeWorksheet->mergeCells(sprintf('B%s:D%s', $i, $i));
$activeWorksheet->setCellValue(sprintf('B%s', $i), 'UKUPNO TEKUĆI RAČUN');
$activeWorksheet->setCellValue(sprintf('E%s', $i), $income);
$activeWorksheet->setCellValue(sprintf('F%s', $i), $outcome);
$activeWorksheet->mergeCells(sprintf('B%s:D%s', $i + 1, $i + 1));
$activeWorksheet->setCellValue(sprintf('B%s', $i + 1), 'UKUPNO (PRIHODI - RASHODI)');
$activeWorksheet->mergeCells(sprintf('E%s:F%s', $i + 1, $i + 1));
$activeWorksheet->setCellValue(sprintf('E%s', $i + 1), $income - $outcome);
$activeWorksheet->mergeCells(sprintf('B%s:D%s', $i + 2, $i + 2));
$activeWorksheet->setCellValue(
sprintf('B%s', $i + 2),
sprintf('STANJE RASPOLOŽIVIH SREDSTAVA NA TEKUĆEM RAČUNU NA DAN: %s', $endDate)
);
$activeWorksheet->mergeCells(sprintf('E%s:F%s', $i + 2, $i + 2));
$activeWorksheet->setCellValue(
sprintf('E%s', $i + 2),
number_format(($saldo + ($income - $outcome)), 2, ',', '.')
);
$activeWorksheet->getColumnDimension('A')->setWidth(5);
$activeWorksheet->getColumnDimension('B')->setWidth(40);
$activeWorksheet->getColumnDimension('C')->setWidth(40);
$activeWorksheet->getColumnDimension('D')->setWidth(20);
$activeWorksheet->getColumnDimension('E')->setWidth(15);
$activeWorksheet->getColumnDimension('F')->setWidth(15);
return new Xlsx($spreadsheet);
}
/**
* @param array<int, string> $columnOptions
* @param Building $building
* @return Xlsx
*/
public function getArrayForFlatsList(array $columnOptions, Building $building): Xlsx
{
/** @var array<Flat> $flats */
$flatsObjs = $this->flatRepository->getFlatsByBuilding($building->getUser(), $building);
foreach ($flatsObjs as $flat) {
$flat['hashCode'] = $this->hashIdService->encodeId($flat['id']);
$flats[$flat['displayFlatId']] = $flat;
}
ksort($flats, SORT_NATURAL);
$spreadsheet = new Spreadsheet();
$activeWorksheet = $spreadsheet->getActiveSheet();
$currentColumn = 'A';
if (in_array("Broj stana", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Broj stana");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(15);
$currentColumn++;
}
if (in_array("Ime vlasnika", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Ime vlasnika");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(30);
$currentColumn++;
}
if (in_array("Broj članova", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Broj članova");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(10);
$currentColumn++;
}
if (in_array("Poziv na broj", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Poziv na broj");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(20);
$currentColumn++;
}
if (in_array("Površina", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Površina");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(10);
$currentColumn++;
}
if (in_array("Telefon", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Telefon");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(20);
$currentColumn++;
}
if (in_array("Detalji", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Detalji");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(20);
$currentColumn++;
}
if (in_array("Email", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Email");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(30);
$currentColumn++;
}
if (in_array("Adresa", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Adresa");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(50);
$currentColumn++;
}
if (in_array("Stari dug", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Stari dug");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(15);
$currentColumn++;
}
if (in_array("Prethodni dug", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Prethodni dug");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(15);
$currentColumn++;
}
if (in_array("Ukupan dug", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Ukupan dug");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(15);
$currentColumn++;
}
if (in_array("Poslednji račun", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Poslednji račun");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(15);
$currentColumn++;
}
if (in_array("Komentar", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Komentar");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(50);
$currentColumn++;
}
if (in_array("Kod za aplikaciju", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Kod za aplikaciju");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(50);
$currentColumn++;
}
if (in_array("Koristi aplikaciju", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Koristi aplikaciju");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(50);
}
$i = 2;
foreach ($flats as $flat) {
$currentColumn = 'A';
if (in_array("Broj stana", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $flat['displayFlatId']);
$currentColumn++;
}
if (in_array("Ime vlasnika", $columnOptions)) {
$activeWorksheet->setCellValue(
sprintf('%s%s', $currentColumn, $i),
$flat['companyName'] ?? sprintf('%s %s', $flat['ownerName'], $flat['ownerLastname'])
);
$currentColumn++;
}
if (in_array("Broj članova", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $flat['members']);
$currentColumn++;
}
if (in_array("Poziv na broj", $columnOptions)) {
$activeWorksheet->setCellValue(
sprintf('%s%s', $currentColumn, $i),
sprintf('%s-%s', $building->getCode(), $flat['displayFlatId'])
);
$currentColumn++;
}
if (in_array("Površina", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $flat['size']);
$currentColumn++;
}
if (in_array("Telefon", $columnOptions)) {
$activeWorksheet->setCellValueExplicit(
sprintf('%s%s', $currentColumn, $i),
$flat['ownerPhoneNumber'],
DataType::TYPE_STRING
);
$currentColumn++;
}
if (in_array("Detalji", $columnOptions)) {
$activeWorksheet->setCellValueExplicit(
sprintf('%s%s', $currentColumn, $i),
$flat['ownerContact'],
DataType::TYPE_STRING
);
$currentColumn++;
}
if (in_array("Email", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $flat['ownerEmail']);
$currentColumn++;
}
if (in_array("Adresa", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $flat['ownerAddress']);
$currentColumn++;
}
if (in_array("Stari dug", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $flat['oldDebit']);
$currentColumn++;
}
if (in_array("Prethodni dug", $columnOptions)) {
$activeWorksheet->setCellValue(
sprintf('%s%s', $currentColumn, $i),
($flat['debit'] + $flat['previousBill'])
);
$currentColumn++;
}
if (in_array("Ukupan dug", $columnOptions)) {
$activeWorksheet->setCellValue(
sprintf('%s%s', $currentColumn, $i),
($flat['debit'] + $flat['previousBill'] + $flat['oldDebit'])
);
$currentColumn++;
}
if (in_array("Poslednji račun", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $flat['previousBill']);
$currentColumn++;
}
if (in_array("Komentar", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $flat['comment']);
$currentColumn++;
}
if (in_array("Kod za aplikaciju", $columnOptions)) {
$activeWorksheet->setCellValue(
sprintf('%s%s', $currentColumn, $i),
$this->hashIdService->encodeId($flat['id'])
);
$currentColumn++;
}
if (in_array("Koristi aplikaciju", $columnOptions)) {
$flatObj = $this->flatRepository->findOneBy(['id' => $flat['id']]);
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $flatObj->getResident() ? 'DA' : '');
}
$i++;
}
return new Xlsx($spreadsheet);
}
/**
* @param array<int, string> $columnOptions
* @param Building $building
* @return Xlsx
* @throws Exception
*/
public function getArrayForFlatsAnalyticsList(array $columnOptions, Building $building): Xlsx
{
/** @var array<Flat> $flats */
$flats = $this->flatRepository->getFlatsByBuildingOrderedById($building->getUser(), $building, 1);
$spreadsheet = new Spreadsheet();
$activeWorksheet = $spreadsheet->getActiveSheet();
$currentColumn = 'A';
if (in_array("Ime i prezime / Naziv dužnika", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Ime i prezime / Naziv dužnika");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(30);
$currentColumn++;
}
if (in_array("Broj posebnog dela", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Broj posebnog dela");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(15);
$currentColumn++;
}
if (in_array("Površina", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Površina");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(10);
$currentColumn++;
}
if (in_array("Adresa dužnika", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Adresa dužnika");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(60);
$currentColumn++;
}
if (in_array("Email adresa dužnika", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Email adresa dužnika");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(40);
$currentColumn++;
}
if (in_array("Telefon", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Telefon");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(20);
$currentColumn++;
}
if (in_array("Detalji", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Detalji");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(20);
$currentColumn++;
}
if (in_array("Komentar", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Komentar");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(30);
$currentColumn++;
}
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Broj fakture");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(20);
$currentColumn++;
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Datum fakture");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(20);
$currentColumn++;
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Datum dospeća");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(20);
$currentColumn++;
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Iznos potraživanja po fakturi");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(20);
$currentColumn++;
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Uplata");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(20);
$currentColumn++;
$activeWorksheet->setCellValue(sprintf('%s1', $currentColumn), "Preostali iznos potraživanja");
$activeWorksheet->getColumnDimension($currentColumn)->setWidth(20);
$i = 2;
foreach ($flats as $flat) {
$sum = 0;
$flatObj = $this->flatRepository->findOneBy(['id' => $flat['id']]);
$logs = $this->moneyLogService->getFlatMoneyLogEntries($flatObj->getUser(), $flatObj);
for ($j = 0; $j < count($logs['processed']); $j++) {
$logs['processed'][$j]['month'] = CommonHelper::getMonth(
(new \DateTime($logs['processed'][$j]['date']))->modify("-1MONTH")->format('d.m.Y')
);
}
foreach ($logs['processed'] as $log) {
$currentColumn = 'A';
if (in_array("Ime i prezime / Naziv dužnika", $columnOptions)) {
$activeWorksheet->setCellValue(
sprintf('%s%s', $currentColumn, $i),
$flat['companyName'] ?? sprintf('%s %s', $flat['ownerName'], $flat['ownerLastname'])
);
$currentColumn++;
}
if (in_array("Broj posebnog dela", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $flat['displayFlatId']);
$currentColumn++;
}
if (in_array("Površina", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $flat['size']);
$currentColumn++;
}
if (in_array("Adresa dužnika", $columnOptions)) {
$address = $flat['ownerAddress'] ?? sprintf(
'%s/%s',
$flatObj->getBuilding()->getAddress(),
$flatObj->getDisplayFlatId()
);
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $address);
$currentColumn++;
}
if (in_array("Email adresa dužnika", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $flat['ownerEmail']);
$currentColumn++;
}
if (in_array("Telefon", $columnOptions)) {
$activeWorksheet->setCellValueExplicit(
sprintf('%s%s', $currentColumn, $i),
$flat['ownerPhoneNumber'],
DataType::TYPE_STRING
);
$currentColumn++;
}
if (in_array("Detalji", $columnOptions)) {
$activeWorksheet->setCellValueExplicit(
sprintf('%s%s', $currentColumn, $i),
$flat['ownerContact'],
DataType::TYPE_STRING
);
$currentColumn++;
}
if (in_array("Komentar", $columnOptions)) {
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $flat['comment']);
$currentColumn++;
}
if ($log['type'] === 'Zaduženje za mesec' || $log['type'] === 'Parcijalno zaduženje za mesec') {
$month = (new DateTime($log['date']))->modify('-1MONTH')->format('m/Y');
$activeWorksheet->setCellValue(
sprintf('%s%s', $currentColumn, $i),
sprintf('%s-%s-%s', $month, $flatObj->getBuilding()->getCode(), $flatObj->getDisplayFlatId())
);
$currentColumn++;
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $log['dateCreatedAt']);
$currentColumn++;
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $log['datumDueDate']);
$currentColumn++;
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $log['debit']);
$currentColumn++;
$currentColumn++;
$sum += $log['debit'];
} elseif ($log['type'] === 'Uplata' || $log['type'] === 'Uplata parcijalnog računa') {
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), 'Uplata');
$currentColumn++;
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $log['date']);
$currentColumn++;
$currentColumn++;
$currentColumn++;
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $log['input']);
$currentColumn++;
$sum -= $log['input'];
}
$activeWorksheet->setCellValue(sprintf('%s%s', $currentColumn, $i), $sum);
$i++;
}
}
return new Xlsx($spreadsheet);
}
/**
* @param $bankAccount
* @return Building|null
* @throws NonUniqueResultException
*/
public function getBuildingByBankAccount($bankAccount): ?Building
{
return $this->buildingRepository->getBuildingsByBankAccount($bankAccount);
}
}