162 lines
6.7 KiB
PHP
162 lines
6.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Business;
|
|
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Routing\Controller;
|
|
use Illuminate\Validation\ValidationException;
|
|
use Modules\EcommerceFinance\Repositories\SupplierManagementMirrorRepository;
|
|
use Modules\EcommerceFinance\Services\SupplierFreeShippingStore;
|
|
use Modules\EcommerceFinance\Services\SupplierFreeShippingWorkbook;
|
|
use Modules\EcommerceFinance\View\SupplierManagementPageData;
|
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
|
|
|
class SupplierManagement extends Controller
|
|
{
|
|
public function export(
|
|
Request $request,
|
|
SupplierManagementMirrorRepository $repository,
|
|
SupplierManagementPageData $page,
|
|
SupplierFreeShippingStore $freeShipping,
|
|
): StreamedResponse {
|
|
abort_unless($repository->ready(), 503, '供应商资料尚未完成首次同步,暂时不能导出。');
|
|
$filters = $page->filters($request->query());
|
|
$columns = SupplierManagementPageData::columns();
|
|
$companyId = (int) (company_id() ?: 1);
|
|
|
|
return response()->streamDownload(static function () use ($repository, $filters, $columns, $freeShipping, $companyId): void {
|
|
$csv = fopen('php://output', 'w');
|
|
fputs($csv, "\xEF\xBB\xBF");
|
|
fputcsv($csv, array_values($columns));
|
|
foreach ($repository->exportRows($filters) as $row) {
|
|
$row = $freeShipping->decorateRow($row, $companyId);
|
|
$values = [];
|
|
foreach (array_keys($columns) as $column) {
|
|
$value = $column === SupplierManagementPageData::FREE_SHIPPING_COLUMN
|
|
? ((bool) ($row->{$column} ?? false) ? '包邮' : '')
|
|
: (string) ($row->{$column} ?? '');
|
|
if ($column === 'coopersgn') $value = ['1' => '合作', '2' => '不合作'][$value] ?? '未维护';
|
|
// Excel 不能执行供应商提供的公式文本,且长编码保留为文本。
|
|
if (preg_match('/^[=+\-@\t\r\n]/', ltrim($value)) || preg_match('/^\d{12,}$/', $value)) $value = "'" . $value;
|
|
$values[] = $value;
|
|
}
|
|
fputcsv($csv, $values);
|
|
}
|
|
fclose($csv);
|
|
}, 'supplier_management_' . now()->format('Ymd_His') . '.csv',
|
|
['Content-Type' => 'text/csv; charset=UTF-8', 'Cache-Control' => 'private, no-store']);
|
|
}
|
|
|
|
public function template(SupplierFreeShippingWorkbook $workbook): StreamedResponse
|
|
{
|
|
return $workbook->template();
|
|
}
|
|
|
|
public function import(
|
|
Request $request,
|
|
SupplierManagementMirrorRepository $repository,
|
|
SupplierFreeShippingStore $freeShipping,
|
|
SupplierFreeShippingWorkbook $workbook,
|
|
): RedirectResponse {
|
|
$request->validate(['import' => ['required', 'file', 'mimes:xlsx,xls,csv', 'max:10240']]);
|
|
abort_unless($repository->ready(), 503, '供应商资料尚未完成首次同步,暂时不能导入。');
|
|
|
|
$valuesByCode = $workbook->read($request->file('import'));
|
|
$suppliers = $repository->suppliersByCodes(array_keys($valuesByCode));
|
|
$matched = [];
|
|
foreach ($suppliers as $supplier) {
|
|
$code = mb_strtolower(trim((string) ($supplier->scmcode ?? '')));
|
|
if ($code !== '') {
|
|
$matched[$code][] = $supplier;
|
|
}
|
|
}
|
|
|
|
$missing = [];
|
|
$ambiguous = [];
|
|
$valuesBySupplierId = [];
|
|
foreach ($valuesByCode as $code => $isFreeShipping) {
|
|
$key = mb_strtolower(trim((string) $code));
|
|
if (! isset($matched[$key])) {
|
|
$missing[] = (string) $code;
|
|
continue;
|
|
}
|
|
if (count($matched[$key]) !== 1) {
|
|
$ambiguous[] = (string) $code;
|
|
continue;
|
|
}
|
|
$valuesBySupplierId[(int) $matched[$key][0]->Id] = $isFreeShipping;
|
|
}
|
|
if ($ambiguous !== []) {
|
|
throw ValidationException::withMessages([
|
|
'import' => '以下供应商代码在供应商主档中存在多条记录,未导入:' . implode('、', array_slice($ambiguous, 0, 8)),
|
|
]);
|
|
}
|
|
if ($missing !== []) {
|
|
throw ValidationException::withMessages([
|
|
'import' => '以下供应商代码未找到,未导入:' . implode('、', array_slice($missing, 0, 8))
|
|
. (count($missing) > 8 ? ' 等 ' . count($missing) . ' 条' : ''),
|
|
]);
|
|
}
|
|
|
|
$result = $freeShipping->saveMany(
|
|
$valuesBySupplierId,
|
|
(int) (company_id() ?: 1),
|
|
user_id() ? (int) user_id() : null,
|
|
'import',
|
|
);
|
|
|
|
return $this->redirectToPage($request)->with(
|
|
'supplier_management_message',
|
|
"导入完成:新增 {$result['created']} 家供应商维护记录,更新 {$result['updated']} 家供应商维护记录。",
|
|
);
|
|
}
|
|
|
|
public function updateFreeShipping(
|
|
Request $request,
|
|
int $supplier,
|
|
SupplierManagementMirrorRepository $repository,
|
|
SupplierFreeShippingStore $freeShipping,
|
|
): JsonResponse|RedirectResponse {
|
|
$request->validate(['value' => ['nullable', 'string', 'in:,包邮']]);
|
|
abort_unless($repository->ready(), 503, '供应商资料尚未完成首次同步,暂时不能编辑。');
|
|
abort_if($repository->supplierById($supplier) === null, 404, '供应商不存在。');
|
|
|
|
$isFreeShipping = $request->input('value') === '包邮';
|
|
$freeShipping->save(
|
|
$supplier,
|
|
$isFreeShipping,
|
|
(int) (company_id() ?: 1),
|
|
user_id() ? (int) user_id() : null,
|
|
'manual',
|
|
);
|
|
|
|
if ($request->expectsJson()) {
|
|
return response()->json([
|
|
'ok' => true,
|
|
'value' => $isFreeShipping ? '包邮' : '',
|
|
'display' => $isFreeShipping ? '包邮' : '-',
|
|
]);
|
|
}
|
|
|
|
return $this->redirectToPage($request)->with('supplier_management_message', '是否包邮厂家已保存。');
|
|
}
|
|
|
|
private function redirectToPage(Request $request): RedirectResponse
|
|
{
|
|
$query = array_filter([
|
|
...app(SupplierManagementPageData::class)->filters($request->query()),
|
|
'page' => max((int) $request->query('page', 1), 1),
|
|
], static fn (mixed $value): bool => $value !== '');
|
|
|
|
$url = route('business.pages.show', [
|
|
'company_id' => company_id() ?: 1,
|
|
'section' => 'supplier-payables',
|
|
'page' => 'supplier-management',
|
|
]);
|
|
|
|
return redirect()->to($url . ($query === [] ? '' : '?' . http_build_query($query)));
|
|
}
|
|
}
|