Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Mutable Content Shop Laravel Package

amarenkov/laravel-mutable-content-shop

A practical Laravel package for mutable-content shops that provides building blocks to manage and dynamically update storefront content. It helps Laravel developers keep product listings, pages, and other shop content editable, organized, and easy to maintain within their applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and publish its assets:

composer require mutable-content/shop
php artisan vendor:publish --tag=mutable-content-shop-config
php artisan vendor:publish --tag=mutable-content-shop-migrations
php artisan migrate

Set invoices_disk in config/mutable-content-shop.php to a valid filesystem disk (e.g. local or s3). If you need custom models or states, review models.invoice, lovs.order_state, and lovs.order_item_state in the same config file. For a first use case, create an order and attach an invoice:

$order = Order::create([...]);
$invoice = $order->invoices()->create([
    'number' => 'INV-001',
    'date' => now(),
    'money' => 10000, // amount in minor units, depending on money package
    'paid_amount' => 2500,
    'comment' => 'First invoice',
]);

$invoice->due();               // remaining amount
$order->invoicedTotal();       // sum of invoice amounts
$order->paidTotal();           // sum of paid amounts

Look first at the Invoice model (fields, due(), hasFile(), Invoice::disk()) and the Order model (invoices(), invoicedTotal(), paidTotal()).

Implementation Patterns

Invoice creation and payment state – Set money and paid_amount; the invoice_payment_state LOV (unpaid, partially_paid, paid) is recalculated automatically on save. Avoid setting the state manually unless you have a custom requirement. Use the state for filtering and reporting.

File attachments – Store documents on the disk returned by Invoice::disk() (driven by invoices_disk). Check existence with $invoice->hasFile(). Upload via Storage::disk(Invoice::disk())->putFile('invoices', $file) and save the path on the invoice.

Totals for dashboards – Order::invoicedTotal() and paidTotal() are convenient for order summaries. Eager load invoices when iterating orders to avoid N+1 queries.

Extending state LOVs – Create a subclass of the relevant LOV class (e.g. OrderState), add your own constants, and point lovs.order_state or lovs.order_item_state to your class. This keeps package behaviour intact while allowing domain‑specific states.

Custom models – Swap models.invoice in config to your own class extending the base Invoice. Ensure it preserves the package’s table name and the static disk() method. Publish only the invoice migration with the mutable-content-shop-migrations tag when you already have other shop tables.

Gotchas and Tips

  • Currency mismatch throws DomainException – paid_amount must use the same currency as money. Validate or convert before saving to avoid runtime exceptions.
  • Payment state is derived – It syncs from amounts on save. If you need to force a state (e.g. write‑off), consider a custom method that adjusts amounts rather than overriding the state directly.
  • Config changes require cache clear – After editing invoices_disk, models.invoice, or LOV classes, run php artisan config:clear. Cached config can cause confusing behaviour in production.
  • Disk misconfiguration – If invoices_disk is not a valid disk, file operations fail. Test Storage::disk(Invoice::disk())->exists(...) early. Do not assume local storage.
  • Migration tag conflicts – Publishing mutable-content-shop-migrations may attempt to recreate existing tables. Use the tag carefully and review the generated migration before running migrate.
  • LOV extension safety – When subclassing LOV classes, never change existing constant values; add new ones. Existing database records rely on the original values.
  • due() return type – It likely returns a money object, not a scalar. Use its API (e.g. ->getAmount()) for comparisons or formatting. Do not cast directly to float.
  • File cleanup – Deleting an invoice does not automatically delete its file. Remove the file in an observer or model event if storage hygiene matters.
  • Total performance – invoicedTotal() and paidTotal() aggregate across invoices. Cache results or use eager‑loaded collections for large order lists.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel