{{-- Shared faithful port of the body used by the FIVE legacy Complain emails in public/referenceonly/mailhandler.php: - sendEmailComplain (L6034-6277) -> "Complaint Created" - sendEmailComplainAssign (L6283-6497) -> "Complete Assignment" - sendEmailComplainClose (L6503-6754) -> "Closed" - sendEmailComplainCEO (L6757-7130) -> "Assign from CEO" - sendEmailComplainReject (L7263-...) -> "Reject" All five render the SAME skeleton: a font-size-6 banner line, a Header table (9 rows), a "Details" font-size-5 label + a wide details table, and -- for Close/CEO/Reject -- a purple #570086 "History Complaint" banner + history table. They diverge only on the flags documented below, so ONE template stays faithful to each variant. Legacy uses raw string concatenation with strip_tags(); this port uses {{ }} auto-escaping everywhere (safer) and null-safe ?-> navigation to mirror the legacy LEFT JOINs (a missing lookup renders an empty cell rather than erroring). ------------------------------------------------------------------------------ VARIABLE CONTRACT (Complain models do not exist yet -- these are the plausible relation/column names the future Mailable must supply, derived from the legacy SQL. Names in (parens) are the underlying table/column.): $complain -- App\Models\Complain (table `complain`) ->ID complain.ID ->ComplainDate complain.ComplainDate ->CompanyAddress complain.CompanyAddress (on complain, NOT company) ->Telp complain.Telp (on complain, NOT company) ->complainType?->Name complaintype.Name (FK ComplainTypeID) ->division?->DivisionName division.DivisionName (FK DivisionID) ->company?->CompanyName company.CompanyName (FK CompanyID) ->companyCP?->CompanyCPName companycp.CompanyCPName (FK CompanyCPID; selected by legacy but NOT rendered -- kept for parity/future use) ->userIDInput?->Nama users.Nama via UserIDInput ("Creator") ->userIDSales?->Nama users.Nama via UserIDSales ("Sales") $details -- Collection (table `complaindetails`, IsDeleted = 0, order by ID asc). Each detail $d: ->ID complaindetails.ID ->PrincipalName complaindetails.PrincipalName (denormalised column) ->PrincipalID complaindetails.PrincipalID (CEO PM lookup; not rendered) ->ProductName complaindetails.ProductName ->application?->ApplicationName application.ApplicationName (FK ApplicationID) ->BarangListID complaindetails.BarangListID (header label "LotNumber") ->QuantityPacking complaindetails.QuantityPacking ->satuanPacking?->QuotationPackName quotationpack.QuotationPackName (FK SatuanPackingID -> quotationpack, NOT satuan -- PRD §5.8 #2. The ComplainDetails::satuanPacking() relation is CORRECT (already targets QuotationPack); this Blade's own earlier `->SatuanName` reference was the actual bug, fixed 2026-07-22 when the Mailables were wired up.) ->ComplainQuantity complaindetails.ComplainQuantity ->satuanComplainQuantity?->SatuanName satuan.SatuanName (FK SatuanComplainQuantityID) — relation name corrected 2026-07-22 to match the real ComplainDetails model (was guessed as `satuanComplain` before the model existed) ->UnitPriceUSD complaindetails.UnitPriceUSD ->satuanUnitPriceUSD?->SatuanName satuan.SatuanName (FK SatuanUnitPriceUSD) — likewise corrected from the guessed `satuanUSD` ->UnitPriceIDR complaindetails.UnitPriceIDR ->TotalValueUSD / ->TotalValueIDR / ->USDRate ->SJNo / ->SJDate / ->InvoiceNo / ->InvoiceDate ->IsPaid complaindetails.IsPaid (0/1 -> No/Yes) ->PaidDate ->ComplainDesc / ->CustomerExpectation / ->ReporterRequestExpectation ->assignments Collection for THIS detail (complaindetailsassignment, IsDeleted = 0, this ComplainID + ComplainDetailsID). Rendered only in the Created email's per-line History column. Each $a: ->ComplainDetailsStatusID 1=Request 2=Review 3=Assign 4=Done 5=Feedback ->DepartmentID 1=SM 2=PM 6=Finance 11=Accounting 8=CS 5=Logistic ->Tanggal ->ReviewRemark / ->AssignRemark / ->DoneRemark / ->FeedbackRemark ->status?->StatusName complaindetailsstatus.StatusName ->user?->Nama users.Nama via UserID $history -- Collection for the WHOLE complain (complaindetailsassignment where ComplainID = c.ID, order by ID). Rendered in the "History Complaint" section (Close/CEO/Reject). Each $h: ->ID, ->status?->StatusName, ->Tanggal, ->user?->Nama ->ReviewRemark, ->AssignRemark, ->DoneRemark, ->FeedbackRemark, ->DepartmentID ------------------------------------------------------------------------------ PER-VARIANT FLAGS (defaults applied in the PHP defaults block below, so the template renders even when a flag is omitted): $title full banner text (string). Legacy strings, verbatim: Created -> 'Colorindo Chemtra - Complaint Created' Assign -> 'Colorindo Chemtra Complaint - Complete Assignment' Close -> 'Colorindo Chemtra Complaint - Closed' CEO -> 'Colorindo Chemtra Complaint - Assign from CEO' Reject -> 'Colorindo Chemtra Complaint - Reject' default: 'Colorindo Chemtra - Complaint' $ceoRemark nullable string. Non-null ONLY for the CEO email -> renders the "Remark from CEO" table between Header and Details (L6941-6956). default: null (block hidden). $showDetailHistory bool. true ONLY for Created -> adds the per-line "History" column to the Details table (L6142, L6183-6256). default: false. $showHistory bool. true for Close/CEO/Reject -> renders the purple "History Complaint" section (L6682 / L7055 / L7440). default: false. $historyShowRemarks bool. Shape of the History table: true (Close/Reject) -> 8 columns incl. RemarkAssignment + RemarkFeedback @ 12.5% (L6683-6730); false (CEO) -> 6 columns @ 16.67% (L7056-7104). default: true. NOTE / deliberate divergences from the literal legacy source: * Legacy emitted detail rows with the opening commented out (and the Created variant never closes or at all -- a bug that collapses every cell into one row). This port wraps each detail row in a proper ... so the table is valid. The commented-out #eee alternating background is NOT applied, matching legacy's rendered (plain-row) output. * The huge   runs padding each in the legacy source are cosmetic and are omitted here; the column header text and order are reproduced exactly. * Header label ":" spacing is normalised to ": " (legacy mixed " :" and " : "). --}} @php $title = $title ?? 'Colorindo Chemtra - Complaint'; $ceoRemark = $ceoRemark ?? null; $showDetailHistory = $showDetailHistory ?? false; $showHistory = $showHistory ?? false; $historyShowRemarks = $historyShowRemarks ?? true; $details = $details ?? collect(); $history = $history ?? collect(); $deptMap = [1 => 'SM', 2 => 'PM', 6 => 'Finance', 11 => 'Accounting', 8 => 'CS', 5 => 'Logistic']; $num = fn ($v) => number_format((float) $v, 2, '.', ','); @endphp {{ $title }} {{-- Header table --}}
Complain ID : {{ str_pad((string) $complain->ID, 6, '0', STR_PAD_LEFT) }}
Complain Type : {{ $complain->complainType?->Name }}
Division : {{ $complain->division?->DivisionName }}
Creator : {{ $complain->userIDInput?->Nama }}
Sales : {{ $complain->userIDSales?->Nama }}
Complain Date : {{ $complain->ComplainDate }}
Company Name : {{ $complain->company?->CompanyName }}
Company Address : {{ $complain->CompanyAddress }}
CompanyTelephone : {{ $complain->Telp }}
{{-- Remark from CEO (CEO email only) --}} @if ($ceoRemark !== null)
Remark from CEO : {{ $ceoRemark }}
@endif {{-- Details --}} Details @if ($showDetailHistory) @endif @foreach ($details as $d) @if ($showDetailHistory) @endif @endforeach
ID Principal ProductName Application LotNumber QtyPacking ComplainQty UnitPriceUSD UnitPriceIDR TotalValueUSD TotalValueIDR USDRate SJNo SJDate InvoiceNo InvoiceDate IsPaid PaidDate ComplainDesc CustomerExpectation ReporterRequestExpectationHistory
{{ $d->ID }} {{ $d->PrincipalName }} {{ $d->ProductName }} {{ $d->application?->ApplicationName }} {{ $d->BarangListID }} {{ $num($d->QuantityPacking) }} / {{ $d->satuanPacking?->QuotationPackName }} {{ $num($d->ComplainQuantity) }} / {{ $d->satuanComplainQuantity?->SatuanName }} {{ $num($d->UnitPriceUSD) }} / {{ $d->satuanUnitPriceUSD?->SatuanName }} {{ $num($d->UnitPriceIDR) }} {{ $num($d->TotalValueUSD) }} {{ $num($d->TotalValueIDR) }} {{ $num($d->USDRate) }} {{ $d->SJNo }} {{ $d->SJDate }} {{ $d->InvoiceNo }} {{ $d->InvoiceDate }} {{ $d->IsPaid == 1 ? 'Yes' : 'No' }} {{ $d->PaidDate }} {{ $d->ComplainDesc }} {{ $d->CustomerExpectation }} {{ $d->ReporterRequestExpectation }} @foreach ($d->assignments as $a) @php $sid = (int) $a->ComplainDetailsStatusID; $dep = $sid === 1 ? '' : ($deptMap[(int) $a->DepartmentID] ?? ''); $rem = match ($sid) { 2 => $a->ReviewRemark, 3 => $a->AssignRemark, 4 => $a->DoneRemark, 5 => $a->FeedbackRemark, default => '', }; @endphp @if ($sid === 1) {{ $a->Tanggal }} | {{ $a->complainDetailsStatus?->StatusName }} | {{ $a->user?->Nama }}
@elseif ($sid === 3) {{ $a->Tanggal }} | {{ $a->complainDetailsStatus?->StatusName }} to {{ $dep }} | {{ $a->user?->Nama }} | {{ $rem }}
@else {{ $a->Tanggal }} | {{ $a->complainDetailsStatus?->StatusName }} {{ $dep }} | {{ $a->user?->Nama }} | {{ $rem }}
@endif @endforeach
{{-- History Complaint (Close / CEO / Reject) --}} @if ($showHistory)

History Complaint

@if ($historyShowRemarks) @endif @foreach ($history as $h) @php $dept = $deptMap[(int) $h->DepartmentID] ?? ''; @endphp @if ($historyShowRemarks) @endif @endforeach
ID Status Tanggal User ReviewRemark RemarkCEORemarkAssignment RemarkFeedback
{{ $h->ID }} {{ $h->complainDetailsStatus?->StatusName }} {{ $h->Tanggal }} {{ $h->user?->Nama }} {{ $h->ReviewRemark }} {{ $h->AssignRemark }} Remark {{ $dept }} : {{ $h->DoneRemark }} Remark {{ $dept }} : {{ $h->FeedbackRemark }}
@endif