| @@ -9,7 +9,7 @@ abstract class FromKintoneController extends WebController | |||
| public function __construct() | |||
| { | |||
| parent::__construct(); | |||
| $this->middleware('formKintone'); | |||
| $this->middleware('fromKintone'); | |||
| } | |||
| protected function makeResponse() | |||
| @@ -0,0 +1,39 @@ | |||
| <?php | |||
| namespace App\Http\Controllers\Web\Receipt; | |||
| use App\Http\Controllers\Web\FromKintoneController; | |||
| use App\Jobs\SeasonTicketContract\Selection\NoticeToCandidates; | |||
| use App\Logic\ReceiptManager; | |||
| use Illuminate\Http\JsonResponse; | |||
| use Illuminate\Http\Request; | |||
| class ReceiptCreateController extends FromKintoneController | |||
| { | |||
| public function name(): string | |||
| { | |||
| return "領収証作成"; | |||
| } | |||
| public function description(): string | |||
| { | |||
| return "領収証を作成する"; | |||
| } | |||
| public function __construct(protected ReceiptCreateParams $param) | |||
| { | |||
| parent::__construct(); | |||
| } | |||
| protected function run(Request $request): JsonResponse | |||
| { | |||
| $param = $this->param; | |||
| $manager = new ReceiptManager(); | |||
| $manager->create($param->recordNo); | |||
| return $this->successResponse(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,19 @@ | |||
| <?php | |||
| namespace App\Http\Controllers\Web\Receipt; | |||
| use App\Http\Controllers\Web\BaseParam; | |||
| /** | |||
| * @property int[] $recordNo | |||
| */ | |||
| class ReceiptCreateParams extends BaseParam | |||
| { | |||
| public function rules(): array | |||
| { | |||
| return [ | |||
| 'record_no' => $this->array(), | |||
| 'record_no.*' => $this->numeric(true), | |||
| ]; | |||
| } | |||
| } | |||
| @@ -64,6 +64,6 @@ class Kernel extends HttpKernel | |||
| 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, | |||
| 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, | |||
| 'formKintone' => \App\Http\Middleware\FromKintoneMiddleware::class, | |||
| 'fromKintone' => \App\Http\Middleware\FromKintoneMiddleware::class, | |||
| ]; | |||
| } | |||
| @@ -0,0 +1,13 @@ | |||
| <?php | |||
| namespace App\Kintone\Models\DropDown\PaymentPlan; | |||
| abstract class PaymentType | |||
| { | |||
| const SEASON_TICKET = "定期料金"; | |||
| const A保証金 = "保証金"; | |||
| const B証明証郵送代 = "証明証郵送代"; | |||
| const C事務手数料 = "事務手数料"; | |||
| const D延滞金 = "延滞金"; | |||
| const E余剰金 = "余剰金"; | |||
| } | |||
| @@ -2,14 +2,30 @@ | |||
| namespace App\Kintone\Models; | |||
| use Illuminate\Support\Carbon; | |||
| /** | |||
| * アプリ名 入金予定・結果 | |||
| * @property int SEASON_TICKET_CONTRACT_RECORD_NO | |||
| * @property string parkingName | |||
| * @property int parkingName | |||
| * @property int customerCode | |||
| * @property string paymentType | |||
| * @property string paymentMethod | |||
| * @property int targetYear | |||
| * @property int targetMonth | |||
| * @property int targetTermMonth | |||
| * @property Carbon appropriationDate | |||
| * @property int appropriationAmount | |||
| * @property int remainingAmount | |||
| */ | |||
| class PaymentPlan extends KintoneModel | |||
| { | |||
| const CONFIG_KEY = "KINTONE_APP_PAYMENT_PLAN"; | |||
| const FIELD_SEASON_TICKET_CONTRACT_RECORD_NO = "contract_record_number"; | |||
| const FIELD_PARKING_NAME = "parking_name"; | |||
| const FIELD_CUSTOMER_CODE = "customer_code"; | |||
| const FIELD_PAYMENT_TYPE = "payment_type"; | |||
| const FIELD_PAYMENT_METHOD = "payment_method"; | |||
| const FIELD_TARGET_YEAR = "target_year"; | |||
| @@ -24,16 +40,18 @@ class PaymentPlan extends KintoneModel | |||
| protected const FIELDS = [ | |||
| ...parent::FIELDS, | |||
| self::FIELD_SEASON_TICKET_CONTRACT_RECORD_NO => FieldType::NUMBER, | |||
| self::FIELD_PARKING_NAME => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_CUSTOMER_CODE => FieldType::NUMBER, | |||
| self::FIELD_PAYMENT_TYPE => FieldType::DROP_DOWN, | |||
| self::FIELD_PAYMENT_METHOD => FieldType::DROP_DOWN, | |||
| self::FIELD_TARGET_YEAR => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_TARGET_MONTH => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_TARGET_TERM_MONTH => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_TARGET_YEAR => FieldType::NUMBER, | |||
| self::FIELD_TARGET_MONTH => FieldType::NUMBER, | |||
| self::FIELD_TARGET_TERM_MONTH => FieldType::NUMBER, | |||
| self::FIELD_PAYMENT_PLAN_DATE => FieldType::DATE, | |||
| self::FIELD_PAYMENT_PLAN_AMOUNT => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_PAYMENT_PLAN_AMOUNT => FieldType::NUMBER, | |||
| self::FIELD_APPROPRIATION_DATE => FieldType::DATE, | |||
| self::FIELD_APPROPRIATION_AMOUNT => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_REMAINING_AMOUNT => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_APPROPRIATION_AMOUNT => FieldType::NUMBER, | |||
| self::FIELD_REMAINING_AMOUNT => FieldType::NUMBER, | |||
| ]; | |||
| protected const FIELD_NAMES = [ | |||
| @@ -43,20 +61,22 @@ class PaymentPlan extends KintoneModel | |||
| self::FIELD_PAYMENT_TYPE => 'payment_type', | |||
| self::FIELD_PAYMENT_METHOD => 'payment_method', | |||
| self::FIELD_PAYMENT_PLAN_DATE => 'payment_plan_date', | |||
| self::FIELD_TARGET_YEAR => 'target_year', | |||
| self::FIELD_TARGET_MONTH => 'target_month', | |||
| ]; | |||
| protected function toArrayCustom(): array | |||
| { | |||
| return [ | |||
| 'payment_status' => $this->donePayment ? "支払済み" : "未払い", | |||
| ]; | |||
| } | |||
| public function donePayment(): bool | |||
| { | |||
| $paymentDate = $this->getDate(self::FIELD_APPROPRIATION_DATE); | |||
| $remainingAmount = $this->getNumber(self::FIELD_REMAINING_AMOUNT); | |||
| $paymentStatus = "未払い"; | |||
| if (!!$paymentDate && $remainingAmount === 0) { | |||
| $paymentStatus = "支払済み"; | |||
| } | |||
| return [ | |||
| 'payment_status' => $paymentStatus, | |||
| ]; | |||
| return !!$paymentDate && $remainingAmount === 0; | |||
| } | |||
| } | |||
| @@ -2,50 +2,100 @@ | |||
| namespace App\Kintone\Models; | |||
| use App\Kintone\Models\SubTable\SeasonTicketContractReserve\TargetRoom; | |||
| use App\Kintone\Models\PaymentPlan as ModelsPaymentPlan; | |||
| use App\Kintone\Models\SubTable\Receipt\PaymentPlan; | |||
| use App\Kintone\Models\SubTable\Receipt\ReceiptDetail; | |||
| use App\Kintone\Models\SubTable\Receipt\TaxDetail; | |||
| use Illuminate\Support\Carbon; | |||
| use Illuminate\Support\Collection; | |||
| /** | |||
| * アプリ名 領収証 | |||
| * @property string receiptNo | |||
| * @property Carbon receiptDate | |||
| * @property string invoiceNo | |||
| * @property string receiptIssure | |||
| * @property string receiptName | |||
| * @property int customerCode | |||
| * @property string customerName | |||
| * @property string parkingName | |||
| * @property string taxType | |||
| * @property Collection<int, ReceiptDetail> receiptDetail | |||
| * @property Collection<int, TaxDetail> taxDetail | |||
| * @property string receiptCustomerName | |||
| * @property string receiptPurpose | |||
| * @property int receiptTotalAmount | |||
| * @property Collection<int, PaymentPlan> paymentPlans | |||
| */ | |||
| class Receipt extends KintoneModel | |||
| { | |||
| const CONFIG_KEY = "KINTONE_APP_RECEIPT"; | |||
| const FIELD_RECEIPT_NO = "領収証番号"; | |||
| const FIELD_RECEIPT_DATE = "発行日"; | |||
| const FIELD_INVOICE_NO = "インボイス登録番号"; | |||
| const FIELD_RECEIPT_ISSURE = "発行事業者名"; | |||
| const FIELD_RECEIPT_NAME = "領収証名称"; | |||
| const FIELD_CUSTOMER_CODE = "顧客コード"; | |||
| const FIELD_CUSTOMER_NAME = "顧客名"; | |||
| const FIELD_TAX_TYPE = "税区分"; | |||
| const FIELD_RECEIPT_DETAIL = "テーブル_明細"; | |||
| const FIELD_RECEIPT_DETAIL_NAME = "明細_名称"; | |||
| const FIELD_RECEIPT_DETAIL_PARKING_NAME = "明細_駐車場名"; | |||
| const FIELD_RECEIPT_DETAIL_TARGET_MONTH = "明細_対象月"; | |||
| const FIELD_RECEIPT_DETAIL_MEMO = "明細_備考"; | |||
| const FIELD_RECEIPT_DETAIL_UNIT_PRICE = "明細_単価"; | |||
| const FIELD_RECEIPT_DETAIL_QUANTITY = "明細_数量"; | |||
| const FIELD_RECEIPT_DETAIL_AMOUNT = "明細_金額"; | |||
| const FIELD_RECEIPT_DETAIL_TAX_RATE = "明細_税率"; | |||
| const FIELD_TAX_DETAIL = "テーブル_内税明細"; | |||
| const FIELD_TAX_DETAIL_TAX_RATE = "内税明細_税率"; | |||
| const FIELD_TAX_DETAIL_TOTAL_AMOUNT = "内税明細_税込金額合計"; | |||
| const FIELD_TAX_DETAIL_TAX_AMOUNT = "内税明細_消費税_内税"; | |||
| const FIELD_RECEIPT_CUSTOMER_NAME = "宛名"; | |||
| const FIELD_RECEIPT_PURPOSE = "但し書き"; | |||
| const FIELD_RECEIPT_TOTAL_AMOUNT = "合計"; | |||
| const FIELD_PAYMENT_PLANS = "テーブル_入金実績"; | |||
| const FIELD_PAYMENT_PLANS_RECORD_NO = "入金実績_入金予定レコード番号"; | |||
| const FIELD_PAYMENT_PLANS_PAYMENT_PURPOSE = "入金実績_支払種別"; | |||
| const FIELD_PAYMENT_PLANS_DATE = "入金実績_入金日"; | |||
| const FIELD_PAYMENT_PLANS_AMOUNT = "入金実績_入金額"; | |||
| const FIELD_PAYMENT_PLANS_TARGET_YEAR = "入金実績支払対象_利用_年"; | |||
| const FIELD_PAYMENT_PLANS_TARGET_MONTH = "入金実績支払対象_利用_月"; | |||
| const FIELD_RECEIPT_PDF_FILE = "領収証PDF"; | |||
| protected const FIELDS = [ | |||
| ...parent::FIELDS, | |||
| self::FIELD_RECEIPT_NO => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_RECEIPT_DATE => FieldType::DATE, | |||
| self::FIELD_INVOICE_NO => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_RECEIPT_ISSURE => FieldType::MULTI_LINE_TEXT, | |||
| self::FIELD_RECEIPT_NAME => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_CUSTOMER_CODE => FieldType::NUMBER, | |||
| self::FIELD_CUSTOMER_NAME => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_TAX_TYPE => FieldType::DROP_DOWN, | |||
| self::FIELD_RECEIPT_DETAIL => FieldType::SUBTABLE, | |||
| self::FIELD_TAX_DETAIL => FieldType::SUBTABLE, | |||
| self::FIELD_RECEIPT_CUSTOMER_NAME => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_RECEIPT_PURPOSE => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_RECEIPT_TOTAL_AMOUNT => FieldType::NUMBER, | |||
| self::FIELD_RECEIPT_PDF_FILE => FieldType::FILE, | |||
| self::FIELD_PAYMENT_PLANS => FieldType::SUBTABLE, | |||
| ]; | |||
| protected const FIELD_NAMES = [ | |||
| ...parent::FIELD_NAMES, | |||
| ]; | |||
| protected const SUB_TABLES = [ | |||
| self::FIELD_RECEIPT_DETAIL => ReceiptDetail::class, | |||
| self::FIELD_TAX_DETAIL => TaxDetail::class, | |||
| self::FIELD_PAYMENT_PLANS => PaymentPlan::class, | |||
| ]; | |||
| protected const RELATIONS = [ | |||
| Customer::class, | |||
| PaymentPlan::class, | |||
| ModelsPaymentPlan::class, | |||
| ]; | |||
| } | |||
| @@ -0,0 +1,37 @@ | |||
| <?php | |||
| namespace App\Kintone\Models\SubTable\Receipt; | |||
| use App\Kintone\Models\Receipt; | |||
| use App\Kintone\Models\SubTable\SubTableData; | |||
| use App\Util\DateUtil; | |||
| use Illuminate\Support\Carbon; | |||
| class PaymentPlan extends SubTableData | |||
| { | |||
| public int $recordNo; | |||
| public string $paymentPurpose; | |||
| public ?Carbon $date; | |||
| public int $amount; | |||
| public int $targetYear; | |||
| public int $targetMonth; | |||
| public function __construct(array $data = []) | |||
| { | |||
| $this->recordNo = intval(data_get($data, Receipt::FIELD_PAYMENT_PLANS_RECORD_NO, 0)); | |||
| $this->paymentPurpose = data_get($data, Receipt::FIELD_PAYMENT_PLANS_PAYMENT_PURPOSE, ""); | |||
| $this->date = DateUtil::parse(data_get($data, Receipt::FIELD_PAYMENT_PLANS_DATE, null)); | |||
| $this->amount = intval(data_get($data, Receipt::FIELD_PAYMENT_PLANS_AMOUNT, 0)); | |||
| $this->targetYear = intval(data_get($data, Receipt::FIELD_PAYMENT_PLANS_TARGET_YEAR, 0)); | |||
| $this->targetMonth = intval(data_get($data, Receipt::FIELD_PAYMENT_PLANS_TARGET_MONTH, 0)); | |||
| parent::__construct($data); | |||
| } | |||
| public function toArray(): array | |||
| { | |||
| return [ | |||
| Receipt::FIELD_PAYMENT_PLANS_RECORD_NO => $this->recordNo, | |||
| ]; | |||
| } | |||
| } | |||
| @@ -0,0 +1,48 @@ | |||
| <?php | |||
| namespace App\Kintone\Models\SubTable\Receipt; | |||
| use App\Kintone\Models\Receipt; | |||
| use App\Kintone\Models\SubTable\SubTableData; | |||
| class ReceiptDetail extends SubTableData | |||
| { | |||
| public string $name = ""; | |||
| public string $parkingName = ""; | |||
| public string $targetMonth = ""; | |||
| public string $memo = ""; | |||
| public int $unitPrice = 0; | |||
| public int $quantity = 0; | |||
| public int $amount = 0; | |||
| public int $taxRate = 0; | |||
| public function __construct(array $data = []) | |||
| { | |||
| $this->name = data_get($data, Receipt::FIELD_RECEIPT_DETAIL_NAME, ""); | |||
| $this->parkingName = data_get($data, Receipt::FIELD_RECEIPT_DETAIL_PARKING_NAME, ""); | |||
| $this->targetMonth = data_get($data, Receipt::FIELD_RECEIPT_DETAIL_TARGET_MONTH, ""); | |||
| $this->memo = data_get($data, Receipt::FIELD_RECEIPT_DETAIL_MEMO, ""); | |||
| $this->unitPrice = intval(data_get($data, Receipt::FIELD_RECEIPT_DETAIL_UNIT_PRICE, 0)); | |||
| $this->quantity = intval(data_get($data, Receipt::FIELD_RECEIPT_DETAIL_QUANTITY, 0)); | |||
| $this->amount = intval(data_get($data, Receipt::FIELD_RECEIPT_DETAIL_AMOUNT, 0)); | |||
| $this->taxRate = intval(data_get($data, Receipt::FIELD_RECEIPT_DETAIL_TAX_RATE, 0)); | |||
| parent::__construct($data); | |||
| } | |||
| public function toArray(): array | |||
| { | |||
| return [ | |||
| Receipt::FIELD_RECEIPT_DETAIL_NAME => $this->name, | |||
| Receipt::FIELD_RECEIPT_DETAIL_PARKING_NAME => $this->parkingName, | |||
| Receipt::FIELD_RECEIPT_DETAIL_TARGET_MONTH => $this->targetMonth, | |||
| Receipt::FIELD_RECEIPT_DETAIL_MEMO => $this->memo, | |||
| Receipt::FIELD_RECEIPT_DETAIL_UNIT_PRICE => $this->unitPrice, | |||
| Receipt::FIELD_RECEIPT_DETAIL_QUANTITY => $this->quantity, | |||
| Receipt::FIELD_RECEIPT_DETAIL_AMOUNT => $this->amount, | |||
| Receipt::FIELD_RECEIPT_DETAIL_TAX_RATE => $this->taxRate, | |||
| ]; | |||
| } | |||
| } | |||
| @@ -0,0 +1,33 @@ | |||
| <?php | |||
| namespace App\Kintone\Models\SubTable\Receipt; | |||
| use App\Kintone\Models\Receipt; | |||
| use App\Kintone\Models\SubTable\SubTableData; | |||
| class TaxDetail extends SubTableData | |||
| { | |||
| public int $taxRate = 0; | |||
| public int $totalAmount = 0; | |||
| public int $taxAmount = 0; | |||
| public function __construct(array $data = []) | |||
| { | |||
| $this->taxRate = intval(data_get($data, Receipt::FIELD_TAX_DETAIL_TAX_RATE, 0)); | |||
| $this->totalAmount = intval(data_get($data, Receipt::FIELD_TAX_DETAIL_TOTAL_AMOUNT, 0)); | |||
| $this->taxAmount = intval(data_get($data, Receipt::FIELD_TAX_DETAIL_TAX_AMOUNT, 0)); | |||
| parent::__construct($data); | |||
| } | |||
| public function toArray(): array | |||
| { | |||
| return [ | |||
| Receipt::FIELD_TAX_DETAIL_TAX_RATE => $this->taxRate, | |||
| Receipt::FIELD_TAX_DETAIL_TOTAL_AMOUNT => $this->totalAmount, | |||
| Receipt::FIELD_TAX_DETAIL_TAX_AMOUNT => $this->taxAmount, | |||
| ]; | |||
| } | |||
| } | |||
| @@ -2,8 +2,19 @@ | |||
| namespace App\Logic; | |||
| use App\Exceptions\AppCommonException; | |||
| use App\Exceptions\GeneralErrorMessageException; | |||
| use App\Files\PDF\Receipt as ReceiptReceipt; | |||
| use App\Kintone\Models\Customer; | |||
| use App\Kintone\Models\DropDown\PaymentPlan\PaymentType; | |||
| use App\Kintone\Models\PaymentPlan; | |||
| use App\Kintone\Models\Receipt; | |||
| use App\Kintone\Models\SubTable\Receipt\PaymentPlan as ReceiptPaymentPlan; | |||
| use App\Kintone\Models\SubTable\Receipt\ReceiptDetail; | |||
| use App\Kintone\Models\SubTable\Receipt\TaxDetail; | |||
| use App\Util\DateUtil; | |||
| use App\Util\TaxUtil; | |||
| use Illuminate\Support\Collection; | |||
| use PDF; | |||
| class ReceiptManager | |||
| @@ -19,16 +30,154 @@ class ReceiptManager | |||
| } | |||
| } | |||
| private function load(int $recordNo) | |||
| public function getReceipt(): Receipt | |||
| { | |||
| $this->receipt = Receipt::find($recordNo); | |||
| return $this->receipt; | |||
| } | |||
| public function getReceipt(): Receipt | |||
| public function create(array $paymentPlanRecordNoList) | |||
| { | |||
| return $this->receipt; | |||
| // 支払予定データの取得 | |||
| $payments = $this->getPayments($paymentPlanRecordNoList); | |||
| $this->checkPayments($payments, count($paymentPlanRecordNoList)); | |||
| // 顧客取得 | |||
| $customer = Customer::findByCustomerCode($payments->first()->customerCode); | |||
| $receipt = $this->receipt; | |||
| $receipt->receiptNo = $this->getReceiptNo(); | |||
| $receipt->receiptDate = DateUtil::now(); | |||
| $receipt->invoiceNo = config("business.invoiceNo", ""); | |||
| $receipt->receiptName = $this->getReceiptName($payments); | |||
| $receipt->customerCode = $customer->customerCode; | |||
| $receipt->taxType = "内税"; | |||
| $receipt->receiptCustomerName = $customer->customerName; | |||
| $receipt->receiptTotalAmount = 0; | |||
| // 明細------------ | |||
| foreach ($payments as $payment) { | |||
| $detail = new ReceiptDetail(); | |||
| $detail->name = $payment->paymentType; | |||
| $detail->parkingName = $payment->parkingName; | |||
| $detail->unitPrice = $payment->appropriationAmount; | |||
| $detail->quantity = 1; | |||
| $detail->amount = $detail->unitPrice * $detail->quantity; | |||
| $detail->targetMonth = $payment->targetMonth ? sprintf("%d月分", $payment->targetMonth) : ""; | |||
| $detail->taxRate = config("business.taxRate.normal", 0); | |||
| $detail->memo = "memo"; | |||
| $receipt->receiptDetail->push($detail); | |||
| $receipt->receiptTotalAmount += $payment->appropriationAmount; | |||
| } | |||
| // 内税明細-------------- | |||
| foreach ($receipt->receiptDetail as $detail) { | |||
| $tax = $receipt->taxDetail->first(function (TaxDetail $ele) use ($detail) { | |||
| return $ele->taxRate === $detail->taxRate; | |||
| }); | |||
| if ($tax === null) { | |||
| $tax = new TaxDetail(); | |||
| $tax->taxRate = $detail->taxRate; | |||
| $receipt->taxDetail->push($tax); | |||
| } | |||
| if ($tax instanceof TaxDetail) { | |||
| $tax->totalAmount += $detail->amount; | |||
| } | |||
| } | |||
| // 税率の昇順に並び替え | |||
| $receipt->taxDetail->sort(function (TaxDetail $a, TaxDetail $b) { | |||
| return $a->taxRate < $b->taxRate ? -1 : 1; | |||
| }); | |||
| // 内税計算 | |||
| foreach ($receipt->taxDetail as $detail) { | |||
| $detail->taxAmount = TaxUtil::calcInnerTaxAmount($detail->totalAmount, $detail->taxRate); | |||
| } | |||
| // 入金実績--------------- | |||
| foreach ($payments as $payment) { | |||
| $detail = new ReceiptPaymentPlan(); | |||
| $detail->recordNo = $payment->getRecordId(); | |||
| $receipt->paymentPlans->push($detail); | |||
| } | |||
| $receipt->save(); | |||
| return $this; | |||
| } | |||
| private function getPayments(array $paymentPlanRecordNoList) | |||
| { | |||
| $query = PaymentPlan::getQuery()->whereIn(PaymentPlan::FIELD_RECORD_NO, $paymentPlanRecordNoList); | |||
| $ret = PaymentPlan::getAccess()->all($query); | |||
| return $ret; | |||
| } | |||
| /** | |||
| * @param Collection<int, PaymentPlan> $payments | |||
| * @return void | |||
| */ | |||
| private function checkPayments(Collection $payments, int $expectCount) | |||
| { | |||
| // データチェック | |||
| if ($payments->isEmpty()) { | |||
| throw new AppCommonException("支払予定検索0件"); | |||
| } | |||
| if ($payments->count() !== $expectCount) { | |||
| throw new AppCommonException(sprintf("件数不正 %d件 期待値:%d件 ", $payments->count(), $expectCount)); | |||
| } | |||
| $customerCode = $payments->first()->customerCode; | |||
| foreach ($payments as $payment) { | |||
| if (!$payment->donePayment()) { | |||
| throw new AppCommonException(sprintf("支払済みでない支払 %d ", $payment->getRecordId())); | |||
| } | |||
| if ($payment->customerCode !== $customerCode) { | |||
| throw new AppCommonException(sprintf("単一の顧客コードのみ設定可能 %d or %d", $customerCode, $payment->customerCode)); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * @param Collection<int, PaymentPlan> $payments | |||
| * @return void | |||
| */ | |||
| private function getReceiptName(Collection $payments): string | |||
| { | |||
| $seasonTicketCount = 0; | |||
| $otherCount = 0; | |||
| $otherName = ""; | |||
| foreach ($payments as $payment) { | |||
| if ($payment->paymentType === PaymentType::SEASON_TICKET) { | |||
| $seasonTicketCount++; | |||
| } else { | |||
| $otherCount++; | |||
| $otherName = $payment->paymentType; | |||
| } | |||
| } | |||
| if (0 < $seasonTicketCount && $otherCount === 0) { | |||
| return "定期料金"; | |||
| } | |||
| if (0 < $seasonTicketCount && 0 < $otherCount) { | |||
| return "定期料金ほか"; | |||
| } | |||
| return $otherName; | |||
| } | |||
| private function load(int $recordNo) | |||
| { | |||
| $this->receipt = Receipt::find($recordNo); | |||
| } | |||
| public function makePdf(): ReceiptReceipt | |||
| { | |||
| $pdf = PDF::loadView("pdf/receipt", $this->getPdfData()) | |||
| @@ -67,4 +216,22 @@ class ReceiptManager | |||
| 'receiptPurpose' => $this->receipt->receiptPurpose, | |||
| ]; | |||
| } | |||
| private function getReceiptNo(): string | |||
| { | |||
| /** | |||
| * 申請番号を発番する。重複チェックを一定回数行う。 | |||
| */ | |||
| for ($i = 0; $i < 10; $i++) { | |||
| $no = sprintf("%s-R%06d", DateUtil::now()->format('Ymd'), rand(1, 999999)); | |||
| $check = Receipt::getAccess()->some(Receipt::getQuery()->where(Receipt::FIELD_RECEIPT_NO, $no)); | |||
| if ($check->isEmpty()) { | |||
| return $no; | |||
| } | |||
| } | |||
| throw new AppCommonException('申請番号取得失敗'); | |||
| } | |||
| } | |||
| @@ -0,0 +1,13 @@ | |||
| <?php | |||
| namespace App\Util; | |||
| class TaxUtil | |||
| { | |||
| public static function calcInnerTaxAmount(int $amount, int $rate): int | |||
| { | |||
| $taxRate = $rate / 100; | |||
| return intval(floor($amount / (1 + $taxRate) * $taxRate)); | |||
| } | |||
| } | |||
| @@ -0,0 +1,32 @@ | |||
| <?php | |||
| use App\Kintone\KintoneConfiguration; | |||
| return [ | |||
| /* | |||
| |-------------------------------------------------------------------------- | |||
| | 税率 | |||
| |-------------------------------------------------------------------------- | |||
| | | |||
| | | |||
| */ | |||
| 'taxRate' => [ | |||
| 'normal' => 10, | |||
| 'reduce' => 8, | |||
| ], | |||
| /* | |||
| |-------------------------------------------------------------------------- | |||
| | インボイス番号 | |||
| |-------------------------------------------------------------------------- | |||
| | | |||
| | | |||
| */ | |||
| 'invoiceNo' => 'T7130005012806', | |||
| ]; | |||
| @@ -15,6 +15,7 @@ use App\Util\RouteHelper; | |||
| RouteHelper::post('/email/send', App\Http\Controllers\Web\Email\EmailSendController::class); | |||
| RouteHelper::post('/season-ticket-contract-selection/notice-to-candidates', App\Http\Controllers\Web\SeasonTicketContract\Selection\NoticeToCandidatesController::class); | |||
| RouteHelper::post('/receipt/create', App\Http\Controllers\Web\Receipt\ReceiptCreateController::class); | |||
| // ------FOR WEBHOOK------------------- | |||