Skip to content

Commit

Permalink
[shopsys] added product inquiries (#3465)
Browse files Browse the repository at this point in the history
  • Loading branch information
grossmannmartin authored Nov 6, 2024
2 parents d7131d0 + 1e465a3 commit 131d461
Show file tree
Hide file tree
Showing 9 changed files with 231 additions and 4 deletions.
84 changes: 84 additions & 0 deletions src/Model/Mutation/Inquiry/CreateInquiryMutation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

declare(strict_types=1);

namespace Shopsys\FrontendApiBundle\Model\Mutation\Inquiry;

use Overblog\GraphQLBundle\Definition\Argument;
use Psr\Log\LoggerInterface;
use Shopsys\FrameworkBundle\Component\Domain\Domain;
use Shopsys\FrameworkBundle\Model\Customer\User\CurrentCustomerUser;
use Shopsys\FrameworkBundle\Model\Inquiry\InquiryData;
use Shopsys\FrameworkBundle\Model\Inquiry\InquiryDataFactory;
use Shopsys\FrameworkBundle\Model\Inquiry\InquiryFacade;
use Shopsys\FrameworkBundle\Model\Inquiry\Mail\InquiryMailFacade;
use Shopsys\FrameworkBundle\Model\Product\Exception\ProductNotFoundException;
use Shopsys\FrameworkBundle\Model\Product\ProductFacade;
use Shopsys\FrontendApiBundle\Model\Mutation\AbstractMutation;
use Shopsys\FrontendApiBundle\Model\Resolver\Products\Exception\ProductNotFoundUserError;

class CreateInquiryMutation extends AbstractMutation
{
/**
* @param \Psr\Log\LoggerInterface $logger
* @param \Shopsys\FrameworkBundle\Model\Inquiry\InquiryDataFactory $inquiryDataFactory
* @param \Shopsys\FrameworkBundle\Model\Inquiry\InquiryFacade $inquiryFacade
* @param \Shopsys\FrameworkBundle\Model\Product\ProductFacade $productFacade
* @param \Shopsys\FrameworkBundle\Model\Inquiry\Mail\InquiryMailFacade $inquiryMailFacade
* @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain
* @param \Shopsys\FrameworkBundle\Model\Customer\User\CurrentCustomerUser $currentCustomerUser
*/
public function __construct(
protected readonly LoggerInterface $logger,
protected readonly InquiryDataFactory $inquiryDataFactory,
protected readonly InquiryFacade $inquiryFacade,
protected readonly ProductFacade $productFacade,
protected readonly InquiryMailFacade $inquiryMailFacade,
protected readonly Domain $domain,
protected readonly CurrentCustomerUser $currentCustomerUser,
) {
}

/**
* @param \Overblog\GraphQLBundle\Definition\Argument $argument
* @return bool
*/
public function createInquiryMutation(Argument $argument): bool
{
try {
$inquiryData = $this->createInquiryDataFromArgument($argument);
$inquiry = $this->inquiryFacade->create($inquiryData);

$this->inquiryMailFacade->sendMail($inquiry);

return true;
} catch (ProductNotFoundException) {
throw new ProductNotFoundUserError(sprintf('Product with UUID "%s" not found', $argument['input']['productUuid']));
}
}

/**
* @param \Overblog\GraphQLBundle\Definition\Argument $argument
* @return \Shopsys\FrameworkBundle\Model\Inquiry\InquiryData
*/
protected function createInquiryDataFromArgument(Argument $argument): InquiryData
{
$input = $argument['input'];

$inquiryData = $this->inquiryDataFactory->create($this->domain->getId());
$product = $this->productFacade->getByUuid($input['productUuid']);

$inquiryData->firstName = $input['firstName'];
$inquiryData->lastName = $input['lastName'];
$inquiryData->email = $input['email'];
$inquiryData->telephone = $input['telephone'];
$inquiryData->companyName = $input['companyName'] ?? null;
$inquiryData->companyNumber = $input['companyNumber'] ?? null;
$inquiryData->companyTaxNumber = $input['companyTaxNumber'] ?? null;
$inquiryData->note = $input['note'] ?? null;
$inquiryData->customerUser = $this->currentCustomerUser->findCurrentCustomerUser();
$inquiryData->product = $product;

return $inquiryData;
}
}
16 changes: 16 additions & 0 deletions src/Model/Resolver/Price/PriceQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPrice;
use Shopsys\FrameworkBundle\Model\Product\Product;
use Shopsys\FrameworkBundle\Model\Product\ProductCachedAttributesFacade;
use Shopsys\FrameworkBundle\Model\Product\ProductTypeEnum;
use Shopsys\FrameworkBundle\Model\Transport\Transport;
use Shopsys\FrameworkBundle\Model\Transport\TransportPriceCalculation;
use Shopsys\FrameworkBundle\Model\Transport\TransportPriceProvider;
Expand Down Expand Up @@ -61,6 +62,10 @@ public function __construct(
*/
public function priceByProductQuery(Product|array $data): ProductPrice
{
if ($this->isProductUponInquiry($data)) {
return ProductPrice::createHiddenProductPrice();
}

if ($data instanceof Product) {
$productPrice = $this->productCachedAttributesFacade->getProductSellingPrice($data);
} else {
Expand All @@ -74,6 +79,17 @@ public function priceByProductQuery(Product|array $data): ProductPrice
return $productPrice;
}

/**
* @param \Shopsys\FrameworkBundle\Model\Product\Product|array $data
* @return bool
*/
protected function isProductUponInquiry(Product|array $data): bool
{
$productType = $data instanceof Product ? $data->getProductType() : $data['product_type'];

return $productType === ProductTypeEnum::TYPE_INQUIRY;
}

/**
* @param \Shopsys\FrameworkBundle\Model\Payment\Payment $payment
* @param string|null $cartUuid
Expand Down
19 changes: 19 additions & 0 deletions src/Model/Resolver/Products/DataMapper/ProductArrayFieldMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Shopsys\FrameworkBundle\Model\Product\Flag\FlagFacade;
use Shopsys\FrameworkBundle\Model\Product\ProductElasticsearchProvider;
use Shopsys\FrameworkBundle\Model\Product\ProductFrontendLimitProvider;
use Shopsys\FrameworkBundle\Model\Product\ProductTypeEnum;
use Shopsys\FrontendApiBundle\Model\Parameter\ParameterWithValuesFactory;

class ProductArrayFieldMapper
Expand Down Expand Up @@ -244,4 +245,22 @@ public function isVisible(array $data): bool

return false;
}

/**
* @param array $data
* @return bool
*/
public function isInquiryType(array $data): bool
{
return $data['product_type'] === ProductTypeEnum::TYPE_INQUIRY;
}

/**
* @param array $data
* @return string
*/
public function getProductType(array $data): string
{
return $data['product_type'];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Shopsys\FrameworkBundle\Model\Product\Collection\ProductCollectionFacade;
use Shopsys\FrameworkBundle\Model\Product\Product;
use Shopsys\FrameworkBundle\Model\Product\ProductFrontendLimitProvider;
use Shopsys\FrameworkBundle\Model\Product\ProductTypeEnum;
use Shopsys\FrameworkBundle\Model\Product\ProductVisibilityFacade;
use Shopsys\FrameworkBundle\Model\Seo\HreflangLinksFacade;
use Shopsys\FrontendApiBundle\Model\Parameter\ParameterWithValuesFactory;
Expand Down Expand Up @@ -222,4 +223,22 @@ public function getVariantsCount(Product $product): Promise

return $this->productsSellableCountByIdsBatchLoader->load($variantIds);
}

/**
* @param \Shopsys\FrameworkBundle\Model\Product\Product $product
* @return bool
*/
public function isInquiryType(Product $product): bool
{
return $product->getProductType() === ProductTypeEnum::TYPE_INQUIRY;
}

/**
* @param \Shopsys\FrameworkBundle\Model\Product\Product $product
* @return string
*/
public function getProductType(Product $product): string
{
return $product->getProductType();
}
}
21 changes: 17 additions & 4 deletions src/Model/Resolver/Query/MoneyResolverMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use GraphQL\Language\AST\StringValueNode;
use Overblog\GraphQLBundle\Resolver\ResolverMap;
use Shopsys\FrameworkBundle\Component\Money\HiddenMoney;
use Shopsys\FrameworkBundle\Component\Money\Money;
use Shopsys\FrameworkBundle\Model\Customer\User\Role\CustomerUserRole;
use Shopsys\FrontendApiBundle\Component\Price\MoneyFormatterHelper;
Expand Down Expand Up @@ -34,16 +35,28 @@ protected function map(): array
];
}

/**
* @param \Shopsys\FrameworkBundle\Component\Money\Money $money
* @return bool
*/
protected function shouldShowAmount(Money $money): bool
{
if ($money instanceof HiddenMoney) {
return false;
}

return
$this->security->getUser() === null ||
$this->security->isGranted(CustomerUserRole::ROLE_API_CUSTOMER_SEES_PRICES);
}

/**
* @param \Shopsys\FrameworkBundle\Component\Money\Money $money
* @return string
*/
protected function serializeMoney(Money $money): string
{
if (
$this->security->getUser() === null ||
$this->security->isGranted(CustomerUserRole::ROLE_API_CUSTOMER_SEES_PRICES)
) {
if ($this->shouldShowAmount($money)) {
return MoneyFormatterHelper::formatWithMaxFractionDigits($money);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
ProductTypeEnumDecorator:
type: enum
decorator: true
config:
description: "One of possible product types"
values:
BASIC:
value: '@=constant("Shopsys\\FrameworkBundle\\Model\\Product\\ProductTypeEnum::TYPE_BASIC")'
description: "Basic product"
INQUIRY:
value: '@=constant("Shopsys\\FrameworkBundle\\Model\\Product\\ProductTypeEnum::TYPE_INQUIRY")'
description: "Product with inquiry form instead of add to cart button"
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
CreateInquiryInputDecorator:
type: input-object
inherits:
- 'NameInputObjectDecorator'
- 'TelephoneInputObjectDecorator'
decorator: true
config:
fields:
productUuid:
type: "Uuid!"
description: "Product UUID"
email:
type: "String!"
description: "The customer's email address"
validation:
- NotBlank:
message: "Please enter email"
- Email:
message: "Please enter valid email"
- Length:
max: 255
maxMessage: "Email cannot be longer than {{ limit }} characters"
companyName:
type: "String"
description: "The customer’s company name"
validation:
- Length:
max: 100
maxMessage: "Company name cannot be longer than {{ limit }} characters"
companyNumber:
type: "String"
description: "The customer’s company identification number"
validation:
- Length:
max: 50
maxMessage: "Identification number cannot be longer than {{ limit }} characters"
- Regex:
pattern: '/^[0-9]+$/'
message: "Please fill in numbers only"
companyTaxNumber:
type: "String"
description: "The customer’s company tax number"
validation:
- Length:
max: 50
maxMessage: "Tax number cannot be longer than {{ limit }} characters"
- Regex:
pattern: '/^[0-9A-Z]*([0-9]+[A-Z]+|[A-Z]+[0-9]+)[0-9A-Z]*$/'
message: "Please check Tax number format"
note:
type: "String"
description: "Customer's question or note to the inquiry product"
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,7 @@ ProductDecorator:
resolve: '@=query("filesByProductPromiseQuery", value)'
isVisible:
type: "Boolean!"
isInquiryType:
type: "Boolean!"
productType:
type: "ProductTypeEnum!"
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,14 @@ MutationDecorator:
type: ContactFormInput!
validation: cascade
resolve: "@=mutation('contactFormMutation', args, validator)"
CreateInquiry:
type: Boolean!
description: "Send the inquiry for the product"
args:
input:
type: CreateInquiryInput!
validation: cascade
resolve: "@=mutation('createInquiryMutation', args)"
AddNewCustomerUser:
type: "CustomerUser!"
description: "Add new customer user to customer"
Expand Down

0 comments on commit 131d461

Please sign in to comment.