diff --git a/app/Config/Constants.php b/app/Config/Constants.php index 87786f7..2a43d92 100644 --- a/app/Config/Constants.php +++ b/app/Config/Constants.php @@ -203,9 +203,16 @@ define('AUTH_ADAPTERS', [ ], ]); +define("MALLS", [ + "support" => "support@idcjp.jp", + "master" => "master@idcjp.jp", + "title" => "Mall Master" +]); + //Upload , Download 관련 define('PATHS', [ 'EXCEL' => WRITEPATH . "excel/", + 'BILLING' => WRITEPATH . "billing/", 'UPLOAD' => WRITEPATH . "uploads/", 'UPLOAD_IMAGE' => FCPATH . 'upload_images/', 'DOWNLOAD' => WRITEPATH . "download/", @@ -249,6 +256,7 @@ define('CLASS_ICONS', [ 'CATEGORY' => '', 'PRODUCT' => '', 'ORDER' => '', + 'BILLING' => '', 'CART' => '', 'CARD' => '', 'DEPOSIT' => '', @@ -257,6 +265,7 @@ define('CLASS_TOP_BANNER', [ 'USER' => '', 'USERSNS' => '', 'ORDER' => '', + 'BILLING' => '', 'CARD' => '', 'DEPOSIT' => '', 'PRODUCT' => '', @@ -269,8 +278,7 @@ define('AUDIOS', [ //Default값 정의 define('DEFAULTS', [ - 'ORDER_CATEGORY' => getenv('default.order_category') ?: 11, - 'USER_CATEGORY' => getenv('default.user_category') ?: 22, + 'CATEGORY' => getenv('default.category') ?: 22, 'ROLE' => getenv('default.role') ?: "guest", 'STATUS' => getenv('default.status') ?: "use", 'EMPTY' => getenv('default.empty') ?: "", diff --git a/app/Config/Routes.php b/app/Config/Routes.php index d2f0323..8011bef 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -123,6 +123,16 @@ $routes->group('admin', ['namespace' => 'App\Controllers\Admin', 'filter' => 'au $routes->get('toggle/(:uuid)/(:hash)', 'OrderController::toggle/$1/$2'); $routes->post('batchjob', 'OrderController::batchjob`'); }); + $routes->group('billing', static function ($routes) { + $routes->get('', 'BillingController::index'); + $routes->get('update/(:uuid)', 'BillingController::update_form/$1'); + $routes->post('update/(:uuid)', 'BillingController::update/$1'); + $routes->get('view/(:uuid)', 'BillingController::view/$1'); + $routes->get('delete/(:uuid)', 'BillingController::delete/$1', ['filter' => 'authFilter:master']); + $routes->get('toggle/(:uuid)/(:hash)', 'BillingController::toggle/$1/$2'); + $routes->post('batchjob', 'BillingController::batchjob`'); + $routes->get('download/(:any)/(:uuid)', 'BillingController::download/$1/$2'); + }); }); $routes->group('front', ['namespace' => 'App\Controllers\Front'], function ($routes) { $routes->group('user', static function ($routes) { @@ -169,6 +179,9 @@ $routes->group('front', ['namespace' => 'App\Controllers\Front'], function ($rou $routes->post('deposit/(:uuid)', 'DepositController::update/$1'); }); }); + $routes->group('billing', static function ($routes) { + $routes->get('', 'BillingController::index'); + }); }); /* * -------------------------------------------------------------------- diff --git a/app/Controllers/Admin/BillingController.php b/app/Controllers/Admin/BillingController.php new file mode 100644 index 0000000..6565949 --- /dev/null +++ b/app/Controllers/Admin/BillingController.php @@ -0,0 +1,49 @@ +_model = new BillingModel(); + $this->_viewDatas['className'] = 'Billing'; + $this->_viewPath .= strtolower($this->_viewDatas['className']); + $this->_viewDatas['title'] = lang($this->_viewDatas['className'] . '.title'); + $this->_viewDatas['class_icon'] = CLASS_ICONS[strtoupper($this->_viewDatas['className'])]; + helper($this->_viewDatas['className']); + } + + final public function getFields(string $action = ""): array + { + switch ($action) { + case 'update': + return ["user_uid", 'order_uid', "title", "upload_file", "status"]; + break; + case "index": + case "excel": + return ["user_uid", "order_uid", "title", "upload_file", "status", "updated_at", "created_at"]; + break; + case "view": + return ["user_uid", 'order_uid', "title", "upload_file", "status", "updated_at", "created_at", 'response']; + break; + default: + return []; + break; + } + } + final public function getFieldFilters(): array + { + return ["user_uid", 'order_uid', "status"]; + } + final public function getFieldBatchFilters(): array + { + return ["status"]; + } +} diff --git a/app/Controllers/Admin/CategoryController.php b/app/Controllers/Admin/CategoryController.php index 664b7ae..cadb596 100644 --- a/app/Controllers/Admin/CategoryController.php +++ b/app/Controllers/Admin/CategoryController.php @@ -57,7 +57,6 @@ class CategoryController extends AdminController private function write_leftmenu($old_category, array $categorys) { //신규 대분류인경우 기존 카테고리 메뉴 만들기 - // $categorys = array_reverse($categorys); //중분류의 경우 나중에 넣은것이 먼저되므로 reverse해서 처리 foreach ($categorys as $category) { $viewDatas = [ 'className' => $this->_viewDatas['className'], @@ -103,6 +102,13 @@ class CategoryController extends AdminController $this->build_leftmenu(); return $entity; } + //Toggle관련 + protected function toggle_process($entity) + { + $entity = parent::toggle_process($entity); + $this->build_leftmenu(); + return $entity; + } //Reply관련 protected function reply_process($entity) { diff --git a/app/Controllers/Admin/OrderController.php b/app/Controllers/Admin/OrderController.php index 1b0deba..a32b0b6 100644 --- a/app/Controllers/Admin/OrderController.php +++ b/app/Controllers/Admin/OrderController.php @@ -31,7 +31,7 @@ class OrderController extends AdminController return ["user_uid", "name", "cost", "sale", "quantity", "price", "status", "updated_at", "created_at"]; break; case "view": - return ["user_uid", 'product_uid', "name", "cost", "sale", "quantity", "price", "status", "updated_at", "created_at", 'response']; + return ["user_uid", 'product_uid', "name", "cost", "sale", "quantity", "price", "status", "updated_at", "created_at"]; break; default: return []; diff --git a/app/Controllers/Front/BillingController.php b/app/Controllers/Front/BillingController.php new file mode 100644 index 0000000..c1e2143 --- /dev/null +++ b/app/Controllers/Front/BillingController.php @@ -0,0 +1,53 @@ +_model = new BillingModel(); + $this->_viewDatas['className'] = 'Billing'; + $this->_viewPath .= strtolower($this->_viewDatas['className']); + $this->_viewDatas['title'] = lang($this->_viewDatas['className'] . '.title'); + $this->_viewDatas['class_icon'] = CLASS_ICONS[strtoupper($this->_viewDatas['className'])]; + helper($this->_viewDatas['className']); + + //Default 회원정보 Category + $this->_category = DEFAULTS['CATEGORY']; + $this->isRole('index'); + } + + final public function getFields(string $action = ""): array + { + switch ($action) { + case 'update': + return ['order_uid', "title", "upload_file", "status"]; + break; + case "index": + case "excel": + return ["order_uid", "title", "upload_file", "status", "updated_at", "created_at"]; + break; + case "view": + return ['order_uid', "title", "upload_file", "status", "updated_at", "created_at", 'response']; + break; + default: + return []; + break; + } + } + final public function getFieldFilters(): array + { + return ["user_uid", 'order_uid', "status"]; + } + final public function getFieldBatchFilters(): array + { + return ["status"]; + } +} diff --git a/app/Controllers/Front/Order/OrderController.php b/app/Controllers/Front/Order/OrderController.php index 04aa484..57b4df7 100644 --- a/app/Controllers/Front/Order/OrderController.php +++ b/app/Controllers/Front/Order/OrderController.php @@ -26,7 +26,7 @@ class OrderController extends FrontController helper($this->_viewDatas['className']); //Default 회원정보 Category - $this->_category = DEFAULTS['ORDER_CATEGORY']; + $this->_category = DEFAULTS['CATEGORY']; $this->isRole('index'); } diff --git a/app/Controllers/Front/Order/Payment/CardController.php b/app/Controllers/Front/Order/Payment/CardController.php index 8d0df6e..535b7ee 100644 --- a/app/Controllers/Front/Order/Payment/CardController.php +++ b/app/Controllers/Front/Order/Payment/CardController.php @@ -83,27 +83,34 @@ class CardController extends PaymentController } //카드결제처리 - private function pg_process(array $responses): array + private function pg_process(): string { //PG사 결제후 정보저장 $adapter = new PaymentAdapter(); $adapter->setDatas($this->_viewDatas['fieldDatas']); $result = $adapter->execute(); + + $response = ""; foreach ($result as $key => $value) { - $responses['response'] .= "{$key}:{$value}\n"; + $response .= "{$key}:{$value}\n"; } - return $responses; + return $response; } protected function update_process($entity) { - //결과저장용 - $responses = array("status" => $this->_viewDatas['className'], "response" => ""); - foreach ($this->_viewDatas['fieldDatas'] as $key => $value) { - $responses['response'] .= "{$key}:{$value}\n"; - } - $this->_viewDatas['fieldDatas'] = $this->pg_process($responses); - // echo var_export($this->_viewDatas['fieldDatas']); - // exit; - return parent::update_process($entity); + //결제처리 + $this->_viewDatas['fieldDatas'] = array("status" => $this->_viewDatas['className']); + $entity = parent::update_process($entity); + //카드결제 + $response = $this->pg_process(); + //청구서 발행정보 + $subject = sprintf("%s %s 청구서입니다.", $entity->getTitle(), date("Y년 m월")); + $html = view( + $this->_viewPath . 'billing', + ['viewDatas' => $this->_viewDatas['fieldDatas']] + ); + //청구서 발행 + $this->billing($entity, $subject, $html); + return $entity; } } diff --git a/app/Controllers/Front/Order/Payment/DepositController.php b/app/Controllers/Front/Order/Payment/DepositController.php index e674cce..2d17b00 100644 --- a/app/Controllers/Front/Order/Payment/DepositController.php +++ b/app/Controllers/Front/Order/Payment/DepositController.php @@ -72,14 +72,17 @@ class DepositController extends PaymentController //무통장입금결제처리 protected function update_process($entity) { - //결과저장용 - $responses = array("status" => $this->_viewDatas['className'], "response" => ""); - foreach ($this->_viewDatas['fieldDatas'] as $key => $value) { - $responses['response'] .= "{$key}:{$value}\n"; - } - $this->_viewDatas['fieldDatas'] = $responses; - // echo var_export($this->_viewDatas['fieldDatas']); - // exit; - return parent::update_process($entity); + //겔제처리 + $this->_viewDatas['fieldDatas'] = array("status" => $this->_viewDatas['className']); + $entity = parent::update_process($entity); + //청구서 발행정보 + $subject = sprintf("%s %s 청구서입니다.", $entity->getTitle(), date("Y년 m월")); + $html = view( + $this->_viewPath . 'billing', + ['viewDatas' => $this->_viewDatas['fieldDatas']] + ); + //청구서 발행 + $this->billing($entity, $subject, $html); + return $entity; } } diff --git a/app/Controllers/Front/Order/Payment/PaymentController.php b/app/Controllers/Front/Order/Payment/PaymentController.php index 712f822..900218a 100644 --- a/app/Controllers/Front/Order/Payment/PaymentController.php +++ b/app/Controllers/Front/Order/Payment/PaymentController.php @@ -3,8 +3,10 @@ namespace App\Controllers\Front\Order\Payment; use App\Controllers\Front\Order\OrderController; +use App\Entities\OrderEntity; use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; +use Dompdf\Dompdf; use Psr\Log\LoggerInterface; class PaymentController extends OrderController @@ -56,4 +58,32 @@ class PaymentController extends OrderController $this->_session->setFlashdata("return_message", $msg); } } + + //청구서관련 + final protected function billing(OrderEntity $entity, string $subject, string $html) + { + //Email 발송 + $email = \Config\Services::email(); + $email->setFrom(MALLS['support'], MALLS['title'], MALLS['master']); + $email->setTo($entity->email); + $email->setCC(MALLS['master']); + $email->setSubject($subject); + $email->setMessage($html); + $email->send(); + + //PDF저장 + $dompdf = new Dompdf(); + $dompdf->loadHtml($html); + $dompdf->setPaper('A4', 'landscape'); + $dompdf->render(); + //Output the generated PDF to Browser + // $dompdf->stream(); + $filename = sprintf( + "%s/%s_%s.pdf", + PATHS['BILLING'], + $entity->getPrimaryKey(), + date("Y-m") + ); + file_put_contents($filename, $dompdf->output()); + } } diff --git a/app/Controllers/Front/UserController.php b/app/Controllers/Front/UserController.php index a20b964..87a2566 100644 --- a/app/Controllers/Front/UserController.php +++ b/app/Controllers/Front/UserController.php @@ -23,7 +23,7 @@ class UserController extends FrontController $this->initAdapters(); //Default 회원정보 Category - $this->_category = DEFAULTS['USER_CATEGORY']; + $this->_category = DEFAULTS['CATEGORY']; $this->isRole('index'); } diff --git a/app/Database/shoppingmall.sql b/app/Database/shoppingmall.sql index 6494012..20b8df1 100644 --- a/app/Database/shoppingmall.sql +++ b/app/Database/shoppingmall.sql @@ -144,7 +144,6 @@ CREATE TABLE shoppingmall.tw_order ( cost int(10) UNSIGNED NOT NULL COMMENT '구매원가', sale int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '할인가', price int(10) UNSIGNED NOT NULL COMMENT '결제액', - response text NULL COMMENT '결제처리결과', quantity varchar(255) NOT NULL COMMENT '수량', paymentday int(2) UNSIGNED NULL COMMENT '결제일', status varchar(10) NOT NULL DEFAULT 'use' COMMENT 'use: 결제하기, unuse: 주문취소, deposit:무통장입금, paid:결제완료 등등', @@ -154,4 +153,21 @@ CREATE TABLE shoppingmall.tw_order ( PRIMARY KEY (uid), CONSTRAINT FOREIGN KEY (product_uid) REFERENCES tw_product (uid), CONSTRAINT FOREIGN KEY (user_uid) REFERENCES tw_user (uid) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT ='Order 정보'; \ No newline at end of file +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT ='Order 정보'; + +DROP TABLE IF EXISTS shoppingmall.tw_billing; +CREATE TABLE shoppingmall.tw_billing ( + uid int(10) UNSIGNED NOT NULL AUTO_INCREMENT, + order_uid varchar(36) NULL COMMENT '주문 정보', + user_uid varchar(36) NULL COMMENT '사용자 정보', + title varchar(255) NOT NULL COMMENT '청구서제목', + upload_file varchar(255) NULL COMMENT 'PDF 파일명', + response text NULL COMMENT '결제처리결과', + status varchar(10) NOT NULL DEFAULT 'use' COMMENT 'use: 사용, unuse: 사용않함 등등', + updated_at timestamp NULL DEFAULT NULL, + created_at timestamp NOT NULL DEFAULT current_timestamp(), + deleted_at timestamp NULL DEFAULT NULL, + PRIMARY KEY (uid), + CONSTRAINT FOREIGN KEY (order_uid) REFERENCES tw_order (uid), + CONSTRAINT FOREIGN KEY (user_uid) REFERENCES tw_user (uid) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT ='청구서 정보'; \ No newline at end of file diff --git a/app/Entities/BillingEntity.php b/app/Entities/BillingEntity.php new file mode 100644 index 0000000..01b0d6c --- /dev/null +++ b/app/Entities/BillingEntity.php @@ -0,0 +1,30 @@ +attributes['name']; + } + //추가기능 + //파일관련 Field전용 + final public function getFileDownload($url, $field = "upload_file") + { + if (is_null($this->attributes[$field])) { + return ""; + } + return anchor( + $url, + ICONS['IMAGE_FILE'] . $this->attributes[$field], + ["target" => "_self"] + ); + } +} diff --git a/app/Helpers/Billing_helper.php b/app/Helpers/Billing_helper.php new file mode 100644 index 0000000..dc4018d --- /dev/null +++ b/app/Helpers/Billing_helper.php @@ -0,0 +1,188 @@ +%s", implode(" ", $attributes), lang("{$viewDatas['className']}.label.{$field}")); + break; + } +} +//header.php에서 getFieldForm_Helper사용 +function getFieldForm_BillingHelper($field, $value, array $viewDatas, array $attributes = array()) +{ + $value = $value ?: DEFAULTS['EMPTY']; + switch ($field) { + case 'order_uid': + case 'user_uid': + $viewDatas['fieldFormOptions'][$field] = [DEFAULTS['EMPTY'] => lang("{$viewDatas['className']}.label.{$field}") . " 선택", ...$viewDatas['fieldFormOptions'][$field]]; + return form_dropdown($field, $viewDatas['fieldFormOptions'][$field], $value, [...$attributes, 'class' => "select-field"]); + // // return form_multiselect($field, $fieldFormOptions[$field], is_array($value) ? [...$value] : [$value], [...$attributes]); + // foreach ($viewDatas['fieldFormOptions'][$field] as $key => $label) { + // $checkboxs[] = form_checkbox("{$field}[]", $key, in_array($key, explode(DEFAULTS["DELIMITER_ROLE"], $value))) . $label; + // } + // return implode(" ", $checkboxs); + break; + case 'title': + case 'name': + return form_input($field, $value, ["placeholder" => "예)", "style" => "width:60%; ::placeholder{ color:silver; opacity: 1; }"]); + break; + case 'passwd': + return sprintf( + "%s %s %s", + form_password($field, DEFAULTS['EMPTY']), + lang("{$viewDatas['className']}.label.confirmpassword"), + form_password('confirmpassword', DEFAULTS['EMPTY']), + ); + break; + case 'content': + case 'head': + case 'tail': + return form_textarea($field, html_entity_decode($value), ['class' => 'editor', 'rows' => '20', 'cols' => '100']); + break; + case 'upload_file': + case 'board_file': + return form_upload($field); + break; + case 'view_cnt': + return form_input($field, $value, ['type' => 'number']); + break; + case "status": + $viewDatas['fieldFormOptions'][$field] = [DEFAULTS['EMPTY'] => lang("{$viewDatas['className']}.label.{$field}") . " 선택", ...$viewDatas['fieldFormOptions'][$field]]; + return form_dropdown($field, $viewDatas['fieldFormOptions'][$field], $value, $attributes); + break; + case 'updated_at': + case 'created_at': + return form_input($field, $value, ['class' => 'calender']); + break; + default: + return form_input($field, $value); + break; + } +} // + +function getFieldView_BillingHelper($field, $entity, array $viewDatas) +{ + $value = $entity->$field ?: DEFAULTS['EMPTY']; + switch ($field) { + case 'cost': + case 'sale': + return number_format(!$value ? 0 : $value) . "원"; + break; + case 'price': + $price = number_format(!$value ? 0 : $value) . "원"; + $paymentday = $entity->paymentday; + return sprintf( + "%s:%s
%s", + lang("{$viewDatas['className']}.label.paymentday"), + $paymentday, + $price + ); + break; + case 'stock': + case 'view_cnt': + return number_format(!$value ? 0 : $value); + break; + case 'response': + return nl2br($value); + break; + case 'content': + return html_entity_decode($value); + break; + case 'updated_at': + case 'created_at': + return $value ? str_split($value, 10)[0] : ""; + break; + default: + return in_array($field, $viewDatas['fieldFilters']) && $value ? $viewDatas['fieldFormOptions'][$field][$value] : $value; + break; + } +} // + +function getFieldFilter_BillingHelper($field, $value, array $viewDatas) +{ + $viewDatas['fieldFormOptions'][$field] = [DEFAULTS['EMPTY'] => lang("{$viewDatas['className']}.label.{$field}") . " 선택", ...$viewDatas['fieldFormOptions'][$field]]; + return form_dropdown($field, $viewDatas['fieldFormOptions'][$field], $value, ['class' => "select-field"]); +} // + +function getFieldIndex_Column_BillingHelper($field, array $viewDatas) +{ + $label = lang("{$viewDatas['className']}.label.{$field}"); + if ($field == $viewDatas['order_field']) { + $label .= $viewDatas['order_value'] == 'ASC' ? ICONS['UP'] : ICONS['DOWN']; + } + $value = $viewDatas['order_value'] == 'DESC' ? "ASC" : "DESC"; + $viewDatas['uri']->addQuery('order_field', $field); + $viewDatas['uri']->addQuery('order_value', $value); + $columnData = anchor($viewDatas['uri'], $label); + switch ($field) { + case 'title': + case 'name': + return sprintf("%s", $columnData); + break; + default: + return sprintf("%s", $columnData); + break; + } +} // + +//Front용 +function getFieldIndex_Row_BillingHelper($field, $entity, array $viewDatas): string +{ + $value = $entity->$field ?: DEFAULTS['EMPTY']; + switch ($field) { + case 'title': + case 'name': + $uid = lang("{$viewDatas['className']}.label.uid") . ' : ' . str_split($entity->getPrimaryKey(), 4)[0] . '-xx-' . str_split($entity->getPrimaryKey(), 4)[1]; + $title = anchor( + current_url() . '/view/' . $entity->getPrimaryKey() . '?category=' . $viewDatas['category']->getPrimaryKey(), + $value, + ["target" => "_self"] + ); + return sprintf("%s
%s", $uid, $title); + break; + case 'board_file': + case 'upload_file': + return $entity->getFileDownload(base_url() . $viewDatas['control'] . '/billing', $field); + break; + default: + return getFieldView_BillingHelper($field, $entity, $viewDatas); + break; + } +} // +//Admin용 +function getFieldIndex_Row_BillingHelper_Admin($field, $entity, array $viewDatas): string +{ + $value = $entity->$field ?: DEFAULTS['EMPTY']; + switch ($field) { + case 'title': + case 'name': + $uid = lang("{$viewDatas['className']}.label.uid") . ' : ' . str_split($entity->getPrimaryKey(), 4)[0] . '-xx-' . str_split($entity->getPrimaryKey(), 4)[1]; + $title = anchor( + current_url() . '/view/' . $entity->getPrimaryKey(), + $value, + ["target" => "_self"] + ); + return sprintf("%s
%s", $uid, $title); + break; + case 'user_uid': + return getFieldView_BillingHelper($field, $entity, $viewDatas); + break; + default: + if (in_array($field, $viewDatas['fieldFilters'])) { + $attributes["onChange"] = sprintf( + 'location.href="%s/toggle/%s/%s?%s="+this.options[this.selectedIndex].value', + current_url(), + $entity->getPrimaryKey(), + $field, + $field + ); + return getFieldForm_BillingHelper($field, $entity->$field, $viewDatas, $attributes); + } + return getFieldIndex_Row_BillingHelper($field, $entity, $viewDatas); + break; + } +} // \ No newline at end of file diff --git a/app/Helpers/Order_helper.php b/app/Helpers/Order_helper.php index 4c0bc96..f47fb5e 100644 --- a/app/Helpers/Order_helper.php +++ b/app/Helpers/Order_helper.php @@ -86,9 +86,6 @@ function getFieldView_OrderHelper($field, $entity, array $viewDatas) case 'view_cnt': return number_format(!$value ? 0 : $value); break; - case 'response': - return nl2br($value); - break; case 'content': return html_entity_decode($value); break; diff --git a/app/Language/ko/Billing.php b/app/Language/ko/Billing.php new file mode 100644 index 0000000..28ee686 --- /dev/null +++ b/app/Language/ko/Billing.php @@ -0,0 +1,18 @@ + "청구서 정보", + 'label' => [ + 'uid' => "청구서번호", + 'order_uid' => "주문정보", + 'user_uid' => "사용자정보", + 'title' => "청구서명", + 'response' => "결제처리결과", + 'status' => "상태", + 'updated_at' => "수정일", + 'created_at' => "작성일" + ], + "STATUS" => [ + "use" => "사용", + "unuse" => "사용않함", + ], +]; diff --git a/app/Language/ko/Order.php b/app/Language/ko/Order.php index 9308452..849096d 100644 --- a/app/Language/ko/Order.php +++ b/app/Language/ko/Order.php @@ -11,7 +11,6 @@ return [ 'sale' => "할인", 'quantity' => "수량", 'price' => "결제금액", - 'response' => "결제처리결과", "paymentday" => "월결제일", 'status' => "상태", 'updated_at' => "수정일", diff --git a/app/Models/BaseHierarchyModel.php b/app/Models/BaseHierarchyModel.php index afc11b8..7067c06 100644 --- a/app/Models/BaseHierarchyModel.php +++ b/app/Models/BaseHierarchyModel.php @@ -37,39 +37,31 @@ abstract class BaseHierarchyModel extends BaseModel return $rules; } + private function getMax($field, $coditions = null) + { + //생성시는 해당Field의 max값을 구해서 넣는다. + $query = is_null($coditions) ? $this->selectMax($field) : $this->selectMax($field)->where($coditions); + $max = $query->get()->getResult()[0]->$field + 1; + if (!$max) { + throw new \Exception("{$field}는 {$max}의 값을 가질수 없습니다."); + } + return $max; + } final protected function create_process($entity, array $formDatas) { //생성시는 grpno의 max값을 구해서 넣는다. - $entity->grpno = $this->selectMax("grpno")->get()->getResult()[0]->grpno + 1; - if (!$entity->grpno) { - throw new \Exception("grpno는 {$entity->grpno}의 값을 가질수 없습니다."); - } + $formDatas['grpno'] = $this->getMax('grpno'); return parent::create_process($entity, $formDatas); } final protected function reply_process($parent_entity, $entity, array $formDatas) { - //부모의 그룹과 grpno가 같고, 부모의 grporder보다 1 큰것을 grporder+1을 해서 update - //escape -> false옵션 반드시 있어야함 - $this->set("grporder", "grporder+1", false); - $this->where([ - "grpno" => $parent_entity->grpno, - "grporder >" => $parent_entity->grporder - ]); - $this->update(); //reply용 설정 $entity->parent_uid = $parent_entity->getPrimaryKey(); $entity->grpno = $parent_entity->grpno; - $entity->grporder = $parent_entity->grporder + 1; + //Reply시는 grpno가 부모와 같고 grporder의 max값을 구해서 넣는다. + $entity->grporder = $this->getMax('grporder', ['grpno' => $parent_entity->grpno]); $entity->grpdepth = $parent_entity->grpdepth + 1; return parent::create_process($entity, $formDatas); } - - public function setIndexOrderBy(?string $field, ?string $order) - { - //계단식의 경우는 먼저 다른것보다 먼저 orderBy가 수행되어야 하므로 - $this->orderBy("grpno", "DESC"); - $this->orderBy("grporder", "ASC"); - parent::setIndexOrderBy($field, $order); - } } diff --git a/app/Models/BillingModel.php b/app/Models/BillingModel.php new file mode 100644 index 0000000..3fd1c47 --- /dev/null +++ b/app/Models/BillingModel.php @@ -0,0 +1,116 @@ +allowedFields = [ + ...$this->allowedFields, 'order_uid', "user_uid", + "title", "upload_file", "response", "status" + ]; + $this->validationRules = [...$this->validationRules, ...$this->getFieldRules($this->allowedFields),]; + } + final public function getTitleField(): string + { + return 'title'; + } + public function getFieldRule(string $field, array $rules, string $action = ""): array + { + switch ($field) { + case 'order_uid': + $rules[$field] = "required|regex_match[/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/]"; + break; + case $this->getTitleField(): + $rules[$field] = "required|trim|string"; + break; + case "upload_file": //uploaded[{$field}] == requried와 같은의미 + $rules[$field] = "if_exist|string"; + break; + case "response": + $rules[$field] = "required|string"; + break; + default: + $rules = parent::getFieldRule($field, $rules, $action); + break; + } + return $rules; + } + //Field별 Form Option용 + public function getFieldFormOption(string $field): array + { + switch ($field) { + case 'product_uid': + if (is_null($this->_product_options)) { + $productModel = new ProductModel(); + $this->_product_options = $productModel->getOptions(); + } + $options = $this->_product_options; + break; + default: + return parent::getFieldFormOption($field); + break; + } + if (!is_array($options)) { + throw new \Exception(__FUNCTION__ . "에서 {$this->getClassName()}의 Field:{$field}의 FormOptionData가 array가 아닙니다.\n" . var_export($options, true)); + } + return $options; + } + public function getEntity($conditions): BillingEntity + { + return parent::getEntity($conditions); + } + public function create(array $formDatas): BillingEntity + { + return $this->create_process(new BillingEntity(), $formDatas); + } + public function modify(BillingEntity $entity, array $formDatas): BillingEntity + { + return $this->modify_process($entity, $formDatas); + } + //Index관련 + public function setIndexWordFilter(string $word) + { + if ($word !== DEFAULTS['EMPTY']) { + parent::setIndexWordFilter($word); + $this->orLike($this->getTitleField(), $word, "both"); + } + } + + //장바구니에 넣기() + final public function addCart(ProductEntity $entity, int $quantity, $paymentDay = null): BillingEntity + { + $formDatas = []; + $formDatas['product_uid'] = $entity->getPrimaryKey(); + //상품명을 복사해서 구매한 상품명에 넣기 + $formDatas[$this->getTitleField()] = $entity->getTitle(); + $formDatas['cost'] = $entity->price; + $formDatas['sale'] = 0; + $formDatas['quantity'] = $quantity; + $formDatas['price'] = $formDatas['cost'] * $formDatas['quantity']; + if (!is_null($paymentDay)) { + $formDatas['paymentday'] = $paymentDay; + } + return $this->create($formDatas); + } + //장바구니에 빼기 + public function cancelCart(BillingEntity $entity) + { + $formDatas = array(); + //장바구니인경우에만 + if ($entity->status == DEFAULTS['STATUS']) { + $formDatas['status'] = 'unuse'; + } + return $this->modify($entity, $formDatas); + } +} diff --git a/app/Models/BoardModel.php b/app/Models/BoardModel.php index dceda43..eb6fc13 100644 --- a/app/Models/BoardModel.php +++ b/app/Models/BoardModel.php @@ -98,6 +98,14 @@ class BoardModel extends BaseHierarchyModel } } + public function setIndexOrderBy(?string $field, ?string $order) + { + //계단식의 경우는 먼저 다른것보다 먼저 orderBy가 수행되어야 하므로 + $this->orderBy("grpno", "DESC"); + $this->orderBy("grporder", "DESC"); + parent::setIndexOrderBy($field, $order); + } + //조회수 올리기 final public function addViewCount(BoardEntity $entity, int $view_cnt = 1): BoardEntity { diff --git a/app/Models/CategoryModel.php b/app/Models/CategoryModel.php index 1c8bc88..8853745 100644 --- a/app/Models/CategoryModel.php +++ b/app/Models/CategoryModel.php @@ -102,7 +102,10 @@ class CategoryModel extends BaseHierarchyModel } public function getEntitys(array $conditions = array()): array { - return $this->where($conditions)->orderby("grpno DESC, grporder ASC")->findAll(); + $this->where($conditions); + $this->orderBy("grpno", "DESC"); + $this->orderBy("grporder", "ASC"); + return $this->findAll(); } public function create(array $formDatas): CategoryEntity { @@ -125,4 +128,11 @@ class CategoryModel extends BaseHierarchyModel $this->orLike("head", $word, "both"); //befor , after , both $this->orLike("tail", $word, "both"); //befor , after , both } + public function setIndexOrderBy(?string $field, ?string $order) + { + //계단식의 경우는 먼저 다른것보다 먼저 orderBy가 수행되어야 하므로 + $this->orderBy("grpno", "DESC"); + $this->orderBy("grporder", "ASC"); + parent::setIndexOrderBy($field, $order); + } } diff --git a/app/Models/OrderModel.php b/app/Models/OrderModel.php index 821b20d..79339a0 100644 --- a/app/Models/OrderModel.php +++ b/app/Models/OrderModel.php @@ -17,7 +17,7 @@ class OrderModel extends BaseModel parent::__construct('Order'); $this->allowedFields = [ ...$this->allowedFields, 'product_uid', "user_uid", - "name", "cost", "sale", "quantity", "price", "response", + "name", "cost", "sale", "quantity", "price", "paymentday", "status" ]; $this->validationRules = [...$this->validationRules, ...$this->getFieldRules($this->allowedFields),]; diff --git a/app/Views/admin/billing/index.php b/app/Views/admin/billing/index.php new file mode 100644 index 0000000..feb021e --- /dev/null +++ b/app/Views/admin/billing/index.php @@ -0,0 +1,48 @@ +extend('layouts/admin') ?> +section('content') ?> + +
+
+ + include('templates/admin/index_head') ?> +
+ + + + + + + + + + + + + status != DEFAULTS['STATUS'] ? 'class="table-danger" rowcolor="red"' : 'rowcolor="red"' ?> onClick="indexRowCheckBoxToggle(this)"> + + + + + + + + + +
#@
+ "checkbox_uid_{$entity->getPrimaryKey()}", "name" => "batchjob_uids[]", "value" => $entity->getPrimaryKey(), "class" => "batchjobuids_checkboxs"]); ?> + getPrimaryKey(), $viewDatas['total_count'] - (($viewDatas['page'] - 1) * $viewDatas['per_page'] + $cnt), ["target" => "_self"]) ?> + getPrimaryKey(), ICONS['DELETE'], ["class" => "btn btn-sm btn-danger btn-circle", "target" => "_self"]) ?>
+
+ + +
+ +
+endSection() ?> \ No newline at end of file diff --git a/app/Views/front/billing/index.php b/app/Views/front/billing/index.php new file mode 100644 index 0000000..8fb38d9 --- /dev/null +++ b/app/Views/front/billing/index.php @@ -0,0 +1,37 @@ +extend('layouts/front') ?> +section('content') ?> + +
+
head) ?>
+
include('templates/front/index_head') ?>
+ + + + + + + + + + + + status != DEFAULTS['STATUS'] ? 'class="table-danger" rowcolor="red"' : 'rowcolor="red"' ?> onClick="indexRowCheckBoxToggle(this)"> + + + + + + + + +
#
+ + +
+
+ +
+ +
tail) ?>
+
+endSection() ?> \ No newline at end of file diff --git a/app/Views/front/order/deposit/billing.php b/app/Views/front/order/deposit/billing.php new file mode 100644 index 0000000..b3ff1f9 --- /dev/null +++ b/app/Views/front/order/deposit/billing.php @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + +
상품명getTitle() ?>
결제금액price) ?>원
은행명
계좌번호
예금주
\ No newline at end of file diff --git a/app/Views/layouts/front/left_menu/leftmenu_11.php b/app/Views/layouts/front/left_menu/leftmenu_11.php index bfe7343..3f3b857 100644 --- a/app/Views/layouts/front/left_menu/leftmenu_11.php +++ b/app/Views/layouts/front/left_menu/leftmenu_11.php @@ -1,13 +1,16 @@ - +
-
개인정보
+
+ 사용자정보 +
주문정보
- 사용자정보 + 청구서정보
- + diff --git a/app/Views/layouts/front/left_menu/leftmenu_14.php b/app/Views/layouts/front/left_menu/leftmenu_14.php index 3b85c56..6565a6b 100644 --- a/app/Views/layouts/front/left_menu/leftmenu_14.php +++ b/app/Views/layouts/front/left_menu/leftmenu_14.php @@ -1,4 +1,4 @@ - +
-
AboutUS
@@ -10,4 +10,4 @@ 회사소개
- + diff --git a/app/Views/layouts/front/left_menu/leftmenu_15.php b/app/Views/layouts/front/left_menu/leftmenu_15.php index 374eb58..381c301 100644 --- a/app/Views/layouts/front/left_menu/leftmenu_15.php +++ b/app/Views/layouts/front/left_menu/leftmenu_15.php @@ -1,4 +1,4 @@ - +
-
AboutUS
@@ -10,4 +10,4 @@ 회사소개
- + diff --git a/app/Views/layouts/front/left_menu/leftmenu_17.php b/app/Views/layouts/front/left_menu/leftmenu_17.php index 1979e81..bfa240c 100644 --- a/app/Views/layouts/front/left_menu/leftmenu_17.php +++ b/app/Views/layouts/front/left_menu/leftmenu_17.php @@ -1,4 +1,4 @@ - +
-
Hosting
@@ -10,4 +10,4 @@ 신청절차
- + diff --git a/app/Views/layouts/front/left_menu/leftmenu_18.php b/app/Views/layouts/front/left_menu/leftmenu_18.php index 1b0ecfa..9e129b1 100644 --- a/app/Views/layouts/front/left_menu/leftmenu_18.php +++ b/app/Views/layouts/front/left_menu/leftmenu_18.php @@ -1,4 +1,4 @@ - +
-
Hosting
@@ -10,4 +10,4 @@ 신청절차
- + diff --git a/app/Views/layouts/front/left_menu/leftmenu_20.php b/app/Views/layouts/front/left_menu/leftmenu_20.php index b42e263..7685ced 100644 --- a/app/Views/layouts/front/left_menu/leftmenu_20.php +++ b/app/Views/layouts/front/left_menu/leftmenu_20.php @@ -1,13 +1,13 @@ - +
-
Service
-
- 기타서비스 -
회선서비스
+
+ 기타서비스 +
- + diff --git a/app/Views/layouts/front/left_menu/leftmenu_21.php b/app/Views/layouts/front/left_menu/leftmenu_21.php index d765366..5ddf997 100644 --- a/app/Views/layouts/front/left_menu/leftmenu_21.php +++ b/app/Views/layouts/front/left_menu/leftmenu_21.php @@ -1,13 +1,13 @@ - +
-
Service
-
- 기타서비스 -
회선서비스
+
+ 기타서비스 +
- + diff --git a/app/Views/layouts/front/left_menu/leftmenu_22.php b/app/Views/layouts/front/left_menu/leftmenu_22.php index 23ef48a..4d04d4a 100644 --- a/app/Views/layouts/front/left_menu/leftmenu_22.php +++ b/app/Views/layouts/front/left_menu/leftmenu_22.php @@ -1,13 +1,16 @@ - +
-
개인정보
-
- 주문정보 -
사용자정보
+
+ 주문정보 +
+
+ 청구서정보 +
- + diff --git a/app/Views/layouts/front/left_menu/leftmenu_24.php b/app/Views/layouts/front/left_menu/leftmenu_24.php new file mode 100644 index 0000000..29dd6cd --- /dev/null +++ b/app/Views/layouts/front/left_menu/leftmenu_24.php @@ -0,0 +1,16 @@ + +
+
-
+
컴퓨터주변기기 구매대행
+
+
+ CPU +
+
+ Memory +
+
+ HDD(SSD) +
+ + diff --git a/app/Views/layouts/front/left_menu/leftmenu_25.php b/app/Views/layouts/front/left_menu/leftmenu_25.php new file mode 100644 index 0000000..74f51c4 --- /dev/null +++ b/app/Views/layouts/front/left_menu/leftmenu_25.php @@ -0,0 +1,16 @@ + +
+
-
+
컴퓨터주변기기 구매대행
+
+
+ CPU +
+
+ Memory +
+
+ HDD(SSD) +
+ + diff --git a/app/Views/layouts/front/left_menu/leftmenu_26.php b/app/Views/layouts/front/left_menu/leftmenu_26.php new file mode 100644 index 0000000..2270868 --- /dev/null +++ b/app/Views/layouts/front/left_menu/leftmenu_26.php @@ -0,0 +1,16 @@ + +
+
-
+
컴퓨터주변기기 구매대행
+
+
+ CPU +
+
+ Memory +
+
+ HDD(SSD) +
+ + diff --git a/app/Views/layouts/front/left_menu/leftmenu_12.php b/app/Views/layouts/front/left_menu/leftmenu_28.php similarity index 62% rename from app/Views/layouts/front/left_menu/leftmenu_12.php rename to app/Views/layouts/front/left_menu/leftmenu_28.php index 7376c87..c936f6b 100644 --- a/app/Views/layouts/front/left_menu/leftmenu_12.php +++ b/app/Views/layouts/front/left_menu/leftmenu_28.php @@ -1,16 +1,16 @@ - +
-
개인정보
+
+ 사용자정보 +
주문정보
- 결제정보 -
-
- 사용자정보 + 청구서정보
- + diff --git a/app/Views/layouts/front/left_menu/leftmenu_3.php b/app/Views/layouts/front/left_menu/leftmenu_3.php index bc1284b..666310e 100644 --- a/app/Views/layouts/front/left_menu/leftmenu_3.php +++ b/app/Views/layouts/front/left_menu/leftmenu_3.php @@ -1,4 +1,4 @@ - +
-
Support
@@ -10,4 +10,4 @@ 자료실
- + diff --git a/app/Views/layouts/front/left_menu/leftmenu_4.php b/app/Views/layouts/front/left_menu/leftmenu_4.php index 30ca7f8..5c4959b 100644 --- a/app/Views/layouts/front/left_menu/leftmenu_4.php +++ b/app/Views/layouts/front/left_menu/leftmenu_4.php @@ -1,4 +1,4 @@ - +
-
Support
@@ -10,4 +10,4 @@ 자료실
- + diff --git a/app/Views/layouts/front/left_menu/leftmenu_5.php b/app/Views/layouts/front/left_menu/leftmenu_5.php index c51e5c0..1448b5e 100644 --- a/app/Views/layouts/front/left_menu/leftmenu_5.php +++ b/app/Views/layouts/front/left_menu/leftmenu_5.php @@ -1,7 +1,7 @@ - +
-
-
네트워크
+
네트워크 구매대행
월이용권 @@ -10,4 +10,4 @@ 판매
- + diff --git a/app/Views/layouts/front/left_menu/leftmenu_6.php b/app/Views/layouts/front/left_menu/leftmenu_6.php index 8fd3f48..90deb4f 100644 --- a/app/Views/layouts/front/left_menu/leftmenu_6.php +++ b/app/Views/layouts/front/left_menu/leftmenu_6.php @@ -1,7 +1,7 @@ - +
-
-
네트워크
+
네트워크 구매대행
월이용권 @@ -10,4 +10,4 @@ 판매
- + diff --git a/app/Views/layouts/front/left_menu/leftmenu_8.php b/app/Views/layouts/front/left_menu/leftmenu_8.php index 1f955ee..29bc5de 100644 --- a/app/Views/layouts/front/left_menu/leftmenu_8.php +++ b/app/Views/layouts/front/left_menu/leftmenu_8.php @@ -1,7 +1,7 @@ - +
-
-
서버
+
서버 구매대행
월이용권 @@ -10,4 +10,4 @@ 판매
- + diff --git a/app/Views/layouts/front/left_menu/leftmenu_9.php b/app/Views/layouts/front/left_menu/leftmenu_9.php index 0261bb8..e8df4f4 100644 --- a/app/Views/layouts/front/left_menu/leftmenu_9.php +++ b/app/Views/layouts/front/left_menu/leftmenu_9.php @@ -1,7 +1,7 @@ - +
-
-
서버
+
서버 구매대행
월이용권 @@ -10,4 +10,4 @@ 판매
- + diff --git a/app/Views/layouts/front/top_menu/top_menu_aboutus.php b/app/Views/layouts/front/top_menu/top_menu_aboutus.php index 292c240..a933ac3 100644 --- a/app/Views/layouts/front/top_menu/top_menu_aboutus.php +++ b/app/Views/layouts/front/top_menu/top_menu_aboutus.php @@ -5,7 +5,7 @@ About US diff --git a/app/Views/layouts/front/top_menu/top_menu_hosting.php b/app/Views/layouts/front/top_menu/top_menu_hosting.php index d2b5f18..a367256 100644 --- a/app/Views/layouts/front/top_menu/top_menu_hosting.php +++ b/app/Views/layouts/front/top_menu/top_menu_hosting.php @@ -5,7 +5,7 @@ Hosting diff --git a/app/Views/layouts/front/top_menu/top_menu_service.php b/app/Views/layouts/front/top_menu/top_menu_service.php index 543b62e..e05cfb3 100644 --- a/app/Views/layouts/front/top_menu/top_menu_service.php +++ b/app/Views/layouts/front/top_menu/top_menu_service.php @@ -5,8 +5,8 @@ Service diff --git a/composer.json b/composer.json index 3addc0e..c70711c 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,8 @@ "twbs/bootstrap": "5.2.3", "guzzlehttp/guzzle": "^7.7", "google/apiclient": "2.12.1", - "tinymce/tinymce": "^6.6" + "tinymce/tinymce": "^6.6", + "dompdf/dompdf": "^2.0" }, "require-dev": { "fakerphp/faker": "^1.9", diff --git a/public/css/front/billing.css b/public/css/front/billing.css new file mode 100644 index 0000000..b796a9d --- /dev/null +++ b/public/css/front/billing.css @@ -0,0 +1,18 @@ +/* ------------------------------------------------------------ +* Name : admin.css +* Desc : Admin StyleSheet +* Created : 2016/9/11 Tri-aBility by Junheum,Choi +* Updated : +------------------------------------------------------------ */ +table#billing td { + text-align: center; + color:white; + padding-right:5px; + /* border: 1px solid blue; */ +} +table#billing td { + height: 27px; +} +table#billing td.label { + width: 15%; +} \ No newline at end of file