@ -103,9 +103,9 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
@@ -103,9 +103,9 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
if ( null = = param . getId ( ) ) {
String idPrefix = "SH" + LocalDateTimeUtil . format ( LocalDateTime . now ( ) , "yyyyMMdd" ) ;
receiveGoodsMain . setId ( SnowFlake . nextId ( ) + "" ) ;
String receiptNumber = param . getReceiptNumber ( ) ;
if ( StrUtil . isBlank ( receiptNumber ) ) {
receiptNumber = String . format ( "%s%03d" , idPrefix , redisSerialNumberUtils . generateSerialNumber ( idPrefix ) ) ;
String receiptNumber = param . getReceiptNumber ( ) ;
if ( StrUtil . isBlank ( receiptNumber ) ) {
receiptNumber = String . format ( "%s%03d" , idPrefix , redisSerialNumberUtils . generateSerialNumber ( idPrefix ) ) ;
}
receiveGoodsMain . setReceiptNumber ( receiptNumber ) ;
receiveGoodsMain . setCreateId ( user . getUserId ( ) ) ;
@ -123,6 +123,7 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
@@ -123,6 +123,7 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
receiveGoodsMain . setPackageQuantity ( param . getPackageQuantity ( ) ) ;
receiveGoodsMain . setDeliveryParty ( param . getDeliveryParty ( ) ) ;
receiveGoodsMain . setReceiveTime ( param . getReceiveTime ( ) ) ;
receiveGoodsMain . setSignPersonTime ( LocalDateTime . now ( ) ) ;
receiveGoodsMain . setUpdateId ( user . getUserId ( ) ) ;
receiveGoodsMain . setUpdateTime ( LocalDateTime . now ( ) ) ;
receiveGoodsMain . setUpdateName ( user . getUserName ( ) ) ;
@ -142,15 +143,15 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
@@ -142,15 +143,15 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
}
this . saveOrUpdate ( receiveGoodsMain ) ;
//版本馆直接生成二维码
if ( mainStatusEnum = = ReceiveGoodsMainEnum . MainStatusEnum . LISTING ) {
if ( mainStatusEnum = = ReceiveGoodsMainEnum . MainStatusEnum . LISTING ) {
//生成二维码
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream ( ) ;
DictionaryDataEntity data = dictionaryDataApi . getByTypeDataCode ( "SampleLibrary" , "xtaddr" ) . getData ( ) ;
String systemUrl = "http://61.169.37.106:9172/api/file/Image/preview/" ;
if ( null ! = data ) {
systemUrl = data . getDescription ( ) ;
String systemUrl = "http://61.169.37.106:9172/api/file/Image/preview/" ;
if ( null ! = data ) {
systemUrl = data . getDescription ( ) ;
}
QrCodeUtil . generate ( systemUrl , 1000 , 1000 , "" , byteArrayOutputStream ) ;
QrCodeUtil . generate ( systemUrl , 1000 , 1000 , "" , byteArrayOutputStream ) ;
MockMultipartFile mockMultipartFile = new MockMultipartFile ( "上架.png" , "上架.png" , "text/plain" , byteArrayOutputStream . toByteArray ( ) ) ;
FileInfo preview = fileUploadApi . uploadFile ( mockMultipartFile , fileApi . getPath ( FileTypeConstant . BIVISUALPATH ) , "preview" , "上架.png" ) ;
@ -179,6 +180,9 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
@@ -179,6 +180,9 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
}
List < ReceiveGoodsMainDto . BunchingInfo > bunchingInfoList = param . getBunchingInfoList ( ) ;
Integer quantityReceived = receiveGoodsMain . getQuantityReceived ( ) ;
if ( null = = quantityReceived ) {
quantityReceived = 0 ;
}
final UserInfo user = UserProvider . getUser ( ) ;
//计算签收数量
for ( ReceiveGoodsMainDto . BunchingInfo bunchingInfo : bunchingInfoList ) {
@ -196,9 +200,9 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
@@ -196,9 +200,9 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
. eq ( TBookGoWhere : : getCreateCorpId , receiveGoodsMain . getCreateCorpId ( ) )
//todo 非样书室时根据所属类型及部门id去查询应送数量
//版本馆根据类型匹配
. eq ( StrUtil . equals ( param . getOrderType ( ) , "2 " ) , TBookGoWhere : : getOrderType , param . getOrderType ( ) )
. eq ( ! StrUtil . equals ( param . getOrderType ( ) , "3 " ) , TBookGoWhere : : getOrderType , param . getOrderType ( ) )
//业务部根据部门id匹配
. eq ( StrUtil . equals ( param . getOrderType ( ) , "1" ) , TBookGoWhere : : getCreateDeptId , receiveGoodsMain . getCreateDeptId ( ) )
// .eq(StrUtil.equals(param.getOrderType(), "1"), TBookGoWhere::getCreateDeptId, receiveGoodsMain.getCreateDeptId())
. eq ( TBookGoWhere : : getWarehouseEntryFlag , "0" )
. eq ( TBookGoWhere : : getType , "0" )
. eq ( TBookGoWhere : : getDelFlag , "0" )
@ -239,22 +243,9 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
@@ -239,22 +243,9 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
if ( StrUtil . isBlank ( bookNumber ) ) {
throw new DataException ( "请输入图书编号" ) ;
}
//查询图书信息
Optional < TLibrary > bookInfo = libraryService . lambdaQuery ( )
. eq ( TLibrary : : getBookNumber , bookNumber )
. list ( ) . stream ( ) . findFirst ( ) ;
if ( ! bookInfo . isPresent ( ) ) {
throw new DataException ( "未查询到图书信息" ) ;
}
TLibrary library = bookInfo . get ( ) ;
ReceiveGoodsMainDto . BunchingInfo bunchingInfo = new ReceiveGoodsMainDto . BunchingInfo ( ) ;
bunchingInfo . setBookNumber ( bookNumber ) ;
bunchingInfo . setBookName ( library . getBookName ( ) ) ;
bunchingInfo . setCoverImage ( library . getCoverImage ( ) ) ;
bunchingInfo . setPress ( library . getPress ( ) ) ;
bunchingInfo . setPrice ( library . getPrice ( ) ) ;
//todo 新增下印册书
return bunchingInfo ;
//查询图书信息
return libraryService . getBunchingInfoByBookNumber ( bookNumber ) ;
}
@Override
@ -298,7 +289,16 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
@@ -298,7 +289,16 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
if ( orderTypeEnum = = ReceiveGoodsMainEnum . OrderTypeEnum . SAMPLE_BOOKSTORE ) {
param . setUserId ( UserProvider . getUser ( ) . getUserId ( ) ) ;
} else {
param . setCorpId ( UserProvider . getUser ( ) . getOrganizeId ( ) ) ;
if ( StrUtil . isNotBlank ( UserProvider . getUser ( ) . getOrganizeId ( ) ) ) {
Optional < OrganizeEntity > deptOptional = organizeService . lambdaQuery ( )
. eq ( OrganizeEntity : : getId , UserProvider . getUser ( ) . getOrganizeId ( ) )
. eq ( OrganizeEntity : : getEnabledMark , "1" ) . list ( ) . stream ( ) . findFirst ( ) ;
if ( deptOptional . isPresent ( ) ) {
OrganizeEntity dept = deptOptional . get ( ) ;
OrganizeEntity corp = getCorp ( dept ) ;
param . setCorpId ( corp . getId ( ) ) ;
}
}
}
try {
LocalDateTimeUtil . parse ( param . getStartTime ( ) , "yyyy-MM-dd HH:mm:ss" ) ;
@ -324,14 +324,26 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
@@ -324,14 +324,26 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
boolean exists = bookGoWhereService . lambdaQuery ( )
. eq ( TBookGoWhere : : getDelFlag , "0" )
. eq ( TBookGoWhere : : getType , "1" )
. eq ( TBookGoWhere : : getBookNumber , receiveGoodsBooks . getBookNumber ( ) )
. eq ( TBookGoWhere : : getRelationId , receiveGoodsBooks . getId ( ) )
. exists ( ) ;
if ( exists ) {
//查询已有数据
return bookGoWhereService . getStackingInformationByRelationId ( receiveGoodsBooks . getId ( ) ) ;
return bookGoWhereService . getStackingInformationByRelationId ( receiveGoodsBooks . getBookNumber ( ) , receiveGoodsBooks . get Id ( ) ) ;
} else {
if ( StrUtil . isNotBlank ( UserProvider . getUser ( ) . getOrganizeId ( ) ) ) {
Optional < OrganizeEntity > deptOptional = organizeService . lambdaQuery ( )
. eq ( OrganizeEntity : : getId , UserProvider . getUser ( ) . getOrganizeId ( ) )
. eq ( OrganizeEntity : : getEnabledMark , "1" ) . list ( ) . stream ( ) . findFirst ( ) ;
if ( deptOptional . isPresent ( ) ) {
OrganizeEntity dept = deptOptional . get ( ) ;
OrganizeEntity corp = getCorp ( dept ) ;
//查询初始化去向数据
return bookGoWhereService . getStackingInformation ( receiveGoodsBooks . getBookNumber ( ) , UserProvider . getUser ( ) . getOrganizeId ( ) ) ;
return bookGoWhereService . getStackingInformation ( receiveGoodsBooks . getBookNumber ( ) , corp . getId ( ) ) ;
}
}
return null ;
}
//todo 添加已发数
}
@ -355,9 +367,17 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
@@ -355,9 +367,17 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
if ( null = = receiveGoodsBooks ) {
throw new DataException ( "该图书信息不存在" ) ;
}
//校验分堆设置是否已存在,已存在的话直接删除,防止多次提交
bookGoWhereService . lambdaUpdate ( )
. eq ( TBookGoWhere : : getDelFlag , "0" )
. eq ( TBookGoWhere : : getType , "1" )
. eq ( TBookGoWhere : : getBookNumber , receiveGoodsBooks . getBookNumber ( ) )
. eq ( TBookGoWhere : : getRelationId , receiveGoodsBooks . getId ( ) )
. remove ( ) ;
for ( TBookGoWhere bookGoWhere : param . getBookGoWhereList ( ) ) {
bookGoWhere . setId ( SnowFlake . nextId ( ) ) ;
bookGoWhere . setCreateTime ( LocalDateTime . now ( ) ) ;
bookGoWhere . setBookNumber ( receiveGoodsBooks . getBookNumber ( ) ) ;
bookGoWhere . setCreateBy ( UserProvider . getUser ( ) . getUserId ( ) ) ;
bookGoWhere . setCreateName ( UserProvider . getUser ( ) . getUserName ( ) ) ;
bookGoWhere . setUpdateTime ( LocalDateTime . now ( ) ) ;
@ -384,7 +404,7 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
@@ -384,7 +404,7 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
@Override
@Transactional
@Transactional ( rollbackFor = Exception . class )
public void saveStackingInformationByReceiveId ( ReceiveGoodsMainDto . SaveStackingInformationByReceiveIdParam param ) {
if ( StrUtil . isBlank ( param . getSaveType ( ) ) ) {
throw new DataException ( "请选择保存类型" ) ;
@ -410,6 +430,50 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
@@ -410,6 +430,50 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
. update ( ) ;
return ;
}
String corpId = "" ;
if ( StrUtil . isNotBlank ( UserProvider . getUser ( ) . getOrganizeId ( ) ) ) {
Optional < OrganizeEntity > deptOptional = organizeService . lambdaQuery ( )
. eq ( OrganizeEntity : : getId , UserProvider . getUser ( ) . getOrganizeId ( ) )
. eq ( OrganizeEntity : : getEnabledMark , "1" ) . list ( ) . stream ( ) . findFirst ( ) ;
if ( deptOptional . isPresent ( ) ) {
OrganizeEntity dept = deptOptional . get ( ) ;
OrganizeEntity corp = getCorp ( dept ) ;
//查询初始化去向数据
corpId = corp . getId ( ) ;
}
}
//确定时对所有未保存的分堆信息进行保存(即无需分堆的图书)
//校验该选书是否进行过保存分堆信息
final String organizeId = corpId ;
//先查询已保存的图书列表
// CompletableFuture.runAsync(() -> {
for ( TReceiveGoodsBooks tReceiveGoodsBooks : receiveGoodsBooksService . lambdaQuery ( )
. eq ( TReceiveGoodsBooks : : getRelationId , tReceiveGoodsMain . getId ( ) )
. eq ( TReceiveGoodsBooks : : getDelFlag , "0" )
. list ( ) ) {
boolean exists = bookGoWhereService . lambdaQuery ( )
. eq ( TBookGoWhere : : getDelFlag , "0" )
. eq ( TBookGoWhere : : getType , "1" )
. eq ( TBookGoWhere : : getBookNumber , tReceiveGoodsBooks . getBookNumber ( ) )
. eq ( TBookGoWhere : : getRelationId , tReceiveGoodsBooks . getId ( ) )
. exists ( ) ;
if ( exists ) {
continue ;
}
List < ReceiveGoodsMainDto . TBookGoWhereEntity > stackingInformation = bookGoWhereService . getStackingInformation ( tReceiveGoodsBooks . getBookNumber ( ) , organizeId ) ;
ReceiveGoodsMainDto . SaveStackingInformationParam saveParam = new ReceiveGoodsMainDto . SaveStackingInformationParam ( ) ;
saveParam . setOrderType ( param . getOrderType ( ) ) ;
saveParam . setId ( tReceiveGoodsBooks . getId ( ) . toString ( ) ) ;
List < TBookGoWhere > stackingList = new ArrayList < > ( ) ;
for ( ReceiveGoodsMainDto . TBookGoWhereEntity tBookGoWhereEntity : stackingInformation ) {
stackingList . add ( BeanUtil . copyProperties ( tBookGoWhereEntity , TBookGoWhere . class ) ) ;
}
saveParam . setBookGoWhereList ( stackingList ) ;
this . saveStackingInformation ( saveParam ) ;
}
// });
//以下逻辑全是确定
ReceiveGoodsMainEnum . MainStatusEnum mainStatusEnum = ReceiveGoodsMainEnum . MainStatusEnum . LISTING ;
//查询图书编号列表
@ -418,56 +482,81 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
@@ -418,56 +482,81 @@ public class TReceiveGoodsMainServiceImpl extends ServiceImpl<TReceiveGoodsMainM
. eq ( TReceiveGoodsBooks : : getDelFlag , "0" )
. list ( )
. stream ( ) . map ( TReceiveGoodsBooks : : getBookNumber ) . collect ( Collectors . toSet ( ) ) ;
if ( CollUtil . isNotEmpty ( bookNumberList ) ) {
//修改图书去向 即之后样书室新建后进行分堆不会再查到老数据
bookGoWhereService . lambdaUpdate ( )
//签收后保存的需要手机端上架后才能修改上架状态,初始化数据可以修改
. set ( TBookGoWhere : : getWarehouseEntryFlag , "1" )
. eq ( TBookGoWhere : : getType , "0" )
. eq ( TBookGoWhere : : getDelFlag , "0" )
. eq ( TBookGoWhere : : getWarehouseEntryFlag , "0" )
. eq ( TBookGoWhere : : getCreateCorpId , corpId )
. in ( TBookGoWhere : : getBookNumber , bookNumberList )
. eq ( TBookGoWhere : : getOrderType , orderTypeEnum . getCode ( ) )
. update ( ) ;
}
//查询是否具有送往版本馆及业务部的数据,有的话就创建收货单
Set < String > otherSH = bookGoWhereService . lambdaQuery ( )
. eq ( TBookGoWhere : : getType , "0" )
. eq ( TBookGoWhere : : getDelFlag , "0" )
. eq ( TBookGoWhere : : getWarehouseEntryFlag , "0" )
. in ( TBookGoWhere : : getTargetName , Arrays . asList ( ReceiveGoodsMainEnum . OrderTypeEnum . BUSINESS_DEPARTMENT . getDescribe ( ) , ReceiveGoodsMainEnum . OrderTypeEnum . VERSION_LIBRARY . getDescribe ( ) ) )
. in ( TBookGoWhere : : getBookNumber , bookNumberList )
. eq ( TBookGoWhere : : getCreateCorpId , corpId )
. list ( ) . stream ( ) . map ( TBookGoWhere : : getTargetName ) . collect ( Collectors . toSet ( ) ) ;
if ( CollUtil . isNotEmpty ( otherSH ) ) {
for ( String sh : otherSH ) {
String orderType = "" ;
if ( StrUtil . equals ( ReceiveGoodsMainEnum . OrderTypeEnum . BUSINESS_DEPARTMENT . getDescribe ( ) , sh ) ) {
orderType = ReceiveGoodsMainEnum . OrderTypeEnum . BUSINESS_DEPARTMENT . getCode ( ) ;
}
if ( StrUtil . equals ( ReceiveGoodsMainEnum . OrderTypeEnum . VERSION_LIBRARY . getDescribe ( ) , sh ) ) {
orderType = ReceiveGoodsMainEnum . OrderTypeEnum . VERSION_LIBRARY . getCode ( ) ;
}
if ( StrUtil . isBlank ( orderType ) ) {
continue ;
}
//生成版本馆/业务部收货单
ReceiveGoodsMainDto . NewReceiptParam newReceiptParam = new ReceiveGoodsMainDto . NewReceiptParam ( ) ;
ReceiveGoodsMainDto . NewReceiptParam newReceiptParam = new ReceiveGoodsMainDto . NewReceiptParam ( ) ;
newReceiptParam . setOrderType ( orderType ) ;
newReceiptParam . setReceiptNumber ( tReceiveGoodsMain . getReceiptNumber ( ) ) ;
newReceiptParam . setOrderType ( param . getOrderType ( ) ) ;
newReceiptParam . setPackageQuantity ( tReceiveGoodsMain . getPackageQuantity ( ) ) ;
newReceiptParam . setDeliveryParty ( tReceiveGoodsMain . getDeliveryParty ( ) ) ;
newReceiptParam . setReceiveTime ( tReceiveGoodsMain . getReceiveTime ( ) ) ;
List < ReceiveGoodsMainDto . BunchingInfo > bunchingInfoList = new ArrayList < > ( ) ;
newReceiptParam . setSaveType ( "1" ) ;
newReceiptParam . setPackageSituation ( tReceiveGoodsMain . getPackageSituation ( ) ) ;
List < ReceiveGoodsMainDto . BunchingInfo > bunchingInfoList = new ArrayList < > ( ) ;
//查询图书编号
Set < String > queryBookInfoNumberList = bookGoWhereService . lambdaQuery ( )
. eq ( TBookGoWhere : : getType , "0" )
. eq ( TBookGoWhere : : getDelFlag , "0" )
. eq ( TBookGoWhere : : getWarehouseEntryFlag , "0" )
// .in(TBookGoWhere::getTargetName, Arrays.asList(ReceiveGoodsMainEnum.OrderTypeEnum.BUSINESS_DEPARTMENT.getDescribe(), ReceiveGoodsMainEnum.OrderTypeEnum.VERSION_LIBRARY.getDescribe()))
. in ( TBookGoWhere : : getBookNumber , bookNumberList )
. eq ( TBookGoWhere : : getCreateCorpId , UserProvider . getUser ( ) . getOrganizeId ( ) )
. eq ( TBookGoWhere : : getOrderType , orderTypeEnum . getCode ( ) )
. eq ( TBookGoWhere : : getCreateCorpId , co rp Id)
. eq ( TBookGoWhere : : getOrderType , orderType )
. list ( ) . stream ( ) . map ( TBookGoWhere : : getBookNumber ) . collect ( Collectors . toSet ( ) ) ;
List < TLibrary > libraryList = libraryService . lambdaQuery ( )
. in ( TLibrary : : getBookNumber , queryBookInfoNumberList )
. list ( ) ;
List < TLibrary > libraryList = libraryService . getListByBookNumberList ( queryBookInfoNumberList ) ;
//创建收货单
if ( CollUtil . isNotEmpty ( libraryList ) ) {
if ( CollUtil . isNotEmpty ( libraryList ) ) {
for ( TLibrary tLibrary : libraryList ) {
bunchingInfoList . add ( BeanUtil . copyProperties ( tLibrary , ReceiveGoodsMainDto . BunchingInfo . class ) ) ;
bunchingInfoList . add ( BeanUtil . copyProperties ( tLibrary , ReceiveGoodsMainDto . BunchingInfo . class ) ) ;
}
newReceiptParam . setBunchingInfoList ( bunchingInfoList ) ;
this . newReceipt ( newReceiptParam ) ;
}
}
if ( CollUtil . isNotEmpty ( bookNumberList ) ) {
//修改图书去向 即之后样书室新建后进行分堆不会再查到老数据
bookGoWhereService . lambdaUpdate ( )
//签收后保存的需要手机端上架后才能修改上架状态,初始化数据可以修改
. set ( TBookGoWhere : : getWarehouseEntryFlag , "1" )
. eq ( TBookGoWhere : : getType , "0" )
. eq ( TBookGoWhere : : getDelFlag , "0" )
. eq ( TBookGoWhere : : getWarehouseEntryFlag , "0" )
. eq ( TBookGoWhere : : getCreateCorpId , UserProvider . getUser ( ) . getOrganizeId ( ) )
. in ( TBookGoWhere : : getBookNumber , bookNumberList )
. eq ( TBookGoWhere : : getOrderType , orderTypeEnum . getCode ( ) )
. update ( ) ;
}
//生成二维码
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream ( ) ;
DictionaryDataEntity data = dictionaryDataApi . getByTypeDataCode ( "SampleLibrary" , "xtaddr" ) . getData ( ) ;
String systemUrl = "http://61.169.37.106:9172/api/file/Image/preview/" ;
if ( null ! = data ) {
systemUrl = data . getDescription ( ) ;
String systemUrl = "http://61.169.37.106:9172/api/file/Image/preview/" ;
if ( null ! = data ) {
systemUrl = data . getDescription ( ) ;
}
QrCodeUtil . generate ( systemUrl , 1000 , 1000 , "" , byteArrayOutputStream ) ;
QrCodeUtil . generate ( systemUrl , 1000 , 1000 , "" , byteArrayOutputStream ) ;
MockMultipartFile mockMultipartFile = new MockMultipartFile ( "上架.png" , "上架.png" , "text/plain" , byteArrayOutputStream . toByteArray ( ) ) ;
FileInfo preview = fileUploadApi . uploadFile ( mockMultipartFile , fileApi . getPath ( FileTypeConstant . BIVISUALPATH ) , "preview" , "上架.png" ) ;