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

[Order][OrderItem] Immutable product/variant names #8874

Merged
merged 9 commits into from
Oct 30, 2017

Conversation

GSadee
Copy link
Member

@GSadee GSadee commented Oct 19, 2017

Q A
Branch? master
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Related tickets fixes #8628
License MIT

It replaces a PR (#8667) created by @johnrisby using his squashed commits.

@GSadee GSadee added this to the 1.1 milestone Oct 19, 2017
@stefandoorn
Copy link
Contributor

It currently covers product + variant information. It would make sense to me also to write the underlying product option values with the variant. For my project they say way more than the variant name / code, as we have 1000s of variants per products and they just have something generated. The underlying naming says way more to the client and is also printed on invoices. Would be great to have that also added.

The basics now already implemented are also a must, so it's great to see it moving on :)

@johnrisby
Copy link
Contributor

Thanks @GSadee!

@GSadee
Copy link
Member Author

GSadee commented Oct 20, 2017

@johnrisby no problem and of course I hope you don't mind that I continue your work 😃

@johnrisby
Copy link
Contributor

Not at all @GSadee, it's great. That's the whole point!

@pjedrzejewski pjedrzejewski requested a review from pamil October 24, 2017 06:20
$this->addSql('ALTER TABLE sylius_order_item ADD immutable_product_name VARCHAR(255), ADD immutable_product_code VARCHAR(255), ADD immutable_variant_name VARCHAR(255), ADD immutable_variant_code VARCHAR(255)');

$this->addSql('UPDATE sylius_order_item
INNER JOIN sylius_order AS o ON sylius_order_item.order_id = o.id
Copy link
Member

Choose a reason for hiding this comment

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

It would much easier to follow the SQL logic if we would use some more appropriate names for aliases rather than abbreviate the table name

INNER JOIN sylius_product_variant AS pv ON sylius_order_item.variant_id = pv.id
INNER JOIN sylius_product_variant_translation AS pt ON pt.translatable_id = pv.id
INNER JOIN sylius_order AS ol ON pt.locale = ol.locale_code
SET sylius_order_item.immutable_variant_name = pt.name, sylius_order_item.immutable_variant_code = pv.code
Copy link
Member

Choose a reason for hiding this comment

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

Is it really worthy to add another SQL statement?

return 1 === count($rows);
foreach ($rows as $row) {
$field = $this->tableAccessor->getFieldFromRow($table, $row, 'item');
$name = $field->find('css', '.sylius-product-name');
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't we assert that the field would exist?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not in this case, it would change the behaviour of this method.

@@ -6,7 +6,7 @@
{% set taxAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::TAX_ADJUSTMENT') %}

{% set variant = item.variant %}
{% set product = variant.product %}
{% set product = item.variant.product %}
Copy link
Member

Choose a reason for hiding this comment

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

What's the difference?

<a href="{{ path('sylius_admin_product_update', {'id': product.id}) }}" class="sylius-product-name" title="{{ product.name }}">{{ product.name }}</a>
<span class="sub header sylius-product-variant-code" title="{{ variant.code }}">
{{ variant.code }}
<div class="sylius-product-name" title="{{ item.immutableProductName }}">{{ item.immutableProductName }}</div>
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to add immutable prefix? It is set to order item, so it shouldn't change anyway.

Just thinking

@@ -17,6 +17,11 @@
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

<mapped-superclass name="Sylius\Component\Core\Model\OrderItem" table="sylius_order_item">
<field name="immutableProductName" column="immutable_product_name" type="string" nullable="true"/>
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure if the product name on order item should be nullable. It is pretty important data

/**
* {@inheritdoc}
*/
public function setImmutableProductCode(?string $immutableProductCode): void
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we could skip this new setter?

@GSadee GSadee force-pushed the immutable-product-name branch from 2609a6a to 61f2419 Compare October 24, 2017 10:36
INNER JOIN sylius_product AS p ON pv.product_id = p.id
INNER JOIN sylius_product_translation AS pt ON pt.translatable_id = p.id
INNER JOIN sylius_order AS ol ON pt.locale = ol.locale_code
SET sylius_order_item.product_name = pt.name
Copy link
Contributor

Choose a reason for hiding this comment

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

Doubled space after = sign 🎉

INNER JOIN sylius_product_variant AS pv ON sylius_order_item.variant_id = pv.id
INNER JOIN sylius_product_variant_translation AS pvt ON pvt.translatable_id = pv.id
INNER JOIN sylius_order AS ol ON pvt.locale = ol.locale_code
SET sylius_order_item.variant_name = pvt.name
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here

INNER JOIN sylius_product_variant AS pv ON sylius_order_item.variant_id = pv.id
INNER JOIN sylius_product AS p ON pv.product_id = p.id
INNER JOIN sylius_product_translation AS pt ON pt.translatable_id = p.id
INNER JOIN sylius_order AS ol ON pt.locale = ol.locale_code
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to join sylius_order for the second time? Isn't WHERE enough then?

/**
* {@inheritdoc}
*/
public function setVariant(?ProductVariantInterface $variant): void
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, what if a product name changes after the product was added to the cart but before the checkout was completed?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point 👍 What is your suggestion? Should I set immutable names on checkout complete transition?

Copy link
Member Author

Choose a reason for hiding this comment

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

I've created OrderImmutableNamesSetter which is called on checkout complete transition.

$this->addSql('ALTER TABLE sylius_order_item ADD product_name VARCHAR(255), ADD variant_name VARCHAR(255)');

$this->addSql('UPDATE sylius_order_item
INNER JOIN sylius_order AS o ON sylius_order_item.order_id = o.id
Copy link
Member

Choose a reason for hiding this comment

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

Can we not abbreviate rest of table aliases. It is not easy to understand what happened here

@GSadee GSadee force-pushed the immutable-product-name branch 2 times, most recently from 620a8fe to 3966d36 Compare October 26, 2017 06:49
@GSadee GSadee changed the title [Order][OrderItem] Immutable product/variant name and code [Order][OrderItem] Immutable product/variant names Oct 26, 2017
/**
* @param OrderInterface $order
*/
public function setNames(OrderInterface $order): void;
Copy link
Contributor

Choose a reason for hiding this comment

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

This can be changed later (up to v1.1.0 release), so it's not a big deal, only this interface name looks weird.

OrderImmutableNamesSetterInterface::setNames -> OrderItemProductNamesSetterInterface::__invoke / OrderFinalizer::__invoke / something else?

@GSadee GSadee force-pushed the immutable-product-name branch from 8005059 to b3be998 Compare October 26, 2017 15:16
@pamil pamil added Feature New feature proposals. and removed New Feature labels Oct 27, 2017
@@ -63,3 +63,7 @@ winzou_state_machine:
on: ["complete"]
do: ["@sylius.state_resolver.order_shipping", "resolve"]
args: ["object"]
sylius_set_order_immutable_names:
Copy link
Member

Choose a reason for hiding this comment

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

We should move it to the main order state machine. This is not really specific to checkout, it should happen whenver we create a new order (cart -> new transition).

@GSadee GSadee force-pushed the immutable-product-name branch from b3be998 to bb52a56 Compare October 30, 2017 08:18
@pjedrzejewski pjedrzejewski merged commit 78fd015 into Sylius:master Oct 30, 2017
@pjedrzejewski
Copy link
Member

Thank you John & Grzesiu, nice work guys! /cc @johnrisby

@GSadee GSadee deleted the immutable-product-name branch October 30, 2017 11:45
@johnrisby
Copy link
Contributor

Great stuff. Sorry I've not contributed more to this recently but I've got a lot on. Thanks for picking up the baton Grzesiu!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature New feature proposals.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Product names are not stored in Orders/OrderItem so can change in the future
6 participants