Weave Code
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

Money Bundle Laravel Package

babdev/money-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require babdev/money-bundle
    

    Enable the bundle in config/bundles.php:

    return [
        // ...
        BabDev\MoneyBundle\MoneyBundle::class => ['all' => true],
    ];
    
  2. Configure Default Currency (optional):

    # config/packages/babdev_money.yaml
    babdev_money:
        default_currency: EUR  # Defaults to USD
    
  3. First Use Case: Create a Money object in a controller:

    use Money\Money;
    
    $price = Money::EUR(1000); // 10.00 EUR (amount in cents)
    return $this->json(['price' => $price]);
    

Implementation Patterns

Core Workflows

  1. Doctrine Integration:

    • ORM: Use #[ORM\Embedded] for Money fields in entities:
      #[ORM\Entity]
      class Product {
          #[ORM\Embedded(class: Money::class)]
          public Money $price;
      }
      
    • MongoDB ODM: Use #[ODM\EmbedOne]:
      #[ODM\Document]
      class Product {
          #[ODM\EmbedOne(targetDocument: Money::class)]
          public Money $price;
      }
      
  2. Form Handling:

    • Use the built-in MoneyType form field:
      use BabDev\MoneyBundle\Form\Type\MoneyType;
      
      $builder->add('price', MoneyType::class, [
          'currency' => 'EUR',
          'required' => true,
      ]);
      
  3. Validation:

    • Apply constraints to Money fields:
      use BabDev\MoneyBundle\Validator\Constraints\MoneyGreaterThan;
      
      #[MoneyGreaterThan(value: 0)]
      public Money $price;
      
  4. Twig Integration:

    • Format Money in templates:
      {{ product.price|money('decimal', 'en_US', {fraction_digits: 2}) }}
      
    • Create Money objects dynamically:
      {% set discount = money(500, 'EUR') %}
      
  5. API Serialization:

    • Automatically serialize Money to JSON:
      {
          "price": {
              "amount": "1000",
              "currency": "EUR"
          }
      }
      

Integration Tips

  • Custom Formatters: Extend MoneyFormatter and register them in Twig:
    $twig->addFunction(new \Twig\TwigFunction('custom_money', function ($money) {
        return (new CustomMoneyFormatter())->format($money);
    }));
    
  • Currency Conversion: Use Money\Currency and Money\Converter for dynamic conversions:
    $converter = new Money\Converter(new Money\CurrencyCollection());
    $converter->convert(Money::USD(1000), 'EUR');
    

Gotchas and Tips

Pitfalls

  1. Amount Precision:

    • Money objects store amounts in cents (e.g., 1000 = 10.00 EUR). Ensure your application logic accounts for this (e.g., avoid floating-point arithmetic).
    • Fix: Use Money::USD(1000)->getAmount() to get raw cents.
  2. Doctrine Type Mismatches:

    • If using Doctrine ORM, ensure Money fields are mapped as embedded (not column). MongoDB ODM handles this automatically.
    • Fix: Add #[ORM\Embedded(class: Money::class)] to your entity properties.
  3. Serializer Conflicts:

    • If using JMS Serializer, ensure JMSSerializerBundle is installed and configured. The Symfony Serializer works out-of-the-box.
    • Fix: Install via Composer:
      composer require jms/serializer-bundle
      
  4. Twig Filter Limitations:

    • The money filter does not support the aggregate formatter from MoneyPHP. Use intl_money or decimal instead.
    • Fix: Pre-format Money objects in PHP if custom formatting is needed.
  5. Validation Groups:

    • Money constraints (e.g., MoneyGreaterThan) require explicit validation groups if used in forms or DTOs.
    • Fix: Add groups: ['validation'] to your constraint options.

Debugging Tips

  • Check Currency Codes: Invalid currency codes (e.g., US instead of USD) will throw exceptions. Validate against ISO 4217.
  • Log Serialized Output: Use var_dump() or dd() to inspect serialized Money objects:
    $serializer->serialize($money, 'json');
    
  • Doctrine Proxy Issues: If Money objects fail to serialize/deserialize, ensure Doctrine proxies are disabled for embedded objects:
    # config/packages/doctrine.yaml
    doctrine:
        orm:
            entity_managers:
                default:
                    metadata_driver:
                        orm:
                            mappings:
                                App:
                                    type: attribute
                                    is_bundle: false
                                    dir: "%kernel.project_dir%/src/Entity"
                                    prefix: "App\Entity"
                                    alias: App
                    dql:
                        string_functions:
                            CONCAT: DoctrineExtensions\Query\Mysql\Concat
    

Extension Points

  1. Custom Validators:

    • Extend MoneyAssert constraints by creating a new validator class:
      use Symfony\Component\Validator\Constraint;
      use Symfony\Component\Validator\ConstraintValidator;
      
      class CustomMoneyValidator extends ConstraintValidator {
          public function validate($value, Constraint $constraint) {
              if (!$value instanceof Money\Money) {
                  $this->context->buildViolation($constraint->message)
                      ->addViolation();
              }
          }
      }
      
    • Register it as a service:
      services:
          App\Validator\CustomMoneyValidator:
              tags: [validator.constraint_validator]
      
  2. Dynamic Currency Switching:

    • Override the default currency per request using middleware:
      use BabDev\MoneyBundle\Money\MoneyService;
      
      public function __construct(private MoneyService $moneyService) {}
      
      public function handle(Request $request, callable $next) {
          $this->moneyService->setDefaultCurrency('EUR'); // Override for request
          return $next($request);
      }
      
  3. Monetary Calculations:

    • Create a service for reusable calculations (e.g., tax, discounts):
      use Money\Money;
      
      class MoneyCalculator {
          public function applyDiscount(Money $price, float $percentage): Money {
              $discountAmount = $price->multiply($percentage / 100);
              return $price->subtract($discountAmount);
          }
      }
      
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware