connectionName()); return $schema->hasTable('kuka_posting_base_imports') && $schema->hasTable('kuka_posting_base_rows'); } public function latestImport(int $companyId): ?object { if (! $this->available()) { return null; } return $this->connection() ->table('kuka_posting_base_imports') ->where('company_id', $companyId) ->orderByDesc('period') ->first(); } public function importFor(int $companyId, string $period): ?object { if (! $this->available()) { return null; } return $this->connection() ->table('kuka_posting_base_imports') ->where('company_id', $companyId) ->where('period', $period) ->first(); } /** * @return list */ public function periods(int $companyId): array { if (! $this->available()) { return []; } return $this->connection() ->table('kuka_posting_base_imports') ->where('company_id', $companyId) ->orderByDesc('period') ->pluck('period') ->map(static fn (mixed $period): string => (string) $period) ->all(); } /** * @return list */ public function statuses(int $companyId, string $period): array { if (! $this->available()) { return []; } return $this->connection() ->table('kuka_posting_base_rows') ->where('company_id', $companyId) ->where('period', $period) ->whereNotNull('order_status') ->where('order_status', '!=', '') ->distinct() ->orderBy('order_status') ->pluck('order_status') ->map(static fn (mixed $status): string => (string) $status) ->all(); } /** * @param list $itemNumbers * @return array */ public function materialMaps(int $companyId, array $itemNumbers): array { $itemNumbers = array_values(array_unique(array_filter(array_map( static fn (mixed $value): string => trim((string) $value), $itemNumbers, )))); if ($itemNumbers === [] || ! Schema::connection($this->connectionName())->hasTable('kuka_posting_material_map_rows')) { return []; } return $this->connection() ->table('kuka_posting_material_map_rows') ->where('company_id', $companyId) ->where('match_status', 'matched') ->whereIn('item_number', $itemNumbers) ->get(['item_number', 'material_number']) ->filter(static fn (object $row): bool => trim((string) $row->material_number) !== '') ->keyBy(static fn (object $row): string => (string) $row->item_number) ->all(); } /** * @param list $materialNumbers * @return array */ public function effectiveQuotations(int $companyId, array $materialNumbers): array { $materialNumbers = array_values(array_unique(array_filter(array_map( static fn (mixed $value): string => trim((string) $value), $materialNumbers, )))); if ($materialNumbers === [] || ! Schema::connection($this->connectionName())->hasTable('kuka_posting_quotation_rows')) { return []; } return $this->connection() ->table('kuka_posting_quotation_rows') ->where('company_id', $companyId) ->where('record_status', '生效') ->whereIn('material_number', $materialNumbers) ->get(['material_number', 'material_desc', 'price_including_tax']) ->keyBy(static fn (object $row): string => (string) $row->material_number) ->all(); } public function paginate( int $companyId, string $period, array $filters, int $page, int $perPage, ): LengthAwarePaginator { $query = $this->connection() ->table('kuka_posting_base_rows') ->where('company_id', $companyId) ->where('period', $period); $storeName = trim((string) ($filters['store_name'] ?? '')); if ($storeName !== '') { $query->where('store_name', $storeName); } $status = trim((string) ($filters['status'] ?? '')); if ($status !== '') { $query->where('order_status', $status); } $keyword = trim((string) ($filters['keyword'] ?? '')); if ($keyword !== '') { $like = '%' . addcslashes($keyword, '\\%_') . '%'; $query->where(static function ($nested) use ($like): void { $nested->where('internal_order_no', 'like', $like) ->orWhere('online_order_no', 'like', $like) ->orWhere('product_code', 'like', $like); }); } return $query ->orderBy('source_row_number') ->paginate($perPage, ['*'], 'page', $page) ->withQueryString(); } private function connection(): ConnectionInterface { return $this->databases->connection($this->connectionName()); } private function connectionName(): string { return (string) config('upstream_mirrors.connection', 'business_mirror'); } }