Skip to content

Allow BuyXGetY discount conditions to be collection or variant, rewards to be variant#2214

Merged
glennjacobs merged 28 commits intolunarphp:1.xfrom
ryanmitchell:feature/buy-x-get-y-collection-conditions
Jul 10, 2025
Merged

Allow BuyXGetY discount conditions to be collection or variant, rewards to be variant#2214
glennjacobs merged 28 commits intolunarphp:1.xfrom
ryanmitchell:feature/buy-x-get-y-collection-conditions

Conversation

@ryanmitchell
Copy link
Contributor

@ryanmitchell ryanmitchell commented Jun 16, 2025

This PR extends the BuyXGetY discount conditions to support Collection or Variant as a condition, and Variant as a reward:

CleanShot 2025-06-16 at 12 01 00@2x

This allows you to choose collections or variants that the discount applies to, not just products, and rewards can be scoped to specific variants, not just products.

As its no longer 'Product Conditions' and Product Rewards, I've also changed lang strings for some elements on the page to make things match the new approach.

Summary by CodeRabbit

  • New Features

    • Discount conditions and rewards now support collections and product variants, expanding beyond just products.
    • Discount management UI allows selection of collections, products, and variants as discountables.
    • New interface for thumbnail images ensures consistent display across collections, products, and variants.
    • Added new scope to filter discounts by collections.
  • Improvements

    • Admin interface uses clearer, more general terminology for discounts, conditions, and rewards.
    • Discount filtering now includes collections, enhancing discount applicability.
  • Bug Fixes

    • Case-insensitive search is standardized in the admin panel.
  • Documentation

    • Updated documentation to reflect new discountable terminology, relationships, and upgrade instructions.
  • Chores

    • Refactored tests and codebase to use new discountable naming conventions and relationships.
    • Database migration renames and updates discount-related tables and columns for consistency.

@vercel
Copy link

vercel bot commented Jun 16, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
lunar-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 10, 2025 11:40am

Copy link
Contributor

@glennjacobs glennjacobs left a comment

Choose a reason for hiding this comment

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

@ryanmitchell I'm not against this idea, in fact I can see it would be handy, but the implementation feels wrong at the moment.

The relation table is called discount_purchasables and so you'd expect the entries to be a purchasable. To now start putting non-purchasables in is confusing.

I'd probably do the database tables differently now, with perhaps discount_conditions & discounts_rewards... it would need some proper thought, but it doesn't help us right now. That sort of change would have to be done in v2.

Can you have a think about how we can implement this, but keep things clean?

@glennjacobs glennjacobs self-assigned this Jun 17, 2025
@glennjacobs glennjacobs removed their assignment Jun 17, 2025
@ryanmitchell
Copy link
Contributor Author

ryanmitchell commented Jun 18, 2025

Yeah I agree.

Currently there are 4 types of 'purchasable' - conditions, rewards, exclusions and limitations, so that would mean 4 tables, and probably more as other discount types are made. Keeping one table makes more sense to me and is more flexible when it's just the 'type' changing each time.

Some suggestions for what we could rename discount_purchasables to:

discount_connections
discount_discountables
discount_relations

or just simply:
discountables (<-- this would be my preference as its a convention used in Lunar already)

Do any of these sit well with you?

@glennjacobs
Copy link
Contributor

Yeah, discountables I think would work. Would you be willing to make the change in this PR?

@ryanmitchell
Copy link
Contributor Author

Yep absolutely, leave it with me and I'll get it updated today.

@ryanmitchell
Copy link
Contributor Author

@glennjacobs thats updated. theres a failing test but its not related to this code - seem to be a random failure.

@glennjacobs
Copy link
Contributor

@alecritson you happy with this route?

@alecritson
Copy link
Collaborator

@alecritson you happy with this route?

From reading it seems sound, have you pulled down and tried it out in the panel?

@ryanmitchell
Copy link
Contributor Author

If you're happy with this direction of travel I'd love to go a step further and allow variants to be selected on Buy X get Y too.

@glennjacobs
Copy link
Contributor

If you're happy with this direction of travel I'd love to go a step further and allow variants to be selected on Buy X get Y too.

Sure, I don't see any issue with that.

@ryanmitchell ryanmitchell changed the title Allow BuyXGetY discount conditions to be collection Allow BuyXGetY discount conditions to be collection or variant, rewards to be variant Jun 30, 2025
@ryanmitchell
Copy link
Contributor Author

thanks @glennjacobs thats been done

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 10, 2025

Walkthrough

This update refactors discount-related models, relationships, and documentation by renaming "DiscountPurchasable" to "Discountable," affecting factories, migrations, interfaces, and relationship methods. The changes broaden discount applicability to include products, variants, and collections. Admin UI language, resource managers, and test cases are updated to use the new terminology and logic. Supporting code and migrations reflect these structural adjustments.

Changes

File(s) Change Summary
docs/core/reference/discounts.md, docs/core/upgrading.md Documentation updated to rename "Discount Purchasable" to "Discountable" and describe broader applicability; upgrade instructions for new discount features and schema changes.
packages/admin/resources/lang/en/discount.php Admin UI language strings generalized from "Product Rewards/Conditions" to "Rewards/Conditions".
packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductConditionRelationManager.php, packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductLimitationRelationManager.php, packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductRewardRelationManager.php, packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductVariantLimitationRelationManager.php Admin resource managers updated: relationship property changed from "purchasables" to "discountables"; queries, form fields, and table columns updated to use new terminology and logic.
packages/admin/src/Support/Tables/Columns/ThumbnailImageColumn.php New ThumbnailImageColumn class added for customizable thumbnail URL resolution in tables.
packages/admin/src/helpers.php get_search_builder function parameters type-hinted; search column expression generation updated for case-insensitive searches.
packages/core/database/factories/DiscountPurchasableFactory.php Factory for DiscountPurchasable removed.
packages/core/database/factories/DiscountableFactory.php New factory for Discountable model added.
packages/core/database/migrations/2024_03_15_100000_remap_polymorphic_relations.php Polymorphic remapping migration updated to reference Discountable instead of DiscountPurchasable.
packages/core/database/migrations/2025_06_18_100000_rename_discount_purchasables_table.php Migration added to rename discount_purchasables table/columns to discountables.
packages/core/src/Base/HasThumbnailImage.php New interface HasThumbnailImage introduced with getThumbnailImage() method.
packages/core/src/DiscountTypes/AmountOff.php, packages/core/src/DiscountTypes/BuyXGetY.php Internal logic updated to use "discountable" relationships and broaden eligibility to collections and variants.
packages/core/src/Managers/DiscountManager.php Discount retrieval logic updated to eager-load and filter by "discountables," including collections.
packages/core/src/Models/Collection.php, packages/core/src/Models/Product.php, packages/core/src/Models/ProductVariant.php Models updated to implement HasThumbnailImage and provide getThumbnailImage() method.
packages/core/src/Models/Contracts/Discount.php Interface methods renamed from "purchasable*" to "discountable*".
packages/core/src/Models/Contracts/Discountable.php Interface renamed from DiscountPurchasable to Discountable; method renamed to discountable().
packages/core/src/Models/Discount.php Relationship methods renamed to "discountable*" variants; new scopeCollections method added; scopes updated to use new naming.
packages/core/src/Models/DiscountCollection.php Factory reference updated to DiscountableFactory.
packages/core/src/Models/Discountable.php Class renamed from DiscountPurchasable to Discountable; property and method names updated accordingly.
packages/core/src/Observers/DiscountObserver.php Deletion logic updated to remove related "discountables" instead of "purchasables".
tests/core/Stubs/Models/DiscountPurchasable.php Stub class for DiscountPurchasable removed.
tests/core/Stubs/Models/Discountable.php Stub class for Discountable added.
tests/core/Unit/DiscountTypes/AmountOffTest.php, tests/core/Unit/DiscountTypes/BuyXGetYTest.php Test cases updated to use "discountable" relationships and keys; new tests added for expanded discountable types and conditions.
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (1)
packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductRewardRelationManager.php (1)

79-81: Potential N+1 query issue acknowledged.

As discussed in previous reviews, the ThumbnailImageColumn may cause N+1 queries due to different media relations across models. The team has accepted this trade-off for now.

🧹 Nitpick comments (3)
packages/core/src/Models/ProductVariant.php (1)

221-224: LGTM! Consider implementing HasThumbnailImage interface.

The method implementation is correct and follows the same pattern as Product and Collection models. However, consider explicitly implementing the HasThumbnailImage interface in the class declaration for better contract compliance.

-class ProductVariant extends BaseModel implements Contracts\ProductVariant, Purchasable
+class ProductVariant extends BaseModel implements Contracts\ProductVariant, Purchasable, \Lunar\Base\HasThumbnailImage
packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductConditionRelationManager.php (1)

73-81: Consider improving the search for ProductVariant.

The current implementation searches variants by SKU prefix. Consider also searching by product name for better user experience.

Forms\Components\MorphToSelect\Type::make(ProductVariant::modelClass())
    ->titleAttribute('sku')
    ->getSearchResultsUsing(static function (Forms\Components\Select $component, string $search): array {
        return get_search_builder(ProductVariant::modelClass(), $search)
-           ->orWhere('sku', 'like', $search.'%')
+           ->orWhere('sku', 'like', '%'.$search.'%')
+           ->orWhereHas('product', fn($q) => $q->whereRaw('JSON_UNQUOTE(JSON_EXTRACT(attribute_data, "$.name.value.en")) LIKE ?', ['%'.$search.'%']))
            ->get()
            ->mapWithKeys(fn (ProductVariantContract $record): array => [$record->getKey() => $record->product->attr('name').' - '.$record->sku])
            ->all();
    }),
packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductRewardRelationManager.php (1)

62-69: Remove incorrect titleAttribute for ProductVariant.

ProductVariant doesn't have a 'name.en' attribute. Since getSearchResultsUsing handles the search logic, the titleAttribute can be omitted.

Forms\Components\MorphToSelect\Type::make(ProductVariant::modelClass())
-   ->titleAttribute('name.en')
    ->getSearchResultsUsing(static function (Forms\Components\Select $component, string $search): array {
        return get_search_builder(ProductVariant::modelClass(), $search)
            ->get()
            ->mapWithKeys(fn (ProductVariantContract $record): array => [$record->getKey() => $record->sku])
            ->all();
    }),
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between afe3528 and cab414c.

📒 Files selected for processing (30)
  • docs/core/reference/discounts.md (1 hunks)
  • docs/core/upgrading.md (1 hunks)
  • packages/admin/resources/lang/en/discount.php (2 hunks)
  • packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductConditionRelationManager.php (4 hunks)
  • packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductLimitationRelationManager.php (3 hunks)
  • packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductRewardRelationManager.php (4 hunks)
  • packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductVariantLimitationRelationManager.php (3 hunks)
  • packages/admin/src/Support/Tables/Columns/ThumbnailImageColumn.php (1 hunks)
  • packages/admin/src/helpers.php (4 hunks)
  • packages/core/database/factories/DiscountPurchasableFactory.php (0 hunks)
  • packages/core/database/factories/DiscountableFactory.php (1 hunks)
  • packages/core/database/migrations/2024_03_15_100000_remap_polymorphic_relations.php (1 hunks)
  • packages/core/database/migrations/2025_06_18_100000_rename_discount_purchasables_table.php (1 hunks)
  • packages/core/src/Base/HasThumbnailImage.php (1 hunks)
  • packages/core/src/DiscountTypes/AmountOff.php (1 hunks)
  • packages/core/src/DiscountTypes/BuyXGetY.php (4 hunks)
  • packages/core/src/Managers/DiscountManager.php (2 hunks)
  • packages/core/src/Models/Collection.php (3 hunks)
  • packages/core/src/Models/Contracts/Discount.php (1 hunks)
  • packages/core/src/Models/Contracts/Discountable.php (1 hunks)
  • packages/core/src/Models/Discount.php (4 hunks)
  • packages/core/src/Models/DiscountCollection.php (2 hunks)
  • packages/core/src/Models/Discountable.php (5 hunks)
  • packages/core/src/Models/Product.php (3 hunks)
  • packages/core/src/Models/ProductVariant.php (1 hunks)
  • packages/core/src/Observers/DiscountObserver.php (1 hunks)
  • tests/core/Stubs/Models/DiscountPurchasable.php (0 hunks)
  • tests/core/Stubs/Models/Discountable.php (1 hunks)
  • tests/core/Unit/DiscountTypes/AmountOffTest.php (4 hunks)
  • tests/core/Unit/DiscountTypes/BuyXGetYTest.php (7 hunks)
💤 Files with no reviewable changes (2)
  • tests/core/Stubs/Models/DiscountPurchasable.php
  • packages/core/database/factories/DiscountPurchasableFactory.php
🧰 Additional context used
🧬 Code Graph Analysis (15)
packages/core/src/Base/HasThumbnailImage.php (3)
packages/core/src/Models/Collection.php (1)
  • getThumbnailImage (153-156)
packages/core/src/Models/ProductVariant.php (1)
  • getThumbnailImage (221-224)
packages/core/src/Models/Product.php (1)
  • getThumbnailImage (216-219)
tests/core/Stubs/Models/Discountable.php (1)
packages/core/src/Models/Discountable.php (1)
  • Discountable (21-69)
packages/core/src/Observers/DiscountObserver.php (4)
packages/core/src/Models/DiscountCollection.php (1)
  • discount (34-37)
packages/core/src/Models/Discountable.php (1)
  • discount (49-52)
packages/core/src/Models/Contracts/Discount.php (1)
  • discountables (20-20)
packages/core/src/Models/Discount.php (1)
  • discountables (95-98)
packages/core/src/Models/DiscountCollection.php (1)
packages/core/database/factories/DiscountableFactory.php (1)
  • DiscountableFactory (8-19)
packages/core/src/Models/Collection.php (5)
packages/core/src/Base/BaseModel.php (1)
  • BaseModel (8-25)
packages/core/src/Base/HasThumbnailImage.php (1)
  • getThumbnailImage (10-10)
packages/core/src/Models/ProductVariant.php (1)
  • getThumbnailImage (221-224)
packages/core/src/Models/Product.php (1)
  • getThumbnailImage (216-219)
packages/core/src/Base/Traits/HasMedia.php (1)
  • thumbnail (35-39)
packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductVariantLimitationRelationManager.php (4)
packages/core/src/Models/ProductVariant.php (1)
  • ProductVariant (54-225)
packages/core/src/Base/Traits/HasModelExtending.php (1)
  • morphName (97-100)
packages/core/src/Models/Contracts/Discountable.php (1)
  • discountable (19-19)
packages/core/src/Models/Discountable.php (1)
  • discountable (57-60)
packages/core/src/Models/Product.php (5)
packages/core/src/Base/BaseModel.php (1)
  • BaseModel (8-25)
packages/core/src/Base/HasThumbnailImage.php (1)
  • getThumbnailImage (10-10)
packages/core/src/Models/Collection.php (1)
  • getThumbnailImage (153-156)
packages/core/src/Models/ProductVariant.php (1)
  • getThumbnailImage (221-224)
packages/core/src/Base/Traits/HasMedia.php (1)
  • thumbnail (35-39)
packages/core/src/Models/Contracts/Discountable.php (3)
packages/core/src/Models/Discountable.php (3)
  • Discountable (21-69)
  • discount (49-52)
  • discountable (57-60)
tests/core/Stubs/Models/Discountable.php (1)
  • Discountable (5-5)
packages/core/src/Models/DiscountCollection.php (1)
  • discount (34-37)
packages/core/database/factories/DiscountableFactory.php (4)
packages/core/src/Models/Discountable.php (1)
  • Discountable (21-69)
tests/core/Stubs/Models/Discountable.php (1)
  • Discountable (5-5)
packages/core/src/Models/ProductVariant.php (1)
  • ProductVariant (54-225)
packages/core/src/Base/Traits/HasModelExtending.php (1)
  • morphName (97-100)
packages/core/database/migrations/2025_06_18_100000_rename_discount_purchasables_table.php (1)
packages/core/src/Base/Migration.php (1)
  • Migration (7-38)
packages/core/src/Managers/DiscountManager.php (5)
packages/core/src/Models/Product.php (1)
  • collections (129-135)
packages/core/src/Models/Discount.php (1)
  • collections (125-133)
packages/core/src/Models/Cart.php (1)
  • lines (210-213)
packages/core/src/Models/CartLine.php (1)
  • purchasable (147-150)
packages/core/src/Models/ProductVariant.php (1)
  • product (88-91)
packages/core/src/Models/Discountable.php (2)
packages/core/database/factories/DiscountableFactory.php (1)
  • DiscountableFactory (8-19)
packages/core/src/Models/Contracts/Discountable.php (1)
  • discountable (19-19)
packages/core/src/Models/Contracts/Discount.php (1)
packages/core/src/Models/Discount.php (5)
  • discountables (95-98)
  • discountableConditions (100-103)
  • discountableExclusions (105-108)
  • discountableLimitations (110-113)
  • discountableRewards (115-118)
packages/admin/src/Support/Tables/Columns/ThumbnailImageColumn.php (4)
packages/core/src/Base/HasThumbnailImage.php (1)
  • getThumbnailImage (10-10)
packages/core/src/Models/Collection.php (1)
  • getThumbnailImage (153-156)
packages/core/src/Models/ProductVariant.php (1)
  • getThumbnailImage (221-224)
packages/core/src/Models/Product.php (1)
  • getThumbnailImage (216-219)
tests/core/Unit/DiscountTypes/BuyXGetYTest.php (5)
packages/core/src/Models/Discount.php (6)
  • discountableLimitations (110-113)
  • discountableRewards (115-118)
  • discountableConditions (100-103)
  • Discount (32-250)
  • customerGroups (145-158)
  • collections (125-133)
packages/core/src/Models/CustomerGroup.php (1)
  • CustomerGroup (23-111)
packages/core/src/Models/Product.php (1)
  • Product (43-220)
packages/core/src/Models/ProductVariant.php (1)
  • ProductVariant (54-225)
packages/core/src/DiscountTypes/BuyXGetY.php (1)
  • BuyXGetY (17-307)
🪛 markdownlint-cli2 (0.17.2)
docs/core/reference/discounts.md

92-92: Table pipe style
Expected: leading_and_trailing; Actual: leading_only; Missing trailing pipe

(MD055, table-pipe-style)


93-93: Table column count
Expected: 3; Actual: 2; Too few cells, row will be missing data

(MD056, table-column-count)


94-94: Table column count
Expected: 3; Actual: 2; Too few cells, row will be missing data

(MD056, table-column-count)

🪛 PHPMD (2.15.0)
packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductRewardRelationManager.php

64-64: Avoid unused parameters such as '$component'. (Unused Code Rules)

(UnusedFormalParameter)

packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductConditionRelationManager.php

75-75: Avoid unused parameters such as '$component'. (Unused Code Rules)

(UnusedFormalParameter)

packages/admin/src/Support/Tables/Columns/ThumbnailImageColumn.php

11-11: Avoid unused parameters such as '$state'. (Unused Code Rules)

(UnusedFormalParameter)

🔇 Additional comments (52)
packages/core/src/Base/HasThumbnailImage.php (1)

1-11: LGTM! Well-designed interface for thumbnail standardization.

The interface provides a clean abstraction for models that need to expose thumbnail images. The method signature and documentation are clear and consistent with the implementations in Product, ProductVariant, and Collection models.

tests/core/Stubs/Models/Discountable.php (1)

1-5: LGTM! Clean test stub implementation.

The stub correctly extends the core Discountable model and follows standard testing patterns. The minimal approach is appropriate for test scenarios.

packages/core/src/Observers/DiscountObserver.php (1)

18-18: LGTM! Correctly updated relationship call.

The change from purchasables() to discountables() aligns with the broader refactor and maintains referential integrity. The Discount model has a proper discountables() relationship as confirmed in the relevant code snippets.

packages/core/src/Models/DiscountCollection.php (2)

8-8: LGTM! Factory import updated correctly.

The import change from DiscountPurchasableFactory to DiscountableFactory aligns with the broader refactor from purchasables to discountables.


31-31: LGTM! Factory usage updated correctly.

The factory method now returns DiscountableFactory::new() which is consistent with the refactor and the factory's proper definition shown in the relevant code snippets.

packages/core/src/Models/Product.php (1)

18-18: LGTM: Consistent HasThumbnailImage interface implementation

The implementation correctly follows the interface contract and matches the pattern used in other models (Collection, ProductVariant). The method properly handles the case where no thumbnail exists by returning an empty string.

Also applies to: 43-43, 216-219

packages/core/database/migrations/2024_03_15_100000_remap_polymorphic_relations.php (1)

29-29: LGTM: Model class name updated for polymorphic relation mapping

The change from DiscountPurchasable to Discountable is consistent with the broader refactor and ensures polymorphic relations are properly remapped to the new model class.

docs/core/upgrading.md (1)

21-28: Well-documented breaking change with clear upgrade guidance

The documentation effectively explains the database schema change and provides clear guidance for users who were directly using the old discount_purchasables table or purchasables relation.

packages/core/src/Models/Collection.php (1)

13-13: LGTM: Consistent HasThumbnailImage interface implementation

The implementation mirrors the Product model's approach and correctly implements the interface contract. The method properly handles cases where no thumbnail exists by returning an empty string.

Also applies to: 37-37, 153-156

packages/core/src/Models/Contracts/Discountable.php (1)

9-9: LGTM: Interface rename aligns with broader refactor

The interface rename from DiscountPurchasable to Discountable and the method rename from purchasable() to discountable() are consistent with the broader refactor. The method contract remains unchanged, ensuring proper polymorphic behavior.

Also applies to: 17-19

packages/core/src/DiscountTypes/AmountOff.php (1)

173-179: LGTM! Consistent refactoring from purchasables to discountables.

The property name changes from purchasableLimitations/purchasableExclusions to discountableLimitations/discountableExclusions and the corresponding property access updates from purchasable to discountable are consistent with the broader refactoring objective. The logic remains intact while expanding the scope to support more entity types.

packages/admin/resources/lang/en/discount.php (2)

251-255: LGTM! Language updates reflect the expanded scope.

The terminology changes from "Product Rewards" to "Rewards" and "Add Product" to "Add Reward" appropriately reflect the expanded functionality where discounts can now apply to products, variants, and collections rather than just products.


286-290: LGTM! Improved terminology for conditions.

The updates from "Product Conditions" to "Conditions" and "Add Product" to "Add Condition" make the UI language more accurate and general, reflecting that conditions can now include various entity types beyond just products.

packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductVariantLimitationRelationManager.php (4)

18-18: LGTM! Updated relationship to use new discountables model.

The change from purchasables to discountables relationship aligns with the broader refactoring and supports the expanded entity types.


38-39: LGTM! Query constraints updated consistently.

The updates from whereDiscountableType and whereHas('discountable') are consistent with the new relationship structure and maintain the same filtering logic.


43-43: LGTM! Form component updated to use discountable relationship.

The MorphToSelect component now correctly targets the discountable relationship, maintaining the same functionality with the new model structure.


67-85: LGTM! Table columns updated to use discountable relationship.

All table column references have been systematically updated from purchasable to discountable, maintaining the same display logic while using the new relationship structure.

packages/core/database/factories/DiscountableFactory.php (1)

8-19: LGTM! Well-structured factory for the new Discountable model.

The factory correctly implements the new Discountable model with appropriate defaults:

  • Uses discountable_id and discountable_type following the new naming convention
  • Defaults to ProductVariant as the discountable entity, which is appropriate for testing
  • Follows Laravel factory conventions
packages/core/src/Models/Discountable.php (5)

10-10: LGTM! Factory reference updated consistently.

The factory reference has been correctly updated from DiscountPurchasableFactory to DiscountableFactory to align with the new naming convention.


21-21: LGTM! Model renamed to reflect broader scope.

The class name change from DiscountPurchasable to Discountable appropriately reflects the expanded functionality where discounts can apply to various entity types beyond just purchasables.


33-34: LGTM! Fillable attributes updated for polymorphic relationship.

The fillable attributes have been correctly updated from purchasable_type and purchasable_id to discountable_type and discountable_id, maintaining the polymorphic relationship structure with the new naming convention.


43-43: LGTM! Factory method updated consistently.

The factory method now correctly returns the new DiscountableFactory instance, maintaining consistency with the renamed factory class.


57-57: LGTM! Polymorphic relationship method renamed appropriately.

The method name change from purchasable() to discountable() is consistent with the model refactoring and maintains the same polymorphic relationship functionality while using the new naming convention.

packages/core/src/Managers/DiscountManager.php (1)

141-141: LGTM: Relationship name updated correctly.

The change from 'purchasables' to 'discountables' aligns with the broader refactor.

packages/core/database/migrations/2025_06_18_100000_rename_discount_purchasables_table.php (1)

1-35: LGTM: Migration correctly renames table and columns.

The migration properly:

  • Renames the table from discount_purchasables to discountables
  • Updates polymorphic column names from purchasable_* to discountable_*
  • Includes reversible down() method
  • Extends the appropriate base migration class
tests/core/Unit/DiscountTypes/AmountOffTest.php (4)

324-329: LGTM: Test updated correctly for new relationship naming.

The changes from purchasableLimitations() to discountableLimitations() and updating the array keys are consistent with the broader refactor.


421-426: LGTM: Test updated correctly for new relationship naming.

The changes from purchasableLimitations() to discountableLimitations() and updating the array keys are consistent with the broader refactor.


518-523: LGTM: Test updated correctly for new relationship naming.

The changes from purchasableExclusions() to discountableExclusions() and updating the array keys are consistent with the broader refactor.


615-620: LGTM: Test updated correctly for new relationship naming.

The changes from purchasableExclusions() to discountableExclusions() and updating the array keys are consistent with the broader refactor.

packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductLimitationRelationManager.php (4)

17-17: LGTM: Relationship property updated correctly.

The change from 'purchasables' to 'discountables' aligns with the broader refactor.


36-38: LGTM: Query filters updated correctly.

The method calls have been updated from purchasable to discountable terminology while maintaining the same filtering logic.


41-52: LGTM: Form component updated correctly.

The MorphToSelect component has been updated to use 'discountable' instead of 'purchasable' while maintaining the same functionality.


61-73: LGTM: Table columns updated correctly.

The table columns have been updated to reference discountable relationships instead of purchasable while maintaining the same display logic.

packages/admin/src/Support/Tables/Columns/ThumbnailImageColumn.php (1)

1-26: LGTM: Well-designed column class for thumbnail image handling.

The class provides a clean abstraction for resolving thumbnail URLs with:

  • Optional custom resolution via closure
  • Fallback to model's getThumbnailImage() method
  • Fluent interface for configuration

The unused $state parameter is expected when overriding parent methods and is not an issue.

packages/admin/src/helpers.php (3)

10-10: LGTM: Added necessary import for search column expression helper.

The import supports the standardization of search column expression generation.


79-79: LGTM: Added explicit string type hints.

The type hints improve function signature clarity and provide better IDE support and static analysis.


97-119: LGTM: Improved search expression generation with proper database context.

The changes enhance search functionality by:

  • Using the standardized generate_search_column_expression helper
  • Passing database connection context for proper SQL generation
  • Enforcing case-insensitive search behavior

These improvements ensure consistent search behavior across different database drivers.

packages/core/src/DiscountTypes/BuyXGetY.php (4)

12-15: LGTM: Added necessary imports for expanded discount support.

The imports for Collection and ProductVariant support the new functionality allowing discounts to be applied to collections and variants in addition to products.


61-83: LGTM: Expanded discount conditions to support products, variants, and collections.

The refactored logic correctly handles three discountable types:

  • Products: Matches against the cart line's product ID
  • Product Variants: Matches against the cart line's purchasable (variant) ID
  • Collections: Matches when the cart line's product belongs to the specified collection

The implementation maintains the original product logic while cleanly extending support for variants and collections.


111-125: LGTM: Consistent reward filtering logic with expanded type support.

The reward filtering logic mirrors the condition logic, supporting the same three discountable types. The implementation correctly identifies eligible reward lines based on product, variant, or collection matching.


218-218: LGTM: Updated automatic rewards to use discountable terminology.

The method call correctly uses the renamed discountableRewards relationship while maintaining the same functionality.

tests/core/Unit/DiscountTypes/BuyXGetYTest.php (5)

180-189: LGTM: Updated test to use discountable terminology.

The test correctly uses the new discountableLimitations() method and discountable_type/discountable_id array keys, maintaining the same test logic while adopting the new terminology.


293-308: LGTM: Updated existing test with new terminology and assertions.

The test correctly uses the new discountableConditions() and discountableRewards() methods. The assertions verify both the expected cart total and the presence of free items, ensuring the discount logic works correctly.


310-404: LGTM: Added comprehensive test for variant-based discounts.

This new test verifies that discounts can be applied when:

  • The condition is based on a product
  • The reward is based on a specific product variant

The test setup and assertions are comprehensive, ensuring the new variant-based discount functionality works correctly.


406-504: LGTM: Added comprehensive test for collection-based conditions.

This new test verifies that discounts can be applied when:

  • The condition is based on a collection
  • Products in the cart belong to that collection
  • The reward is based on a different product

The test includes proper collection-product relationship setup and comprehensive assertions.


506-600: LGTM: Added comprehensive test for variant-based conditions.

This new test verifies that discounts can be applied when:

  • The condition is based on a specific product variant
  • The reward is based on a product

The test complements the other new tests by covering the variant-as-condition scenario.

packages/core/src/Models/Contracts/Discount.php (1)

18-40: LGTM: Updated interface to reflect discountable terminology.

The interface correctly updates all method names and documentation from "purchasable" to "discountable" while maintaining the same method signatures and return types. This aligns with the implementation changes in the concrete Discount model and supports the expanded functionality for collections and variants.

packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductConditionRelationManager.php (2)

10-16: LGTM! Clean imports for extended functionality.

The imports properly support the new discountable types (Collection, Product, ProductVariant) and the custom ThumbnailImageColumn.


47-48: Good implementation of polymorphic filtering.

The query correctly filters for multiple discountable types and ensures the related model exists.

packages/core/src/Models/Discount.php (3)

95-118: Well-structured relationship refactoring.

The renaming from purchasable* to discountable* relationships is consistent and properly maintains the type filtering logic. This change successfully broadens the scope beyond just purchasable items.


180-199: Excellent implementation of the collections scope.

The new scopeCollections method follows the established pattern and properly handles:

  • Collection ID normalization
  • Type filtering
  • Polymorphic relationship queries with correct morph type checking

This enables filtering discounts by collections, completing the feature set alongside products and variants.


209-240: Consistent updates to existing scopes.

The scopeProducts and scopeProductVariants methods have been properly updated to use the new discountables relationship while maintaining their original filtering logic.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductRewardRelationManager.php (1)

45-46: Method casing inconsistency remains unfixed.

The method name WhereIn should be whereIn following Laravel's camelCase conventions.

-    ->WhereIn('discountable_type', [Product::morphName(), ProductVariant::morphName()])
+    ->whereIn('discountable_type', [Product::morphName(), ProductVariant::morphName()])
🧹 Nitpick comments (1)
packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductRewardRelationManager.php (1)

64-64: Remove unused parameter in closure.

The $component parameter is not used in the closure and should be removed.

-    ->getSearchResultsUsing(static function (Forms\Components\Select $component, string $search): array {
+    ->getSearchResultsUsing(static function (string $search): array {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cab414c and 1b2da4c.

📒 Files selected for processing (2)
  • docs/core/reference/discounts.md (2 hunks)
  • packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductRewardRelationManager.php (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/core/reference/discounts.md
🧰 Additional context used
🪛 PHPMD (2.15.0)
packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductRewardRelationManager.php

64-64: Avoid unused parameters such as '$component'. (Unused Code Rules)

(UnusedFormalParameter)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
  • GitHub Check: shipping - PHP 8.4 - L12.* ↑ E
  • GitHub Check: admin - PHP 8.4 - L12.* ↑
  • GitHub Check: search - PHP 8.4 - L12.* ↑ E
  • GitHub Check: shipping - PHP 8.4 - L11.* ↑ E
  • GitHub Check: core - PHP 8.4 - L12.* ↑ E
  • GitHub Check: search - PHP 8.4 - L11.* ↑
  • GitHub Check: stripe - PHP 8.4 - L11.* ↑ E
  • GitHub Check: admin - PHP 8.4 - L11.* ↑ E
  • GitHub Check: core - PHP 8.4 - L11.* ↑ E
  • GitHub Check: search - PHP 8.3 - L12.* ↑
  • GitHub Check: core - PHP 8.3 - L12.* ↑
  • GitHub Check: core - PHP 8.3 - L12.* ↑ E
  • GitHub Check: core - PHP 8.3 - L11.* ↑ E
  • GitHub Check: admin - PHP 8.3 - L11.* ↑ E
  • GitHub Check: admin - PHP 8.3 - L11.* ↑
  • GitHub Check: core - PHP 8.3 - L11.* ↑
  • GitHub Check: PHP 8.3 - L^12.0 ↑
🔇 Additional comments (6)
packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductRewardRelationManager.php (6)

10-14: LGTM: Imports updated correctly for new functionality.

The addition of ThumbnailImageColumn and ProductVariant imports aligns with the expanded discount functionality.


20-20: LGTM: Relationship name updated consistently.

The change from 'purchasables' to 'discountables' is consistent with the broader refactoring initiative.


50-70: LGTM: MorphToSelect configuration supports both Product and ProductVariant types.

The form configuration correctly handles both entity types with appropriate search functionality.


79-81: ThumbnailImageColumn implementation looks correct.

The implementation properly resolves thumbnail URLs from the polymorphic discountable relationship. This addresses the image handling challenges discussed in previous reviews.


83-89: Conditional display logic correctly handles both Product and ProductVariant types.

The implementation properly differentiates between ProductVariant (showing SKU) and Product (showing name) types.


91-97: New discountable type column provides valuable context.

The addition of the type column helps users understand what type of entity each reward represents, enhancing the admin interface usability.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductRewardRelationManager.php (1)

80-82: Verify the ThumbnailImageColumn implementation addresses N+1 concerns.

The implementation uses a closure to resolve thumbnail URLs from the discountable relation. Based on past discussions, this approach may still cause N+1 queries when dealing with media relations across different models.

Let me verify the ThumbnailImageColumn implementation to ensure it properly handles the media loading:

#!/bin/bash
# Description: Check the ThumbnailImageColumn implementation to understand how it handles media loading

# Search for the ThumbnailImageColumn class definition
ast-grep --pattern 'class ThumbnailImageColumn $$$'

# Check if there are any eager loading optimizations
rg -A 10 -B 5 "getThumbnailImage|resolveThumbnailUrlUsing" packages/admin/src/Support/Tables/Columns/
🧹 Nitpick comments (1)
packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductRewardRelationManager.php (1)

50-70: Remove unused parameter in search callback.

The $component parameter is not used in the search callback function on line 64. Consider removing it to clean up the code.

-                                ->getSearchResultsUsing(static function (Forms\Components\Select $component, string $search): array {
+                                ->getSearchResultsUsing(static function (string $search): array {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1b2da4c and 310d34b.

📒 Files selected for processing (2)
  • packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductRewardRelationManager.php (4 hunks)
  • packages/core/src/Models/ProductVariant.php (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/core/src/Models/ProductVariant.php
🧰 Additional context used
🪛 PHPMD (2.15.0)
packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductRewardRelationManager.php

64-64: Avoid unused parameters such as '$component'. (Unused Code Rules)

(UnusedFormalParameter)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: search - PHP 8.4 - L12.* ↑
  • GitHub Check: search - PHP 8.4 - L12.* ↑ E
  • GitHub Check: core - PHP 8.4 - L12.* ↑ E
  • GitHub Check: shipping - PHP 8.4 - L12.* ↑
  • GitHub Check: core - PHP 8.4 - L11.* ↑
  • GitHub Check: search - PHP 8.3 - L12.* ↑
  • GitHub Check: admin - PHP 8.3 - L12.* ↑ E
  • GitHub Check: admin - PHP 8.3 - L12.* ↑
  • GitHub Check: core - PHP 8.4 - L11.* ↑ E
  • GitHub Check: shipping - PHP 8.3 - L12.* ↑
  • GitHub Check: search - PHP 8.3 - L12.* ↑ E
  • GitHub Check: core - PHP 8.3 - L12.* ↑
  • GitHub Check: admin - PHP 8.3 - L11.* ↑ E
  • GitHub Check: core - PHP 8.3 - L12.* ↑ E
  • GitHub Check: core - PHP 8.3 - L11.* ↑ E
  • GitHub Check: admin - PHP 8.3 - L11.* ↑
  • GitHub Check: core - PHP 8.3 - L11.* ↑
  • GitHub Check: PHP 8.3 - L^11.0 ↑
  • GitHub Check: PHP 8.4 - L^11.0 ↑
  • GitHub Check: PHP 8.4 - L^12.0 ↑
🔇 Additional comments (5)
packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductRewardRelationManager.php (5)

10-14: LGTM: Import statements correctly updated for new functionality.

The new imports for ThumbnailImageColumn, ProductVariantContract, and ProductVariant are necessary for the enhanced functionality to support variant-level discounts.


20-20: LGTM: Relationship name updated to reflect new terminology.

The change from 'purchasables' to 'discountables' aligns with the broader refactoring effort and maintains consistency across the codebase.


45-46: LGTM: Query filtering updated correctly.

The query modifications correctly use the new discountable_type and discountable relationship names, maintaining the same filtering logic with updated terminology.


84-90: LGTM: Text column logic properly handles both Product and ProductVariant.

The conditional formatting correctly displays either the product name for products or "product name - SKU" for product variants, providing clear identification for each discountable type.


92-98: LGTM: New type column provides helpful context.

The addition of a discountable type column with proper formatting enhances the user interface by clearly showing whether each reward is a product or variant.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductConditionRelationManager.php (1)

91-109: Consider refactoring shared column logic.

The table column implementations (ThumbnailImageColumn, name formatting, type display) are identical between ProductConditionRelationManager and ProductRewardRelationManager. This creates maintenance overhead and potential inconsistencies.

Consider extracting the common column logic into a shared trait or base class method to reduce code duplication.

Example approach:

// In BaseRelationManager or a new trait
protected function getDiscountableColumns(): array
{
    return [
        ThumbnailImageColumn::make('discountable_id')
            ->resolveThumbnailUrlUsing(fn (?Model $record) => $record?->discountable?->getThumbnailImage())
            ->label(''),
        
        Tables\Columns\TextColumn::make('discountable.id')
            ->label(__('lunarpanel::discount.relationmanagers.conditions.table.name.label'))
            ->formatStateUsing(
                fn (Model $record) => $record->discountable instanceof ProductVariantContract 
                    ? $record->discountable->product->attr('name').' - '.$record->discountable->sku 
                    : $record->discountable->attr('name')
            ),
        
        Tables\Columns\TextColumn::make('discountable_type')
            ->label(__('lunarpanel::discount.relationmanagers.conditions.table.type.label'))
            ->formatStateUsing(
                fn (Model $record) => str($record->discountable->morphName())->replace('_', ' ')->title(),
            ),
    ];
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 310d34b and 6cf37de.

📒 Files selected for processing (2)
  • packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductConditionRelationManager.php (4 hunks)
  • packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductRewardRelationManager.php (4 hunks)
🧰 Additional context used
🪛 PHPMD (2.15.0)
packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductConditionRelationManager.php

75-75: Avoid unused parameters such as '$component'. (Unused Code Rules)

(UnusedFormalParameter)

packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductRewardRelationManager.php

64-64: Avoid unused parameters such as '$component'. (Unused Code Rules)

(UnusedFormalParameter)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
  • GitHub Check: shipping - PHP 8.4 - L11.* ↑
  • GitHub Check: shipping - PHP 8.4 - L11.* ↑ E
  • GitHub Check: search - PHP 8.4 - L11.* ↑ E
  • GitHub Check: admin - PHP 8.4 - L12.* ↑
  • GitHub Check: core - PHP 8.4 - L12.* ↑ E
  • GitHub Check: core - PHP 8.3 - L12.* ↑
  • GitHub Check: admin - PHP 8.3 - L12.* ↑
  • GitHub Check: shipping - PHP 8.3 - L12.* ↑
  • GitHub Check: stripe - PHP 8.3 - L12.* ↑
  • GitHub Check: shipping - PHP 8.3 - L12.* ↑ E
  • GitHub Check: stripe - PHP 8.3 - L11.* ↑ E
  • GitHub Check: admin - PHP 8.3 - L12.* ↑ E
  • GitHub Check: core - PHP 8.3 - L12.* ↑ E
  • GitHub Check: core - PHP 8.3 - L11.* ↑
  • GitHub Check: admin - PHP 8.3 - L11.* ↑
  • GitHub Check: PHP 8.3 - L^11.0 ↑
  • GitHub Check: PHP 8.3 - L^12.0 ↑
🔇 Additional comments (9)
packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductRewardRelationManager.php (6)

20-20: LGTM: Relationship renamed consistently.

The relationship name change from 'purchasables' to 'discountables' aligns with the broader refactoring effort described in the PR objectives.


45-46: LGTM: Query logic updated correctly.

The query modifications properly:

  • Use correct camelCase method naming (whereIn instead of the previous WhereIn)
  • Update column references from purchasable_type to discountable_type
  • Update relationship checks from purchasable to discountable
  • Include both Product and ProductVariant types for reward selection

50-70: LGTM: MorphToSelect implementation supports multiple entity types.

The form field correctly implements support for both Product and ProductVariant types with appropriate search logic. The ProductVariant search includes both name and SKU matching, and the display format clearly distinguishes variants with "Product Name - SKU" format.


80-82: LGTM: ThumbnailImageColumn implementation follows established pattern.

The image column correctly uses the new ThumbnailImageColumn class with a closure to resolve thumbnail URLs from the discountable relationship. This addresses the previous discussions about image handling in the admin panel.


84-90: LGTM: Text column handles multiple entity types appropriately.

The column correctly formats display names based on the discountable type:

  • ProductVariant: Shows "Product Name - SKU"
  • Other types: Shows the entity name
    This provides clear identification for users.

92-98: LGTM: Type column provides useful context.

The discountable type column helps users understand what type of entity they're working with, using a clean formatted display.

packages/admin/src/Filament/Resources/DiscountResource/RelationManagers/ProductConditionRelationManager.php (3)

47-48: LGTM: Query includes all supported condition types.

The query correctly includes Collection, Product, and ProductVariant types for discount conditions, expanding the functionality as described in the PR objectives.


55-62: LGTM: Collection support implemented consistently.

The Collection type implementation follows the same pattern as Product and ProductVariant types with appropriate search functionality using the collection name attribute.


73-81: LGTM: ProductVariant support matches reward manager implementation.

The ProductVariant implementation is consistent with the ProductRewardRelationManager, ensuring a uniform user experience across condition and reward management.

@glennjacobs glennjacobs merged commit 6b6075a into lunarphp:1.x Jul 10, 2025
47 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants