Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
O
order-group
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
order-group-application
order-group
Commits
931b343f
Commit
931b343f
authored
Jan 27, 2021
by
chongfu.liang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix
parent
15297d0f
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
111 additions
and
73 deletions
+111
-73
shopping-cart-application-service/src/main/java/cn/freemud/demo/entities/GetCheckSpqBo.java
+28
-0
shopping-cart-application-service/src/main/java/cn/freemud/demo/manager/coupon/CouponService.java
+2
-1
shopping-cart-application-service/src/main/java/cn/freemud/demo/manager/coupon/KgdCouponServiceImpl.java
+60
-17
shopping-cart-application-service/src/main/java/cn/freemud/demo/service/AbstractAddGoodsService.java
+3
-12
shopping-cart-application-service/src/main/java/cn/freemud/demo/service/PlatformAddGoodsService.java
+0
-7
shopping-cart-application-service/src/main/java/cn/freemud/demo/service/PlatformUpdateGoodsQtyService.java
+18
-36
No files found.
shopping-cart-application-service/src/main/java/cn/freemud/demo/entities/GetCheckSpqBo.java
0 → 100644
View file @
931b343f
package
cn
.
freemud
.
demo
.
entities
;
import
cn.freemud.demo.manager.product.ProductService
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
@Data
@AllArgsConstructor
@NoArgsConstructor
public
class
GetCheckSpqBo
{
private
String
partnerId
;
private
String
couponCode
;
private
String
storeId
;
private
String
menuType
;
private
String
spuId
;
private
String
skuId
;
private
ProductService
productService
;
}
shopping-cart-application-service/src/main/java/cn/freemud/demo/manager/coupon/CouponService.java
View file @
931b343f
...
...
@@ -2,6 +2,7 @@ package cn.freemud.demo.manager.coupon;
import
cn.freemud.demo.entities.CheckSpqBO
;
import
cn.freemud.demo.entities.CouponDetailBO
;
import
cn.freemud.demo.entities.GetCheckSpqBo
;
import
cn.freemud.demo.entities.GetCouponDetailBO
;
import
cn.freemud.demo.entities.bo.goods.GetProductBO
;
import
cn.freemud.demo.entities.bo.goods.add.BaseAddGoodsBO
;
...
...
@@ -10,6 +11,6 @@ public interface CouponService {
CouponDetailBO
getCouponDetail
(
GetCouponDetailBO
getCouponDetailBO
);
CheckSpqBO
checkSpq
(
BaseAddGoodsBO
baseRequestBO
);
CheckSpqBO
checkSpq
(
GetCheckSpqBo
GetCheckSpqBo
);
}
shopping-cart-application-service/src/main/java/cn/freemud/demo/manager/coupon/KgdCouponServiceImpl.java
View file @
931b343f
package
cn
.
freemud
.
demo
.
manager
.
coupon
;
import
cn.freemud.constant.ResponseCodeConstant
;
import
cn.freemud.demo.ValidateShopProductRequestBO
;
import
cn.freemud.demo.entities.*
;
import
cn.freemud.demo.entities.bo.goods.GetProductBySkuIdResponseBO
;
import
cn.freemud.demo.entities.bo.goods.ProductBO
;
import
cn.freemud.demo.entities.bo.goods.add.BaseAddGoodsBO
;
import
cn.freemud.demo.entities.bo.goods.add.MCoffeeAddGoodsBO
;
import
cn.freemud.demo.entities.bo.goods.update.UpdateAddGoodsBO
;
import
cn.freemud.demo.manager.product.ProductManager
;
import
cn.freemud.demo.manager.store.StoreService
;
import
cn.freemud.entities.dto.GetAppKeyRequestDto
;
...
...
@@ -13,11 +16,17 @@ import cn.freemud.entities.dto.GetCouponDetailResponseDto;
import
cn.freemud.enums.CouponStatus
;
import
cn.freemud.enums.ResponseResult
;
import
cn.freemud.enums.StoreItemStatus
;
import
cn.freemud.interceptor.ServiceException
;
import
cn.freemud.redis.RedisCache
;
import
cn.freemud.service.thirdparty.CardBinClient
;
import
cn.freemud.service.thirdparty.CouponOnlineClient
;
import
cn.freemud.utils.LogUtil
;
import
cn.freemud.utils.RedisUtil
;
import
com.freemud.application.sdk.api.productcenter.constant.ResponseConstant
;
import
com.freemud.application.sdk.api.productcenter.request.product.valid.ValidateShopProductRequest
;
import
com.freemud.application.sdk.api.productcenter.request.product.valid.ValidateShopProductType
;
import
com.freemud.application.sdk.api.productcenter.response.ProductResponseDTO
;
import
com.freemud.application.sdk.api.productcenter.response.valid.ValiadShopProductResponse
;
import
com.freemud.card.sdk.comm.Finals
;
import
com.freemud.card.sdk.comm.SignUtil
;
import
com.freemud.sdk.api.assortment.shoppingcart.constant.CommonsConstant
;
...
...
@@ -88,10 +97,10 @@ public class KgdCouponServiceImpl implements CouponService {
}
@Override
public
CheckSpqBO
checkSpq
(
BaseAddGoodsBO
baseRequestBO
)
{
public
CheckSpqBO
checkSpq
(
GetCheckSpqBo
getCheckSpqBo
)
{
CheckSpqBO
result
=
new
CheckSpqBO
();
GetCouponDetailBO
getCouponDetail
=
convert2GetCouponDetailBO
(
baseRequestBO
);
GetCouponDetailBO
getCouponDetail
=
convert2GetCouponDetailBO
(
getCheckSpqBo
);
// 如果是商品券,获取商品券信息
CouponDetailBO
couponDetail
=
getCouponDetail
(
getCouponDetail
);
...
...
@@ -104,13 +113,13 @@ public class KgdCouponServiceImpl implements CouponService {
}
Integer
couponType
=
0
;
CouponDetailBO
.
Details
couponActivityDetail
=
null
;
if
(
StringUtils
.
isNotBlank
(
baseRequestBO
.
getSkuId
())){
if
(
StringUtils
.
isNotBlank
(
getCheckSpqBo
.
getSkuId
())){
boolean
productValid
=
false
;
for
(
CouponDetailBO
.
Details
detail
:
couponDetail
.
getDetails
())
{
if
(
productValid
)
break
;
if
(!
CouponStatus
.
STATUS_0
.
getCode
().
equals
(
detail
.
getStatus
()))
continue
;
for
(
CouponDetailBO
.
ActiveProduct
activeProduct
:
detail
.
getActiveProduct
())
{
if
(
baseRequestBO
.
getSkuId
().
equals
(
activeProduct
.
getProductIdPartner
()))
{
if
(
getCheckSpqBo
.
getSkuId
().
equals
(
activeProduct
.
getProductIdPartner
()))
{
productValid
=
true
;
couponActivityDetail
=
detail
;
couponType
=
detail
.
getType
();
...
...
@@ -133,24 +142,31 @@ public class KgdCouponServiceImpl implements CouponService {
couPonstoreIds
.
add
(
activeRestrictionVO
.
getStoreIdPartner
());
}
}
if
(
CollectionUtils
.
isNotEmpty
(
couPonstoreIds
)
&&
!
couPonstoreIds
.
contains
(
baseRequestBO
.
getShop
Id
()))
{
if
(
CollectionUtils
.
isNotEmpty
(
couPonstoreIds
)
&&
!
couPonstoreIds
.
contains
(
getCheckSpqBo
.
getStore
Id
()))
{
return
null
;
}
//券返回的商品id
List
<
String
>
skuIds
=
Lists
.
newArrayList
();
String
skuId
=
baseRequestBO
.
getSkuId
();
String
skuId
=
getCheckSpqBo
.
getSkuId
();
if
(
StringUtils
.
isBlank
(
skuId
)){
skuId
=
couponDetail
.
getDetails
().
get
(
0
).
getActiveProduct
().
get
(
0
).
getProductIdPartner
();
}
skuIds
.
add
(
skuId
);
// 通过skuid查询spuid
GetProductBySkuIdBO
getProductBySkuIdBO
=
convert2GetProductBySkuIdBO
(
baseRequestBO
);
Map
<
String
,
GetProductBySkuIdResponseBO
>
productsInfoBySkuIds
=
productManager
.
getProductsInfoBySkuIds
(
getProductBySkuIdBO
,
baseRequestBO
.
getManagerService
()
.
getProductService
());
GetProductBySkuIdBO
getProductBySkuIdBO
=
convert2GetProductBySkuIdBO
(
getCheckSpqBo
);
Map
<
String
,
GetProductBySkuIdResponseBO
>
productsInfoBySkuIds
=
productManager
.
getProductsInfoBySkuIds
(
getProductBySkuIdBO
,
getCheckSpqBo
.
getProductService
());
GetProductBySkuIdResponseBO
productsVo
=
productsInfoBySkuIds
.
get
(
skuId
);
if
(
null
==
productsVo
||
!
Objects
.
equals
(
productsVo
.
getStatus
(),
StoreItemStatus
.
PUT_ON_SALE
.
getCode
()))
{
return
null
;
}
// 商品券商品时间校验
ValidateShopProductRequestBO
validateShopProductRequestBO
=
getValidateShopProductRequestBO
(
productsVo
,
getCheckSpqBo
.
getPartnerId
(),
getCheckSpqBo
.
getStoreId
(),
getCheckSpqBo
.
getMenuType
());
ValiadShopProductBO
valiadShopProductBO
=
productManager
.
validateShopProduct
(
validateShopProductRequestBO
,
getCheckSpqBo
.
getProductService
());
if
(
valiadShopProductBO
==
null
||
CollectionUtils
.
isEmpty
(
valiadShopProductBO
.
getSuccessList
())
){
throw
new
ServiceException
(
ResponseResult
.
SHOPPING_CART_COUPON_NOT_USE
);
}
result
.
setType
(
couponType
);
result
.
setDetails
(
couponActivityDetail
);
result
.
setSkuId
(
productsVo
.
getSkuId
());
...
...
@@ -160,6 +176,33 @@ public class KgdCouponServiceImpl implements CouponService {
}
private
ValidateShopProductRequestBO
getValidateShopProductRequestBO
(
GetProductBySkuIdResponseBO
product
,
String
partnerId
,
String
storeId
,
String
menuType
)
{
ValidateShopProductRequestBO
request
=
new
ValidateShopProductRequestBO
();
request
.
setChannel
(
menuType
);
request
.
setPartnerId
(
partnerId
);
request
.
setStoreId
(
storeId
);
List
<
ValidateShopProductType
>
productTypeList
=
new
ArrayList
<>();
ValidateShopProductType
productType
=
new
ValidateShopProductType
();
productType
.
setAttributeList
(
null
);
productType
.
setComboProductTypeList
(
null
);
productType
.
setMemberDiscount
(
null
);
productType
.
setPrice
(
product
.
getFinalPrice
().
intValue
());
productType
.
setProductGroupTypeList
(
null
);
productType
.
setSkuId
(
product
.
getSkuId
());
productType
.
setSpuId
(
product
.
getSpuId
());
productType
.
setUuid
(
UUID
.
randomUUID
().
toString
());
productType
.
setValidateAttribute
(
0
);
productType
.
setValidatePrice
(
0
);
productType
.
setValidateStatuses
(
null
);
productTypeList
.
add
(
productType
);
request
.
setProductTypeList
(
productTypeList
);
return
request
;
}
private
CouponDetailBO
convert2CouponDetailBO
(
GetCouponDetailResponseDto
responseDto
)
{
CouponDetailBO
couponDetailBO
=
mapperFacade
.
map
(
responseDto
,
CouponDetailBO
.
class
);
return
couponDetailBO
;
...
...
@@ -182,23 +225,23 @@ public class KgdCouponServiceImpl implements CouponService {
private
GetCouponDetailBO
convert2GetCouponDetailBO
(
BaseAddGoodsBO
baseRequestBO
)
{
private
GetCouponDetailBO
convert2GetCouponDetailBO
(
GetCheckSpqBo
getCheckSpqBo
)
{
GetCouponDetailBO
getCouponDetailBO
=
new
GetCouponDetailBO
();
getCouponDetailBO
.
setPartnerId
(
baseRequestBO
.
getPartnerId
());
getCouponDetailBO
.
setCouponCode
(
StringUtils
.
isBlank
(
baseRequestBO
.
getCouponCode
())
?
baseRequestBO
.
getSpuId
().
substring
(
CommonsConstant
.
COUPON_PREFIX
.
length
())
:
baseRequestBO
.
getCouponCode
());
getCouponDetailBO
.
setStoreCode
(
baseRequestBO
.
getShop
Id
());
getCouponDetailBO
.
setPartnerId
(
getCheckSpqBo
.
getPartnerId
());
getCouponDetailBO
.
setCouponCode
(
getCheckSpqBo
.
getCouponCode
());
getCouponDetailBO
.
setStoreCode
(
getCheckSpqBo
.
getStore
Id
());
return
getCouponDetailBO
;
}
private
GetProductBySkuIdBO
convert2GetProductBySkuIdBO
(
BaseAddGoodsBO
baseRequestBO
)
{
private
GetProductBySkuIdBO
convert2GetProductBySkuIdBO
(
GetCheckSpqBo
getCheckSpqBo
)
{
GetProductBySkuIdBO
getProductBySkuIdBO
=
new
GetProductBySkuIdBO
();
getProductBySkuIdBO
.
setMenuType
(
baseRequestBO
.
getMenuType
());
getProductBySkuIdBO
.
setPartnerId
(
baseRequestBO
.
getPartnerId
());
getProductBySkuIdBO
.
setMenuType
(
getCheckSpqBo
.
getMenuType
());
getProductBySkuIdBO
.
setPartnerId
(
getCheckSpqBo
.
getPartnerId
());
List
<
String
>
skuids
=
new
ArrayList
<>();
skuids
.
add
(
baseRequestBO
.
getSkuId
());
skuids
.
add
(
getCheckSpqBo
.
getSkuId
());
getProductBySkuIdBO
.
setSkuids
(
skuids
);
getProductBySkuIdBO
.
setStoreId
(
baseRequestBO
.
getShop
Id
());
getProductBySkuIdBO
.
setStoreId
(
getCheckSpqBo
.
getStore
Id
());
return
getProductBySkuIdBO
;
}
...
...
shopping-cart-application-service/src/main/java/cn/freemud/demo/service/AbstractAddGoodsService.java
View file @
931b343f
...
...
@@ -277,7 +277,9 @@ public abstract class AbstractAddGoodsService implements AddGoodsService {
getProductBO
.
setPartnerId
(
baseRequestBO
.
getPartnerId
());
if
(
baseRequestBO
.
getSpuId
().
startsWith
(
CommonsConstant
.
COUPON_PREFIX
))
{
CheckSpqBO
checkSpqBO
=
couponService
.
checkSpq
(
baseRequestBO
);
GetCheckSpqBo
getCheckSpqBo
=
new
GetCheckSpqBo
(
baseRequestBO
.
getPartnerId
(),
baseRequestBO
.
getSpuId
().
substring
(
CommonsConstant
.
COUPON_PREFIX
.
length
()),
baseRequestBO
.
getShopId
(),
baseRequestBO
.
getMenuType
(),
baseRequestBO
.
getSpuId
(),
baseRequestBO
.
getSkuId
(),
baseRequestBO
.
getManagerService
().
getProductService
());
CheckSpqBO
checkSpqBO
=
couponService
.
checkSpq
(
getCheckSpqBo
);
if
(
checkSpqBO
==
null
){
return
null
;
}
...
...
@@ -293,17 +295,6 @@ public abstract class AbstractAddGoodsService implements AddGoodsService {
return
getProductBO
;
}
private
GetProductBySkuIdBO
convert2GetProductBySkuIdBO
(
BaseAddGoodsBO
baseRequestBO
)
{
GetProductBySkuIdBO
getProductBySkuIdBO
=
new
GetProductBySkuIdBO
();
getProductBySkuIdBO
.
setMenuType
(
baseRequestBO
.
getMenuType
());
getProductBySkuIdBO
.
setPartnerId
(
baseRequestBO
.
getPartnerId
());
List
<
String
>
skuids
=
new
ArrayList
<>();
skuids
.
add
(
baseRequestBO
.
getSkuId
());
getProductBySkuIdBO
.
setSkuids
(
skuids
);
getProductBySkuIdBO
.
setStoreId
(
baseRequestBO
.
getShopId
());
return
getProductBySkuIdBO
;
}
/**
* 具体业务逻辑校验, 例如商品数量,库存等校验
*
...
...
shopping-cart-application-service/src/main/java/cn/freemud/demo/service/PlatformAddGoodsService.java
View file @
931b343f
...
...
@@ -167,13 +167,6 @@ public class PlatformAddGoodsService extends AbstractAddGoodsService {
@Override
public
AddGoodsToShoppingCartBO
checkCustomBusinessRules
(
BaseAddGoodsBO
baseRequestDTO
,
CheckBussinessRulesBO
checkBussinessRulesBO
,
AddGoodsToShoppingCartBO
addGoodsToShoppingCartBO
)
{
// 商品券商品时间校验
ValidateShopProductRequestBO
validateShopProductRequestBO
=
getValidateShopProductRequestBO
(
checkBussinessRulesBO
.
getProduct
(),
baseRequestDTO
);
ValiadShopProductBO
valiadShopProductBO
=
productManager
.
validateShopProduct
(
validateShopProductRequestBO
,
baseRequestDTO
.
getManagerService
().
getProductService
());
if
(
valiadShopProductBO
==
null
||
CollectionUtils
.
isEmpty
(
valiadShopProductBO
.
getSuccessList
())
){
throw
new
ServiceException
(
ResponseResult
.
SHOPPING_CART_COUPON_NOT_USE
);
}
return
addGoodsToShoppingCartBO
;
}
...
...
shopping-cart-application-service/src/main/java/cn/freemud/demo/service/PlatformUpdateGoodsQtyService.java
View file @
931b343f
...
...
@@ -5,6 +5,7 @@ import cn.freemud.demo.ValidateShopProductRequestBO;
import
cn.freemud.demo.entities.*
;
import
cn.freemud.demo.entities.bo.goods.ProductBO
;
import
cn.freemud.demo.entities.bo.goods.update.UpdateAddGoodsBO
;
import
cn.freemud.demo.manager.coupon.CouponService
;
import
cn.freemud.demo.manager.customer.CustomerManager
;
import
cn.freemud.demo.manager.product.ProductManager
;
import
cn.freemud.demo.manager.store.StoreManager
;
...
...
@@ -44,6 +45,9 @@ public class PlatformUpdateGoodsQtyService extends AbstractUpdateGoodsQtyService
@Autowired
private
ProductManager
productManager
;
@Autowired
private
CouponService
couponService
;
@Override
public
BaseResponse
checkCustomParams
(
UpdateAddGoodsBO
baseRequestDTO
)
{
...
...
@@ -73,7 +77,6 @@ public class PlatformUpdateGoodsQtyService extends AbstractUpdateGoodsQtyService
this
.
setCommonDiscountGoods
(
calculationDiscountGoodsList
,
cartGoods
);
}
else
{
//商品券->商品券ID换取商品
String
goodsId
=
StringUtils
.
isNotBlank
(
cartGoods
.
getSkuId
())
?
cartGoods
.
getSkuId
()
:
cartGoods
.
getSpuId
();
GetCalculationDiscountBO
.
CalculationDiscountCoupon
coupon
=
new
GetCalculationDiscountBO
.
CalculationDiscountCoupon
();
coupon
.
setCode
(
cartGoods
.
getCouponCode
());
...
...
@@ -160,47 +163,26 @@ public class PlatformUpdateGoodsQtyService extends AbstractUpdateGoodsQtyService
@Override
public
AddGoodsToShoppingCartBO
checkCustomBusinessRules
(
UpdateAddGoodsBO
baseRequestDTO
,
CheckBussinessRulesBO
checkBussinessRulesBO
,
AddGoodsToShoppingCartBO
addGoodsToShoppingCartBO
)
{
List
<
CartGoods
>
cartGoodsList
=
addGoodsToShoppingCartBO
.
getCartGoods
();
int
cartSize
=
cartGoodsList
.
size
()
-
1
;
// 校验商品券
// 商品券商品时间校验
ValidateShopProductRequestBO
validateShopProductRequestBO
=
getValidateShopProductRequestBO
(
checkBussinessRulesBO
.
getProduct
(),
baseRequestDTO
);
ValiadShopProductBO
valiadShopProductBO
=
productManager
.
validateShopProduct
(
validateShopProductRequestBO
,
baseRequestDTO
.
getManagerService
().
getProductService
());
if
(
valiadShopProductBO
==
null
||
CollectionUtils
.
isEmpty
(
valiadShopProductBO
.
getSuccessList
())
){
throw
new
ServiceException
(
ResponseResult
.
SHOPPING_CART_COUPON_NOT_USE
);
for
(
int
i
=
cartSize
;
i
>=
0
;
i
--){
CartGoods
cartGoods
=
cartGoodsList
.
get
(
i
);
if
(
cartGoods
.
getCartGoodsUid
().
startsWith
(
CommonsConstant
.
COUPON_PREFIX
)){
GetCheckSpqBo
getCheckSpqBo
=
new
GetCheckSpqBo
(
baseRequestDTO
.
getPartnerId
(),
baseRequestDTO
.
getSpuId
().
substring
(
CommonsConstant
.
COUPON_PREFIX
.
length
()),
baseRequestDTO
.
getShopId
(),
baseRequestDTO
.
getMenuType
(),
cartGoods
.
getSpuId
(),
cartGoods
.
getSkuId
(),
baseRequestDTO
.
getManagerService
().
getProductService
());
CheckSpqBO
checkSpqBO
=
couponService
.
checkSpq
(
getCheckSpqBo
);
if
(
getCheckSpqBo
==
null
){
cartGoodsList
.
remove
(
i
);
}
else
{
cartGoods
.
setActivityCode
(
checkSpqBO
.
getDetails
().
getActiveCode
());
}
}
}
return
addGoodsToShoppingCartBO
;
}
private
ValidateShopProductRequestBO
getValidateShopProductRequestBO
(
ProductBO
product
,
UpdateAddGoodsBO
baseRequestDTO
)
{
ValidateShopProductRequestBO
request
=
new
ValidateShopProductRequestBO
();
request
.
setChannel
(
baseRequestDTO
.
getMenuType
());
request
.
setPartnerId
(
baseRequestDTO
.
getPartnerId
());
request
.
setStoreId
(
baseRequestDTO
.
getShopId
());
List
<
ValidateShopProductType
>
productTypeList
=
new
ArrayList
<>();
ValidateShopProductType
productType
=
new
ValidateShopProductType
();
productType
.
setAttributeList
(
null
);
productType
.
setComboProductTypeList
(
null
);
productType
.
setMemberDiscount
(
null
);
productType
.
setPrice
(
product
.
getFinalPrice
().
intValue
());
productType
.
setProductGroupTypeList
(
null
);
productType
.
setSkuId
(
product
.
getSkuId
());
productType
.
setSpuId
(
product
.
getSpuId
());
productType
.
setUuid
(
UUID
.
randomUUID
().
toString
());
productType
.
setValidateAttribute
(
0
);
productType
.
setValidatePrice
(
0
);
productType
.
setValidateStatuses
(
null
);
productTypeList
.
add
(
productType
);
request
.
setProductTypeList
(
productTypeList
);
return
request
;
}
private
Long
calculateDeliveryAmount
(
String
receiveId
,
String
partnerId
,
String
storeId
,
String
wxappid
,
/*ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo,*/
Integer
orderType
,
ManagerServiceBO
managerServiceBO
)
{
Long
deliveryAmount
=
0L
;
// 如果订单的收获地址为空,且订单是外卖单,返回运费
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment