diff --git a/app/Controllers/EcommerceController.php b/app/Controllers/EcommerceController.php index 0a42e36..5855cab 100644 --- a/app/Controllers/EcommerceController.php +++ b/app/Controllers/EcommerceController.php @@ -2,7 +2,9 @@ namespace App\Controllers; +use App\Entities\PaymentEntity; use App\Models\OrderModel; +use App\Models\PaymentModel; use App\Models\ProductModel; use CodeIgniter\Controller; use CodeIgniter\HTTP\CLIRequest; @@ -42,6 +44,7 @@ class EcommerceController extends Controller private $_viewDatas = array(); private $_orderModel = null; private $_productModel = null; + private $_paymentModel = null; public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger) { parent::initController($request, $response, $logger); @@ -57,8 +60,12 @@ class EcommerceController extends Controller { return $this->_productModel = $this->_productModel ?: new ProductModel(); } + private function getPaymentModel() + { + return $this->_paymentModel = $this->_paymentModel ?: new PaymentModel(); + } - //주문 + //주문정보 확인 private function addCart_validate() { //fieldData Rule 검사 @@ -72,6 +79,7 @@ class EcommerceController extends Controller } } + //주문(장바구니담기) public function addCart() { $msg = ""; @@ -129,7 +137,7 @@ class EcommerceController extends Controller } } - //주문취소 + //주문취소(uid -> order_uid) public function cancelCart($uid) { $msg = ""; @@ -175,4 +183,39 @@ class EcommerceController extends Controller $this->_session->setFlashdata("return_message", $msg); } } + + //결제(uid -> order_uid) + public function payment($uid) + { + $msg = ""; + try { + $this->_viewDatas['fields'] = ["product_uid", "quantity", "price"]; + $this->_viewDatas['fieldRules'] = $this->getOrderModel()->getFieldRules($this->_viewDatas['fields']); + //Transaction 시작 + $this->getOrderModel()->transStart(); + //Transaction Commit + $this->getOrderModel()->transComplete(); + $entity = new PaymentEntity(); + $msg = sprintf( + "%s\n 상품명:%s\n 상품갯수:%s개, 구매금액:%s원\n 장바구니에 담았습니다.", + $this->_viewDatas['title'], + $entity->getTitle(), + $entity->quantity, + number_format($entity->price) + ); + return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL'])); + } catch (\Exception $e) { + //Transaction Rollback + $this->getOrderModel()->transRollback(); + log_message("error", $e->getMessage()); + $msg = sprintf( + "%s에서 다음 오류로 인해 장바구니에 담기를 실패하였습니다.\n%s", + $this->_viewDatas['title'], + $e->getMessage() + ); + return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL'])); + } finally { + $this->_session->setFlashdata("return_message", $msg); + } + } } diff --git a/app/Database/shoppingmall.sql b/app/Database/shoppingmall.sql index 5555589..43c58ad 100644 --- a/app/Database/shoppingmall.sql +++ b/app/Database/shoppingmall.sql @@ -146,11 +146,35 @@ CREATE TABLE shoppingmall.tw_order ( sale int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '할인가', price int(10) UNSIGNED NOT NULL COMMENT '결제액', quantity varchar(255) NOT NULL COMMENT '수량', - status varchar(10) NOT NULL DEFAULT 'use' COMMENT 'use: 주문대기, unuse: 사용않함 등등', + status varchar(10) NOT NULL DEFAULT 'use' COMMENT 'use: 결제하기, unuse: 주문취소, paid:결제완료 등등', 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 (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_payment; +CREATE TABLE shoppingmall.tw_payment ( + uid int(10) UNSIGNED NOT NULL AUTO_INCREMENT, + TID varchar(20) NOT NULL COMMENT 'PG사 결제 거래고유번호 (전표출력 및 결제취소에 사용됩니다)' + ORDERNO varchar(50) NOT NULL COMMENT '주문번호', + AMOUNT int(10) UNSIGNED NOT NULL COMMENT '결제 된 금액', + QUOTA varchar(2) NOT NULL COMMENT '카드 할부결제시 할부기간 (00:일시불, 01:1개월)', + ACCEPTNO varchar(10) NOT NULL COMMENT '승인번호', + ACCEPTDATE varchar(20) NOT NULL COMMENT '승인일시', + RESULTCODE varchar(4) NOT NULL COMMENT '결제결과코드', + RESULTMSG varchar(100) NOT NULL COMMENT '결제결과메세지', + ETC1 varchar(100) NULL COMMENT '결제 요청시 입력한 값', + ETC2 varchar(100) NULL COMMENT '결제 요청시 입력한 값', + ETC3 varchar(100) NULL COMMENT '결제 요청시 입력한 값', + ETC4 varchar(100) NULL COMMENT '결제 요청시 입력한 값', + ETC5 varchar(100) NULL COMMENT '결제 요청시 입력한 값', + updated_at timestamp NULL DEFAULT NULL, + created_at timestamp NOT NULL DEFAULT current_timestamp(), + deleted_at timestamp NULL DEFAULT NULL, + PRIMARY KEY (uid), + UNIQUE KEY (tid), + CONSTRAINT FOREIGN KEY (orderno) REFERENCES tw_order (uid) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT ='Payment 정보'; \ No newline at end of file diff --git a/app/Entities/PaymentEntity.php b/app/Entities/PaymentEntity.php new file mode 100644 index 0000000..17691b3 --- /dev/null +++ b/app/Entities/PaymentEntity.php @@ -0,0 +1,19 @@ +attributes['buyername']; + } + //추가기능 + +} diff --git a/app/Helpers/Order_helper.php b/app/Helpers/Order_helper.php index 792156d..affa005 100644 --- a/app/Helpers/Order_helper.php +++ b/app/Helpers/Order_helper.php @@ -71,6 +71,8 @@ function getFieldView_OrderHelper($field, $entity, array $viewDatas) case 'cost': case 'price': case 'sale': + return number_format(!$value ? 0 : $value) . "원"; + break; case 'stock': case 'view_cnt': return number_format(!$value ? 0 : $value); @@ -120,6 +122,17 @@ function getFieldIndex_Row_OrderHelper($field, $entity, array $viewDatas): strin ) ); break; + case 'status': + if ($value == DEFAULTS['STATUS']) { + return anchor( + '/front/ecommerce/payment' . $entity->getPrimaryKey(), + $viewDatas['fieldFormOptions'][$field][$value], + ["class" => "btn btn-sm btn-primary btn-circle", "style" => "color:white", "target" => "_self"] + ); + } else { + return getFieldView_OrderHelper($field, $entity, $viewDatas); + } + break; default: return getFieldView_OrderHelper($field, $entity, $viewDatas); break; diff --git a/app/Helpers/Product_helper.php b/app/Helpers/Product_helper.php index 0e1d6ed..5a83d97 100644 --- a/app/Helpers/Product_helper.php +++ b/app/Helpers/Product_helper.php @@ -89,6 +89,8 @@ function getFieldView_ProductHelper($field, $entity, array $viewDatas) case 'cost': case 'price': case 'sale': + return number_format(!$value ? 0 : $value) . "원"; + break; case 'stock': case 'view_cnt': return number_format(!$value ? 0 : $value); diff --git a/app/Language/ko/Order.php b/app/Language/ko/Order.php index 589a989..6a8b695 100644 --- a/app/Language/ko/Order.php +++ b/app/Language/ko/Order.php @@ -16,9 +16,8 @@ return [ 'created_at' => "작성일" ], "STATUS" => [ - "use" => "장바구니", + "use" => "결제하기", "unuse" => "주문취소", - "confirm" => "주문완료", "paid" => "결제완료" ] ]; diff --git a/app/Models/PaymentModel.php b/app/Models/PaymentModel.php new file mode 100644 index 0000000..e196701 --- /dev/null +++ b/app/Models/PaymentModel.php @@ -0,0 +1,106 @@ +allowedFields = [...$this->allowedFields, 'product_uid', "user_uid", "name", "cost", "sale", "quantity", "price", "status"]; + $this->validationRules = [...$this->validationRules, ...$this->getFieldRules($this->allowedFields),]; + } + final public function getTitleField(): string + { + return 'name'; + } + protected function getFieldRule(string $field, array $rules, string $action = ""): array + { + switch ($field) { + case 'product_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 'cost': + case 'quantity': + case 'price': + $rules[$field] = "required|numeric"; + break; + case 'sale': + $rules[$field] = "if_exist|numeric"; + 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): PaymentEntity + { + return parent::getEntity($conditions); + } + public function create(array $formDatas): PaymentEntity + { + return $this->create_process(new PaymentEntity(), $formDatas); + } + public function modify(PaymentEntity $entity, array $formDatas): PaymentEntity + { + 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"); + } + } + + //장바구니에 넣기 + public function addCart(array $formDatas): PaymentEntity + { + $orderFormDatas = []; + $orderFormDatas[$this->getTitleField()] = $formDatas[$this->getTitleField()]; + $orderFormDatas['product_uid'] = $formDatas['product_uid']; + $orderFormDatas['cost'] = $formDatas['price']; + $orderFormDatas['sale'] = 0; + $orderFormDatas['quantity'] = $formDatas['quantity']; + $orderFormDatas['price'] = ($orderFormDatas['cost'] - $orderFormDatas['sale']) * $orderFormDatas['quantity']; + // echo var_export($orderFormDatas); + // exit; + return $this->create_process(new PaymentEntity(), $orderFormDatas); + } + //장바구니에 빼기 + public function cancelCart(PaymentEntity $entity) + { + return $this->delete($entity->getPrimaryKey()); + } +}