Skip to content

Commit

Permalink
[shopsys] show prices for customer user with role `ROLE_API_CUSTOMER_…
Browse files Browse the repository at this point in the history
…SEES_PRICES` (#3319)
  • Loading branch information
JanMolcik committed Sep 17, 2024
2 parents 2951a87 + a22c7b9 commit c679700
Show file tree
Hide file tree
Showing 11 changed files with 364 additions and 2 deletions.
81 changes: 81 additions & 0 deletions src/Controller/Front/PersonalDataController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

declare(strict_types=1);

namespace Shopsys\FrameworkBundle\Controller\Front;

use Shopsys\FrameworkBundle\Component\Domain\Domain;
use Shopsys\FrameworkBundle\Component\HttpFoundation\XmlResponse;
use Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserFacade;
use Shopsys\FrameworkBundle\Model\Newsletter\NewsletterFacade;
use Shopsys\FrameworkBundle\Model\Order\OrderFacade;
use Shopsys\FrameworkBundle\Model\PersonalData\PersonalDataAccessRequest;
use Shopsys\FrameworkBundle\Model\PersonalData\PersonalDataAccessRequestFacade;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class PersonalDataController extends AbstractController
{
/**
* @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain
* @param \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserFacade $customerUserFacade
* @param \Shopsys\FrameworkBundle\Model\Order\OrderFacade $orderFacade
* @param \Shopsys\FrameworkBundle\Model\Newsletter\NewsletterFacade $newsletterFacade
* @param \Shopsys\FrameworkBundle\Model\PersonalData\PersonalDataAccessRequestFacade $personalDataAccessRequestFacade
* @param \Shopsys\FrameworkBundle\Component\HttpFoundation\XmlResponse $xmlResponse
*/
public function __construct(
protected readonly Domain $domain,
protected readonly CustomerUserFacade $customerUserFacade,
protected readonly OrderFacade $orderFacade,
protected readonly NewsletterFacade $newsletterFacade,
protected readonly PersonalDataAccessRequestFacade $personalDataAccessRequestFacade,
protected readonly XmlResponse $xmlResponse,
) {
}

/**
* @param string $hash
* @return \Symfony\Component\HttpFoundation\Response
*/
public function exportXmlAction(string $hash): Response
{
$personalDataAccessRequest = $this->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();
}
}
15 changes: 15 additions & 0 deletions src/Model/Customer/User/CustomerUserFacade.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ public function edit(
?DeliveryAddress $deliveryAddress = null,
) {
$customerUser = $this->getCustomerUserById($customerUserId);
$customerUserOriginalRoles = $customerUser->getRoles();

if (
$customerUserUpdateData->deliveryAddressData
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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) !== [];
}
}
2 changes: 2 additions & 0 deletions src/Model/Customer/User/Role/CustomerUserRole.php
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, string>
Expand All @@ -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,
];
}
}
41 changes: 41 additions & 0 deletions src/Model/Customer/User/Role/CustomerUserRoleProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace Shopsys\FrameworkBundle\Model\Customer\User\Role;

use Shopsys\FrameworkBundle\Model\Customer\User\CustomerUser;
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;

class CustomerUserRoleProvider
{
/**
* @param \Symfony\Component\Security\Core\Role\RoleHierarchyInterface $roleHierarchy
*/
public function __construct(
protected readonly RoleHierarchyInterface $roleHierarchy,
) {
}

/**
* @param \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUser $customerUser
* @return string[]
*/
public function getRolesForCustomerUser(CustomerUser $customerUser): array
{
$roles = $this->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);
}
}
3 changes: 3 additions & 0 deletions src/Resources/translations/messages.cs.po
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
3 changes: 3 additions & 0 deletions src/Resources/translations/messages.en.po
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,9 @@ msgstr ""
msgid "Customer phone number"
msgstr ""

msgid "Customer sees prices"
msgstr ""

msgid "Customer self manage"
msgstr ""

Expand Down
21 changes: 21 additions & 0 deletions src/Resources/views/Front/Content/PersonalData/adress.xml.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<customer_addresses>
{% set billingAddress = customerUser.customer.billingAddress %}
<address>
<address_type>billing</address_type>
<street><![CDATA[{{ billingAddress.street }}]]></street>
<city><![CDATA[{{ billingAddress.city }}]]></city>
<postal_code><![CDATA[{{ billingAddress.postCode }}]]></postal_code>
<country_code><![CDATA[{{ billingAddress.country.code|default('') }}]]></country_code>
</address>
{% if customerUser.customer.deliveryAddresses is not null %}
{% for deliveryAddress in customerUser.customer.deliveryAddresses %}
<address>
<address_type>shipping</address_type>
{% if deliveryAddress.street is not null %}<street><![CDATA[{{ deliveryAddress.street }}]]></street>{% endif %}
{% if deliveryAddress.city is not null %}<city><![CDATA[{{ deliveryAddress.city }}]]></city>{% endif %}
{% if deliveryAddress.postCode is not null %}<postal_code><![CDATA[{{ deliveryAddress.postCode }}]]></postal_code>{% endif %}
{% if deliveryAddress.country is not null %}<country_code><![CDATA[{{ deliveryAddress.country.code }}]]></country_code>{% endif %}
</address>
{% endfor %}
{% endif %}
</customer_addresses>
43 changes: 43 additions & 0 deletions src/Resources/views/Front/Content/PersonalData/export.xml.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>

<customers>
<customer>

{% if customerUser is not null %}
<customer_name>
<firstname><![CDATA[{{ customerUser.firstName }}]]></firstname>
<lastname><![CDATA[{{ customerUser.lastName }}]]></lastname>
<phone><![CDATA[{{ customerUser.telephone }}]]></phone>
<email><![CDATA[{{ customerUser.email }}]]></email>
</customer_name>

{% 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 %}
<customer_company>
{% if billingAddress.companyName is not null %}
<company_name><![CDATA[{{ billingAddress.companyName }}]]></company_name>
{% endif %}
{% if billingAddress.companyNumber is not null %}
<company_registration_number><![CDATA[{{ billingAddress.companyNumber }}]]></company_registration_number>
{% endif %}
{% if billingAddress.companyTaxNumber is not null %}
<company_vat_registration_number><![CDATA[{{ billingAddress.companyTaxNumber }}]]></company_vat_registration_number>
{% endif %}
</customer_company>
{% endif %}
{% endif %}

<other_information>
<newsletter_subscription>{% if newsletterSubscriber is null %}0{% else %}1{% endif %}</newsletter_subscription>
</other_information>

{% if orders|length > 0 %}
{% include('@ShopsysFramework/Front/Content/PersonalData/orders.xml.twig' ) with {'orders': orders} %}
{% endif %}

</customer>
</customers>
104 changes: 104 additions & 0 deletions src/Resources/views/Front/Content/PersonalData/orders.xml.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<customer_orders>
{% for order in orders %}
{% set customerUser = order.customerUser %}
<order>
<variable_symbol>{{ order.number }}</variable_symbol>
<order_create_date>{{ order.createdAt|date('c') }}</order_create_date>
<order_canceled>{% if order.isCancelled %}1{% else %}0{% endif %}</order_canceled>
<order_addresses>
<address>
<address_type>billing</address_type>
<street><![CDATA[{{ order.street }}]]></street>
<city><![CDATA[{{ order.city }}]]></city>
<postal_code><![CDATA[{{ order.postCode }}]]></postal_code>
<country_code><![CDATA[{{ order.country.code }}]]></country_code>

{% if order.companyName is not null %}
<company>
{% if order.companyName is not null %}
<company_name><![CDATA[{{ order.companyName }}]]></company_name>
{% endif %}
{% if order.companyNumber is not null %}
<company_registration_number><![CDATA[{{ order.companyNumber }}]]></company_registration_number>
{% endif %}
{% if order.companyTaxNumber is not null %}
<company_vat_registration_number><![CDATA[{{ order.companyTaxNumber }}]]></company_vat_registration_number>
{% endif %}
</company>
{% endif %}

<contact_name>
{% if order.firstName is not null %}
<firstname><![CDATA[{{ order.firstName }}]]></firstname>
{% endif %}
{% if order.lastName is not null %}
<lastname><![CDATA[{{ order.lastName }}]]></lastname>
{% endif %}
{% if order.companyName is not null %}
<company_name><![CDATA[{{ order.companyName }}]]></company_name>
{% endif %}
</contact_name>
</address>

{% if order.deliveryAddressSameAsBillingAddress == false %}
<address>
<address_type>shipping</address_type>
<contact_name>
{% if order.deliveryFirstName is not null %}
<firstname><![CDATA[{{ order.deliveryFirstName }}]]></firstname>
{% endif %}
{% if order.deliveryLastName is not null %}
<lastname><![CDATA[{{ order.deliveryLastName }}]]></lastname>
{% endif %}
</contact_name>

{% if order.deliveryCompanyName is not null %}
<company>
<company_name><![CDATA[{{ order.deliveryCompanyName }}]]></company_name>
</company>
{% endif %}

{% if order.deliveryStreet is not null %}
<street><![CDATA[{{ order.deliveryStreet }}]]></street>
{% endif %}
{% if order.deliveryCity is not null %}
<city><![CDATA[{{ order.deliveryCity }}]]></city>
{% endif %}
{% if order.deliveryPostCode is not null %}
<postal_code><![CDATA[{{ order.deliveryPostcode }}]]></postal_code>
{% endif %}
{% if order.deliveryCountry is not null %}
<country_code><![CDATA[{{ order.deliveryCountry.code }}]]></country_code>
{% endif %}
</address>
{% endif %}

</order_addresses>

<order_items>
{% for item in order.items %}
<item>
<item_name><![CDATA[{{ item.name }}]]></item_name>
<item_quantity>{{ item.quantity }}</item_quantity>
<item_unit><![CDATA[{{ item.unitName|default('') }}]]></item_unit>
{% if not item.unitPriceWithoutVat.isZero %}
<item_unit_price_without_vat>{{ item.unitPriceWithoutVat|moneyFormat|hidePrice(customerUser) }}</item_unit_price_without_vat>
{% endif %}
{% if not item.unitPriceWithVat.isZero %}
<item_unit_price_with_vat>{{ item.unitPriceWithVat|moneyFormat|hidePrice(customerUser) }}</item_unit_price_with_vat>
{% endif %}
{% if order.currency.code %}
<item_currency_code><![CDATA[{{ order.currency.code }}]]></item_currency_code>
{% endif %}
</item>
{% endfor %}
</order_items>

<order_other_data>
<order_status>{{ order.status.name }}</order_status>
<phone><![CDATA[{{ order.telephone }}]]></phone>
<email><![CDATA[{{ order.email }}]]></email>
</order_other_data>
</order>
{% endfor %}
</customer_orders>
4 changes: 2 additions & 2 deletions src/Resources/views/Mail/Order/products.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
<tr>
<td style="font-weight: bold;">{{ item.name }}</td>
<td style="text-align: right;">{{ item.quantity|formatNumber(orderLocale) }} {{ item.unitName }}</td>
<td style="text-align: right;">{{ item.unitPriceWithVat|priceTextWithCurrencyByCurrencyIdAndLocale(order.currency.id, orderLocale) }}</td>
<td style="text-align: right;">{{ orderItemTotalPricesById[item.id].priceWithVat|priceTextWithCurrencyByCurrencyIdAndLocale(order.currency.id, orderLocale) }}</td>
<td style="text-align: right;">{{ item.unitPriceWithVat|priceTextWithCurrencyByCurrencyIdAndLocale(order.currency.id, orderLocale)|hidePrice(order.customerUser) }}</td>
<td style="text-align: right;">{{ orderItemTotalPricesById[item.id].priceWithVat|priceTextWithCurrencyByCurrencyIdAndLocale(order.currency.id, orderLocale)|hidePrice(order.customerUser) }}</td>
</tr>
{% endfor %}
</table>
Loading

0 comments on commit c679700

Please sign in to comment.