diff --git a/modules/EcommerceFinance/Repositories/SupplierManagementMirrorRepository.php b/modules/EcommerceFinance/Repositories/SupplierManagementMirrorRepository.php index 4a6ca9d8..d0862fef 100644 --- a/modules/EcommerceFinance/Repositories/SupplierManagementMirrorRepository.php +++ b/modules/EcommerceFinance/Repositories/SupplierManagementMirrorRepository.php @@ -141,7 +141,7 @@ class SupplierManagementMirrorRepository return $this->mirror->connection()->table($this->datasets->get(self::DATASET)->targetTable()) ->whereIn('scmname', $names) ->orderBy('Id') - ->get(['Id', 'scmcode', 'scmname']) + ->get(['Id', 'scmcode', 'scmname', 'buyer']) ->all(); } diff --git a/modules/EcommerceFinance/View/SupplierNegativeAlertPageData.php b/modules/EcommerceFinance/View/SupplierNegativeAlertPageData.php index 67fa3424..bfdf447a 100644 --- a/modules/EcommerceFinance/View/SupplierNegativeAlertPageData.php +++ b/modules/EcommerceFinance/View/SupplierNegativeAlertPageData.php @@ -4,8 +4,10 @@ namespace Modules\EcommerceFinance\View; use App\Http\Controllers\Business\PayablesFinalActions; use Illuminate\Pagination\LengthAwarePaginator; +use Modules\EcommerceFinance\Repositories\SupplierManagementMirrorRepository; use Modules\EcommerceFinance\Services\PayablesFinalRegistry; use Modules\EcommerceFinance\Services\SupplierPayableOverrideStore; +use Throwable; /** * 供应商负数预警:直接读取「供应商应付(终版)→ 供应商应付表」, @@ -20,6 +22,7 @@ class SupplierNegativeAlertPageData public function __construct( private readonly SupplierPayableOverrideStore $store, private readonly PayablesFinalRegistry $registry, + private readonly SupplierManagementMirrorRepository $supplierManagement, ) { } @@ -110,19 +113,59 @@ class SupplierNegativeAlertPageData $total = count($negativeRows); $pages = max((int) ceil($total / self::PER_PAGE), 1); $page = min(max((int) request()->query('page', 1), 1), $pages); - $items = array_map( - static fn (array $row): object => (object) $row, - array_slice($negativeRows, ($page - 1) * self::PER_PAGE, self::PER_PAGE), + $pageRows = array_slice($negativeRows, ($page - 1) * self::PER_PAGE, self::PER_PAGE); + $pageSupplierNames = array_values(array_unique(array_filter( + array_map( + static fn (array $row): string => trim((string) ($row['supplier'] ?? '')), + $pageRows, + ), + static fn (string $name): bool => $name !== '', + ))); + $purchasersBySupplier = []; + if ($pageSupplierNames !== []) { + try { + foreach ($this->supplierManagement->suppliersByNames($pageSupplierNames) as $supplier) { + $name = trim((string) ($supplier->scmname ?? '')); + $buyer = trim((string) ($supplier->buyer ?? '')); + if ($name !== '' && $buyer !== '') { + $purchasersBySupplier[$name][$buyer] = true; + } + } + } catch (Throwable $exception) { + report($exception); + } + } + $purchasersBySupplier = array_map( + static fn (array $buyers): string => implode('、', array_keys($buyers)), + $purchasersBySupplier, ); + $items = array_map( + static function (array $row) use ($purchasersBySupplier): object { + $supplier = trim((string) ($row['supplier'] ?? '')); + $row['purchaser'] = $purchasersBySupplier[$supplier] ?? ''; + + return (object) $row; + }, + $pageRows, + ); + + $negativeAlertFields = []; + $fields = collect($this->registry->fields( + PayablesFinalRegistry::SECTION_SUPPLIER, + self::DATASET, + ))->map( + static fn (array $definition, string $name): array => ['name' => $name] + $definition, + )->values()->all(); + foreach ($fields as $field) { + $negativeAlertFields[] = $field; + if (($field['name'] ?? '') === 'negative_reason') { + $negativeAlertFields[] = ['name' => 'purchaser', 'label' => '采购', 'type' => 'text']; + } + } return [ 'view' => 'business.pages.negative-alerts.supplier-negative-alert', - 'negativeAlertFields' => collect($this->registry->fields( - PayablesFinalRegistry::SECTION_SUPPLIER, - self::DATASET, - ))->map( - static fn (array $definition, string $name): array => ['name' => $name] + $definition, - )->values()->all(), + 'negativeAlertFields' => $negativeAlertFields, 'negativeAlertRows' => new LengthAwarePaginator( $items, $total, diff --git a/tests/Feature/Business/NegativeAlertPagesTest.php b/tests/Feature/Business/NegativeAlertPagesTest.php index 7c38dbf7..f86856dd 100644 --- a/tests/Feature/Business/NegativeAlertPagesTest.php +++ b/tests/Feature/Business/NegativeAlertPagesTest.php @@ -6,6 +6,7 @@ use App\Http\Controllers\Business\PayablesFinalActions; use App\Listeners\Menu\ShowInAdmin; use App\Models\Auth\Permission; use App\Utilities\BusinessNavigation; +use Modules\EcommerceFinance\Repositories\SupplierManagementMirrorRepository; use Modules\EcommerceFinance\Services\PayablesFinalRegistry; use Modules\EcommerceFinance\Services\SupplierPayableOverrideStore; use Tests\Feature\FeatureTestCase; @@ -57,6 +58,17 @@ class NegativeAlertPagesTest extends FeatureTestCase 'should_pay' => '-500.00', 'estimated_price' => '50.00', ]); + $supplierManagement = \Mockery::mock(SupplierManagementMirrorRepository::class); + $supplierManagement->shouldReceive('suppliersByNames') + ->once() + ->withArgs(static fn (array $names): bool => count($names) === 2 + && in_array('负余额供应商', $names, true) + && in_array('公式命中供应商', $names, true)) + ->andReturn([ + (object) ['scmname' => '负余额供应商', 'buyer' => '采购甲'], + (object) ['scmname' => '公式命中供应商', 'buyer' => '采购乙'], + ]); + $this->app->instance(SupplierManagementMirrorRepository::class, $supplierManagement); $response = $this->loginAs() ->get(route('business.pages.show', [ @@ -72,6 +84,8 @@ class NegativeAlertPagesTest extends FeatureTestCase ->assertSeeText('公式命中供应商') ->assertSeeText('-128.50') ->assertSeeText('历史多付款') + ->assertSeeText('采购甲') + ->assertSeeText('采购乙') ->assertDontSeeText('正余额供应商') ->assertDontSeeText('负余额但公式为正供应商'); @@ -81,7 +95,16 @@ class NegativeAlertPagesTest extends FeatureTestCase ); $html = (string) $response->getContent(); preg_match_all('/