| @@ -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 = ""; | $str = ""; | ||||
| foreach ($row as $col => $val) { | foreach ($row as $col => $val) { | ||||
| if ($str !== "") { | if ($str !== "") { | ||||
| @@ -51,4 +55,18 @@ class CsvFile extends TmpFile | |||||
| { | { | ||||
| return mb_convert_encoding($source, "SJIS", "UTF8"); | 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\Http\Controllers\Web\BaseParam; | ||||
| use App\Repositories\Custom\HelloTechno\UseSummaryRepository as Repository; | 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 | class UseSummariesParam extends BaseParam | ||||
| @@ -17,8 +18,8 @@ class UseSummariesParam extends BaseParam | |||||
| return | return | ||||
| array_merge( | 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(), | $this->sortableRules(), | ||||
| ); | ); | ||||
| @@ -6,9 +6,10 @@ use App\Codes\UserRole; | |||||
| use App\Features\LoginUser; | use App\Features\LoginUser; | ||||
| use App\Files\CsvFile; | use App\Files\CsvFile; | ||||
| use App\Http\Controllers\Web\IParam; | 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\Http\Request; | ||||
| use Illuminate\Support\Facades\Auth; | |||||
| use Symfony\Component\HttpFoundation\BinaryFileResponse; | use Symfony\Component\HttpFoundation\BinaryFileResponse; | ||||
| class UseSummaryCSVController extends HelloTechnoController | class UseSummaryCSVController extends HelloTechnoController | ||||
| @@ -28,7 +29,8 @@ class UseSummaryCSVController extends HelloTechnoController | |||||
| public function __construct( | public function __construct( | ||||
| protected UseSummaryCSVParam $param, | protected UseSummaryCSVParam $param, | ||||
| private Repository $repository | |||||
| private ReceiptIssuingOrderRepository $receiptIssuingOrderRepository, | |||||
| private UseSummaryRepository $useSummaryRepository, | |||||
| ) { | ) { | ||||
| parent::__construct(); | parent::__construct(); | ||||
| $this->roleAllow(UserRole::NORMAL_ADMIN); | $this->roleAllow(UserRole::NORMAL_ADMIN); | ||||
| @@ -43,36 +45,82 @@ class UseSummaryCSVController extends HelloTechnoController | |||||
| { | { | ||||
| $param = $this->param; | $param = $this->param; | ||||
| // データ取得 | |||||
| $condition = [ | $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()); | 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() | private function getDownloadFileName() | ||||
| @@ -4,9 +4,12 @@ namespace App\Http\Controllers\Web\Custom\HelloTechno; | |||||
| use App\Http\Controllers\Web\BaseParam; | use App\Http\Controllers\Web\BaseParam; | ||||
| use App\Repositories\Custom\HelloTechno\UseSummaryRepository as Repository; | 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 | class UseSummaryCSVParam extends BaseParam | ||||
| @@ -16,7 +19,9 @@ class UseSummaryCSVParam extends BaseParam | |||||
| return | return | ||||
| array_merge( | 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; | namespace App\Repositories\Custom\HelloTechno; | ||||
| use App\Models\ReceiptIssuingHTParkingCustomOrder as CustomOrder; | use App\Models\ReceiptIssuingHTParkingCustomOrder as CustomOrder; | ||||
| use App\Repositories\Custom\HelloTechno\ReceiptIssuingOrderRepositoryData as Data; | |||||
| use App\Models\ReceiptIssuingOrder; | use App\Models\ReceiptIssuingOrder; | ||||
| use App\Models\ReceiptIssuingOrderTax; | use App\Models\ReceiptIssuingOrderTax; | ||||
| use App\Models\User; | use App\Models\User; | ||||
| @@ -48,7 +49,7 @@ class ReceiptIssuingOrderRepository extends BaseRepository | |||||
| * コレクションを取得する | * コレクションを取得する | ||||
| * | * | ||||
| * @param array $condition | * @param array $condition | ||||
| * @return Collection<ParkingRepositoryData> | |||||
| * @return Collection<Data> | |||||
| */ | */ | ||||
| public function get(array $condition): Collection | public function get(array $condition): Collection | ||||
| { | { | ||||
| @@ -160,9 +161,9 @@ class ReceiptIssuingOrderRepository extends BaseRepository | |||||
| $handler = static::TABLE_HANDLER; | $handler = static::TABLE_HANDLER; | ||||
| $tax = static::TABLE_TAX; | $tax = static::TABLE_TAX; | ||||
| $columns = [ | $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_KEY1]), | ||||
| $this->makeColumnNameForSelect([$order, ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY2]), | $this->makeColumnNameForSelect([$order, ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY2]), | ||||
| $this->makeColumnNameForSelect([$order, ReceiptIssuingOrder::COL_NAME_ACCESS_TOKEN]), | $this->makeColumnNameForSelect([$order, ReceiptIssuingOrder::COL_NAME_ACCESS_TOKEN]), | ||||
| @@ -2,10 +2,57 @@ | |||||
| namespace App\Repositories\Custom\HelloTechno; | namespace App\Repositories\Custom\HelloTechno; | ||||
| use App\Models\ReceiptIssuingHTParkingCustomOrder as CustomOrder; | |||||
| use App\Models\ReceiptIssuingOrder; | |||||
| use App\Repositories\BaseRepositoryData; | use App\Repositories\BaseRepositoryData; | ||||
| /** | /** | ||||
| */ | */ | ||||
| class ReceiptIssuingOrderRepositoryData extends 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; | namespace App\Repositories\Custom\HelloTechno; | ||||
| use App\Exceptions\AppCommonException; | |||||
| use App\Models\HtCustomParkingName; | use App\Models\HtCustomParkingName; | ||||
| use App\Models\ReceiptIssuingHTParkingCustomOrder; | |||||
| use App\Models\ReceiptIssuingOrder; | |||||
| use App\Models\SMSSendOrder; | |||||
| use App\Models\UseByKeySummary; | use App\Models\UseByKeySummary; | ||||
| use App\Repositories\BaseRepository; | use App\Repositories\BaseRepository; | ||||
| use App\Util\SelectQueryUtil; | |||||
| use Illuminate\Database\Query\JoinClause; | use Illuminate\Database\Query\JoinClause; | ||||
| use Illuminate\Support\Carbon; | |||||
| use Illuminate\Support\Collection; | use Illuminate\Support\Collection; | ||||
| use Illuminate\Support\Facades\DB; | use Illuminate\Support\Facades\DB; | ||||
| use Illuminate\Support\Facades\Storage; | |||||
| use LogicException; | use LogicException; | ||||
| class UseSummaryRepository extends BaseRepository | class UseSummaryRepository extends BaseRepository | ||||
| { | { | ||||
| const CONDITION_ID = 'id'; | |||||
| const CONDITION_SUMMARY_YYYYMM = 'summary_yyyymm'; | |||||
| // 必須検索項目 | |||||
| const CONDITION_CONTRACT_ID = 'contract_id'; | 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 | 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( | $join->on( | ||||
| $this->makeColumnName([static::TABLE_SUMMARY, UseByKeySummary::COL_NAME_SUMMARY_KEY1]), | $this->makeColumnName([static::TABLE_SUMMARY, UseByKeySummary::COL_NAME_SUMMARY_KEY1]), | ||||
| $this->makeColumnName([static::TABLE_NAME, HtCustomParkingName::COL_NAME_CUSTOMER_CODE]) | $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); | $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); | $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() | 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 = [ | $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; | 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; | |||||
| } | |||||
| } | |||||