Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate attribute group edit #31502

Merged

Conversation

JevgenijVisockij
Copy link
Contributor

@JevgenijVisockij JevgenijVisockij commented Feb 23, 2023

Questions Answers
Branch? develop
Description? Migrates attribute group form to symfony
Type? refacto
Category? BO
BC breaks? no
Deprecations? no
How to test? Turn on attributes in experimental feature, the edit and add buttons in attribute groups list should now lead to new symfony form. Form should allow to create new attribute groups and edit existing ones, should work with multishop. IMPORTANT: Meta Title, URL and Indexable fields in attribute group from come from faceted search module and will not appear in this form. Those will need to be added on faceted search module side once this PR is merged.
UI Tests: https://github.com/matthieu-rolland/ga.tests.ui.pr/actions/runs/6232728862
Fixed ticket? #10508

@JevgenijVisockij JevgenijVisockij requested a review from a team as a code owner February 23, 2023 07:40
@prestonBot prestonBot added develop Branch Refactoring Type: Refactoring labels Feb 23, 2023
@JevgenijVisockij JevgenijVisockij changed the title Migrate attribute view Migrate attribute group edit Feb 23, 2023
Copy link
Contributor

@matthieu-rolland matthieu-rolland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

integration tests are red, they must be updated due to your migration I guess 👍

@matthieu-rolland matthieu-rolland dismissed their stale review February 23, 2023 14:37

misclick I wanted to comment-review

Comment on lines 33 to 37
public const ATTRIBUTE_GROUP_TYPE_SELECT = 'select';

public const ATTRIBUTE_GROUP_TYPE_RADIO = 'radio';

public const ATTRIBUTE_GROUP_TYPE_COLOR = 'color';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should introduce VO AttributeGroupType which would also validate itself in constructor

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed it can be interesting to have such VOs that ensures the limited choices of this field

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea! Implemented it

Comment on lines 73 to 83
try {
$attributeGroup = new \AttributeGroup($attributeGroupId->getValue());
} catch (PrestaShopException $e) {
throw new AttributeGroupException('Failed to create new attribute group', 0, $e);
}

if ($attributeGroup->id !== $attributeGroupId->getValue()) {
throw new AttributeGroupNotFoundException(sprintf('Attribute group with id "%s" was not found.', $attributeGroupId->getValue()));
}

return $attributeGroup;
Copy link
Contributor

@zuk3975 zuk3975 Mar 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inject PrestaShop\PrestaShop\Adapter\AttributeGroup\Repository\AttributeGroupRepository
and a new method if it doesn't yet exist get(AttributeGroupId $attributeGroupId, ShopId $shopId): AttributeGroup and use it here instead

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right I didn't remember but a repository for this entity already exists

class AttributeGroupRepository extends AbstractMultiShopObjectModelRepository

So you should use and improve it to match your needs here (creation, update, get entity), most of the code you are using here is actually factorized and mutualized vie the abstract module repository helper methods like getObjectModel

throw new AttributeGroupConstraintException('Invalid attribute group data', AttributeGroupConstraintException::INVALID_NAME);
}

if (false === $attributeGroup->update()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Im pretty sure this could also be used from repository. as well as the validations (same as in other subdomains like product) object model validator can check the fields it already has some methods encapsulated with correct exception throws etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed you should use an ObjectModel repository here as well

* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
*#}

{% set layoutTitle = 'Add a new attribute group'|trans({}, 'Admin.Catalog.attribute') %}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move the layoutTitle to controller and name it New attribute to keep consistent with #31322, the wording is validated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, so @JevgenijVisockij this should be a template variable set in the controller when you are rendering the page

* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
*#}

{% set layoutTitle = 'Edit: %name%'|trans({'%name%': attributeGroupName}, 'Admin.Actions') %}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move the layoutTitle to controller and name it Editing attribute %name% to keep consistent with #31322, the wording is validated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, except it should be Aditing attribute group %name% here, this PR targets the AttributeGroup entity not the Attribute one


<div class="card">
<h3 class="card-header">
{{ 'Attribute Group'|trans({}, 'Admin.Catalog.Attribute') }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{{ 'Attribute'|trans({}, 'Admin.Catalog.Attribute') }}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this new wording is more adapted, to understand the difference between Attribute group and its contained Attributes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So to clarify it should stay as Attribute group right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jolelievre @JevgenijVisockij @l-delin It has always been Attribute and Attribute value and I think it should stay like that.

It's called Attribute group only in the code and in the database.

Copy link
Contributor

@zuk3975 zuk3975 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we wait for @jolelievre review aswell? Im kinda not sure which things we want to require and which not.
I added couple comments which would follow the same principle as we recently done with product page, but don't rush with them.
I have couple doubts, e.g. if we need to use shop constraint for GetAttributeGroupCommand, or we should use the ShopId? because query will always need to get the values only from one shop, so the shopGroup and allShops constraints would become useless (futhermore the attributeGroup doesn't have "default shop id" in database as product does, so what would be the value of shopId when allshops or group shop constraint is given? (it would end up taking first random shop then?) . Anyway I think it may be nice to have a meetup and align before we start requesting different things. It would also apply to other migration PR's

throw new AttributeGroupConstraintException('Invalid attribute group data', AttributeGroupConstraintException::INVALID_NAME);
}

if (false === $attributeGroup->add()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this part should also be moved to a new repository method "create({all the required props}): Product"

*
* @throws AttributeGroupConstraintException
*/
public function __construct(int $attributeGroupId, array $localizedNames, array $localizedPublicNames, string $type, array $shopAssociation = [])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

split to multiline

@@ -537,6 +537,12 @@ services:

PrestaShopBundle\Form\Admin\Type\AmountCurrencyType:

PrestaShopBundle\Form\Admin\Sell\Catalog\AttributeGroupType:
public: true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im pretty sure it can also be autowired and private

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Private for sure, autowire why not it won't bring much since you still need to manually define $isMultistoreEnabled But it can anticipate future modifications

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Romeved public true, but is autwire needed? there defaults autowire: true at the top of the file

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh if there is default autowire:true then its all good (didn't see that)

Copy link
Contributor

@zuk3975 zuk3975 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok so after brief discussion with @jolelievre you could address my comments. It is better if we implement those repositories/validators and shopId explicitly

Copy link
Contributor

@jolelievre jolelievre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @JevgenijVisockij

actually unlike what I though initially and what @zuk3975 suggested, I don't think we need a shopId or a ShopConstraint inside the commands/queries for this Entity.

It's not like for product where the shop context changes the entity content completely (because many things are editable based on shop context and override many values). For this entity it's actually much simpler it only handles an association between the entity and the shops, but the content doesn't change. So you only need to handle in update (and potentially creation) to edit the list of associated shops.

],
);

new window.prestashop.component.ChoiceTree('#attribute_group_shop_association').enableAutoCheckChildren();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not blocking but could you move these selectors into a separate mapping file, please? It makes it easier to centralize them and modify them when a refacto/modification is needed

@zuk3975
Copy link
Contributor

zuk3975 commented Mar 6, 2023

Hi @JevgenijVisockij

actually unlike what I though initially and what @zuk3975 suggested, I don't think we need a shopId or a ShopConstraint inside the commands/queries for this Entity.

It's not like for product where the shop context changes the entity content completely (because many things are editable based on shop context and override many values). For this entity it's actually much simpler it only handles an association between the entity and the shops, but the content doesn't change. So you only need to handle in update (and potentially creation) to edit the list of associated shops.

Ok sorry for confusion, I agree.
Attribute_group_shop only contains associations (so either group is assigned to shop or not, but values between shops are always the same) 🙇

Copy link
Contributor

@jolelievre jolelievre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @JevgenijVisockij

sorry for all the comments again 😅

throw new AttributeGroupConstraintException('Invalid attribute group data', AttributeGroupConstraintException::INVALID_NAME);
}

if (false === $attributeGroup->update()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed you should use an ObjectModel repository here as well

Comment on lines 73 to 83
try {
$attributeGroup = new \AttributeGroup($attributeGroupId->getValue());
} catch (PrestaShopException $e) {
throw new AttributeGroupException('Failed to create new attribute group', 0, $e);
}

if ($attributeGroup->id !== $attributeGroupId->getValue()) {
throw new AttributeGroupNotFoundException(sprintf('Attribute group with id "%s" was not found.', $attributeGroupId->getValue()));
}

return $attributeGroup;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right I didn't remember but a repository for this entity already exists

class AttributeGroupRepository extends AbstractMultiShopObjectModelRepository

So you should use and improve it to match your needs here (creation, update, get entity), most of the code you are using here is actually factorized and mutualized vie the abstract module repository helper methods like getObjectModel

Comment on lines 33 to 37
public const ATTRIBUTE_GROUP_TYPE_SELECT = 'select';

public const ATTRIBUTE_GROUP_TYPE_RADIO = 'radio';

public const ATTRIBUTE_GROUP_TYPE_COLOR = 'color';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed it can be interesting to have such VOs that ensures the limited choices of this field

…m_type.yml

Co-authored-by: Jonathan Lelievre <jo.lelievre@gmail.com>
Copy link
Member

@boherm boherm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks @JevgenijVisockij!
Just a small comment but I don't block your PR. ;)

Comment on lines +48 to +53
private $attributeGroupRepository;

public function __construct(AttributeGroupRepository $attributeGroupRepository)
{
$this->attributeGroupRepository = $attributeGroupRepository;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we are in develop branch and we drop some PHP versions oldies, you can use constructor property promotion here (and in other handler classes) to simplify some lines.
Anyway, I'm not blocking your PR for this, but it can be a must have now in develop branch PRs! ;)

@MatShir
Copy link
Contributor

MatShir commented Sep 19, 2023

Test UI and let's go !!!!!!

@MatShir
Copy link
Contributor

MatShir commented Sep 19, 2023

@matthieu-rolland UI test are 🔴 :/

@matthieu-rolland matthieu-rolland added this to the 9.0.0 milestone Sep 19, 2023
@matthieu-rolland matthieu-rolland merged commit 2a94cbf into PrestaShop:develop Sep 19, 2023
18 checks passed
@matthieu-rolland
Copy link
Contributor

and it's a merge ! thank you @JevgenijVisockij !

@matks
Copy link
Contributor

matks commented Sep 19, 2023

7 months until merge 😄

@matks matks added the migration symfony migration project label Sep 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
develop Branch migration symfony migration project Refactoring Type: Refactoring Wording ✔️ Status: check done, wording approved
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

None yet

10 participants