Skip to content

Commit 697ce5e

Browse files
author
Rostislav Kreisinger
committed
[SSP-2007] Entity log - admin grid
1 parent 4350be0 commit 697ce5e

15 files changed

Lines changed: 363 additions & 5 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Shopsys\FrameworkBundle\Component\EntityLog\ChangeSet\Formatter;
6+
7+
class CollectionChangesFormatter
8+
{
9+
/**
10+
* @param array $changes
11+
* @return string
12+
*/
13+
public function formatChanges(array $changes): string
14+
{
15+
$formattedCollectionChanges = [];
16+
$this->formatInsertedItems($changes['insertedItems'], $formattedCollectionChanges);
17+
$this->formatDeletedItems($changes['deletedItems'], $formattedCollectionChanges);
18+
19+
return implode(',<br> ', $formattedCollectionChanges);
20+
}
21+
22+
/**
23+
* @param array $insertedChanges
24+
* @param string[] $formattedCollectionChanges
25+
*/
26+
protected function formatInsertedItems(array $insertedChanges, array &$formattedCollectionChanges): void
27+
{
28+
foreach ($insertedChanges as $insertedChange) {
29+
$formattedCollectionChanges[] = t('Created %dataType%: "%readableValue%"', ['%dataType%' => $insertedChange['dataType'], '%readableValue%' => $insertedChange['newReadableValue']]);
30+
}
31+
}
32+
33+
/**
34+
* @param array $deletedChanges
35+
* @param string[] $formattedCollectionChanges
36+
*/
37+
protected function formatDeletedItems(array $deletedChanges, array &$formattedCollectionChanges): void
38+
{
39+
foreach ($deletedChanges as $deletedChange) {
40+
$formattedCollectionChanges[] = t('Removed %dataType%: "%readableValue%"', ['%dataType%' => $deletedChange['dataType'], '%readableValue%' => $deletedChange['oldReadableValue']]);
41+
}
42+
}
43+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Shopsys\FrameworkBundle\Component\EntityLog\ChangeSet\Formatter;
6+
7+
use DateTime;
8+
use Shopsys\FrameworkBundle\Twig\DateTimeFormatterExtension;
9+
10+
class DateTimeDataTypeFormatter
11+
{
12+
/**
13+
* @param \Shopsys\FrameworkBundle\Twig\DateTimeFormatterExtension $dateTimeFormatterExtension
14+
*/
15+
public function __construct(
16+
protected readonly DateTimeFormatterExtension $dateTimeFormatterExtension,
17+
) {
18+
}
19+
20+
/**
21+
* @param array $changes
22+
* @return string
23+
*/
24+
public function formatChanges(array $changes): string
25+
{
26+
$changes['oldReadableValue'] = $changes['oldValue'] ? $this->dateTimeFormatterExtension->formatDateTime(new DateTime($changes['oldValue'])) : t('empty value');
27+
$changes['newReadableValue'] = $changes['newValue'] ? $this->dateTimeFormatterExtension->formatDateTime(new DateTime($changes['newValue'])) : t('empty value');
28+
29+
return t('from "oldReadableValue" to "newReadableValue"', $changes);
30+
}
31+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Shopsys\FrameworkBundle\Component\EntityLog\ChangeSet\Formatter;
6+
7+
use Shopsys\FrameworkBundle\Component\Money\Money;
8+
9+
class MoneyDataTypeFormatter
10+
{
11+
/**
12+
* @param array $changes
13+
* @return string
14+
*/
15+
public function formatChanges(array $changes): string
16+
{
17+
$changes['oldReadableValue'] = Money::create($changes['oldReadableValue'])->round(2)->getAmount();
18+
$changes['newReadableValue'] = Money::create($changes['newReadableValue'])->round(2)->getAmount();
19+
20+
return t('from "oldReadableValue" to "newReadableValue"', $changes);
21+
}
22+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Shopsys\FrameworkBundle\Component\EntityLog\ChangeSet\Formatter;
6+
7+
class ResolvedChangesFormatter
8+
{
9+
/**
10+
* @param \Shopsys\FrameworkBundle\Component\EntityLog\ChangeSet\Formatter\CollectionChangesFormatter $collectionChangesFormatter
11+
* @param \Shopsys\FrameworkBundle\Component\EntityLog\ChangeSet\Formatter\ScalarDataTypeFormatter $scalarDataTypeFormatter
12+
* @param \Shopsys\FrameworkBundle\Component\EntityLog\ChangeSet\Formatter\MoneyDataTypeFormatter $moneyDataTypeFormatter
13+
* @param \Shopsys\FrameworkBundle\Component\EntityLog\ChangeSet\Formatter\DateTimeDataTypeFormatter $dateTimeDataTypeFormatter
14+
*/
15+
public function __construct(
16+
protected readonly CollectionChangesFormatter $collectionChangesFormatter,
17+
protected readonly ScalarDataTypeFormatter $scalarDataTypeFormatter,
18+
protected readonly MoneyDataTypeFormatter $moneyDataTypeFormatter,
19+
protected readonly DateTimeDataTypeFormatter $dateTimeDataTypeFormatter,
20+
) {
21+
}
22+
23+
/**
24+
* @param array $changeSet
25+
* @return string
26+
*/
27+
public function formatResolvedChanges(array $changeSet): string
28+
{
29+
$formattedChanges = [];
30+
31+
foreach ($changeSet as $attribute => $changes) {
32+
if ($changes['dataType'] === 'Collection') {
33+
$formattedChanges[] = t(
34+
'Collection %collectionAttribute% was changed:<br> %changes%',
35+
[
36+
'%collectionAttribute%' => $attribute,
37+
'%changes%' => $this->collectionChangesFormatter->formatChanges($changes),
38+
],
39+
);
40+
41+
continue;
42+
}
43+
44+
if (in_array($changes['dataType'], ['DateTimeImmutable', 'DateTime'], true)) {
45+
$formattedChanges[] = t(
46+
'Attribute %attribute% was changed %changes%',
47+
[
48+
'%attribute%' => $attribute,
49+
'%changes%' => $this->dateTimeDataTypeFormatter->formatChanges($changes),
50+
],
51+
);
52+
53+
continue;
54+
}
55+
56+
if ($changes['dataType'] === 'Money') {
57+
$formattedChanges[] = t(
58+
'Attribute %attribute% was changed %changes%',
59+
[
60+
'%attribute%' => $attribute,
61+
'%changes%' => $this->moneyDataTypeFormatter->formatChanges($changes),
62+
],
63+
);
64+
65+
continue;
66+
}
67+
68+
$formattedChanges[] = t(
69+
'Attribute %attribute% was changed %changes%',
70+
[
71+
'%attribute%' => $attribute,
72+
'%changes%' => $this->scalarDataTypeFormatter->formatChanges($changes),
73+
],
74+
);
75+
}
76+
77+
return implode('<br>', $formattedChanges);
78+
}
79+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Shopsys\FrameworkBundle\Component\EntityLog\ChangeSet\Formatter;
6+
7+
class ScalarDataTypeFormatter
8+
{
9+
/**
10+
* @param array $changes
11+
* @return string
12+
*/
13+
public function formatChanges(array $changes): string
14+
{
15+
return t('from "oldReadableValue" to "newReadableValue"', $changes);
16+
}
17+
}

src/Component/EntityLog/Model/EntityLogRepository.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ protected function getRepository(): EntityRepository
3131
* @param int $entityId
3232
* @return \Doctrine\ORM\QueryBuilder
3333
*/
34-
protected function getQueryBuilderByEntityNameAndEntityId(string $entityName, int $entityId): QueryBuilder
34+
public function getQueryBuilderByEntityNameAndEntityId(string $entityName, int $entityId): QueryBuilder
3535
{
3636
return $this->getRepository()->createQueryBuilder('el')
3737
->select('el')
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Shopsys\FrameworkBundle\Component\EntityLog\Model\Grid;
6+
7+
use Shopsys\FrameworkBundle\Component\EntityLog\ChangeSet\Formatter\ResolvedChangesFormatter;
8+
use Shopsys\FrameworkBundle\Component\EntityLog\Enum\EntityLogActionEnum;
9+
use Shopsys\FrameworkBundle\Component\EntityLog\Model\EntityLogRepository;
10+
use Shopsys\FrameworkBundle\Component\Grid\Grid;
11+
use Shopsys\FrameworkBundle\Component\Grid\GridFactory;
12+
use Shopsys\FrameworkBundle\Component\Grid\QueryBuilderWithRowManipulatorDataSource;
13+
14+
class EntityLogGridFactory
15+
{
16+
/**
17+
* @param \Shopsys\FrameworkBundle\Component\Grid\GridFactory $gridFactory
18+
* @param \Shopsys\FrameworkBundle\Component\EntityLog\Model\EntityLogRepository $entityLogRepository
19+
* @param \Shopsys\FrameworkBundle\Component\EntityLog\ChangeSet\Formatter\ResolvedChangesFormatter $resolvedChangesFormatter
20+
*/
21+
public function __construct(
22+
protected readonly GridFactory $gridFactory,
23+
protected readonly EntityLogRepository $entityLogRepository,
24+
protected readonly ResolvedChangesFormatter $resolvedChangesFormatter,
25+
) {
26+
}
27+
28+
/**
29+
* @param string $entityName
30+
* @param int $entityId
31+
* @return \Shopsys\FrameworkBundle\Component\Grid\Grid
32+
*/
33+
public function createByEntityNameAndEntityId(string $entityName, int $entityId): Grid
34+
{
35+
$queryBuilder = $this->entityLogRepository->getQueryBuilderByEntityNameAndEntityId($entityName, $entityId);
36+
$queryBuilder->andWhere('(el.action = :createAction AND el.parentEntityId IS NULL) OR el.action != :createAction');
37+
$queryBuilder->setParameter('createAction', EntityLogActionEnum::CREATE);
38+
39+
$dataSource = new QueryBuilderWithRowManipulatorDataSource(
40+
$queryBuilder,
41+
'el.id',
42+
function ($row) {
43+
$row['el']['changeSet'] = $this->resolvedChangesFormatter->formatResolvedChanges($row['el']['changeSet']);
44+
45+
return $row;
46+
},
47+
);
48+
49+
$grid = $this->gridFactory->create('entityLogList', $dataSource);
50+
51+
$grid->addColumn('userIdentifier', 'el.userIdentifier', t('User'));
52+
$grid->addColumn('action', 'el.action', t('Action'));
53+
$grid->addColumn('entityName', 'el.entityName', t('Entity'));
54+
$grid->addColumn('entityIdentifier', 'el.entityIdentifier', t('Entity identifier'));
55+
$grid->addColumn('changeSet', 'el.changeSet', t('Changes'));
56+
$grid->addColumn('createAt', 'el.createdAt', t('Date'));
57+
58+
$grid->setTheme('@ShopsysFramework/Admin/Content/EntityLog/listGrid.html.twig');
59+
60+
return $grid;
61+
}
62+
}

src/Controller/Admin/OrderController.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
use Shopsys\FrameworkBundle\Component\Domain\AdminDomainFilterTabsFacade;
88
use Shopsys\FrameworkBundle\Component\Domain\Domain;
9+
use Shopsys\FrameworkBundle\Component\EntityLog\Model\EntityLogFacade;
10+
use Shopsys\FrameworkBundle\Component\EntityLog\Model\Grid\EntityLogGridFactory;
911
use Shopsys\FrameworkBundle\Component\Grid\DataSourceInterface;
1012
use Shopsys\FrameworkBundle\Component\Grid\GridFactory;
1113
use Shopsys\FrameworkBundle\Component\Grid\QueryBuilderWithRowManipulatorDataSource;
@@ -38,6 +40,7 @@ class OrderController extends AdminBaseController
3840
* @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain
3941
* @param \Shopsys\FrameworkBundle\Model\Order\OrderDataFactoryInterface $orderDataFactory
4042
* @param \Shopsys\FrameworkBundle\Component\Domain\AdminDomainFilterTabsFacade $adminDomainFilterTabsFacade
43+
* @param \Shopsys\FrameworkBundle\Component\EntityLog\Model\Grid\EntityLogGridFactory $entityLogGridFactory
4144
*/
4245
public function __construct(
4346
protected readonly OrderFacade $orderFacade,
@@ -50,6 +53,7 @@ public function __construct(
5053
protected readonly Domain $domain,
5154
protected readonly OrderDataFactoryInterface $orderDataFactory,
5255
protected readonly AdminDomainFilterTabsFacade $adminDomainFilterTabsFacade,
56+
protected readonly EntityLogGridFactory $entityLogGridFactory,
5357
) {
5458
}
5559

@@ -95,9 +99,15 @@ public function editAction(Request $request, $id)
9599
t('Editing order - Nr. %number%', ['%number%' => $order->getNumber()]),
96100
);
97101

102+
$entityLogGrid = $this->entityLogGridFactory->createByEntityNameAndEntityId(
103+
EntityLogFacade::getEntityNameByEntity($order),
104+
$order->getId(),
105+
);
106+
98107
return $this->render('@ShopsysFramework/Admin/Content/Order/edit.html.twig', [
99108
'form' => $form->createView(),
100109
'order' => $order,
110+
'entityLogGridView' => $entityLogGrid->createView(),
101111
]);
102112
}
103113

src/Model/Order/Item/OrderItem.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Shopsys\FrameworkBundle\Model\Order\Item;
66

77
use Doctrine\ORM\Mapping as ORM;
8+
use Litipk\BigNumbers\Decimal;
89
use Shopsys\FrameworkBundle\Component\EntityLog\Attribute\EntityLogIdentify;
910
use Shopsys\FrameworkBundle\Component\EntityLog\Attribute\Loggable;
1011
use Shopsys\FrameworkBundle\Component\EntityLog\Attribute\LoggableChild;
@@ -295,7 +296,7 @@ public function edit(OrderItemData $orderItemData)
295296
$this->setTotalPrice(new Price($orderItemData->totalPriceWithoutVat, $orderItemData->totalPriceWithVat));
296297
}
297298

298-
$this->vatPercent = $orderItemData->vatPercent;
299+
$this->vatPercent = Decimal::create($orderItemData->vatPercent, 6)->innerValue();
299300
$this->quantity = $orderItemData->quantity;
300301
$this->unitName = $orderItemData->unitName;
301302
$this->catnum = $orderItemData->catnum;

src/Resources/config/services.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ services:
1616
public: false
1717

1818
Shopsys\FrameworkBundle\:
19-
resource: '../../**/*{Calculation,Dispatcher,Facade,Factory,Generator,Handler,InlineEdit,Listener,Loader,Mapper,Middleware,Parser,Provider,Recalculator,Registry,Repository,Resolver,Service,Scheduler,Subscriber,Transformer,DataFetcher}.php'
19+
resource: '../../**/*{Calculation,Dispatcher,Facade,Factory,Formatter,Generator,Handler,InlineEdit,Listener,Loader,Mapper,Middleware,Parser,Provider,Recalculator,Registry,Repository,Resolver,Service,Scheduler,Subscriber,Transformer,DataFetcher}.php'
2020
exclude: '../../{Command,Controller,DependencyInjection,Form,Migrations,Resources,Twig}'
2121

2222
Shopsys\FrameworkBundle\Model\AdvancedSearch\Filter\:

0 commit comments

Comments
 (0)