189 lines
5.8 KiB
PHP
189 lines
5.8 KiB
PHP
<?php
|
|
|
|
namespace App\Business\KukaPostingBase;
|
|
|
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
|
use Illuminate\Database\ConnectionInterface;
|
|
use Illuminate\Database\DatabaseManager;
|
|
use Illuminate\Support\Facades\Schema;
|
|
|
|
class KukaPostingBaseRepository
|
|
{
|
|
public function __construct(private readonly DatabaseManager $databases)
|
|
{
|
|
}
|
|
|
|
public function available(): bool
|
|
{
|
|
$schema = Schema::connection($this->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<string>
|
|
*/
|
|
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<string>
|
|
*/
|
|
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<string> $itemNumbers
|
|
* @return array<string,object>
|
|
*/
|
|
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<string> $materialNumbers
|
|
* @return array<string,object>
|
|
*/
|
|
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');
|
|
}
|
|
}
|