├── .env
├── .env.test
├── .gitignore
├── .php-cs-fixer.dist.php
├── README.md
├── bin
└── console
├── composer.json
├── composer.lock
├── config
├── bundles.php
├── packages
│ ├── cache.yaml
│ ├── doctrine.yaml
│ ├── doctrine_migrations.yaml
│ ├── features_flag.yaml
│ ├── framework.yaml
│ ├── prod
│ │ └── doctrine.yaml
│ ├── routing.yaml
│ └── test
│ │ ├── dama_doctrine_test_bundle.yaml
│ │ └── doctrine.yaml
├── preload.php
├── routes.yaml
├── routes
│ ├── annotations.yaml
│ └── framework.yaml
├── services.yaml
└── services_test.yaml
├── docker-compose.override.yml
├── docker-compose.yml
├── docs
└── xstate.js
├── migrations
├── Version20220121160323.php
├── Version20220123120851.php
├── Version20220123224330.php
├── Version20220209194742.php
├── Version20220210152256.php
├── Version20220210184450.php
├── Version20220211204206.php
├── Version20220212082639.php
├── Version20220212164138.php
├── Version20220303185743.php
├── Version20220326082730.php
├── Version20220327203954.php
├── Version20220407185153.php
├── Version20220414204404.php
├── Version20220418190006.php
├── Version20220418223109.php
├── Version20220419063121.php
├── Version20220419070117.php
└── Version20220420061415.php
├── phpunit.xml.dist
├── public
└── index.php
├── src
├── Agreements
│ ├── Contract.php
│ ├── ContractAttachment.php
│ ├── ContractAttachmentDTO.php
│ ├── ContractAttachmentData.php
│ ├── ContractAttachmentDataRepository.php
│ ├── ContractController.php
│ ├── ContractDTO.php
│ ├── ContractRepository.php
│ └── ContractService.php
├── Assignment
│ ├── AssignmentStatus.php
│ ├── DriverAssignment.php
│ ├── DriverAssignmentFacade.php
│ ├── DriverAssignmentRepository.php
│ └── InvolvedDriversSummary.php
├── CarFleet
│ ├── CarType.php
│ ├── CarTypeActiveCounter.php
│ ├── CarTypeActiveCounterRepository.php
│ ├── CarTypeController.php
│ ├── CarTypeDTO.php
│ ├── CarTypeRepository.php
│ └── CarTypeService.php
├── Common
│ ├── BaseEntity.php
│ ├── Clock.php
│ ├── DTOArgumentResolver.php
│ ├── ObjectHash.php
│ ├── RequestTransactionSubscriber.php
│ └── SystemClock.php
├── Config
│ ├── AppProperties.php
│ └── Neo4jClientFactory.php
├── Contracts
│ ├── Application
│ │ ├── Acme
│ │ │ ├── Dynamic
│ │ │ │ ├── DocumentOperationResult.php
│ │ │ │ └── DocumentResourceManager.php
│ │ │ └── Straigthforward
│ │ │ │ ├── AcmeContractProcessBasedOnStraightforwardDocumentModel.php
│ │ │ │ ├── AcmeStateFactory.php
│ │ │ │ └── ContractResult.php
│ │ └── Editor
│ │ │ ├── CommitResult.php
│ │ │ ├── DocumentDTO.php
│ │ │ └── DocumentEditor.php
│ ├── Infra
│ │ └── DoctrineDocumentHeaderRepository.php
│ ├── Legacy
│ │ ├── BaseAggregateRoot.php
│ │ ├── Contract2.php
│ │ ├── Document.php
│ │ ├── DocumentStatus.php
│ │ ├── OOParadigm.php
│ │ ├── Printable.php
│ │ ├── UnsupportedTransitionException.php
│ │ ├── User.php
│ │ ├── UserRepository.php
│ │ └── Versionable.php
│ └── Model
│ │ ├── Content
│ │ ├── ContentVersion.php
│ │ ├── DocumentContent.php
│ │ ├── DocumentContentRepository.php
│ │ └── DocumentNumber.php
│ │ ├── ContentId.php
│ │ ├── DocumentHeader.php
│ │ ├── DocumentHeaderRepository.php
│ │ └── State
│ │ ├── Dynamic
│ │ ├── Acme
│ │ │ └── AcmeContractStateAssembler.php
│ │ ├── ChangeCommand.php
│ │ ├── Config
│ │ │ ├── Actions
│ │ │ │ ├── Action.php
│ │ │ │ ├── ChangeVerifier.php
│ │ │ │ └── PublishEvent.php
│ │ │ ├── Events
│ │ │ │ ├── DocumentEvent.php
│ │ │ │ ├── DocumentPublished.php
│ │ │ │ └── DocumentUnpublished.php
│ │ │ └── Predicates
│ │ │ │ ├── ContentChange
│ │ │ │ ├── NegativePredicate.php
│ │ │ │ ├── PositivePredicate.php
│ │ │ │ └── Predicate.php
│ │ │ │ └── StateChange
│ │ │ │ ├── AuthorIsNotAVerifier.php
│ │ │ │ ├── ContentNotEmptyVerifier.php
│ │ │ │ ├── PositiveVerifier.php
│ │ │ │ ├── Predicate.php
│ │ │ │ └── PreviousStateVerifier.php
│ │ ├── State.php
│ │ ├── StateBuilder.php
│ │ └── StateConfig.php
│ │ └── Straightforward
│ │ ├── Acme
│ │ ├── ArchivedState.php
│ │ ├── DraftState.php
│ │ ├── PublishedState.php
│ │ └── VerifiedState.php
│ │ └── BaseState.php
├── Crm
│ ├── Claims
│ │ ├── Claim.php
│ │ ├── ClaimAttachment.php
│ │ ├── ClaimAttachmentRepository.php
│ │ ├── ClaimController.php
│ │ ├── ClaimDTO.php
│ │ ├── ClaimNumberGenerator.php
│ │ ├── ClaimRepository.php
│ │ ├── ClaimResolver
│ │ │ └── Result.php
│ │ ├── ClaimService.php
│ │ ├── ClaimsResolver.php
│ │ └── ClaimsResolverRepository.php
│ ├── Client.php
│ ├── ClientController.php
│ ├── ClientDTO.php
│ ├── ClientRepository.php
│ ├── ClientService.php
│ └── TransitAnalyzer
│ │ ├── AnalyzedAddressesDTO.php
│ │ ├── GraphTransitAnalyzer.php
│ │ ├── PopulateGraphService.php
│ │ └── TransitAnalyzerController.php
├── DriverFleet
│ ├── Driver.php
│ ├── DriverAttribute.php
│ ├── DriverAttributeDTO.php
│ ├── DriverAttributeRepository.php
│ ├── DriverController.php
│ ├── DriverDTO.php
│ ├── DriverFee.php
│ ├── DriverFeeRepository.php
│ ├── DriverFeeService.php
│ ├── DriverLicense.php
│ ├── DriverReport
│ │ ├── DriverReport.php
│ │ ├── DriverReportController.php
│ │ ├── SqlBasedDriverReportCreator.php
│ │ └── TravelledDistance
│ │ │ ├── TimeSlot.php
│ │ │ ├── TravelledDistance.php
│ │ │ ├── TravelledDistanceRepository.php
│ │ │ └── TravelledDistanceService.php
│ ├── DriverRepository.php
│ └── DriverService.php
├── Geolocation
│ ├── Address
│ │ ├── Address.php
│ │ ├── AddressDTO.php
│ │ └── AddressRepository.php
│ ├── Distance.php
│ ├── DistanceCalculator.php
│ ├── DistanceType.php
│ └── GeocodingService.php
├── Invocing
│ ├── Invoice.php
│ ├── InvoiceGenerator.php
│ └── InvoiceRepository.php
├── Kernel.php
├── Loyalty
│ ├── AwardedMiles.php
│ ├── AwardsAccount.php
│ ├── AwardsAccountController.php
│ ├── AwardsAccountDTO.php
│ ├── AwardsAccountRepository.php
│ ├── AwardsService.php
│ ├── AwardsServiceImpl.php
│ ├── ConstantUntil.php
│ ├── Miles.php
│ ├── MilesType.php
│ └── TwoStepExpiringMiles.php
├── Money
│ ├── Money.php
│ └── MoneyType.php
├── Notification
│ ├── ClientNotificationService.php
│ └── DriverNotificationService.php
├── Party
│ ├── Api
│ │ ├── PartyId.php
│ │ ├── PartyMapper.php
│ │ └── RoleObjectFactory.php
│ ├── Infra
│ │ ├── DoctrinePartyRelationshipRepository.php
│ │ └── DoctrinePartyRepository.php
│ └── Model
│ │ ├── Party
│ │ ├── Party.php
│ │ ├── PartyRelationship.php
│ │ ├── PartyRelationshipRepository.php
│ │ ├── PartyRepository.php
│ │ └── PartyRole.php
│ │ └── Role
│ │ └── PartyBasedRole.php
├── Pricing
│ ├── Tariff.php
│ └── Tariffs.php
├── Repair
│ ├── Api
│ │ ├── AssistanceRequest.php
│ │ ├── ContractManager.php
│ │ ├── RepairProcess.php
│ │ ├── RepairRequest.php
│ │ └── ResolveResult.php
│ ├── Legacy
│ │ ├── DAO
│ │ │ └── UserDAO.php
│ │ ├── Job
│ │ │ ├── CommonBaseAbstractJob.php
│ │ │ ├── JobResult.php
│ │ │ ├── MaintenanceJob.php
│ │ │ └── RepairJob.php
│ │ ├── Parts
│ │ │ └── Parts.php
│ │ ├── Service
│ │ │ └── JobDoer.php
│ │ └── User
│ │ │ ├── CommonBaseAbstractUser.php
│ │ │ ├── EmployeeDriver.php
│ │ │ ├── EmployeeDriverWithLeasedCar.php
│ │ │ ├── EmployeeDriverWithOwnCar.php
│ │ │ ├── SignedContract.php
│ │ │ ├── SubcontractorDriver.php
│ │ │ ├── SubcontractorDriverWithOwnCar.php
│ │ │ └── SubcontractorWithRentedCar.php
│ └── Model
│ │ ├── Dict
│ │ ├── PartyRelationshipsDictionary.php
│ │ └── PartyRolesDictionary.php
│ │ └── Roles
│ │ ├── Assistance
│ │ └── RoleForAssistance.php
│ │ ├── Blank
│ │ ├── Customer.php
│ │ └── Insured.php
│ │ └── Repair
│ │ ├── ExtendedInsurance.php
│ │ ├── RepairingResult.php
│ │ ├── RoleForRepairer.php
│ │ └── Warranty.php
├── Ride
│ ├── ChangeDestinationService.php
│ ├── ChangePickupService.php
│ ├── CompleteTransitService.php
│ ├── DemandService.php
│ ├── Details
│ │ ├── Status.php
│ │ ├── TransitDetails.php
│ │ ├── TransitDetailsDTO.php
│ │ ├── TransitDetailsFacade.php
│ │ └── TransitDetailsRepository.php
│ ├── Events
│ │ └── TransitCompleted.php
│ ├── RequestForTransit.php
│ ├── RequestForTransitRepository.php
│ ├── RequestTransitService.php
│ ├── RideService.php
│ ├── StartTransitService.php
│ ├── Transit.php
│ ├── TransitController.php
│ ├── TransitDTO.php
│ ├── TransitDemand.php
│ ├── TransitDemandRepository.php
│ └── TransitRepository.php
└── Tracking
│ ├── DriverPosition.php
│ ├── DriverPositionDTO.php
│ ├── DriverPositionDTOV2.php
│ ├── DriverPositionRepository.php
│ ├── DriverSession.php
│ ├── DriverSessionController.php
│ ├── DriverSessionDTO.php
│ ├── DriverSessionRepository.php
│ ├── DriverSessionService.php
│ ├── DriverTrackingController.php
│ └── DriverTrackingService.php
├── symfony.lock
└── tests
├── Common
├── AddressFixture.php
├── AwardsAccountFixture.php
├── CarTypeFixture.php
├── ClaimFixture.php
├── ClientFixture.php
├── DriverFixture.php
├── Factory.php
├── FixedClock.php
├── Fixtures.php
├── PrivateProperty.php
├── RideFixture.php
├── StubbedTransitPrice.php
└── TransitFixture.php
├── Double
├── FakeAppProperties.php
├── FakeGeocodingService.php
└── FakeTariffs.php
├── Integration
├── AnalyzeNearbyTransitsIntegrationTest.php
├── AwardMilesManagementIntegrationTest.php
├── CalculateDriverFeeIntegrationTest.php
├── CalculateDriverPeriodicPaymentsIntegrationTest.php
├── CalculateDriverTravelledDistanceIntegrationTest.php
├── CarTypeUpdateIntegrationTest.php
├── ClaimAutomaticResolvingIntegrationTest.php
├── ContractLifecycleIntegrationTest.php
├── Contracts
│ └── Application
│ │ └── Acme
│ │ ├── Dynamic
│ │ ├── AcmeContractManagerBasedOnDynamicStateModelTest.php
│ │ └── DocumentOperationResultAssert.php
│ │ └── Straightforward
│ │ ├── AcmeContractProcessBasedOnStraightforwardStateModelTest.php
│ │ └── ContractResultAssert.php
├── CreateDriverReportIntegrationTest.php
├── DriverTrackingServiceIntegrationTest.php
├── ExpiringMilesIntegrationTest.php
├── GraphTransitAnalyzerIntegrationTest.php
├── Neo4jTestCase.php
├── PopulateGraphServiceIntegrationTest.php
├── RemovingAwardMilesIntegrationTest.php
├── Repair
│ ├── RepairProcessTest.php
│ └── VehicleRepairAssert.php
├── TariffRecognizingIntegrationTest.php
├── TransitLifeCycleIntegrationTest.php
└── ValidateDriverLicenseIntegrationTest.php
├── Unit
├── Agreements
│ └── ContractLifecycleTest.php
├── Assigment
│ └── DriverAssignmentTest.php
├── Contracts
│ ├── Legacy
│ │ └── DocumentTest.php
│ └── Model
│ │ └── State
│ │ ├── Dynamic
│ │ ├── AcmeContractTest.php
│ │ └── FakeDocumentPublisher.php
│ │ └── Straightforward
│ │ └── AcmeContractTest.php
├── Distance
│ └── DistanceTest.php
├── Entity
│ ├── ClaimAutomaticResolvingTest.php
│ ├── DriverLicenseTest.php
│ ├── Miles
│ │ └── MilesTest.php
│ ├── TariffTest.php
│ └── TimeSlotTest.php
├── Money
│ └── MoneyTest.php
├── Pricing
│ └── CalculateTransitPriceTest.php
├── Repair
│ └── Legacy
│ │ ├── Job
│ │ └── RepairTest.php
│ │ └── Service
│ │ └── JobDoerTest.php
├── Ride
│ ├── RequestForTransitTest.php
│ ├── TransitDemandTest.php
│ └── TransitTest.php
└── Ui
│ └── CalculateTransitDistanceTest.php
└── bootstrap.php
/.env:
--------------------------------------------------------------------------------
1 | # In all environments, the following files are loaded if they exist,
2 | # the latter taking precedence over the former:
3 | #
4 | # * .env contains default values for the environment variables needed by the app
5 | # * .env.local uncommitted file with local overrides
6 | # * .env.$APP_ENV committed environment-specific defaults
7 | # * .env.$APP_ENV.local uncommitted environment-specific overrides
8 | #
9 | # Real environment variables win over .env files.
10 | #
11 | # DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
12 | #
13 | # Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
14 | # https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
15 |
16 | ###> symfony/framework-bundle ###
17 | APP_ENV=dev
18 | APP_SECRET=d7bcf0b5664f320f82dc7b620705ff0f
19 | ###< symfony/framework-bundle ###
20 |
21 | ###> doctrine/doctrine-bundle ###
22 | # Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
23 | # IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
24 | #
25 | # DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"
26 | # DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=5.7"
27 | DATABASE_URL="postgresql://symfony:ChangeMe@127.0.0.1:5432/app?serverVersion=13&charset=utf8"
28 | ###< doctrine/doctrine-bundle ###
29 |
30 | NEO4J_DSN="bolt://neo4j:password@localhost"
31 |
--------------------------------------------------------------------------------
/.env.test:
--------------------------------------------------------------------------------
1 | KERNEL_CLASS='LegacyFighter\Cabs\Kernel'
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ###> symfony/framework-bundle ###
2 | /.env.local
3 | /.env.local.php
4 | /.env.*.local
5 | /config/secrets/prod/prod.decrypt.private.php
6 | /public/bundles/
7 | /var/
8 | /vendor/
9 | ###< symfony/framework-bundle ###
10 |
11 | ###> friendsofphp/php-cs-fixer ###
12 | /.php-cs-fixer.php
13 | /.php-cs-fixer.cache
14 | ###< friendsofphp/php-cs-fixer ###
15 |
16 | /.phpunit.cache
17 | /phpunit.xml
18 |
--------------------------------------------------------------------------------
/.php-cs-fixer.dist.php:
--------------------------------------------------------------------------------
1 | in(__DIR__.'/src')
5 | ->in(__DIR__.'/tests')
6 | ;
7 |
8 | return (new PhpCsFixer\Config())
9 | ->setRiskyAllowed(true)
10 | ->setRules([
11 | '@PHP71Migration' => true,
12 | '@Symfony' => true,
13 | 'array_syntax' => ['syntax' => 'short'],
14 | 'no_superfluous_elseif' => true,
15 | 'no_superfluous_phpdoc_tags' => ['allow_mixed' => true],
16 | 'no_unreachable_default_argument_value' => true,
17 | 'no_useless_else' => true,
18 | 'no_useless_return' => true,
19 | 'no_unused_imports' => true,
20 | 'declare_strict_types' => true,
21 | 'ordered_imports' => [
22 | 'imports_order' => null,
23 | 'sort_algorithm' => 'alpha',
24 | ],
25 | 'phpdoc_order' => true,
26 | 'phpdoc_align' => true,
27 | 'phpdoc_no_access' => true,
28 | 'phpdoc_separation' => true,
29 | 'increment_style' => true,
30 | 'single_quote' => true,
31 | 'trim_array_spaces' => true,
32 | 'single_blank_line_before_namespace' => true,
33 | 'yoda_style' => false,
34 | 'global_namespace_import' => [
35 | 'import_classes' => false,
36 | 'import_constants' => false,
37 | 'import_functions' => false
38 | ],
39 | // risky -->
40 | 'strict_param' => true,
41 | ])
42 | ->setFinder($finder)
43 | ;
44 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Rozwój kodu
2 |
3 | Kod będzie rozwijać się wraz z cotygodniową narracją szkoleniową.
4 | Zarówno pojawiać się w nim będą kolejne poprawki jak i odziedziczone po firmach partnerskich nowe moduły ;-) Jak to w prawdziwym legacy.
5 |
6 | # Przeglądanie kodu
7 |
8 | Poszczególne kroki refaktoryzacyjne najlepiej przeglądać używając tagów. Każdy krok szkoleniowy, który opisany jest w odcinku Legacy Fighter posiada na końcu planszę z nazwą odpowiedniego taga. Porównać zmiany można robiąc diffa w stosunku do poprzedniego taga z narracji.
9 |
--------------------------------------------------------------------------------
/bin/console:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | ['all' => true],
5 | Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
6 | Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
7 | Pheature\Community\Symfony\PheatureFlagsBundle::class => ['all' => true],
8 | DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true],
9 | ];
10 |
--------------------------------------------------------------------------------
/config/packages/cache.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | cache:
3 | # Unique name of your app: used to compute stable namespaces for cache keys.
4 | #prefix_seed: your_vendor_name/app_name
5 |
6 | # The "app" cache stores to the filesystem by default.
7 | # The data in this cache should persist between deploys.
8 | # Other options include:
9 |
10 | # Redis
11 | #app: cache.adapter.redis
12 | #default_redis_provider: redis://localhost
13 |
14 | # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
15 | #app: cache.adapter.apcu
16 |
17 | # Namespaced pools use the above "app" backend by default
18 | #pools:
19 | #my.dedicated.cache: null
20 |
--------------------------------------------------------------------------------
/config/packages/doctrine.yaml:
--------------------------------------------------------------------------------
1 | doctrine:
2 | dbal:
3 | url: '%env(resolve:DATABASE_URL)%'
4 | types:
5 | money: 'LegacyFighter\Cabs\Money\MoneyType'
6 | miles: 'LegacyFighter\Cabs\Loyalty\MilesType'
7 | distance: 'LegacyFighter\Cabs\Geolocation\DistanceType'
8 | # IMPORTANT: You MUST configure your server version,
9 | # either here or in the DATABASE_URL env var (see .env file)
10 | #server_version: '13'
11 | orm:
12 | auto_generate_proxy_classes: true
13 | naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
14 | auto_mapping: true
15 | mappings:
16 | LegacyFighter:
17 | is_bundle: false
18 | dir: '%kernel.project_dir%/src'
19 | prefix: 'LegacyFighter\Cabs'
20 | alias: LegacyFighter
21 |
--------------------------------------------------------------------------------
/config/packages/doctrine_migrations.yaml:
--------------------------------------------------------------------------------
1 | doctrine_migrations:
2 | migrations_paths:
3 | # namespace is arbitrary but should be different from App\Migrations
4 | # as migrations classes should NOT be autoloaded
5 | 'DoctrineMigrations': '%kernel.project_dir%/migrations'
6 | enable_profiler: '%kernel.debug%'
7 |
--------------------------------------------------------------------------------
/config/packages/features_flag.yaml:
--------------------------------------------------------------------------------
1 | pheature_flags:
2 | driver: "inmemory"
3 | driver_options: []
4 | toggles: []
5 |
--------------------------------------------------------------------------------
/config/packages/framework.yaml:
--------------------------------------------------------------------------------
1 | # see https://symfony.com/doc/current/reference/configuration/framework.html
2 | framework:
3 | secret: '%env(APP_SECRET)%'
4 | #csrf_protection: true
5 | http_method_override: false
6 |
7 | # Enables session support. Note that the session will ONLY be started if you read or write from it.
8 | # Remove or comment this section to explicitly disable session support.
9 | session:
10 | handler_id: null
11 | cookie_secure: auto
12 | cookie_samesite: lax
13 | storage_factory_id: session.storage.factory.native
14 |
15 | #esi: true
16 | #fragments: true
17 | php_errors:
18 | log: true
19 |
20 | when@test:
21 | framework:
22 | test: true
23 | session:
24 | storage_factory_id: session.storage.factory.mock_file
25 |
--------------------------------------------------------------------------------
/config/packages/prod/doctrine.yaml:
--------------------------------------------------------------------------------
1 | doctrine:
2 | orm:
3 | auto_generate_proxy_classes: false
4 | query_cache_driver:
5 | type: pool
6 | pool: doctrine.system_cache_pool
7 | result_cache_driver:
8 | type: pool
9 | pool: doctrine.result_cache_pool
10 |
11 | framework:
12 | cache:
13 | pools:
14 | doctrine.result_cache_pool:
15 | adapter: cache.app
16 | doctrine.system_cache_pool:
17 | adapter: cache.system
18 |
--------------------------------------------------------------------------------
/config/packages/routing.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | router:
3 | utf8: true
4 |
5 | # Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
6 | # See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
7 | #default_uri: http://localhost
8 |
9 | when@prod:
10 | framework:
11 | router:
12 | strict_requirements: null
13 |
--------------------------------------------------------------------------------
/config/packages/test/dama_doctrine_test_bundle.yaml:
--------------------------------------------------------------------------------
1 | dama_doctrine_test:
2 | enable_static_connection: true
3 | enable_static_meta_data_cache: true
4 | enable_static_query_cache: true
5 |
--------------------------------------------------------------------------------
/config/packages/test/doctrine.yaml:
--------------------------------------------------------------------------------
1 | doctrine:
2 | dbal:
3 | # "TEST_TOKEN" is typically set by ParaTest
4 | dbname_suffix: '_test%env(default::TEST_TOKEN)%'
5 |
--------------------------------------------------------------------------------
/config/preload.php:
--------------------------------------------------------------------------------
1 | doctrine/doctrine-bundle ###
5 | database:
6 | ports:
7 | - "5432"
8 | ###< doctrine/doctrine-bundle ###
9 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | ###> doctrine/doctrine-bundle ###
5 | database:
6 | image: postgres:${POSTGRES_VERSION:-13}-alpine
7 | environment:
8 | POSTGRES_DB: ${POSTGRES_DB:-app}
9 | # You should definitely change the password in production
10 | POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-ChangeMe}
11 | POSTGRES_USER: ${POSTGRES_USER:-symfony}
12 | volumes:
13 | - db-data:/var/lib/postgresql/data:rw
14 | # You may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data!
15 | # - ./docker/db/data:/var/lib/postgresql/data:rw
16 | ###< doctrine/doctrine-bundle ###
17 |
18 | neo4j:
19 | image: neo4j:4.0.3
20 | hostname: neo4j
21 | container_name: neo4j
22 | ports:
23 | - "7474:7474"
24 | - "7687:7687"
25 | volumes:
26 | - ./neo4j/plugins:/plugins
27 | environment:
28 | NEO4J_AUTH: neo4j/password
29 | NEO4J_dbms_logs_debug_level: DEBUG
30 |
31 | volumes:
32 | ###> doctrine/doctrine-bundle ###
33 | db-data:
34 | ###< doctrine/doctrine-bundle ###
35 |
--------------------------------------------------------------------------------
/docs/xstate.js:
--------------------------------------------------------------------------------
1 | // https://xstate.js.org/viz/
2 |
3 | // Available variables:
4 | // - Machine
5 | // - interpret
6 | // - assign
7 | // - send
8 | // - sendParent
9 | // - spawn
10 | // - raise
11 | // - actions
12 | // - XState (all XState exports)
13 |
14 | const machine = Machine({
15 | id: 'transit',
16 | initial: 'draft',
17 | context: {
18 | retries: 0
19 | },
20 | states: {
21 | draft: {
22 | on: {
23 | PUBLISH: 'waiting_for_driver_acceptance'
24 | }
25 | },
26 | waiting_for_driver_acceptance: {
27 | on: {
28 | CANCEL: 'cancelled',
29 | ACCEPT: 'transit_to_passenger',
30 | FAILED: 'driver_assignment_failed'
31 | }
32 | },
33 | transit_to_passenger: {
34 | on: {
35 | CANCEL: 'cancelled',
36 | START_TRANSIT: 'in_transit'
37 | }
38 | },
39 | in_transit: {
40 | on: {
41 | COMPLETE: 'completed'
42 | }
43 | },
44 | cancelled: {
45 | type: 'final'
46 | },
47 | completed: {
48 | type: 'final'
49 | },
50 | driver_assignment_failed: {
51 | type: 'final'
52 | }
53 | }
54 | });
55 |
--------------------------------------------------------------------------------
/migrations/Version20220123120851.php:
--------------------------------------------------------------------------------
1 | addSql('COMMENT ON COLUMN driver_fee.min IS \'(DC2Type:money)\'');
24 | $this->addSql('COMMENT ON COLUMN transit.price IS \'(DC2Type:money)\'');
25 | $this->addSql('COMMENT ON COLUMN transit.estimated_price IS \'(DC2Type:money)\'');
26 | }
27 |
28 | public function down(Schema $schema): void
29 | {
30 | // this down() migration is auto-generated, please modify it to your needs
31 | $this->addSql('COMMENT ON COLUMN transit.price IS NULL');
32 | $this->addSql('COMMENT ON COLUMN transit.estimated_price IS NULL');
33 | $this->addSql('COMMENT ON COLUMN driver_fee.min IS NULL');
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/migrations/Version20220123224330.php:
--------------------------------------------------------------------------------
1 | addSql('ALTER TABLE transit ADD tariff_km_rate DOUBLE PRECISION NOT NULL');
24 | $this->addSql('ALTER TABLE transit ADD tariff_name VARCHAR(255) NOT NULL');
25 | $this->addSql('ALTER TABLE transit ADD tariff_base_fee INT NOT NULL');
26 | $this->addSql('ALTER TABLE transit DROP factor');
27 | }
28 |
29 | public function down(Schema $schema): void
30 | {
31 | // this down() migration is auto-generated, please modify it to your needs
32 | $this->addSql('ALTER TABLE transit ADD factor INT DEFAULT NULL');
33 | $this->addSql('ALTER TABLE transit DROP tariff_km_rate');
34 | $this->addSql('ALTER TABLE transit DROP tariff_name');
35 | $this->addSql('ALTER TABLE transit DROP tariff_base_fee');
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/migrations/Version20220209194742.php:
--------------------------------------------------------------------------------
1 | addSql('CREATE TABLE car_type_active_counter (car_class VARCHAR(255) NOT NULL, active_cars_counter INT NOT NULL, PRIMARY KEY(car_class))');
24 | $this->addSql('ALTER TABLE car_type DROP active_cars_counter');
25 | $this->addSql('ALTER TABLE transit ALTER drivers_fee TYPE INT');
26 | $this->addSql('ALTER TABLE transit ALTER drivers_fee DROP DEFAULT');
27 | $this->addSql('COMMENT ON COLUMN transit.drivers_fee IS \'(DC2Type:money)\'');
28 | }
29 |
30 | public function down(Schema $schema): void
31 | {
32 | // this down() migration is auto-generated, please modify it to your needs
33 | $this->addSql('DROP TABLE car_type_active_counter');
34 | $this->addSql('ALTER TABLE car_type ADD active_cars_counter INT NOT NULL');
35 | $this->addSql('ALTER TABLE transit ALTER drivers_fee TYPE INT');
36 | $this->addSql('ALTER TABLE transit ALTER drivers_fee DROP DEFAULT');
37 | $this->addSql('COMMENT ON COLUMN transit.drivers_fee IS NULL');
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/migrations/Version20220210152256.php:
--------------------------------------------------------------------------------
1 | addSql('DROP INDEX uniq_a769de27617c70e0');
24 | $this->addSql('CREATE INDEX IDX_A769DE27617C70E0 ON claim (transit_id)');
25 | }
26 |
27 | public function down(Schema $schema): void
28 | {
29 | // this down() migration is auto-generated, please modify it to your needs
30 | $this->addSql('DROP INDEX IDX_A769DE27617C70E0');
31 | $this->addSql('CREATE UNIQUE INDEX uniq_a769de27617c70e0 ON claim (transit_id)');
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/migrations/Version20220210184450.php:
--------------------------------------------------------------------------------
1 | addSql('CREATE SEQUENCE claims_resolver_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
24 | $this->addSql('CREATE TABLE claims_resolver (id INT NOT NULL, client_id INT NOT NULL, claimed_transits_ids JSON NOT NULL, version INT DEFAULT 1 NOT NULL, PRIMARY KEY(id))');
25 | }
26 |
27 | public function down(Schema $schema): void
28 | {
29 | // this down() migration is auto-generated, please modify it to your needs
30 | $this->addSql('DROP SEQUENCE claims_resolver_id_seq CASCADE');
31 | $this->addSql('DROP TABLE claims_resolver');
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/migrations/Version20220211204206.php:
--------------------------------------------------------------------------------
1 | addSql('ALTER TABLE awarded_miles DROP expiration_date');
24 | $this->addSql('ALTER TABLE awarded_miles DROP is_special');
25 | $this->addSql('ALTER TABLE awarded_miles DROP miles');
26 | $this->addSql('ALTER TABLE awarded_miles ADD miles JSON NOT NULL');
27 | }
28 |
29 | public function down(Schema $schema): void
30 | {
31 | // this down() migration is auto-generated, please modify it to your needs
32 | $this->addSql('ALTER TABLE awarded_miles ADD expiration_date TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL');
33 | $this->addSql('ALTER TABLE awarded_miles ADD is_special BOOLEAN NOT NULL');
34 | $this->addSql('ALTER TABLE awarded_miles DROP miles');
35 | $this->addSql('ALTER TABLE awarded_miles ADD miles INT NOT NULL');
36 | $this->addSql('COMMENT ON COLUMN awarded_miles.expiration_date IS \'(DC2Type:datetime_immutable)\'');
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/migrations/Version20220212082639.php:
--------------------------------------------------------------------------------
1 | addSql('ALTER TABLE awarded_miles ADD account_id INT DEFAULT NULL');
24 | $this->addSql('ALTER TABLE awarded_miles ADD CONSTRAINT FK_43471B899B6B5FBA FOREIGN KEY (account_id) REFERENCES awards_account (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
25 | $this->addSql('CREATE INDEX IDX_43471B899B6B5FBA ON awarded_miles (account_id)');
26 | $this->addSql('COMMENT ON COLUMN awarded_miles.miles IS \'(DC2Type:miles)\'');
27 | }
28 |
29 | public function down(Schema $schema): void
30 | {
31 | // this down() migration is auto-generated, please modify it to your needs
32 | $this->addSql('ALTER TABLE awarded_miles DROP CONSTRAINT FK_43471B899B6B5FBA');
33 | $this->addSql('DROP INDEX IDX_43471B899B6B5FBA');
34 | $this->addSql('ALTER TABLE awarded_miles DROP account_id');
35 | $this->addSql('COMMENT ON COLUMN awarded_miles.miles IS NULL');
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/migrations/Version20220303185743.php:
--------------------------------------------------------------------------------
1 | addSql('CREATE TABLE travelled_distance (interval_id UUID NOT NULL, driver_id INT NOT NULL, last_latitude DOUBLE PRECISION NOT NULL, last_longitude DOUBLE PRECISION NOT NULL, distance DOUBLE PRECISION NOT NULL, beginning TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, "end" TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(interval_id))');
24 | $this->addSql('COMMENT ON COLUMN travelled_distance.interval_id IS \'(DC2Type:uuid)\'');
25 | $this->addSql('COMMENT ON COLUMN travelled_distance.distance IS \'(DC2Type:distance)\'');
26 | $this->addSql('COMMENT ON COLUMN travelled_distance.beginning IS \'(DC2Type:datetime_immutable)\'');
27 | $this->addSql('COMMENT ON COLUMN travelled_distance."end" IS \'(DC2Type:datetime_immutable)\'');
28 | }
29 |
30 | public function down(Schema $schema): void
31 | {
32 | // this down() migration is auto-generated, please modify it to your needs
33 | $this->addSql('DROP TABLE travelled_distance');
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/migrations/Version20220407185153.php:
--------------------------------------------------------------------------------
1 | addSql('CREATE SEQUENCE signed_contract_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
24 | $this->addSql('CREATE TABLE signed_contract (id INT NOT NULL, covered_parts JSON NOT NULL, coverage_ratio DOUBLE PRECISION NOT NULL, version INT DEFAULT 1 NOT NULL, PRIMARY KEY(id))');
25 | }
26 |
27 | public function down(Schema $schema): void
28 | {
29 | // this down() migration is auto-generated, please modify it to your needs
30 | $this->addSql('DROP SEQUENCE signed_contract_id_seq CASCADE');
31 | $this->addSql('DROP TABLE signed_contract');
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/migrations/Version20220419063121.php:
--------------------------------------------------------------------------------
1 | addSql('ALTER TABLE driver_session DROP CONSTRAINT fk_15bbb1b4c3423909');
24 | $this->addSql('DROP INDEX idx_15bbb1b4c3423909');
25 | $this->addSql('ALTER TABLE driver_session ALTER driver_id SET NOT NULL');
26 | }
27 |
28 | public function down(Schema $schema): void
29 | {
30 | // this down() migration is auto-generated, please modify it to your needs
31 | $this->addSql('ALTER TABLE driver_session ALTER driver_id DROP NOT NULL');
32 | $this->addSql('ALTER TABLE driver_session ADD CONSTRAINT fk_15bbb1b4c3423909 FOREIGN KEY (driver_id) REFERENCES driver (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
33 | $this->addSql('CREATE INDEX idx_15bbb1b4c3423909 ON driver_session (driver_id)');
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 | tests
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
33 |
34 | src
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 | contractAttachmentNo = $contractAttachmentId;
25 | $this->data = $data;
26 | $this->creationDate = new \DateTimeImmutable();
27 | }
28 |
29 | public function getContractAttachmentNo(): Uuid
30 | {
31 | return $this->contractAttachmentNo;
32 | }
33 |
34 | public function getData(): string
35 | {
36 | return $this->data;
37 | }
38 |
39 | public function getCreationDate(): \DateTimeImmutable
40 | {
41 | return $this->creationDate;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/Agreements/ContractAttachmentDataRepository.php:
--------------------------------------------------------------------------------
1 | em->persist($contractAttachmentData);
16 | $this->em->flush();
17 | return $contractAttachmentData;
18 | }
19 |
20 | /**
21 | * @param Uuid[] $attachmentIds
22 | * @return ContractAttachmentData[]
23 | */
24 | public function findByContractAttachmentNoIn(array $attachmentIds): array
25 | {
26 | return $this->em->getRepository(ContractAttachmentData::class)->matching(Criteria::create()->where(
27 | Criteria::expr()->in('contractAttachmentNo', $attachmentIds)
28 | ))->toArray();
29 | }
30 |
31 | public function deleteByAttachmentId(int $id): void
32 | {
33 | $this->em->getConnection()->executeQuery('
34 | DELETE FROM contract_attachment_data cad WHERE cad.contract_attachment_no = (
35 | (SELECT ca.contract_attachment_no FROM contract_attachment ca WHERE ca.id = :id)
36 | )', ['id' => $id]);
37 | $this->em->clear(ContractAttachmentData::class);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Agreements/ContractRepository.php:
--------------------------------------------------------------------------------
1 | em->getRepository(Contract::class)->findBy(['partnerName' => $partnerName]);
18 | }
19 |
20 | public function save(Contract $contract): Contract
21 | {
22 | $this->em->persist($contract);
23 | $this->em->flush();
24 | return $contract;
25 | }
26 |
27 | public function getOne(int $id): ?Contract
28 | {
29 | return $this->em->find(Contract::class, $id);
30 | }
31 |
32 | public function findByAttachmentId(int $attachmentId): ?Contract
33 | {
34 | return $this->em->createQuery(sprintf(
35 | 'SELECT c FROM %s c JOIN c.attachments ca WHERE ca.id = %s',
36 | Contract::class,
37 | $attachmentId
38 | ))->getSingleResult();
39 | }
40 |
41 | public function findContractAttachmentNoById(int $attachmentId): ?Uuid
42 | {
43 | $uuid = $this->em->getConnection()->fetchOne(
44 | 'SELECT c.contract_attachment_no FROM contract_attachment c WHERE c.id = :id',
45 | ['id' => $attachmentId]
46 | );
47 | return $uuid !== false ? Uuid::fromString($uuid) : null;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/Assignment/AssignmentStatus.php:
--------------------------------------------------------------------------------
1 | em->persist($driverAssignment);
15 | $this->em->flush();
16 | return $driverAssignment;
17 | }
18 |
19 | public function findByRequestUuid(Uuid $requestUuid): ?DriverAssignment
20 | {
21 | return $this->em->getRepository(DriverAssignment::class)->findOneBy([
22 | 'requestId' => $requestUuid
23 | ]);
24 | }
25 |
26 | public function findByRequestUuidAndStatus(Uuid $requestId, string $status): ?DriverAssignment
27 | {
28 | return $this->em->getRepository(DriverAssignment::class)->findOneBy([
29 | 'requestId' => $requestId,
30 | 'status' => $status
31 | ]);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Assignment/InvolvedDriversSummary.php:
--------------------------------------------------------------------------------
1 | carClass = $carClass;
22 | }
23 |
24 | public function getActiveCarsCounter(): int
25 | {
26 | return $this->activeCarsCounter;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/CarFleet/CarTypeActiveCounterRepository.php:
--------------------------------------------------------------------------------
1 | em->find(CarTypeActiveCounter::class, $carClass);
14 | }
15 |
16 | public function save(CarTypeActiveCounter $carTypeActiveCounter): void
17 | {
18 | $this->em->persist($carTypeActiveCounter);
19 | }
20 |
21 | public function incrementCounter(string $carClass): void
22 | {
23 | $this->em->getConnection()->executeQuery('
24 | UPDATE car_type_active_counter counter SET active_cars_counter = active_cars_counter + 1
25 | WHERE counter.car_class = :car_class', [
26 | 'car_class' => $carClass
27 | ]);
28 | $this->em->clear(CarTypeActiveCounter::class);
29 | }
30 |
31 | public function decrementCounter(string $carClass): void
32 | {
33 | $this->em->getConnection()->executeQuery('
34 | UPDATE car_type_active_counter counter SET active_cars_counter = active_cars_counter - 1
35 | WHERE counter.car_class = :car_class', [
36 | 'car_class' => $carClass
37 | ]);
38 | $this->em->clear(CarTypeActiveCounter::class);
39 | }
40 |
41 | public function delete(CarTypeActiveCounter $carTypeActiveCounter): void
42 | {
43 | $this->em->remove($carTypeActiveCounter);
44 | $this->em->flush();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/CarFleet/CarTypeController.php:
--------------------------------------------------------------------------------
1 | carTypeService->create($carTypeDTO));
17 | }
18 |
19 | #[Route('/cartypes/{carClass}/registerCar', methods: ['POST'])]
20 | public function registerCar(string $carClass): Response
21 | {
22 | $this->carTypeService->registerCar($carClass);
23 | return new JsonResponse();
24 | }
25 |
26 | #[Route('/cartypes/{carClass}/unregisterCar', methods: ['POST'])]
27 | public function unregisterCar(string $carClass): Response
28 | {
29 | $this->carTypeService->unregisterCar($carClass);
30 | return new JsonResponse();
31 | }
32 |
33 | #[Route('/cartypes/{id}/activate', methods: ['POST'])]
34 | public function activate(int $id): Response
35 | {
36 | $this->carTypeService->activate($id);
37 | return new JsonResponse();
38 | }
39 |
40 | #[Route('/cartypes/{id}/deactivate', methods: ['POST'])]
41 | public function deactivate(int $id): Response
42 | {
43 | $this->carTypeService->deactivate($id);
44 | return new JsonResponse();
45 | }
46 |
47 | #[Route('/cartypes/{id}', methods: ['GET'])]
48 | public function find(int $id): Response
49 | {
50 | return new JsonResponse($this->carTypeService->loadDto($id));
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/CarFleet/CarTypeRepository.php:
--------------------------------------------------------------------------------
1 | em->find(CarType::class, $carTypeId);
18 | }
19 |
20 | public function findByCarClass(string $carClass): ?CarType
21 | {
22 | return $this->em->getRepository(CarType::class)->findOneBy(['carClass' => $carClass]);
23 | }
24 |
25 | public function findActiveCounter(string $carClass): ?CarTypeActiveCounter
26 | {
27 | return $this->carTypeActiveCounterRepository->findByCarClass($carClass);
28 | }
29 |
30 | /**
31 | * @return CarType[]
32 | */
33 | public function findByStatus(string $status): array
34 | {
35 | return $this->em->getRepository(CarType::class)->findBy(['status' => $status]);
36 | }
37 |
38 | public function save(CarType $carType): void
39 | {
40 | $this->em->persist($carType);
41 | $this->carTypeActiveCounterRepository->save(new CarTypeActiveCounter($carType->getCarClass()));
42 | $this->em->flush();
43 | }
44 |
45 | public function delete(CarType $carType): void
46 | {
47 | $this->em->remove($carType);
48 | $this->carTypeActiveCounterRepository->delete($this->carTypeActiveCounterRepository->findByCarClass($carType->getCarClass()));
49 | $this->em->flush();
50 | }
51 |
52 | public function incrementCounter(string $carClass): void
53 | {
54 | $this->carTypeActiveCounterRepository->incrementCounter($carClass);
55 | }
56 |
57 | public function decrementCounter(string $carClass): void
58 | {
59 | $this->carTypeActiveCounterRepository->decrementCounter($carClass);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/Common/BaseEntity.php:
--------------------------------------------------------------------------------
1 | id;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Common/Clock.php:
--------------------------------------------------------------------------------
1 | serializer = new Serializer(
23 | [new PropertyNormalizer(null, null, new ReflectionExtractor())],
24 | [new JsonEncoder()]
25 | );
26 | }
27 |
28 |
29 | public function supports(Request $request, ArgumentMetadata $argument)
30 | {
31 | return str_starts_with($argument->getType(), 'LegacyFighter\Cabs\DTO');
32 | }
33 |
34 | public function resolve(Request $request, ArgumentMetadata $argument)
35 | {
36 | try {
37 | yield $this->serializer->deserialize($request->getContent(), $argument->getType(), 'json');
38 | } catch (ExceptionInterface $exception) {
39 | throw new BadRequestHttpException($exception->getMessage(), $exception);
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Common/ObjectHash.php:
--------------------------------------------------------------------------------
1 | entityManager = $entityManager;
18 | }
19 |
20 | public static function getSubscribedEvents(): array
21 | {
22 | return [
23 | KernelEvents::CONTROLLER => ['startTransaction', 10],
24 | KernelEvents::RESPONSE => ['commitTransaction', 10],
25 | KernelEvents::EXCEPTION => ['rollbackTransaction', 11],
26 | ];
27 | }
28 |
29 | public function startTransaction(KernelEvent $event): void
30 | {
31 | if(in_array($event->getRequest()->getMethod(), [Request::METHOD_POST, Request::METHOD_DELETE], true)) {
32 | $this->entityManager->beginTransaction();
33 | }
34 | }
35 |
36 | public function commitTransaction(): void
37 | {
38 | if($this->entityManager->getConnection()->isTransactionActive()) {
39 | $this->entityManager->flush();
40 | $this->entityManager->commit();
41 | }
42 | }
43 |
44 | public function rollbackTransaction(): void
45 | {
46 | if($this->entityManager->getConnection()->isTransactionActive()) {
47 | $this->entityManager->rollback();
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Common/SystemClock.php:
--------------------------------------------------------------------------------
1 | noOfTransitsForClaimAutomaticRefund;
17 | }
18 |
19 | public function getAutomaticRefundForVipThreshold(): int
20 | {
21 | return $this->automaticRefundForVipThreshold;
22 | }
23 |
24 | public function getMinNoOfCarsForEcoClass(): int
25 | {
26 | return $this->minNoOfCarsForEcoClass;
27 | }
28 |
29 | public function getMilesExpirationInDays(): int
30 | {
31 | return $this->milesExpirationInDays;
32 | }
33 |
34 | public function getDefaultMilesBonus(): int
35 | {
36 | return $this->defaultMilesBonus;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Config/Neo4jClientFactory.php:
--------------------------------------------------------------------------------
1 | withDriver('bolt', $neo4jDsn)
14 | ->withDefaultDriver('bolt')
15 | ->build();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Contracts/Application/Acme/Dynamic/DocumentOperationResult.php:
--------------------------------------------------------------------------------
1 | result;
29 | }
30 |
31 | public function getStateName(): string
32 | {
33 | return $this->stateName;
34 | }
35 |
36 | public function getContentId(): ?ContentId
37 | {
38 | return $this->contentId;
39 | }
40 |
41 | public function getDocumentHeaderId(): int
42 | {
43 | return $this->documentHeaderId;
44 | }
45 |
46 | public function getDocumentNumber(): DocumentNumber
47 | {
48 | return $this->documentNumber;
49 | }
50 |
51 | public function getPossibleTransitionsAndRules(): array
52 | {
53 | return $this->possibleTransitionsAndRules;
54 | }
55 |
56 | public function isContentChangePossible(): bool
57 | {
58 | return $this->contentChangePossible;
59 | }
60 |
61 | public function getContentChangePredicate(): string
62 | {
63 | return $this->contentChangePredicate;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/Contracts/Application/Acme/Straigthforward/AcmeStateFactory.php:
--------------------------------------------------------------------------------
1 | getStateDescriptor();
16 | if($className === null) {
17 | $state = new DraftState();
18 | $state->init($header);
19 | return $state;
20 | }
21 |
22 | try {
23 | $state = new $className();
24 | $state->init($header);
25 | return $state;
26 | } catch (\Throwable $exception) {
27 | throw new \RuntimeException('Invalid class name '.$className, 0, $exception);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Contracts/Application/Acme/Straigthforward/ContractResult.php:
--------------------------------------------------------------------------------
1 | result;
24 | }
25 |
26 | public function getDocumentHeaderId(): int
27 | {
28 | return $this->documentHeaderId;
29 | }
30 |
31 | public function getDocumentNumber(): DocumentNumber
32 | {
33 | return $this->documentNumber;
34 | }
35 |
36 | public function getStateDescriptor(): ?string
37 | {
38 | return $this->stateDescriptor;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Contracts/Application/Editor/CommitResult.php:
--------------------------------------------------------------------------------
1 | contentId = $contentId;
19 | $this->result = $result;
20 | $this->message = $message;
21 | }
22 |
23 | public function getContentId(): Uuid
24 | {
25 | return $this->contentId;
26 | }
27 |
28 | public function getResult(): string
29 | {
30 | return $this->result;
31 | }
32 |
33 | public function getMessage(): ?string
34 | {
35 | return $this->message;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Contracts/Application/Editor/DocumentDTO.php:
--------------------------------------------------------------------------------
1 | contentId = $contentId;
17 | $this->physicalContent = $physicalContent;
18 | $this->contentVersion = $contentVersion;
19 | }
20 |
21 | public function getContentId(): ?Uuid
22 | {
23 | return $this->contentId;
24 | }
25 |
26 | public function getPhysicalContent(): string
27 | {
28 | return $this->physicalContent;
29 | }
30 |
31 | public function getContentVersion(): ContentVersion
32 | {
33 | return $this->contentVersion;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Contracts/Application/Editor/DocumentEditor.php:
--------------------------------------------------------------------------------
1 | getContentId();
20 | $content = new DocumentContent($previousID, $document->getContentVersion(), $document->getPhysicalContent());
21 | $this->documentContentRepository->save($content);
22 | return new CommitResult($content->getId(), CommitResult::SUCCESS);
23 | }
24 |
25 | public function get(Uuid $contentId): DocumentDTO
26 | {
27 | $content = $this->documentContentRepository->getOne($contentId);
28 | return new DocumentDTO($contentId, $content->getPhysicalContent(), $content->getContentVersion());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Contracts/Infra/DoctrineDocumentHeaderRepository.php:
--------------------------------------------------------------------------------
1 | em->contains($header)) {
20 | $this->em->lock($header, LockMode::OPTIMISTIC);
21 | } else {
22 | $this->em->persist($header);
23 | }
24 | $this->em->flush();
25 | }
26 |
27 | public function getOne(int $id): ?DocumentHeader
28 | {
29 | assert($this->em instanceof EntityManager);
30 | return $this->em->find(DocumentHeader::class, $id, LockMode::OPTIMISTIC);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Contracts/Legacy/BaseAggregateRoot.php:
--------------------------------------------------------------------------------
1 | status, DocumentStatus::PUBLISHED);
10 | }
11 |
12 | public function accept(): void
13 | {
14 | if($this->status === DocumentStatus::VERIFIED) {
15 | $this->status = DocumentStatus::PUBLISHED; //reusing unused enum to provide data model for new status
16 | }
17 | }
18 |
19 | //Contracts just don't have a title, it's just a part of the content
20 | public function changeTitle(string $title): void
21 | {
22 | parent::changeContent($title . $this->getContent());
23 | }
24 |
25 | public function changeContentFor(string $content, string $userStatus): void
26 | {
27 | if($userStatus === 'ChiefSalesOfficerStatus' || $this->misterVladimirIsLoggedIn($userStatus)) {
28 | $this->overridePublished = true;
29 | $this->changeContent($content);
30 | }
31 | }
32 |
33 | private function misterVladimirIsLoggedIn(string $userStatus): bool
34 | {
35 | return trim(mb_strtolower($userStatus)) === '!!!id='.self::NUMBER_OF_THE_BEAST;
36 | }
37 |
38 | private const NUMBER_OF_THE_BEAST = 616;
39 |
40 | public function recreateTo(int $version): void
41 | {
42 | //TODO need to learn Kafka
43 | }
44 |
45 | public function getLastVersion(): int
46 | {
47 | return random_int(1, PHP_INT_MAX);
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/Contracts/Legacy/DocumentStatus.php:
--------------------------------------------------------------------------------
1 | current;
18 | }
19 |
20 | public function getDesired(): string
21 | {
22 | return $this->desired;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Contracts/Legacy/User.php:
--------------------------------------------------------------------------------
1 | em->persist($user);
14 | $this->em->flush();
15 | return $user;
16 | }
17 |
18 | public function getOne(int $userId): ?User
19 | {
20 | return $this->em->find(User::class, $userId);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Contracts/Legacy/Versionable.php:
--------------------------------------------------------------------------------
1 | id = Uuid::v4();
28 | }
29 |
30 | public function getId(): Uuid
31 | {
32 | return $this->id;
33 | }
34 |
35 | public function getPreviousId(): ?Uuid
36 | {
37 | return $this->previousId;
38 | }
39 |
40 | public function getContentVersion(): ContentVersion
41 | {
42 | return $this->contentVersion;
43 | }
44 |
45 | public function getPhysicalContent(): string
46 | {
47 | return $this->physicalContent;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/Contracts/Model/Content/DocumentContentRepository.php:
--------------------------------------------------------------------------------
1 | em->persist($content);
15 | $this->em->flush();
16 | }
17 |
18 | public function getOne(Uuid $contentId): DocumentContent
19 | {
20 | $documentContent = $this->em->find(DocumentContent::class, $contentId);
21 | if($documentContent===null) {
22 | throw new \RuntimeException(sprintf('Document %s not found', $contentId));
23 | }
24 |
25 | return $documentContent;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Contracts/Model/Content/DocumentNumber.php:
--------------------------------------------------------------------------------
1 | contentId = $contentId;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Contracts/Model/DocumentHeader.php:
--------------------------------------------------------------------------------
1 | authorId = $authorId;
21 | $this->number = $number;
22 | }
23 |
24 | public function changeCurrentContent(ContentId $contentId): void
25 | {
26 | $this->contentId = $contentId;
27 | }
28 |
29 | public function noEmpty(): bool
30 | {
31 | return $this->contentId !== null;
32 | }
33 |
34 | public function getAuthorId(): int
35 | {
36 | return $this->authorId;
37 | }
38 |
39 | public function setAuthorId(int $authorId): void
40 | {
41 | $this->authorId = $authorId;
42 | }
43 |
44 | public function getVerifierId(): ?int
45 | {
46 | return $this->verifierId;
47 | }
48 |
49 | public function setVerifierId(?int $verifierId): void
50 | {
51 | $this->verifierId = $verifierId;
52 | }
53 |
54 | public function getStateDescriptor(): ?string
55 | {
56 | return $this->stateDescriptor;
57 | }
58 |
59 | public function setStateDescriptor(?string $stateDescriptor): void
60 | {
61 | $this->stateDescriptor = $stateDescriptor;
62 | }
63 |
64 | public function getDocumentNumber(): DocumentNumber
65 | {
66 | return $this->number;
67 | }
68 |
69 | public function getContentId(): ?ContentId
70 | {
71 | return $this->contentId;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/Contracts/Model/DocumentHeaderRepository.php:
--------------------------------------------------------------------------------
1 |
10 | */
11 | private array $params;
12 |
13 | public function __construct(string $desiredState, array $params = [])
14 | {
15 | $this->desiredState = $desiredState;
16 | $this->params = $params;
17 | }
18 |
19 | public function getDesiredState(): string
20 | {
21 | return $this->desiredState;
22 | }
23 |
24 | public function getParam(string $name)
25 | {
26 | return $this->params[$name] ?? null;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Contracts/Model/State/Dynamic/Config/Actions/Action.php:
--------------------------------------------------------------------------------
1 | setVerifierId($changeCommand->getParam(self::PARAM_VERIFIER));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Contracts/Model/State/Dynamic/Config/Actions/PublishEvent.php:
--------------------------------------------------------------------------------
1 | $eventClass
14 | */
15 | public function __construct(
16 | private string $eventClass,
17 | private EventDispatcherInterface $dispatcher
18 | )
19 | {
20 | }
21 |
22 | public function apply(DocumentHeader $documentHeader, ChangeCommand $changeCommand): void
23 | {
24 | $eventClass = $this->eventClass;
25 | $this->dispatcher->dispatch(new $eventClass(
26 | $documentHeader->getId(),
27 | $documentHeader->getStateDescriptor(),
28 | $documentHeader->getContentId(),
29 | $documentHeader->getDocumentNumber()
30 | ));
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/Contracts/Model/State/Dynamic/Config/Events/DocumentEvent.php:
--------------------------------------------------------------------------------
1 | documentId = $documentId;
18 | $this->currentSate = $currentSate;
19 | $this->contentId = $contentId;
20 | $this->documentNumber = $documentNumber;
21 | }
22 |
23 | public function getDocumentId(): int
24 | {
25 | return $this->documentId;
26 | }
27 |
28 | public function getCurrentSate(): string
29 | {
30 | return $this->currentSate;
31 | }
32 |
33 | public function getContentId(): ContentId
34 | {
35 | return $this->contentId;
36 | }
37 |
38 | public function getDocumentNumber(): DocumentNumber
39 | {
40 | return $this->documentNumber;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Contracts/Model/State/Dynamic/Config/Events/DocumentPublished.php:
--------------------------------------------------------------------------------
1 | getParam(ChangeVerifier::PARAM_VERIFIER) !== $state->getDocumentHeader()->getAuthorId();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Contracts/Model/State/Dynamic/Config/Predicates/StateChange/ContentNotEmptyVerifier.php:
--------------------------------------------------------------------------------
1 | getDocumentHeader()->getContentId() !== null;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Contracts/Model/State/Dynamic/Config/Predicates/StateChange/PositiveVerifier.php:
--------------------------------------------------------------------------------
1 | getStateDescriptor() === $this->stateDescriptor;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Contracts/Model/State/Dynamic/StateConfig.php:
--------------------------------------------------------------------------------
1 | getDocumentHeader()->noEmpty();
23 | }
24 |
25 | protected function acquire(DocumentHeader $header): void
26 | {
27 |
28 | }
29 |
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/Contracts/Model/State/Straightforward/Acme/VerifiedState.php:
--------------------------------------------------------------------------------
1 | verifierId = $verifierId;
15 | }
16 |
17 | protected function canChangeContent(): bool
18 | {
19 | return true;
20 | }
21 |
22 | protected function stateAfterContentChange(): BaseState
23 | {
24 | return new DraftState();
25 | }
26 |
27 | protected function canChangeFrom(BaseState $previousState): bool
28 | {
29 | return $previousState instanceof DraftState
30 | && $previousState->getDocumentHeader()->getAuthorId() !== $this->verifierId
31 | && $previousState->getDocumentHeader()->noEmpty()
32 | ;
33 | }
34 |
35 | protected function acquire(DocumentHeader $header): void
36 | {
37 | $this->documentHeader->setVerifierId($this->verifierId);
38 | }
39 |
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/Crm/Claims/ClaimAttachment.php:
--------------------------------------------------------------------------------
1 | creationDate = new \DateTimeImmutable();
28 | }
29 |
30 | public function getClientId(): int
31 | {
32 | return $this->claim->getOwnerId();
33 | }
34 |
35 | public function getClaim(): Claim
36 | {
37 | return $this->claim;
38 | }
39 |
40 | public function getCreationDate(): \DateTimeImmutable
41 | {
42 | return $this->creationDate;
43 | }
44 |
45 | public function setCreationDate(\DateTimeImmutable $creationDate): void
46 | {
47 | $this->creationDate = $creationDate;
48 | }
49 |
50 | public function getDescription(): string
51 | {
52 | return $this->description;
53 | }
54 |
55 | public function setDescription(string $description): void
56 | {
57 | $this->description = $description;
58 | }
59 |
60 | public function getData(): string
61 | {
62 | return $this->data;
63 | }
64 |
65 | public function setData(string $data): void
66 | {
67 | $this->data = $data;
68 | }
69 |
70 | public function setClaim(Claim $claim): void
71 | {
72 | $this->claim = $claim;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/Crm/Claims/ClaimAttachmentRepository.php:
--------------------------------------------------------------------------------
1 | em->persist($claimAttachment);
14 | $this->em->flush();
15 | }
16 |
17 | public function getOne(int $id): ?ClaimAttachment
18 | {
19 | return $this->em->find(ClaimAttachment::class, $id);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Crm/Claims/ClaimController.php:
--------------------------------------------------------------------------------
1 | claimService->create($claimDTO);
17 | return new JsonResponse(ClaimDTO::from($created));
18 | }
19 |
20 | #[Route('/claims/send', methods: ['POST'])]
21 | public function sendNew(ClaimDTO $claimDTO): Response
22 | {
23 | $claimDTO->setIsDraft(false);
24 | $claim = $this->claimService->create($claimDTO);
25 | return new JsonResponse(ClaimDTO::from($claim));
26 | }
27 |
28 | #[Route('/claims/{id}/markInProcess', methods: ['POST'])]
29 | public function markAsInProcess(int $id): Response
30 | {
31 | $claim = $this->claimService->setStatus(Claim::STATUS_IN_PROCESS, $id);
32 | return new JsonResponse(ClaimDTO::from($claim));
33 | }
34 |
35 | #[Route('/claims/{id}', methods: ['GET'])]
36 | public function find(int $id): Response
37 | {
38 | $claim = $this->claimService->find($id);
39 | return new JsonResponse(ClaimDTO::from($claim));
40 | }
41 |
42 | #[Route('/claims/{id}', methods: ['POST'])]
43 | public function tryToAutomaticallyResolve(int $id): Response
44 | {
45 | $claim = $this->claimService->tryToResolveAutomatically($id);
46 | return new JsonResponse(ClaimDTO::from($claim));
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Crm/Claims/ClaimNumberGenerator.php:
--------------------------------------------------------------------------------
1 | claimRepository = $claimRepository;
12 | }
13 |
14 | public function generate(Claim $claim): string
15 | {
16 | $count = $this->claimRepository->count();
17 | $prefix = $count;
18 | if($count===0) {
19 | $prefix=1;
20 | }
21 |
22 | return sprintf('%s---%s', $prefix, $claim->getCreationDate()->format('d/m/Y'));
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Crm/Claims/ClaimRepository.php:
--------------------------------------------------------------------------------
1 | em->getRepository(Claim::class)->count([]);
14 | }
15 |
16 | public function getOne(int $claimId): ?Claim
17 | {
18 | return $this->em->find(Claim::class, $claimId);
19 | }
20 |
21 | public function save(Claim $claim): Claim
22 | {
23 | $this->em->persist($claim);
24 | $this->em->flush();
25 | return $claim;
26 | }
27 |
28 | public function countByOwnerId(int $clientId): int
29 | {
30 | return $this->em->getRepository(Claim::class)->count(['ownerId' => $clientId]);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Crm/Claims/ClaimResolver/Result.php:
--------------------------------------------------------------------------------
1 | whoToAsk = $whoToAsk;
26 | $this->decision = $decision;
27 | }
28 |
29 | public function getWhoToAsk(): string
30 | {
31 | return $this->whoToAsk;
32 | }
33 |
34 | public function getDecision(): string
35 | {
36 | return $this->decision;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Crm/Claims/ClaimsResolverRepository.php:
--------------------------------------------------------------------------------
1 | em->getRepository(ClaimsResolver::class)->findOneBy(['clientId' => $clientId]);
14 | }
15 |
16 | public function save(ClaimsResolver $claimsResolver): ClaimsResolver
17 | {
18 | $this->em->persist($claimsResolver);
19 | return $claimsResolver;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Crm/ClientController.php:
--------------------------------------------------------------------------------
1 | clientService->registerClient($dto->getName(), $dto->getLastName(), $dto->getType(), $dto->getDefaultPaymentType());
17 | return new JsonResponse($this->clientService->load($c->getId()));
18 | }
19 |
20 | #[Route('/clients/{clientId}', methods: ['GET'])]
21 | public function find(int $clientId): Response
22 | {
23 | return new JsonResponse($this->clientService->load($clientId));
24 | }
25 |
26 | #[Route('/clients/{clientId}/upgrade', methods: ['POST'])]
27 | public function upgradeToVIP(int $clientId): Response
28 | {
29 | $this->clientService->upgradeToVIP($clientId);
30 | return new JsonResponse($this->clientService->load($clientId));
31 | }
32 |
33 | #[Route('/clients/{clientId}/downgrade', methods: ['POST'])]
34 | public function downgrade(int $clientId): Response
35 | {
36 | $this->clientService->downgradeToRegular($clientId);
37 | return new JsonResponse($this->clientService->load($clientId));
38 | }
39 |
40 | #[Route('/clients/{clientId}/changeDefaultPaymentType', methods: ['POST'])]
41 | public function changeDefaultPaymentType(int $clientId, ClientDTO $clientDTO): Response
42 | {
43 | $this->clientService->changeDefaultPaymentType($clientId, $clientDTO->getDefaultPaymentType());
44 | return new JsonResponse($this->clientService->load($clientId));
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Crm/ClientDTO.php:
--------------------------------------------------------------------------------
1 | id = $client->getId();
18 | $this->type = $client->getType();
19 | $this->name = $client->getName();
20 | $this->lastName = $client->getLastName();
21 | $this->defaultPaymentType = $client->getDefaultPaymentType();
22 | $this->clientType = $client->getClientType();
23 | }
24 |
25 | public static function from(Client $client): self
26 | {
27 | return new self($client);
28 | }
29 |
30 | public function getId(): int
31 | {
32 | return $this->id;
33 | }
34 |
35 | public function getType(): string
36 | {
37 | return $this->type;
38 | }
39 |
40 | public function getName(): string
41 | {
42 | return $this->name;
43 | }
44 |
45 | public function getLastName(): string
46 | {
47 | return $this->lastName;
48 | }
49 |
50 | public function getDefaultPaymentType(): string
51 | {
52 | return $this->defaultPaymentType;
53 | }
54 |
55 | public function getClientType(): string
56 | {
57 | return $this->clientType;
58 | }
59 |
60 | public function jsonSerialize(): array
61 | {
62 | return [
63 | 'id' => $this->id,
64 | 'type' => $this->type,
65 | 'name' => $this->name,
66 | 'lastName' => $this->lastName,
67 | 'paymentType' => $this->defaultPaymentType,
68 | 'clientType' => $this->clientType
69 | ];
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/Crm/ClientRepository.php:
--------------------------------------------------------------------------------
1 | em = $em;
14 | }
15 |
16 | public function getOne(int $clientId): ?Client
17 | {
18 | return $this->em->find(Client::class, $clientId);
19 | }
20 |
21 | public function save(Client $client): Client
22 | {
23 | $this->em->persist($client);
24 | $this->em->flush();
25 | return $client;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Crm/TransitAnalyzer/AnalyzedAddressesDTO.php:
--------------------------------------------------------------------------------
1 | addresses = $addresses;
20 | }
21 |
22 | public function jsonSerialize(): array
23 | {
24 | return [
25 | 'addresses' => $this->addresses
26 | ];
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Crm/TransitAnalyzer/PopulateGraphService.php:
--------------------------------------------------------------------------------
1 | transitDetailsFacade->findCompleted() as $transit) {
19 | $transitDetails = $this->transitDetailsFacade->find($transit->transitId);
20 | $this->graphTransitAnalyzer->addTransitBetweenAddresses(
21 | $transitDetails->client->getId(),
22 | $transit->transitId,
23 | $transitDetails->from->getHash(),
24 | $transitDetails->to->getHash(),
25 | $transitDetails->started,
26 | $transitDetails->completedAt
27 | );
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Crm/TransitAnalyzer/TransitAnalyzerController.php:
--------------------------------------------------------------------------------
1 | analyzer->analyze($clientId, $this->addressRepository->findHashById($addressId));
22 | return new JsonResponse(new AnalyzedAddressesDTO(array_map(
23 | fn (int $hash) => AddressDTO::from($this->addressRepository->getByHash($hash)),
24 | $addresses
25 | )));
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/DriverFleet/DriverAttributeDTO.php:
--------------------------------------------------------------------------------
1 | name = $name;
13 | $this->value = $value;
14 | }
15 |
16 | public static function with(string $name, string $value): self
17 | {
18 | return new self($name, $value);
19 | }
20 |
21 | public static function from(DriverAttribute $driverAttribute): self
22 | {
23 | return new self($driverAttribute->getName(), $driverAttribute->getValue());
24 | }
25 |
26 | public function jsonSerialize(): array
27 | {
28 | return [
29 | 'name' => $this->name,
30 | 'value' => $this->value
31 | ];
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/DriverFleet/DriverAttributeRepository.php:
--------------------------------------------------------------------------------
1 | em->persist($driverAttribute);
14 | $this->em->flush();
15 | return $driverAttribute;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/DriverFleet/DriverController.php:
--------------------------------------------------------------------------------
1 | toArray();
20 | $driver = $this->driverService->createDriver($data['license'], $data['lastName'], $data['firstName'], Driver::TYPE_CANDIDATE, Driver::STATUS_INACTIVE, $data['photo'] ?? null);
21 | return new JsonResponse($this->driverService->load($driver->getId()));
22 | }
23 |
24 | #[Route('/drivers/{id}', methods: ['GET'], )]
25 | public function getDriver(int $id): Response {return new JsonResponse($this->driverService->load($id));}
26 |
27 | #[Route('/drivers/{id}', methods: ['POST'], )]
28 | public function updateDriver(int $id): Response
29 | {
30 |
31 | return new JsonResponse($this->driverService->load($id));
32 | }
33 |
34 | #[Route('/drivers/{id}/deactivate', methods: ['POST'], )]
35 | public function deactivateDriver(int $id): Response
36 | {
37 | $this->driverService->changeDriverStatus($id, Driver::STATUS_INACTIVE);
38 | return new JsonResponse($this->driverService->load($id));
39 | }
40 |
41 | #[Route('/drivers/{id}/activate', methods: ['POST'], )]
42 | public function activateDriver(int $id): Response
43 | {
44 | $this->driverService->changeDriverStatus($id, Driver::STATUS_ACTIVE);
45 | return new JsonResponse($this->driverService->load($id));
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/DriverFleet/DriverFee.php:
--------------------------------------------------------------------------------
1 | type = $type;
32 | $this->driver = $driver;
33 | $this->amount = $amount;
34 | $this->min = $min;
35 | }
36 |
37 | public function getType(): string
38 | {
39 | return $this->type;
40 | }
41 |
42 | public function setType(string $type): void
43 | {
44 | $this->type = $type;
45 | }
46 |
47 | public function getDriver(): Driver
48 | {
49 | return $this->driver;
50 | }
51 |
52 | public function setDriver(Driver $driver): void
53 | {
54 | $this->driver = $driver;
55 | }
56 |
57 | public function getAmount(): int
58 | {
59 | return $this->amount;
60 | }
61 |
62 | public function setAmount(int $amount): void
63 | {
64 | $this->amount = $amount;
65 | }
66 |
67 | public function getMin(): ?Money
68 | {
69 | return $this->min;
70 | }
71 |
72 | public function setMin(?Money $min): void
73 | {
74 | $this->min = $min;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/DriverFleet/DriverFeeRepository.php:
--------------------------------------------------------------------------------
1 | em->getRepository(DriverFee::class)->findOneBy(['driver' => $driverId]);
14 | }
15 |
16 | public function save(DriverFee $driverFee): DriverFee
17 | {
18 | $this->em->persist($driverFee);
19 | $this->em->flush();
20 | return $driverFee;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/DriverFleet/DriverFeeService.php:
--------------------------------------------------------------------------------
1 | driverFeeRepository->findByDriverId($driverId);
17 | if($driverFee === null) {
18 | throw new \InvalidArgumentException('driver Fees not defined for driver, driver id = '.$driverId);
19 | }
20 | if($driverFee->getType() === DriverFee::TYPE_FLAT) {
21 | $finalFee = $transitPrice->subtract(Money::from($driverFee->getAmount()));
22 | } else {
23 | $finalFee = $transitPrice->percentage($driverFee->getAmount());
24 | }
25 |
26 | return Money::from((int) max($finalFee->toInt(), $driverFee->getMin() === null ? 0 : $driverFee->getMin()->toInt()));
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/DriverFleet/DriverLicense.php:
--------------------------------------------------------------------------------
1 | driverLicense = $driverLicense;
19 | }
20 |
21 | public static function withLicense(string $driverLicense): self
22 | {
23 | if($driverLicense === '' || preg_match(self::DRIVER_LICENSE_REGEX, $driverLicense) !== 1) {
24 | throw new \InvalidArgumentException('Illegal license no = '.$driverLicense);
25 | }
26 |
27 | return new self($driverLicense);
28 | }
29 |
30 | public static function withoutValidation(string $driverLicense): self
31 | {
32 | return new self($driverLicense);
33 | }
34 |
35 | public function asString(): string
36 | {
37 | return $this->driverLicense;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/DriverFleet/DriverReport/DriverReport.php:
--------------------------------------------------------------------------------
1 |
21 | */
22 | private array $sessions = [];
23 |
24 | public function __construct()
25 | {
26 | }
27 |
28 | public function getDriverDTO(): DriverDTO
29 | {
30 | return $this->driverDTO;
31 | }
32 |
33 | public function setDriverDTO(DriverDTO $driverDTO): void
34 | {
35 | $this->driverDTO = $driverDTO;
36 | }
37 |
38 | public function getAttributes(): array
39 | {
40 | return $this->attributes;
41 | }
42 |
43 | /**
44 | * @param DriverAttributeDTO[] $attributes
45 | */
46 | public function setAttributes(array $attributes): void
47 | {
48 | $this->attributes = $attributes;
49 | }
50 |
51 | public function addAttr(string $name, string $value): void
52 | {
53 | $this->attributes[] = DriverAttributeDTO::with($name, $value);
54 | }
55 |
56 | public function getSessions(): array
57 | {
58 | return $this->sessions;
59 | }
60 |
61 | /**
62 | * @param array $sessions
63 | */
64 | public function setSessions(array $sessions): void
65 | {
66 | $this->sessions = $sessions;
67 | }
68 |
69 | public function jsonSerialize()
70 | {
71 | return [
72 | 'driver' => $this->driverDTO,
73 | 'attributes' => $this->attributes,
74 | 'sessions' => $this->sessions
75 | ];
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/DriverFleet/DriverReport/DriverReportController.php:
--------------------------------------------------------------------------------
1 | driverReportCreator->createReport($driverId, (int) $request->get('lastDays', 1)));
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/DriverFleet/DriverRepository.php:
--------------------------------------------------------------------------------
1 | em->persist($driver);
14 | $this->em->flush();
15 | return $driver;
16 | }
17 |
18 | public function getOne(int $driverId): ?Driver
19 | {
20 | return $this->em->find(Driver::class, $driverId);
21 | }
22 |
23 | /**
24 | * @param int[] $ids
25 | * @return Driver[]
26 | */
27 | public function findAllByIds(array $ids): array
28 | {
29 | return $this->em->getRepository(Driver::class)->findBy(['id' => $ids]);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Geolocation/Address/AddressRepository.php:
--------------------------------------------------------------------------------
1 | em = $em;
14 | }
15 |
16 | public function getOne(int $addressId): ?Address
17 | {
18 | return $this->em->find(Address::class, $addressId);
19 | }
20 |
21 | // FIX ME: To replace with getOrCreate method instead of that?
22 | // Actual workaround for address uniqueness problem: assign result from repo.save to variable for later usage
23 | public function save(Address $address): Address
24 | {
25 | $address->hash();
26 | if(!$this->isIdSet($address)) {
27 | $existingAddress = $this->em->getRepository(Address::class)->findOneBy(['hash' => $address->getHash()]);
28 | if($existingAddress !== null) {
29 | return $existingAddress;
30 | }
31 | }
32 | $this->em->persist($address);
33 | $this->em->flush();
34 | return $address;
35 | }
36 |
37 | public function findHashById(int $id): int
38 | {
39 | return (int) $this->em->getConnection()->executeQuery(
40 | 'SELECT hash FROM address WHERE id = :id',
41 | ['id' => $id]
42 | )->fetchOne();
43 | }
44 |
45 | public function getByHash(int $hash): Address
46 | {
47 | return $this->em->getRepository(Address::class)->findOneBy(['hash' => $hash]);
48 | }
49 |
50 | private function isIdSet(Address $address): bool
51 | {
52 | try {
53 | $address->getId();
54 | return true;
55 | } catch (\Throwable $exception) {
56 | return false;
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/Geolocation/Distance.php:
--------------------------------------------------------------------------------
1 | km + $travelled->km);
26 | }
27 |
28 | public function toKmInFloat(): float
29 | {
30 | return $this->km;
31 | }
32 |
33 | public function printIn(string $unit): string
34 | {
35 | if($unit === 'km') {
36 | if($this->km === ceil($this->km)) {
37 | return sprintf('%d', round($this->km)).'km';
38 | }
39 | return sprintf('%.3f', $this->km).'km';
40 | }
41 | if($unit === 'miles') {
42 | $distance = $this->km / self::MILES_TO_KILOMETERS_RATIO;
43 | if($distance === ceil($distance)) {
44 | return sprintf('%d', round($distance)).'miles';
45 | }
46 | return sprintf('%.3f', $distance).'miles';
47 | }
48 | if($unit === 'm') {
49 | return sprintf('%d', round($this->km * 1000)).'m';
50 | }
51 | throw new \InvalidArgumentException('Invalid unit '.$unit);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/Geolocation/DistanceCalculator.php:
--------------------------------------------------------------------------------
1 | toKmInFloat();
27 | }
28 |
29 | public function requiresSQLCommentHint(AbstractPlatform $platform)
30 | {
31 | return true;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Geolocation/GeocodingService.php:
--------------------------------------------------------------------------------
1 | amount = $amount;
21 | $this->subjectName = $subjectName;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Invocing/InvoiceGenerator.php:
--------------------------------------------------------------------------------
1 | invoiceRepository = $invoiceRepository;
12 | }
13 |
14 | public function generate(float $amount, string $subjectName): Invoice
15 | {
16 | return $this->invoiceRepository->save(new Invoice($amount, $subjectName));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Invocing/InvoiceRepository.php:
--------------------------------------------------------------------------------
1 | em->persist($invoice);
14 | $this->em->flush();
15 | return $invoice;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Kernel.php:
--------------------------------------------------------------------------------
1 | import('../config/{packages}/*.yaml');
19 | $container->import('../config/{packages}/'.$this->environment.'/*.yaml');
20 |
21 | if (is_file(\dirname(__DIR__).'/config/services.yaml')) {
22 | $container->import('../config/services.yaml');
23 | $container->import('../config/{services}_'.$this->environment.'.yaml');
24 | } else {
25 | $container->import('../config/{services}.php');
26 | }
27 | }
28 |
29 | protected function configureRoutes(RoutingConfigurator $routes): void
30 | {
31 | $routes->import('../config/{routes}/'.$this->environment.'/*.yaml');
32 | $routes->import('../config/{routes}/*.yaml');
33 |
34 | if (is_file(\dirname(__DIR__).'/config/routes.yaml')) {
35 | $routes->import('../config/routes.yaml');
36 | } else {
37 | $routes->import('../config/{routes}.php');
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Loyalty/AwardsAccountDTO.php:
--------------------------------------------------------------------------------
1 | clientDTO = $clientDTO;
17 | $this->date = $account->getDate();
18 | $this->isActive = $account->isActive();
19 | $this->transactions = $account->getTransactions();
20 | }
21 |
22 | public static function from(AwardsAccount $account, ClientDTO $clientDTO): self
23 | {
24 | return new self($account, $clientDTO);
25 | }
26 |
27 | public function getClient(): ClientDTO
28 | {
29 | return $this->clientDTO;
30 | }
31 |
32 | public function isActive(): bool
33 | {
34 | return $this->isActive;
35 | }
36 |
37 | public function getTransactions(): int
38 | {
39 | return $this->transactions;
40 | }
41 |
42 | public function jsonSerialize(): array
43 | {
44 | return [
45 | 'client' => $this->clientDTO,
46 | 'date' => $this->date->format('Y-m-d H:i:s'),
47 | 'active' => $this->isActive,
48 | 'transactions' => $this->transactions
49 | ];
50 | }
51 |
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/Loyalty/AwardsAccountRepository.php:
--------------------------------------------------------------------------------
1 | em->getRepository(AwardsAccount::class)->findOneBy(['clientId' => $clientId]);
15 | }
16 |
17 | public function save(AwardsAccount $account): void
18 | {
19 | $this->em->persist($account);
20 | $this->em->flush();
21 | }
22 |
23 | /**
24 | * @return AwardedMiles[]
25 | */
26 | public function findAllMilesBy(Client $client): array
27 | {
28 | return $this->findByClientId($client->getId())?->getMiles() ?? [];
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Loyalty/AwardsService.php:
--------------------------------------------------------------------------------
1 | amount = $amount;
13 | $this->whenExpires = $whenExpires;
14 | }
15 |
16 | public static function untilForever(int $amount): self
17 | {
18 | return new self($amount, null);
19 | }
20 |
21 | public static function until(int $amount, \DateTimeImmutable $when): self
22 | {
23 | return new self($amount, $when);
24 | }
25 |
26 | public function getAmountFor(\DateTimeImmutable $moment): int
27 | {
28 | return $this->whenExpires === null || $this->whenExpires >= $moment ? $this->amount : 0;
29 | }
30 |
31 | public function subtract(int $amount, \DateTimeImmutable $moment): Miles
32 | {
33 | if($this->getAmountFor($moment) < $amount) {
34 | throw new \InvalidArgumentException('Insufficient amount of miles');
35 | }
36 | return new self($this->amount - $amount, $this->whenExpires);
37 | }
38 |
39 | public function expiresAt(): ?\DateTimeImmutable
40 | {
41 | return $this->whenExpires;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/Loyalty/Miles.php:
--------------------------------------------------------------------------------
1 | amount = $amount;
14 | $this->whenFirstHalfExpires = $whenFirstHalfExpires;
15 | $this->whenExpires = $whenExpires;
16 | }
17 |
18 | public function getAmountFor(\DateTimeImmutable $moment): int
19 | {
20 | if($this->whenFirstHalfExpires >= $moment) {
21 | return $this->amount;
22 | }
23 |
24 | if($this->whenExpires >= $moment) {
25 | return $this->amount - $this->halfOf($this->amount);
26 | }
27 |
28 | return 0;
29 | }
30 |
31 | private function halfOf(int $amount): int
32 | {
33 | return $amount / 2;
34 | }
35 |
36 | public function subtract(int $amount, \DateTimeImmutable $moment): Miles
37 | {
38 | $currentAmount = $this->getAmountFor($moment);
39 | if($currentAmount < $amount) {
40 | throw new \InvalidArgumentException('Insufficient amount of miles');
41 | }
42 | return new self($currentAmount - $amount, $this->whenFirstHalfExpires, $this->whenExpires);
43 | }
44 |
45 | public function expiresAt(): ?\DateTimeImmutable
46 | {
47 | return $this->whenExpires;
48 | }
49 |
50 | public function getWhenFirstHalfExpires(): \DateTimeImmutable
51 | {
52 | return $this->whenFirstHalfExpires;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Money/Money.php:
--------------------------------------------------------------------------------
1 | value = $value;
12 | }
13 |
14 | public static function from(int $value): self
15 | {
16 | return new self($value);
17 | }
18 |
19 | public static function zero(): self
20 | {
21 | return new self(0);
22 | }
23 |
24 | public function add(self $other): self
25 | {
26 | return new self($this->value + $other->value);
27 | }
28 |
29 | public function subtract(self $other): self
30 | {
31 | return new self($this->value - $other->value);
32 | }
33 |
34 | public function percentage(int $percentage): self
35 | {
36 | return new self((int) round($percentage * $this->value/100));
37 | }
38 |
39 | public function toInt(): int
40 | {
41 | return $this->value;
42 | }
43 |
44 | public function toString(): string
45 | {
46 | return sprintf('%.2f', $this->value / 100);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Money/MoneyType.php:
--------------------------------------------------------------------------------
1 | toInt();
27 | }
28 |
29 | public function requiresSQLCommentHint(AbstractPlatform $platform)
30 | {
31 | return true;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Notification/ClientNotificationService.php:
--------------------------------------------------------------------------------
1 | id = Uuid::v4();
14 | }
15 |
16 | public function toUuid(): Uuid
17 | {
18 | return $this->id;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Party/Api/PartyMapper.php:
--------------------------------------------------------------------------------
1 | repository = $repository;
16 | }
17 |
18 | /**
19 | * @return Option
20 | */
21 | public function mapRelation(PartyId $id, string $relationshipName): Option
22 | {
23 | return $this->repository->findRelationshipFor($id, $relationshipName);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Party/Api/RoleObjectFactory.php:
--------------------------------------------------------------------------------
1 |
18 | */
19 | private array $roles = [];
20 |
21 | public static function from(PartyRelationship $relationship): self
22 | {
23 | $roleObject = new self();
24 | $roleObject->addRelationship($relationship);
25 |
26 | return $roleObject;
27 | }
28 |
29 | public function hasRole(string $role): bool
30 | {
31 | return isset($this->roles[$role]);
32 | }
33 |
34 | public function getRole(string $class): Option
35 | {
36 | return Option::of($this->roles[$class] ?? null);
37 | }
38 |
39 | private function addRelationship(PartyRelationship $relationship): void
40 | {
41 | $this->add($relationship->getRoleA(), $relationship->getPartyA());
42 | $this->add($relationship->getRoleB(), $relationship->getPartyB());
43 | }
44 |
45 | private function add(string $role, Party $party): void
46 | {
47 | //in sake of simplicity: a role name is same as a class name with no mapping between them
48 | if(!class_exists($role) || !is_subclass_of($role, PartyBasedRole::class)) {
49 | throw new \InvalidArgumentException();
50 | }
51 | $parentClass = get_parent_class($role);
52 | $key = $parentClass !== PartyBasedRole::class ? $parentClass : $role;
53 |
54 | $this->roles[$key] = new $role($party);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Party/Infra/DoctrinePartyRepository.php:
--------------------------------------------------------------------------------
1 | em->find(Party::class, $id);
19 | if($party === null) {
20 | $party = new Party($id);
21 | $this->em->persist($party);
22 | $this->em->flush();
23 | }
24 |
25 | return $party;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/Party/Model/Party/Party.php:
--------------------------------------------------------------------------------
1 | id = $id;
20 | }
21 |
22 | public function getId(): Uuid
23 | {
24 | return $this->id;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Party/Model/Party/PartyRelationship.php:
--------------------------------------------------------------------------------
1 | id = Uuid::v4();
36 | }
37 |
38 | public function getName(): string
39 | {
40 | return $this->name;
41 | }
42 |
43 | public function setName(string $name): void
44 | {
45 | $this->name = $name;
46 | }
47 |
48 | public function getRoleA(): string
49 | {
50 | return $this->roleA;
51 | }
52 |
53 | public function setRoleA(string $roleA): void
54 | {
55 | $this->roleA = $roleA;
56 | }
57 |
58 | public function getRoleB(): string
59 | {
60 | return $this->roleB;
61 | }
62 |
63 | public function setRoleB(string $roleB): void
64 | {
65 | $this->roleB = $roleB;
66 | }
67 |
68 | public function getPartyA(): Party
69 | {
70 | return $this->partyA;
71 | }
72 |
73 | public function setPartyA(Party $partyA): void
74 | {
75 | $this->partyA = $partyA;
76 | }
77 |
78 | public function getPartyB(): Party
79 | {
80 | return $this->partyB;
81 | }
82 |
83 | public function setPartyB(Party $partyB): void
84 | {
85 | $this->partyB = $partyB;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/Party/Model/Party/PartyRelationshipRepository.php:
--------------------------------------------------------------------------------
1 |
14 | */
15 | public function findRelationshipFor(PartyId $id, string $relationshipName): Option;
16 | }
17 |
--------------------------------------------------------------------------------
/src/Party/Model/Party/PartyRepository.php:
--------------------------------------------------------------------------------
1 | id = Uuid::v4();
22 | }
23 |
24 | public function getName(): string
25 | {
26 | return $this->name;
27 | }
28 |
29 | public function setName(string $name): void
30 | {
31 | $this->name = $name;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Party/Model/Role/PartyBasedRole.php:
--------------------------------------------------------------------------------
1 | party = $party;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Pricing/Tariffs.php:
--------------------------------------------------------------------------------
1 | partyRepository->put($insurerId->toUuid());
21 | $vehicle = $this->partyRepository->put($vehicleId->toUuid());
22 |
23 | $this->partyRelationshipRepository->put(
24 | PartyRelationshipsDictionary::REPAIR,
25 | PartyRolesDictionary::INSURER, $insurer,
26 | PartyRolesDictionary::INSURED, $vehicle
27 | );
28 | }
29 |
30 | public function manufacturerWarrantyRegistered(PartyId $distributorId, PartyId $vehicleId): void
31 | {
32 | $distributor = $this->partyRepository->put($distributorId->toUuid());
33 | $vehicle = $this->partyRepository->put($vehicleId->toUuid());
34 |
35 | $this->partyRelationshipRepository->put(
36 | PartyRelationshipsDictionary::REPAIR,
37 | PartyRolesDictionary::GUARANTOR, $distributor,
38 | PartyRolesDictionary::CUSTOMER, $vehicle
39 | );
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Repair/Api/RepairRequest.php:
--------------------------------------------------------------------------------
1 | vehicle = $vehicle;
19 | $this->partsToRepair = $partsToRepair;
20 | }
21 |
22 | public function getVehicle(): PartyId
23 | {
24 | return $this->vehicle;
25 | }
26 |
27 | public function getPartsToRepair(): array
28 | {
29 | return $this->partsToRepair;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Repair/Api/ResolveResult.php:
--------------------------------------------------------------------------------
1 | handlingParty = $handlingParty;
21 | $this->totalCost = $totalCost;
22 | $this->acceptedParts = $acceptedParts;
23 | $this->status = $status;
24 | }
25 |
26 | public function getHandlingParty(): ?Uuid
27 | {
28 | return $this->handlingParty;
29 | }
30 |
31 | public function getTotalCost(): ?Money
32 | {
33 | return $this->totalCost;
34 | }
35 |
36 | public function getAcceptedParts(): array
37 | {
38 | return $this->acceptedParts;
39 | }
40 |
41 | public function getStatus(): string
42 | {
43 | return $this->status;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Repair/Legacy/DAO/UserDAO.php:
--------------------------------------------------------------------------------
1 | setCoveredParts([Parts::ENGINE, Parts::GEARBOX, Parts::PAINT, Parts::SUSPENSION]);
19 | $contract->setCoverageRatio(100);
20 |
21 | $user = new EmployeeDriverWithOwnCar();
22 | $user->setContract($contract);
23 |
24 | return $user;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Repair/Legacy/Job/CommonBaseAbstractJob.php:
--------------------------------------------------------------------------------
1 |
15 | */
16 | private array $params = [];
17 |
18 | public function __construct(string $decision)
19 | {
20 | if(!in_array($decision, [self::DECISION_ACCEPTED, self::DECISION_ERROR, self::DECISION_REDIRECTION])) {
21 | throw new \InvalidArgumentException();
22 | }
23 |
24 | $this->decision = $decision;
25 | }
26 |
27 | public function addParam(string $name, $value): self
28 | {
29 | $this->params[$name] = $value;
30 |
31 | return $this;
32 | }
33 |
34 | /**
35 | * @return mixed|null
36 | */
37 | public function getParam(string $name)
38 | {
39 | return $this->params[$name] ?? null;
40 | }
41 |
42 | public function getDecision(): string
43 | {
44 | return $this->decision;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Repair/Legacy/Job/MaintenanceJob.php:
--------------------------------------------------------------------------------
1 | partsToRepair = [];
18 | $this->estimatedValue = Money::zero();
19 | }
20 |
21 | public function getPartsToRepair(): array
22 | {
23 | return $this->partsToRepair;
24 | }
25 |
26 | public function getEstimatedValue(): Money
27 | {
28 | return $this->estimatedValue;
29 | }
30 |
31 | /**
32 | * @param string[] $partsToRepair
33 | */
34 | public function setPartsToRepair(array $partsToRepair): void
35 | {
36 | $this->partsToRepair = $partsToRepair;
37 | }
38 |
39 | public function setEstimatedValue(Money $estimatedValue): void
40 | {
41 | $this->estimatedValue = $estimatedValue;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/Repair/Legacy/Parts/Parts.php:
--------------------------------------------------------------------------------
1 | userDAO = $userDAO;
16 | }
17 |
18 | public function repair(int $userId, CommonBaseAbstractJob $job): JobResult
19 | {
20 | $user = $this->userDAO->getOne($userId);
21 | return $user->doJob($job);
22 | }
23 |
24 | public function repair2parallelModels(int $userId, CommonBaseAbstractJob $job): JobResult
25 | {
26 | $user = $this->userDAO->getOne($userId);
27 | return $user->doJob($job);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Repair/Legacy/User/CommonBaseAbstractUser.php:
--------------------------------------------------------------------------------
1 | handleRepairJob($job);
18 | }
19 | if($job instanceof MaintenanceJob) {
20 | return $this->handleMaintenanceJob($job);
21 | }
22 |
23 | return $this->defaultHandler($job);
24 | }
25 |
26 | protected function handleRepairJob(RepairJob $job): JobResult
27 | {
28 | return $this->defaultHandler($job);
29 | }
30 |
31 | protected function handleMaintenanceJob(MaintenanceJob $job): JobResult
32 | {
33 | return $this->defaultHandler($job);
34 | }
35 |
36 | protected function defaultHandler(CommonBaseAbstractJob $job): JobResult
37 | {
38 | throw new \InvalidArgumentException(sprintf('%s can not handle %s', static::class, get_class($job)));
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Repair/Legacy/User/EmployeeDriver.php:
--------------------------------------------------------------------------------
1 | addParam('shouldHandleBy', $this->lasingCompanyId);
15 | }
16 |
17 | public function getLasingCompanyId(): int
18 | {
19 | return $this->lasingCompanyId;
20 | }
21 |
22 | public function setLasingCompanyId(int $lasingCompanyId): void
23 | {
24 | $this->lasingCompanyId = $lasingCompanyId;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Repair/Legacy/User/EmployeeDriverWithOwnCar.php:
--------------------------------------------------------------------------------
1 | getPartsToRepair(), $this->contract->getCoveredParts());
15 |
16 | $coveredCost = $job->getEstimatedValue()->percentage((int) $this->contract->getCoverageRatio());
17 | $totalCost = $job->getEstimatedValue()->subtract($coveredCost);
18 |
19 | return (new JobResult(JobResult::DECISION_ACCEPTED))->addParam('totalCost', $totalCost)->addParam('acceptedParts',$acceptedParts);
20 | }
21 |
22 |
23 | public function setContract(SignedContract $contract): void
24 | {
25 | $this->contract = $contract;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Repair/Legacy/User/SignedContract.php:
--------------------------------------------------------------------------------
1 | coveredParts;
27 | }
28 |
29 | /**
30 | * @param string[] $coveredParts
31 | */
32 | public function setCoveredParts(array $coveredParts): void
33 | {
34 | $this->coveredParts = $coveredParts;
35 | }
36 |
37 | public function getCoverageRatio(): float
38 | {
39 | return $this->coverageRatio;
40 | }
41 |
42 | public function setCoverageRatio(float $coverageRatio): void
43 | {
44 | $this->coverageRatio = $coverageRatio;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Repair/Legacy/User/SubcontractorDriver.php:
--------------------------------------------------------------------------------
1 | getPartsToRepair(), fn(string $part) => $part !== Parts::PAINT);
14 |
15 | return new RepairingResult($this->party->getId(), Money::zero(), $handledParts);
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/Repair/Model/Roles/Repair/RepairingResult.php:
--------------------------------------------------------------------------------
1 | handlingParty = $handlingParty;
17 | $this->totalCost = $totalCost;
18 | $this->handledParts = $handledParts;
19 | }
20 |
21 | public function getHandlingParty(): Uuid
22 | {
23 | return $this->handlingParty;
24 | }
25 |
26 | public function getTotalCost(): Money
27 | {
28 | return $this->totalCost;
29 | }
30 |
31 | public function getHandledParts(): array
32 | {
33 | return $this->handledParts;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Repair/Model/Roles/Repair/RoleForRepairer.php:
--------------------------------------------------------------------------------
1 | party->getId(), Money::zero(), $request->getPartsToRepair());
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Ride/ChangeDestinationService.php:
--------------------------------------------------------------------------------
1 | geocodingService->geocodeAddress($from);
25 | $geoTo = $this->geocodingService->geocodeAddress($newAddress);
26 | $newDistance = Distance::ofKm($this->distanceCalculator->calculateByMap($geoFrom[0], $geoFrom[1], $geoTo[0], $geoTo[1]));
27 | $transit = $this->transitRepository->findByTransitRequestUuid($requestUuid);
28 | $transit?->changeDestination($newDistance);
29 | return $newDistance;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Ride/CompleteTransitService.php:
--------------------------------------------------------------------------------
1 | transitRepository->findByTransitRequestUuid($requestUuid);
25 | if($transit === null) {
26 | throw new \InvalidArgumentException('Transit does not exist, id = '.$requestUuid);
27 | }
28 |
29 | // FIXME later: add some exceptions handling
30 | $geoFrom = $this->geocodingService->geocodeAddress($from);
31 | $geoTo = $this->geocodingService->geocodeAddress($destinationAddress);
32 | $distance = Distance::ofKm($this->distanceCalculator->calculateByMap($geoFrom[0], $geoFrom[1], $geoTo[0], $geoTo[1]));
33 | $finalPrice = $transit->completeAt($distance);
34 | $this->transitRepository->save($transit);
35 |
36 | return $finalPrice;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Ride/DemandService.php:
--------------------------------------------------------------------------------
1 | transitDemandRepository->save(new TransitDemand($requestUuid));
18 | }
19 |
20 | public function cancelDemand(Uuid $requestUuid): void
21 | {
22 | $transitDemand = $this->transitDemandRepository->findByRequestUuid($requestUuid);
23 | if($transitDemand !== null) {
24 | $transitDemand->cancel();
25 | }
26 | }
27 |
28 | public function acceptDemand(Uuid $requestUuid): void
29 | {
30 | $transitDemand = $this->transitDemandRepository->findByRequestUuid($requestUuid);
31 | if($transitDemand !== null) {
32 | $transitDemand->accept();
33 | }
34 | }
35 |
36 | public function existsFor(Uuid $requestUuid): bool
37 | {
38 | return $this->transitDemandRepository->findByRequestUuid($requestUuid) !== null;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Ride/Details/Status.php:
--------------------------------------------------------------------------------
1 | clientId;
19 | }
20 |
21 | public function transitId(): int
22 | {
23 | return $this->transitId;
24 | }
25 |
26 | public function addressFromHash(): int
27 | {
28 | return $this->addressFromHash;
29 | }
30 |
31 | public function addressToHash(): int
32 | {
33 | return $this->addressToHash;
34 | }
35 |
36 | public function started(): \DateTimeImmutable
37 | {
38 | return $this->started;
39 | }
40 |
41 | public function completeAt(): \DateTimeImmutable
42 | {
43 | return $this->completeAt;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Ride/RequestForTransit.php:
--------------------------------------------------------------------------------
1 | requestUuid = Uuid::v4();
29 | $this->tariff = $tariff;
30 | $this->distance = $distance;
31 | }
32 |
33 | public function getEstimatedPrice(): Money
34 | {
35 | return $this->tariff->calculateCost($this->distance);
36 | }
37 |
38 | public function getRequestUuid(): Uuid
39 | {
40 | return $this->requestUuid;
41 | }
42 |
43 | public function getTariff(): Tariff
44 | {
45 | return $this->tariff;
46 | }
47 |
48 | public function getDistance(): Distance
49 | {
50 | return $this->distance;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Ride/RequestForTransitRepository.php:
--------------------------------------------------------------------------------
1 | em->find(RequestForTransit::class, $id);
15 | }
16 |
17 | public function findByRequestUuid(Uuid $requestUuid): ?RequestForTransit
18 | {
19 | return $this->em->getRepository(RequestForTransit::class)->findOneBy([
20 | 'requestUuid' => $requestUuid
21 | ]);
22 | }
23 |
24 | public function save(RequestForTransit $requestForTransit): RequestForTransit
25 | {
26 | $this->em->persist($requestForTransit);
27 | $this->em->flush();
28 | return $requestForTransit;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Ride/RequestTransitService.php:
--------------------------------------------------------------------------------
1 | geocodingService->geocodeAddress($from);
30 | $geoTo = $this->geocodingService->geocodeAddress($to);
31 | $distance = Distance::ofKm($this->distanceCalculator->calculateByMap($geoFrom[0], $geoFrom[1], $geoTo[0], $geoTo[1]));
32 | $now = $this->clock->now();
33 | $tariff = $this->tariffs->choose($now);
34 | return $this->requestForTransitRepository->save(new RequestForTransit($tariff, $distance));
35 | }
36 |
37 | public function findCalculationUUID(int $requestId): Uuid
38 | {
39 | return $this->requestForTransitRepository->getOne($requestId)->getRequestUuid();
40 | }
41 |
42 | public function findTariff(Uuid $requestUuid): Tariff
43 | {
44 | return $this->requestForTransitRepository->findByRequestUuid($requestUuid)->getTariff();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Ride/StartTransitService.php:
--------------------------------------------------------------------------------
1 | transitRepository->save(new Transit($this->requestTransitService->findTariff($requestUuid), $requestUuid));
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Ride/TransitDemandRepository.php:
--------------------------------------------------------------------------------
1 | em->getRepository(TransitDemand::class)->findOneBy([
15 | 'requestUuid' => $requestUuid
16 | ]);
17 | }
18 |
19 | public function save(TransitDemand $transitDemand): TransitDemand
20 | {
21 | $this->em->persist($transitDemand);
22 | $this->em->flush();
23 | return $transitDemand;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Tracking/DriverPosition.php:
--------------------------------------------------------------------------------
1 | driverId = $driverId;
27 | $this->latitude = $latitude;
28 | $this->longitude = $longitude;
29 | $this->seenAt = $seenAt;
30 | }
31 |
32 | public function getDriverId(): int
33 | {
34 | return $this->driverId;
35 | }
36 |
37 | public function getLatitude(): float
38 | {
39 | return $this->latitude;
40 | }
41 |
42 | public function getLongitude(): float
43 | {
44 | return $this->longitude;
45 | }
46 |
47 | public function getSeenAt(): \DateTimeImmutable
48 | {
49 | return $this->seenAt;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/Tracking/DriverPositionDTO.php:
--------------------------------------------------------------------------------
1 | driverId = $driverId;
15 | $this->latitude = $latitude;
16 | $this->longitude = $longitude;
17 | $this->seenAt = $seenAt;
18 | }
19 |
20 | public static function from(int $driverId, float $latitude, float $longitude, \DateTimeImmutable $seenAt): self
21 | {
22 | return new self($driverId, $latitude, $longitude, $seenAt);
23 | }
24 |
25 | public function getDriverId(): int
26 | {
27 | return $this->driverId;
28 | }
29 |
30 | public function getLatitude(): float
31 | {
32 | return $this->latitude;
33 | }
34 |
35 | public function getLongitude(): float
36 | {
37 | return $this->longitude;
38 | }
39 |
40 | public function getSeenAt(): \DateTimeImmutable
41 | {
42 | return $this->seenAt;
43 | }
44 |
45 | public function jsonSerialize(): array
46 | {
47 | return [
48 | 'driverId' => $this->driverId,
49 | 'latitude' => $this->latitude,
50 | 'longitude' => $this->longitude,
51 | 'seenAt' => $this->seenAt->format('Y-m-d H:i:s')
52 | ];
53 | }
54 |
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/Tracking/DriverPositionDTOV2.php:
--------------------------------------------------------------------------------
1 | driverId = $driverId;
15 | $this->latitude = $latitude;
16 | $this->longitude = $longitude;
17 | $this->seenAt = $seenAt;
18 | }
19 |
20 | public function getDriverId(): int
21 | {
22 | return $this->driverId;
23 | }
24 |
25 | public function getLatitude(): float
26 | {
27 | return $this->latitude;
28 | }
29 |
30 | public function getLongitude(): float
31 | {
32 | return $this->longitude;
33 | }
34 |
35 | public function getSeenAt(): \DateTimeImmutable
36 | {
37 | return $this->seenAt;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Tracking/DriverPositionRepository.php:
--------------------------------------------------------------------------------
1 | em->persist($driverPosition);
15 | $this->em->flush();
16 | return $driverPosition;
17 | }
18 |
19 | /**
20 | * @return DriverPositionDTOV2[]
21 | */
22 | public function findAverageDriverPositionSince(float $latitudeMin, float $latitudeMax, float $longitudeMin, float $longitudeMax, \DateTimeImmutable $date): array
23 | {
24 | return \array_map(
25 | static fn (array $data): DriverPositionDTOV2 => new DriverPositionDTOV2($data['driver'], $data['lat'], $data['lon'], new \DateTimeImmutable($data['seen'])),
26 | $this->em->createQueryBuilder()
27 | ->select(\sprintf('d.id as driver, avg(p.latitude) as lat, avg(p.longitude) as lon, max(p.seenAt) as seen'))
28 | ->from(Driver::class, 'd')
29 | ->join(DriverPosition::class, 'p', 'WITH', 'p.driverId = d.id')
30 | ->where('p.latitude between :latitudeMin and :latitudeMax')
31 | ->andWhere('p.longitude between :longitudeMin and :longitudeMax')
32 | ->andWhere('p.seenAt >= :seenAt')
33 | ->setParameters([
34 | 'latitudeMin' => $latitudeMin,
35 | 'latitudeMax' => $latitudeMax,
36 | 'longitudeMin' => $longitudeMin,
37 | 'longitudeMax' => $longitudeMax,
38 | 'seenAt' => $date
39 | ])
40 | ->groupBy('d.id')
41 | ->getQuery()
42 | ->getResult());
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Tracking/DriverSessionController.php:
--------------------------------------------------------------------------------
1 | driverSessionService->logIn($driverId, $driverSessionDTO->getPlatesNumber(), $driverSessionDTO->getCarClass(), $driverSessionDTO->getCarBrand());
19 | return new JsonResponse();
20 | }
21 |
22 | #[Route('/drivers/{driverId}/driverSessions/{sessionId}', methods: ['DELETE'])]
23 | public function logOut(int $driverId, int $sessionId): Response
24 | {
25 | $this->driverSessionService->logOut($sessionId);
26 | return new JsonResponse();
27 | }
28 |
29 | #[Route('/drivers/{driverId}/driverSessions', methods: ['DELETE'])]
30 | public function logOutCurrent(int $driverId): Response
31 | {
32 | $this->driverSessionService->logOutCurrentSession($driverId);
33 | return new JsonResponse();
34 | }
35 |
36 | #[Route('/drivers/{driverId}/driverSessions', methods: ['GET'])]
37 | public function list(int $driverId): Response
38 | {
39 | return new JsonResponse(array_map(
40 | fn(DriverSession $s) => DriverSessionDTO::from($s),
41 | $this->driverSessionService->findByDriver($driverId)
42 | ));
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Tracking/DriverTrackingController.php:
--------------------------------------------------------------------------------
1 | trackingService->registerPosition($driverPositionDTO->getDriverId(), $driverPositionDTO->getLatitude(), $driverPositionDTO->getLongitude(), $driverPositionDTO->getSeenAt());
18 | return new JsonResponse($this->toDto($driverPosition));
19 | }
20 |
21 | #[Route('/driverPositions/{id}/total', methods: ['GET'])]
22 | public function calculateTravelledDistance(int $id, Request $request): Response
23 | {
24 | return new JsonResponse($this->trackingService->calculateTravelledDistance($id, new \DateTimeImmutable($request->get('from')), new \DateTimeImmutable($request->get('to')))->toKmInFloat());
25 | }
26 |
27 | private function toDto(DriverPosition $driverPosition): DriverPositionDTO
28 | {
29 | return DriverPositionDTO::from(
30 | $driverPosition->getDriverId(),
31 | $driverPosition->getLatitude(),
32 | $driverPosition->getLongitude(),
33 | $driverPosition->getSeenAt()
34 | );
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tests/Common/AddressFixture.php:
--------------------------------------------------------------------------------
1 | setPostalCode('11-111');
20 | $address->setName('Home');
21 | $address->setDistrict('district');
22 | return $this->addressRepository->save($address);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tests/Common/AwardsAccountFixture.php:
--------------------------------------------------------------------------------
1 | awardsService->registerToProgram($client->getId());
19 | }
20 |
21 | public function activeAwardsAccount(Client $client): void
22 | {
23 | $this->awardsAccount($client);
24 | $this->awardsService->activateAccount($client->getId());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/Common/CarTypeFixture.php:
--------------------------------------------------------------------------------
1 | carTypeService->create($carTypeDTO);
23 | $this->carTypeService->registerCar($carClass);
24 | $this->carTypeService->activate($carType->getId());
25 | return $carType;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/tests/Common/ClaimFixture.php:
--------------------------------------------------------------------------------
1 | getId(), $transit->getId());
23 | $claimDto->setIsDraft(false);
24 | return $this->claimService->create($claimDto);
25 | }
26 |
27 | public function createAndResolveClaim(Client $client, TransitDTO $transit): Claim
28 | {
29 | $claim = $this->createClaim($client, $transit);
30 | $this->claimService->tryToResolveAutomatically($claim->getId());
31 | return $claim;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/tests/Common/ClientFixture.php:
--------------------------------------------------------------------------------
1 | setName('Janusz');
20 | $client->setLastName('Kowalski');
21 | $client->setType($type);
22 | $client->setDefaultPaymentType(Client::PAYMENT_TYPE_MONTHLY_INVOICE);
23 | return $this->clientRepository->save($client);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/tests/Common/Factory.php:
--------------------------------------------------------------------------------
1 | fixed ?? new \DateTimeImmutable();
14 | }
15 |
16 | public function setDateTime(?\DateTimeImmutable $dateTime): void
17 | {
18 | $this->fixed = $dateTime;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tests/Common/PrivateProperty.php:
--------------------------------------------------------------------------------
1 | getProperty('id');
11 | $property->setAccessible(true);
12 | $property->setValue($object, $value);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tests/Common/StubbedTransitPrice.php:
--------------------------------------------------------------------------------
1 | fakeTariffs->setFakeTariff(Tariff::of(0, 'faked', $faked));
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tests/Common/TransitFixture.php:
--------------------------------------------------------------------------------
1 | transitRepository->save(new Transit(Tariff::of(0, 'fake', Money::from($price)), Uuid::v4()));
34 | $this->stubbedTransitPrice->stub(Money::from($price));
35 | $this->transitDetailsFacade->transitRequested($when, $transit->getRequestUuid(), $from, $to, Distance::zero(), $client, CarType::CAR_CLASS_VAN, Money::from($price), Tariff::ofTime($when));
36 | $this->transitDetailsFacade->transitAccepted($transit->getRequestUuid(), $when, $driver->getId());
37 | $this->transitDetailsFacade->transitStarted($transit->getRequestUuid(), $transit->getId(), $when);
38 | $this->transitDetailsFacade->transitCompleted($transit->getRequestUuid(), $when, Money::from($price), Money::zero());
39 | return $transit;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/tests/Double/FakeAppProperties.php:
--------------------------------------------------------------------------------
1 | automaticRefundForVipThreshold;
18 | }
19 |
20 | public function setAutomaticRefundForVipThreshold(int $automaticRefundForVipThreshold): void
21 | {
22 | $this->automaticRefundForVipThreshold = $automaticRefundForVipThreshold;
23 | }
24 |
25 | public function getNoOfTransitsForClaimAutomaticRefund(): int
26 | {
27 | return $this->noOfTransitsForClaimAutomaticRefund;
28 | }
29 |
30 | public function setNoOfTransitsForClaimAutomaticRefund(int $noOfTransitsForClaimAutomaticRefund): void
31 | {
32 | $this->noOfTransitsForClaimAutomaticRefund = $noOfTransitsForClaimAutomaticRefund;
33 | }
34 |
35 | public function getMilesExpirationInDays(): int
36 | {
37 | return $this->milesExpirationInDays;
38 | }
39 |
40 | public function setMilesExpirationInDays(int $milesExpirationInDays): void
41 | {
42 | $this->milesExpirationInDays = $milesExpirationInDays;
43 | }
44 |
45 | public function getDefaultMilesBonus(): int
46 | {
47 | return $this->defaultMilesBonus;
48 | }
49 |
50 | public function setDefaultMilesBonus(int $defaultMilesBonus): void
51 | {
52 | $this->defaultMilesBonus = $defaultMilesBonus;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/tests/Double/FakeGeocodingService.php:
--------------------------------------------------------------------------------
1 | addressMap[$address->getHash()])) {
16 | return $this->addressMap[$address->getHash()];
17 | }
18 |
19 | if($this->returnValues !== []) {
20 | return array_shift($this->returnValues);
21 | }
22 |
23 | return [1.0, 1.0];
24 | }
25 |
26 | public function setReturnValues(array $returnValues): void
27 | {
28 | $this->returnValues = $returnValues;
29 | }
30 |
31 | public function setValuesForAddress(Address $address, array $values): void
32 | {
33 | $this->addressMap[$address->getHash()] = $values;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/tests/Double/FakeTariffs.php:
--------------------------------------------------------------------------------
1 | fakeTariff = $tariff;
15 | }
16 |
17 | public function choose(?\DateTimeImmutable $when = null): Tariff
18 | {
19 | if($this->fakeTariff !== null) {
20 | return $this->fakeTariff;
21 | }
22 |
23 | return parent::choose($when);
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/tests/Integration/Contracts/Application/Acme/Dynamic/DocumentOperationResultAssert.php:
--------------------------------------------------------------------------------
1 | result = $result;
16 | self::assertEquals(DocumentOperationResult::SUCCESS, $result->getResult());
17 | }
18 |
19 | public function editable(): self
20 | {
21 | self::assertTrue($this->result->isContentChangePossible());
22 | return $this;
23 | }
24 |
25 | public function uneditable(): self
26 | {
27 | self::assertFalse($this->result->isContentChangePossible());
28 | return $this;
29 | }
30 |
31 | public function state(string $state): self
32 | {
33 | self::assertEquals($state, $this->result->getStateName());
34 | return $this;
35 | }
36 |
37 | public function content(ContentId $contentId): self
38 | {
39 | self::assertEquals($contentId, $this->result->getContentId());
40 | return $this;
41 | }
42 |
43 | public function possibleNextStates(string ...$states): self
44 | {
45 | self::assertEquals($states, array_keys($this->result->getPossibleTransitionsAndRules()));
46 | return $this;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/tests/Integration/Contracts/Application/Acme/Straightforward/ContractResultAssert.php:
--------------------------------------------------------------------------------
1 | result = $result;
16 | self::assertEquals(ContractResult::SUCCESS, $result->getResult());
17 | }
18 |
19 | public function state(BaseState $state): self
20 | {
21 | self::assertEquals($state->getStateDescriptor(), $this->result->getStateDescriptor());
22 | return $this;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tests/Integration/GraphTransitAnalyzerIntegrationTest.php:
--------------------------------------------------------------------------------
1 | analyzer = $this->getContainer()->get(GraphTransitAnalyzer::class);
15 | }
16 |
17 | /**
18 | * @test
19 | */
20 | public function canRecognizeNewAddress(): void
21 | {
22 | //given
23 | $this->analyzer->addTransitBetweenAddresses(1, 1, 111, 222, new \DateTimeImmutable(), new \DateTimeImmutable());
24 | $this->analyzer->addTransitBetweenAddresses(1, 1, 222, 333 , new \DateTimeImmutable(), new \DateTimeImmutable());
25 | $this->analyzer->addTransitBetweenAddresses(1, 1, 333, 444, new \DateTimeImmutable(), new \DateTimeImmutable());
26 |
27 | //when
28 | $result = $this->analyzer->analyze(1, 111);
29 |
30 | //then
31 | self::assertSame([111, 222, 333, 444], $result);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/tests/Integration/Neo4jTestCase.php:
--------------------------------------------------------------------------------
1 | getContainer()->get(ClientInterface::class)->transaction(function(TransactionInterface $tsx) {
14 | $tsx->run('MATCH (n) DETACH DELETE n');
15 | });
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/Integration/Repair/VehicleRepairAssert.php:
--------------------------------------------------------------------------------
1 | getStatus());
18 | } else {
19 | self::assertEquals(ResolveResult::STATUS_ERROR, $result->getStatus());
20 | }
21 | $this->result = $result;
22 | }
23 |
24 | public function free(): self
25 | {
26 | self::assertEquals(Money::zero(), $this->result->getTotalCost());
27 | return $this;
28 | }
29 |
30 | public function allParts(array $parts): self
31 | {
32 | self::assertEquals($parts, $this->result->getAcceptedParts());
33 | return $this;
34 | }
35 |
36 | public function by(PartyId $handlingParty): self
37 | {
38 | self::assertEquals($handlingParty->toUuid(), $this->result->getHandlingParty());
39 | return $this;
40 | }
41 |
42 | public function allPartsBut(array $parts, array $excludedParts): self
43 | {
44 | $exptectedParts = array_filter($parts, fn(string $part) => !in_array($part, $excludedParts));
45 | self::assertEquals($exptectedParts, $this->result->getAcceptedParts());
46 | return $this;
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/tests/Unit/Contracts/Legacy/DocumentTest.php:
--------------------------------------------------------------------------------
1 | anyUser = new User();
20 | $this->otherUser = new User();
21 | }
22 |
23 | /**
24 | * @test
25 | */
26 | public function onlyDraftCanBeVerifiedByUserOtherThanCreator(): void
27 | {
28 | $doc = new Document($this->anyNumber, $this->anyUser);
29 |
30 | $doc->verifyBy($this->otherUser);
31 |
32 | self::assertEquals(DocumentStatus::VERIFIED, $doc->getStatus());
33 | }
34 |
35 | /**
36 | * @test
37 | */
38 | public function canNotChangePublished(): void
39 | {
40 | $doc = new Document($this->anyNumber, $this->anyUser);
41 | $doc->changeTitle($this->title);
42 | $doc->verifyBy($this->otherUser);
43 | $doc->publish();
44 |
45 | try {
46 | $doc->changeTitle('');
47 | } catch (\Throwable $exception) {
48 | self::assertTrue(true);
49 | }
50 |
51 | self::assertEquals($this->title, $doc->getTitle());
52 | }
53 |
54 | /**
55 | * @test
56 | */
57 | public function changingVerifiedMovesToDraft(): void
58 | {
59 | $doc = new Document($this->anyNumber, $this->anyUser);
60 | $doc->changeTitle($this->title);
61 | $doc->verifyBy($this->otherUser);
62 |
63 | $doc->changeTitle('');
64 |
65 | self::assertEquals(DocumentStatus::DRAFT, $doc->getStatus());
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/tests/Unit/Contracts/Model/State/Dynamic/FakeDocumentPublisher.php:
--------------------------------------------------------------------------------
1 | events[] = $event;
15 | return $event;
16 | }
17 |
18 | public function contains(string $eventClass): void
19 | {
20 | $events = array_filter($this->events, fn($event) => get_class($event) === $eventClass);
21 | Assert::assertNotEmpty($events);
22 | }
23 |
24 | public function noEvents(): void
25 | {
26 | Assert::assertEmpty($this->events);
27 | }
28 |
29 | public function reset(): void
30 | {
31 | $this->events = [];
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/tests/Unit/Entity/DriverLicenseTest.php:
--------------------------------------------------------------------------------
1 | expectException(\InvalidArgumentException::class);
16 | DriverLicense::withLicense('invalid');
17 | }
18 |
19 | /**
20 | * @test
21 | */
22 | public function cannotCreateEmptyLicense(): void
23 | {
24 | $this->expectException(\InvalidArgumentException::class);
25 | DriverLicense::withLicense('');
26 | }
27 |
28 | /**
29 | * @test
30 | */
31 | public function canCreateValidLicense(): void
32 | {
33 | //when
34 | $license = DriverLicense::withLicense('FARME100165AB5EW');
35 |
36 | //then
37 | self::assertEquals('FARME100165AB5EW', $license->asString());
38 | }
39 |
40 | /**
41 | * @test
42 | */
43 | public function canCreateInvalidLicenseExplicitly(): void
44 | {
45 | //when
46 | $license = DriverLicense::withoutValidation('invalid');
47 |
48 | //then
49 | self::assertEquals('invalid', $license->asString());
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/tests/Unit/Repair/Legacy/Job/RepairTest.php:
--------------------------------------------------------------------------------
1 | setContract($this->fullCoverageWarranty());
23 | //when
24 | $result = $employee->doJob($this->fullRepair());
25 | //then
26 | self::assertEquals(JobResult::DECISION_ACCEPTED, $result->getDecision());
27 | self::assertEquals(Money::zero(), $result->getParam('totalCost'));
28 | self::assertEquals($this->allParts(), $result->getParam('acceptedParts'));
29 | }
30 |
31 | private function fullRepair(): RepairJob
32 | {
33 | $job = new RepairJob();
34 | $job->setEstimatedValue(Money::from(50000));
35 | $job->setPartsToRepair($this->allParts());
36 |
37 | return $job;
38 | }
39 |
40 | private function fullCoverageWarranty(): SignedContract
41 | {
42 | $contract = new SignedContract();
43 | $contract->setCoverageRatio(100);
44 | $contract->setCoveredParts($this->allParts());
45 |
46 | return $contract;
47 | }
48 |
49 | /**
50 | * @return string[]
51 | */
52 | private function allParts(): array
53 | {
54 | return [Parts::SUSPENSION, Parts::PAINT, Parts::GEARBOX, Parts::ENGINE];
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/tests/Unit/Repair/Legacy/Service/JobDoerTest.php:
--------------------------------------------------------------------------------
1 | repair(1, $this->repairJob());
23 |
24 | self::assertEquals(JobResult::DECISION_ACCEPTED, $result->getDecision());
25 | self::assertEquals(Money::zero(), $result->getParam('totalCost'));
26 | self::assertEquals($this->allParts(), $result->getParam('acceptedParts'));
27 | }
28 |
29 | private function repairJob(): RepairJob
30 | {
31 | $job = new RepairJob();
32 | $job->setEstimatedValue(Money::from(7000));
33 | $job->setPartsToRepair($this->allParts());
34 |
35 | return $job;
36 | }
37 |
38 | /**
39 | * @return string[]
40 | */
41 | private function allParts(): array
42 | {
43 | return [Parts::ENGINE, Parts::GEARBOX, Parts::PAINT, Parts::SUSPENSION];
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/tests/Unit/Ride/RequestForTransitTest.php:
--------------------------------------------------------------------------------
1 | getTariff()->getName());
22 | self::assertNotEquals(0,$requestForTransit->getTariff()->getKmRate());
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tests/Unit/Ride/TransitTest.php:
--------------------------------------------------------------------------------
1 | transit();
21 |
22 | //expect
23 | $transit->changeDestination(Distance::ofKm(20));
24 |
25 | //then
26 | self::assertEquals(Distance::ofKm(20), $transit->getDistance());
27 | }
28 |
29 | /**
30 | * @test
31 | */
32 | public function cannotChangeDestinationWhenTransitIsCompleted(): void
33 | {
34 | //given
35 | $transit = $this->transit();
36 | //and
37 | $transit->completeAt(Distance::ofKm(20));
38 |
39 | //then
40 | self::expectException(\RuntimeException::class);
41 |
42 | //when
43 | $transit->changeDestination(Distance::ofKm(20));
44 | }
45 |
46 | /**
47 | * @test
48 | */
49 | public function canCompleteTransit(): void
50 | {
51 | //given
52 | $transit = $this->transit();
53 |
54 | //expect
55 | $transit->completeAt(Distance::ofKm(20));
56 |
57 | //then
58 | self::assertEquals(Status::COMPLETED, $transit->getStatus());
59 | }
60 |
61 | private function transit(): Transit
62 | {
63 | return new Transit(Tariff::ofTime(new \DateTimeImmutable()), Uuid::v4());
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 | bootEnv(dirname(__DIR__).'/.env');
13 | }
14 |
--------------------------------------------------------------------------------