diff --git a/src/Controller/Front/PersonalDataController.php b/src/Controller/Front/PersonalDataController.php new file mode 100644 index 0000000000..c9913d1e08 --- /dev/null +++ b/src/Controller/Front/PersonalDataController.php @@ -0,0 +1,81 @@ +personalDataAccessRequestFacade->findByHashAndDomainId( + $hash, + $this->domain->getId(), + ); + + if ( + $personalDataAccessRequest !== null + && $personalDataAccessRequest->getType() === PersonalDataAccessRequest::TYPE_EXPORT + ) { + $customerUser = $this->customerUserFacade->findCustomerUserByEmailAndDomain( + $personalDataAccessRequest->getEmail(), + $this->domain->getId(), + ); + + $orders = $this->orderFacade->getOrderListForEmailByDomainId( + $personalDataAccessRequest->getEmail(), + $this->domain->getId(), + ); + + $newsletterSubscriber = $this->newsletterFacade->findNewsletterSubscriberByEmailAndDomainId( + $personalDataAccessRequest->getEmail(), + $this->domain->getId(), + ); + + $xmlContent = $this->render('@ShopsysFramework/Front/Content/PersonalData/export.xml.twig', [ + 'customerUser' => $customerUser, + 'newsletterSubscriber' => $newsletterSubscriber, + 'orders' => $orders, + ])->getContent(); + + $fileName = $personalDataAccessRequest->getEmail() . '.xml'; + + return $this->xmlResponse->getXmlResponse($fileName, $xmlContent); + } + + throw new NotFoundHttpException(); + } +} diff --git a/src/Model/Customer/User/CustomerUserFacade.php b/src/Model/Customer/User/CustomerUserFacade.php index 65e162f14e..91c7ef40de 100644 --- a/src/Model/Customer/User/CustomerUserFacade.php +++ b/src/Model/Customer/User/CustomerUserFacade.php @@ -165,6 +165,7 @@ public function edit( ?DeliveryAddress $deliveryAddress = null, ) { $customerUser = $this->getCustomerUserById($customerUserId); + $customerUserOriginalRoles = $customerUser->getRoles(); if ( $customerUserUpdateData->deliveryAddressData @@ -199,6 +200,10 @@ public function edit( $this->newsletterFacade->deleteSubscribedEmailIfExists($customerUser->getEmail(), $customerUser->getDomainId()); } + if ($this->areRolesChanged($customerUser->getRoles(), $customerUserOriginalRoles)) { + $this->customerUserRefreshTokenChainFacade->removeAllCustomerUserRefreshTokenChains($customerUser); + } + return $customerUser; } @@ -465,4 +470,14 @@ public function isLastSecurityChangeOlderThan(string $customerUserUuid, DateTime { return $this->customerUserRepository->isLastSecurityChangeOlderThan($customerUserUuid, $referenceDateTime); } + + /** + * @param string[] $customerUserCurrentRoles + * @param string[] $customerUserOriginalRoles + * @return bool + */ + protected function areRolesChanged(array $customerUserCurrentRoles, array $customerUserOriginalRoles): bool + { + return array_diff($customerUserCurrentRoles, $customerUserOriginalRoles) !== [] || array_diff($customerUserOriginalRoles, $customerUserCurrentRoles) !== []; + } } diff --git a/src/Model/Customer/User/Role/CustomerUserRole.php b/src/Model/Customer/User/Role/CustomerUserRole.php index 5c8c7db6bb..7f3bfb5f15 100644 --- a/src/Model/Customer/User/Role/CustomerUserRole.php +++ b/src/Model/Customer/User/Role/CustomerUserRole.php @@ -9,6 +9,7 @@ class CustomerUserRole public const ROLE_API_LOGGED_CUSTOMER = 'ROLE_API_LOGGED_CUSTOMER'; public const ROLE_API_ALL = 'ROLE_API_ALL'; public const ROLE_API_CUSTOMER_SELF_MANAGE = 'ROLE_API_CUSTOMER_SELF_MANAGE'; + public const ROLE_API_CUSTOMER_SEES_PRICES = 'ROLE_API_CUSTOMER_SEES_PRICES'; /** * @return array @@ -18,6 +19,7 @@ public function getAvailableRoles(): array return [ t('B2B data and user management') => self::ROLE_API_ALL, t('Customer self manage') => self::ROLE_API_CUSTOMER_SELF_MANAGE, + t('Customer sees prices') => self::ROLE_API_CUSTOMER_SEES_PRICES, ]; } } diff --git a/src/Model/Customer/User/Role/CustomerUserRoleProvider.php b/src/Model/Customer/User/Role/CustomerUserRoleProvider.php new file mode 100644 index 0000000000..05b5603241 --- /dev/null +++ b/src/Model/Customer/User/Role/CustomerUserRoleProvider.php @@ -0,0 +1,41 @@ +roleHierarchy->getReachableRoleNames($customerUser->getRoles()); + + return array_unique($roles); + } + + /** + * @param \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUser $customerUser + * @return bool + */ + public function canSeePrices(CustomerUser $customerUser): bool + { + $roles = $this->getRolesForCustomerUser($customerUser); + + return in_array(CustomerUserRole::ROLE_API_CUSTOMER_SEES_PRICES, $roles, true); + } +} diff --git a/src/Resources/translations/messages.cs.po b/src/Resources/translations/messages.cs.po index d4ca04c94a..03d3f81632 100644 --- a/src/Resources/translations/messages.cs.po +++ b/src/Resources/translations/messages.cs.po @@ -979,6 +979,9 @@ msgstr "Jméno zákazníka" msgid "Customer phone number" msgstr "Telefonní číslo zákazníka" +msgid "Customer sees prices" +msgstr "Zákazník vidí ceny" + msgid "Customer self manage" msgstr "Spravovat své údaje" diff --git a/src/Resources/translations/messages.en.po b/src/Resources/translations/messages.en.po index 9bd1add867..aa878ccc64 100644 --- a/src/Resources/translations/messages.en.po +++ b/src/Resources/translations/messages.en.po @@ -979,6 +979,9 @@ msgstr "" msgid "Customer phone number" msgstr "" +msgid "Customer sees prices" +msgstr "" + msgid "Customer self manage" msgstr "" diff --git a/src/Resources/views/Front/Content/PersonalData/adress.xml.twig b/src/Resources/views/Front/Content/PersonalData/adress.xml.twig new file mode 100644 index 0000000000..dad7bb0e88 --- /dev/null +++ b/src/Resources/views/Front/Content/PersonalData/adress.xml.twig @@ -0,0 +1,21 @@ + + {% set billingAddress = customerUser.customer.billingAddress %} +
+ billing + + + + +
+ {% if customerUser.customer.deliveryAddresses is not null %} + {% for deliveryAddress in customerUser.customer.deliveryAddresses %} +
+ shipping + {% if deliveryAddress.street is not null %}{% endif %} + {% if deliveryAddress.city is not null %}{% endif %} + {% if deliveryAddress.postCode is not null %}{% endif %} + {% if deliveryAddress.country is not null %}{% endif %} +
+ {% endfor %} + {% endif %} +
diff --git a/src/Resources/views/Front/Content/PersonalData/export.xml.twig b/src/Resources/views/Front/Content/PersonalData/export.xml.twig new file mode 100644 index 0000000000..82e0a0f256 --- /dev/null +++ b/src/Resources/views/Front/Content/PersonalData/export.xml.twig @@ -0,0 +1,43 @@ + + + + + + {% if customerUser is not null %} + + + + + + + + {% if customerUser.customer.billingAdress is defined or customerUser.customer.deliveryAddresses is defined %} + {% include '@ShopsysFramework/Front/Content/PersonalData/adress.xml.twig' with {'customerUser' : customerUser} %} + {% endif %} + + {% if customerUser.customer.billingAddress is defined and customerUser.customer.billingAddress.companyCustomer %} + {% set billingAddress = customerUser.customer.billingAddress %} + + {% if billingAddress.companyName is not null %} + + {% endif %} + {% if billingAddress.companyNumber is not null %} + + {% endif %} + {% if billingAddress.companyTaxNumber is not null %} + + {% endif %} + + {% endif %} + {% endif %} + + + {% if newsletterSubscriber is null %}0{% else %}1{% endif %} + + + {% if orders|length > 0 %} + {% include('@ShopsysFramework/Front/Content/PersonalData/orders.xml.twig' ) with {'orders': orders} %} + {% endif %} + + + diff --git a/src/Resources/views/Front/Content/PersonalData/orders.xml.twig b/src/Resources/views/Front/Content/PersonalData/orders.xml.twig new file mode 100644 index 0000000000..c8e0552f9e --- /dev/null +++ b/src/Resources/views/Front/Content/PersonalData/orders.xml.twig @@ -0,0 +1,104 @@ + + {% for order in orders %} + {% set customerUser = order.customerUser %} + + {{ order.number }} + {{ order.createdAt|date('c') }} + {% if order.isCancelled %}1{% else %}0{% endif %} + +
+ billing + + + + + + {% if order.companyName is not null %} + + {% if order.companyName is not null %} + + {% endif %} + {% if order.companyNumber is not null %} + + {% endif %} + {% if order.companyTaxNumber is not null %} + + {% endif %} + + {% endif %} + + + {% if order.firstName is not null %} + + {% endif %} + {% if order.lastName is not null %} + + {% endif %} + {% if order.companyName is not null %} + + {% endif %} + +
+ + {% if order.deliveryAddressSameAsBillingAddress == false %} +
+ shipping + + {% if order.deliveryFirstName is not null %} + + {% endif %} + {% if order.deliveryLastName is not null %} + + {% endif %} + + + {% if order.deliveryCompanyName is not null %} + + + + {% endif %} + + {% if order.deliveryStreet is not null %} + + {% endif %} + {% if order.deliveryCity is not null %} + + {% endif %} + {% if order.deliveryPostCode is not null %} + + {% endif %} + {% if order.deliveryCountry is not null %} + + {% endif %} +
+ {% endif %} + +
+ + + {% for item in order.items %} + + + {{ item.quantity }} + + {% if not item.unitPriceWithoutVat.isZero %} + {{ item.unitPriceWithoutVat|moneyFormat|hidePrice(customerUser) }} + {% endif %} + {% if not item.unitPriceWithVat.isZero %} + {{ item.unitPriceWithVat|moneyFormat|hidePrice(customerUser) }} + {% endif %} + {% if order.currency.code %} + + {% endif %} + + {% endfor %} + + + + {{ order.status.name }} + + + +
+ {% endfor %} +
diff --git a/src/Resources/views/Mail/Order/products.html.twig b/src/Resources/views/Mail/Order/products.html.twig index 8a5dcd278c..5500009742 100644 --- a/src/Resources/views/Mail/Order/products.html.twig +++ b/src/Resources/views/Mail/Order/products.html.twig @@ -9,8 +9,8 @@ {{ item.name }} {{ item.quantity|formatNumber(orderLocale) }} {{ item.unitName }} - {{ item.unitPriceWithVat|priceTextWithCurrencyByCurrencyIdAndLocale(order.currency.id, orderLocale) }} - {{ orderItemTotalPricesById[item.id].priceWithVat|priceTextWithCurrencyByCurrencyIdAndLocale(order.currency.id, orderLocale) }} + {{ item.unitPriceWithVat|priceTextWithCurrencyByCurrencyIdAndLocale(order.currency.id, orderLocale)|hidePrice(order.customerUser) }} + {{ orderItemTotalPricesById[item.id].priceWithVat|priceTextWithCurrencyByCurrencyIdAndLocale(order.currency.id, orderLocale)|hidePrice(order.customerUser) }} {% endfor %} diff --git a/src/Twig/HiddenPriceExtension.php b/src/Twig/HiddenPriceExtension.php new file mode 100644 index 0000000000..f73f426ab2 --- /dev/null +++ b/src/Twig/HiddenPriceExtension.php @@ -0,0 +1,49 @@ +hidePriceFilter(...), + ), + ]; + } + + /** + * @param string $price + * @param \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUser|null $customerUser + * @return string + */ + public function hidePriceFilter(string $price, ?CustomerUser $customerUser): string + { + if ($customerUser !== null && !$this->customerUserRoleProvider->canSeePrices($customerUser)) { + return MoneyFormatterHelper::HIDDEN_FORMAT; + } + + return $price; + } +}