[ 'nullable', 'string', 'max:50', Rule::unique('bills', 'bill_number')->where(function ($query) use ($tenantId) { return $query->where('tenant_id', $tenantId); }), ], 'bill_type' => ['required', 'string', 'in:received,issued'], 'client_id' => ['nullable', 'integer', 'exists:clients,id'], 'client_name' => ['nullable', 'string', 'max:100'], 'amount' => ['required', 'numeric', 'min:0'], 'issue_date' => ['required', 'date'], 'maturity_date' => ['nullable', 'date', 'after_or_equal:issue_date'], 'status' => ['nullable', 'string', 'max:30'], 'reason' => ['nullable', 'string', 'max:255'], 'installment_count' => ['nullable', 'integer', 'min:0'], 'note' => ['nullable', 'string', 'max:1000'], 'is_electronic' => ['nullable', 'boolean'], 'bank_account_id' => ['nullable', 'integer', 'exists:bank_accounts,id'], // === V8 증권종류/매체/구분 === 'instrument_type' => ['nullable', 'string', 'in:promissory,exchange,cashierCheck,currentCheck'], 'medium' => ['nullable', 'string', 'in:electronic,paper'], 'bill_category' => ['nullable', 'string', 'in:commercial,other'], // === 전자어음 === 'electronic_bill_no' => ['nullable', 'string', 'max:100'], 'registration_org' => ['nullable', 'string', 'in:kftc,bank'], // === 환어음 === 'drawee' => ['nullable', 'string', 'max:100'], 'acceptance_status' => ['nullable', 'string', 'in:accepted,pending,refused'], 'acceptance_date' => ['nullable', 'date'], 'acceptance_refusal_date' => ['nullable', 'date'], 'acceptance_refusal_reason' => ['nullable', 'string', 'max:50'], // === 받을어음 전용 === 'endorsement' => ['nullable', 'string', 'in:endorsable,nonEndorsable'], 'endorsement_order' => ['nullable', 'string', 'max:5'], 'storage_place' => ['nullable', 'string', 'in:safe,bank,other'], 'issuer_bank' => ['nullable', 'string', 'max:100'], // 할인 'is_discounted' => ['nullable', 'boolean'], 'discount_date' => ['nullable', 'date'], 'discount_bank' => ['nullable', 'string', 'max:100'], 'discount_rate' => ['nullable', 'numeric', 'min:0', 'max:100'], 'discount_amount' => ['nullable', 'numeric', 'min:0'], // 배서양도 'endorsement_date' => ['nullable', 'date'], 'endorsee' => ['nullable', 'string', 'max:100'], 'endorsement_reason' => ['nullable', 'string', 'in:payment,guarantee,collection,other'], // 추심 'collection_bank' => ['nullable', 'string', 'max:100'], 'collection_request_date' => ['nullable', 'date'], 'collection_fee' => ['nullable', 'numeric', 'min:0'], 'collection_complete_date' => ['nullable', 'date'], 'collection_result' => ['nullable', 'string', 'in:success,partial,failed,pending'], 'collection_deposit_date' => ['nullable', 'date'], 'collection_deposit_amount' => ['nullable', 'numeric', 'min:0'], // === 지급어음 전용 === 'settlement_bank' => ['nullable', 'string', 'max:100'], 'payment_method' => ['nullable', 'string', 'in:autoTransfer,currentAccount,other'], 'actual_payment_date' => ['nullable', 'date'], // === 공통 === 'payment_place' => ['nullable', 'string', 'max:30'], 'payment_place_detail' => ['nullable', 'string', 'max:200'], // 개서 'renewal_date' => ['nullable', 'date'], 'renewal_new_bill_no' => ['nullable', 'string', 'max:50'], 'renewal_reason' => ['nullable', 'string', 'in:maturityExtension,amountChange,conditionChange,other'], // 소구 'recourse_date' => ['nullable', 'date'], 'recourse_amount' => ['nullable', 'numeric', 'min:0'], 'recourse_target' => ['nullable', 'string', 'max:100'], 'recourse_reason' => ['nullable', 'string', 'in:endorsedDishonor,discountDishonor,other'], // 환매 'buyback_date' => ['nullable', 'date'], 'buyback_amount' => ['nullable', 'numeric', 'min:0'], 'buyback_bank' => ['nullable', 'string', 'max:100'], // 부도/법적절차 'dishonored_date' => ['nullable', 'date'], 'dishonored_reason' => ['nullable', 'string', 'max:30'], 'has_protest' => ['nullable', 'boolean'], 'protest_date' => ['nullable', 'date'], 'recourse_notice_date' => ['nullable', 'date'], 'recourse_notice_deadline' => ['nullable', 'date'], // 분할배서 'is_split' => ['nullable', 'boolean'], // === 차수 관리 === 'installments' => ['nullable', 'array'], 'installments.*.date' => ['required_with:installments', 'date'], 'installments.*.amount' => ['required_with:installments', 'numeric', 'min:0'], 'installments.*.type' => ['nullable', 'string', 'max:30'], 'installments.*.counterparty' => ['nullable', 'string', 'max:100'], 'installments.*.note' => ['nullable', 'string', 'max:255'], ]; } public function messages(): array { return [ 'bill_number.unique' => __('error.bill.duplicate_number'), 'bill_type.required' => __('validation.required', ['attribute' => __('validation.attributes.bill_type')]), 'bill_type.in' => __('validation.in', ['attribute' => __('validation.attributes.bill_type')]), 'amount.required' => __('validation.required', ['attribute' => __('validation.attributes.amount')]), 'amount.min' => __('validation.min.numeric', ['attribute' => __('validation.attributes.amount'), 'min' => 0]), 'issue_date.required' => __('validation.required', ['attribute' => __('validation.attributes.issue_date')]), 'maturity_date.required' => __('validation.required', ['attribute' => __('validation.attributes.maturity_date')]), 'maturity_date.after_or_equal' => __('validation.after_or_equal', ['attribute' => __('validation.attributes.maturity_date'), 'date' => __('validation.attributes.issue_date')]), ]; } public function attributes(): array { return [ 'bill_number' => __('validation.attributes.bill_number'), 'bill_type' => __('validation.attributes.bill_type'), 'client_id' => __('validation.attributes.client_id'), 'client_name' => __('validation.attributes.client_name'), 'amount' => __('validation.attributes.amount'), 'issue_date' => __('validation.attributes.issue_date'), 'maturity_date' => __('validation.attributes.maturity_date'), 'status' => __('validation.attributes.status'), 'reason' => __('validation.attributes.reason'), 'note' => __('validation.attributes.note'), 'is_electronic' => __('validation.attributes.is_electronic'), 'bank_account_id' => __('validation.attributes.bank_account_id'), ]; } }