Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
51 / 51
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
ProposalTemplateRenderer
100.00% covered (success)
100.00%
51 / 51
100.00% covered (success)
100.00%
2 / 2
13
100.00% covered (success)
100.00%
1 / 1
 render
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
1
 buildSnapshot
100.00% covered (success)
100.00%
36 / 36
100.00% covered (success)
100.00%
1 / 1
12
1<?php
2
3declare(strict_types=1);
4
5namespace ImovelZapAi\Proposals\Application\Services;
6
7use ImovelZapAi\Proposals\Infrastructure\Persistence\Eloquent\ProposalModel;
8use ImovelZapAi\Proposals\Infrastructure\Persistence\Eloquent\ProposalTemplateModel;
9use ImovelZapAi\Publishing\Infrastructure\Persistence\Eloquent\TenantPublishingConfigModel;
10use ImovelZapAi\Tenancy\Infrastructure\Persistence\Eloquent\TenantModel;
11
12final class ProposalTemplateRenderer
13{
14    /**
15     * @param  array<string, mixed>  $snapshot
16     */
17    public function render(ProposalTemplateModel $template, ProposalModel $proposal, array $snapshot): string
18    {
19        $map = [
20            '{{client_name}}' => (string) ($snapshot['client_name'] ?? ''),
21            '{{owner_name}}' => (string) ($snapshot['owner_name'] ?? ''),
22            '{{amount}}' => (string) ($snapshot['amount_formatted'] ?? ''),
23            '{{commission}}' => (string) ($snapshot['commission_formatted'] ?? ''),
24            '{{property_address}}' => (string) ($snapshot['property_address'] ?? ''),
25            '{{property_features}}' => (string) ($snapshot['property_features'] ?? ''),
26            '{{broker_name}}' => (string) ($snapshot['broker_name'] ?? ''),
27            '{{company_name}}' => (string) ($snapshot['company_name'] ?? ''),
28            '{{logo_url}}' => (string) ($snapshot['logo_url'] ?? ''),
29            '{{intro_message}}' => (string) ($snapshot['intro_message'] ?? $proposal->intro_message ?? ''),
30            '{{proposal_number}}' => (string) $proposal->number,
31            '{{version}}' => (string) ($snapshot['version'] ?? '1'),
32        ];
33
34        return str_replace(array_keys($map), array_values($map), $template->body_html);
35    }
36
37    /** @return array<string, mixed> */
38    public function buildSnapshot(ProposalModel $proposal, int $version): array
39    {
40        $tenant = TenantModel::query()->find($proposal->tenant_id);
41        $branding = TenantPublishingConfigModel::query()->where('tenant_id', $proposal->tenant_id)->first();
42        $property = $proposal->property;
43        $amount = $proposal->amount !== null ? 'R$ '.number_format((float) $proposal->amount, 2, ',', '.') : 'A combinar';
44        $commission = $proposal->commission_percent !== null
45            ? number_format((float) $proposal->commission_percent, 2, ',', '.').'%'
46            : '—';
47
48        $address = collect([
49            $property?->street,
50            $property?->number,
51            $property?->neighborhood?->name ?? null,
52            $property?->city?->name ?? null,
53        ])->filter()->implode(', ');
54
55        $features = collect([
56            $property?->bedrooms ? $property->bedrooms.' quartos' : null,
57            $property?->bathrooms ? $property->bathrooms.' banheiros' : null,
58            $property?->parking_spaces ? $property->parking_spaces.' vagas' : null,
59            $property?->useful_area ? $property->useful_area.' m²' : null,
60        ])->filter()->implode(' · ');
61
62        return [
63            'version' => $version,
64            'client_name' => $proposal->contact?->display_name ?: 'Cliente',
65            'owner_name' => $proposal->owner_id ? 'Proprietário' : '—',
66            'amount' => $proposal->amount,
67            'amount_formatted' => $amount,
68            'commission_percent' => $proposal->commission_percent,
69            'commission_formatted' => $commission,
70            'property_address' => $address !== '' ? $address : ($property?->title ?? 'Imóvel'),
71            'property_features' => $features !== '' ? $features : ($property?->title ?? '—'),
72            'broker_name' => $proposal->responsible?->name ?? 'Corretor',
73            'company_name' => $branding?->company_name ?: ($tenant?->name ?? 'Imobiliária'),
74            'logo_url' => $branding?->logo_url,
75            'intro_message' => $proposal->intro_message,
76            'property_id' => $proposal->property_id,
77            'deal_id' => $proposal->deal_id,
78        ];
79    }
80}