| @@ -29,8 +29,12 @@ class CsvFile extends TmpFile | |||
| } | |||
| } | |||
| public function addLine(array|Collection $row) | |||
| public function addLine(array|Collection $row, array|null $sortDef = null) | |||
| { | |||
| if ($sortDef !== null) { | |||
| $row = $this->sortColumn($sortDef, $row); | |||
| } | |||
| $str = ""; | |||
| foreach ($row as $col => $val) { | |||
| if ($str !== "") { | |||
| @@ -51,4 +55,18 @@ class CsvFile extends TmpFile | |||
| { | |||
| return mb_convert_encoding($source, "SJIS", "UTF8"); | |||
| } | |||
| private function sortColumn(array $sortDef, $data): array | |||
| { | |||
| $ele = []; | |||
| $notFound = Str::uuid(); | |||
| foreach ($sortDef as $def) { | |||
| $ret = data_get($data, $def, $notFound); | |||
| if ($ret === $notFound) { | |||
| throw new LogicException("存在しない項目:" . $def); | |||
| } | |||
| $ele[] = $ret; | |||
| } | |||
| return $ele; | |||
| } | |||
| } | |||
| @@ -4,10 +4,11 @@ namespace App\Http\Controllers\Web\Custom\HelloTechno; | |||
| use App\Http\Controllers\Web\BaseParam; | |||
| use App\Repositories\Custom\HelloTechno\UseSummaryRepository as Repository; | |||
| use Illuminate\Support\Carbon; | |||
| /** | |||
| * @property ?string $id | |||
| * @property ?string $summaryYyyymm | |||
| * @property Carbon $dateFrom | |||
| * @property Carbon $dateTo | |||
| */ | |||
| class UseSummariesParam extends BaseParam | |||
| @@ -17,8 +18,8 @@ class UseSummariesParam extends BaseParam | |||
| return | |||
| array_merge( | |||
| [ | |||
| Repository::CONDITION_ID => $this->str(true), | |||
| Repository::CONDITION_SUMMARY_YYYYMM => $this->str(), | |||
| Repository::CONDITION_ORDER_DATE_FROM => $this->date(), | |||
| Repository::CONDITION_ORDER_DATE_TO => $this->date(), | |||
| ], | |||
| $this->sortableRules(), | |||
| ); | |||
| @@ -6,9 +6,10 @@ use App\Codes\UserRole; | |||
| use App\Features\LoginUser; | |||
| use App\Files\CsvFile; | |||
| use App\Http\Controllers\Web\IParam; | |||
| use App\Repositories\Custom\HelloTechno\UseSummaryRepository as Repository; | |||
| use App\Repositories\Custom\HelloTechno\ReceiptIssuingOrderRepository; | |||
| use App\Repositories\Custom\HelloTechno\ReceiptIssuingOrderRepositoryData as RDATA; | |||
| use App\Repositories\Custom\HelloTechno\UseSummaryRepository; | |||
| use Illuminate\Http\Request; | |||
| use Illuminate\Support\Facades\Auth; | |||
| use Symfony\Component\HttpFoundation\BinaryFileResponse; | |||
| class UseSummaryCSVController extends HelloTechnoController | |||
| @@ -28,7 +29,8 @@ class UseSummaryCSVController extends HelloTechnoController | |||
| public function __construct( | |||
| protected UseSummaryCSVParam $param, | |||
| private Repository $repository | |||
| private ReceiptIssuingOrderRepository $receiptIssuingOrderRepository, | |||
| private UseSummaryRepository $useSummaryRepository, | |||
| ) { | |||
| parent::__construct(); | |||
| $this->roleAllow(UserRole::NORMAL_ADMIN); | |||
| @@ -43,36 +45,82 @@ class UseSummaryCSVController extends HelloTechnoController | |||
| { | |||
| $param = $this->param; | |||
| // データ取得 | |||
| $condition = [ | |||
| ...$param->toArray(), | |||
| Repository::CONDITION_CONTRACT_ID => $this->loginUser()->getCurrentContractId(), | |||
| Repository::CONDITION_SORT_TARGET => 'customer_code', | |||
| UseSummaryRepository::CONDITION_CONTRACT_ID => $this->loginUser()->getCurrentContractId(), | |||
| UseSummaryRepository::CONDITION_SORT_TARGET => 'customer_code', | |||
| ReceiptIssuingOrderRepository::CONDITION_ORDER_DATE_FROM => $param->dateFrom, | |||
| ReceiptIssuingOrderRepository::CONDITION_ORDER_DATE_TO => $param->dateTo, | |||
| UseSummaryRepository::CONDITION_ORDER_DATE_FROM => $param->dateFrom, | |||
| UseSummaryRepository::CONDITION_ORDER_DATE_TO => $param->dateTo, | |||
| ]; | |||
| $receiptIssuingOrderList = $this->receiptIssuingOrderRepository->get($condition); | |||
| $summaryList = $this->useSummaryRepository->get($condition); | |||
| // CSVファイル作成 | |||
| // 領収証発行依頼データ | |||
| $csv = new CsvFile($this->getReceiptIssuingOrdersLabel(), CsvFile::ENCODE_SJIS); | |||
| $sortDef = array_keys($this->getReceiptIssuingOrdersLabel()); | |||
| foreach ($receiptIssuingOrderList as $row) { | |||
| $csv->addLine($row->toArray(), $sortDef); | |||
| } | |||
| $list = $this->repository->forCsv()->get($condition); | |||
| $csv = new CsvFile($this->getHeaderLabel(), CsvFile::ENCODE_SJIS); | |||
| foreach ($list as $row) { | |||
| $csv->addLine($row->toArray()); | |||
| // 集計データ | |||
| $csv->addLine([]); | |||
| $csv->addLine($this->getSummaryHeaderLabels()); | |||
| $sortDef = array_keys($this->getSummaryHeaderLabels()); | |||
| foreach ($summaryList as $row) { | |||
| $csv->addLine($row->toArray(), $sortDef); | |||
| } | |||
| return $csv->download($this->getDownloadFileName()); | |||
| } | |||
| private function getHeaderLabel(): array | |||
| private function getReceiptIssuingOrdersLabel(): array | |||
| { | |||
| $headers = [ | |||
| '集計ID', | |||
| '集計年月', | |||
| '顧客コード', | |||
| '顧客名', | |||
| '駐車場管理コード', | |||
| '駐車場名', | |||
| '領収証発行依頼件数', | |||
| '郵送依頼件数', | |||
| 'SMS送信件数', | |||
| return [ | |||
| RDATA::COL_NAME_ID => 'ID', | |||
| RDATA::COL_NAME_ORDER_DATETIME => '受付時刻', | |||
| RDATA::COL_NAME_STATUS_NAME => 'ステータス', | |||
| RDATA::COL_NAME_PARKING_NAME => '駐車場名', | |||
| RDATA::COL_NAME_RECEIPT_USE_DATE => '利用日', | |||
| RDATA::COL_NAME_ADJUST_SEQ_NO => '精算連番', | |||
| RDATA::COL_NAME_RECEIPT_AMOUNT => '金額', | |||
| RDATA::COL_NAME_RECEIPT_NAME => '宛名', | |||
| RDATA::COL_NAME_STATUS_DONE => '完了', | |||
| RDATA::COL_NAME_RECEIPT_NO => '領収証番号', | |||
| // アクション日付 | |||
| RDATA::COL_NAME_SMS_PHONE_NUMBER => 'SMS送信先', | |||
| RDATA::COL_NAME_STATUS_SMS_SEND_DATETIME => 'SMS送信日時', | |||
| RDATA::COL_NAME_STATUS_FIRST_ACCESS_DATETIME => '初回アクセス日時', | |||
| RDATA::COL_NAME_STATUS_RECEIPT_CONFIRM_DATETIME => '領収証確定日時', | |||
| RDATA::COL_NAME_STATUS_ORDER_MAIL_DATETIME => '郵送依頼日時', | |||
| RDATA::COL_NAME_STATUS_MAIL_POST_DATE => '投函日', | |||
| RDATA::COL_NAME_STATUS_RECEIPT_DOWNLOAD_DATETIME => '領収証ダウンロード日時', | |||
| RDATA::COL_NAME_STATUS_RECEIPT_EMAIL_SEND_ORDER_DATETIME => 'EMAIL送信依頼日時', | |||
| RDATA::COL_NAME_STATUS_RECEIPT_EMAIL_SEND_DATETIME => 'EMAIL送信日時', | |||
| // 郵送先 | |||
| RDATA::COL_NAME_MAIL_ZIP_CODE => '郵便番号', | |||
| RDATA::COL_NAME_MAIL_ADDRESS1 => '住所1', | |||
| RDATA::COL_NAME_MAIL_ADDRESS2 => '住所2', | |||
| RDATA::COL_NAME_MAIL_ADDRESS3 => '住所3', | |||
| RDATA::COL_NAME_MAIL_NAME => '郵送宛名', | |||
| ]; | |||
| } | |||
| return $headers; | |||
| private function getSummaryHeaderLabels(): array | |||
| { | |||
| return [ | |||
| 'date_from' => '開始年月日', | |||
| 'date_to' => '終了年月日', | |||
| 'customer_name' => '顧客名', | |||
| 'receipt_order_count' => '領収証発行依頼件数', | |||
| 'mail_order_count' => '郵送依頼件数', | |||
| 'sms_send_count' => 'SMS送信件数', | |||
| ]; | |||
| } | |||
| private function getDownloadFileName() | |||
| @@ -4,9 +4,12 @@ namespace App\Http\Controllers\Web\Custom\HelloTechno; | |||
| use App\Http\Controllers\Web\BaseParam; | |||
| use App\Repositories\Custom\HelloTechno\UseSummaryRepository as Repository; | |||
| use Illuminate\Support\Carbon; | |||
| /** | |||
| * @property ?string $summaryYyyymm | |||
| * @property Carbon $dateFrom | |||
| * @property Carbon $dateTo | |||
| * @property string $customerCode | |||
| */ | |||
| class UseSummaryCSVParam extends BaseParam | |||
| @@ -16,7 +19,9 @@ class UseSummaryCSVParam extends BaseParam | |||
| return | |||
| array_merge( | |||
| [ | |||
| Repository::CONDITION_SUMMARY_YYYYMM => $this->str(), | |||
| Repository::CONDITION_ORDER_DATE_FROM => $this->date(), | |||
| Repository::CONDITION_ORDER_DATE_TO => $this->date(), | |||
| Repository::CONDITION_CUSTOMER_CODE => $this->str(), | |||
| ], | |||
| ); | |||
| } | |||
| @@ -3,6 +3,7 @@ | |||
| namespace App\Repositories\Custom\HelloTechno; | |||
| use App\Models\ReceiptIssuingHTParkingCustomOrder as CustomOrder; | |||
| use App\Repositories\Custom\HelloTechno\ReceiptIssuingOrderRepositoryData as Data; | |||
| use App\Models\ReceiptIssuingOrder; | |||
| use App\Models\ReceiptIssuingOrderTax; | |||
| use App\Models\User; | |||
| @@ -48,7 +49,7 @@ class ReceiptIssuingOrderRepository extends BaseRepository | |||
| * コレクションを取得する | |||
| * | |||
| * @param array $condition | |||
| * @return Collection<ParkingRepositoryData> | |||
| * @return Collection<Data> | |||
| */ | |||
| public function get(array $condition): Collection | |||
| { | |||
| @@ -160,9 +161,9 @@ class ReceiptIssuingOrderRepository extends BaseRepository | |||
| $handler = static::TABLE_HANDLER; | |||
| $tax = static::TABLE_TAX; | |||
| $columns = [ | |||
| $this->makeColumnNameForSelect([$order, ReceiptIssuingOrder::COL_NAME_ID], 'id'), | |||
| $this->makeColumnNameForSelect([$order, ReceiptIssuingOrder::COL_NAME_STATUS_NAME], 'status_name'), | |||
| $this->makeColumnNameForSelect([$order, ReceiptIssuingOrder::COL_NAME_ORDER_DATETIME], 'order_datetime'), | |||
| $this->makeColumnNameForSelect([$order, ReceiptIssuingOrder::COL_NAME_ID]), | |||
| $this->makeColumnNameForSelect([$order, ReceiptIssuingOrder::COL_NAME_STATUS_NAME]), | |||
| $this->makeColumnNameForSelect([$order, ReceiptIssuingOrder::COL_NAME_ORDER_DATETIME]), | |||
| $this->makeColumnNameForSelect([$order, ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY1]), | |||
| $this->makeColumnNameForSelect([$order, ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY2]), | |||
| $this->makeColumnNameForSelect([$order, ReceiptIssuingOrder::COL_NAME_ACCESS_TOKEN]), | |||
| @@ -2,10 +2,57 @@ | |||
| namespace App\Repositories\Custom\HelloTechno; | |||
| use App\Models\ReceiptIssuingHTParkingCustomOrder as CustomOrder; | |||
| use App\Models\ReceiptIssuingOrder; | |||
| use App\Repositories\BaseRepositoryData; | |||
| /** | |||
| */ | |||
| class ReceiptIssuingOrderRepositoryData extends BaseRepositoryData | |||
| { | |||
| const COL_NAME_ID = ReceiptIssuingOrder::COL_NAME_ID; | |||
| const COL_NAME_CONTRACT_ID = ReceiptIssuingOrder::COL_NAME_CONTRACT_ID; | |||
| const COL_NAME_HANDLER_ID = ReceiptIssuingOrder::COL_NAME_HANDLER_ID; | |||
| const COL_NAME_ORDER_DATETIME = ReceiptIssuingOrder::COL_NAME_ORDER_DATETIME; | |||
| const COL_NAME_STATUS_NAME = ReceiptIssuingOrder::COL_NAME_STATUS_NAME; | |||
| const COL_NAME_SUMMARY_KEY1 = ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY1; | |||
| const COL_NAME_SUMMARY_KEY2 = ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY2; | |||
| const COL_NAME_ACCESS_TOKEN = ReceiptIssuingOrder::COL_NAME_ACCESS_TOKEN; | |||
| const COL_NAME_ACCESS_TOKEN_EXPIRES_AT = ReceiptIssuingOrder::COL_NAME_ACCESS_TOKEN_EXPIRES_AT; | |||
| const COL_NAME_STATUS_DONE = ReceiptIssuingOrder::COL_NAME_STATUS_DONE; | |||
| const COL_NAME_STATUS_SMS_SEND_DATETIME = ReceiptIssuingOrder::COL_NAME_STATUS_SMS_SEND_DATETIME; | |||
| const COL_NAME_STATUS_FIRST_ACCESS_DATETIME = ReceiptIssuingOrder::COL_NAME_STATUS_FIRST_ACCESS_DATETIME; | |||
| const COL_NAME_STATUS_RECEIPT_CONFIRM_DATETIME = ReceiptIssuingOrder::COL_NAME_STATUS_RECEIPT_CONFIRM_DATETIME; | |||
| const COL_NAME_STATUS_ORDER_MAIL_DATETIME = ReceiptIssuingOrder::COL_NAME_STATUS_ORDER_MAIL_DATETIME; | |||
| const COL_NAME_STATUS_MAIL_DOWNLOAD_DATETIME = ReceiptIssuingOrder::COL_NAME_STATUS_MAIL_DOWNLOAD_DATETIME; | |||
| const COL_NAME_STATUS_MAIL_POST_DATE = ReceiptIssuingOrder::COL_NAME_STATUS_MAIL_POST_DATE; | |||
| const COL_NAME_STATUS_RECEIPT_DOWNLOAD_DATETIME = ReceiptIssuingOrder::COL_NAME_STATUS_RECEIPT_DOWNLOAD_DATETIME; | |||
| const COL_NAME_STATUS_RECEIPT_EMAIL_SEND_ORDER_DATETIME = ReceiptIssuingOrder::COL_NAME_STATUS_RECEIPT_EMAIL_SEND_ORDER_DATETIME; | |||
| const COL_NAME_STATUS_RECEIPT_EMAIL_SEND_DATETIME = ReceiptIssuingOrder::COL_NAME_STATUS_RECEIPT_EMAIL_SEND_DATETIME; | |||
| const COL_NAME_SMS_PHONE_NUMBER = ReceiptIssuingOrder::COL_NAME_SMS_PHONE_NUMBER; | |||
| const COL_NAME_SMS_SEND_SUCCESS = ReceiptIssuingOrder::COL_NAME_SMS_SEND_SUCCESS; | |||
| const COL_NAME_RECEIPT_NO = ReceiptIssuingOrder::COL_NAME_RECEIPT_NO; | |||
| const COL_NAME_RECEIPT_USE_DATE = ReceiptIssuingOrder::COL_NAME_RECEIPT_USE_DATE; | |||
| const COL_NAME_RECEIPT_SHOP_NAME = ReceiptIssuingOrder::COL_NAME_RECEIPT_SHOP_NAME; | |||
| const COL_NAME_RECEIPT_ISSUER = ReceiptIssuingOrder::COL_NAME_RECEIPT_ISSUER; | |||
| const COL_NAME_RECEIPT_NAME = ReceiptIssuingOrder::COL_NAME_RECEIPT_NAME; | |||
| const COL_NAME_RECEIPT_PURPOSE = ReceiptIssuingOrder::COL_NAME_RECEIPT_PURPOSE; | |||
| const COL_NAME_RECEIPT_INVOICE_NO = ReceiptIssuingOrder::COL_NAME_RECEIPT_INVOICE_NO; | |||
| const COL_NAME_RECEIPT_AMOUNT = ReceiptIssuingOrder::COL_NAME_RECEIPT_AMOUNT; | |||
| const COL_NAME_EMAIL = ReceiptIssuingOrder::COL_NAME_EMAIL; | |||
| const COL_NAME_MAIL_PREF_CODE = ReceiptIssuingOrder::COL_NAME_MAIL_PREF_CODE; | |||
| const COL_NAME_MAIL_ZIP_CODE = ReceiptIssuingOrder::COL_NAME_MAIL_ZIP_CODE; | |||
| const COL_NAME_MAIL_ADDRESS1 = ReceiptIssuingOrder::COL_NAME_MAIL_ADDRESS1; | |||
| const COL_NAME_MAIL_ADDRESS2 = ReceiptIssuingOrder::COL_NAME_MAIL_ADDRESS2; | |||
| const COL_NAME_MAIL_ADDRESS3 = ReceiptIssuingOrder::COL_NAME_MAIL_ADDRESS3; | |||
| const COL_NAME_MAIL_NAME = ReceiptIssuingOrder::COL_NAME_MAIL_NAME; | |||
| const COL_NAME_MEMO = ReceiptIssuingOrder::COL_NAME_MEMO; | |||
| const COL_NAME_PARKING_NAME = CustomOrder::COL_NAME_PARKING_NAME; | |||
| const COL_NAME_ADJUST_SEQ_NO = CustomOrder::COL_NAME_ADJUST_SEQ_NO; | |||
| } | |||
| @@ -2,36 +2,38 @@ | |||
| namespace App\Repositories\Custom\HelloTechno; | |||
| use App\Exceptions\AppCommonException; | |||
| use App\Models\HtCustomParkingName; | |||
| use App\Models\ReceiptIssuingHTParkingCustomOrder; | |||
| use App\Models\ReceiptIssuingOrder; | |||
| use App\Models\SMSSendOrder; | |||
| use App\Models\UseByKeySummary; | |||
| use App\Repositories\BaseRepository; | |||
| use App\Util\SelectQueryUtil; | |||
| use Illuminate\Database\Query\JoinClause; | |||
| use Illuminate\Support\Carbon; | |||
| use Illuminate\Support\Collection; | |||
| use Illuminate\Support\Facades\DB; | |||
| use Illuminate\Support\Facades\Storage; | |||
| use LogicException; | |||
| class UseSummaryRepository extends BaseRepository | |||
| { | |||
| const CONDITION_ID = 'id'; | |||
| const CONDITION_SUMMARY_YYYYMM = 'summary_yyyymm'; | |||
| // 必須検索項目 | |||
| const CONDITION_CONTRACT_ID = 'contract_id'; | |||
| const CONDITION_ORDER_DATE_FROM = 'date_from'; | |||
| const CONDITION_ORDER_DATE_TO = 'date_to'; | |||
| const TABLE_SUMMARY = "summary"; | |||
| const TABLE_NAME = "name"; | |||
| const CONDITION_CUSTOMER_CODE = 'customer_code'; | |||
| private const SELECT_LIST = 'SELECT_LIST'; | |||
| private const SELECT_CSV = 'SELECT_CSV'; | |||
| private const TABLE_TARGET = "target"; | |||
| private const TABLE_SMS = "SMS"; | |||
| private const TABLE_SUMMARY = "summary"; | |||
| private const TABLE_NAME = "name"; | |||
| private string $select = self::SELECT_LIST; | |||
| public function forCsv(): static | |||
| { | |||
| $this->select = self::SELECT_CSV; | |||
| return $this; | |||
| } | |||
| private Carbon $dateFrom; | |||
| private Carbon $dateTo; | |||
| /** | |||
| @@ -42,83 +44,139 @@ class UseSummaryRepository extends BaseRepository | |||
| */ | |||
| public function get(array $condition): Collection | |||
| { | |||
| $order = UseByKeySummary::getBuilder(static::TABLE_SUMMARY); | |||
| $contractId = data_get($condition, self::CONDITION_CONTRACT_ID); | |||
| $parkingName = HtCustomParkingName::getBuilder(); | |||
| if (!$contractId) { | |||
| throw new AppCommonException('契約ID不正'); | |||
| } | |||
| $dateFrom = data_get($condition, self::CONDITION_ORDER_DATE_FROM); | |||
| $dateTo = data_get($condition, self::CONDITION_ORDER_DATE_TO); | |||
| if (!($dateFrom instanceof Carbon) || !($dateTo instanceof Carbon)) { | |||
| throw new AppCommonException('検索日付不正'); | |||
| } | |||
| $this->dateFrom = $dateFrom; | |||
| $this->dateTo = $dateTo; | |||
| $target = ReceiptIssuingOrder::getBuilder(self::TABLE_TARGET) | |||
| ->where( | |||
| $this->makeColumnName([static::TABLE_TARGET, ReceiptIssuingOrder::COL_NAME_CONTRACT_ID]), | |||
| $contractId | |||
| ) | |||
| ->where( | |||
| $this->makeColumnName([static::TABLE_TARGET, ReceiptIssuingOrder::COL_NAME_ORDER_DATETIME]), | |||
| '>=', | |||
| $dateFrom | |||
| ) | |||
| ->where( | |||
| $this->makeColumnName([static::TABLE_TARGET, ReceiptIssuingOrder::COL_NAME_ORDER_DATETIME]), | |||
| '<', | |||
| $dateTo | |||
| ); | |||
| $customerCode = data_get($condition, self::CONDITION_CUSTOMER_CODE); | |||
| if ($customerCode) { | |||
| $target->where( | |||
| $this->makeColumnName([static::TABLE_TARGET, ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY1]), | |||
| $customerCode | |||
| ); | |||
| } | |||
| $table = $order | |||
| ->leftJoinSub($parkingName, static::TABLE_NAME, function (JoinClause $join) { | |||
| $smsCount = $target->clone() | |||
| ->joinSub( | |||
| SMSSendOrder::getBuilder(), | |||
| self::TABLE_SMS, | |||
| function (JoinClause $join) { | |||
| $join->on( | |||
| $this->makeColumnName([static::TABLE_SMS, SMSSendOrder::COL_NAME_RECEIPT_ISSUING_ORDER_ID]), | |||
| $this->makeColumnName([static::TABLE_TARGET, ReceiptIssuingOrder::COL_NAME_ID]), | |||
| ); | |||
| } | |||
| ) | |||
| ->whereNotNull(SMSSendOrder::COL_NAME_SEND_DATETIME) | |||
| ->groupBy( | |||
| $this->makeColumnName([static::TABLE_TARGET, ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY1]) | |||
| ) | |||
| ->select([ | |||
| $this->makeColumnName([static::TABLE_TARGET, ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY1]), | |||
| DB::raw('count(*) as sms_send_count'), | |||
| ]); | |||
| $orderCount = $target->clone() | |||
| ->groupBy([ | |||
| $this->makeColumnName([static::TABLE_TARGET, UseByKeySummary::COL_NAME_SUMMARY_KEY1]) | |||
| ]) | |||
| ->select([ | |||
| ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY1, | |||
| DB::raw(sprintf("count(*) as %s", 'receipt_order_count')), | |||
| DB::raw(sprintf("count(%s) as %s", ReceiptIssuingOrder::COL_NAME_STATUS_ORDER_MAIL_DATETIME, 'mail_order_count')), | |||
| ]); | |||
| $summary = DB::table($orderCount, self::TABLE_SUMMARY) | |||
| ->joinSub( | |||
| $smsCount, | |||
| self::TABLE_SMS, | |||
| function (JoinClause $join) { | |||
| $join->on( | |||
| $this->makeColumnName([static::TABLE_SMS, ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY1]), | |||
| $this->makeColumnName([static::TABLE_SUMMARY, ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY1]), | |||
| ); | |||
| } | |||
| ); | |||
| // 顧客名解決 | |||
| $name = HtCustomParkingName::getBuilder()->select([ | |||
| HtCustomParkingName::COL_NAME_CUSTOMER_CODE, | |||
| HtCustomParkingName::COL_NAME_CUSTOMER_NAME, | |||
| DB::raw('RANK() OVER(PARTITION BY customer_code ORDER BY updated_at DESC) as rank') | |||
| ]); | |||
| $main = $summary | |||
| ->leftJoinSub($name, static::TABLE_NAME, function (JoinClause $join) { | |||
| $join->on( | |||
| $this->makeColumnName([static::TABLE_SUMMARY, UseByKeySummary::COL_NAME_SUMMARY_KEY1]), | |||
| $this->makeColumnName([static::TABLE_NAME, HtCustomParkingName::COL_NAME_CUSTOMER_CODE]) | |||
| )->on( | |||
| $this->makeColumnName([static::TABLE_SUMMARY, UseByKeySummary::COL_NAME_SUMMARY_KEY2]), | |||
| $this->makeColumnName([static::TABLE_NAME, HtCustomParkingName::COL_NAME_PARKING_MANAGEMENT_CODE]) | |||
| ); | |||
| )->where($this->makeColumnName([static::TABLE_NAME, 'rank']), 1); | |||
| }); | |||
| // -----検索条件 | |||
| // 契約ID | |||
| $this->where($table, $condition, static::CONDITION_CONTRACT_ID, $this->makeColumnName([static::TABLE_SUMMARY, UseByKeySummary::COL_NAME_CONTRACT_ID])); | |||
| // 年月 | |||
| $this->where($table, $condition, static::CONDITION_SUMMARY_YYYYMM, $this->makeColumnName([static::TABLE_SUMMARY, UseByKeySummary::COL_NAME_SUMMARY_YYYYMM])); | |||
| if ($this->select === self::SELECT_LIST) { | |||
| $table->select($this->columns()); | |||
| } else if ($this->select === self::SELECT_CSV) { | |||
| $table->select($this->csvColumns()); | |||
| } else { | |||
| throw new LogicException("SELECT不正"); | |||
| } | |||
| $main = DB::table($table, "main"); | |||
| // $main = DB::table($table, "main"); | |||
| $main->select($this->columns()); | |||
| // ソート | |||
| $this->sort($main, $condition); | |||
| $main->orderBy(static::CONDITION_ID); | |||
| $main->orderBy( | |||
| $this->makeColumnName([static::TABLE_SUMMARY, ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY1]), | |||
| ); | |||
| // リミット | |||
| $this->limit($main, $condition); | |||
| $sql = $main->toSql(); | |||
| Storage::put('summary.sql', $sql); | |||
| return ReceiptIssuingOrderRepositoryData::makeList($main->get()); | |||
| return UseSummaryRepositoryData::makeList($main->get()); | |||
| } | |||
| private function columns() | |||
| { | |||
| $summary = static::TABLE_SUMMARY; | |||
| $name = static::TABLE_NAME; | |||
| $columns = [ | |||
| $this->makeColumnNameForSelect([$summary, UseByKeySummary::COL_NAME_ID]), | |||
| $this->makeColumnNameForSelect([$summary, UseByKeySummary::COL_NAME_SUMMARY_YYYYMM]), | |||
| $this->makeColumnNameForSelect([$summary, UseByKeySummary::COL_NAME_SUMMARY_KEY1]), | |||
| $this->makeColumnNameForSelect([$summary, UseByKeySummary::COL_NAME_SUMMARY_KEY2]), | |||
| $this->makeColumnNameForSelect([$summary, UseByKeySummary::COL_NAME_RECEIPT_ORDER_COUNT]), | |||
| $this->makeColumnNameForSelect([$summary, UseByKeySummary::COL_NAME_MAIL_ORDER_COUNT]), | |||
| $this->makeColumnNameForSelect([$summary, UseByKeySummary::COL_NAME_SMS_SEND_COUNT]), | |||
| $this->makeColumnNameForSelect([$summary, UseByKeySummary::COL_NAME_IS_FIXED]), | |||
| $this->makeColumnNameForSelect([$summary, UseByKeySummary::COL_NAME_UPDATED_AT]), | |||
| $this->makeColumnNameForSelect([$name, HtCustomParkingName::COL_NAME_CUSTOMER_NAME]), | |||
| $this->makeColumnNameForSelect([$name, HtCustomParkingName::COL_NAME_PARKING_NAME]), | |||
| ]; | |||
| return $columns; | |||
| } | |||
| private function csvColumns() | |||
| { | |||
| $summary = static::TABLE_SUMMARY; | |||
| $name = static::TABLE_NAME; | |||
| $sms = self::TABLE_SMS; | |||
| $summary = self::TABLE_SUMMARY; | |||
| $name = self::TABLE_NAME; | |||
| $columns = [ | |||
| $this->makeColumnNameForSelect([$summary, UseByKeySummary::COL_NAME_ID]), | |||
| $this->makeColumnNameForSelect([$summary, UseByKeySummary::COL_NAME_SUMMARY_YYYYMM]), | |||
| $this->makeColumnNameForSelect([$summary, UseByKeySummary::COL_NAME_SUMMARY_KEY1]), | |||
| $this->makeColumnNameForSelect([$name, HtCustomParkingName::COL_NAME_CUSTOMER_NAME]), | |||
| $this->makeColumnNameForSelect([$summary, UseByKeySummary::COL_NAME_SUMMARY_KEY2]), | |||
| $this->makeColumnNameForSelect([$name, HtCustomParkingName::COL_NAME_PARKING_NAME]), | |||
| $this->makeColumnNameForSelect([$summary, UseByKeySummary::COL_NAME_RECEIPT_ORDER_COUNT]), | |||
| $this->makeColumnNameForSelect([$summary, UseByKeySummary::COL_NAME_MAIL_ORDER_COUNT]), | |||
| $this->makeColumnNameForSelect([$summary, UseByKeySummary::COL_NAME_SMS_SEND_COUNT]), | |||
| SelectQueryUtil::value($this->dateFrom->format('Y/m/d'), 'date_from'), | |||
| SelectQueryUtil::value($this->dateTo->format('Y/m/d'), 'date_to'), | |||
| SelectQueryUtil::select([$name, HtCustomParkingName::COL_NAME_CUSTOMER_CODE])->build(), | |||
| SelectQueryUtil::select([$name, HtCustomParkingName::COL_NAME_CUSTOMER_NAME])->build(), | |||
| SelectQueryUtil::select([$summary, 'receipt_order_count'])->build(), | |||
| SelectQueryUtil::select([$summary, 'mail_order_count'])->build(), | |||
| SelectQueryUtil::select([$sms, 'sms_send_count'])->nullValue(0)->build(), | |||
| ]; | |||
| return $columns; | |||
| } | |||
| @@ -0,0 +1,90 @@ | |||
| <?php | |||
| namespace App\Util; | |||
| use Illuminate\Support\Arr; | |||
| use Illuminate\Support\Facades\DB; | |||
| class SelectQueryUtil | |||
| { | |||
| public static function select(array|string $columns, string $as = null): static | |||
| { | |||
| return new static($columns, $as); | |||
| } | |||
| public static function value(string|int $val, string $as) | |||
| { | |||
| if (is_string($val)) { | |||
| return DB::raw(sprintf("'%s' as %s", $val, $as)); | |||
| } else if (is_int($val)) { | |||
| return DB::raw(sprintf("CAST('%s' as INTEGER) as %s", $val, $as)); | |||
| } | |||
| return ""; | |||
| } | |||
| private string $columnName; | |||
| private string|null $as = null; | |||
| private string|int|null $nullValue = null; | |||
| public function __construct(array|string $column, string $as = null) | |||
| { | |||
| if (is_string($column)) { | |||
| $this->columnName = $column; | |||
| $this->as = $column; | |||
| } else { | |||
| $ret = ""; | |||
| foreach ($column as $c) { | |||
| if ($ret !== "") { | |||
| $ret .= "."; | |||
| } | |||
| $ret .= sprintf('"%s"', $c); | |||
| } | |||
| $this->columnName = $ret; | |||
| $this->as = Arr::last($column); | |||
| } | |||
| if ($as !== null) { | |||
| $this->as = $as; | |||
| } | |||
| } | |||
| public function as(string $as): static | |||
| { | |||
| $this->as = $as; | |||
| return $this; | |||
| } | |||
| public function nullValue(string|int|null $nullValue): static | |||
| { | |||
| $this->nullValue = $nullValue; | |||
| return $this; | |||
| } | |||
| public function build() | |||
| { | |||
| $query = $this->columnName; | |||
| $needRaw = true; | |||
| if ($this->nullValue !== null) { | |||
| if (is_string($this->nullValue)) { | |||
| $query = sprintf("COALESCE(%s, '%s')", $query, $this->nullValue); | |||
| $needRaw = true; | |||
| } else if (is_int($this->nullValue)) { | |||
| $query = sprintf("COALESCE(%s, %d)", $query, $this->nullValue); | |||
| $needRaw = true; | |||
| } | |||
| } | |||
| if ($this->as !== null) { | |||
| $query = sprintf('%s as %s', $query, $this->as); | |||
| } | |||
| return $needRaw ? DB::raw($query) : $query; | |||
| } | |||
| } | |||