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.
Installation:
composer require greenter/core
Add the service provider to config/app.php:
'providers' => [
// ...
Greenter\Core\GreenterServiceProvider::class,
],
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).
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).Document Generation:
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'; }
}
Greenter\Core\NotaCredito or NotaDebito with similar patterns.Tax and Sunat Compliance:
$item = new SaleDetail();
$item->setSunatCode('1000') // Gravado
->setUnitPrice(100)
->setQuantity(2)
->setTotal(200);
$tax = $item->calculateTax(); // Returns tax amount based on config/greenter.php
config/greenter.php under sunat_codes or extend via SunatCodeProvider.Notifications:
use Greenter\Core\Notification;
$notification = new Notification();
$notification->addAttachment('path/to/invoice.pdf')
->send(); // Uses the Notificator service (configured in config/greenter.php)
Validation:
@Assert\NotBlank) or extend via ErrorCodeProvider:
class CustomErrorProvider implements IErrorCodeProvider {
public function getErrors(): array {
return [
'INVALID_SERIE' => 'La serie debe ser FXXX',
];
}
}
greenter.sale.created or greenter.notification.sent in EventServiceProvider:
protected $listen = [
'greenter.sale.created' => [
'App\Listeners\LogSale',
],
];
Notification::dispatch($notification)->onQueue('notifications');
return response()->xml($factura->generate())->header('Content-Type', 'application/xml');
UBL Version Mismatch:
ubl_version in config/greenter.php matches the document type (e.g., 2.1 for Facturas/Boletas in v2.1+).Greenter\Core\UBL\Generator to support custom versions.Sunat Code Conflicts:
'1000') may break if tax rules change.SunatCodeProvider interface to fetch dynamic codes:
$provider = app(SunatCodeProvider::class);
$code = $provider->getCodeForItem($item);
Validation Annotations:
@Assert annotations may conflict with Laravel’s validation.Greenter\Core\Validator directly.Date Handling:
Fecha de Vencimiento (due date) must be in Y-m-d format. Older versions (<1.2.1) may fail silently.if (!$dueDate instanceof \DateTime) {
throw new \InvalidArgumentException('Due date must be a DateTime object.');
}
Deprecated Methods:
Summary class was removed in v1.2.0. Use BaseSale::getTotal() instead.php artisan greenter:validate to check UBL compliance.
php artisan greenter:validate --file=path/to/invoice.xml
config/greenter.php:
'debug' => env('GREENTER_DEBUG', false),
Logs will appear in storage/logs/greenter.log.Custom Document Types:
Extend BaseSale and register the new type in config/greenter.php:
'document_types' => [
'recibo_honorarios' => \App\Models\Recibo::class,
],
Tax Rules:
Override tax calculation logic by binding a custom ITaxCalculator:
$this->app->bind(ITaxCalculator::class, function ($app) {
return new CustomTaxCalculator();
});
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();
});
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
});
How can I help you explore Laravel packages today?