From 27d55ec6283fc97eadf41a0848e96b370bebda70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B5=9C=EC=A4=80=ED=9D=A0git=20config=20git=20config=20-?= =?UTF-8?q?-helpgit=20config=20--global=20user=2Ename=20=EC=B5=9C=EC=A4=80?= =?UTF-8?q?=ED=9D=A0?= Date: Mon, 31 Jul 2023 23:03:38 +0900 Subject: [PATCH] shoppingmallv2 init... --- app/Backend/BaseBackend.php | 66 +++++++------ app/Backend/BoardBackend.php | 33 ++++++- app/Backend/EcommerceBackend.php | 92 +++++++++++++++++++ app/Backend/OrderBackend.php | 39 +------- app/Backend/ProductBackend.php | 34 +++++++ app/Config/Routes.php | 6 +- app/Config/Services.php | 7 ++ app/Config/Services_Shoppingmall.php | 9 +- app/Controllers/Admin/EcommerceController.php | 87 ++++++++++++++++++ app/Controllers/Admin/OrderController.php | 41 --------- app/Controllers/Front/EcommerceController.php | 59 ++++++++++++ app/Models/OrderModel.php | 8 ++ app/Models/ProductModel.php | 15 ++- app/Views/admin/ecommerce/index.php | 46 ++++++++++ .../view_org.php => ecommerce/view.php} | 10 +- app/Views/admin/product/orderform.php | 2 +- 16 files changed, 428 insertions(+), 126 deletions(-) create mode 100644 app/Backend/EcommerceBackend.php create mode 100644 app/Controllers/Admin/EcommerceController.php create mode 100644 app/Controllers/Front/EcommerceController.php create mode 100644 app/Views/admin/ecommerce/index.php rename app/Views/admin/{order/view_org.php => ecommerce/view.php} (76%) diff --git a/app/Backend/BaseBackend.php b/app/Backend/BaseBackend.php index 498c041..2484785 100644 --- a/app/Backend/BaseBackend.php +++ b/app/Backend/BaseBackend.php @@ -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 diff --git a/app/Backend/BoardBackend.php b/app/Backend/BoardBackend.php index 0cc30ba..e9dc152 100644 --- a/app/Backend/BoardBackend.php +++ b/app/Backend/BoardBackend.php @@ -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 { diff --git a/app/Backend/EcommerceBackend.php b/app/Backend/EcommerceBackend.php new file mode 100644 index 0000000..59030b0 --- /dev/null +++ b/app/Backend/EcommerceBackend.php @@ -0,0 +1,92 @@ +_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); + } +} diff --git a/app/Backend/OrderBackend.php b/app/Backend/OrderBackend.php index a63c424..75a792a 100644 --- a/app/Backend/OrderBackend.php +++ b/app/Backend/OrderBackend.php @@ -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); } } diff --git a/app/Backend/ProductBackend.php b/app/Backend/ProductBackend.php index 505a19e..faedca9 100644 --- a/app/Backend/ProductBackend.php +++ b/app/Backend/ProductBackend.php @@ -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); + } } diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 52e74cb..5dab8e4 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -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'); diff --git a/app/Config/Services.php b/app/Config/Services.php index e4fbd42..260277c 100644 --- a/app/Config/Services.php +++ b/app/Config/Services.php @@ -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(); + } } diff --git a/app/Config/Services_Shoppingmall.php b/app/Config/Services_Shoppingmall.php index 7d2eca1..260277c 100644 --- a/app/Config/Services_Shoppingmall.php +++ b/app/Config/Services_Shoppingmall.php @@ -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(); + } } diff --git a/app/Controllers/Admin/EcommerceController.php b/app/Controllers/Admin/EcommerceController.php new file mode 100644 index 0000000..fa52f73 --- /dev/null +++ b/app/Controllers/Admin/EcommerceController.php @@ -0,0 +1,87 @@ +_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()); + } + } +} diff --git a/app/Controllers/Admin/OrderController.php b/app/Controllers/Admin/OrderController.php index fa1f69c..e4e8afb 100644 --- a/app/Controllers/Admin/OrderController.php +++ b/app/Controllers/Admin/OrderController.php @@ -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); - } } diff --git a/app/Controllers/Front/EcommerceController.php b/app/Controllers/Front/EcommerceController.php new file mode 100644 index 0000000..5d4be63 --- /dev/null +++ b/app/Controllers/Front/EcommerceController.php @@ -0,0 +1,59 @@ +_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); + } +} diff --git a/app/Models/OrderModel.php b/app/Models/OrderModel.php index 8788a66..e9e526d 100644 --- a/app/Models/OrderModel.php +++ b/app/Models/OrderModel.php @@ -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]); + } } diff --git a/app/Models/ProductModel.php b/app/Models/ProductModel.php index e6eb5fa..a01977f 100644 --- a/app/Models/ProductModel.php +++ b/app/Models/ProductModel.php @@ -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); } } diff --git a/app/Views/admin/ecommerce/index.php b/app/Views/admin/ecommerce/index.php new file mode 100644 index 0000000..28fce26 --- /dev/null +++ b/app/Views/admin/ecommerce/index.php @@ -0,0 +1,46 @@ +extend('layouts/admin') ?> +section('content') ?> +
+
+ "get")) ?> + + +
+ + + + + + + + + + getStatus() != 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"]); ?> + + + getStatus() == DEFAULTS['STATUS'] ? anchor(current_url() . '/delete/' . $entity->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/admin/order/view_org.php b/app/Views/admin/ecommerce/view.php similarity index 76% rename from app/Views/admin/order/view_org.php rename to app/Views/admin/ecommerce/view.php index b5cd6a5..d64b8be 100644 --- a/app/Views/admin/order/view_org.php +++ b/app/Views/admin/ecommerce/view.php @@ -2,10 +2,6 @@ section('content') ?> include('templates/admin/header'); ?> - - - - @@ -24,11 +20,11 @@ - + - - + + diff --git a/app/Views/admin/product/orderform.php b/app/Views/admin/product/orderform.php index 54ca9df..e99cfcc 100644 --- a/app/Views/admin/product/orderform.php +++ b/app/Views/admin/product/orderform.php @@ -1,4 +1,4 @@ -getPrimaryKey(), ['method' => 'post']) ?> +getPrimaryKey(), ['method' => 'post']) ?> getPrimaryKey()) ?> getPrice() - $entity->getSale()) ?> 구매 수량 :
판매자getTitle() ?>
제품명 getTitle() ?>
구매수량getQuantity() ?>개getQuantity() ?>개
결제금액getPrice() - $product->getSale()) * $entity->getQuantity()) ?>원구매금액getPrice()) ?>원
getContent()) ?>