208 lines
8.4 KiB
PHP
208 lines
8.4 KiB
PHP
<?php
|
|
|
|
namespace Modules\EcommerceFinance\Services;
|
|
|
|
use App\Utilities\FinanceLedgerAccountStatus;
|
|
use App\Utilities\FinanceLedgerAccountShouldKeep;
|
|
use App\Utilities\FinanceLedgerAccountType;
|
|
use Illuminate\Support\Facades\DB;
|
|
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
|
use PhpOffice\PhpSpreadsheet\Cell\DataValidation;
|
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
|
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
|
use PhpOffice\PhpSpreadsheet\Style\Border;
|
|
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
|
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
|
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
|
|
|
/**
|
|
* 财务台账账户总表空白录入模板。
|
|
*/
|
|
class FinanceLedgerAccountTemplate
|
|
{
|
|
private const MAX_ROWS = 1000;
|
|
|
|
private const HEADERS = [
|
|
'公司名称',
|
|
'账户简称',
|
|
'账户类型',
|
|
'账户状态',
|
|
'地区',
|
|
'账号',
|
|
'开户行',
|
|
'开户城市/网点',
|
|
'公司规划',
|
|
'账户是否保留',
|
|
'后4位',
|
|
'单笔限额',
|
|
'日限额',
|
|
'月限额',
|
|
'年限额',
|
|
'可用金额',
|
|
'不可用金额',
|
|
'每日可出',
|
|
'预计出清天数',
|
|
'提额目标',
|
|
'提额状态',
|
|
'提额动作',
|
|
'已做动作',
|
|
'下一步',
|
|
'备注',
|
|
'责任人',
|
|
];
|
|
|
|
public function download(): StreamedResponse
|
|
{
|
|
$spreadsheet = $this->makeSpreadsheet();
|
|
|
|
return response()->streamDownload(function () use ($spreadsheet): void {
|
|
$writer = new Xlsx($spreadsheet);
|
|
$writer->setPreCalculateFormulas(false);
|
|
$writer->save('php://output');
|
|
$spreadsheet->disconnectWorksheets();
|
|
}, '财务台账-账户总表录入模板.xlsx', [
|
|
'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
'Cache-Control' => 'no-store, no-cache, must-revalidate',
|
|
]);
|
|
}
|
|
|
|
private function makeSpreadsheet(): Spreadsheet
|
|
{
|
|
$spreadsheet = new Spreadsheet();
|
|
$spreadsheet->getProperties()
|
|
->setTitle('财务台账账户总表录入模板')
|
|
->setSubject('账户总表重新录入');
|
|
|
|
$sheet = $spreadsheet->getActiveSheet();
|
|
$sheet->setTitle('账户总表');
|
|
$lastColumn = Coordinate::stringFromColumnIndex(count(self::HEADERS));
|
|
$lastRow = self::MAX_ROWS + 1;
|
|
|
|
foreach (self::HEADERS as $index => $header) {
|
|
$column = Coordinate::stringFromColumnIndex($index + 1);
|
|
$sheet->setCellValue("{$column}1", $header);
|
|
$sheet->getColumnDimension($column)->setWidth($this->width($index));
|
|
}
|
|
|
|
$sheet->freezePane('A2');
|
|
$sheet->setAutoFilter("A1:{$lastColumn}1");
|
|
$sheet->getRowDimension(1)->setRowHeight(28);
|
|
$sheet->getStyle("A1:{$lastColumn}1")->getAlignment()
|
|
->setHorizontal(Alignment::HORIZONTAL_CENTER)
|
|
->setVertical(Alignment::VERTICAL_CENTER)
|
|
->setWrapText(true);
|
|
$sheet->getStyle("A1:{$lastColumn}1")->getFont()->setBold(true)->getColor()->setARGB('FFFFFFFF');
|
|
$sheet->getStyle("A1:{$lastColumn}1")->getFill()
|
|
->setFillType(Fill::FILL_SOLID)
|
|
->getStartColor()->setARGB('FF856632');
|
|
$sheet->getStyle("A1:{$lastColumn}{$lastRow}")->getBorders()->getAllBorders()
|
|
->setBorderStyle(Border::BORDER_THIN)->getColor()->setARGB('FFD8D2C7');
|
|
|
|
$sheet->getStyle("A2:O{$lastRow}")->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_TEXT);
|
|
$sheet->getStyle("P2:R{$lastRow}")->getNumberFormat()->setFormatCode('#,##0.00');
|
|
$sheet->getStyle("S2:S{$lastRow}")->getNumberFormat()->setFormatCode('0.00');
|
|
$sheet->getStyle("T2:Z{$lastRow}")->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_TEXT);
|
|
|
|
$options = $spreadsheet->createSheet();
|
|
$options->setTitle('选项');
|
|
$options->setCellValue('A1', '账户状态');
|
|
$options->setCellValue('B1', '账户类型');
|
|
$options->setCellValue('C1', '账户是否保留');
|
|
$statuses = array_values(FinanceLedgerAccountStatus::OPTIONS);
|
|
$types = $this->accountTypes();
|
|
$keepOptions = FinanceLedgerAccountShouldKeep::OPTIONS;
|
|
foreach ($statuses as $index => $status) {
|
|
$options->setCellValue('A' . ($index + 2), $status);
|
|
}
|
|
foreach ($types as $index => $type) {
|
|
$options->setCellValue('B' . ($index + 2), $type);
|
|
}
|
|
foreach ($keepOptions as $index => $option) {
|
|
$options->setCellValue('C' . ($index + 2), $option);
|
|
}
|
|
$options->setSheetState(Worksheet::SHEETSTATE_HIDDEN);
|
|
|
|
$this->applyListValidation($sheet, 'D', '\'选项\'!$A$2:$A$' . (count($statuses) + 1), '请选择账户状态');
|
|
if ($types !== []) {
|
|
$this->applyListValidation($sheet, 'C', '\'选项\'!$B$2:$B$' . (count($types) + 1), '请选择账户类型');
|
|
}
|
|
$this->applyListValidation($sheet, 'J', '\'选项\'!$C$2:$C$' . (count($keepOptions) + 1), '请选择账户是否保留');
|
|
|
|
$notes = $spreadsheet->createSheet();
|
|
$notes->setTitle('填写说明');
|
|
$notes->fromArray([
|
|
['项目', '说明'],
|
|
['用途', '账户总表重新录入模板,不包含当前账户数据。'],
|
|
['必填', '公司名称、账户简称。'],
|
|
['账户状态', implode(' / ', $statuses)],
|
|
['账户类型', $types !== [] ? implode(' / ', $types) : '留空或按实际填写'],
|
|
['账户是否保留', implode(' / ', $keepOptions)],
|
|
['金额', '可用金额、不可用金额、每日可出按数字填写;限额列保留原有组合写法。'],
|
|
['提交前', '请核对账户数、余额合计和期初合计,再导入系统。'],
|
|
], null, 'A1');
|
|
$notes->getColumnDimension('A')->setWidth(16);
|
|
$notes->getColumnDimension('B')->setWidth(70);
|
|
$notes->getStyle('A1:B1')->getFont()->setBold(true)->getColor()->setARGB('FFFFFFFF');
|
|
$notes->getStyle('A1:B1')->getFill()
|
|
->setFillType(Fill::FILL_SOLID)
|
|
->getStartColor()->setARGB('FF856632');
|
|
$notes->getStyle('A1:B8')->getAlignment()->setVertical(Alignment::VERTICAL_TOP)->setWrapText(true);
|
|
$notes->getStyle('A1:B8')->getBorders()->getAllBorders()
|
|
->setBorderStyle(Border::BORDER_THIN)->getColor()->setARGB('FFD8D2C7');
|
|
$notes->getRowDimension(1)->setRowHeight(26);
|
|
|
|
$spreadsheet->setActiveSheetIndex(0);
|
|
|
|
return $spreadsheet;
|
|
}
|
|
|
|
private function applyListValidation(
|
|
Worksheet $sheet,
|
|
string $column,
|
|
string $formula,
|
|
string $prompt,
|
|
): void {
|
|
$validation = $sheet->getCell("{$column}2")->getDataValidation();
|
|
$validation->setType(DataValidation::TYPE_LIST);
|
|
$validation->setErrorStyle(DataValidation::STYLE_STOP);
|
|
$validation->setAllowBlank(true);
|
|
$validation->setShowInputMessage(true);
|
|
$validation->setPromptTitle('选择' . $prompt);
|
|
$validation->setPrompt($prompt);
|
|
$validation->setShowErrorMessage(true);
|
|
$validation->setErrorTitle('选项无效');
|
|
$validation->setError($prompt);
|
|
$validation->setFormula1($formula);
|
|
$validation->setShowDropDown(true);
|
|
|
|
for ($row = 2; $row <= self::MAX_ROWS + 1; $row++) {
|
|
$sheet->getCell("{$column}{$row}")->setDataValidation(clone $validation);
|
|
}
|
|
}
|
|
|
|
private function accountTypes(): array
|
|
{
|
|
$connection = DB::connection((string) config('upstream_mirrors.connection', 'business_mirror'));
|
|
$base = $connection->table('fin_accounts')
|
|
->whereNotNull('account_type')->where('account_type', '<>', '')
|
|
->distinct()->pluck('account_type')->all();
|
|
$overrides = $connection->table('fin_account_type_overrides')
|
|
->whereNotNull('account_type')->where('account_type', '<>', '')
|
|
->distinct()->pluck('account_type')->all();
|
|
return FinanceLedgerAccountType::options($base, $overrides);
|
|
}
|
|
|
|
private function width(int $index): int
|
|
{
|
|
return match ($index) {
|
|
0, 6 => 30,
|
|
1, 5, 7, 24 => 22,
|
|
2, 3, 4, 8, 9, 18 => 13,
|
|
15, 16, 17 => 16,
|
|
default => 18,
|
|
};
|
|
}
|
|
}
|