shoppingmallv2 init...

This commit is contained in:
최준흠git config git config --helpgit config --global user.name 최준흠 2023-07-31 23:03:38 +09:00
parent 3439bbfb94
commit 27d55ec628
16 changed files with 428 additions and 126 deletions

View File

@ -18,58 +18,40 @@ abstract class BaseBackend
$this->_session = \Config\Services::session();
}
//공통사용
final public function getClassName()
{
return $this->_className;
}
//User모델
final public function getUserModel(): UserModel
{
return is_null($this->_userModel) ? new UserModel() : $this->_userModel;
}
//Entity값 가져오기
final public function getEntity($uid)
{
return $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]);
}
//transaction관련
final public function transStart($isTest = false)
{
$this->_model->transStart($isTest);
}
final public function transComplete()
{
$this->_model->transComplete();
}
final public function transRollback()
{
$this->_model->transRollback();
}
//초기화
final public function getFields(string $action)
{
return $this->_model->getFields($action);
}
//TitleField
final public function getTitleField()
//초기 선언부-------
//Title Field
public function getTitleField()
{
return $this->_model->getTitleField();
}
//Form Fields
public function getFields(string $action)
{
return $this->_model->getFields($action);
}
//Field별 Form Rule용
final public function getFieldRules(array $fields, string $action)
public function getFieldRules(array $fields, string $action)
{
return $this->_model->getFieldRules($fields, $action);
}
//Field별 Form Filter용
final public function getFieldFilters()
public function getFieldFilters()
{
return $this->_model->getFieldFilters();
}
//Field별 Form BatchFilter용
final public function getFieldBatchFilters()
public function getFieldBatchFilters()
{
return $this->_model->getFieldBatchFilters();
}
@ -101,6 +83,30 @@ abstract class BaseBackend
}
return $fieldFormOptions;
}
//Entity값 가져오기
public function getEntity($uid)
{
return $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]);
}
public function getEntitys($condition)
{
return $this->_model->getEntitys($condition);
}
//-----초기 선언부
//transaction관련
final public function transStart($isTest = false)
{
$this->_model->transStart($isTest);
}
final public function transComplete()
{
$this->_model->transComplete();
}
final public function transRollback()
{
$this->_model->transRollback();
}
//Insert관련
public function insert(array $fieldDatas): BaseEntity

View File

@ -15,11 +15,42 @@ class BoardBackend extends BaseHierarchyBackend
$this->_model = new BoardModel();
}
//BoardConfig모델
final public function getBoardConfigModel(): BoardConfigModel
public function getBoardConfigModel(): BoardConfigModel
{
return is_null($this->_boardConfigModel) ? new BoardConfigModel() : $this->_boardConfigModel;
}
//초기선언부
//Entity값 가져오기
public function getEntity($uid)
{
return $this->_model->getEntity([$this->_model->getPrimaryKey() => $uid]);
}
public function getFields(string $action)
{
return $this->_model->getFields($action);
}
//TitleField
public function getTitleField()
{
return $this->_model->getTitleField();
}
//Field별 Form Rule용
public function getFieldRules(array $fields, string $action)
{
return $this->_model->getFieldRules($fields, $action);
}
//Field별 Form Filter용
public function getFieldFilters()
{
return $this->_model->getFieldFilters();
}
//Field별 Form BatchFilter용
public function getFieldBatchFilters()
{
return $this->_model->getFieldBatchFilters();
}
//Field별 Form Option용
public function getFieldFormOption(string $field): array
{

View File

@ -0,0 +1,92 @@
<?php
namespace App\Backend;
class EcommerceBackend extends BaseBackend
{
private $_product = null;
private $_order = null;
public function __construct()
{
parent::__construct('Order');
$this->_product = new ProductBackend();
$this->_order = new OrderBackend();
}
final public function getOrderBackend()
{
$this->_order;
}
final public function getProductBackend()
{
$this->_product;
}
//초기선언부--------
//Title Field
public function getTitleField()
{
return "product_uid";
}
//Form Fields
public function getFields(string $action = ""): array
{
$fields = ['product_uid', "quantity", "price"];
switch ($action) {
default:
return $fields;
break;
}
}
public function getFieldFilters(): array
{
return ['product_uid', "user_uid"];
}
public function getFieldBatchFilters(): array
{
return ["status"];
}
public function getFieldRule(string $field, array $rules, string $action = ""): array
{
switch ($field) {
case $this->getTitleField():
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 'quantity':
case 'price':
$rules[$field] = "required|numeric";
break;
default:
throw new \Exception(__FUNCTION__ . "에서 오류발생: Field명:{$field}는 사용할수없습니다.");
break;
}
return $rules;
}
public function getFieldRules(array $fields, string $action)
{
$rules = array();
foreach ($fields as $field) {
$rules = $this->getFieldRule($field, $rules, $action);
}
return $rules;
}
//Entity값 가져오기
public function getEntity($uid)
{
throw new \Exception(__FUNCTION__ . "에서 오류발생: 사용할수없습니다.");
}
public function getEntitys($condition)
{
throw new \Exception(__FUNCTION__ . "에서 오류발생: 사용할수없습니다.");
}
//-------초기선언부
//장바구니에 담기
public function addCart(string $product_uid, int $quantity, int $price)
{
$product = $this->_product->getEntity($product_uid);
$this->_product->addCart($product, $quantity, $price);
$this->_order->addCart($product, $quantity, $price);
}
}

View File

@ -3,6 +3,7 @@
namespace App\Backend;
use App\Entities\OrderEntity;
use App\Entities\ProductEntity;
use App\Models\OrderModel;
use App\Models\ProductModel;
@ -39,41 +40,9 @@ class OrderBackend extends BaseBackend
return $options;
}
//Insert관련 //장바구니에 담기 및 Product 재고 차감
public function insert(array $fieldDatas): OrderEntity
//장바구니에 담기 및 Product 재고 차감
public function addCart(ProductEntity $product, int $quantity, int $price): OrderEntity
{
//상품정보가져오기
$product = $this->getProductModel()->getEntity([$this->getProductModel()->getPrimaryKey() => $fieldDatas['product_uid']]);
if (!$fieldDatas['quantity']) {
throw new \Exception("제품 구매수량을 확인해주세요");
}
if (!$fieldDatas['price']) {
throw new \Exception("제품 구매금액을 확인해주세요");
}
if ($product->getStock() < $fieldDatas['quantity']) {
throw new \Exception(sprintf(
"%s의 재고수[%s]보다 많은 수량[%s]을 주문하셨습니다.\\n",
$product->getTitle(),
$product->getStock(),
$fieldDatas['quantity']
));
}
//구매금액 = (판매가-할인가)*구매수량과 맞는지 다시 확인.
// $calculated_price = ($product->getPrice() - $product->getSale()) * $quantity;
$calculated_price = ($product->getPrice() - $product->getSale()) * $fieldDatas['quantity'];
if ($fieldDatas['price'] != $calculated_price) {
throw new \Exception(
sprintf(
"%s상품의 구매금액[%s원]과 판매금액[%s원]이 맞지않습니다.",
$product->getTitle(),
number_format($fieldDatas['price']),
number_format($calculated_price)
)
);
}
//상품모델에서 Order에 담은 갯수만큼 재고에서 뺀다.
$this->getProductModel()->decreaseStock($product, $fieldDatas['quantity']);
// throw new \Exception(var_export($fieldDatas, true));
return parent::insert($fieldDatas);
return $this->_model->addCart($product, $quantity, $price);
}
}

View File

@ -2,6 +2,7 @@
namespace App\Backend;
use App\Entities\ProductEntity;
use App\Models\CategoryModel;
use App\Models\ProductModel;
@ -37,4 +38,37 @@ class ProductBackend extends BaseBackend
}
return $options;
}
public function addCart(ProductEntity $product, int $quantity, int $price)
{
if (!$quantity) {
throw new \Exception("제품 구매수량을 확인해주세요");
}
if (!$price) {
throw new \Exception("제품 구매금액을 확인해주세요");
}
if ($product->getStock() < $quantity) {
throw new \Exception(sprintf(
"%s의 재고수[%s]보다 많은 수량[%s]을 주문하셨습니다.\\n",
$product->getTitle(),
$product->getStock(),
$quantity
));
}
//구매금액 = (판매가-할인가)*구매수량과 맞는지 다시 확인.
// $calculated_price = ($product->getPrice() - $product->getSale()) * $quantity;
$calculated_price = ($product->getPrice() - $product->getSale()) * $quantity;
if ($price != $calculated_price) {
throw new \Exception(
sprintf(
"%s상품의 구매금액[%s원]과 판매금액[%s원]이 맞지않습니다.",
$product->getTitle(),
number_format($price),
number_format($calculated_price)
)
);
}
//상품모델에서 Order에 담은 갯수만큼 재고에서 뺀다.
$this->_model->addCart($product, $quantity);
}
}

View File

@ -122,11 +122,15 @@ $routes->group('admin', ['namespace' => 'App\Controllers\Admin', 'filter' => 'au
});
$routes->group('order', static function ($routes) {
$routes->get('', 'OrderController::index');
$routes->post('insert/(:uuid)', 'OrderController::insert/$1');
$routes->get('view/(:uuid)', 'OrderController::view/$1');
$routes->post('batchjob', 'OrderController::batchjob`');
$routes->get('delete/(:uuid)', 'OrderController::delete/$1', ['filter' => 'authFilter:master']);
});
$routes->group('ecommerce', static function ($routes) {
$routes->get('', 'EcommerceController::index');
$routes->post('addcart', 'EcommerceController::addCart');
$routes->get('view/(:uuid)', 'EcommerceController::viewCart/$1');
});
});
$routes->group('front', ['namespace' => 'App\Controllers\Front'], function ($routes) {
$routes->get('/', 'Home::index');

View File

@ -78,4 +78,11 @@ class Services extends BaseService
}
return new \App\Backend\OrderBackend();
}
public static function ecommerce($getShared = true)
{
if ($getShared) {
return static::getSharedInstance('ecommerce');
}
return new \App\Backend\EcommerceBackend();
}
}

View File

@ -64,7 +64,7 @@ class Services extends BaseService
}
return new \App\Backend\CategoryBackend();
}
public static function prodcut($getShared = true)
public static function product($getShared = true)
{
if ($getShared) {
return static::getSharedInstance('product');
@ -78,4 +78,11 @@ class Services extends BaseService
}
return new \App\Backend\OrderBackend();
}
public static function ecommerce($getShared = true)
{
if ($getShared) {
return static::getSharedInstance('ecommerce');
}
return new \App\Backend\EcommerceBackend();
}
}

View File

@ -0,0 +1,87 @@
<?php
namespace App\Controllers\Admin;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
class EcommerceController extends AdminController
{
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
$this->_backend = service('ecommerce');
parent::initController($request, $response, $logger);
$this->_viewPath .= strtolower($this->_backend->getClassName());
}
//장바구니에 담기
public function addCart()
{
$msg = "";
try {
$this->_viewDatas = $this->init(__FUNCTION__);
//Transaction 시작
$this->_backend->transStart();
$this->insert_process();
$this->_backend->addCart($this->_viewDatas['fieldDatas']);
//Transaction Commit
$this->_backend->transCommit();
$msg = sprintf(
"%s에서 해당 상품 %s개를 장바구니에 담았습니다.",
$this->_viewDatas['title'],
$this->_viewDatas['fieldDatas']['quantity']
);
} catch (\Exception $e) {
//Transaction Rollback
$this->_backend->transRollback();
$msg = sprintf(
"%s에서 다음 오류로 인해 장바구니에 담기를 실패하였습니다.\n%s",
$this->_viewDatas['title'],
$e->getMessage()
);
log_message("error", $e->getMessage());
log_message("error", var_export($this->_viewDatas['fieldDatas'], true));
} finally {
$this->_session->setFlashdata("return_message", $msg);
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']));
}
}
//View관련
public function viewCart($order_uid)
{
try {
$this->_viewDatas = $this->init(__FUNCTION__);
helper(['form']);
$this->_viewDatas['forms'] = ['attributes' => ['method' => "post",], 'hiddens' => []];
$this->_viewDatas['order'] = $this->_backend->getOrderBackend()->getEntity($order_uid);
$this->_viewDatas['product'] = $this->_backend->getProductBackend()->getEntity($this->_viewDatas['order']->getProduct_uid());
$this->_session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
return view($this->_viewPath . '/view', $this->_viewDatas);
} catch (\Exception $e) {
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']))->with('return_message', $e->getMessage());
}
}
public function index()
{
try {
$this->_viewDatas = $this->init(__FUNCTION__);
helper(['form']);
$this->_viewDatas['forms'] = ['attributes' => ['method' => "post",], 'hiddens' => []];
foreach ($this->_viewDatas['fieldFilters'] as $field) {
$this->_viewDatas[$field] = $this->request->getVar($field) ?: DEFAULTS['EMPTY'];
}
//모델 처리
$this->_viewDatas['entitys'] = $this->_backend->getOrderBackend()->getEntitys(['status' => DEFAULTS['STATUS']]);
// log_message("debug", __METHOD__ . "에서 호출:" . $this->_backend->getLastQuery());
//setting return_url to session flashdata
$this->_session->setFlashdata(SESSION_NAMES['RETURN_URL'], current_url() . '?' . $this->request->getUri()->getQuery() ?: "");
return view($this->_viewPath . '/index', $this->_viewDatas);
} catch (\Exception $e) {
return redirect()->back()->with('return_message', $e->getMessage());
}
}
}

View File

@ -15,45 +15,4 @@ class OrderController extends AdminController
parent::initController($request, $response, $logger);
$this->_viewPath .= strtolower($this->_backend->getClassName());
}
//장바구니에 담기
public function insert()
{
$msg = "";
try {
$this->_viewDatas = $this->init(__FUNCTION__);
//Transaction 시작
$this->_backend->transStart();
$this->insert_process();
$entity = $this->_backend->insert($this->_viewDatas['fieldDatas']);
//Transaction Commit
$this->_backend->transCommit();
$msg = sprintf(
"%s에서 해당 상품 %s개를 장바구니에 담았습니다.",
$this->_viewDatas['title'],
$this->_viewDatas['fieldDatas']['quantity']
);
} catch (\Exception $e) {
//Transaction Rollback
$this->_backend->transRollback();
$msg = sprintf(
"%s에서 다음 오류로 인해 장바구니에 담기를 실패하였습니다.\n%s",
$this->_viewDatas['title'],
$e->getMessage()
);
log_message("error", $e->getMessage());
log_message("error", var_export($this->_viewDatas['fieldDatas'], true));
} finally {
$this->_session->setFlashdata("return_message", $msg);
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']));
}
}
//View관련
protected function view_process($entity)
{
$this->_viewDatas['user'] = $this->_backend->getUserModel()->getEntity([$this->_backend->getUserModel()->getPrimaryKey() => $entity->getUser_uid()]);
$this->_viewDatas['product'] = $this->_backend->getProductModel()->getEntity([$this->_backend->getProductModel()->getPrimaryKey() => $entity->getProduct_uid()]);
return parent::view_process($entity);
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\Controllers\Front;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
class EcommerceController extends FrontController
{
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
$this->_backend = service('ecommerce');
parent::initController($request, $response, $logger);
$this->_viewPath .= strtolower($this->_backend->getClassName());
}
//장바구니에 담기
public function addCart()
{
$msg = "";
try {
$this->_viewDatas = $this->init(__FUNCTION__);
//Transaction 시작
$this->_backend->transStart();
$this->insert_process();
$this->_backend->addCart($this->_viewDatas['fieldDatas']);
//Transaction Commit
$this->_backend->transCommit();
$msg = sprintf(
"%s에서 해당 상품 %s개를 장바구니에 담았습니다.",
$this->_viewDatas['title'],
$this->_viewDatas['fieldDatas']['quantity']
);
} catch (\Exception $e) {
//Transaction Rollback
$this->_backend->transRollback();
$msg = sprintf(
"%s에서 다음 오류로 인해 장바구니에 담기를 실패하였습니다.\n%s",
$this->_viewDatas['title'],
$e->getMessage()
);
log_message("error", $e->getMessage());
log_message("error", var_export($this->_viewDatas['fieldDatas'], true));
} finally {
$this->_session->setFlashdata("return_message", $msg);
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']));
}
}
//View관련
protected function view_process($entity)
{
$this->_viewDatas['user'] = $this->_backend->getUserModel()->getEntity([$this->_backend->getUserModel()->getPrimaryKey() => $entity->getUser_uid()]);
$this->_viewDatas['product'] = $this->_backend->getProductModel()->getEntity([$this->_backend->getProductModel()->getPrimaryKey() => $entity->getProduct_uid()]);
return parent::view_process($entity);
}
}

View File

@ -3,6 +3,7 @@
namespace App\Models;
use App\Entities\OrderEntity;
use App\Entities\ProductEntity;
class OrderModel extends BaseModel
{
@ -96,4 +97,11 @@ class OrderModel extends BaseModel
parent::setIndexWordFilter($word);
$this->orLike($this->getTitleField(), $word, "both");
}
//Ecommerce Action
//장바구니에 넣기
final public function addCart(ProductEntity $product, int $quantity, int $price): OrderEntity
{
return $this->create(['product_uid' => $product->getPrimaryKey(), 'quantity' => $quantity, 'price' => $price]);
}
}

View File

@ -98,17 +98,14 @@ class ProductModel extends BaseModel
$this->orLike("content", $word, "both"); //befor , after , both
}
//추가Action
//장바구니에 넣은 갯수만큼 차감
final public function decreaseStock(ProductEntity $entity, int $cnt)
//Ecommerce Action
//장바구니에 넣
final public function addCart(ProductEntity $entity, int $quantity): ProductEntity
{
if ($entity->getStock() == $cnt) {
if ($entity->getStock() == $quantity) {
$entity->status = "outofstock";
}
$entity->stock -= $cnt;
$this->save_process($entity);
// throw new \Exception($this->getLastQuery());
// echo "TEST";
// exit;
$entity->stock -= $quantity;
return $this->save_process($entity);
}
}

View File

@ -0,0 +1,46 @@
<?= $this->extend('layouts/admin') ?>
<?= $this->section('content') ?>
<div class="content">
<div class="top">
<?= form_open(current_url(), array("method" => "get")) ?>
<ul class="nav">
조건검색:<?php foreach ($fieldFilters as $field) : ?><li class="nav-item"><?= getFieldFilter_OrderHelper($field, $$field, $fieldFormOptions) ?></li><?php endforeach; ?>
<?= $this->include('templates/admin/index_head'); ?>
</ul>
<?= form_close(); ?>
</div>
<?= form_open(current_url() . '/batchjob', $forms['attributes'], $forms['hiddens']) ?>
<table class="table table-bordered table-hover table-striped">
<tr>
<th>번호</th>
<?php foreach ($fields as $field) : ?><th><?= getFieldIndex_Column_OrderHelper($field, $order_field, $order_value) ?></th><?php endforeach; ?>
<th>작업</th>
</tr>
<?php $i = 0; ?>
<?php foreach ($entitys as $entity) : ?>
<tr id="<?= $entity->getPrimaryKey() ?>" <?= $entity->getStatus() != DEFAULTS['STATUS'] ? 'class="table-danger" rowcolor="red"' : 'rowcolor="red"' ?> onClick="indexRowCheckBoxToggle(this);">
<td>
<?= form_checkbox(["id" => "checkbox_uid_{$entity->getPrimaryKey()}", "name" => "batchjob_uids[]", "value" => $entity->getPrimaryKey(), "class" => "batchjobuids_checkboxs"]); ?>
<?= $total_count - (($page - 1) * $per_page + $i) ?>
</td>
<?php foreach ($fields as $field) : ?>
<td nowrap><?= getFieldIndex_Row_OrderHelper($field, $entity, $fieldFilters, $fieldFormOptions) ?></td>
<?php endforeach; ?>
<td>
<?= $entity->getStatus() == DEFAULTS['STATUS'] ? anchor(current_url() . '/delete/' . $entity->getPrimaryKey(), ICONS['DELETE'], ["class" => "btn btn-sm btn-danger btn-circle", "target" => "_self"]) : "" ?>
</td>
</tr>
<?php $i++; ?>
<?php endforeach; ?>
</table>
<div class="bottom">
<ul class="nav justify-content-center">
<li class="nav-item"><?= form_checkbox(array("id" => "batchjobuids_checkbox")) ?>ALL</li>
<?php foreach ($batchjobFilters as $field) : ?><li class="nav-item"><?= getFieldFilter_OrderHelper($field, DEFAULTS['EMPTY'], $fieldFormOptions) ?></li><?php endforeach; ?>
<li class="nav-item"><?= form_submit('', '일괄처리', array("class" => "btn btn-outline btn-warning")); ?></li>
</ul>
<?= $pagination ?>
</div>
<?= form_close(); ?>
</div>
<?= $this->endSection() ?>

View File

@ -2,10 +2,6 @@
<?= $this->section('content') ?>
<?= $this->include('templates/admin/header'); ?>
<table class="table table-bordered table-hover table-striped indexTable ">
<tr>
<td>판매자</td>
<td><?= $user->getTitle() ?></td>
</tr>
<tr>
<td>제품명</td>
<td><?= $product->getTitle() ?></td>
@ -24,11 +20,11 @@
</tr>
<tr>
<td>구매수량</td>
<td><?= $entity->getQuantity() ?>개</td>
<td><?= $order->getQuantity() ?>개</td>
</tr>
<tr>
<td>결제금액</td>
<td><?= number_format(($product->getPrice() - $product->getSale()) * $entity->getQuantity()) ?>원</td>
<td>구매금액</td>
<td><?= number_format($order->getPrice()) ?>원</td>
</tr>
<tr>
<td colspan="2"><?= html_entity_decode($product->getContent()) ?></td>

View File

@ -1,4 +1,4 @@
<?= form_open("admin/order/insert/" . $entity->getPrimaryKey(), ['method' => 'post']) ?>
<?= form_open("admin/ecommerce/addcart/" . $entity->getPrimaryKey(), ['method' => 'post']) ?>
<?= form_hidden("product_uid", $entity->getPrimaryKey()) ?>
<?= form_hidden("price", $entity->getPrice() - $entity->getSale()) ?>
구매 수량 : <?= getFieldForm_ProductHelper('quantity', 1, $fieldFormOptions) ?>