167 lines
6.9 KiB
PHP
167 lines
6.9 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 Illuminate\Validation\ValidationException;
|
|
|
|
/**
|
|
* 在账户总表中新增一个财务台账账户,并在公司不存在时同步建立公司台账。
|
|
*/
|
|
class FinanceLedgerAccountCreator
|
|
{
|
|
public function create(array $data): array
|
|
{
|
|
$connection = DB::connection((string) config('upstream_mirrors.connection', 'business_mirror'));
|
|
$companyName = $this->text($data['company_name'] ?? '');
|
|
$accountShort = $this->text($data['account_short'] ?? '');
|
|
$accountNo = $this->text($data['account_no'] ?? '');
|
|
$accountType = $this->text($data['account_type'] ?? '');
|
|
$companyPlan = $this->text($data['company_plan'] ?? '');
|
|
$companyFields = [
|
|
'register_place' => $this->nullableText($data['company_register_place'] ?? null),
|
|
'business_type' => $this->nullableText($data['company_business_type'] ?? null),
|
|
'tax_type' => $this->nullableText($data['company_tax_type'] ?? null),
|
|
'status' => $this->nullableText($data['company_status'] ?? null),
|
|
'basic_bank' => $this->nullableText($data['company_basic_bank'] ?? null),
|
|
'basic_account_last4' => $this->nullableText($data['company_basic_account_last4'] ?? null),
|
|
'remark' => $this->nullableText($data['company_remark'] ?? null),
|
|
];
|
|
$openingDate = (string) ($data['opening_date'] ?? now()->toDateString());
|
|
$openingBalance = round((float) ($data['opening_balance'] ?? 0), 2);
|
|
$status = FinanceLedgerAccountStatus::normalize((string) ($data['status'] ?? ''));
|
|
$accountShouldKeep = FinanceLedgerAccountShouldKeep::normalize(
|
|
(string) ($data['account_should_keep'] ?? ''),
|
|
);
|
|
$accountLast4 = FinanceLedgerAccountType::last4($accountType, $accountNo);
|
|
$normal = $status === FinanceLedgerAccountStatus::NORMAL;
|
|
$now = now();
|
|
|
|
return $connection->transaction(function () use (
|
|
$connection,
|
|
$companyName,
|
|
$accountShort,
|
|
$accountNo,
|
|
$accountType,
|
|
$companyPlan,
|
|
$companyFields,
|
|
$openingDate,
|
|
$openingBalance,
|
|
$status,
|
|
$accountShouldKeep,
|
|
$accountLast4,
|
|
$normal,
|
|
$data,
|
|
$now,
|
|
): array {
|
|
if ($connection->table('fin_accounts')->where('account_short', $accountShort)->exists()) {
|
|
throw ValidationException::withMessages([
|
|
'account_short' => '账户简称已存在,请改用其他简称或直接编辑现有账户。',
|
|
]);
|
|
}
|
|
|
|
$company = $connection->table('fin_companies')->where('name', $companyName)->first(['id']);
|
|
$companyCreated = $company === null;
|
|
$companyUpdated = false;
|
|
if ($companyCreated) {
|
|
$connection->table('fin_companies')->insert([
|
|
'name' => $companyName,
|
|
...$companyFields,
|
|
'created_at' => $now,
|
|
'updated_at' => $now,
|
|
]);
|
|
} else {
|
|
$providedCompanyFields = array_filter(
|
|
$companyFields,
|
|
static fn (?string $value): bool => $value !== null,
|
|
);
|
|
if ($providedCompanyFields !== []) {
|
|
$connection->table('fin_companies')
|
|
->where('id', $company->id)
|
|
->update([
|
|
...$providedCompanyFields,
|
|
'updated_at' => $now,
|
|
]);
|
|
$companyUpdated = true;
|
|
}
|
|
}
|
|
|
|
$accountId = $connection->table('fin_accounts')->insertGetId([
|
|
'company_name' => $companyName,
|
|
'account_short' => $accountShort,
|
|
'region' => $this->nullableText($data['region'] ?? null),
|
|
'account_no' => $accountNo !== '' ? $accountNo : null,
|
|
'bank_name' => $this->nullableText($data['bank_name'] ?? null),
|
|
'bank_city_branch' => $this->nullableText($data['bank_city_branch'] ?? null),
|
|
'account_type' => $accountType !== '' ? $accountType : null,
|
|
'company_plan' => $companyPlan !== '' ? $companyPlan : null,
|
|
'account_should_keep' => $accountShouldKeep !== '' ? $accountShouldKeep : null,
|
|
'account_last4' => $accountLast4,
|
|
'current_balance' => $openingBalance,
|
|
'blocked_amount' => $normal ? 0 : $openingBalance,
|
|
'daily_available' => $normal ? $openingBalance : 0,
|
|
'created_at' => $now,
|
|
'updated_at' => $now,
|
|
]);
|
|
|
|
$connection->table('fin_account_opening')->insert([
|
|
'account_short' => $accountShort,
|
|
'opening_date' => $openingDate,
|
|
'opening_balance' => $openingBalance,
|
|
'remark' => '新增账户期初',
|
|
'created_at' => $now,
|
|
'updated_at' => $now,
|
|
]);
|
|
|
|
$connection->table('fin_daily_flows')->insert([
|
|
'flow_date' => $openingDate,
|
|
'company_name' => $companyName,
|
|
'account_short' => $accountShort,
|
|
'opening_balance' => $openingBalance,
|
|
'inflow' => 0,
|
|
'outflow' => 0,
|
|
'closing_balance' => $openingBalance,
|
|
'remark' => '新增账户期初',
|
|
'created_at' => $now,
|
|
'updated_at' => $now,
|
|
]);
|
|
|
|
if (! $normal) {
|
|
$connection->table('fin_account_statuses')->insert([
|
|
'account_short' => $accountShort,
|
|
'status' => $status,
|
|
'updated_by' => (string) user()->name,
|
|
'created_at' => $now,
|
|
'updated_at' => $now,
|
|
]);
|
|
}
|
|
|
|
return [
|
|
'id' => (int) $accountId,
|
|
'company_name' => $companyName,
|
|
'account_short' => $accountShort,
|
|
'company_created' => $companyCreated,
|
|
'company_updated' => $companyUpdated,
|
|
'status' => $status,
|
|
'opening_date' => $openingDate,
|
|
'opening_balance' => $openingBalance,
|
|
];
|
|
});
|
|
}
|
|
|
|
private function text(mixed $value): string
|
|
{
|
|
return preg_replace('/\s+/u', ' ', trim((string) $value)) ?? trim((string) $value);
|
|
}
|
|
|
|
private function nullableText(mixed $value): ?string
|
|
{
|
|
$text = $this->text($value);
|
|
|
|
return $text !== '' ? $text : null;
|
|
}
|
|
}
|