Daniel пре 2 година
родитељ
комит
b7d729b44e
65 измењених фајлова са 13518 додато и 0 уклоњено
  1. +8
    -0
      .idea/.gitignore
  2. +4
    -0
      .idea/encodings.xml
  3. +8
    -0
      .idea/modules.xml
  4. +8
    -0
      .idea/spt-crm-backend.iml
  5. +6
    -0
      .idea/vcs.xml
  6. +46
    -0
      httpdocs/.env
  7. +10
    -0
      httpdocs/.gitignore
  8. +17
    -0
      httpdocs/bin/console
  9. +74
    -0
      httpdocs/composer.json
  10. +5829
    -0
      httpdocs/composer.lock
  11. +9
    -0
      httpdocs/config/bundles.php
  12. +19
    -0
      httpdocs/config/packages/cache.yaml
  13. +44
    -0
      httpdocs/config/packages/doctrine.yaml
  14. +6
    -0
      httpdocs/config/packages/doctrine_migrations.yaml
  15. +25
    -0
      httpdocs/config/packages/framework.yaml
  16. +3
    -0
      httpdocs/config/packages/mailer.yaml
  17. +12
    -0
      httpdocs/config/packages/routing.yaml
  18. +39
    -0
      httpdocs/config/packages/security.yaml
  19. +3
    -0
      httpdocs/config/packages/sensio_framework_extra.yaml
  20. +5
    -0
      httpdocs/config/preload.php
  21. +5
    -0
      httpdocs/config/routes.yaml
  22. +4
    -0
      httpdocs/config/routes/framework.yaml
  23. +32
    -0
      httpdocs/config/services.yaml
  24. +0
    -0
      httpdocs/migrations/.gitignore
  25. +9
    -0
      httpdocs/public/index.php
  26. +292
    -0
      httpdocs/src/Command/CmdSendReminderEmails.php
  27. +0
    -0
      httpdocs/src/Controller/.gitignore
  28. +87
    -0
      httpdocs/src/Controller/AdminController.php
  29. +227
    -0
      httpdocs/src/Controller/CustomerEditController.php
  30. +281
    -0
      httpdocs/src/Controller/CustomerMeetingEditController.php
  31. +49
    -0
      httpdocs/src/Controller/CustomerViewController.php
  32. +80
    -0
      httpdocs/src/Controller/ExportController.php
  33. +247
    -0
      httpdocs/src/Controller/InternalMeetingEditController.php
  34. +90
    -0
      httpdocs/src/Controller/MeetingViewController.php
  35. +57
    -0
      httpdocs/src/Controller/PublicController.php
  36. +0
    -0
      httpdocs/src/Entity/.gitignore
  37. +166
    -0
      httpdocs/src/Entity/EntCountry.php
  38. +458
    -0
      httpdocs/src/Entity/EntCustomer.php
  39. +473
    -0
      httpdocs/src/Entity/EntCustomerContact.php
  40. +758
    -0
      httpdocs/src/Entity/EntCustomerMeeting.php
  41. +96
    -0
      httpdocs/src/Entity/EntCustomerMeetingParticipant.php
  42. +440
    -0
      httpdocs/src/Entity/EntCustomerNote.php
  43. +338
    -0
      httpdocs/src/Entity/EntInternalMeeting.php
  44. +96
    -0
      httpdocs/src/Entity/EntInternalMeetingParticipant.php
  45. +93
    -0
      httpdocs/src/Entity/EntMeetingType.php
  46. +349
    -0
      httpdocs/src/Entity/EntUser.php
  47. +161
    -0
      httpdocs/src/Entity/EntUserType.php
  48. +21
    -0
      httpdocs/src/Entity/IFace/IEntity.php
  49. +106
    -0
      httpdocs/src/Entity/convertAnnotations.php
  50. +100
    -0
      httpdocs/src/EntityVirtual/ServiceData.php
  51. +69
    -0
      httpdocs/src/EventListener/ControllerListener.php
  52. +72
    -0
      httpdocs/src/EventListener/DatabaseListener.php
  53. +11
    -0
      httpdocs/src/Kernel.php
  54. +0
    -0
      httpdocs/src/Repository/.gitignore
  55. +132
    -0
      httpdocs/src/Security/JsonAuthenticator.php
  56. +37
    -0
      httpdocs/src/Utils/Config.php
  57. +530
    -0
      httpdocs/src/Utils/Excel.php
  58. +139
    -0
      httpdocs/src/Utils/ExcelStyle.php
  59. +209
    -0
      httpdocs/src/Utils/Message.php
  60. +185
    -0
      httpdocs/src/Utils/Reply.php
  61. +610
    -0
      httpdocs/src/Utils/Utils.php
  62. +130
    -0
      httpdocs/symfony.lock
  63. +12
    -0
      httpdocs/templates/base.html.twig
  64. +46
    -0
      httpdocs/templates/contacts_export.html.twig
  65. +46
    -0
      httpdocs/templates/xmas_addresses.html.twig

+ 8
- 0
.idea/.gitignore Прегледај датотеку

@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

+ 4
- 0
.idea/encodings.xml Прегледај датотеку

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
</project>

+ 8
- 0
.idea/modules.xml Прегледај датотеку

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/spt-crm-backend.iml" filepath="$PROJECT_DIR$/.idea/spt-crm-backend.iml" />
</modules>
</component>
</project>

+ 8
- 0
.idea/spt-crm-backend.iml Прегледај датотеку

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

+ 6
- 0
.idea/vcs.xml Прегледај датотеку

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

+ 46
- 0
httpdocs/.env Прегледај датотеку

@@ -0,0 +1,46 @@
# In all environments, the following files are loaded if they exist,
# the latter taking precedence over the former:
#
# * .env contains default values for the environment variables needed by the app
# * .env.local uncommitted file with local overrides
# * .env.$APP_ENV committed environment-specific defaults
# * .env.$APP_ENV.local uncommitted environment-specific overrides
#
# Real environment variables win over .env files.
#
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
#
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
# https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration

###> symfony/framework-bundle ###
APP_ENV=dev
APP_SECRET=87663e220c9c6c788a7a600f2c718777
#TRUSTED_PROXIES=127.0.0.1,127.0.0.2
#TRUSTED_HOSTS='^localhost|example\.com$'
###< symfony/framework-bundle ###

###> doctrine/doctrine-bundle ###
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
# For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data.db"
# For a PostgreSQL database, use: "postgresql://db_user:db_password@127.0.0.1:5432/db_name?serverVersion=11"
# IMPORTANT: You MUST also configure your db driver and server_version in config/packages/doctrine.yaml
DATABASE_URL=mysql://root@127.0.0.1:3306/spt_crm
###< doctrine/doctrine-bundle ###

###> nelmio/cors-bundle ###
CORS_ALLOW_ORIGIN=^https?://localhost:?[0-9]*$
###< nelmio/cors-bundle ###

###> symfony/swiftmailer-bundle ###
# For Gmail as a transport, use: "gmail://username:password@localhost"
# For a generic SMTP server, use: "smtp://localhost:25?encryption=&auth_mode="
# Delivery is disabled by default via "null://localhost"
#MAILER_URL=null://localhost
MAILER_DSN=smtp://spawntree.de?auth_mode=login&username=re@spawntree.de&password=EisenKnud2016
#MAILER_URL=smtp://localhost:465?encryption=ssl&auth_mode=login&username=&password=
###< symfony/swiftmailer-bundle ###

###> symfony/mailer ###
# MAILER_DSN=null://null
###< symfony/mailer ###

+ 10
- 0
httpdocs/.gitignore Прегледај датотеку

@@ -0,0 +1,10 @@

###> symfony/framework-bundle ###
/.env.local
/.env.local.php
/.env.*.local
/config/secrets/prod/prod.decrypt.private.php
/public/bundles/
/var/
/vendor/
###< symfony/framework-bundle ###

+ 17
- 0
httpdocs/bin/console Прегледај датотеку

@@ -0,0 +1,17 @@
#!/usr/bin/env php
<?php

use App\Kernel;
use Symfony\Bundle\FrameworkBundle\Console\Application;

if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {
throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".');
}

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

return function (array $context) {
$kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);

return new Application($kernel);
};

+ 74
- 0
httpdocs/composer.json Прегледај датотеку

@@ -0,0 +1,74 @@
{
"type": "project",
"license": "proprietary",
"minimum-stability": "stable",
"prefer-stable": true,
"require": {
"php": ">=8.1",
"ext-ctype": "*",
"ext-iconv": "*",
"doctrine/annotations": "^2.0",
"doctrine/doctrine-bundle": "^2.9",
"doctrine/doctrine-migrations-bundle": "^3.2",
"doctrine/orm": "^2.15",
"dompdf/dompdf": "*",
"phpoffice/phpspreadsheet": "*",
"sensio/framework-extra-bundle": "*",
"symfony/console": "6.2.*",
"symfony/dotenv": "6.2.*",
"symfony/flex": "^2",
"symfony/framework-bundle": "6.2.*",
"symfony/mailer": "6.2.*",
"symfony/runtime": "6.2.*",
"symfony/security-bundle": "6.2.*",
"symfony/yaml": "6.2.*"
},
"config": {
"allow-plugins": {
"php-http/discovery": true,
"symfony/flex": true,
"symfony/runtime": true
},
"sort-packages": true
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Tests\\": "tests/"
}
},
"replace": {
"symfony/polyfill-ctype": "*",
"symfony/polyfill-iconv": "*",
"symfony/polyfill-php72": "*",
"symfony/polyfill-php73": "*",
"symfony/polyfill-php74": "*",
"symfony/polyfill-php80": "*",
"symfony/polyfill-php81": "*"
},
"scripts": {
"auto-scripts": {
"cache:clear": "symfony-cmd",
"assets:install %PUBLIC_DIR%": "symfony-cmd"
},
"post-install-cmd": [
"@auto-scripts"
],
"post-update-cmd": [
"@auto-scripts"
]
},
"conflict": {
"symfony/symfony": "*"
},
"extra": {
"symfony": {
"allow-contrib": false,
"require": "6.2.*"
}
}
}

+ 5829
- 0
httpdocs/composer.lock
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 9
- 0
httpdocs/config/bundles.php Прегледај датотеку

@@ -0,0 +1,9 @@
<?php

return [
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true],
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
];

+ 19
- 0
httpdocs/config/packages/cache.yaml Прегледај датотеку

@@ -0,0 +1,19 @@
framework:
cache:
# Unique name of your app: used to compute stable namespaces for cache keys.
#prefix_seed: your_vendor_name/app_name

# The "app" cache stores to the filesystem by default.
# The data in this cache should persist between deploys.
# Other options include:

# Redis
#app: cache.adapter.redis
#default_redis_provider: redis://localhost

# APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
#app: cache.adapter.apcu

# Namespaced pools use the above "app" backend by default
#pools:
#my.dedicated.cache: null

+ 44
- 0
httpdocs/config/packages/doctrine.yaml Прегледај датотеку

@@ -0,0 +1,44 @@
doctrine:
dbal:
url: '%env(resolve:DATABASE_URL)%'

# IMPORTANT: You MUST configure your server version,
# either here or in the DATABASE_URL env var (see .env file)
#server_version: '15'
orm:
auto_generate_proxy_classes: true
enable_lazy_ghost_objects: true
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: true
mappings:
App:
is_bundle: false
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App

when@test:
doctrine:
dbal:
# "TEST_TOKEN" is typically set by ParaTest
dbname_suffix: '_test%env(default::TEST_TOKEN)%'

when@prod:
doctrine:
orm:
auto_generate_proxy_classes: false
proxy_dir: '%kernel.build_dir%/doctrine/orm/Proxies'
query_cache_driver:
type: pool
pool: doctrine.system_cache_pool
result_cache_driver:
type: pool
pool: doctrine.result_cache_pool

framework:
cache:
pools:
doctrine.result_cache_pool:
adapter: cache.app
doctrine.system_cache_pool:
adapter: cache.system

+ 6
- 0
httpdocs/config/packages/doctrine_migrations.yaml Прегледај датотеку

@@ -0,0 +1,6 @@
doctrine_migrations:
migrations_paths:
# namespace is arbitrary but should be different from App\Migrations
# as migrations classes should NOT be autoloaded
'DoctrineMigrations': '%kernel.project_dir%/migrations'
enable_profiler: false

+ 25
- 0
httpdocs/config/packages/framework.yaml Прегледај датотеку

@@ -0,0 +1,25 @@
# see https://symfony.com/doc/current/reference/configuration/framework.html
framework:
secret: '%env(APP_SECRET)%'
#csrf_protection: true
http_method_override: false
handle_all_throwables: true

# Enables session support. Note that the session will ONLY be started if you read or write from it.
# Remove or comment this section to explicitly disable session support.
session:
handler_id: null
cookie_secure: auto
cookie_samesite: lax
storage_factory_id: session.storage.factory.native

#esi: true
#fragments: true
php_errors:
log: true

when@test:
framework:
test: true
session:
storage_factory_id: session.storage.factory.mock_file

+ 3
- 0
httpdocs/config/packages/mailer.yaml Прегледај датотеку

@@ -0,0 +1,3 @@
framework:
mailer:
dsn: '%env(MAILER_DSN)%'

+ 12
- 0
httpdocs/config/packages/routing.yaml Прегледај датотеку

@@ -0,0 +1,12 @@
framework:
router:
utf8: true

# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
#default_uri: http://localhost

when@prod:
framework:
router:
strict_requirements: null

+ 39
- 0
httpdocs/config/packages/security.yaml Прегледај датотеку

@@ -0,0 +1,39 @@
security:
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
providers:
users_in_memory: { memory: null }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
lazy: true
provider: users_in_memory

# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#the-firewall

# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true

# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }

when@test:
security:
password_hashers:
# By default, password hashers are resource intensive and take time. This is
# important to generate secure password hashes. In tests however, secure hashes
# are not important, waste resources and increase test times. The following
# reduces the work factor to the lowest possible values.
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
algorithm: auto
cost: 4 # Lowest possible value for bcrypt
time_cost: 3 # Lowest possible value for argon
memory_cost: 10 # Lowest possible value for argon

+ 3
- 0
httpdocs/config/packages/sensio_framework_extra.yaml Прегледај датотеку

@@ -0,0 +1,3 @@
sensio_framework_extra:
router:
annotations: false

+ 5
- 0
httpdocs/config/preload.php Прегледај датотеку

@@ -0,0 +1,5 @@
<?php

if (file_exists(dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php')) {
require dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php';
}

+ 5
- 0
httpdocs/config/routes.yaml Прегледај датотеку

@@ -0,0 +1,5 @@
controllers:
resource:
path: ../src/Controller/
namespace: App\Controller
type: attribute

+ 4
- 0
httpdocs/config/routes/framework.yaml Прегледај датотеку

@@ -0,0 +1,4 @@
when@dev:
_errors:
resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
prefix: /_error

+ 32
- 0
httpdocs/config/services.yaml Прегледај датотеку

@@ -0,0 +1,32 @@
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.

# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
parameters:

services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'

# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones

App\Command\:
resource: '../src/Command/'
autowire: true
autoconfigure: true
arguments: ['@doctrine.orm.entity_manager', '@service_container', '@mailer']
tags:
- { name: 'console.command' }

+ 0
- 0
httpdocs/migrations/.gitignore Прегледај датотеку


+ 9
- 0
httpdocs/public/index.php Прегледај датотеку

@@ -0,0 +1,9 @@
<?php

use App\Kernel;

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

return function (array $context) {
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
};

+ 292
- 0
httpdocs/src/Command/CmdSendReminderEmails.php Прегледај датотеку

@@ -0,0 +1,292 @@
<?php

namespace App\Command;

use App\Entity\EntCustomer;
use App\Entity\EntCustomerMeeting;
use App\Entity\EntCustomerMeetingParticipant;
use App\Entity\EntInternalMeeting;
use App\Entity\EntInternalMeetingParticipant;
use App\Entity\EntUser;
use App\Utils\Utils;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query;
use Psr\Container\ContainerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Mailer\MailerInterface;


/**
* Command to import excel that with answers of specifications
*
* Class CmdImportAll
* @package App\Command
*/
#[AsCommand(
name: 'app:send-reminder',
description: 'Send reminder emails for meetings.',
hidden: false
)]
class CmdSendReminderEmails extends Command
{
private EntityManagerInterface $em;

private ContainerInterface $container;

private MailerInterface $mailer;

private $environment;

public function __construct(EntityManagerInterface $em, ContainerInterface $container, MailerInterface $mailer)
{
$this->em = $em;
$this->container = $container;
$this->mailer = $mailer;
$kernel = $this->container->get('kernel');
$this->environment = $kernel->getEnvironment();
parent::__construct();
}

/**
* @param InputInterface $input
* @param OutputInterface $output
* @return int|null|void
* @throws \Exception
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
Utils::sendMail($this->mailer, 'test', 'd.knudsen@spawntree.de', 'this is a test', $this->environment);

$usersById = Utils::getSortedObjectsById($this->em->getRepository(EntUser::class)->findAll());
$customersById = Utils::getSortedObjectsById($this->em->getRepository(EntCustomer::class)->findAll());

$now = (new \DateTime())->format("Y-m-d H:i:s");
$checkStartDay = (new \DateTime())->modify('+2 day')->format("Y-m-d H:i:s");
$checkStartHours = (new \DateTime())->modify('+2 hours')->format("Y-m-d H:i:s");

// customer
/** @var Query $query */
$query = $this->em->createQuery(
"SELECT cm FROM ".
"App\Entity\EntCustomerMeeting cm ".
"WHERE cm.start_date < '".$checkStartDay."' ".
"AND cm.start_date > '".$now."' ".
"AND cm.first_reminder_sent = 0"
);
$meetingsCustomer2Days = $query->getResult();

$query = $this->em->createQuery(
"SELECT cm FROM ".
"App\Entity\EntCustomerMeeting cm ".
"WHERE cm.start_date < '".$checkStartHours."' ".
"AND cm.start_date > '".$now."' ".
"AND cm.second_reminder_sent = 0"
);
$meetingsCustomer2Hours = $query->getResult();

// internal
$query = $this->em->createQuery(
"SELECT im FROM ".
"App\Entity\EntInternalMeeting im ".
"WHERE im.start_date < '".$checkStartDay."' ".
"AND im.start_date > '".$now."' ".
"AND im.first_reminder_sent = 0"
);
$meetingsInternal2Days = $query->getResult();

$query = $this->em->createQuery(
"SELECT im FROM ".
"App\Entity\EntInternalMeeting im ".
"WHERE im.start_date < '".$checkStartHours."' ".
"AND im.start_date > '".$now."' ".
"AND im.second_reminder_sent = 0"
);
$meetingsInternal2Hours = $query->getResult();

$this->sendCustomerReminder($meetingsCustomer2Days, $customersById, $usersById, true);
$this->sendCustomerReminder($meetingsCustomer2Hours, $customersById, $usersById, false);
$this->sendInternalReminder($meetingsInternal2Days, $usersById, true);
$this->sendInternalReminder($meetingsInternal2Hours, $usersById, false);

// Report reminder
$checkStartDay = (new \DateTime())->modify('-3 day')->format("Y-m-d H:i:s");
$query = $this->em->createQuery(
"SELECT cm FROM ".
"App\Entity\EntCustomerMeeting cm ".
"WHERE cm.end_date < '".$checkStartDay."' ".
"AND cm.report IS NULL ".
"AND cm.report_reminder_sent = 0"
);
$meetingsCustomerNoReport = $query->getResult();
$this->sendCustomerMeetingReportReminder($meetingsCustomerNoReport, $customersById, $usersById);

$query = $this->em->createQuery(
"SELECT im FROM ".
"App\Entity\EntInternalMeeting im ".
"WHERE im.end_date < '".$checkStartDay."' ".
"AND im.report IS NULL ".
"AND im.report_reminder_sent = 0"
);
$meetingsInternalNoReport = $query->getResult();
$this->sendInternalMeetingReportReminder($meetingsInternalNoReport, $usersById);

}

protected function sendCustomerReminder($meetings, $customersById, $usersById, $firstReminder)
{
/** @var EntCustomerMeeting $meeting */
foreach ($meetings as $meeting) {
/** @var EntUser $owner */
$owner = $usersById[$meeting->getOwnerUserId()];
/** @var EntCustomer $customer */
$customer = $customersById[$meeting->getCustomerId()];
$participantsByUserId = Utils::getSortedObjects('getParticipantUserId',
$this->em->getRepository('App:EntCustomerMeetingParticipant')->findBy(['customer_meeting_id' => $meeting->getId()]));

$subject = "Termin-Erinnerung: ". $customer->getName(). " ".$meeting->getStartDate()->format('d.m.Y H:i');
$body = $this->createCustomerMeetingReminderEmailBody($meeting, $subject, $customer, $owner, $participantsByUserId, $usersById);
Utils::sendMail($this->mailer, $subject, $owner->getEmail(), $body, $this->environment);

/*** @var EntCustomerMeetingParticipant $participant */
foreach ($participantsByUserId as $userId => $participant) {
/** @var EntUser $pUser */
$pUser = $usersById[$participant->getParticipantUserId()];
Utils::sendMail($this->mailer, $subject, $pUser->getEmail(), $body, $this->environment);
}

$firstReminder ? $meeting->setFirstReminderSent(true) : $meeting->setSecondReminderSent(true);
$this->em->persist($meeting);
$this->em->flush();
}
}

protected function sendInternalReminder($meetings, $usersById, $firstReminder)
{
/** @var EntInternalMeeting $meeting */
foreach ($meetings as $meeting) {
/** @var EntUser $owner */
$owner = $usersById[$meeting->getOwnerUserId()];
$participantsByUserId = Utils::getSortedObjects('getParticipantUserId',
$this->em->getRepository('App:EntInternalMeetingParticipant')->findBy(['internal_meeting_id' => $meeting->getId()]));

$subject = "Termin-Erinnerung: PLP intern ".$meeting->getStartDate()->format('d.m.Y H:i');
$body = $this->createInternalMeetingReminderEmailBody($meeting, $subject, $owner, $participantsByUserId, $usersById);
Utils::sendMail($this->mailer, $subject, $owner->getEmail(), $body, $this->environment);

/*** @var EntInternalMeetingParticipant $participant */
foreach ($participantsByUserId as $userId => $participant) {
/** @var EntUser $pUser */
$pUser = $usersById[$participant->getParticipantUserId()];
Utils::sendMail($this->mailer, $subject, $pUser->getEmail(), $body, $this->environment);
}

$firstReminder ? $meeting->setFirstReminderSent(true) : $meeting->setSecondReminderSent(true);
$this->em->persist($meeting);
$this->em->flush();
}
}

protected function createCustomerMeetingReminderEmailBody(EntCustomerMeeting $meeting, $subject, EntCustomer $customer, EntUser $owner, $participantsByUserId, $usersById)
{
$body = $subject." </br>";
$body.= "Kunde: ".$customer->getName()."</br>";
$body.= "Betreff: ".$meeting->getTitle()."</br>";
$body.= "Interner Verantwortlicher: ".$owner->getFirstname()." ".$owner->getLastname()."</br>";
$body.= "Start: ".$meeting->getStartDate()->format('d.m.Y H:i')."</br>";
$body.= "Ende: ".$meeting->getEndDate()->format('d.m.Y H:i')."</br></br>";
$body.= "Ansprechpartner: </br>";
$body.= "Name: ";
$body.= !is_null($meeting->getGender()) ? Utils::getTranslatedGender($meeting->getGender())." " : "";
$body.= !is_null($meeting->getFirstname()) ? $meeting->getFirstname()." " : "";
$body.= !is_null($meeting->getLastname()) ? $meeting->getLastname()." " : "";
$body.= "</br>";
$body.= "Abteilung: ".!is_null($meeting->getDescription()) ? $meeting->getDescription()."</br>" : "</br>";
$body.= "Email: ".!is_null($meeting->getEmail()) ? $meeting->getEmail()."</br>" : "</br>";
$body.= "Telefon: ".!is_null($meeting->getPhoneNo()) ? $meeting->getPhoneNo()."</br>" : "</br>";
$body.= "Mobil: ".!is_null($meeting->getMobileNo()) ? $meeting->getMobileNo()."</br>" : "</br>";
$body.= "Adresse: ";
$body.= !is_null($meeting->getStreet()) ? $meeting->getStreet()." " : "";
$body.= !is_null($meeting->getStreetNo()) ? $meeting->getStreetNo()." " : "";
$body.= !is_null($meeting->getZip()) ? $meeting->getZip()." " : "";
$body.= !is_null($meeting->getCity()) ? $meeting->getCity()." " : "";
$body.= "</br>";
$body.= "Bemerkung: ".$meeting->getDescription()."</br>";
$body.= "Options-Termin: ".($meeting->getIsOptionMeeting() ? "ja" : "nein")."</br></br>";
$body.= "Interne Teilnehmer: </br>";
foreach ($participantsByUserId as $pUserId => $item) {
/** @var EntUser $participant */
$participant = $usersById[$pUserId];
$body.= $participant->getFirstname(). " ". $participant->getLastname(). "</br>";
}
return $body;
}

protected function createInternalMeetingReminderEmailBody(EntInternalMeeting $meeting, $subject, EntUser $owner, $participantsByUserId, $usersById)
{
$body = $subject." </br>";
$body.= "Betreff: ".$meeting->getTitle()."</br>";
$body.= "Interner Verantwortlicher: ".$owner->getFirstname()." ".$owner->getLastname()."</br>";
$body.= "Start: ".$meeting->getStartDate()->format('d.m.Y H:i')."</br>";
$body.= "Ende: ".$meeting->getEndDate()->format('d.m.Y H:i')."</br></br>";
$body.= "Bemerkung: ".$meeting->getDescription()."</br>";
$body.= "Interne Teilnehmer: </br>";
foreach ($participantsByUserId as $pUserId => $item) {
/** @var EntUser $participant */
$participant = $usersById[$pUserId];
$body.= $participant->getFirstname(). " ". $participant->getLastname(). "</br>";
}
return $body;
}

protected function sendCustomerMeetingReportReminder($meetings, $customersById, $usersById)
{
/** @var EntCustomerMeeting $meeting */
foreach ($meetings as $meeting) {
/** @var EntUser $owner */
$owner = $usersById[$meeting->getOwnerUserId()];
/** @var EntCustomer $customer */
$customer = $customersById[$meeting->getCustomerId()];

$subject = "Termin-Report-Erinnerung (Kundentermin) ". $customer->getName();
$body = $this->createReportReminderEmailBody($meeting, $subject, $owner);
Utils::sendMail($this->mailer, $subject, $owner->getEmail(), $body, $this->environment);

$meeting->setReportReminderSent(true);
$this->em->persist($meeting);
$this->em->flush();
}
}

protected function sendInternalMeetingReportReminder($meetings, $usersById)
{
/** @var EntInternalMeeting $meeting */
foreach ($meetings as $meeting) {
/** @var EntUser $owner */
$owner = $usersById[$meeting->getOwnerUserId()];

$subject = "Termin-Report-Erinnerung (PLP intern)";
$body = $this->createReportReminderEmailBody($meeting, $subject, $owner);
Utils::sendMail($this->mailer, $subject, $owner->getEmail(), $body, $this->environment);

$meeting->setReportReminderSent(true);
$this->em->persist($meeting);
$this->em->flush();
}
}

protected function createReportReminderEmailBody($meeting, $subject, EntUser $owner)
{
$body = $subject." </br>";
$body.= "Für folgenden Termin wurde bisher noch kein Report angelegt.</br>";
$body.= "Betreff: ".$meeting->getTitle()."</br>";
$body.= "Interner Verantwortlicher: ".$owner->getFirstname()." ".$owner->getLastname()."</br>";
$body.= "Start: ".$meeting->getStartDate()->format('d.m.Y H:i')."</br>";
$body.= "Ende: ".$meeting->getEndDate()->format('d.m.Y H:i')."</br></br>";
$body.= "Bemerkung: ".$meeting->getDescription()."</br>";
return $body;
}

}

+ 0
- 0
httpdocs/src/Controller/.gitignore Прегледај датотеку


+ 87
- 0
httpdocs/src/Controller/AdminController.php Прегледај датотеку

@@ -0,0 +1,87 @@
<?php
/**
* Created by PhpStorm.
* User: danielknudsen
* Date: 05.04.18
* Time: 13:09
*/
namespace App\Controller;

use App\Entity\EntCountry;
use App\Utils\Reply;
use Dompdf\Dompdf;
use Dompdf\Options;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

#[Security("is_granted('ROLE_ADMIN')")]
class AdminController extends AbstractController
{
const XMAS_CONTACT_PDF_TYPE_CUSTOMER = 'customer';

#[Route('/create-xmas-pdf', name: 'create_xmas_pdf')]
public function createXmasPdf(Request $request)
{
$type = $request->request->get('type');
$em = $this->getDoctrine()->getManager();
$entityCache = [];

switch ($type) {
case self::XMAS_CONTACT_PDF_TYPE_CUSTOMER:
$sql = "SELECT cc.*, c.name AS company FROM customer_contact cc, customer c WHERE cc.is_xmas_mail_recipient = 1 AND cc.customer_id = c.id ORDER BY cc.lastname ASC";
$statement = $em->getConnection()->prepare($sql);
$statement->execute();
$entries = $statement->fetchAll();
break;
default:
throw new Exception('invalid type given');
}

$data = [];
foreach ($entries as $entry) {
$cacheKey = trim($entry['firstname'].$entry['lastname'].$entry['street'].$entry['street_no'].$entry['zip'].$entry['city']);
if (!array_key_exists($cacheKey, $entityCache)) {
$entityCache[$cacheKey] = 1;
/** @var EntCountry $entCountry */
$entCountry = !is_null($entry['country_id']) ? EntCountry::getCountryById($em, $entry['country_id']) : null;
$data[] = [
'company' => $entry['company'],
'firstname' => $entry['firstname'],
'lastname' => $entry['lastname'],
'street' => $entry['street'],
'street_no' => $entry['street_no'],
'zip' => $entry['zip'],
'city' => $entry['city'],
'country' => !is_null($entCountry) ? $entCountry->getName() : ""
];
}
}

// Configure Dompdf according to your needs
$pdfOptions = new Options();
$pdfOptions->set('defaultFont', 'Arial');

// Instantiate Dompdf with our options
$dompdf = new Dompdf($pdfOptions);

// Retrieve the HTML generated in our twig file
$html = $this->renderView('xmas_addresses.html.twig', [
'data' => $data
]);

// Load HTML to Dompdf
$dompdf->loadHtml($html);

// (Optional) Setup the paper size and orientation 'portrait' or 'portrait'
$dompdf->setPaper('A4', 'portrait');

// Render the HTML as PDF
$dompdf->render();

return Reply::getSteamedFileResponse($dompdf->output());
}

}

+ 227
- 0
httpdocs/src/Controller/CustomerEditController.php Прегледај датотеку

@@ -0,0 +1,227 @@
<?php
/**
* Created by PhpStorm.
* User: danielknudsen
* Date: 05.04.18
* Time: 13:09
*/
namespace App\Controller;

use App\Entity\EntCustomer;
use App\Entity\EntCustomerContact;
use App\Entity\EntCustomerMeeting;
use App\Entity\EntCustomerMeetingParticipant;
use App\Entity\EntCustomerNote;
use App\Entity\EntMeetingType;
use App\Entity\EntUser;
use App\EntityVirtual\ServiceData;
use App\Utils\Message;
use App\Utils\Reply;
use App\Utils\Utils;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

#[Security("is_granted('ROLE_ADMIN')")]
class CustomerEditController extends AbstractController
{
#[Route('/create-customer', name: 'create_customer')]
public function createCustomer(Request $request)
{
$customerClient = json_decode($request->request->get('customer'));
$em = $this->getDoctrine()->getManager();
/** @var EntCustomer $entCustomer */
$entCustomer = new EntCustomer($em, $customerClient->name);
$entCustomer->setClientData($em, $customerClient);
$em->persist($entCustomer);
$em->flush();

$fullMappedCustomer = $entCustomer->clientMapper($em, true);
$serviceData = new ServiceData();
$serviceData->addServiceData(ServiceData::SERVICE_DATA_TYPE_CUSTOMERS, ServiceData::ACTION_ADD, $fullMappedCustomer);
return Reply::getResponse($fullMappedCustomer, Message::SUCCESS_CUSTOMER_CREATE, 0, $serviceData);
}

#[Route('/edit-customer', name: 'edit_customer')]
public function editCustomer(Request $request)
{
$customerClient = json_decode($request->request->get('customer'));
$em = $this->getDoctrine()->getManager();
/** @var EntCustomer $entCustomer */
$entCustomer = $em->getRepository('App:EntCustomer')->find($customerClient->id);
if (is_null($entCustomer)) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}
$entCustomer->setClientData($em, $customerClient);
$em->persist($entCustomer);
$em->flush();

$fullMappedCustomer = $entCustomer->clientMapper($em, true);
$serviceData = new ServiceData();
$serviceData->addServiceData(ServiceData::SERVICE_DATA_TYPE_CUSTOMERS, ServiceData::ACTION_EDIT, $fullMappedCustomer);
return Reply::getResponse($fullMappedCustomer, Message::SUCCESS_CUSTOMER_EDIT, 0, $serviceData);
}

#[Route('/create-customer-contact', name: 'create_customer_contact')]
public function createCustomerContact(Request $request)
{
$customerContactClient = json_decode($request->request->get('customerContact'));
$em = $this->getDoctrine()->getManager();
/** @var EntCustomer $entCustomer */
$entCustomer = $em->getRepository('App:EntCustomer')->find($customerContactClient->customer_id);
if (is_null($entCustomer)) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

/** @var EntCustomerContact $entCustomerContact */
$entCustomerContact = new EntCustomerContact($em, $entCustomer, $customerContactClient->lastname);
$entCustomerContact->setClientData($em, $customerContactClient);
$em->persist($entCustomerContact);
$em->flush();

$fullMappedCustomerContact = $entCustomerContact->clientMapper($em, true);
$serviceData = new ServiceData();
$serviceData->addServiceData(ServiceData::SERVICE_DATA_TYPE_CUSTOMER_CONTACTS, ServiceData::ACTION_ADD, $fullMappedCustomerContact);
return Reply::getResponse($entCustomer->clientMapper($em, true), Message::SUCCESS_CUSTOMER_CONTACT_CREATE, 0, $serviceData);
}

#[Route('/edit-customer-contact', name: 'edit_customer_contact')]
public function editCustomerContact(Request $request)
{
$customerContactClient = json_decode($request->request->get('customerContact'));
$em = $this->getDoctrine()->getManager();
/** @var EntCustomerContact $entCustomerContact */
$entCustomerContact = $em->getRepository('App:EntCustomerContact')->find($customerContactClient->id);
if (is_null($entCustomerContact)) {
return Reply::getErrorResponse(Message::ERROR_NON_EXISTING_DATA);
}

/** @var EntCustomer $entCustomer */
$entCustomer = $em->getRepository('App:EntCustomer')->find($entCustomerContact->getCustomerId());
if (is_null($entCustomer)) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

$entCustomerContact->setClientData($em, $customerContactClient);
$em->persist($entCustomerContact);
$em->flush();

$fullMappedCustomerContact = $entCustomerContact->clientMapper($em, true);
$serviceData = new ServiceData();
$serviceData->addServiceData(ServiceData::SERVICE_DATA_TYPE_CUSTOMER_CONTACTS, ServiceData::ACTION_EDIT, $fullMappedCustomerContact);
return Reply::getResponse($entCustomer->clientMapper($em, true), Message::SUCCESS_CUSTOMER_CONTACT_EDIT, 0, $serviceData);
}

#[Route('/delete-customer-contact', name: 'delete_customer_contact')]
public function deleteCustomerContact(Request $request)
{
$customerContactIdClient = json_decode($request->request->get('customerContactId'));
$em = $this->getDoctrine()->getManager();
/** @var EntCustomerContact $entCustomerContact */
$entCustomerContact = $em->getRepository('App:EntCustomerContact')->find($customerContactIdClient);
if (is_null($entCustomerContact)) {
return Reply::getErrorResponse(Message::ERROR_NON_EXISTING_DATA);
}

/** @var EntCustomer $entCustomer */
$entCustomer = $em->getRepository('App:EntCustomer')->find($entCustomerContact->getCustomerId());
if (is_null($entCustomer)) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}
$fullMappedCustomerContact = $entCustomerContact->clientMapper($em, true);
$em->remove($entCustomerContact);
$em->flush();

$sql = "UPDATE `customer_meeting` SET `customer_contact_id` = NULL WHERE `customer_contact_id` = ". $customerContactIdClient;
$statement = $em->getConnection()->prepare($sql);
$statement->execute();

$sql = "UPDATE `customer_note` SET `customer_contact_id` = NULL WHERE `customer_contact_id` = ". $customerContactIdClient;
$statement = $em->getConnection()->prepare($sql);
$statement->execute();

$serviceData = new ServiceData();
$serviceData->addServiceData(ServiceData::SERVICE_DATA_TYPE_CUSTOMER_CONTACTS, ServiceData::ACTION_DELETE, $fullMappedCustomerContact);
return Reply::getResponse($entCustomer->clientMapper($em, true), Message::SUCCESS_CUSTOMER_CONTACT_DELETE, 0, $serviceData);
}

#[Route('/create-customer-note', name: 'create_customer_note')]
public function createCustomerNote(Request $request)
{
$customerNoteClient = json_decode($request->request->get('customerNote'));
$em = $this->getDoctrine()->getManager();
/** @var EntUser $user */
$user = $this->getUser();
/** @var EntCustomer $entCustomer */
$entCustomer = $em->getRepository('App:EntCustomer')->find($customerNoteClient->customer_id);
if (is_null($entCustomer)) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

/** @var EntCustomerNote $entCustomerNote */
$entCustomerNote = new EntCustomerNote($em, $entCustomer, $user, $customerNoteClient->title);
$entCustomerNote->setClientData($em, $customerNoteClient);
$em->persist($entCustomerNote);
$em->flush();

return Reply::getResponse($entCustomer->clientMapper($em, true), Message::SUCCESS_CUSTOMER_NOTE_CREATE);
}

#[Route('/edit-customer-note', name: 'edit_customer_note')]
public function editCustomerNote(Request $request)
{
$customerNoteClient = json_decode($request->request->get('customerNote'));
$em = $this->getDoctrine()->getManager();
/** @var EntUser $user */
$user = $this->getUser();
/** @var EntCustomerNote $entCustomerNote */
$entCustomerNote = $em->getRepository(EntCustomerNote::class)->find($customerNoteClient->id);
$bHasRightsToEdit = $entCustomerNote->getCreationUserId() == $user->getId() || $user->isAdmin();
if (is_null($entCustomerNote) || !$bHasRightsToEdit) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

/** @var EntCustomer $entCustomer */
$entCustomer = $em->getRepository(EntCustomer::class)->find($entCustomerNote->getCustomerId());
if (is_null($entCustomer)) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

$entCustomerNote->setClientData($em, $customerNoteClient);
$em->persist($entCustomerNote);
$em->flush();

return Reply::getResponse($entCustomer->clientMapper($em, true), Message::SUCCESS_CUSTOMER_NOTE_EDIT);
}

#[Route('/delete-customer-note', name: 'delete_customer_note')]
public function deleteCustomerNote(Request $request)
{
$customerNoteIdClient = json_decode($request->request->get('customerNoteId'));
$em = $this->getDoctrine()->getManager();
/** @var EntUser $user */
$user = $this->getUser();

/** @var EntCustomerNote $entCustomerNote */
$entCustomerNote = $em->getRepository('App:EntCustomerNote')->find($customerNoteIdClient);
$bHasRightsToDelete = $entCustomerNote->getCreationUserId() == $user->getId() || $user->isAdmin();
if (is_null($entCustomerNote) || !$bHasRightsToDelete) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

/** @var EntCustomer $entCustomer */
$entCustomer = $em->getRepository('App:EntCustomer')->find($entCustomerNote->getCustomerId());
if (is_null($entCustomer)) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

$em->remove($entCustomerNote);
$em->flush();

return Reply::getResponse($entCustomer->clientMapper($em, true), Message::SUCCESS_CUSTOMER_NOTE_DELETE);
}
}

+ 281
- 0
httpdocs/src/Controller/CustomerMeetingEditController.php Прегледај датотеку

@@ -0,0 +1,281 @@
<?php
/**
* Created by PhpStorm.
* User: danielknudsen
* Date: 05.04.18
* Time: 13:09
*/
namespace App\Controller;

use App\Entity\EntCustomer;
use App\Entity\EntCustomerMeeting;
use App\Entity\EntCustomerMeetingParticipant;
use App\Entity\EntMeetingType;
use App\Entity\EntUser;
use App\EntityVirtual\ServiceData;
use App\Utils\Message;
use App\Utils\Reply;
use App\Utils\Utils;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

#[Security("is_granted('ROLE_ADMIN') and is_granted('ROLE_SALES')")]
class CustomerMeetingEditController extends AbstractController
{
#[Route('/create-customer-meeting', name: 'create_customer_meeting')]
public function createCustomerMeeting(Request $request)
{
$customerMeetingClient = json_decode($request->request->get('customerMeeting'));
$em = $this->getDoctrine()->getManager();
/** @var EntUser $user */
$user = $this->getUser();
/** @var EntCustomer $entCustomer */
$entCustomer = $em->getRepository(EntCustomer::class)->find($customerMeetingClient->customer_id);
if (is_null($entCustomer)) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

/** @var EntUser $entOwnerUser */
$entOwnerUser = $em->getRepository(EntUser::class)->find($customerMeetingClient->owner_user_id);
if (is_null($entOwnerUser)) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

/** @var EntMeetingType $entMeetingType */
$entMeetingType = $em->getRepository(EntMeetingType::class)->find($customerMeetingClient->meeting_type_id);
if (is_null($entMeetingType)) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

// Database manipulation in transaction
$dbCon = $this->getDoctrine()->getConnection();
$dbCon->beginTransaction();

try {
/** @var EntCustomerMeeting $entCustomerMeeting */
$entCustomerMeeting = new EntCustomerMeeting($em, $entCustomer, $user, $entOwnerUser, $entMeetingType, $customerMeetingClient->is_option_meeting,
$customerMeetingClient->title, $customerMeetingClient->start_date, $customerMeetingClient->end_date);
$entCustomerMeeting->setClientData($em, $customerMeetingClient);
$em->persist($entCustomerMeeting);
$em->flush();
$cntParticipants = count($customerMeetingClient->v_participants);
for ($i = 0; $i < $cntParticipants; $i++) {
/** @var EntUser $participantUser */
$participantUser = $em->getRepository('App:EntUser')->find($customerMeetingClient->v_participants[$i]->participant_user_id);
if (is_null($participantUser)) {
throw new Exception('invalid participant user');
}

/** @var EntCustomerMeetingParticipant $entParticipant */
$entParticipant = new EntCustomerMeetingParticipant($em, $entCustomerMeeting, $participantUser);
$em->persist($entParticipant);
}
$em->flush();

} catch (Exception $e) {
return Reply::getErrorResponse(Message::ERROR_INVALID_DATA);
}
// All data stored correctly
$dbCon->commit();

$serviceData = new ServiceData();
$serviceData->addServiceData(ServiceData::SERVICE_DATA_TYPE_CUSTOMER_MEETINGS, ServiceData::ACTION_ADD, $entCustomerMeeting->clientMapper($em, true));
return Reply::getResponse($entCustomer->clientMapper($em, true), Message::SUCCESS_CUSTOMER_MEETING_CREATE, 0, $serviceData);
}

#[Route('/edit-customer-meeting', name: 'edit_customer_meeting')]
public function editCustomerMeeting(Request $request)
{
$customerMeetingClient = json_decode($request->request->get('customerMeeting'));
$em = $this->getDoctrine()->getManager();
/** @var EntUser $user */
$user = $this->getUser();
/** @var EntCustomer $entCustomer */
$entCustomer = $em->getRepository('App:EntCustomer')->find($customerMeetingClient->customer_id);
if (is_null($entCustomer)) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

/** @var EntUser $entOwnerUser */
$entOwnerUser = $em->getRepository('App:EntUser')->find($customerMeetingClient->owner_user_id);
if (is_null($entOwnerUser)) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

/** @var EntMeetingType $entMeetingType */
$entMeetingType = $em->getRepository('App:EntMeetingType')->find($customerMeetingClient->meeting_type_id);
if (is_null($entMeetingType)) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

/** @var EntCustomerMeeting $entCustomerMeeting */
$entCustomerMeeting = $em->getRepository('App:EntCustomerMeeting')->find($customerMeetingClient->id);
if (is_null($entCustomerMeeting)) {
return Reply::getErrorResponse(Message::ERROR_NON_EXISTING_DATA);
}

if (!$entCustomerMeeting->isEditDeletable()) {
return Reply::getErrorResponse(Message::ERROR_MEETING_NOT_EDIT_DELETABLE);
}

$bHasRightsToEdit =
$entCustomerMeeting->getCreationUserId() == $user->getId() ||
$entCustomerMeeting->getOwnerUserId() == $user->getId() ||
$user->isAdmin();
if (!$bHasRightsToEdit) {
return Reply::getErrorResponse(Message::ERROR_NOT_ENOUGH_RIGHTS);
}

// Database manipulation in transaction
$dbCon = $this->getDoctrine()->getConnection();
$dbCon->beginTransaction();

try {
$entCustomerMeeting->setClientData($em, $customerMeetingClient);
$em->persist($entCustomerMeeting);
$em->flush();

$formerParticipantsByUserId = Utils::getSortedObjects('getParticipantUserId',
$em->getRepository('App:EntCustomerMeetingParticipant')->findBy(['customer_meeting_id' => $entCustomerMeeting->getId()]));
$pUserIdsToKeep = [];
$cntParticipants = count($customerMeetingClient->v_participants);
for ($i = 0; $i < $cntParticipants; $i++) {
if (!array_key_exists($customerMeetingClient->v_participants[$i]->participant_user_id, $formerParticipantsByUserId)) {
/** @var EntUser $participantUser */
$participantUser = $em->getRepository('App:EntUser')->find($customerMeetingClient->v_participants[$i]->participant_user_id);
if (is_null($participantUser)) {
throw new Exception('invalid participant user');
}

/** @var EntCustomerMeetingParticipant $entParticipant */
$entParticipant = new EntCustomerMeetingParticipant($em, $entCustomerMeeting, $participantUser);
$em->persist($entParticipant);
} else {
$pUserIdsToKeep[$customerMeetingClient->v_participants[$i]->participant_user_id] = 1;
}
}

/** @var EntCustomerMeetingParticipant $formerParticipant */
foreach ($formerParticipantsByUserId as $pUserId => $formerParticipant) {
if (!array_key_exists($pUserId, $pUserIdsToKeep)) {
$em->remove($formerParticipant);
}
}
$em->flush();

} catch (Exception $e) {
return Reply::getErrorResponse(Message::ERROR_INVALID_DATA);
}
// All data stored correctly
$dbCon->commit();
$serviceData = new ServiceData();
$serviceData->addServiceData(ServiceData::SERVICE_DATA_TYPE_CUSTOMER_MEETINGS, ServiceData::ACTION_EDIT, $entCustomerMeeting->clientMapper($em, true));
return Reply::getResponse($entCustomer->clientMapper($em, true), Message::SUCCESS_CUSTOMER_MEETING_EDIT, 0, $serviceData);
}

#[Route('/delete-customer-meeting', name: 'delete_customer_meeting')]
public function deleteCustomerMeeting(Request $request)
{
$customerMeetingIdClient = json_decode($request->request->get('customerMeetingId'));
$em = $this->getDoctrine()->getManager();
/** @var EntUser $user */
$user = $this->getUser();

/** @var EntCustomerMeeting $entCustomerMeeting */
$entCustomerMeeting = $em->getRepository('App:EntCustomerMeeting')->find($customerMeetingIdClient);
if (is_null($entCustomerMeeting)) {
return Reply::getErrorResponse(Message::ERROR_NON_EXISTING_DATA);
}

$bHasRightsToDelete =
$entCustomerMeeting->getCreationUserId() == $user->getId() ||
$entCustomerMeeting->getOwnerUserId() == $user->getId() ||
$user->isAdmin();
if (!$bHasRightsToDelete) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

if (!$entCustomerMeeting->isEditDeletable()) {
return Reply::getErrorResponse(Message::ERROR_MEETING_NOT_EDIT_DELETABLE);
}

/** @var EntCustomer $entCustomer */
$entCustomer = $em->getRepository('App:EntCustomer')->find($entCustomerMeeting->getCustomerId());
if (is_null($entCustomer)) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}
$mappedCustomerMeeting = $entCustomerMeeting->clientMapper($em, true);
$em->remove($entCustomerMeeting);

$participants = $em->getRepository('App:EntCustomerMeetingParticipant')->findBy(['customer_meeting_id' => $entCustomerMeeting->getId()]);
/** @var EntCustomerMeetingParticipant $participant */
foreach ($participants as $participant) {
$em->remove($participant);
}
$em->flush();

$serviceData = new ServiceData();
$serviceData->addServiceData(ServiceData::SERVICE_DATA_TYPE_CUSTOMER_MEETINGS, ServiceData::ACTION_DELETE, $mappedCustomerMeeting);
return Reply::getResponse($entCustomer->clientMapper($em, true), Message::SUCCESS_CUSTOMER_MEETING_DELETE, 0, $serviceData);
}

#[Route('/check-customer-meeting-report', name: 'check_customer_meeting_report')]
public function checkCustomerMeetingReport(Request $request)
{
$customerMeetingIdClient = json_decode($request->request->get('customerMeetingId'));
$em = $this->getDoctrine()->getManager();
/** @var EntUser $user */
$user = $this->getUser();

/** @var EntCustomerMeeting $entCustomerMeeting */
$entCustomerMeeting = $em->getRepository('App:EntCustomerMeeting')->find($customerMeetingIdClient);
$bHasRightsToMakeReport =
$entCustomerMeeting->getCreationUserId() == $user->getId() ||
$entCustomerMeeting->getOwnerUserId() == $user->getId() ||
$user->isAdmin();
if (is_null($entCustomerMeeting) || !$bHasRightsToMakeReport) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

$check = new \DateTime() > $entCustomerMeeting->getStartDate();
return $check ? Reply::getResponse($check) : Reply::getErrorResponse(Message::ERROR_REPORT_NOT_EDITABLE_YET);
}

#[Route('/edit-customer-meeting-report', name: 'edit_customer_meeting_report')]
public function editCustomerMeetingReport(Request $request)
{
$customerMeetingIdClient = json_decode($request->request->get('customerMeetingId'));
$customerMeetingReportClient = json_decode($request->request->get('customerMeetingReport'));
$em = $this->getDoctrine()->getManager();
/** @var EntUser $user */
$user = $this->getUser();


/** @var EntCustomerMeeting $entCustomerMeeting */
$entCustomerMeeting = $em->getRepository('App:EntCustomerMeeting')->find($customerMeetingIdClient);
$bHasRightsToMakeReport =
$entCustomerMeeting->getOwnerUserId() == $user->getId() ||
$user->isAdmin();
if (is_null($entCustomerMeeting) || !$bHasRightsToMakeReport) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

$entCustomer = $em->getRepository('App:EntCustomer')->find($entCustomerMeeting->getCustomerId());
if (is_null($entCustomer)) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

$entCustomerMeeting->setReport($customerMeetingReportClient);
$em->persist($entCustomerMeeting);
$em->flush();

$serviceData = new ServiceData();
$serviceData->addServiceData(ServiceData::SERVICE_DATA_TYPE_CUSTOMER_MEETINGS, ServiceData::ACTION_EDIT, $entCustomerMeeting->clientMapper($em, true));
return Reply::getResponse($entCustomer->clientMapper($em, true), Message::SUCCESS_CUSTOMER_MEETING_REPORT_SET, 0, $serviceData);
}
}

+ 49
- 0
httpdocs/src/Controller/CustomerViewController.php Прегледај датотеку

@@ -0,0 +1,49 @@
<?php
/**
* Created by PhpStorm.
* User: danielknudsen
* Date: 05.04.18
* Time: 13:09
*/
namespace App\Controller;

use App\Entity\EntCustomer;
use App\Utils\Message;
use App\Utils\Reply;
use App\Utils\Utils;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

#[Security("is_granted('ROLE_USER')")]
class CustomerViewController extends AbstractController
{
#[Route('/get-customer-data', name: 'get_customer_data')]
public function getCustomerData()
{
$em = $this->getDoctrine()->getManager();
return Reply::getResponse(
[
'customers' => Utils::clientMap($em, $em->getRepository('App:EntCustomer')->findAll()),
'customerContacts' => Utils::clientMap($em, $em->getRepository('App:EntCustomerContact')->findAll()),
'customerMeetings' => Utils::clientMap($em, $em->getRepository('App:EntCustomerMeeting')->findAll()),
]
);
}

#[Route('/get-customer-full', name: 'get_customer_full')]
public function getCustomerFull(Request $request)
{
$customerId = json_decode($request->request->get('customerId'));
$em = $this->getDoctrine()->getManager();
/** @var EntCustomer $entCustomer */
$entCustomer = $em->getRepository('App:EntCustomer')->find($customerId);
if (is_null($entCustomer)) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

return Reply::getResponse($entCustomer->clientMapper($em, true));
}

}

+ 80
- 0
httpdocs/src/Controller/ExportController.php Прегледај датотеку

@@ -0,0 +1,80 @@
<?php
/**
* Created by PhpStorm.
* User: danielknudsen
* Date: 05.04.18
* Time: 13:09
*/
namespace App\Controller;

use App\Entity\EntUser;
use App\Utils\Reply;
use Dompdf\Dompdf;
use Dompdf\Options;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

#[Security("is_granted('ROLE_ACCOUNTING') and is_granted('ROLE_TECHNIQUE')")]
class ExportController extends AbstractController
{
const CONTACT_PDF_TYPE_CUSTOMER = 'customer';

#[Route('/get-customer-full', name: 'get_customer_full')]
public function exportContacts(Request $request)
{
ini_set('max_execution_time', '300');
ini_set('memory_limit','1024');
$type = $request->request->get('type');
$em = $this->getDoctrine()->getManager();
$title = "";
/** @var EntUser $user */
$user = $this->getUser();


switch ($type) {
case self::CONTACT_PDF_TYPE_CUSTOMER:
if (!$user->isAdmin()) {
throw new Exception('invalid role');
}
$sql = "SELECT cc.*, c.name AS company
FROM customer_contact cc, customer c
WHERE cc.customer_id = c.id
ORDER BY company ASC, cc.lastname ASC";
$statement = $em->getConnection()->prepare($sql);
$statement->execute();
$entries = $statement->fetchAll();
$title = "Kunden Kontakte";
break;
default:
throw new Exception('invalid type given');
}

// Configure Dompdf according to your needs
$pdfOptions = new Options();
$pdfOptions->set('defaultFont', 'Arial');

// Instantiate Dompdf with our options
$dompdf = new Dompdf($pdfOptions);

// Retrieve the HTML generated in our twig file
$html = $this->renderView('contacts_export.html.twig', [
'data' => $entries,
'title' => $title
]);

// Load HTML to Dompdf
$dompdf->loadHtml($html);

// (Optional) Setup the paper size and orientation 'portrait' or 'portrait'
$dompdf->setPaper('A4', 'landscape');

// Render the HTML as PDF
$dompdf->render();

return Reply::getSteamedFileResponse($dompdf->output());
}

}

+ 247
- 0
httpdocs/src/Controller/InternalMeetingEditController.php Прегледај датотеку

@@ -0,0 +1,247 @@
<?php
/**
* Created by PhpStorm.
* User: danielknudsen
* Date: 05.04.18
* Time: 13:09
*/
namespace App\Controller;

use App\Entity\EntInternalMeeting;
use App\Entity\EntInternalMeetingParticipant;
use App\Entity\EntUser;
use App\EntityVirtual\ServiceData;
use App\Utils\Message;
use App\Utils\Reply;
use App\Utils\Utils;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

#[Security("is_granted('ROLE_USER')")]
class InternalMeetingEditController extends AbstractController
{
#[Route('/create-internal-meeting', name: 'create_internal_meeting')]
public function createInternalMeeting(Request $request)
{
$internalMeetingClient = json_decode($request->request->get('internalMeeting'));
$em = $this->getDoctrine()->getManager();
/** @var EntUser $user */
$user = $this->getUser();

/** @var EntUser $entOwnerUser */
$entOwnerUser = $em->getRepository('App:EntUser')->find($internalMeetingClient->owner_user_id);
if (is_null($entOwnerUser)) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

// Database manipulation in transaction
$dbCon = $this->getDoctrine()->getConnection();
$dbCon->beginTransaction();

try {
/** @var EntInternalMeeting $entInternalMeeting */
$entInternalMeeting = new EntInternalMeeting($em, $user, $entOwnerUser, $internalMeetingClient->title, $internalMeetingClient->start_date, $internalMeetingClient->end_date);
$entInternalMeeting->setClientData($em, $internalMeetingClient);
$em->persist($entInternalMeeting);
$em->flush();
$cntParticipants = count($internalMeetingClient->v_participants);
for ($i = 0; $i < $cntParticipants; $i++) {
/** @var EntUser $participantUser */
$participantUser = $em->getRepository('App:EntUser')->find($internalMeetingClient->v_participants[$i]->participant_user_id);
if (is_null($participantUser)) {
throw new Exception('invalid participant user');
}

/** @var EntInternalMeetingParticipant $entParticipant */
$entParticipant = new EntInternalMeetingParticipant($em, $entInternalMeeting, $participantUser);
$em->persist($entParticipant);
}
$em->flush();

} catch (Exception $e) {
return Reply::getErrorResponse(Message::ERROR_INVALID_DATA);
}
// All data stored correctly
$dbCon->commit();

$mappedInternalMeeting = $entInternalMeeting->clientMapper($em, true);
$serviceData = new ServiceData();
$serviceData->addServiceData(ServiceData::SERVICE_DATA_TYPE_INTERNAL_MEETINGS, ServiceData::ACTION_ADD, $mappedInternalMeeting);
return Reply::getResponse($mappedInternalMeeting, Message::SUCCESS_INTERNAL_MEETING_CREATE, 0, $serviceData);
}

#[Route('/edit-internal-meeting', name: 'edit_internal_meeting')]
public function editInternalMeeting(Request $request)
{
$internalMeetingClient = json_decode($request->request->get('internalMeeting'));
$em = $this->getDoctrine()->getManager();
/** @var EntUser $user */
$user = $this->getUser();

/** @var EntUser $entOwnerUser */
$entOwnerUser = $em->getRepository('App:EntUser')->find($internalMeetingClient->owner_user_id);
if (is_null($entOwnerUser)) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

/** @var EntInternalMeeting $entInternalMeeting */
$entInternalMeeting = $em->getRepository('App:EntInternalMeeting')->find($internalMeetingClient->id);
if (is_null($entInternalMeeting)) {
return Reply::getErrorResponse(Message::ERROR_NON_EXISTING_DATA);
}

$bHasRightsToEdit =
$entInternalMeeting->getCreationUserId() == $user->getId() ||
$entInternalMeeting->getOwnerUserId() == $user->getId() ||
$user->isAdmin();
if (!$bHasRightsToEdit) {
return Reply::getErrorResponse(Message::ERROR_NOT_ENOUGH_RIGHTS);
}

if (!$entInternalMeeting->isEditDeletable()) {
return Reply::getErrorResponse(Message::ERROR_MEETING_NOT_EDIT_DELETABLE);
}

// Database manipulation in transaction
$dbCon = $this->getDoctrine()->getConnection();
$dbCon->beginTransaction();

try {
$entInternalMeeting->setClientData($em, $internalMeetingClient);
$em->persist($entInternalMeeting);
$em->flush();

$formerParticipantsByUserId = Utils::getSortedObjects('getParticipantUserId',
$em->getRepository('App:EntInternalMeetingParticipant')->findBy(['internal_meeting_id' => $entInternalMeeting->getId()]));
$pUserIdsToKeep = [];
$cntParticipants = count($internalMeetingClient->v_participants);
for ($i = 0; $i < $cntParticipants; $i++) {
if (!array_key_exists($internalMeetingClient->v_participants[$i]->participant_user_id, $formerParticipantsByUserId)) {
/** @var EntUser $participantUser */
$participantUser = $em->getRepository('App:EntUser')->find($internalMeetingClient->v_participants[$i]->participant_user_id);
if (is_null($participantUser)) {
throw new Exception('invalid participant user');
}

/** @var EntInternalMeetingParticipant $entParticipant */
$entParticipant = new EntInternalMeetingParticipant($em, $entInternalMeeting, $participantUser);
$em->persist($entParticipant);
} else {
$pUserIdsToKeep[$internalMeetingClient->v_participants[$i]->participant_user_id] = 1;
}
}

/** @var EntInternalMeetingParticipant $formerParticipant */
foreach ($formerParticipantsByUserId as $pUserId => $formerParticipant) {
if (!array_key_exists($pUserId, $pUserIdsToKeep)) {
$em->remove($formerParticipant);
}
}
$em->flush();

} catch (Exception $e) {
return Reply::getErrorResponse(Message::ERROR_INVALID_DATA);
}
// All data stored correctly
$dbCon->commit();

$mappedInternalMeeting = $entInternalMeeting->clientMapper($em, true);
$serviceData = new ServiceData();
$serviceData->addServiceData(ServiceData::SERVICE_DATA_TYPE_INTERNAL_MEETINGS, ServiceData::ACTION_EDIT, $mappedInternalMeeting);
return Reply::getResponse($mappedInternalMeeting, Message::SUCCESS_INTERNAL_MEETING_EDIT, 0, $serviceData);
}

#[Route('/delete-internal-meeting', name: 'delete_internal_meeting')]
public function deleteInternalMeeting(Request $request)
{
$internalMeetingIdClient = json_decode($request->request->get('internalMeetingId'));
$em = $this->getDoctrine()->getManager();
/** @var EntUser $user */
$user = $this->getUser();

/** @var EntInternalMeeting $entInternalMeeting */
$entInternalMeeting = $em->getRepository('App:EntInternalMeeting')->find($internalMeetingIdClient);
if (is_null($entInternalMeeting)) {
return Reply::getErrorResponse(Message::ERROR_NON_EXISTING_DATA);
}

$bHasRightsToDelete =
$entInternalMeeting->getCreationUserId() == $user->getId() ||
$entInternalMeeting->getOwnerUserId() == $user->getId() ||
$user->isAdmin();
if (!$bHasRightsToDelete) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

if (!$entInternalMeeting->isEditDeletable()) {
return Reply::getErrorResponse(Message::ERROR_MEETING_NOT_EDIT_DELETABLE);
}

$mappedInternalMeeting = $entInternalMeeting->clientMapper($em, true);
$em->remove($entInternalMeeting);

$participants = $em->getRepository('App:EntInternalMeetingParticipant')->findBy(['internal_meeting_id' => $entInternalMeeting->getId()]);
/** @var EntInternalMeetingParticipant $participant */
foreach ($participants as $participant) {
$em->remove($participant);
}
$em->flush();

$serviceData = new ServiceData();
$serviceData->addServiceData(ServiceData::SERVICE_DATA_TYPE_INTERNAL_MEETINGS, ServiceData::ACTION_DELETE, $mappedInternalMeeting);
return Reply::getResponse($mappedInternalMeeting, Message::SUCCESS_INTERNAL_MEETING_DELETE, 0, $serviceData);
}

#[Route('/check-internal-meeting-report', name: 'check_internal_meeting_report')]
public function checkInternalMeetingReport(Request $request)
{
$internalMeetingIdClient = json_decode($request->request->get('internalMeetingId'));
$em = $this->getDoctrine()->getManager();
/** @var EntUser $user */
$user = $this->getUser();

/** @var EntInternalMeeting $entInternalMeeting */
$entInternalMeeting = $em->getRepository('App:EntInternalMeeting')->find($internalMeetingIdClient);
$bHasRightsToMakeReport =
$entInternalMeeting->getOwnerUserId() == $user->getId() ||
$user->isAdmin();
if (is_null($entInternalMeeting) || !$bHasRightsToMakeReport) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

$check = new \DateTime() > $entInternalMeeting->getStartDate();
return $check ? Reply::getResponse($check) : Reply::getErrorResponse(Message::ERROR_REPORT_NOT_EDITABLE_YET);
}

#[Route('/edit-internal-meeting-report', name: 'edit_internal_meeting_report')]
public function editInternalMeetingReport(Request $request)
{
$internalMeetingIdClient = json_decode($request->request->get('internalMeetingId'));
$internalMeetingReportClient = json_decode($request->request->get('internalMeetingReport'));
$em = $this->getDoctrine()->getManager();
/** @var EntUser $user */
$user = $this->getUser();


/** @var EntInternalMeeting $entInternalMeeting */
$entInternalMeeting = $em->getRepository('App:EntInternalMeeting')->find($internalMeetingIdClient);
$bHasRightsToMakeReport =
$entInternalMeeting->getOwnerUserId() == $user->getId() ||
$user->isAdmin();
if (is_null($entInternalMeeting) || !$bHasRightsToMakeReport) {
return Reply::getErrorResponse(Message::ERROR_DEFAULT);
}

$entInternalMeeting->setReport($internalMeetingReportClient);
$em->persist($entInternalMeeting);
$em->flush();

$mappedInternalMeeting = $entInternalMeeting->clientMapper($em, true);
$serviceData = new ServiceData();
$serviceData->addServiceData(ServiceData::SERVICE_DATA_TYPE_INTERNAL_MEETINGS, ServiceData::ACTION_EDIT, $mappedInternalMeeting);
return Reply::getResponse($mappedInternalMeeting, Message::SUCCESS_INTERNAL_MEETING_REPORT_SET, 0, $serviceData);
}
}

+ 90
- 0
httpdocs/src/Controller/MeetingViewController.php Прегледај датотеку

@@ -0,0 +1,90 @@
<?php
/**
* Created by PhpStorm.
* User: danielknudsen
* Date: 05.04.18
* Time: 13:09
*/
namespace App\Controller;

use App\Entity\EntCustomerMeeting;
use App\Entity\EntInternalMeeting;
use App\Utils\Excel;
use App\Utils\ExcelStyle;
use App\Utils\Reply;
use App\Utils\Utils;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

#[Security("is_granted('ROLE_USER')")]
class MeetingViewController extends AbstractController
{
#[Route('/get-meeting-data', name: 'get_meeting_data')]
public function getMeetingData()
{
$em = $this->getDoctrine()->getManager();
return Reply::getResponse(
[
'customerMeetings' => Utils::clientMap($em, $em->getRepository(EntCustomerMeeting::class)->findAll()),
'internalMeetings' => Utils::clientMap($em, $em->getRepository(EntInternalMeeting::class)->findAll()),
]
);
}

#[Route('/export-meeting-list', name: 'export_meeting_list')]
public function exportMeetingData(Request $request)
{
$clientData = json_decode($request->request->get('meetingList'));
$assetDir = $this->getParameter('asset_directory');

$spreadsheet = new Spreadsheet();
$activeSheet = $spreadsheet->getActiveSheet();

$writer = new Xlsx($spreadsheet);

Excel::setRangeColor($activeSheet, 'A', 1, 'I', 1, 'FF9bb3d4');

Excel::setColumn($activeSheet, 'A', 20, "Typ",
ExcelStyle::$CADASTER_BORDERS, 1,Alignment::HORIZONTAL_LEFT, Alignment::HORIZONTAL_LEFT, true, 'FFD9D8D9', null, true);
Excel::setColumn($activeSheet, 'B', 20, "Datum (Start)",
ExcelStyle::$CADASTER_BORDERS, 1,Alignment::HORIZONTAL_LEFT, Alignment::HORIZONTAL_LEFT, true, 'FFD9D8D9', null, true);
Excel::setColumn($activeSheet, 'C', 20, "Datum (Ende)",
ExcelStyle::$CADASTER_BORDERS, 1,Alignment::HORIZONTAL_LEFT, Alignment::HORIZONTAL_LEFT, true, 'FFD9D8D9', null, true);
Excel::setColumn($activeSheet, 'D', 30, "Kunde / Betreiber",
ExcelStyle::$CADASTER_BORDERS, 1,Alignment::HORIZONTAL_LEFT, Alignment::HORIZONTAL_LEFT, true, 'FFD9D8D9', null, true);
Excel::setColumn($activeSheet, 'E', 30, "PLP Verantwortlicher",
ExcelStyle::$CADASTER_BORDERS, 1,Alignment::HORIZONTAL_LEFT, Alignment::HORIZONTAL_LEFT, true, 'FFD9D8D9', null, true);
Excel::setColumn($activeSheet, 'F', 30, "Gesprächspartner",
ExcelStyle::$CADASTER_BORDERS, 1,Alignment::HORIZONTAL_LEFT, Alignment::HORIZONTAL_LEFT, true, 'FFD9D8D9', null, true);
Excel::setColumn($activeSheet, 'G', 40, "Titel",
ExcelStyle::$CADASTER_BORDERS, 1,Alignment::HORIZONTAL_LEFT, Alignment::HORIZONTAL_LEFT, true, 'FFD9D8D9', null, true);
Excel::setColumn($activeSheet, 'H', 10, "Termin-Art",
ExcelStyle::$CADASTER_BORDERS, 1,Alignment::HORIZONTAL_LEFT, Alignment::HORIZONTAL_LEFT, true, 'FFD9D8D9', null, true);
Excel::setColumn($activeSheet, 'I', 10, "Options-Termin",
ExcelStyle::$CADASTER_BORDERS, 1,Alignment::HORIZONTAL_LEFT, Alignment::HORIZONTAL_LEFT, true, 'FFD9D8D9', null, true);

$entryRowIndex = 2;
foreach ($clientData as $entry) {
$activeSheet->getCell('A'.$entryRowIndex)->setValue($entry->itemType === "customer" ? "Kundentermin" : ($entry->itemType === "internal" ? "Intern" : "Betreibertermin"));

$startDate = \DateTime::createFromFormat('Y-m-d H:i:s', $entry->dateStart);
$endDate = \DateTime::createFromFormat('Y-m-d H:i:s', $entry->dateEnd);
$activeSheet->getCell('B'.$entryRowIndex)->setValue(date_format($startDate, 'd.m.Y H:i'));
$activeSheet->getCell('C'.$entryRowIndex)->setValue(date_format($endDate, 'd.m.Y H:i'));
$activeSheet->getCell('D'.$entryRowIndex)->setValue($entry->objectName);
$activeSheet->getCell('E'.$entryRowIndex)->setValue($entry->owner);
$activeSheet->getCell('F'.$entryRowIndex)->setValue($entry->contactName);
$activeSheet->getCell('G'.$entryRowIndex)->setValue($entry->title);
$activeSheet->getCell('H'.$entryRowIndex)->setValue($entry->type);
$activeSheet->getCell('I'.$entryRowIndex)->setValue($entry->is_option_meeting ? "Ja" : "Nein");
$entryRowIndex++;
}

return Reply::getExcelResponse($spreadsheet, $writer, $assetDir, "Terminliste");
}
}

+ 57
- 0
httpdocs/src/Controller/PublicController.php Прегледај датотеку

@@ -0,0 +1,57 @@
<?php
/**
* Created by PhpStorm.
* User: danielknudsen
* Date: 05.04.18
* Time: 13:09
*/
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class PublicController extends AbstractController
{
#[Route('/', name: 'index')]
public function showIndexAction()
{
$data = array(
// you might translate this message
'message' => 'CRM api ready'
);
return new JsonResponse($data);
}

#[Route('/test', name: 'test')]
public function showTestAction()
{
$data = array(
// you might translate this message
'message' => 'PHP api'
);
//return 1;
return new Response('<html><body>Debug data</body></html>');
}

#[Route('/login', name: 'login')]
public function loginAction()
{
$error = $this->get('security.authentication_utils')->getLastAuthenticationError();

$data = [
'error' => $error
];

return new JsonResponse($data);
}

#[Route('/logout', name: 'security_logout')]
public function logoutAction()
{
throw new Exception('this should not be reached');
}

}

+ 0
- 0
httpdocs/src/Entity/.gitignore Прегледај датотеку


+ 166
- 0
httpdocs/src/Entity/EntCountry.php Прегледај датотеку

@@ -0,0 +1,166 @@
<?php

namespace App\Entity;
use App\Entity\IFace\IEntity;
use App\Utils\Utils;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Config\Definition\Exception\Exception;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity
* @ORM\Table(name="country")
*/
class EntCountry implements IEntity
{
const COUNTRY_GERMANY_ID = 1;
const COUNTRY_AUSTRIA_ID = 2;
const COUNTRY_SWITZERLAND_ID = 3;
const COUNTRY_FRANCE_ID = 4;

private static $cacheCountriesById = null;
private static $cacheCountriesByName = null;

private static $validCountries = array(
self::COUNTRY_GERMANY_ID => 'Deutschland',
self::COUNTRY_AUSTRIA_ID => 'Österreich',
self::COUNTRY_SWITZERLAND_ID => 'Schweiz',
self::COUNTRY_FRANCE_ID => 'Frankreich',
);

/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
protected $id;

/**
* @ORM\Column(type="string", length=50, nullable=false)
*/
protected $name;

/**
* @ORM\Column(type="string", length=3)
*/
protected $iso_code;


/**
* Gets static countries
* @param EntityManagerInterface $em
* @return array
*/
public static function getCountriesById(EntityManagerInterface $em)
{
if (is_null(self::$cacheCountriesById)) {
self::$cacheCountriesById = Utils::getSortedObjectsById($em->getRepository('App:EntCountry')->findAll());
}
return self::$cacheCountriesById;
}

/**
* Gets static country
* @param EntityManagerInterface $em
* @param $countryId
* @return mixed|null
*/
public static function getCountryById(EntityManagerInterface $em, $countryId)
{
$entCountries = self::getCountriesById($em);
return array_key_exists($countryId, $entCountries) ? $entCountries[$countryId] : null;
}

/**
* Gets static country by name
* @param EntityManagerInterface $em
* @param $countryName
* @return mixed|null
*/
public static function getCountryByName(EntityManagerInterface $em, $countryName)
{
$entCountries = self::getCountriesById($em);
if (is_null(self::$cacheCountriesByName)) {
self::$cacheCountriesByName = Utils::getSortedObjects('getName', $entCountries);
}
return array_key_exists($countryName, self::$cacheCountriesByName) ? self::$cacheCountriesByName[$countryName] : null;
}

/**
* EntCountry constructor.
* @param $countryName
* @param $isoCode
*/
public function __construct($countryName, $isoCode)
{
if (!in_array($countryName, self::$validCountries)) {
throw new Exception('Invalid country name');
}

$this->name = $countryName;
$this->iso_code = $isoCode;
}

/**
* @return mixed
*/
public function getId()
{
return $this->id;
}

/**
* @return mixed
*/
public function getName()
{
return $this->name;
}

/**
* @return mixed
*/
public function getIsoCode()
{
return $this->iso_code;
}

/**
* Returns if country id is valid
* @param $countryId
* @return bool
*/
public static function isValidCountryId($countryId)
{
return array_key_exists($countryId, self::$validCountries);
}

/**
* Returns country name by given country id
* @param $countryId
* @return mixed|string
*/
public static function getCountryNameById($countryId)
{
if (!self::isValidCountryId($countryId)) {
return "";
}
return self::$validCountries[$countryId];
}

/**
* Clientmapper
* @param EntityManagerInterface $em
* @param bool $fullMapping
* @return array
*/
public function clientMapper(EntityManagerInterface $em, $fullMapping = false)
{
return [
'id' => $this->getId(),
'name' => $this->getName(),
'iso_code' => $this->getIsoCode(),
];
}
}

+ 458
- 0
httpdocs/src/Entity/EntCustomer.php Прегледај датотеку

@@ -0,0 +1,458 @@
<?php

namespace App\Entity;


use App\Entity\IFace\IEntity;
use App\Utils\Utils;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity
* @ORM\Table(name="customer")
*/
class EntCustomer implements IEntity
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
protected $id;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $old_plp_id;

/**
* @ORM\Column(type="string", nullable=false)
*/
protected $name;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $name_additional;

/**
* @ORM\Column(type="integer", nullable=true, options={"unsigned" = true})
*/
protected $consultant_user_id;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $street;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $street_no;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $zip;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $city;

/**
* @ORM\Column(type="integer", nullable=true, options={"unsigned" = true})
*/
protected $country_id;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $url;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $email;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $phone_no;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $mobile_no;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $fax_no;

/**
* @ORM\Column(type="text", nullable=true)
*/
protected $comment;

/**
* @ORM\Column(type="boolean", nullable=false)
*/
protected $active;

/**
* @ORM\Column(type="datetime", nullable=false)
*/
protected $creation_date;

/**
* EntCustomer constructor.
* @param ObjectManager $em
* @param $name
* @throws \Exception
*/
public function __construct(ObjectManager $em, $name)
{
$this->name = $name;
$this->active = true;
$this->creation_date = new \DateTime();
}

/**
* @return mixed
*/
public function getId()
{
return $this->id;
}

/**
* @return mixed
*/
public function getName()
{
return $this->name;
}

/**
* @return mixed
*/
public function getNameAdditional()
{
return $this->name_additional;
}

/**
* @return mixed
*/
public function getConsultantUserId()
{
return $this->consultant_user_id;
}

/**
* @return mixed
*/
public function getStreet()
{
return $this->street;
}

/**
* @return mixed
*/
public function getStreetNo()
{
return $this->street_no;
}

/**
* @return mixed
*/
public function getZip()
{
return $this->zip;
}

/**
* @return mixed
*/
public function getCity()
{
return $this->city;
}

/**
* @return mixed
*/
public function getCountryId()
{
return $this->country_id;
}

/**
* @return mixed
*/
public function getUrl()
{
return $this->url;
}

/**
* @return mixed
*/
public function getEmail()
{
return $this->email;
}

/**
* @return mixed
*/
public function getPhoneNo()
{
return $this->phone_no;
}

/**
* @return mixed
*/
public function getMobileNo()
{
return $this->mobile_no;
}

/**
* @return mixed
*/
public function getFaxNo()
{
return $this->fax_no;
}

/**
* @return mixed
*/
public function getComment()
{
return $this->comment;
}

/**
* @return mixed
*/
public function getActive()
{
return $this->active;
}

/**
* @return mixed
*/
public function getOldPlpId()
{
return $this->old_plp_id;
}

/**
* @return mixed
*/
public function getCreationDate()
{
return $this->creation_date;
}

/**
* @param mixed $name
*/
public function setName($name): void
{
$this->name = $name;
}

/**
* @param mixed $name_additional
*/
public function setNameAdditional($name_additional): void
{
$this->name_additional = $name_additional;
}

/**
* @param mixed $consultant_user_id
*/
public function setConsultantUserId($consultant_user_id): void
{
$this->consultant_user_id = $consultant_user_id;
}

/**
* @param mixed $street
*/
public function setStreet($street): void
{
$this->street = $street;
}

/**
* @param mixed $street_no
*/
public function setStreetNo($street_no): void
{
$this->street_no = $street_no;
}

/**
* @param mixed $zip
*/
public function setZip($zip): void
{
$this->zip = $zip;
}

/**
* @param mixed $city
*/
public function setCity($city): void
{
$this->city = $city;
}

/**
* @param mixed $country_id
*/
public function setCountryId($country_id): void
{
$this->country_id = $country_id;
}

/**
* @param mixed $url
*/
public function setUrl($url): void
{
$this->url = $url;
}

/**
* @param mixed $email
*/
public function setEmail($email): void
{
$this->email = $email;
}

/**
* @param mixed $phone_no
*/
public function setPhoneNo($phone_no): void
{
$this->phone_no = $phone_no;
}

/**
* @param mixed $mobile_no
*/
public function setMobileNo($mobile_no): void
{
$this->mobile_no = $mobile_no;
}

/**
* @param mixed $fax_no
*/
public function setFaxNo($fax_no): void
{
$this->fax_no = $fax_no;
}

/**
* @param mixed $active
*/
public function setActive($active): void
{
$this->active = $active;
}

/**
* @param mixed $comment
*/
public function setComment($comment): void
{
$this->comment = $comment;
}

/**
* @param mixed $old_plp_id
*/
public function setOldPlpId($old_plp_id): void
{
$this->old_plp_id = $old_plp_id;
}

/**
* Sets client data
* @param EntityManagerInterface $em
* @param $clientData
*/
public function setClientData(EntityManagerInterface $em, $clientData)
{
$this->setName($clientData->name);
$this->setNameAdditional($clientData->name_additional);
$this->setStreet($clientData->street);
$this->setStreetNo($clientData->street_no);
$this->setZip($clientData->zip);
$this->setCity($clientData->city);
$this->setCountryId($clientData->country_id);
$this->setUrl($clientData->url);
$this->setEmail($clientData->email);
$this->setPhoneNo($clientData->phone_no);
$this->setMobileNo($clientData->mobile_no);
$this->setFaxNo($clientData->fax_no);
$this->setComment($clientData->comment);
$this->setActive($clientData->active);
$this->setConsultantUserId($clientData->consultant_user_id);
}

/**
* Client mapper
* @param EntityManagerInterface $em
* @param bool $fullMapping
* @return array
*/
public function clientMapper(EntityManagerInterface $em, $fullMapping = false)
{
$res = [
'id' => $this->id,
'old_plp_id' => $this->old_plp_id,
'name' => $this->name,
'name_additional' => $this->name_additional,
'consultant_user_id' => $this->consultant_user_id,
'street' => $this->street,
'street_no' => $this->street_no,
'zip' => $this->zip,
'city' => $this->city,
'country_id' => $this->country_id,
'url' => $this->url,
'email' => $this->email,
'phone_no' => $this->phone_no,
'mobile_no' => $this->mobile_no,
'fax_no' => $this->fax_no,
'comment' => $this->comment,
'active' => $this->active,
'v_customer_contacts' => [],
'v_customer_notes' => [],
'v_customer_meetings' => [],
];

if ($fullMapping) {
$res['v_customer_contacts'] = Utils::clientMap($em, $em->getRepository('App:EntCustomerContact')->findBy(['customer_id' => $this->getId()]));
$res['v_customer_notes'] = Utils::clientMap($em, $em->getRepository('App:EntCustomerNote')->findBy(['customer_id' => $this->getId()]));
$res['v_customer_meetings'] = Utils::clientMap($em, $em->getRepository('App:EntCustomerMeeting')->findBy(['customer_id' => $this->getId()]));
}

return $res;
}

}

+ 473
- 0
httpdocs/src/Entity/EntCustomerContact.php Прегледај датотеку

@@ -0,0 +1,473 @@
<?php

namespace App\Entity;


use App\Entity\IFace\IEntity;
use App\Utils\Utils;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Config\Definition\Exception\Exception;

/**
* @ORM\Entity
* @ORM\Table(name="customer_contact")
*/
class EntCustomerContact implements IEntity
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
protected $id;

/**
* @ORM\Column(type="integer", nullable=false, options={"unsigned" = true})
*/
protected $customer_id;

/**
* @ORM\Column(name="gender", type="string", columnDefinition="enum('male', 'female', 'diverse')")
*/
protected $gender;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $firstname;

/**
* @ORM\Column(type="string", nullable=false)
*/
protected $lastname;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $email;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $phone_no;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $mobile_no;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $fax_no;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $department;

/**
* @ORM\Column(type="date", nullable=true)
*/
protected $date_of_birth;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $street;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $street_no;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $zip;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $city;

/**
* @ORM\Column(type="integer", nullable=true, options={"unsigned" = true})
*/
protected $country_id;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $comment;

/**
* @ORM\Column(type="datetime", nullable=false)
*/
protected $creation_date;

/**
* @ORM\Column(type="boolean", nullable=false)
*/
protected $is_xmas_mail_recipient = false;

/**
* EntCustomerContact constructor.
* @param ObjectManager $em
* @param EntCustomer $entCustomer
* @param $lastName
* @throws \Exception
*/
public function __construct(ObjectManager $em, EntCustomer $entCustomer, $lastName)
{
if (is_null($entCustomer->getId())) {
throw new Exception('no id found');
}

$this->customer_id = $entCustomer->getId();
$this->lastname = $lastName;
$this->creation_date = new \DateTime();
}

/**
* @return mixed
*/
public function getId()
{
return $this->id;
}

/**
* @return mixed
*/
public function getCustomerId()
{
return $this->customer_id;
}

/**
* @return mixed
*/
public function getGender()
{
return $this->gender;
}

/**
* @return mixed
*/
public function getFirstname()
{
return $this->firstname;
}

/**
* @return mixed
*/
public function getLastname()
{
return $this->lastname;
}

/**
* @return mixed
*/
public function getEmail()
{
return $this->email;
}

/**
* @return mixed
*/
public function getPhoneNo()
{
return $this->phone_no;
}

/**
* @return mixed
*/
public function getMobileNo()
{
return $this->mobile_no;
}

/**
* @return mixed
*/
public function getFaxNo()
{
return $this->fax_no;
}

/**
* @return mixed
*/
public function getDepartment()
{
return $this->department;
}

/**
* @return mixed
*/
public function getCreationDate()
{
return $this->creation_date;
}

/**
* @return mixed
*/
public function getDateOfBirth()
{
return $this->date_of_birth;
}

/**
* @return mixed
*/
public function getStreet()
{
return $this->street;
}

/**
* @return mixed
*/
public function getStreetNo()
{
return $this->street_no;
}

/**
* @return mixed
*/
public function getZip()
{
return $this->zip;
}

/**
* @return mixed
*/
public function getCity()
{
return $this->city;
}

/**
* @return mixed
*/
public function getCountryId()
{
return $this->country_id;
}

/**
* @return mixed
*/
public function getComment()
{
return $this->comment;
}

/**
* @param mixed $gender
*/
public function setGender($gender): void
{
if (!is_null($gender) && !Utils::isValidGender($gender)) {
throw new Exception('invalid gender');
}
$this->gender = $gender;
}

/**
* @param mixed $firstname
*/
public function setFirstname($firstname): void
{
$this->firstname = $firstname;
}

/**
* @param mixed $lastname
*/
public function setLastname($lastname): void
{
$this->lastname = $lastname;
}

/**
* @param mixed $email
*/
public function setEmail($email): void
{
$this->email = $email;
}

/**
* @param mixed $phone_no
*/
public function setPhoneNo($phone_no): void
{
$this->phone_no = $phone_no;
}

/**
* @param mixed $mobile_no
*/
public function setMobileNo($mobile_no): void
{
$this->mobile_no = $mobile_no;
}

/**
* @param mixed $fax_no
*/
public function setFaxNo($fax_no): void
{
$this->fax_no = $fax_no;
}

/**
* @param mixed $department
*/
public function setDepartment($department): void
{
$this->department = $department;
}

/**
* @param mixed $date_of_birth
*/
public function setDateOfBirth($date_of_birth): void
{
$this->date_of_birth = !is_null($date_of_birth) ? \DateTime::createFromFormat('Y-m-d', $date_of_birth) : $date_of_birth;
}

/**
* @param mixed $street
*/
public function setStreet($street): void
{
$this->street = $street;
}

/**
* @param mixed $street_no
*/
public function setStreetNo($street_no): void
{
$this->street_no = $street_no;
}

/**
* @param mixed $zip
*/
public function setZip($zip): void
{
$this->zip = $zip;
}

/**
* @param mixed $city
*/
public function setCity($city): void
{
$this->city = $city;
}

/**
* @param mixed $country_id
*/
public function setCountryId($country_id): void
{
$this->country_id = $country_id;
}

/**
* @param mixed $comment
*/
public function setComment($comment): void
{
$this->comment = $comment;
}

/**
* @return bool
*/
public function isIsxmasMailRecipient(): bool
{
return $this->is_xmas_mail_recipient;
}

/**
* @param bool $is_xmas_mail_recipient
*/
public function setIsxmasMailRecipient(bool $is_xmas_mail_recipient): void
{
$this->is_xmas_mail_recipient = $is_xmas_mail_recipient;
}

/**
* Sets client data
* @param EntityManagerInterface $em
* @param $clientData
*/
public function setClientData(EntityManagerInterface $em, $clientData)
{
$this->setGender($clientData->gender);
$this->setFirstname($clientData->firstname);
$this->setLastname($clientData->lastname);
$this->setEmail($clientData->email);
$this->setPhoneNo($clientData->phone_no);
$this->setMobileNo($clientData->mobile_no);
$this->setFaxNo($clientData->fax_no);
$this->setDepartment($clientData->department);
$this->setDateOfBirth($clientData->date_of_birth);
$this->setStreet($clientData->street);
$this->setStreetNo($clientData->street_no);
$this->setZip($clientData->zip);
$this->setCity($clientData->city);
$this->setCountryId($clientData->country_id);
$this->setComment($clientData->comment);
$this->setIsxmasMailRecipient($clientData->is_xmas_mail_recipient);

}

/**
* Client mapper
* @param EntityManagerInterface $em
* @param bool $fullMapping
* @return array
*/
public function clientMapper(EntityManagerInterface $em, $fullMapping = false)
{
return [
'id' => $this->id,
'customer_id' => $this->customer_id,
'gender' => $this->gender,
'firstname' => $this->firstname,
'lastname' => $this->lastname,
'email' => $this->email,
'phone_no' => $this->phone_no,
'mobile_no' => $this->mobile_no,
'fax_no' => $this->fax_no,
'department' => $this->department,
'date_of_birth' => !is_null($this->date_of_birth) ? $this->date_of_birth->format('Y-m-d'): null,
'street' => $this->street,
'street_no' => $this->street_no,
'zip' => $this->zip,
'city' => $this->city,
'country_id' => $this->country_id,
'comment' => $this->comment,
'is_xmas_mail_recipient' => $this->is_xmas_mail_recipient,
];
}

}

+ 758
- 0
httpdocs/src/Entity/EntCustomerMeeting.php Прегледај датотеку

@@ -0,0 +1,758 @@
<?php

namespace App\Entity;


use App\Entity\IFace\IEntity;
use App\Utils\Utils;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Config\Definition\Exception\Exception;

/**
* @ORM\Entity
* @ORM\Table(name="customer_meeting", indexes={@ORM\Index(name="search_customer_idx", columns={"customer_id", "owner_user_id", "customer_contact_id"})})
*/
class EntCustomerMeeting implements IEntity
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
protected $id;

/**
* @ORM\Column(type="integer", nullable=false, options={"unsigned" = true})
*/
protected $customer_id;

/**
* @ORM\Column(type="integer", nullable=false, options={"unsigned" = true})
*/
protected $creation_user_id;

/**
* @ORM\Column(type="integer", nullable=false, options={"unsigned" = true})
*/
protected $owner_user_id;

/**
* @ORM\Column(type="integer", nullable=false, options={"unsigned" = true})
*/
protected $meeting_type_id;

/**
* @ORM\Column(type="boolean", nullable=false)
*/
protected $is_option_meeting;

/**
* @ORM\Column(type="string", nullable=false)
*/
protected $title;

/**
* @ORM\Column(type="text", nullable=true)
*/
protected $description;

/**
* @ORM\Column(type="datetime", nullable=false)
*/
protected $start_date;

/**
* @ORM\Column(type="datetime", nullable=false)
*/
protected $end_date;

/**
* @ORM\Column(type="integer", nullable=true, options={"unsigned" = true})
*/
protected $customer_contact_id;

/**
* @ORM\Column(name="gender", type="string", columnDefinition="enum('male', 'female', 'diverse')")
*/
protected $gender;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $firstname;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $lastname;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $email;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $phone_no;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $mobile_no;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $department;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $street;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $street_no;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $zip;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $city;

/**
* @ORM\Column(type="integer", nullable=true, options={"unsigned" = true})
*/
protected $country_id;

/**
* @ORM\Column(type="text", nullable=true)
*/
protected $report;

/**
* @ORM\Column(type="boolean", nullable=false)
*/
protected $first_reminder_sent;

/**
* @ORM\Column(type="boolean", nullable=false)
*/
protected $second_reminder_sent;

/**
* @ORM\Column(type="boolean", nullable=false)
*/
protected $report_done;

/**
* @ORM\Column(type="boolean", nullable=false)
*/
protected $report_reminder_sent;

/**
* @ORM\Column(type="datetime", nullable=false)
*/
protected $creation_date;


/**
* EntCustomerMeeting constructor.
* @param ObjectManager $em
* @param EntCustomer $entCustomer
* @param EntUser $entCreationUser
* @param EntUser $entOwnerUser
* @param EntMeetingType $entMeetingType
* @param $isOptionMeeting
* @param $title
* @param $startDate
* @param $endDate
* @throws \Exception
*/
public function __construct(ObjectManager $em, EntCustomer $entCustomer, EntUser $entCreationUser, EntUser $entOwnerUser,
EntMeetingType $entMeetingType, $isOptionMeeting, $title, $startDate, $endDate)
{
if (is_null($entCustomer->getId())) {
throw new Exception('no id found');
}

if (is_null($entCreationUser->getId())) {
throw new Exception('no id found');
}

if (is_null($entOwnerUser->getId())) {
throw new Exception('no id found');
}

$meetingTypesById = EntMeetingType::getMeetingTypesById($em);
if (is_null($entMeetingType->getId()) || !array_key_exists($entMeetingType->getId(), $meetingTypesById)) {
throw new Exception('no id found');
}

$this->customer_id = $entCustomer->getId();
$this->creation_user_id = $entCreationUser->getId();
$this->owner_user_id = $entOwnerUser->getId();
$this->meeting_type_id = $entMeetingType->getId();
$this->is_option_meeting = $isOptionMeeting;
$this->title = $title;
$this->setStartDate($startDate);
$this->setEndDate($endDate);
$this->first_reminder_sent = false;
$this->second_reminder_sent = false;
$this->report_done = false;
$this->report_reminder_sent = false;
$this->creation_date = new \DateTime();
}

/**
* @return mixed
*/
public function getId()
{
return $this->id;
}

/**
* @return mixed
*/
public function getCustomerId()
{
return $this->customer_id;
}

/**
* @return mixed
*/
public function getCreationUserId()
{
return $this->creation_user_id;
}

/**
* @return mixed
*/
public function getOwnerUserId()
{
return $this->owner_user_id;
}

/**
* @return mixed
*/
public function getMeetingTypeId()
{
return $this->meeting_type_id;
}

/**
* @return mixed
*/
public function getIsOptionMeeting()
{
return $this->is_option_meeting;
}

/**
* @return mixed
*/
public function getTitle()
{
return $this->title;
}

/**
* @return mixed
*/
public function getDescription()
{
return $this->description;
}

/**
* @return mixed
*/
public function getStartDate()
{
return $this->start_date;
}

/**
* @return mixed
*/
public function getEndDate()
{
return $this->end_date;
}

/**
* @return mixed
*/
public function getCustomerContactId()
{
return $this->customer_contact_id;
}

/**
* @return mixed
*/
public function getGender()
{
return $this->gender;
}

/**
* @return mixed
*/
public function getFirstname()
{
return $this->firstname;
}

/**
* @return mixed
*/
public function getLastname()
{
return $this->lastname;
}

/**
* @return mixed
*/
public function getEmail()
{
return $this->email;
}

/**
* @return mixed
*/
public function getPhoneNo()
{
return $this->phone_no;
}

/**
* @return mixed
*/
public function getMobileNo()
{
return $this->mobile_no;
}

/**
* @return mixed
*/
public function getDepartment()
{
return $this->department;
}

/**
* @return mixed
*/
public function getStreet()
{
return $this->street;
}

/**
* @return mixed
*/
public function getStreetNo()
{
return $this->street_no;
}

/**
* @return mixed
*/
public function getZip()
{
return $this->zip;
}

/**
* @return mixed
*/
public function getCity()
{
return $this->city;
}

/**
* @return mixed
*/
public function getCountryId()
{
return $this->country_id;
}

/**
* @return mixed
*/
public function getReport()
{
return $this->report;
}

/**
* @return mixed
*/
public function getFirstReminderSent()
{
return $this->first_reminder_sent;
}

/**
* @return mixed
*/
public function getSecondReminderSent()
{
return $this->second_reminder_sent;
}

/**
* @return mixed
*/
public function getReportDone()
{
return $this->report_done;
}

/**
* @return mixed
*/
public function getReportReminderSent()
{
return $this->report_reminder_sent;
}

/**
* @return \DateTime
*/
public function getCreationDate(): \DateTime
{
return $this->creation_date;
}

/**
* @param mixed $owner_user_id
*/
public function setOwnerUserId($owner_user_id): void
{
$this->owner_user_id = $owner_user_id;
}

/**
* @param mixed $gender
*/
public function setGender($gender): void
{
if (!is_null($gender) && !Utils::isValidGender($gender)) {
throw new Exception('invalid gender');
}
$this->gender = $gender;
}

/**
* @param mixed $meeting_type_id
*/
public function setMeetingTypeId($meeting_type_id): void
{
$this->meeting_type_id = $meeting_type_id;
}

/**
* @param mixed $is_option_meeting
*/
public function setIsOptionMeeting($is_option_meeting): void
{
$this->is_option_meeting = $is_option_meeting;
}

/**
* @param mixed $title
*/
public function setTitle($title): void
{
$this->title = $title;
}

/**
* @param mixed $description
*/
public function setDescription($description): void
{
$this->description = $description;
}

/**
* @param mixed $start_date
*/
public function setStartDate($start_date): void
{
$this->start_date = \DateTime::createFromFormat('Y-m-d H:i:s', $start_date);
}

/**
* @param mixed $end_date
*/
public function setEndDate($end_date): void
{
$this->end_date = \DateTime::createFromFormat('Y-m-d H:i:s', $end_date);
}

/**
* @param ObjectManager $em
* @param $customer_contact_id
*/
public function setCustomerContactId(ObjectManager $em, $customer_contact_id): void
{
if ($customer_contact_id == 0) {
$this->customer_contact_id = $customer_contact_id;
} else {
/** @var EntCustomerContact $entCustomerContact */
$entCustomerContact = $em->getRepository('App:EntCustomerContact')->find($customer_contact_id);
// NOTE: Check if contact still exists
$this->customer_contact_id = !is_null($entCustomerContact) ? $customer_contact_id : null;
}
}

/**
* @param mixed $firstname
*/
public function setFirstname($firstname): void
{
$this->firstname = $firstname;
}

/**
* @param mixed $lastname
*/
public function setLastname($lastname): void
{
$this->lastname = $lastname;
}

/**
* @param mixed $email
*/
public function setEmail($email): void
{
$this->email = $email;
}

/**
* @param mixed $phone_no
*/
public function setPhoneNo($phone_no): void
{
$this->phone_no = $phone_no;
}

/**
* @param mixed $mobile_no
*/
public function setMobileNo($mobile_no): void
{
$this->mobile_no = $mobile_no;
}

/**
* @param mixed $department
*/
public function setDepartment($department): void
{
$this->department = $department;
}

/**
* @param mixed $street
*/
public function setStreet($street): void
{
$this->street = $street;
}

/**
* @param mixed $street_no
*/
public function setStreetNo($street_no): void
{
$this->street_no = $street_no;
}

/**
* @param mixed $zip
*/
public function setZip($zip): void
{
$this->zip = $zip;
}

/**
* @param mixed $city
*/
public function setCity($city): void
{
$this->city = $city;
}

/**
* @param mixed $country_id
*/
public function setCountryId($country_id): void
{
$this->country_id = $country_id;
}

/**
* @param $report
* @throws \Exception
*/
public function setReport($report): void
{
$now = new \DateTime();
if ($now < $this->getStartDate()) {
throw new Exception('meeting has not started yet');
}
$this->report = $report;
}

/**
* @param mixed $first_reminder_sent
*/
public function setFirstReminderSent($first_reminder_sent): void
{
$this->first_reminder_sent = $first_reminder_sent;
}

/**
* @param mixed $second_reminder_sent
*/
public function setSecondReminderSent($second_reminder_sent): void
{
$this->second_reminder_sent = $second_reminder_sent;
}

/**
* @param mixed $report_done
*/
public function setReportDone($report_done): void
{
$this->report_done = $report_done;
}

/**
* @param mixed $report_reminder_sent
*/
public function setReportReminderSent($report_reminder_sent): void
{
$this->report_reminder_sent = $report_reminder_sent;
}

/**
* Checks if meeting is editable or deletable
* @return bool
* @throws \Exception
*/
public function isEditDeletable()
{
$now = new \DateTime();
return $now < $this->getStartDate();
}

/**
* Sets client data
* @param EntityManagerInterface $em
* @param $clientData
*/
public function setClientData(EntityManagerInterface $em, $clientData)
{
$this->setOwnerUserId($clientData->owner_user_id);
$this->setMeetingTypeId($clientData->meeting_type_id);
$this->setIsOptionMeeting($clientData->is_option_meeting);
$this->setTitle($clientData->title);
$this->setDescription($clientData->description);
$this->setStartDate($clientData->start_date);
$this->setEndDate($clientData->end_date);
$this->setStreet($clientData->street);
$this->setStreetNo($clientData->street_no);
$this->setZip($clientData->zip);
$this->setCity($clientData->city);
$this->setCountryId($clientData->country_id);
$this->setCustomerContactId($em, $clientData->customer_contact_id);

if (is_null($this->customer_contact_id)) {
$this->setGender(null);
$this->setFirstname(null);
$this->setLastname(null);
$this->setEmail(null);
$this->setPhoneNo(null);
$this->setMobileNo(null);
$this->setDepartment(null);
} else {
$this->setGender($clientData->gender);
$this->setFirstname($clientData->firstname);
$this->setLastname($clientData->lastname);
$this->setEmail($clientData->email);
$this->setPhoneNo($clientData->phone_no);
$this->setMobileNo($clientData->mobile_no);
$this->setDepartment($clientData->department);
}
}

/**
* Client mapper
* @param EntityManagerInterface $em
* @param bool $fullMapping
* @return array
* @throws \Exception
*/
public function clientMapper(EntityManagerInterface $em, $fullMapping = false)
{
$now = new \DateTime();
return [
'id' => $this->id,
'customer_id' => (int)$this->customer_id,
'creation_user_id' => (int)$this->creation_user_id,
'owner_user_id' => (int)$this->owner_user_id,
'meeting_type_id' => (int)$this->meeting_type_id,
'is_option_meeting' => $this->is_option_meeting,
'title' => $this->title,
'description' => $this->description,
'start_date' => !is_null($this->start_date) ? $this->start_date->format('Y-m-d H:i:s'): null,
'end_date' => !is_null($this->end_date) ? $this->end_date->format('Y-m-d H:i:s'): null,
'customer_contact_id' => $this->customer_contact_id,
'gender' => $this->gender,
'firstname' => $this->firstname,
'lastname' => $this->lastname,
'email' => $this->email,
'phone_no' => $this->phone_no,
'mobile_no' => $this->mobile_no,
'department' => $this->department,
'street' => $this->street,
'street_no' => $this->street_no,
'zip' => $this->zip,
'city' => $this->city,
'country_id' => $this->country_id,
'report' => $this->report,
'first_reminder_sent' => $this->first_reminder_sent,
'second_reminder_sent' => $this->second_reminder_sent,
'report_done' => $this->report_done,
'report_reminder_sent' => $this->report_reminder_sent,
'creation_date' => !is_null($this->creation_date) ? $this->creation_date->format('Y-m-d H:i:s'): null,
'v_participants' => Utils::clientMap($em, $em->getRepository('App:EntCustomerMeetingParticipant')->findBy(['customer_meeting_id' => $this->id])),
'v_is_editable' => $now < $this->start_date,
];
}

}

+ 96
- 0
httpdocs/src/Entity/EntCustomerMeetingParticipant.php Прегледај датотеку

@@ -0,0 +1,96 @@
<?php

namespace App\Entity;


use App\Entity\IFace\IEntity;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\UniqueConstraint;
use Symfony\Component\Config\Definition\Exception\Exception;

/**
* @ORM\Entity
* @ORM\Table(name="customer_meeting_participant",indexes={@ORM\Index(name="search_participant_idx", columns={"customer_meeting_id", "participant_user_id"})},
* uniqueConstraints={@UniqueConstraint(name="unique_participant", columns={"customer_meeting_id", "participant_user_id"})})
*/
class EntCustomerMeetingParticipant implements IEntity
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
protected $id;

/**
* @ORM\Column(type="integer", nullable=false, options={"unsigned" = true})
*/
protected $customer_meeting_id;

/**
* @ORM\Column(type="integer", nullable=false, options={"unsigned" = true})
*/
protected $participant_user_id;


/**
* EntCustomerMeetingParticipant constructor.
* @param EntityManagerInterface $em
* @param EntCustomerMeeting $entCustomerMeeting
* @param EntUser $entParticipantUser
*/
public function __construct(EntityManagerInterface $em, EntCustomerMeeting $entCustomerMeeting, EntUser $entParticipantUser)
{
if (is_null($entCustomerMeeting->getId())) {
throw new Exception('no id found');
}

if (is_null($entParticipantUser->getId())) {
throw new Exception('no id found');
}

$this->customer_meeting_id = $entCustomerMeeting->getId();
$this->participant_user_id = $entParticipantUser->getId();
}

/**
* @return mixed
*/
public function getId()
{
return $this->id;
}

/**
* @return mixed
*/
public function getCustomerMeetingId()
{
return $this->customer_meeting_id;
}

/**
* @return mixed
*/
public function getParticipantUserId()
{
return $this->participant_user_id;
}

/**
* Client mapper
* @param EntityManagerInterface $em
* @param bool $fullMapping
* @return array
*/
public function clientMapper(EntityManagerInterface $em, $fullMapping = false)
{
return [
'id' => $this->id,
'customer_meeting_id' => $this->customer_meeting_id,
'participant_user_id' => $this->participant_user_id,
];
}

}

+ 440
- 0
httpdocs/src/Entity/EntCustomerNote.php Прегледај датотеку

@@ -0,0 +1,440 @@
<?php

namespace App\Entity;


use App\Entity\IFace\IEntity;
use App\Utils\Utils;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Config\Definition\Exception\Exception;

/**
* @ORM\Entity
* @ORM\Table(name="customer_note")
*/
class EntCustomerNote implements IEntity
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
protected $id;

/**
* @ORM\Column(type="integer", nullable=false, options={"unsigned" = true})
*/
protected $customer_id;

/**
* @ORM\Column(type="integer", nullable=true, options={"unsigned" = true})
*/
protected $customer_contact_id;

/**
* @ORM\Column(name="gender", type="string", columnDefinition="enum('male', 'female', 'diverse')")
*/
protected $gender;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $firstname;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $lastname;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $email;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $phone_no;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $mobile_no;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $fax_no;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $department;

/**
* @ORM\Column(type="string", nullable=false)
*/
protected $title;

/**
* @ORM\Column(type="text", nullable=true)
*/
protected $comment;

/**
* @ORM\Column(type="date", nullable=false)
*/
protected $note_date;

/**
* @ORM\Column(type="integer", nullable=false, options={"unsigned" = true})
*/
protected $creation_user_id;

/**
* @ORM\Column(type="string", nullable=true)
*/
protected $creation_user_firstname;

/**
* @ORM\Column(type="string", nullable=false)
*/
protected $creation_user_lastname;

/**
* @ORM\Column(type="datetime", nullable=false)
*/
protected $creation_date;


/**
* EntCustomerNote constructor.
* @param ObjectManager $em
* @param EntCustomer $entCustomer
* @param EntUser $entUser
* @param $title
* @throws \Exception
*/
public function __construct(ObjectManager $em, EntCustomer $entCustomer, EntUser $entUser, $title)
{
if (is_null($entCustomer->getId())) {
throw new Exception('no id found');
}

if (is_null($entUser->getId())) {
throw new Exception('no id found');
}

$this->customer_id = $entCustomer->getId();
$this->creation_user_id = $entUser->getId();
$this->creation_user_firstname = $entUser->getFirstname();
$this->creation_user_lastname = $entUser->getLastname();
$this->title = $title;
$this->note_date = new \DateTime();
$this->creation_date = new \DateTime();
}

/**
* @return mixed
*/
public function getId()
{
return $this->id;
}

/**
* @return mixed
*/
public function getCustomerId()
{
return $this->customer_id;
}

/**
* @return mixed
*/
public function getCreationUserId()
{
return $this->creation_user_id;
}

/**
* @return mixed
*/
public function getGender()
{
return $this->gender;
}

/**
* @return mixed
*/
public function getFirstname()
{
return $this->firstname;
}

/**
* @return mixed
*/
public function getLastname()
{
return $this->lastname;
}

/**
* @return mixed
*/
public function getEmail()
{
return $this->email;
}

/**
* @return mixed
*/
public function getPhoneNo()
{
return $this->phone_no;
}

/**
* @return mixed
*/
public function getMobileNo()
{
return $this->mobile_no;
}

/**
* @return mixed
*/
public function getFaxNo()
{
return $this->fax_no;
}

/**
* @return mixed
*/
public function getDepartment()
{
return $this->department;
}

/**
* @return mixed
*/
public function getTitle()
{
return $this->title;
}

/**
* @return mixed
*/
public function getComment()
{
return $this->comment;
}

/**
* @return mixed
*/
public function getNoteDate()
{
return $this->note_date;
}

/**
* @return mixed
*/
public function getCreationUserFirstname()
{
return $this->creation_user_firstname;
}

/**
* @return mixed
*/
public function getCreationUserLastname()
{
return $this->creation_user_lastname;
}

/**
* @return mixed
*/
public function getCreationDate()
{
return $this->creation_date;
}

/**
* @return mixed
*/
public function getCustomerContactId()
{
return $this->customer_contact_id;
}

/**
* @param ObjectManager $em
* @param $customer_contact_id
*/
public function setCustomerContactId(ObjectManager $em, $customer_contact_id): void
{
if ($customer_contact_id == 0) {
$this->customer_contact_id = $customer_contact_id;
} else {
/** @var EntCustomerContact $entCustomerContact */
$entCustomerContact = $em->getRepository('App:EntCustomerContact')->find($customer_contact_id);
// NOTE: Check if contact still exists
$this->customer_contact_id = !is_null($entCustomerContact) ? $customer_contact_id : null;
}
}

/**
* @param mixed $gender
*/
public function setGender($gender): void
{
if (!is_null($gender) && !Utils::isValidGender($gender)) {
throw new Exception('invalid gender');
}
$this->gender = $gender;
}

/**
* @param mixed $firstname
*/
public function setFirstname($firstname): void
{
$this->firstname = $firstname;
}

/**
* @param mixed $lastname
*/
public function setLastname($lastname): void
{
$this->lastname = $lastname;
}

/**
* @param mixed $email
*/
public function setEmail($email): void
{
$this->email = $email;
}

/**
* @param mixed $phone_no
*/
public function setPhoneNo($phone_no): void
{
$this->phone_no = $phone_no;
}

/**
* @param mixed $mobile_no
*/
public function setMobileNo($mobile_no): void
{
$this->mobile_no = $mobile_no;
}

/**
* @param mixed $fax_no
*/
public function setFaxNo($fax_no): void
{
$this->fax_no = $fax_no;
}

/**
* @param mixed $department
*/
public function setDepartment($department): void
{
$this->department = $department;
}

/**
* @param mixed $title
*/
public function setTitle($title): void
{
$this->title = $title;
}

/**
* @param mixed $comment
*/
public function setComment($comment): void
{
$this->comment = $comment;
}

/**
* @param mixed $note_date
*/
public function setNoteDate($note_date): void
{
$this->note_date = \DateTime::createFromFormat('Y-m-d', $note_date);
}

/**
* Sets client data
* @param EntityManagerInterface $em
* @param $clientData
*/
public function setClientData(EntityManagerInterface $em, $clientData)
{
$this->setCustomerContactId($em, $clientData->customer_contact_id);
$this->setGender($clientData->gender);
$this->setFirstname($clientData->firstname);
$this->setLastname($clientData->lastname);
$this->setEmail($clientData->email);
$this->setPhoneNo($clientData->phone_no);
$this->setMobileNo($clientData->mobile_no);
$this->setFaxNo($clientData->fax_no);
$this->setDepartment($clientData->department);
$this->setTitle($clientData->title);
$this->setComment($clientData->comment);
$this->setNoteDate($clientData->note_date);
}

/**
* Client mapper
* @param EntityManagerInterface $em
* @param bool $fullMapping
* @return array
*/
public function clientMapper(EntityManagerInterface $em, $fullMapping = false)
{
return [
'id' => $this->id,
'customer_id' => $this->customer_id,
'customer_contact_id' => $this->customer_contact_id,
'gender' => $this->gender,
'firstname' => $this->firstname,
'lastname' => $this->lastname,
'email' => $this->email,
'phone_no' => $this->phone_no,
'mobile_no' => $this->mobile_no,
'fax_no' => $this->fax_no,
'department' => $this->department,
'title' => $this->title,
'comment' => $this->comment,
'note_date' => !is_null($this->note_date) ? $this->note_date->format('Y-m-d'): null,
'creation_date' => !is_null($this->creation_date) ? $this->creation_date->format('Y-m-d'): null,
'creation_user_id' => $this->getCreationUserId(),
'creation_user_firstname' => $this->getCreationUserFirstname(),
'creation_user_lastname' => $this->getCreationUserLastname(),
];
}

}

+ 338
- 0
httpdocs/src/Entity/EntInternalMeeting.php Прегледај датотеку

@@ -0,0 +1,338 @@
<?php

namespace App\Entity;


use App\Entity\IFace\IEntity;
use App\Utils\Utils;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Config\Definition\Exception\Exception;

/**
* @ORM\Entity
* @ORM\Table(name="internal_meeting", indexes={@ORM\Index(name="search_owner_idx", columns={"owner_user_id"})})
*/
class EntInternalMeeting implements IEntity
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
protected $id;

/**
* @ORM\Column(type="integer", nullable=false, options={"unsigned" = true})
*/
protected $creation_user_id;

/**
* @ORM\Column(type="integer", nullable=false, options={"unsigned" = true})
*/
protected $owner_user_id;

/**
* @ORM\Column(type="string", nullable=false)
*/
protected $title;

/**
* @ORM\Column(type="text", nullable=true)
*/
protected $description;

/**
* @ORM\Column(type="datetime", nullable=false)
*/
protected $start_date;

/**
* @ORM\Column(type="datetime", nullable=false)
*/
protected $end_date;

/**
* @ORM\Column(type="text", nullable=true)
*/
protected $report;

/**
* @ORM\Column(type="boolean", nullable=false)
*/
protected $first_reminder_sent;

/**
* @ORM\Column(type="boolean", nullable=false)
*/
protected $second_reminder_sent;

/**
* @ORM\Column(type="boolean", nullable=false)
*/
protected $report_reminder_sent;

/**
* @ORM\Column(type="datetime", nullable=false)
*/
protected $creation_date;


/**
* EntInternalMeeting constructor.
* @param ObjectManager $em
* @param EntUser $entCreationUser
* @param EntUser $entOwnerUser
* @param $title
* @param $startDate
* @param $endDate
* @throws \Exception
*/
public function __construct(ObjectManager $em, EntUser $entCreationUser, EntUser $entOwnerUser, $title, $startDate, $endDate)
{
if (is_null($entCreationUser->getId())) {
throw new Exception('no id found');
}

if (is_null($entOwnerUser->getId())) {
throw new Exception('no id found');
}

$this->creation_user_id = $entCreationUser->getId();
$this->owner_user_id = $entOwnerUser->getId();
$this->title = $title;
$this->setStartDate($startDate);
$this->setEndDate($endDate);
$this->first_reminder_sent = false;
$this->second_reminder_sent = false;
$this->report_reminder_sent = false;
$this->creation_date = new \DateTime();
}

/**
* @return mixed
*/
public function getId()
{
return $this->id;
}

/**
* @return mixed
*/
public function getCreationUserId()
{
return $this->creation_user_id;
}

/**
* @return mixed
*/
public function getOwnerUserId()
{
return $this->owner_user_id;
}

/**
* @return mixed
*/
public function getTitle()
{
return $this->title;
}

/**
* @return mixed
*/
public function getDescription()
{
return $this->description;
}

/**
* @return mixed
*/
public function getStartDate()
{
return $this->start_date;
}

/**
* @return mixed
*/
public function getEndDate()
{
return $this->end_date;
}

/**
* @return mixed
*/
public function getReport()
{
return $this->report;
}

/**
* @return mixed
*/
public function getFirstReminderSent()
{
return $this->first_reminder_sent;
}

/**
* @return mixed
*/
public function getSecondReminderSent()
{
return $this->second_reminder_sent;
}

/**
* @return mixed
*/
public function getReportReminderSent()
{
return $this->report_reminder_sent;
}

/**
* @return \DateTime
*/
public function getCreationDate(): \DateTime
{
return $this->creation_date;
}

/**
* @param mixed $owner_user_id
*/
public function setOwnerUserId($owner_user_id): void
{
$this->owner_user_id = $owner_user_id;
}

/**
* @param mixed $title
*/
public function setTitle($title): void
{
$this->title = $title;
}

/**
* @param mixed $description
*/
public function setDescription($description): void
{
$this->description = $description;
}

/**
* @param mixed $start_date
*/
public function setStartDate($start_date): void
{
$this->start_date = \DateTime::createFromFormat('Y-m-d H:i:s', $start_date);
}

/**
* @param mixed $end_date
*/
public function setEndDate($end_date): void
{
$this->end_date = \DateTime::createFromFormat('Y-m-d H:i:s', $end_date);
}

/**
* @param $report
* @throws \Exception
*/
public function setReport($report): void
{
$now = new \DateTime();
if ($now < $this->getStartDate()) {
throw new Exception('meeting has not started yet');
}
$this->report = $report;
}

/**
* @param mixed $first_reminder_sent
*/
public function setFirstReminderSent($first_reminder_sent): void
{
$this->first_reminder_sent = $first_reminder_sent;
}

/**
* @param mixed $second_reminder_sent
*/
public function setSecondReminderSent($second_reminder_sent): void
{
$this->second_reminder_sent = $second_reminder_sent;
}

/**
* @param mixed $report_reminder_sent
*/
public function setReportReminderSent($report_reminder_sent): void
{
$this->report_reminder_sent = $report_reminder_sent;
}

/**
* Checks if meeting is editable or deletable
* @return bool
* @throws \Exception
*/
public function isEditDeletable()
{
$now = new \DateTime();
return $now < $this->getStartDate();
}

/**
* Sets client data
* @param EntityManagerInterface $em
* @param $clientData
*/
public function setClientData(EntityManagerInterface $em, $clientData)
{
$this->setOwnerUserId($clientData->owner_user_id);
$this->setTitle($clientData->title);
$this->setDescription($clientData->description);
$this->setStartDate($clientData->start_date);
$this->setEndDate($clientData->end_date);
}

/**
* Client mapper
* @param EntityManagerInterface $em
* @param bool $fullMapping
* @return array
* @throws \Exception
*/
public function clientMapper(EntityManagerInterface $em, $fullMapping = false)
{
$now = new \DateTime();
return [
'id' => $this->id,
'creation_user_id' => (int)$this->creation_user_id,
'owner_user_id' => (int)$this->owner_user_id,
'title' => $this->title,
'description' => $this->description,
'start_date' => !is_null($this->start_date) ? $this->start_date->format('Y-m-d H:i:s'): null,
'end_date' => !is_null($this->end_date) ? $this->end_date->format('Y-m-d H:i:s'): null,
'report' => $this->report,
'first_reminder_sent' => $this->first_reminder_sent,
'second_reminder_sent' => $this->second_reminder_sent,
'report_reminder_sent' => $this->report_reminder_sent,
'creation_date' => !is_null($this->creation_date) ? $this->creation_date->format('Y-m-d H:i:s'): null,
'v_participants' => Utils::clientMap($em, $em->getRepository('App:EntInternalMeetingParticipant')->findBy(['internal_meeting_id' => $this->id])),
'v_is_editable' => $now < $this->start_date,
];
}

}

+ 96
- 0
httpdocs/src/Entity/EntInternalMeetingParticipant.php Прегледај датотеку

@@ -0,0 +1,96 @@
<?php

namespace App\Entity;


use App\Entity\IFace\IEntity;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\UniqueConstraint;
use Symfony\Component\Config\Definition\Exception\Exception;

/**
* @ORM\Entity
* @ORM\Table(name="internal_meeting_participant",indexes={@ORM\Index(name="search_participant_idx", columns={"internal_meeting_id", "participant_user_id"})},
* uniqueConstraints={@UniqueConstraint(name="unique_participant", columns={"internal_meeting_id", "participant_user_id"})})
*/
class EntInternalMeetingParticipant implements IEntity
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
protected $id;

/**
* @ORM\Column(type="integer", nullable=false, options={"unsigned" = true})
*/
protected $internal_meeting_id;

/**
* @ORM\Column(type="integer", nullable=false, options={"unsigned" = true})
*/
protected $participant_user_id;


/**
* EntInternalMeetingParticipant constructor.
* @param EntityManagerInterface $em
* @param EntInternalMeeting $entInternalMeeting
* @param EntUser $entParticipantUser
*/
public function __construct(EntityManagerInterface $em, EntInternalMeeting $entInternalMeeting, EntUser $entParticipantUser)
{
if (is_null($entInternalMeeting->getId())) {
throw new Exception('no id found');
}

if (is_null($entParticipantUser->getId())) {
throw new Exception('no id found');
}

$this->internal_meeting_id = $entInternalMeeting->getId();
$this->participant_user_id = $entParticipantUser->getId();
}

/**
* @return mixed
*/
public function getId()
{
return $this->id;
}

/**
* @return mixed
*/
public function getInternalMeetingId()
{
return $this->internal_meeting_id;
}

/**
* @return mixed
*/
public function getParticipantUserId()
{
return $this->participant_user_id;
}

/**
* Client mapper
* @param EntityManagerInterface $em
* @param bool $fullMapping
* @return array
*/
public function clientMapper(EntityManagerInterface $em, $fullMapping = false)
{
return [
'id' => $this->id,
'internal_meeting_id' => $this->internal_meeting_id,
'participant_user_id' => $this->participant_user_id,
];
}

}

+ 93
- 0
httpdocs/src/Entity/EntMeetingType.php Прегледај датотеку

@@ -0,0 +1,93 @@
<?php

namespace App\Entity;
use App\Entity\IFace\IEntity;
use App\Utils\Utils;

use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity
* @ORM\Table(name="meeting_type")
*/
class EntMeetingType implements IEntity
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
protected $id;

/**
* @ORM\Column(type="string", nullable=false, unique=true)
*/
protected $type;

/**
* @ORM\Column(type="string", nullable=false, unique=true)
*/
protected $name;

private static $cacheMeetingTypesById;

/**
* Gets static room cycle types
* @param EntityManagerInterface $em
* @return array
*/
public static function getMeetingTypesById(EntityManagerInterface $em)
{
if (is_null(self::$cacheMeetingTypesById)) {
self::$cacheMeetingTypesById = Utils::getSortedObjectsById($em->getRepository('App:EntMeetingType')->findAll());
}
return self::$cacheMeetingTypesById;
}

public function __construct($type, $name)
{
$this->type = $type;
$this->name = $name;
}

/**
* @return mixed
*/
public function getId()
{
return $this->id;
}

/**
* @return mixed
*/
public function getType()
{
return $this->type;
}

/**
* @return mixed
*/
public function getName()
{
return $this->name;
}

/**
* Clientmapper
* @param EntityManagerInterface $em
* @param bool $fullMapping
* @return array
*/
public function clientMapper(EntityManagerInterface $em, $fullMapping = false) {
return [
'id' => $this->id,
'type' => $this->type,
'name' => $this->name,
];
}


}

+ 349
- 0
httpdocs/src/Entity/EntUser.php Прегледај датотеку

@@ -0,0 +1,349 @@
<?php

namespace App\Entity;


use App\Entity\IFace\IEntity;
use App\Utils\Utils;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\Security\Core\User\UserInterface;

/**
* @ORM\Entity
* @ORM\Table(name="user")
*/
#[ORM\Entity()]
class EntUser implements IEntity, UserInterface
{
// User id of system
const SYSTEM_USER_ID = 0;

// Costs of password encryption
const CRYPT_COST = 12;

#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
protected int $id;

#[ORM\Column(Types::STRING, unique: true)]
protected string $email;

#[ORM\Column(Types::INTEGER)]
protected int $user_type_id;

/**
* @ORM\Column(type="string", length=50, nullable=false)
*/
protected string $firstname;

/**
* @ORM\Column(type="string", length=50, nullable=false)
*/
protected string $lastname;

/**
* @ORM\Column(type="string", length=60, nullable=false)
*/
protected string $password;

/**
* @ORM\Column(type="boolean", nullable=false)
*/
protected bool $active;

/**
* @ORM\Column(type="boolean", nullable=false)
*/
protected bool $visible;

/**
* @ORM\Column(type="datetime", nullable=false)
*/
protected $creation_date;

/**
* EntUser constructor.
* @param EntityManagerInterface $em
* @param $email
* @param $firstName
* @param $lastName
* @param $password
* @param $userTypeId
* @param $userTypeIdCreatingUser
* @param EntUser|null $editingUser
* @throws \Exception
*/
public function __construct(EntityManagerInterface $em, $email, $firstName, $lastName, $password, $userTypeId, $userTypeIdCreatingUser, EntUser $editingUser = null)
{
// Check email
if (!Utils::validateEmail($em, $email)) {
throw new Exception('invalid or existent email given: '.$email);
}

$this->setUserTypeId($userTypeIdCreatingUser, $userTypeId, $editingUser);

// Check password length
if (!Utils::isValidPasswordLength($password)) {
throw new Exception('invalid password length');
}

$this->email = $email;
$this->user_type_id = $userTypeId;
$this->firstname = $firstName;
$this->lastname = $lastName;
$this->password = password_hash($password, PASSWORD_BCRYPT, ["cost" => self::CRYPT_COST]);
$this->active = true;
$this->visible = true;
$this->creation_date = new \DateTime();
}

/**
* @return mixed
*/
public function getId()
{
return $this->id;
}

/**
* @return mixed
*/
public function getEmail()
{
return $this->email;
}

/**
* @return mixed
*/
public function getUserTypeId()
{
return $this->user_type_id;
}

/**
* @return mixed
*/
public function getFirstname()
{
return $this->firstname;
}

/**
* @return mixed
*/
public function getLastname()
{
return $this->lastname;
}

/**
* @return mixed
*/
public function getPassword()
{
return $this->password;
}

/**
* @return bool
*/
public function isVisible(): bool
{
return $this->visible;
}

/**
* @return bool
*/
public function isActive(): bool
{
return $this->active;
}

/**
* @return mixed
*/
public function getCreationDate()
{
return $this->creation_date;
}

/**
* Returns username as part of UserInterface needed in Symfony
* @return string
*/
public function getUserIdentifier(): string
{
return $this->email;
}

/**
* Returns roles as part of UserInterface needed in Symfony
* @return string[]
*/
public function getRoles(): array
{
return EntUserType::getUserRoles($this->user_type_id);
}

/**
* Returns if user has admin rights
* @return bool
*/
public function isAdmin()
{
return in_array(EntUserType::USER_ROLE_ADMIN, $this->getRoles());
}

/**
* Erases credentials as part of UserInterface needed in Symfony
*/
public function eraseCredentials() {}

/**
* Checks password as part of UserInterface needed in Symfony
* @param $password
* @return bool
*/
public function checkPassword($password)
{
return $this->active && password_verify($password, $this->password);
}

/**
* Returns salt as part of UserInterface needed in Symfony
* @return null|string|void
*/
public function getSalt() {}

/**
* @param $userTypeIdCreatingUser
* @param $userTypeId
* @param EntUser|null $editingUser
*/
public function setUserTypeId($userTypeIdCreatingUser, $userTypeId, EntUser $editingUser = null): void
{
// Check user type id
if (!EntUserType::isValidUserTypeId($userTypeId)) {
throw new Exception('invalid user type id');
}

// Compare creating user type with this user type
$isEditingUser = is_null($editingUser) ? false : $editingUser->getId() == $this->id;
if (!EntUserType::isHigherUserType($userTypeIdCreatingUser, $userTypeId) && !$isEditingUser) {
throw new Exception('creating user has not enough rights to create this user type');
}
$this->user_type_id = $userTypeId;

}

/**
* Sets email with check on validity and existence
* @param ObjectManager $em
* @param $email
*/
public function setEmail(ObjectManager $em, $email)
{
if ($email != $this->email) {
if (!Utils::validateEmail($em, $email)) {
throw new Exception('email is invalid or already exists: '.$email);
}
$this->email = $email;
}
}

/**
* @param bool|string $password
*/
public function setPassword($password): void
{
$this->password = $password;
}

/**
* @param bool $active
*/
public function setActive(bool $active): void
{
$this->active = $active;
}

/**
* @param mixed $lastname
*/
public function setLastname($lastname): void
{
$this->lastname = $lastname;
}

/**
* @param string $firstname
* @return EntUser
*/
public function setFirstname(string $firstname): self
{
$this->firstname = $firstname;

return $this;
}

/**
* @param bool $visible
*/
public function setVisible(bool $visible): void
{
$this->visible = $visible;
}

/**
* Returns whether this user is on higher user role level than given user to compare with
* @param EntUser $compareUser
* @return bool
*/
public function isHigherUser(EntUser $compareUser)
{
return EntUserType::isHigherUserType($this->user_type_id, $compareUser->getUserTypeId());
}


/**
* Sets client data
* @param EntityManagerInterface $em
* @param $clientData
*/
public function setClientData(EntityManagerInterface $em, $clientData)
{
$this->setFirstname($clientData->firstname);
$this->setLastname($clientData->lastname);
$this->setEmail($em, $clientData->email);
}

/**
* Client mapper
* @param EntityManagerInterface $em
* @param bool $fullMapping
* @return array
*/
public function clientMapper(EntityManagerInterface $em, $fullMapping = false)
{
/** @var EntUserType $userType */
$userType = $em->getRepository('App:EntUserType')->find($this->user_type_id);

return [
'id' => $this->id,
'email' => $this->email,
'firstname' => $this->firstname,
'lastname' => $this->lastname,
'active' => $this->active,
'visible' => $this->visible,
'v_translated_role' => EntUserType::getTranslatedRole($this->user_type_id),
'v_user_type' => $userType->clientMapper($em, $fullMapping),
];
}

}

+ 161
- 0
httpdocs/src/Entity/EntUserType.php Прегледај датотеку

@@ -0,0 +1,161 @@
<?php

namespace App\Entity;
use App\Entity\IFace\IEntity;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Config\Definition\Exception\Exception;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity
* @ORM\Table(name="user_type")
*/
class EntUserType implements IEntity
{
// User type for system
const USER_TYPE_ID_SYSTEM = 0;

// User types for real users
const USER_TYPE_ID_ADMIN = 1;
const USER_TYPE_ID_SALES = 2;
const USER_TYPE_ID_TECHNIQUE = 3;
const USER_TYPE_ID_PRODUCTION = 4;
const USER_TYPE_ID_ACCOUNTING = 5;
const USER_TYPE_ID_SERVICE = 6;

const USER_ROLE_ADMIN = 'ROLE_ADMIN';
const USER_ROLE_USER = 'ROLE_USER';
const USER_ROLE_SALES = 'ROLE_SALES';
const USER_ROLE_TECHNIQUE = 'ROLE_TECHNIQUE';
const USER_ROLE_PRODUCTION = 'ROLE_PRODUCTION';
const USER_ROLE_ACCOUNTING = 'ROLE_ACCOUNTING';
const USER_ROLE_SERVICE = 'ROLE_SERVICE';

// Maps user type to set of roles
private static $userRoles = array(
self::USER_TYPE_ID_ADMIN => array(self::USER_ROLE_ADMIN, self::USER_ROLE_USER, self::USER_ROLE_SALES, self::USER_ROLE_TECHNIQUE,
self::USER_ROLE_PRODUCTION, self::USER_ROLE_ACCOUNTING, self::USER_ROLE_SERVICE),
self::USER_TYPE_ID_SALES => array(self::USER_ROLE_USER, self::USER_ROLE_SALES),
self::USER_TYPE_ID_TECHNIQUE => array(self::USER_ROLE_USER, self::USER_ROLE_TECHNIQUE, self::USER_ROLE_PRODUCTION, self::USER_ROLE_SERVICE),
self::USER_TYPE_ID_PRODUCTION => array(self::USER_ROLE_USER, self::USER_ROLE_PRODUCTION, self::USER_ROLE_SERVICE),
self::USER_TYPE_ID_ACCOUNTING => array(self::USER_ROLE_USER, self::USER_ROLE_ACCOUNTING),
self::USER_TYPE_ID_SERVICE => array(self::USER_ROLE_USER, self::USER_ROLE_SERVICE, self::USER_ROLE_PRODUCTION),
);

// Role translations for client
private static $translatedRoles = array(
self::USER_TYPE_ID_ADMIN => 'Admin',
self::USER_TYPE_ID_SALES => 'Vertrieb',
self::USER_TYPE_ID_TECHNIQUE => 'Technik',
self::USER_TYPE_ID_PRODUCTION => 'Produktion',
self::USER_TYPE_ID_ACCOUNTING => 'Buchhaltung',
self::USER_TYPE_ID_SERVICE => 'Service'
);

/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
protected $id;

/**
* @ORM\Column(name="type", type="string", nullable=false, unique=true)
*/
protected $type;


public function __construct($type)
{
$this->type = $type;
}

/**
* @return mixed
*/
public function getId()
{
return $this->id;
}

/**
* @return mixed
*/
public function getType()
{
return $this->type;
}

/**
* Returns all available user roles
* @return array
*/
public static function getAllUserRoles()
{
return self::$userRoles;
}

/**
* Returns user roles
* @param $userTypeId
* @return string[]
*/
public static function getUserRoles($userTypeId)
{
if (!array_key_exists($userTypeId, self::$userRoles)) {
throw new Exception("unknown user type");
}
return self::$userRoles[$userTypeId];
}

public static function getTranslatedRole($userTypeId)
{
if (!array_key_exists($userTypeId, self::$translatedRoles)) {
throw new Exception('invalid user type id given');
}
return self::$translatedRoles[$userTypeId];
}

/**
* Returns role config
* @return array
*/
public static function getRolesConfig()
{
$rolesConfig = array();
foreach (self::$userRoles as $userTypeId => $ur) {
$rolesConfig[] = array(
'user_type_id' => $userTypeId,
'roles' => $ur,
'translation' => self::$translatedRoles[$userTypeId]
);
}
return $rolesConfig;
}

public static function isValidUserTypeId($userTypeId)
{
return array_key_exists($userTypeId, self::$userRoles);
}

/**
* Check if a given user type is higher than given compare id
* @param $higherUserTypeId
* @return bool
*/
public static function isHigherUserType($higherUserTypeId, $lowerUserTypeId)
{
return $higherUserTypeId < $lowerUserTypeId;
}

public function clientMapper(EntityManagerInterface $em, $fullMapping = false) {
return [
'user_type_id' => $this->getId(),
'type' => $this->type,
'v_roles' => self::getUserRoles($this->getId())
];
}


}

+ 21
- 0
httpdocs/src/Entity/IFace/IEntity.php Прегледај датотеку

@@ -0,0 +1,21 @@
<?php
/**
* Created by PhpStorm.
* User: danielknudsen
* Date: 03.04.18
* Time: 09:18
*/
namespace App\Entity\IFace;
use Doctrine\ORM\EntityManagerInterface;

/**
* Interface for regular entity classes
*
* Interface IEntity
* @package App\Entity\iface
*/
interface IEntity
{
public function getId();
public function clientMapper(EntityManagerInterface $em, $fullMapping = false);
}

+ 106
- 0
httpdocs/src/Entity/convertAnnotations.php Прегледај датотеку

@@ -0,0 +1,106 @@
<?php
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\AnnotationRegistry;
use Doctrine\Common\Annotations\DocParser;
use Doctrine\Common\Annotations\IndexedReader;
use Doctrine\Common\Annotations\PhpParser;
use Doctrine\ORM\Mapping\Column;
use Doctrine\DBAL\Types\Types;

// Lade die Klassen, die du konvertieren möchtest
$entityDir = './';

// Initialisiere den AnnotationReader
$annotationReader = new AnnotationReader();

// Erzeuge den DocParser mit der gewünschten PHP-Parser-Klasse
$phpParser = new PhpParser();
$docParser = new DocParser($phpParser);
$docParser->setIgnoreNotImportedAnnotations(true);
$docParser->setImports([
'orm' => 'Doctrine\ORM\Mapping',
]);

// Initialisiere den IndexedReader mit dem AnnotationReader und DocParser
$indexedReader = new IndexedReader($annotationReader, $docParser);

// Lade alle Entity-Klassen im Entity-Verzeichnis
$directoryIterator = new \RecursiveDirectoryIterator($entityDir);
$iterator = new \RecursiveIteratorIterator($directoryIterator);
$regexIterator = new \RegexIterator($iterator, '/^.+\.php$/i', \RecursiveRegexIterator::GET_MATCH);

// Schleife über alle Entity-Klassen
foreach ($regexIterator as $file) {
$filePath = $file[0];

// Lade die Entity-Klasse und rufe die Annotationen ab
require_once $filePath;
$className = getClassNameFromFile($filePath);
$reflectionClass = new \ReflectionClass($className);
$reflectionProperties = $reflectionClass->getProperties();

// Konvertiere die Annotationen in die zweite Art
foreach ($reflectionProperties as $reflectionProperty) {
$annotations = $annotationReader->getPropertyAnnotations($reflectionProperty);

foreach ($annotations as $annotation) {
if ($annotation instanceof Column) {
$type = Types::STRING;
$length = $annotation->length;
$nullable = !$annotation->nullable;

$reflectionProperty->setAccessible(true);
$columnAnnotation = $reflectionProperty->getValue($reflectionClass);

$columnAnnotation->type = $type;
$columnAnnotation->length = $length;
$columnAnnotation->nullable = $nullable;

$reflectionProperty->setAccessible(false);
}
}
}
}

/**
* Liefert den Klassennamen aus einer Datei.
*
* @param string $filePath Der Pfad zur Datei.
*
* @return string|null Der Klassenname oder null, wenn kein gültiger Klassenname gefunden wurde.
*/
function getClassNameFromFile(string $filePath): ?string
{
$phpCode = file_get_contents($filePath);
$tokens = token_get_all($phpCode);

$namespace = '';
$className = '';
$isNamespaceFound = false;
$isClassFound = false;

foreach ($tokens as $token) {
if (is_array($token)) {
list($tokenType, $tokenValue) = $token;

if ($tokenType === T_NAMESPACE) {
$isNamespaceFound = true;
$namespace = '';
} elseif ($tokenType === T_CLASS) {
$isClassFound = true;
$className = '';
} elseif ($isNamespaceFound && $tokenType === T_STRING) {
$namespace .= $tokenValue;
} elseif ($isClassFound && $tokenType === T_STRING) {
$className = $tokenValue;
break;
}
}
}

if ($isNamespaceFound && $isClassFound && !empty($className)) {
return $namespace . '\\' . $className;
}

return null;
}

+ 100
- 0
httpdocs/src/EntityVirtual/ServiceData.php Прегледај датотеку

@@ -0,0 +1,100 @@
<?php
/**
* Created by PhpStorm.
* User: danielknudsen
* Date: 20.11.19
* Time: 19:42
*/

namespace App\EntityVirtual;


use Symfony\Component\Config\Definition\Exception\Exception;

class ServiceData
{

const SERVICE_DATA_TYPE_CUSTOMERS = 'customers';
const SERVICE_DATA_TYPE_CUSTOMER_CONTACTS = 'customerContacts';
const SERVICE_DATA_TYPE_CUSTOMER_MEETINGS = 'customerMeetings';
const SERVICE_DATA_TYPE_INTERNAL_MEETINGS = 'internalMeetings';

const ACTION_ADD = 'add';
const ACTION_EDIT = 'edit';
const ACTION_DELETE = 'delete';

private static $validServiceDataTypes = [
self::SERVICE_DATA_TYPE_CUSTOMERS => 1,
self::SERVICE_DATA_TYPE_CUSTOMER_CONTACTS => 1,
self::SERVICE_DATA_TYPE_CUSTOMER_MEETINGS => 1,
self::SERVICE_DATA_TYPE_INTERNAL_MEETINGS => 1,
];

private static $validActions = [
self::ACTION_ADD => 1,
self::ACTION_EDIT => 1,
self::ACTION_DELETE => 1,
];

private $serviceData;

/**
* ServiceData constructor.
*/
public function __construct()
{
$this->serviceData = [];
foreach (self::$validServiceDataTypes as $serviceDataType => $dummy) {
$this->serviceData[$serviceDataType] = null;
}
}

public function getServiceData()
{
return $this->serviceData;
}

/**
* @param $serviceDataType
* @param $action
* @param $data
*/
public function addServiceData($serviceDataType, $action, $data)
{
if (!$this->isValidServiceDataType($serviceDataType)) {
throw new Exception('invalid service data type');
}

if (!$this->isValidAction($action)) {
throw new Exception('invalid action');
}

if (is_null($this->serviceData[$serviceDataType])) {
$this->serviceData[$serviceDataType] = [
self::ACTION_ADD => [],
self::ACTION_EDIT => [],
self::ACTION_DELETE => [],
];
}
$this->serviceData[$serviceDataType][$action][] = $data;
}

/**
* @param $serviceDataType
* @return bool
*/
private function isValidServiceDataType($serviceDataType)
{
return array_key_exists($serviceDataType, self::$validServiceDataTypes);
}

/**
* @param $action
* @return bool
*/
private function isValidAction($action)
{
return array_key_exists($action, self::$validActions);
}

}

+ 69
- 0
httpdocs/src/EventListener/ControllerListener.php Прегледај датотеку

@@ -0,0 +1,69 @@
<?php

namespace App\EventListener;


use App\Entity\EntUser;
use App\Utils\Tools;
use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Event\PostResponseEvent;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;

class ControllerListener
{
private $router;
private $tokenStorage;
private $em;

/**
* ControllerListener constructor.
* @param RouterInterface $router
* @param TokenStorage $tokenStorage
* @param EntityManager $em
*/
public function __construct(RouterInterface $router, TokenStorage $tokenStorage, EntityManager $em)
{
$this->router = $router;
$this->tokenStorage = $tokenStorage;
$this->em = $em;
}

/**
* On kernel request
* @param GetResponseEvent $event
*/
public function onKernelRequest(GetResponseEvent $event)
{
// ini_set("memory_limit","1024M");
//
// // NOTE: Increase execution time (be careful)
// ini_set('max_execution_time', 180);

// $user = $this->tokenStorage->getToken()->getUser();
// $attributeParams = $event->getRequest()->attributes;
// $requestParams = $event->getRequest()->request;
// $route = $attributeParams->get('_route');

}

public function onKernelException(GetResponseForExceptionEvent $event)
{

}

public function onKernelResponse(FilterResponseEvent $event)
{
// Compress all responsesF
ob_start('ob_gzhandler');
}

public function onKernelTerminate(PostResponseEvent $event)
{
//sleep(60);
}

}

+ 72
- 0
httpdocs/src/EventListener/DatabaseListener.php Прегледај датотеку

@@ -0,0 +1,72 @@
<?php
/**
* Created by PhpStorm.
* User: danielknudsen
* Date: 11.04.18
* Time: 18:56
*/

namespace App\EventListener;


use App\Entity\EntUser;
use App\Entity\IFace\IEntity;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;

class DatabaseListener implements EventSubscriber
{
const ENVIRONMENT_DEV = "dev";

/** @var TokenStorage $tokenStorage */
private $tokenStorage;

public function __construct(TokenStorage $tokenStorage, $environment)
{
$this->tokenStorage = $tokenStorage;
}


public function getSubscribedEvents()
{
return [
'postPersist',
'postUpdate'
];
}

/**
* @param LifecycleEventArgs $args
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function postUpdate(LifecycleEventArgs $args)
{

}

/**
* @param LifecycleEventArgs $args
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function postPersist(LifecycleEventArgs $args)
{

}

/**
* Creates a log entry for deleted entity
* @param LifecycleEventArgs $args
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function preRemove(LifecycleEventArgs $args)
{

}

}

+ 11
- 0
httpdocs/src/Kernel.php Прегледај датотеку

@@ -0,0 +1,11 @@
<?php

namespace App;

use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;

class Kernel extends BaseKernel
{
use MicroKernelTrait;
}

+ 0
- 0
httpdocs/src/Repository/.gitignore Прегледај датотеку


+ 132
- 0
httpdocs/src/Security/JsonAuthenticator.php Прегледај датотеку

@@ -0,0 +1,132 @@
<?php
/**
* Created by PhpStorm.
* User: danielknudsen
* Date: 05.04.18
* Time: 10:12
*/
namespace App\Security;

use App\Entity\EntUser;
use App\Utils\Config;
use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;

class JsonAuthenticator extends AbstractGuardAuthenticator
{
const LOGIN_FAILED = 0;
const LOGIN_SUCCESS = 1;

private $em;

private $router;

/** @var $user EntUser */
private $user;

/**
* JsonAuthenticator constructor.
* @param $em
*/
public function __construct(EntityManager $em, RouterInterface $router)
{
$this->em = $em;
$this->router = $router;
$this->user = null;
}

/**
* Called on every request to decide if this authenticator should be
* used for the request. Returning false will cause this authenticator
* to be skipped.
*/
public function supports(Request $request)
{
if ($request->getPathInfo() != "/login" || !$request->isMethod('POST')) {
return false;
}

return !is_null($request->request->get('email')) &&
!is_null($request->request->get('password'));
}

/**
* Called on every request. Return whatever credentials you want to
* be passed to getUser() as $credentials.
*/
public function getCredentials(Request $request)
{
return [
'email' => $request->request->get('email'),
'password' => $request->request->get('password'),
];
}

public function getUser($credentials, UserProviderInterface $userProvider)
{
$email = $credentials['email'];
$this->user = $this->em->getRepository('App:EntUser')->findOneBy(['email' => $email]);

// if a User object, checkCredentials() is called
return $this->user;
}

public function checkCredentials($credentials, UserInterface $user)
{
/** @var $user EntUser */
return !is_null($user) && $user->checkPassword($credentials['password']);
}

public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
// on success, let the request continue
$data = array('message' => 'logged in successfully',
'isLoggedIn' => self::LOGIN_SUCCESS,
'user' => $this->user->clientMapper($this->em),
'config' => Config::getConfig($this->em),
);
return new JsonResponse($data, Response::HTTP_ACCEPTED);
}

public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
$data = array(
'message' => strtr($exception->getMessageKey(), $exception->getMessageData()),
'isLoggedIn' => self::LOGIN_FAILED,
'user' => null,
'config' => null,

// or to translate this message
//$this->translator->trans($exception->getMessageKey(), $exception->getMessageData())
);
return new JsonResponse($data, Response::HTTP_FORBIDDEN);
}

/**
* Called when authentication is needed, but it's not sent
*/
public function start(Request $request, AuthenticationException $authException = null)
{
$data = array(
// you might translate this message
'message' => 'Authentication Required'
);

return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
}

public function supportsRememberMe()
{
return true;
}


}

+ 37
- 0
httpdocs/src/Utils/Config.php Прегледај датотеку

@@ -0,0 +1,37 @@
<?php
/**
* Created by PhpStorm.
* User: danielknudsen
* Date: 03.05.18
* Time: 16:43
*/

namespace App\Utils;


use App\Entity\EntCadasterGlassSurfaceEntry;
use App\Entity\EntCadasterLocalizationEntry;
use App\Entity\EntCadasterTreeEntry;
use App\Entity\EntCountry;
use App\Entity\EntLocationObject;
use App\Entity\EntQualityRequirementRoom;
use App\Entity\EntUserType;
use Doctrine\Common\Persistence\ObjectManager;

class Config
{
/**
* Returns api config
* @param ObjectManager $em
* @return array
*/
public static function getConfig(ObjectManager $em)
{
return [
'users' => Utils::clientMap($em, $em->getRepository('App:EntUser')->findBy(['visible' => true])),
'meeting_types' => Utils::clientMap($em, $em->getRepository('App:EntMeetingType')->findAll()),
'countries' => Utils::clientMap($em, $em->getRepository('App:EntCountry')->findAll()),
];
}

}

+ 530
- 0
httpdocs/src/Utils/Excel.php Прегледај датотеку

@@ -0,0 +1,530 @@
<?php
/**
* Created by PhpStorm.
* User: danielknudsen
* Date: 10.01.19
* Time: 09:14
*/

namespace App\Utils;


use App\ControllerHelper\Tender\TenderHelper;
use App\Entity\EntDinSecondLevel;
use App\Entity\EntDinVersion;
use App\Entity\EntMandator;
use Doctrine\Common\Persistence\ObjectManager;
use Onurb\Bundle\ExcelBundle\Factory\ExcelFactory;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Color;
use PhpOffice\PhpSpreadsheet\Style\Conditional;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use PhpOffice\PhpSpreadsheet\Style\Protection;
use PhpOffice\PhpSpreadsheet\Worksheet\HeaderFooter;
use PhpOffice\PhpSpreadsheet\Worksheet\HeaderFooterDrawing;
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use Psr\Container\ContainerInterface;
use Symfony\Component\Config\Definition\Exception\Exception;

class Excel
{
const EXCEL_CREATOR = "PLP Parkhauswerbung";

const EXCEL_BOOLEAN_WORD_TRUE = 'ja';
const EXCEL_BOOLEAN_WORD_FALSE = 'nein';
const EXCEL_BOOLEAN_TRUE = 'x';
const EXCEL_BOOLEAN_FALSE = '--';

public static $validCheckboxValues = [
self::EXCEL_BOOLEAN_WORD_TRUE => 1,
self::EXCEL_BOOLEAN_WORD_FALSE => 1,
self::EXCEL_BOOLEAN_TRUE => 1,
self::EXCEL_BOOLEAN_FALSE => 1,
'0' => 1,
'1' => 1,
'' => 1
];

/**
* Returns spreadsheet with meta data
* @param ContainerInterface $container
* @param null $filename
* @return Spreadsheet
*/
public static function createSpreadSheet(ContainerInterface $container, $filename = null)
{
/** @var ExcelFactory $phpSpreadsheet */
$phpSpreadSheet = $container->get('phpspreadsheet');
/** @var Spreadsheet $spreadSheet */
$spreadSheet = $phpSpreadSheet->createSpreadsheet($filename);
$spreadSheet->getProperties()->setCreator(self::EXCEL_CREATOR);
$spreadSheet->getProperties()->setLastModifiedBy(self::EXCEL_CREATOR);
//$phpSpreadSheet->createSheet()
return $spreadSheet;
}

/**
* Returns an excel writer
* @param ContainerInterface $container
* @param Spreadsheet $spreadsheet
* @return \PhpOffice\PhpSpreadsheet\Writer\IWriter
*/
public static function createWriter(ContainerInterface $container, Spreadsheet $spreadsheet)
{
/** @var ExcelFactory $phpSpreadsheet */
$phpSpreadSheet = $container->get('phpspreadsheet');
$writer = $phpSpreadSheet->createWriter($spreadsheet, 'Xlsx');
return $writer;
}

/**
* Returns active sheet
* @param Spreadsheet $spreadSheet
* @param null $sheetName
* @param null $assetDir
* @param int $activeSheetIndex
* @return Worksheet
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function getActiveSheet(Spreadsheet $spreadSheet, $sheetName = null, $assetDir = null, $activeSheetIndex = 0)
{
$spreadSheet->setActiveSheetIndex($activeSheetIndex);
$activeSheet = $spreadSheet->getActiveSheet();
$activeSheet->setTitle($sheetName);
return $activeSheet;
}

/**
* Check if given excel value is a valid checkbox value
* @param $value
* @return bool
*/
private static function isExcelCheckboxValue($value)
{
return array_key_exists($value, self::$validCheckboxValues);
}

/**
* Returns Excel checkbox value
* @param Worksheet $sheet
* @param $column
* @param $row
* @return bool
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function getExcelCheckboxValue(Worksheet $sheet, $column, $row)
{
$value = self::getExcelTextValue($sheet, $column, $row);
if (!self::isExcelCheckboxValue($value)) {
throw new Exception('invalid check box value');
}
return $value == "1" || $value == "ja" || $value == "x";
}

/**
* Return Excel date value
* @param Worksheet $sheet
* @param $column
* @param $row
* @return bool|null|string
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function getExcelDateValue(Worksheet $sheet, $column, $row)
{
$value = self::getExcelTextValue($sheet, $column, $row);
if (!is_null($value)) {
$date = null;
// Try all valid date formats of too1s
$date = \DateTime::createFromFormat("d.m.y", $value);
if ($date !== false) {
return $date->format('Y-m-d');
}
$date = \DateTime::createFromFormat("d.m.Y", $value);
if ($date !== false) {
return $date->format('Y-m-d');
}
$date = \DateTime::createFromFormat("j.n.y", $value);
if ($date !== false) {
return $date->format('Y-m-d');
}
$date = \DateTime::createFromFormat("j.n.Y", $value);
if ($date !== false) {
return $date->format('Y-m-d');
}
throw new Exception('invalid date value'); // No valid date
}
return null;
}

/**
* Gets date for excel export (german date format)
* @param $value
* @return bool|null|string
*/
public static function getExcelExportDate($value)
{
if (!is_null($value)) {
$date = \DateTime::createFromFormat("Y-m-d", $value);
if ($date !== false) {
return $date->format('d.m.Y');
}
return false; // No valid date
}
return null;
}

/**
* Returns text value of Excel sheet
* @param Worksheet $sheet
* @param $column
* @param $row
* @param bool $stringResult
* @return null|string
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function getExcelTextValue(Worksheet $sheet, $column, $row, $stringResult = false)
{
$column = self::convertColumnToIndex($column);
$value = $sheet->getCell($column.$row);
return $value == "" ? ($stringResult ? "" : null) : trim($value);
}

/**
* Returns integer value of Excel sheet
* @param Worksheet $sheet
* @param $column
* @param $row
* @return float|null
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function getExcelIntValue(Worksheet $sheet, $column, $row)
{
$value = self::getExcelTextValue($sheet, $column, $row);
if (!is_null($value)) {
$value = intval($value);
if (!Utils::isIntValue($value)) {
throw new Exception('invalid integer value');
}
return $value;
}
return null;
}

/**
* Returns float value of Excel sheet
* @param Worksheet $sheet
* @param $column
* @param $row
* @return float|null
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function getExcelFloatValue(Worksheet $sheet, $column, $row)
{
$value = self::getExcelTextValue($sheet, $column, $row);
if (!is_null($value)) {
if (!Utils::isFloatValue($value)) {
throw new Exception('invalid float value');
}
return Utils::getFloatValue($value);
}
return null;
}

/**
* @param $value
* @return string
*/
public static function getBooleanExcelValue($value)
{
return $value === true ? self::EXCEL_BOOLEAN_TRUE : self::EXCEL_BOOLEAN_FALSE;
}

/**
* @param $value
* @return string
*/
public static function getBooleanExcelValueWord($value)
{
return $value === true ? 'x' : '';
}

/**
* Converts numeric column index to string column
* @param $column
* @return string
*/
public static function convertColumnToIndex($column)
{
return is_numeric($column) ? Coordinate::stringFromColumnIndex($column) : $column;
}

/**
* Converts string column index to numeric column index
* @param $columnIndex
* @return int|string
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function convertIndexToColumn($columnIndex)
{
return !is_numeric($columnIndex) ? Coordinate::columnIndexFromString($columnIndex) : $columnIndex;
}

/**
* Returns calculated value of Excel sheet
* @param Worksheet $sheet
* @param $column
* @param $row
* @param bool $stringResult
* @return null|string
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function getExcelCalculatedValue(Worksheet $sheet, $column, $row, $stringResult = false)
{
$column = self::convertColumnToIndex($column);
$value = $sheet->getCell($column.$row)->getCalculatedValue();
return $value;
}

/**
* Sets a column of given worksheet with optional header content and border etc.
* @param Worksheet $worksheet
* @param $column
* @param int $width
* @param null $headerContent
* @param null $bordersArray
* @param int $colRow
* @param null $colAlign
* @param null $colCellAlign
* @param bool $wrapText
* @param null $colCellColor
* @param null $colCellFontColor
* @param bool $bold
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function setColumn(Worksheet $worksheet, $column, $width = 10, $headerContent = null,
$bordersArray = null, $colRow = 1, $colAlign = null, $colCellAlign = null,
$wrapText = true, $colCellColor = null, $colCellFontColor = null, $bold = false)
{
$column = self::convertColumnToIndex($column);
$worksheet->getColumnDimension($column)->setWidth($width);
$cell = $column.$colRow;
!is_null($headerContent) ? $worksheet->getCell($cell)->setValue($headerContent) : null;
!is_null($bordersArray) ? $worksheet->getStyle($cell)->applyFromArray($bordersArray) : null;
!is_null($colAlign) ? $worksheet->getStyle($column.":".$column)->getAlignment()->setHorizontal($colAlign) : null;
!is_null($colCellAlign) ? $worksheet->getStyle($cell)->getAlignment()->setHorizontal($colCellAlign) : null;
$worksheet->getStyle($cell)->getAlignment()->setWrapText($wrapText);

!is_null($colCellColor) ? $worksheet->getStyle($cell)->getFill()->setFillType(Fill::FILL_SOLID): null;
!is_null($colCellColor) ? $worksheet->getStyle($cell)->getFill()->getStartColor()->setARGB($colCellColor): null;
!is_null($colCellFontColor) ? $worksheet->getStyle($cell)->getFont()->getColor()->setARGB($colCellFontColor): null;
$worksheet->getStyle($cell)->getFont()->setBold($bold);
}

/**
* Sets a cell value of given worksheet
* @param Worksheet $worksheet
* @param $column
* @param $row
* @param $value
* @param null $cellColor
* @param null $cellFontColor
* @param bool $bold
* @param bool $wrapText
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function setCellValue(Worksheet $worksheet, $column, $row, $value,
$cellColor = null, $cellFontColor = null, $bold = false, $wrapText = true)
{
$column = self::convertColumnToIndex($column);
$cell = $column.$row;
self::setCellValueSimple($worksheet, $column, $row, $value);
!is_null($cellColor) ? $worksheet->getStyle($cell)->getFill()->setFillType(Fill::FILL_SOLID): null;
!is_null($cellColor) ? $worksheet->getStyle($cell)->getFill()->getStartColor()->setARGB($cellColor): null;
!is_null($cellFontColor) ? $worksheet->getStyle($cell)->getFont()->getColor()->setARGB($cellFontColor): null;
$worksheet->getStyle($cell)->getFont()->setBold($bold);
$worksheet->getStyle($cell)->getAlignment()->setWrapText($wrapText);
}

/**
* Just set value
* @param Worksheet $worksheet
* @param $column
* @param $row
* @param $value
* @param bool $bAsPlainText
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function setCellValueSimple(Worksheet $worksheet, $column, $row, $value, $bAsPlainText = false)
{
$column = self::convertColumnToIndex($column);
if ($bAsPlainText) {
// @TODO: this is a hack to force excel to render value not as number
$worksheet->getCell($column.$row)->setValue(strval($value)." ");
self::setFormatCode($worksheet, $column, $row, $column, $row, NumberFormat::FORMAT_TEXT);
} else {
$worksheet->getCell($column.$row)->setValue($value);
}
}

/**
* Sets cells unlocked (need to implement: $activeSheet->getProtection()->setSheet(true); )
* @param Worksheet $worksheet
* @param $startCol
* @param $startRow
* @param $endCol
* @param $endRow
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function setUnLocked(Worksheet $worksheet, $startCol, $startRow, $endCol, $endRow)
{
$startCol = self::convertColumnToIndex($startCol);
$endCol = self::convertColumnToIndex($endCol);
$startCol = is_numeric($startCol) ? Coordinate::stringFromColumnIndex($startCol) : $startCol;
$endCol = is_numeric($endCol) ? Coordinate::stringFromColumnIndex($endCol) : $endCol;
$worksheet->getStyle($startCol.$startRow.':'.$endCol.$endRow)->getProtection()->setLocked(Protection::PROTECTION_UNPROTECTED);
}

/**
* Sets Conditional
* @param Worksheet $worksheet
* @param $condition_type
* @param $operator_type
* @param $condition_value
* @param $startCol
* @param $startRow
* @param null $endCol
* @param null $endRow
* @param string $background_color
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function setConditional(Worksheet $worksheet, $condition_type, $operator_type, $condition_value,
$startCol, $startRow, $endCol = null, $endRow = null, $background_color = Color::COLOR_WHITE)
{
$startCol = self::convertColumnToIndex($startCol);
$endCol = self::convertColumnToIndex($endCol);
$conditional1 = new Conditional();
$conditional1->setConditionType($condition_type);
$conditional1->setOperatorType($operator_type);
$conditional1->addCondition($condition_value);
$conditional1->getStyle()->getFill()->setFillType(Fill::FILL_SOLID);
$conditional1->getStyle()->getFill()->getEndColor()->setARGB($background_color);

$conditionalStyles = $worksheet->getStyle($startCol.$startRow)->getConditionalStyles();
$conditionalStyles[] = $conditional1;

if (!is_null($endCol) && !is_null($endRow)) {
$worksheet->getStyle($startCol.$startRow.':'.$endCol.$endRow)->setConditionalStyles($conditionalStyles);
} else {
$worksheet->getStyle($startCol.$startRow)->setConditionalStyles($conditionalStyles);
}
}

/**
* Merges cells of given range
* @param Worksheet $worksheet
* @param $startCol
* @param $endCol
* @param $startRow
* @param $endRow
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function mergeCells(Worksheet $worksheet, $startCol, $startRow, $endCol, $endRow)
{
$startCol = self::convertColumnToIndex($startCol);
$endCol = self::convertColumnToIndex($endCol);
$worksheet->mergeCells($startCol.$startRow.':'.$endCol.$endRow);
}

/**
* Unmerges cells of given range
* @param Worksheet $worksheet
* @param $startCol
* @param $startRow
* @param $endCol
* @param $endRow
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function unMergeCells(Worksheet $worksheet, $startCol, $startRow, $endCol, $endRow)
{
$startCol = self::convertColumnToIndex($startCol);
$endCol = self::convertColumnToIndex($endCol);
$worksheet->unmergeCells($startCol.$startRow.':'.$endCol.$endRow);
}

/**
* Sets color for cell range
* @param Worksheet $worksheet
* @param $startCol
* @param $startRow
* @param $endCol
* @param $endRow
* @param string $color
* @param string $fontColor
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function setRangeColor(Worksheet $worksheet, $startCol, $startRow, $endCol, $endRow,
$color = Color::COLOR_WHITE, $fontColor = Color::COLOR_BLACK)
{
$startCol = self::convertColumnToIndex($startCol);
$endCol = self::convertColumnToIndex($endCol);
$worksheet->getStyle($startCol.$startRow.':'.$endCol.$endRow)->getFill()->setFillType(Fill::FILL_SOLID);
$worksheet->getStyle($startCol.$startRow.':'.$endCol.$endRow)->getFill()->getStartColor()->setARGB($color);
$worksheet->getStyle($startCol.$startRow.':'.$endCol.$endRow)->getFont()->getColor()->setARGB($fontColor);
}

/**
* Sets range border
* @param Worksheet $worksheet
* @param $startCol
* @param $startRow
* @param $endCol
* @param $endRow
* @param $bordersArray
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function setRangeBorder(Worksheet $worksheet, $startCol, $startRow, $endCol, $endRow, $bordersArray)
{
$startCol = self::convertColumnToIndex($startCol);
$endCol = self::convertColumnToIndex($endCol);
$worksheet->getStyle($startCol.$startRow.':'.$endCol.$endRow)->applyFromArray($bordersArray);
}

/**
* Sets format code
* @param Worksheet $worksheet
* @param $startCol
* @param $startRow
* @param $endCol
* @param $endRow
* @param $formatCode
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function setFormatCode(Worksheet $worksheet, $startCol, $startRow, $endCol, $endRow, $formatCode)
{
$startCol = self::convertColumnToIndex($startCol);
$endCol = self::convertColumnToIndex($endCol);
$worksheet->getStyle($startCol.$startRow.':'.$endCol.$endRow)->getNumberFormat()->setFormatCode($formatCode);
}

/**
* Sets styles from style array
* @param Worksheet $worksheet
* @param $startCol
* @param $startRow
* @param $endCol
* @param $endRow
* @param $styleArray
* @throws \PhpOffice\PhpSpreadsheet\Exception
*/
public static function setStyleArray(Worksheet $worksheet, $startCol, $startRow, $endCol, $endRow, $styleArray)
{
$startCol = self::convertColumnToIndex($startCol);
$endCol = self::convertColumnToIndex($endCol);
$worksheet->getStyle($startCol.$startRow.':'.$endCol.$endRow)->applyFromArray($styleArray);
}
}

+ 139
- 0
httpdocs/src/Utils/ExcelStyle.php Прегледај датотеку

@@ -0,0 +1,139 @@
<?php
/**
* Created by PhpStorm.
* User: danielknudsen
* Date: 10.01.19
* Time: 09:14
*/

namespace App\Utils;


use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;

class ExcelStyle
{
const NUMBER_FORMAT_DECIMAL_STANDARD = NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED1;
const NUMBER_FORMAT_DECIMAL_ONE_DIGIT = '#,#0.0';
const NUMBER_FORMAT_EURO = NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE;
const NUMBER_FORMAT_METER = '#,##0.00_-"m"';
const NUMBER_FORMAT_SQUARE_METER = '#,##0.00_-"m²"';
const NUMBER_FORMAT_HOUR = '#,##0.00_-"Std"';
const NUMBER_FORMAT_EMPLOYEE = '#,##0.00_-"MA"';
const NUMBER_FORMAT_PIECES = '#,##0.00_-"Stück"';

// Styles for cadaster excels
public static $CADASTER_STYLES = [
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_CENTER,
'vertical' => Alignment::VERTICAL_CENTER,
'wrapText' => true
],
'font' => [
'size' => 11,
'name' => 'Arial'
],
];

// Font styles for cadaster excels
public static $CADASTER_FONT = [
'font' => [
'size' => 11,
'name' => 'Arial'
],
];

// Bold style
public static $FONT_BOLD = [
'font' => [
'bold' => true
],
];

// Font align right
public static $ALIGN_LEFT = [
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_LEFT,
'vertical' => Alignment::VERTICAL_CENTER,
'wrapText' => true
]
];

// Font align right
public static $ALIGN_RIGHT = [
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_RIGHT,
'vertical' => Alignment::VERTICAL_CENTER,
'wrapText' => true
]
];

// Font align center
public static $ALIGN_CENTER = [
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_CENTER,
'vertical' => Alignment::VERTICAL_CENTER,
'wrapText' => true
]
];

// Borders for cadaster excels
public static $CADASTER_BORDERS = [
'borders' => [
'top' => [
'borderStyle' => Border::BORDER_THIN,
'color' => array('argb' => 'FF000000'),
],
'bottom' => [
'borderStyle' => Border::BORDER_THIN,
'color' => array('argb' => 'FF000000'),
],
'left' => [
'borderStyle' => Border::BORDER_THIN,
'color' => array('argb' => 'FF000000'),
],
'right' => [
'borderStyle' => Border::BORDER_THIN,
'color' => array('argb' => 'FF000000'),
],
],
];

// Medium borders for cadaster excels
public static $CADASTER_BORDERS_MEDIUM = [
'borders' => [
'allBorders' => [
'borderStyle' => Border::BORDER_THIN,
'color' => array('argb' => 'FF000000'),
],
'top' => [
'borderStyle' => Border::BORDER_MEDIUM,
'color' => array('argb' => 'FF000000'),
],
'bottom' => [
'borderStyle' => Border::BORDER_MEDIUM,
'color' => array('argb' => 'FF000000'),
],
'left' => [
'borderStyle' => Border::BORDER_MEDIUM,
'color' => array('argb' => 'FF000000'),
],
'right' => [
'borderStyle' => Border::BORDER_MEDIUM,
'color' => array('argb' => 'FF000000'),
],
],
];

// Dashed border
public static $DASHED_BORDERS = [
'borders' => [
'bottom' => [
'borderStyle' => Border::BORDER_MEDIUMDASHED,
'color' => array('argb' => 'FF000000'),
]
],
];
}

+ 209
- 0
httpdocs/src/Utils/Message.php Прегледај датотеку

@@ -0,0 +1,209 @@
<?php
/**
* Created by PhpStorm.
* User: danielknudsen
* Date: 03.05.18
* Time: 16:43
*/

namespace App\Utils;


class Message
{
// Default messages
const SUCCESS_DEFAULT = "Aktion erfolgreich ausgeführt";
const ERROR_DEFAULT = "Es ist ein Fehler aufgetreten";
const INFO_DEFAULT = "";

// Success codes
const SUCCESS_NONE = 0;
const SUCCESS_CUSTOMER_CREATE = 1;
const SUCCESS_CUSTOMER_EDIT = 2;
const SUCCESS_CUSTOMER_CONTACT_CREATE = 3;
const SUCCESS_CUSTOMER_CONTACT_EDIT = 4;
const SUCCESS_CUSTOMER_CONTACT_DELETE = 5;
const SUCCESS_CUSTOMER_MEETING_CREATE = 6;
const SUCCESS_CUSTOMER_MEETING_EDIT = 7;
const SUCCESS_CUSTOMER_MEETING_DELETE = 8;
const SUCCESS_CUSTOMER_MEETING_REPORT_SET = 9;
const SUCCESS_CUSTOMER_NOTE_CREATE = 10;
const SUCCESS_CUSTOMER_NOTE_EDIT = 11;
const SUCCESS_CUSTOMER_NOTE_DELETE = 12;
const SUCCESS_INTERNAL_MEETING_CREATE = 13;
const SUCCESS_INTERNAL_MEETING_EDIT = 14;
const SUCCESS_INTERNAL_MEETING_DELETE = 15;
const SUCCESS_INTERNAL_MEETING_REPORT_SET = 16;
const SUCCESS_OPERATOR_CREATE = 17;
const SUCCESS_OPERATOR_EDIT = 18;
const SUCCESS_OPERATOR_CONTACT_CREATE = 19;
const SUCCESS_OPERATOR_CONTACT_EDIT = 20;
const SUCCESS_OPERATOR_CONTACT_DELETE = 21;
const SUCCESS_OPERATOR_MEETING_CREATE = 22;
const SUCCESS_OPERATOR_MEETING_EDIT = 23;
const SUCCESS_OPERATOR_MEETING_DELETE = 24;
const SUCCESS_OPERATOR_MEETING_REPORT_SET = 25;
const SUCCESS_OPERATOR_NOTE_CREATE = 26;
const SUCCESS_OPERATOR_NOTE_EDIT = 27;
const SUCCESS_OPERATOR_NOTE_DELETE = 28;
const SUCCESS_PRODUCTION_CREATE = 29;
const SUCCESS_PRODUCTION_EDIT = 30;
const SUCCESS_PRODUCTION_CONTACT_CREATE = 31;
const SUCCESS_PRODUCTION_CONTACT_EDIT = 32;
const SUCCESS_PRODUCTION_CONTACT_DELETE = 33;
const SUCCESS_PRODUCTION_MEETING_CREATE = 34;
const SUCCESS_PRODUCTION_MEETING_EDIT = 35;
const SUCCESS_PRODUCTION_MEETING_DELETE = 36;
const SUCCESS_PRODUCTION_MEETING_REPORT_SET = 37;
const SUCCESS_PRODUCTION_NOTE_CREATE = 38;
const SUCCESS_PRODUCTION_NOTE_EDIT = 39;
const SUCCESS_PRODUCTION_NOTE_DELETE = 40;
const SUCCESS_SERVICE_CREATE = 41;
const SUCCESS_SERVICE_EDIT = 42;
const SUCCESS_SERVICE_CONTACT_CREATE = 43;
const SUCCESS_SERVICE_CONTACT_EDIT = 44;
const SUCCESS_SERVICE_CONTACT_DELETE = 45;
const SUCCESS_SERVICE_MEETING_CREATE = 46;
const SUCCESS_SERVICE_MEETING_EDIT = 47;
const SUCCESS_SERVICE_MEETING_DELETE = 48;
const SUCCESS_SERVICE_MEETING_REPORT_SET = 49;
const SUCCESS_SERVICE_NOTE_CREATE = 50;
const SUCCESS_SERVICE_NOTE_EDIT = 51;
const SUCCESS_SERVICE_NOTE_DELETE = 52;

// Error codes
const ERROR_UNKNOWN = -1;
const ERROR_INVALID_DATA = -2;
const ERROR_NON_EXISTING_DATA = -3;
const ERROR_REPORT_NOT_EDITABLE_YET = -4;
const ERROR_MEETING_NOT_EDIT_DELETABLE = -5;
const ERROR_NOT_ENOUGH_RIGHTS = -6;

// Admin error codes


// Info codes
const INFO_NONE = 0;
const INFO_DATA_UNKNOWN = 1;

public static $errorMessages = [
self::ERROR_UNKNOWN => "Es ist ein Fehler aufgetreten",
self::ERROR_INVALID_DATA => "Notwendige Daten fehlen oder sind ungültig",
self::ERROR_NON_EXISTING_DATA => "Die von Ihnen bearbeiteten Daten existieren nicht mehr. Bitte aktualisieren Sie die Seite.",
self::ERROR_REPORT_NOT_EDITABLE_YET => "Der Report kann erst nach Start des Termins bearbeitet werden.",
self::ERROR_MEETING_NOT_EDIT_DELETABLE => "Ein Termin kann nach Beginn nicht mehr verändert bzw. gelöscht werden.",
self::ERROR_NOT_ENOUGH_RIGHTS => "Sie sind nicht der Ersteller / Verantwortlicher für diesen Datensatz oder verfügen nicht über entsprechenden Recht Änderungen vorzunehmen.",
// Admin errors

];

// Success messages
public static $successMessages = [
self::SUCCESS_CUSTOMER_CREATE => "Kunde wurde erfolgreich angelegt.",
self::SUCCESS_CUSTOMER_EDIT => "Kunde wurde erfolgreich geändert.",
self::SUCCESS_CUSTOMER_CONTACT_CREATE => "Ansprechpartner von Kunde wurde erfolgreich angelegt.",
self::SUCCESS_CUSTOMER_CONTACT_EDIT => "Ansprechpartner von Kunde wurde erfolgreich geändert.",
self::SUCCESS_CUSTOMER_CONTACT_DELETE => "Ansprechpartner von Kunde wurde erfolgreich gelöscht.",
self::SUCCESS_CUSTOMER_MEETING_CREATE => "Termin mit Kunde wurde erfolgreich angelegt.",
self::SUCCESS_CUSTOMER_MEETING_EDIT => "Termin mit Kunde wurde erfolgreich geändert.",
self::SUCCESS_CUSTOMER_MEETING_DELETE => "Termin mit Kunde wurde erfolgreich gelöscht.",
self::SUCCESS_CUSTOMER_MEETING_REPORT_SET => "Report für Kundenmeeting wurde erfolgreich bearbeitet.",
self::SUCCESS_CUSTOMER_NOTE_CREATE => "Notiz für Kunde wurde erfolgreich angelegt.",
self::SUCCESS_CUSTOMER_NOTE_EDIT => "Notiz für Kunde wurde erfolgreich geändert.",
self::SUCCESS_CUSTOMER_NOTE_DELETE => "Notiz für Kunde wurde erfolgreich gelöscht.",
self::SUCCESS_INTERNAL_MEETING_CREATE => "Interner Termin wurde erfolgreich angelegt.",
self::SUCCESS_INTERNAL_MEETING_EDIT => "Interner Termin wurde erfolgreich geändert.",
self::SUCCESS_INTERNAL_MEETING_DELETE => "Interner Termin wurde erfolgreich gelöscht.",
self::SUCCESS_INTERNAL_MEETING_REPORT_SET => "Report für internen Termin wurde erfolgreich bearbeitet.",
self::SUCCESS_OPERATOR_CREATE => "Betreiber wurde erfolgreich angelegt.",
self::SUCCESS_OPERATOR_EDIT => "Betreiber wurde erfolgreich geändert.",
self::SUCCESS_OPERATOR_CONTACT_CREATE => "Ansprechpartner von Betreiber wurde erfolgreich angelegt.",
self::SUCCESS_OPERATOR_CONTACT_EDIT => "Ansprechpartner von Betreiber wurde erfolgreich geändert.",
self::SUCCESS_OPERATOR_CONTACT_DELETE => "Ansprechpartner von Betreiber wurde erfolgreich gelöscht.",
self::SUCCESS_OPERATOR_MEETING_CREATE => "Termin mit Betreiber wurde erfolgreich angelegt.",
self::SUCCESS_OPERATOR_MEETING_EDIT => "Termin mit Betreiber wurde erfolgreich geändert.",
self::SUCCESS_OPERATOR_MEETING_DELETE => "Termin mit Betreiber wurde erfolgreich gelöscht.",
self::SUCCESS_OPERATOR_MEETING_REPORT_SET => "Report für Termin mit Betreiber wurde erfolgreich bearbeitet.",
self::SUCCESS_OPERATOR_NOTE_CREATE => "Notiz für Betreiber wurde erfolgreich angelegt.",
self::SUCCESS_OPERATOR_NOTE_EDIT => "Notiz für Betreiber wurde erfolgreich geändert.",
self::SUCCESS_OPERATOR_NOTE_DELETE => "Notiz für Betreiber wurde erfolgreich gelöscht.",
self::SUCCESS_PRODUCTION_CREATE => "Produzent wurde erfolgreich angelegt.",
self::SUCCESS_PRODUCTION_EDIT => "Produzent wurde erfolgreich geändert.",
self::SUCCESS_PRODUCTION_CONTACT_CREATE => "Ansprechpartner von Produzent wurde erfolgreich angelegt.",
self::SUCCESS_PRODUCTION_CONTACT_EDIT => "Ansprechpartner von Produzent wurde erfolgreich geändert.",
self::SUCCESS_PRODUCTION_CONTACT_DELETE => "Ansprechpartner von Produzent wurde erfolgreich gelöscht.",
self::SUCCESS_PRODUCTION_MEETING_CREATE => "Termin mit Produzent wurde erfolgreich angelegt.",
self::SUCCESS_PRODUCTION_MEETING_EDIT => "Termin mit Produzent wurde erfolgreich geändert.",
self::SUCCESS_PRODUCTION_MEETING_DELETE => "Termin mit Produzent wurde erfolgreich gelöscht.",
self::SUCCESS_PRODUCTION_MEETING_REPORT_SET => "Report für Termin mit Produzent wurde erfolgreich bearbeitet.",
self::SUCCESS_PRODUCTION_NOTE_CREATE => "Notiz für Produzent wurde erfolgreich angelegt.",
self::SUCCESS_PRODUCTION_NOTE_EDIT => "Notiz für Produzent wurde erfolgreich geändert.",
self::SUCCESS_PRODUCTION_NOTE_DELETE => "Notiz für Produzent wurde erfolgreich gelöscht.",
self::SUCCESS_SERVICE_CREATE => "Service-Dienstleister wurde erfolgreich angelegt.",
self::SUCCESS_SERVICE_EDIT => "Service-Dienstleister wurde erfolgreich geändert.",
self::SUCCESS_SERVICE_CONTACT_CREATE => "Ansprechpartner von Service-Dienstleister wurde erfolgreich angelegt.",
self::SUCCESS_SERVICE_CONTACT_EDIT => "Ansprechpartner von Service-Dienstleister wurde erfolgreich geändert.",
self::SUCCESS_SERVICE_CONTACT_DELETE => "Ansprechpartner von Service-Dienstleister wurde erfolgreich gelöscht.",
self::SUCCESS_SERVICE_MEETING_CREATE => "Termin mit Service-Dienstleister wurde erfolgreich angelegt.",
self::SUCCESS_SERVICE_MEETING_EDIT => "Termin mit Service-Dienstleister wurde erfolgreich geändert.",
self::SUCCESS_SERVICE_MEETING_DELETE => "Termin mit Service-Dienstleister wurde erfolgreich gelöscht.",
self::SUCCESS_SERVICE_MEETING_REPORT_SET => "Report für Termin mit Service-Dienstleister wurde erfolgreich bearbeitet.",
self::SUCCESS_SERVICE_NOTE_CREATE => "Notiz für Service-Dienstleister wurde erfolgreich angelegt.",
self::SUCCESS_SERVICE_NOTE_EDIT => "Notiz für Service-Dienstleister wurde erfolgreich geändert.",
self::SUCCESS_SERVICE_NOTE_DELETE => "Notiz für Service-Dienstleister wurde erfolgreich gelöscht.",
];
// Error messages

// Info messages
public static $infoMessages = [
self::INFO_DATA_UNKNOWN => "Ein oder mehrere gefundene(r) Wert(e) sind unbekannt oder fehlerhaft und wurden zurückgesetzt. Bitte überprüfen Sie Ihre Eingaben.",
];

/**
* Returns success message
* @param null $successCode
* @return mixed|string
*/
public static function getSuccessMessage($successCode = null)
{
if ($successCode == self::SUCCESS_NONE) {
return null;
}
if (is_null($successCode) || !array_key_exists($successCode, self::$successMessages)) {
return self::SUCCESS_DEFAULT;
} else {
return self::$successMessages[$successCode];
}
}

/**
* Returns error message
* @param null $errorCode
* @return mixed|string
*/
public static function getErrorMessage($errorCode = null)
{
if (is_null($errorCode) || !array_key_exists($errorCode, self::$errorMessages)) {
return self::ERROR_DEFAULT;
} else {
return self::$errorMessages[$errorCode];
}
}

/**
* Returns info message
* @param null $infoCode
* @return mixed|string
*/
public static function getInfoMessage($infoCode = null)
{
if ($infoCode == self::INFO_NONE) {
return null;
}
if (is_null($infoCode) || !array_key_exists($infoCode, self::$infoMessages)) {
return self::INFO_DEFAULT;
} else {
return self::$infoMessages[$infoCode];
}
}
}

+ 185
- 0
httpdocs/src/Utils/Reply.php Прегледај датотеку

@@ -0,0 +1,185 @@
<?php
/**
* Created by PhpStorm.
* User: danielknudsen
* Date: 03.05.18
* Time: 16:43
*/

namespace App\Utils;

use App\EntityVirtual\ServiceData;
use Onurb\Bundle\ExcelBundle\Factory\ExcelFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;

class Reply
{
/**
* Returns a json response object containing the actual result and some optional service cache data
* @param $result
* @param int $success
* @param int $info
* @param ServiceData|null $serviceData
* @return JsonResponse
*/
public static function getResponse($result, $success = 0, $info = 0, ServiceData $serviceData = null)
{
$res = [
'result_data' => $result,
'success_code' => $success,
'success_msg' => Message::getSuccessMessage($success),
'info_code' => $info,
'info_msg' => Message::getInfoMessage($info),
'service_data' => !is_null($serviceData) ? $serviceData->getServiceData() : null,
];
return new JsonResponse($res);
}

/**
* Returns error response according to error code
* @param string $error
* @param null $optionalInfo
* @return JsonResponse
*/
public static function getErrorResponse($error = null, $optionalInfo = null)
{
$res = [
'error_code' => $error,
'error_msg' => Message::getErrorMessage($error),
'optional_info' => $optionalInfo
];

return new JsonResponse($res, 419);
}

/**
* Returns file as response
* @param $filePath
* @param $fileName
* @return Response
*/
public static function getFileResponse($filePath, $fileName, $zipped = false)
{
$response = new Response(file_get_contents($filePath . $fileName));
if ($zipped) {
$response->headers->set('Content-Type', 'application/zip');
} else {
$response->headers->set('Content-Type', 'application/octet-stream');
}
$response->headers->set('Content-Disposition', 'attachment;filename="' . $fileName . '"');
$response->headers->set('Content-Transfer-Encoding','binary');
$response->headers->set('Expires', '0');
$response->headers->set('Cache-Control', 'must-revalidate, post-check=0, pre-check=0');
$response->headers->set('Pragma', 'public');
$response->headers->set('Content-length', filesize($filePath . $fileName));

return $response;
}

/**
* Creates a file response with temporary file (not in filesystem)
* @param $fileObject
* @param string $fileName
* @return Response
*/
public static function getSteamedFileResponse($fileObject, $fileName = "")
{
$response = new Response($fileObject);
$response->headers->set('Content-Type', 'application/octet-stream');
$response->headers->set('Content-Disposition', 'attachment;filename="' . $fileName . '"');
$response->headers->set('Content-Transfer-Encoding','binary');
$response->headers->set('Expires', '0');
$response->headers->set('Cache-Control', 'must-revalidate, post-check=0, pre-check=0');
$response->headers->set('Pragma', 'public');
return $response;
}

/**
* @param Spreadsheet $phpSpreadsheet
* @param Xlsx $writer
* @param $filePath
* @param $fileName
* @param $zipped
* @param $fileNameWithDate
* @return Response|StreamedResponse
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
*/
public static function getExcelResponse(Spreadsheet $phpSpreadsheet, Xlsx $writer, $filePath, $fileName, $zipped = false, $fileNameWithDate = true)
{
if (!file_exists($filePath)) {
mkdir($filePath, 0777, true);
}

$date = date('Y-m-d');
$outputFilename = ($fileNameWithDate ? $date : "") . '_' . $fileName . '.xlsx';
if (!$zipped) {
// Just plain excel file
$headers = array(
'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8',
'Content-Disposition' => 'attachment; filename=' . $outputFilename,
'Content-Description' => 'File Transfer',
'Pragma' => 'public',
'Expires' => '0',
'Accept-Ranges' => 'bytes',
'Content-Transfer-Encoding' => 'binary',
'Cache-Control' => 'maxage=1'
);
// Return excel as blob file response
$response = new StreamedResponse(
function () use ($writer) {
$writer->save('php://output');
},
200,
$headers
);

} else {
// Return zip file
// Save file temporarily
$writer->save($filePath . $outputFilename);

$files[] = [
'filePath' => $filePath,
'fileName' => $outputFilename
];

$response = self::getZippedFileResponse($filePath, $outputFilename, $files);

// Delete file
unlink($filePath . $outputFilename);
}
return $response;
}

/**
* Returns zipped response of given files
* @param $zipFilePath
* @param $zipFileName
* @param $files
* @param bool $deleteZip
* @param bool $deleteFiles
* @return Response
*/
public static function getZippedFileResponse($zipFilePath, $zipFileName, $files, $deleteZip = false, $deleteFiles = false)
{
$resZipFileName = Utils::createZipFile($zipFilePath, $zipFileName, $files);
$response = self::getFileResponse($zipFilePath, $resZipFileName);

if ($deleteZip) {
unlink($zipFilePath . $resZipFileName);
}

if ($deleteFiles) {
foreach ($files as $file2) {
unlink($file2['filePath'] . $file2['fileName']);
}
}
return $response;
}


}

+ 610
- 0
httpdocs/src/Utils/Utils.php Прегледај датотеку

@@ -0,0 +1,610 @@
<?php
/**
* Created by PhpStorm.
* User: danielknudsen
* Date: 03.05.18
* Time: 16:43
*/

namespace App\Utils;


use App\Entity\IFace\IEntity;
use Doctrine\DBAL\DriverManager;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
use function Couchbase\defaultDecoder;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\HttpFoundation\File\UploadedFile;

class Utils
{
// Environments
const ENV_DEV = "dev";
const ENV_BETA = "beta";
const ENV_GAMMA = "gamma";

// Password length
const PASSWORD_MIN_LENGTH = 5;
const PASSWORD_MAX_LENGTH = 50;

// Image formats
const IMAGE_FORMAT_JPG = "jpg";
const IMAGE_FORMAT_JPEG = "jpeg";
const IMAGE_FORMAT_PNG = "png";
const IMAGE_FORMAT_GIF = "gif";
const IMAGE_FORMAT_BMP = "bmp";

// Max image width
const MAX_IMAGE_WIDTH = 300;

// Genders
const GENDER_MALE = 'male';
const GENDER_FEMALE = 'female';
const GENDER_DIVERSE = 'diverse';

const GENDER_MALE_TRANSLATED = 'Herr';
const GENDER_FEMALE_TRANSLATED = 'Frau';
const GENDER_DIVERSE_TRANSLATED = 'Divers';

// const HOST_URL = "";
// const MASTER_PW = "";
// const ADMIN_USER = "";
const ADMIN_EMAIL = "admin@plp-tool.de";
const SYS_EMAIL = "reminder@plp-tool.de";
const ADMIN_EMAIL_BETA = "re@spawntree.de";
const SYS_EMAIL_BETA = "reminder-beta@plp-tool.de";



public static $validImageFormats = array(
self::IMAGE_FORMAT_JPG, self::IMAGE_FORMAT_JPEG,
self::IMAGE_FORMAT_PNG, self::IMAGE_FORMAT_GIF, self::IMAGE_FORMAT_BMP);

/**
* Checks is given value is int value
* @param $value
* @return bool
*/
public static function isIntValue($value)
{
return filter_var(intval($value), FILTER_VALIDATE_INT) !== false;
}

/**
* Checks is given value is float value
* @param $value
* @return mixed
*/
public static function isFloatValue($value)
{
return filter_var(str_replace(",", ".", floatval($value)), FILTER_VALIDATE_FLOAT) !== false;
}

/**
* Returns float value and replaces "," if given by client
* @param $value
* @return float
*/
public static function getFloatValue($value)
{
//return floatval(str_replace(',', '.', str_replace('.', '', $value)));
return floatval(str_replace(",", ".", $value));
}

/**
* Converts number to float in german format
* @param $value
* @param int $digits
* @return string
*/
public static function getGermanFloat($value, $digits = 2)
{
return number_format($value, $digits, ',', '.');
}

/**
* Checks is given value is int value
* @param $value
* @return mixed
*/
public static function isBoolValue($value)
{
return filter_var($value, FILTER_VALIDATE_BOOLEAN);
}

/**
* Checks email format
* @param $email
* @return bool
*/
public static function isValidEmail($email)
{
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}

/**
* Checks if valid gender
* @param $gender
* @return bool
*/
public static function isValidGender($gender)
{
return $gender == self::GENDER_MALE || $gender == self::GENDER_FEMALE || $gender == self::GENDER_DIVERSE;
}

/**
* Checks if an email exists in users, persons or locations
* @param ObjectManager $em
* @param $email
* @return bool
*/
public static function emailUserExists(ObjectManager $em, $email)
{
$existingUserEmail = $em->getRepository('App:EntUser')->findOneBy(['email' => $email]);
return !is_null($existingUserEmail);
}

/**
* Validates email and checks existence
* @param ObjectManager $em
* @param $email
* @return bool
*/
public static function validateEmail(ObjectManager $em, $email)
{
return self::isValidEmail($email) && !self::emailUserExists($em, $email);
}

/**
* Checks if uploaded file is an excel file
* @param UploadedFile $uploadedFile
* @return bool
*/
public static function isExcelFile(UploadedFile $uploadedFile)
{
// Check client mime type
return $uploadedFile->getClientMimeType() == 'application/vnd.ms-excel' ||
$uploadedFile->getClientMimeType() == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
}

/**
* Checks length of password
* @param $password
* @return bool
*/
public static function isValidPasswordLength($password)
{
return strlen($password) >= self::PASSWORD_MIN_LENGTH &&
strlen($password) <= self::PASSWORD_MAX_LENGTH;
}

/**
* Returns sorted array by getter name
* @param $getterName
* @param $arr
* @return array
*/
public static function getSortedObjects($getterName, $arr)
{
$res = [];
foreach ($arr as $item) {
$res[$item->{$getterName}()] = $item;
}
return $res;
}

/**
* Returns sorted array by getter name
* @param $arr
* @return array
*/
public static function getSortedObjectsById($arr)
{
return self::getSortedObjects('getId', $arr);
}

/**
* Returns sorted array by getter name
* @param $firstGetterName
* @param $secondGetterName
* @param $arr
* @return array
*/
public static function getSortedMultipleObjects($firstGetterName, $secondGetterName, $arr)
{
$res = [];
foreach ($arr as $item) {
$res[$item->{$firstGetterName}()][$item->{$secondGetterName}()] = $item;
}
return $res;
}

/**
* Returns sorted array by key
* @param $key
* @param $arr
* @return array
*/
public static function getSortedArray($key, $arr)
{
$res = [];
foreach ($arr as $item) {
$res[$item[$key]] = $item;
}
return $res;
}

/**
* Returns inverted array (values are keys)
* @param $arr
* @return array
*/
public static function getInvertedArray($arr)
{
$res = [];
foreach ($arr as $key => $value) {
$res[$value] = $key;
}
return $res;
}

public static function getGermanDateTime(\DateTime $dateTime = null)
{
if (is_null($dateTime)) {
$dateTime = new \DateTime();
}
$localTimeZone = new \DateTimeZone('Europe/Berlin');
$dateTime->setTimezone($localTimeZone);
return $dateTime;
}

/**
* Returns array of client mappable items
* @param ObjectManager $em
* @param $arr
* @param bool $fullMapping
* @return array
*/
public static function clientMap(ObjectManager $em, $arr, $fullMapping = false)
{
$res = [];
foreach ($arr as $key => $value) {

if (!$value instanceof IEntity) {
throw new Exception("Items must implement IEntity");
}
$res[] = $value->clientMapper($em, $fullMapping);

}
return $res;
}

/**
* Returns array with file path info
* @param $filePath
* @param $fileName
* @return array
*/
public static function getFilePathArray($filePath, $fileName)
{
return [
'filePath' => $filePath,
'fileName' => $fileName
];
}

/**
* Creates a zip file of given files
* @param $zipFilePath
* @param $zipFileName
* @param $files
* @return string
*/
public static function createZipFile($zipFilePath, $zipFileName, $files)
{
$zip = new \ZipArchive();
$zipFileName .= ".zip";

$zip->open($zipFilePath . $zipFileName, \ZipArchive::CREATE);
foreach ($files as $file) {
$zip->addFromString(basename($file['filePath'] . $file['fileName']), file_get_contents($file['filePath'] . $file['fileName']));
}
$zip->close();
return $zipFileName;
}

/**
* Creates a zip file from folder and optionally excluded files
* @param $zipFilePath
* @param $zipFileName
* @param array $skippedFileNames
* @param bool $includeZipPathFolder
*/
public static function createZipFileFromFolder($zipFilePath, $zipFileName, $skippedFileNames = [], $includeZipPathFolder = false)
{
$skippedFileNamesByName = Utils::getInvertedArray($skippedFileNames);

// Initialize archive object
$zip = new \ZipArchive();
$zip->open($zipFilePath.$zipFileName.'.zip', \ZipArchive::CREATE | \ZipArchive::OVERWRITE);

// Create recursive directory iterator
/** @var \SplFileInfo[] $files */
$files = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($zipFilePath),
\RecursiveIteratorIterator::LEAVES_ONLY
);

$folderSuffix = "";
if ($includeZipPathFolder) {
$zipFilePathParts = explode('/', $zipFilePath);
$folderSuffix = $zipFilePathParts[count($zipFilePathParts)-2]."/";
}

foreach ($files as $name => $file)
{
// Skip directories (they would be added automatically)
if (!$file->isDir())
{
// Get real and relative path for current file
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen($zipFilePath));
$relativePathParts = explode('/', $relativePath);
$fileName = $relativePathParts[count($relativePathParts)-1];

if (!array_key_exists($fileName, $skippedFileNamesByName)) {
// Add current file to archive
$zip->addFile($filePath, $folderSuffix.$relativePath);
}
}
}

// Zip archive will be created only after closing object
$zip->close();
}

/**
* Checks file size of uploaded file
*/
public static function checkUploadedFileSize()
{
foreach ($_FILES as $filename => $file) {
if ($file['error'] == 1) {
return false;
}
}
return true;
}

/**
* Checks if given file has valid image format
* @param UploadedFile $imgFile
* @return bool
*/
public static function isValidImageFile(UploadedFile $imgFile)
{
return in_array(strtolower($imgFile->getClientOriginalExtension()), self::$validImageFormats);
}

/**
* @param UploadedFile $imgFile
* @param $path
* @param $filename
* @param $assetDir
*/
public static function saveResizedImage(UploadedFile $imgFile, $path, $filename, $assetDir)
{
if (!self::isValidImageFile($imgFile)) {
throw new Exception('invalid image file format');
}

// Save file temporarily
$tmpFilePath = $assetDir. '/tmp/';
$imgFile->move($tmpFilePath, $filename);

// Calc new dimension
list($width, $height) = getimagesize($tmpFilePath.$filename);
$ratio = $width / $height;

$newWidth = self::MAX_IMAGE_WIDTH;
$newHeight = $newWidth / $ratio;

$source = null;
$thumb = imagecreatetruecolor($newWidth, $newHeight);
switch (strtolower($imgFile->getClientOriginalExtension())) {
case self::IMAGE_FORMAT_JPG:
case self::IMAGE_FORMAT_JPEG:
$source = imagecreatefromjpeg($tmpFilePath.$filename);
imagecopyresized($thumb, $source, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
imagejpeg($thumb);
break;
case self::IMAGE_FORMAT_PNG:
$source = imagecreatefrompng($tmpFilePath.$filename);
imagecopyresized($thumb, $source, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
imagepng($thumb, $path.$filename);
break;
case self::IMAGE_FORMAT_GIF:
$source = imagecreatefromgif($tmpFilePath.$filename);
imagecopyresized($thumb, $source, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
break;
case self::IMAGE_FORMAT_BMP:
$source = imagecreatefromwbmp($tmpFilePath.$filename);
imagecopyresized($thumb, $source, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
break;
default:
throw new Exception("Invalid file type");
}

// Remove temporary file
unlink($tmpFilePath.$filename);
}

/**
* Copies a folder recursively
* @param $sourcPath
* @param $destinationPath
*/
public static function copyFolderRecursively($sourcPath, $destinationPath)
{
$dir = opendir($sourcPath);
@mkdir($destinationPath);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($sourcPath . '/' . $file) ) {
self::copyFolderRecursively($sourcPath . '/' . $file,$destinationPath . '/' . $file);
}
else {
copy($sourcPath . '/' . $file,$destinationPath . '/' . $file);
}
}
}
closedir($dir);
}

/**
* Deletes directory with contained files
* @param $dirPath
*/
public static function deleteDirectory($dirPath) {
$dir = opendir($dirPath);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
$full = $dirPath . '/' . $file;
if ( is_dir($full) ) {
self::deleteDirectory($full);
}
else {
unlink($full);
}
}
}
closedir($dir);
rmdir($dirPath);
}

/**
* Checks if a process is already running
* @param $processName
* @return bool
*/
public static function checkOnRunningProcess($processName)
{
$processCount = 0;
exec("ps aux | grep -i ".$processName, $pids);
foreach ($pids as $pid) {
if (strpos($pid, "bin/console ".$processName) !== false) {
$processCount++;
}
}
// If process is running, there will be two instances (running process and the one that just started!)
return $processCount > 1;
}

/**
* Returns gender value from translated gender
* @param $gender
* @return string
*/
public static function getGenderFromTranslatedGender($gender)
{
switch ($gender) {
case Utils::GENDER_MALE_TRANSLATED:
return Utils::GENDER_MALE;
break;
case Utils::GENDER_FEMALE_TRANSLATED:
return Utils::GENDER_FEMALE;
break;
default:
return Utils::GENDER_DIVERSE;
}
}

/**
* Returns translated gender
* @param $gender
* @return string
*/
public static function getTranslatedGender($gender)
{
switch ($gender) {
case Utils::GENDER_MALE:
return Utils::GENDER_MALE_TRANSLATED;
break;
case Utils::GENDER_FEMALE:
return Utils::GENDER_FEMALE_TRANSLATED;
break;
default:
return Utils::GENDER_DIVERSE_TRANSLATED;
}
}

/**
* Sends mail depending on environment
* @param MailerInterface $mailer
* @param $subject
* @param $emailAddress
* @param $body
* @param $environment
*/
public static function sendMail(MailerInterface $mailer, $subject, $emailAddress, $body, $environment)
{
$sendFrom = Utils::SYS_EMAIL;
if ($environment === Utils::ENV_DEV || $environment === Utils::ENV_BETA) {
$emailAddress = self::ADMIN_EMAIL_BETA;
$sendFrom = $environment == Utils::ENV_DEV ? self::ADMIN_EMAIL_BETA : self::SYS_EMAIL_BETA;
}

// Send Email to target from admin / sys mail
$email = (new Email())
->from($sendFrom)
->to($emailAddress)
//->cc('cc@example.com')
//->bcc('bcc@example.com')
//->replyTo('fabien@example.com')
//->priority(Email::PRIORITY_HIGH)
->subject($subject)
->text('Sending emails is fun again!')
->html($body);

$mailer->send($email);
}

/**
* Returns db connection to old database depending on environment
* @param $environment
* @return \Doctrine\DBAL\Connection
* @throws \Doctrine\DBAL\DBALException
*/
public static function getOldDbConnection($environment)
{
$dbConnectionParams = null;
switch($environment) {
case self::ENV_DEV:
$dbConnectionParams = array(
'dbname' => 'plpp',
'user' => 'root',
'password' => '',
'host' => '127.0.0.1',
'driver' => 'pdo_mysql',
);
break;
case self::ENV_BETA:
case self::ENV_GAMMA:
$dbConnectionParams = array(
'dbname' => 'plpp',
'user' => 'plp',
'password' => 'Ba06TH%dG,7f',
'host' => '127.0.0.1',
'driver' => 'pdo_mysql',
);
break;
default:
throw new Exception('unknown environment');
}
$dbHandle = DriverManager::getConnection($dbConnectionParams);
$dbHandle->query("SET NAMES 'utf8'");
return $dbHandle;
}
}

+ 130
- 0
httpdocs/symfony.lock Прегледај датотеку

@@ -0,0 +1,130 @@
{
"doctrine/annotations": {
"version": "2.0",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "1.10",
"ref": "64d8583af5ea57b7afa4aba4b159907f3a148b05"
}
},
"doctrine/doctrine-bundle": {
"version": "2.9",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "2.8",
"ref": "67961f095352f829a24c035639b3d0d3378ffbf2"
},
"files": [
"config/packages/doctrine.yaml",
"src/Entity/.gitignore",
"src/Repository/.gitignore"
]
},
"doctrine/doctrine-migrations-bundle": {
"version": "3.2",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "3.1",
"ref": "1d01ec03c6ecbd67c3375c5478c9a423ae5d6a33"
},
"files": [
"config/packages/doctrine_migrations.yaml",
"migrations/.gitignore"
]
},
"sensio/framework-extra-bundle": {
"version": "6.2",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "5.2",
"ref": "fb7e19da7f013d0d422fa9bce16f5c510e27609b"
},
"files": [
"config/packages/sensio_framework_extra.yaml"
]
},
"symfony/console": {
"version": "6.2",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "5.3",
"ref": "da0c8be8157600ad34f10ff0c9cc91232522e047"
},
"files": [
"bin/console"
]
},
"symfony/flex": {
"version": "2.2",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "1.0",
"ref": "146251ae39e06a95be0fe3d13c807bcf3938b172"
},
"files": [
".env"
]
},
"symfony/framework-bundle": {
"version": "6.2",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "6.2",
"ref": "af47254c5e4cd543e6af3e4508298ffebbdaddd3"
},
"files": [
"config/packages/cache.yaml",
"config/packages/framework.yaml",
"config/preload.php",
"config/routes/framework.yaml",
"config/services.yaml",
"public/index.php",
"src/Controller/.gitignore",
"src/Kernel.php"
]
},
"symfony/mailer": {
"version": "6.2",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "4.3",
"ref": "2bf89438209656b85b9a49238c4467bff1b1f939"
},
"files": [
"config/packages/mailer.yaml"
]
},
"symfony/routing": {
"version": "6.2",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "6.2",
"ref": "e0a11b4ccb8c9e70b574ff5ad3dfdcd41dec5aa6"
},
"files": [
"config/packages/routing.yaml",
"config/routes.yaml"
]
},
"symfony/security-bundle": {
"version": "6.2",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "6.0",
"ref": "8a5b112826f7d3d5b07027f93786ae11a1c7de48"
},
"files": [
"config/packages/security.yaml"
]
}
}

+ 12
- 0
httpdocs/templates/base.html.twig Прегледај датотеку

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title>
{% block stylesheets %}{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
{% block javascripts %}{% endblock %}
</body>
</html>

+ 46
- 0
httpdocs/templates/contacts_export.html.twig Прегледај датотеку

@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
<style>
@page {margin-bottom: 0;}
body {margin: 0;padding: 0;}
table {width: 100%;page-break-after: always;}
td {width: 50%;padding-top: 12px;}
p, tr, td, table {padding: 0;margin: 0;font-family: Arial, Verdana, sans-serif;font-size: 10px;line-height: 19px;border:0;}
tr, td, table {vertical-align: top;text-align: left;}
div {overflow:hidden;height: 148px;}
span {font-size: 8px;line-height: 10px;padding: 0 0 0 15px;}
p {padding: 5px 0 0 15px;}
td:nth-child(2) span,
td:nth-child(2) p {padding-left: 45px;}
</style>
</head>
<body>
<table width="100%" class="addresses" cellpadding="0" cellspacing="0" border="0">
<tr>
<th>Firma</th>
<th>Name</th>
<th>Email</th>
<th>Straße</th>
<th>Ort</th>
<th>Abteilung</th>
<th>Telefon</th>
<th>Mobil</th>
</tr>
{% for key, value in data %}
<tr>
<td>{{ value.company }}</td>
<td>{{ value.firstname }} {{ value.lastname }}</td>
<td>{{ value.email }}</td>
<td>{{ value.street }} {{ value.street_no }}</td>
<td>{{ value.zip }} {{ value.city }}</td>
<td>{{ value.department }}</td>
<td>{{ value.phone_no }}</td>
<td>{{ value.mobile_no }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>

+ 46
- 0
httpdocs/templates/xmas_addresses.html.twig Прегледај датотеку

@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Weihnachtspost Etiketten</title>
<style>
@page {margin-bottom: 0;}
body {margin: 0;padding: 0;}
table {width: 100%;page-break-after: always;}
td {width: 50%;padding-top: 12px;}
p, tr, td, table {padding: 0;margin: 0;font-family: Arial, Verdana, sans-serif;font-size: 14px;line-height: 19px;border:0;}
tr, td, table {vertical-align: top;text-align: left;}
div {overflow:hidden;height: 148px;}
span {font-size: 8px;line-height: 10px;padding: 0 0 0 15px;}
p {padding: 5px 0 0 15px;}
td:nth-child(2) span,
td:nth-child(2) p {padding-left: 45px;}
</style>
</head>
<body>
{% for key, value in data %}
{% if key == 0 or key % 14 == 0 %}
<table width="100%" class="addresses" cellpadding="0" cellspacing="0" border="0">
{% endif %}
{% if key % 2 == 0 %}
<tr>
{% endif %}
<td>
<div>
<span>PLP Parkhauswerbung GmbH | Siemensstraße 19 | 40721 Hilden</span>
<p>{{ value.firstname }} {{ value.lastname }}<br />
<em>{{ value.company }}</em></p>
<p>{{ value.street }} {{ value.street_no }}<br />
<strong>{{ value.zip }} {{ value.city }}</strong><br />
{{ value.country }}</p>
</div>
</td>
{% if key % 2 != 0 %}
</tr>
{% endif %}
{% if (key + 1) % 14 == 0 or data|length == key + 1 %}
</table>
{% endif %}
{% endfor %}
</body>
</html>

Loading…
Откажи
Сачувај