'integer', 'total' => 'integer', 'discount' => 'float', 'quantity' => 'float', 'discount_val' => 'integer', 'tax' => 'integer', ]; } /* |-------------------------------------------------------------------------- | Relationships |-------------------------------------------------------------------------- */ /** * Document this line was billed on. */ public function invoice(): BelongsTo { return $this->belongsTo(Invoice::class); } /** * Catalog entry the line was copied from, kept for reporting. */ public function item(): BelongsTo { return $this->belongsTo(Item::class); } /** * Taxes applied to this line, in per-item tax mode. */ public function taxes(): HasMany { return $this->hasMany(Tax::class); } /** * Schedule this line belongs to, when it is part of a recurring template * rather than of an issued document. */ public function recurringInvoice(): BelongsTo { return $this->belongsTo(RecurringInvoice::class); } /* |-------------------------------------------------------------------------- | Query scopes |-------------------------------------------------------------------------- */ /** * Narrow to one company. */ public function scopeWhereCompany(Builder $query, int $company_id): void { $query->where('company_id', $company_id); } /** * Restrict to lines billed on a document issued inside the inclusive range. */ public function scopeInvoicesBetween(Builder $query, Carbon $start, Carbon $end): void { $range = [$start->format('Y-m-d'), $end->format('Y-m-d')]; $query->whereHas('invoice', function ($invoice) use ($range) { $invoice->whereBetween('invoice_date', $range); }); } /** * Apply the date range, which counts only when the caller supplied both * ends of it. */ public function scopeApplyInvoiceFilters(Builder $query, array $filters): void { $from = $filters['from_date'] ?? null; $to = $filters['to_date'] ?? null; if ($from && $to) { $query->invoicesBetween( Carbon::createFromFormat('Y-m-d', $from), Carbon::createFromFormat('Y-m-d', $to) ); } } /** * Roll the lines up by product name, totalling quantity sold and the * revenue it brought in, in the company's own currency. */ public function scopeItemAttributes(Builder $query): void { $columns = [ 'sum(quantity) as total_quantity', 'sum(base_total) as total_amount', 'invoice_items.name', ]; $query->select(DB::raw(implode(', ', $columns))) ->groupBy('invoice_items.name'); } }