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

Core Laravel Package

greenter/core

Greenter Core provides shared definitions and abstractions for the Greenter ecosystem. Use it as the foundation for building Peru electronic invoicing (SUNAT) solutions, with common contracts and core structures used across Greenter packages.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require greenter/core
    

    Add the service provider to config/app.php:

    'providers' => [
        // ...
        Greenter\Core\GreenterServiceProvider::class,
    ],
    
  2. Publish Config:

    php artisan vendor:publish --provider="Greenter\Core\GreenterServiceProvider"
    

    This generates a config/greenter.php file with default settings (e.g., UBL version, tax rules, and Sunat codes).

  3. First Use Case: Generate a basic invoice (factura) with UBL 2.1:

    use Greenter\Core\Factura;
    
    $factura = new Factura();
    $factura->setSerie('F001')
            ->setNumero(1001)
            ->addCliente('12345678', 'John Doe')
            ->addItem('010110', 'Product X', 100, 1.2, 'UN')
            ->setTotal(120);
    
    $xml = $factura->generate();
    

    Key Files to Review:

    • config/greenter.php (tax rules, Sunat codes, and UBL settings).
    • src/Contracts/ (interfaces like ISale, IErrorCodeProvider for extension points).
    • src/Models/ (base models like BaseSale, SaleDetail).

Implementation Patterns

Core Workflows

  1. Document Generation:

    • Facturas/Boletas: Extend Greenter\Core\Models\BaseSale and implement ISale.
      class MyInvoice extends BaseSale implements ISale {
          public function getType(): string { return 'factura'; }
          public function getUbication(): string { return 'PE'; }
      }
      
    • Notas de Crédito/Débito: Use Greenter\Core\NotaCredito or NotaDebito with similar patterns.
  2. Tax and Sunat Compliance:

    • Dynamic Tax Calculation:
      $item = new SaleDetail();
      $item->setSunatCode('1000') // Gravado
            ->setUnitPrice(100)
            ->setQuantity(2)
            ->setTotal(200);
      
      $tax = $item->calculateTax(); // Returns tax amount based on config/greenter.php
      
    • Sunat Codes: Reference config/greenter.php under sunat_codes or extend via SunatCodeProvider.
  3. Notifications:

    • Attach files (e.g., PDFs) to notifications:
      use Greenter\Core\Notification;
      
      $notification = new Notification();
      $notification->addAttachment('path/to/invoice.pdf')
                   ->send(); // Uses the Notificator service (configured in config/greenter.php)
      
  4. Validation:

    • Use built-in Symfony annotations (e.g., @Assert\NotBlank) or extend via ErrorCodeProvider:
      class CustomErrorProvider implements IErrorCodeProvider {
          public function getErrors(): array {
              return [
                  'INVALID_SERIE' => 'La serie debe ser FXXX',
              ];
          }
      }
      

Integration Tips

  • Laravel Events: Bind to greenter.sale.created or greenter.notification.sent in EventServiceProvider:
    protected $listen = [
        'greenter.sale.created' => [
            'App\Listeners\LogSale',
        ],
    ];
    
  • Queue Jobs: Dispatch notifications asynchronously:
    Notification::dispatch($notification)->onQueue('notifications');
    
  • API Responses: Serialize documents to XML/JSON:
    return response()->xml($factura->generate())->header('Content-Type', 'application/xml');
    

Gotchas and Tips

Pitfalls

  1. UBL Version Mismatch:

    • Ensure ubl_version in config/greenter.php matches the document type (e.g., 2.1 for Facturas/Boletas in v2.1+).
    • Fix: Update the config or extend Greenter\Core\UBL\Generator to support custom versions.
  2. Sunat Code Conflicts:

    • Hardcoding Sunat codes (e.g., '1000') may break if tax rules change.
    • Fix: Use the SunatCodeProvider interface to fetch dynamic codes:
      $provider = app(SunatCodeProvider::class);
      $code = $provider->getCodeForItem($item);
      
  3. Validation Annotations:

    • Symfony’s @Assert annotations may conflict with Laravel’s validation.
    • Fix: Exclude Greenter models from Laravel’s validation pipeline or use Greenter\Core\Validator directly.
  4. Date Handling:

    • Fecha de Vencimiento (due date) must be in Y-m-d format. Older versions (<1.2.1) may fail silently.
    • Fix: Validate dates explicitly:
      if (!$dueDate instanceof \DateTime) {
          throw new \InvalidArgumentException('Due date must be a DateTime object.');
      }
      
  5. Deprecated Methods:

    • Summary class was removed in v1.2.0. Use BaseSale::getTotal() instead.

Debugging Tips

  • XML Validation: Use php artisan greenter:validate to check UBL compliance.
    php artisan greenter:validate --file=path/to/invoice.xml
    
  • Logging: Enable debug mode in config/greenter.php:
    'debug' => env('GREENTER_DEBUG', false),
    
    Logs will appear in storage/logs/greenter.log.

Extension Points

  1. Custom Document Types: Extend BaseSale and register the new type in config/greenter.php:

    'document_types' => [
        'recibo_honorarios' => \App\Models\Recibo::class,
    ],
    
  2. Tax Rules: Override tax calculation logic by binding a custom ITaxCalculator:

    $this->app->bind(ITaxCalculator::class, function ($app) {
        return new CustomTaxCalculator();
    });
    
  3. Notificator: Replace the default notificator (e.g., for email/SMS) by binding Greenter\Core\Contracts\INotificator:

    $this->app->bind(INotificator::class, function ($app) {
        return new SlackNotificator();
    });
    
  4. Parser Extensions: Extend the built-in parser (added in v1.0.1) to support custom XML structures:

    use Greenter\Core\Parser\XmlParser;
    
    $parser = new XmlParser();
    $parser->addCustomHandler('custom_tag', function ($node) {
        // Handle custom XML nodes
    });
    
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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours