shoppingmallv2 init...

This commit is contained in:
최준흠 2023-08-14 11:32:36 +09:00
parent 3e55c62922
commit db0d7e6a09
14 changed files with 185 additions and 123 deletions

View File

@ -24,7 +24,7 @@ class OrderController extends AdminController
{
switch ($action) {
case 'update':
return ['product_uid', "cost", "sale", "quantity", "status"];
return ['product_uid', "paymentday", "cost", "sale", "quantity", "status"];
break;
case "index":
case "excel":
@ -40,7 +40,7 @@ class OrderController extends AdminController
}
final public function getFieldFilters(): array
{
return ["user_uid", 'product_uid', "status"];
return ["user_uid", 'product_uid', "status"];
}
final public function getFieldBatchFilters(): array
{

View File

@ -2,14 +2,14 @@
namespace App\Controllers\Front\Order;
use App\Entities\OrderEntity;
use App\Entities\ProductEntity;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
use App\Models\ProductModel;
class CartController extends OrderController
{
private $_productModel = null;
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
parent::initController($request, $response, $logger);
@ -20,17 +20,11 @@ class CartController extends OrderController
helper($this->_viewDatas['className']);
}
final protected function getProductModel()
{
return $this->_productModel = $this->_productModel ?: new ProductModel();
}
public function getFields(string $action = ""): array
{
switch ($action) {
case 'insert':
return ["product_uid", "quantity", "price"];
return $this->_product->type == DEFAULTS['STATUS'] ? ["product_uid", "quantity", "price", 'paymentday'] : ["product_uid", "quantity", "price"];
break;
default:
return [];
@ -47,6 +41,9 @@ class CartController extends OrderController
case 'price':
$rules[$field] = "required|numeric";
break;
case 'paymentday':
$rules[$field] = $this->_product->type == DEFAULTS['STATUS'] ? "required|numeric" : "if_exist|numeric";
break;
default:
$rules = parent::getFieldRule($field, $rules, $action);
break;
@ -62,53 +59,39 @@ class CartController extends OrderController
return parent::getFieldBatchFilters();
}
protected function insert_process()
{
//addCart용 데이터 재처리 작업
$orderFormDatas = [];
$orderFormDatas[$this->_model->getTitleField()] = $this->_viewDatas['fieldDatas'][$this->_model->getTitleField()];
$orderFormDatas['product_uid'] = $this->_viewDatas['fieldDatas']['product_uid'];
$orderFormDatas['cost'] = $this->_viewDatas['fieldDatas']['price'];
$orderFormDatas['sale'] = 0;
$orderFormDatas['quantity'] = $this->_viewDatas['fieldDatas']['quantity'];
$orderFormDatas['price'] = $orderFormDatas['cost'] * $orderFormDatas['quantity'];
$this->_viewDatas['fieldDatas'] = $orderFormDatas;
// echo var_export($this->_viewDatas['fieldDatas']);
// exit;
return parent::insert_process();
}
//주문(uid->product_uid)
//insert관련
public function insert()
{
$msg = "";
try {
//상품정보가져오기
$product = $this->getProductModel()->getEntity([$this->getProductModel()->getPrimaryKey() => $this->_viewDatas['fieldDatas']['product_uid']]);
$this->_viewDatas = $this->init(__FUNCTION__);
//장바구니정보 검증
$this->insert_validate();
//상품정보 가져오기
$product = $this->getProductModel()->getEntity([$this->getProductModel()->getPrimaryKey() => $this->_viewDatas['fieldDatas']['product_uid']]);
//재고수 비교
if ($product->stock < $this->_viewDatas['fieldDatas']['quantity']) {
throw new \Exception("구매수량이 너무 많습니다.\n구매수량:{$this->_viewDatas['fieldDatas']['quantity']}개, 남은 재고수량:{$product->stock}");
throw new \Exception("구매수량이 너무 많습니다.\n구매수량:{$this->_viewDatas['fieldDatas']['quantity']}개, 남은 재고수량:{$entity->stock}");
}
//구매 금액 비교
$price = $product->price * $this->_viewDatas['fieldDatas']['quantity'];
if ($price != $this->_viewDatas['fieldDatas']['price']) {
throw new \Exception("실 상품금액{$price} 와 구매금액{$this->_viewDatas['fieldDatas']['price']}이 서로 다릅니다.");
}
//상품명을 복사해서 구매한 상품명에 넣기
$this->_viewDatas['fieldDatas'][$this->_model->getTitleField()] = $product->getTitle();
//결제방식이 월이용권이면 결제일 확인
$paymentDay = null;
if ($product->category_uid == DEFAULTS['STATUS']) {
$paymentDay = $this->request->getVar('paymentday') ?: throw new \Exception("월이용권 상품의 경우는 매월 결제일을 지정해주셔야합니다.");
}
//Transaction 시작
$this->_model->transStart();
//주문추가
$entity = $this->insert_process();
$order = $this->_model->addCart($product, $this->_viewDatas['fieldDatas']['quantity'], $paymentDay);
//상품재고감소
$product = $this->getProductModel()->addCart($product, $this->_viewDatas['fieldDatas']['quantity']);
$entity = $this->getProductModel()->addCart($product, $this->_viewDatas['fieldDatas']['quantity']);
//주문정보 세션에 넣기
$order_uids = $this->_session->get(SESSION_NAMES['CART']) ?: array();
$this->_session->set(SESSION_NAMES['CART'], [...$order_uids, $entity->getPrimaryKey()]);
$this->_session->set(SESSION_NAMES['CART'], [...$order_uids, $order->getPrimaryKey()]);
//Transaction Commit
$this->_model->transComplete();
$msg = sprintf(
@ -142,15 +125,15 @@ class CartController extends OrderController
$msg = "";
try {
//주문정보 가져오기
$entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]);
$entity = $this->getProductModel()->getEntity([$this->getProductModel()->getPrimaryKey() => $uid]);
//상품정보 가져오기
$product = $this->getProductModel()->getEntity([$this->getProductModel()->getPrimaryKey() => $entity->product_uid]);
$entity = $this->getProductModel()->getEntity([$this->getProductModel()->getPrimaryKey() => $entity->product_uid]);
//Transaction 시작
$this->_model->transStart();
$this->getProductModel()->transStart();
//주문취소
$entity = $this->_model->modify($entity, ['status' => 'unuse']);
$entity = $this->getProductModel()->modify($entity, ['status' => 'unuse']);
//상품반환
$product = $this->getProductModel()->cancelCart($product, $entity->quantity);
$entity = $this->getProductModel()->cancelCart($entity, $entity->quantity);
//주문정보 세션에서 빼기
$order_uids = $this->_session->get(SESSION_NAMES['CART']) ?: array();
$temps = array();
@ -161,12 +144,12 @@ class CartController extends OrderController
}
$this->_session->set(SESSION_NAMES['CART'], $temps);
//Transaction Commit
$this->_model->transComplete();
$this->getProductModel()->transComplete();
$msg = "{$this->_viewDatas['title']}에서 {$entity->getTitle()} {$entity->quantity}개의 주문을 취소하였습니다.";
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']));
} catch (\Exception $e) {
//Transaction Rollback
$this->_model->transRollback();
$this->getProductModel()->transRollback();
$msg = sprintf(
"%s에서 다음 오류로 인해 주문취소를 실패하였습니다.\n%s",
$this->_viewDatas['title'],

View File

@ -2,16 +2,19 @@
namespace App\Controllers\Front\Order;
use App\Controllers\Front\FrontController;
use App\Models\OrderModel;
use App\Models\ProductModel;
use App\Models\UserModel;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
use App\Controllers\Front\FrontController;
use App\Models\UserModel;
class OrderController extends FrontController
{
private $_userModel = null;
private $_productModel = null;
protected $_product = null;
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
parent::initController($request, $response, $logger);
@ -31,10 +34,13 @@ class OrderController extends FrontController
{
return $this->_userModel = $this->_userModel ?: new UserModel();
}
final protected function getProductModel()
{
return $this->_productModel = $this->_productModel ?: new ProductModel();
}
public function getFields(string $action = ""): array
{
$fields = ["product_uid", "cost", "sale", "quantity", "price", "status"];
switch ($action) {
case "index":
case "excel":
@ -44,60 +50,19 @@ class OrderController extends FrontController
return ['name', "cost", "sale", "quantity", "price", "status", "updated_at", "created_at"];
break;
default:
return $fields;
return [];
break;
}
}
public function getFieldFilters(): array
{
return ['product_uid', "status"];
return ['product_uid', "type", "status"];
}
public function getFieldBatchFilters(): array
{
return ["status"];
}
//Update관련 (결제처리용)
protected function update_form_process($entity)
{
$entity = parent::update_form_process($entity);
$this->_viewDatas['user'] = $this->getUserModel()->getEntity([$this->getUserModel()->getPrimaryKey() => $this->_viewDatas['auth'][AUTH_FIELDS['ID']]]);
return $entity;
}
final public function update_form($uid)
{
try {
$this->_viewDatas = $this->init(__FUNCTION__);
$entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]);
$this->_viewDatas['entity'] = $this->update_form_process($entity);
helper(['form']);
$this->_session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
return view($this->_viewPath . '/update', ['viewDatas' => $this->_viewDatas]);
} catch (\Exception $e) {
log_message("error", $e->getMessage());
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/")->with('return_message', $e->getMessage());
}
}
public function update($uid)
{
$msg = "";
try {
$this->_viewDatas = $this->init(__FUNCTION__);
$entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]);
$this->update_validate($entity);
$entity = $this->update_process($entity);
$msg = "{$this->_viewDatas['title']}에서 {$entity->getTitle()}의 결제가 완료하였습니다.";
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/");
} catch (\Exception $e) {
$msg = "{$this->_viewDatas['title']}에서 결제를 실패하였습니다.\n" . $e->getMessage();
log_message("error", $e->getMessage());
$this->_session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
return redirect()->back()->withInput();
} finally {
$this->_session->setFlashdata("return_message", $msg);
}
}
//View관련
protected function view_process($entity)
{

View File

@ -1,13 +1,13 @@
<?php
namespace App\Controllers\Front\Order;
namespace App\Controllers\Front\Order\Payment;
use App\Libraries\Adapter\Payment\CookiePayment as PaymentAdapter;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
class CardController extends OrderController
class CardController extends PaymentController
{
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{

View File

@ -1,12 +1,12 @@
<?php
namespace App\Controllers\Front\Order;
namespace App\Controllers\Front\Order\Payment;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
class DepositController extends OrderController
class DepositController extends PaymentController
{
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{

View File

@ -0,0 +1,63 @@
<?php
namespace App\Controllers\Front\Order\Payment;
use App\Controllers\Front\Order\OrderController;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
abstract class PaymentController extends OrderController
{
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
parent::initController($request, $response, $logger);
}
abstract public function getFields(string $action = ""): array;
abstract public function getFieldFilters(): array;
abstract public function getFieldBatchFilters(): array;
//Update관련 (결제처리용)
protected function update_form_process($entity)
{
$entity = parent::update_form_process($entity);
$this->_viewDatas['user'] = $this->getUserModel()->getEntity([$this->getUserModel()->getPrimaryKey() => $this->_viewDatas['auth'][AUTH_FIELDS['ID']]]);
return $entity;
}
final public function update_form($uid)
{
try {
$entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]);
$this->_product = $this->getProductModel()->getEntity([$this->_model->getPrimaryKey() => $entity->product_uid]);
$this->_viewDatas = $this->init(__FUNCTION__);
$this->_viewDatas['entity'] = $this->update_form_process($entity);
helper(['form']);
$this->_session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
return view($this->_viewPath . '/update', ['viewDatas' => $this->_viewDatas]);
} catch (\Exception $e) {
log_message("error", $e->getMessage());
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/")->with('return_message', $e->getMessage());
}
}
final public function update($uid)
{
$msg = "";
try {
$entity = $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]);
$this->_product = $this->getProductModel()->getEntity([$this->_model->getPrimaryKey() => $entity->product_uid]);
$this->_viewDatas = $this->init(__FUNCTION__);
$this->update_validate($entity);
$entity = $this->update_process($entity);
$msg = "{$this->_viewDatas['title']}에서 {$entity->getTitle()}의 결제가 완료하였습니다.";
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/");
} catch (\Exception $e) {
$msg = "{$this->_viewDatas['title']}에서 결제를 실패하였습니다.\n" . $e->getMessage();
log_message("error", $e->getMessage());
$this->_session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
return redirect()->back()->withInput();
} finally {
$this->_session->setFlashdata("return_message", $msg);
}
}
}

View File

@ -147,6 +147,7 @@ CREATE TABLE shoppingmall.tw_order (
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:결제완료 등등',
updated_at timestamp NULL DEFAULT NULL,
created_at timestamp NOT NULL DEFAULT current_timestamp(),

View File

@ -69,10 +69,19 @@ function getFieldView_OrderHelper($field, $entity, array $viewDatas)
$value = $entity->$field ?: DEFAULTS['EMPTY'];
switch ($field) {
case 'cost':
case 'price':
case 'sale':
return number_format(!$value ? 0 : $value) . "";
break;
case 'price':
$price = number_format(!$value ? 0 : $value) . "";
$paymentday = $entity->paymentday;
return sprintf(
"%s:%s<BR>%s",
lang("{$viewDatas['className']}.label.paymentday"),
$paymentday,
$price
);
break;
case 'stock':
case 'view_cnt':
return number_format(!$value ? 0 : $value);

View File

@ -12,10 +12,15 @@ return [
'quantity' => "수량",
'price' => "결제금액",
'response' => "결제처리결과",
"paymentday" => "월결제일",
'status' => "상태",
'updated_at' => "수정일",
'created_at' => "작성일"
],
"TYPE" => [
"use" => "월이용권",
"unuse" => "판매",
],
"STATUS" => [
"use" => "장바구니",
"unuse" => "주문취소",

View File

@ -17,6 +17,10 @@ return [
'updated_at' => "수정일",
'created_at' => "생성일"
],
"TYPE" => [
"use" => "월이용권",
"unuse" => "판매",
],
"STATUS" => [
"use" => "판매중",
"unuse" => "판매일시중지",

View File

@ -3,6 +3,7 @@
namespace App\Models;
use App\Entities\OrderEntity;
use App\Entities\ProductEntity;
class OrderModel extends BaseModel
{
@ -14,7 +15,11 @@ class OrderModel extends BaseModel
public function __construct()
{
parent::__construct('Order');
$this->allowedFields = [...$this->allowedFields, 'product_uid', "user_uid", "name", "cost", "sale", "quantity", "price", "response", "status"];
$this->allowedFields = [
...$this->allowedFields, 'product_uid', "user_uid",
"name", "cost", "sale", "quantity", "price", "response",
"paymentday", "status"
];
$this->validationRules = [...$this->validationRules, ...$this->getFieldRules($this->allowedFields),];
}
final public function getTitleField(): string
@ -36,6 +41,7 @@ class OrderModel extends BaseModel
$rules[$field] = "required|numeric";
break;
case 'sale':
case 'paymentday':
$rules[$field] = "if_exist|numeric";
break;
default:
@ -84,4 +90,31 @@ class OrderModel extends BaseModel
$this->orLike($this->getTitleField(), $word, "both");
}
}
//장바구니에 넣기()
final public function addCart(ProductEntity $entity, int $quantity, $paymentDay = null): OrderEntity
{
$formDatas = [];
$formDatas['product_uid'] = $entity->getPrimaryKey();
//상품명을 복사해서 구매한 상품명에 넣기
$formDatas[$this->_model->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(OrderEntity $entity)
{
$formDatas = array();
//장바구니인경우에만
if ($entity->status == DEFAULTS['STATUS']) {
$formDatas['status'] = 'unuse';
}
return $this->modify($entity, $formDatas);
}
}

View File

@ -1,21 +0,0 @@
<?= form_open(URLS['addCart'], ['method' => 'post']) ?>
<?= form_hidden("product_uid", $viewDatas['entity']->getPrimaryKey()) ?>
<input type="hidden" id="price" name="price" value="<?= ($viewDatas['entity']->price) * 1 ?>">
<?php
$quantityOptions = [DEFAULTS['EMPTY'] => "구매수량 선택"];
for ($i = 1; $i <= $viewDatas['entity']->stock; $i++) {
$quantityOptions[$i] = $i . "";
}
?>
구매 수량 : <?= form_dropdown('quantity', $quantityOptions, 1, ['onChange' => "cal_price(this.options[this.selectedIndex].value)"]); ?>
구매 금액 : <span id="order_price"><?= number_format($viewDatas['entity']->price * 1) ?></span>원
<?= form_submit('', '최소:1 ~ 최대:' . $viewDatas['entity']->stock, array("class" => "btn btn-outline btn-primary")); ?>
<?= form_close(); ?>
<script>
function cal_price(quantity) {
var price = 0;
price = <?= $viewDatas['entity']->price ?> * quantity;;
document.getElementById('price').value = price;
document.getElementById('order_price').textContent = new Intl.NumberFormat().format(price);
}
</script>

View File

@ -18,7 +18,27 @@
</table>
<div style="text-align:center">
<?php if ($viewDatas['entity']->status == DEFAULTS['STATUS']) : ?>
<?= $this->include('front/product/addCart'); ?>
<?= form_open(URLS['addCart'], ['method' => 'post']) ?>
<?= form_hidden("product_uid", $viewDatas['entity']->getPrimaryKey()) ?>
<input type="hidden" id="price" name="price" value="<?= ($viewDatas['entity']->price) * 1 ?>">
<?php
$quantityOptions = [DEFAULTS['EMPTY'] => "구매수량 선택"];
for ($i = 1; $i <= $viewDatas['entity']->stock; $i++) {
$quantityOptions[$i] = $i . "";
}
?>
구매 수량 : <?= form_dropdown('quantity', $quantityOptions, 1, ['onChange' => "cal_price(this.options[this.selectedIndex].value)"]); ?>
구매 금액 : <span id="order_price"><?= number_format($viewDatas['entity']->price * 1) ?></span>원
<?= form_submit('', '최소:1 ~ 최대:' . $viewDatas['entity']->stock, array("class" => "btn btn-outline btn-primary")); ?>
<?= form_close(); ?>
<script>
function cal_price(quantity) {
var price = 0;
price = <?= $viewDatas['entity']->price ?> * quantity;;
document.getElementById('price').value = price;
document.getElementById('order_price').textContent = new Intl.NumberFormat().format(price);
}
</script>
<?php else : ?>
이제품은 현재[<?= lang('Product.STATUS.' . $viewDatas['entity']->status) ?>]입니다.
<?php endif ?>

View File

@ -5,8 +5,8 @@
* Updated :
------------------------------------------------------------ */
function trim(str){
return this.replace(/(^\s*)|(\s*$)/gi, "");
function trim(str){
return this.replace(/(^\s*)|(\s*$)/gi, "");
}//
function bookmarksite(title,url) {
@ -70,7 +70,7 @@ function is_NumericKey(evt,obj){
}
function is_NumericType(data){
if(!data.match(/^[0-9]+$/)){
throw (new Error('숫자가 아닌값['+data+']이 있습니다'));
throw (new Error('숫자가 아닌값['+data+']이 있습니다'));
}
return true;
}//
@ -80,7 +80,7 @@ function change_CurrencyFormat(obj,currencies){
for(i=0; i<currencies.length; i+2){
try {
is_NumericType(currencies[i].value)//값이 숫자형식인지 판단
} catch(err) {
} catch(err) {
alert(err.message);
currencies[i].focus();
return false;
@ -90,4 +90,4 @@ function change_CurrencyFormat(obj,currencies){
}
obj.parentElement.innerHTML=total_currency.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,")+'원'
return true;
}
}