Commit ac09da2d authored by frank.xa.zhang's avatar frank.xa.zhang

remove blank

parent 6edf0b16
......@@ -18,6 +18,7 @@ public class FTPClientPool {
private GenericObjectPool<FTPClient> pool;
private String ftpRootPath;
private static final String SYMBOL = "/";
private FTPClientConfig ftpClientConfig;
@Value("${ftp.host}")
private String ftpHost;
......@@ -36,6 +37,7 @@ public class FTPClientPool {
clientConfig.setPort(ftpPort);
clientConfig.setUsername(ftpUser);
clientConfig.setPassword(ftpPwd);
ftpClientConfig = clientConfig;
pool = new GenericObjectPool<>(new FtpClientFactory(clientConfig), config);
ftpRootPath = pool.borrowObject().printWorkingDirectory();
}
......@@ -54,19 +56,23 @@ public class FTPClientPool {
*/
public void upload(String filePath, String fileName, InputStream inputStream) throws Exception {
String upPath;
if (StringUtils.isBlank(filePath)) {
upPath = ftpRootPath;
} else {
upPath = filePath;
}
if (!StringUtils.endsWith(upPath, SYMBOL)) {
upPath = upPath + SYMBOL;
}
FTPClient client = getClient();
if (!isExist(upPath, client)) {
mkDir(upPath, client);
try {
if (StringUtils.isBlank(filePath)) {
upPath = ftpRootPath;
} else {
upPath = filePath;
}
if (!StringUtils.endsWith(upPath, SYMBOL)) {
upPath = upPath + SYMBOL;
}
if (!isExist(upPath, client)) {
mkDir(upPath, client);
}
client.storeFile(upPath + fileName, inputStream);
} finally {
pool.returnObject(client);
}
client.storeFile(upPath + fileName, inputStream);
}
/**
......@@ -78,8 +84,12 @@ public class FTPClientPool {
*/
public InputStream download(String filePath) throws Exception {
FTPClient client = getClient();
client.changeWorkingDirectory(ftpRootPath);
return StringUtils.isBlank(filePath) ? null : client.retrieveFileStream(filePath);
try {
client.changeWorkingDirectory(ftpRootPath);
return StringUtils.isBlank(filePath) ? null : client.retrieveFileStream(filePath);
} finally {
pool.returnObject(client);
}
}
private void mkDir(String path, FTPClient ftpClient) throws IOException {
......@@ -121,12 +131,19 @@ public class FTPClientPool {
if (StringUtils.isBlank(filePath)) {
return;
}
FTPClient client = getClient();
if (!isExist(filePath, client)) {
return;
} else {
client.deleteFile(filePath);
try {
if (!isExist(filePath, client)) {
return;
} else {
client.deleteFile(filePath);
}
} finally {
pool.returnObject(client);
}
}
public FTPClientConfig getFtpClientConfig() {
return ftpClientConfig;
}
}
......@@ -17,23 +17,23 @@ public class ReportController {
@Autowired
ReportService reportService;
@RequestMapping(value = "template/{organizationID}/{serviceType}/{period}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public OperationResultDto<List<ReportDto>> getTemplate(@PathVariable String organizationID,@PathVariable int serviceType, @PathVariable Integer period) {
return reportService.getReportTemplate(organizationID, EnumServiceType.getEnumByCode(serviceType), period);
@RequestMapping(value = "template/{projectID}/{serviceType}/{period}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public OperationResultDto<List<ReportDto>> getTemplate(@PathVariable String projectID, @PathVariable int serviceType, @PathVariable Integer period) {
return reportService.getReportTemplate(projectID, EnumServiceType.getEnumByCode(serviceType), period);
}
@RequestMapping(value = "updateConfig/{projectId}/{ifDeleteManualDataSource}/{period}", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public OperationResultDto updateConfig(@PathVariable String projectId,@PathVariable Boolean ifDeleteManualDataSource, @PathVariable Integer period, @RequestParam String generator) {
public OperationResultDto updateConfig(@PathVariable String projectId, @PathVariable Boolean ifDeleteManualDataSource, @PathVariable Integer period, @RequestParam String generator) {
return reportService.updateConfig(projectId, period, ifDeleteManualDataSource, generator);
}
@RequestMapping(value = "generateByTotal/{projectId}/{ifDeleteManualDataSource}/{period}",method = RequestMethod.POST,produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public OperationResultDto generateAllData(@PathVariable String projectId,@PathVariable Boolean ifDeleteManualDataSource,@PathVariable Integer period,@RequestParam String generator){
return reportService.generateData(projectId,EnumServiceType.VAT,ifDeleteManualDataSource,period,null,generator);
@RequestMapping(value = "generateByTotal/{projectId}/{ifDeleteManualDataSource}/{period}", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public OperationResultDto generateAllData(@PathVariable String projectId, @PathVariable Boolean ifDeleteManualDataSource, @PathVariable Integer period, @RequestParam String generator) {
return reportService.generateData(projectId, EnumServiceType.VAT, ifDeleteManualDataSource, period, null, generator);
}
@RequestMapping(value = "templateReferences/{period}",method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public List<CellTemplateReferenceDto> getTemplateReferences(@PathVariable int period){
@RequestMapping(value = "templateReferences/{period}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public List<CellTemplateReferenceDto> getTemplateReferences(@PathVariable int period) {
return reportService.getTemplateReferences(period);
}
}
......@@ -7,6 +7,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import pwc.taxtech.atms.dto.vatdto.TemplateByGroupDto;
import pwc.taxtech.atms.exception.ApplicationException;
import pwc.taxtech.atms.common.ftp.FTPClientPool;
import pwc.taxtech.atms.dto.*;
......@@ -137,4 +138,15 @@ public class TemplateController extends BaseController {
}
}
@RequestMapping(value = "getGroupTemplateByGroupID", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public @ResponseBody
OperationResultDto<List<TemplateByGroupDto>> getGroupTemplateByGroupID(@RequestParam Long templateGroupID, @RequestParam String projectID) {
OperationResultDto resultDto = new OperationResultDto();
if (templateGroupID == null || templateGroupID.equals("undefined") || StringUtils.isBlank(projectID) || projectID.equals("undefined")) {
resultDto.setResult(false);
return resultDto;
}
return templateService.getByGroupID(templateGroupID, projectID);
}
}
......@@ -7,6 +7,7 @@ import org.apache.ibatis.session.RowBounds;
import pwc.taxtech.atms.MyMapper;
import pwc.taxtech.atms.entitiy.Industry;
import pwc.taxtech.atms.entitiy.IndustryExample;
import pwc.taxtech.atms.entitiy.TemplateGroup;
@Mapper
public interface IndustryMapper extends MyMapper {
......@@ -107,4 +108,6 @@ public interface IndustryMapper extends MyMapper {
int updateByPrimaryKey(Industry record);
List<Industry> getAllAvailableIndustry();
List<TemplateGroup> getTemplateGroup();
}
\ No newline at end of file
package pwc.taxtech.atms.dto.vatdto;
import lombok.Getter;
import lombok.Setter;
import pwc.taxtech.atms.dto.TemplateDto;
import java.util.List;
@Getter
@Setter
public class TemplateByGroupDto {
private Long id ;
private String name ;
private int OrderIndex ;
private List<TemplateDto> children ;
}
package pwc.taxtech.atms.service;
import pwc.taxtech.atms.dto.*;
import pwc.taxtech.atms.dto.vatdto.TemplateByGroupDto;
import pwc.taxtech.atms.entitiy.Template;
import java.util.List;
......@@ -24,4 +25,6 @@ public interface TemplateService {
OperationResultDto<String> deleteTemplate(DeleteTemplateParam param);
OperationResultDto setRowColName(Long id,List<CellBriefDto> cellInfo);
OperationResultDto<List<TemplateByGroupDto>> getByGroupID(Long templateGroupID, String projectID);
}
......@@ -125,4 +125,6 @@ public class AbstractService {
protected FormulaConfigMapper formulaConfigMapper;
@Autowired
DistributedIDService distributedIDService;
@Autowired
ProjectMapper projectMapper;
}
......@@ -5,11 +5,11 @@ import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import pwc.taxtech.atms.common.CommonUtils;
import pwc.taxtech.atms.constant.Constant;
import pwc.taxtech.atms.constant.enums.TemplateGroupType;
import pwc.taxtech.atms.dao.ProjectMapper;
import pwc.taxtech.atms.dto.*;
import pwc.taxtech.atms.entitiy.CellTemplate;
import pwc.taxtech.atms.entitiy.CellTemplateExample;
import pwc.taxtech.atms.entitiy.Template;
import pwc.taxtech.atms.entitiy.TemplateExample;
import pwc.taxtech.atms.dto.vatdto.TemplateByGroupDto;
import pwc.taxtech.atms.entitiy.*;
import pwc.taxtech.atms.service.TemplateService;
import java.util.*;
......@@ -224,6 +224,75 @@ public class TemplateServiceImpl extends AbstractService implements TemplateServ
return result;
}
@Override
public OperationResultDto<List<TemplateByGroupDto>> getByGroupID(Long templateGroupID, String projectID) {
OperationResultDto result = new OperationResultDto();
Long bspl = getBSPLTemplateGroup(projectID);
TemplateExample example = new TemplateExample();
List<Long> ids = new ArrayList<>();
ids.add(templateGroupID);
ids.add(bspl);
example.createCriteria().andTemplateGroupIdIn(ids);
example.setOrderByClause(" order_index");
List<Template> templates = templateMapper.selectByExample(example);
TemplateByGroupDto bsplGroup = new TemplateByGroupDto();
bsplGroup.setId(bspl);
bsplGroup.setName(TemplateGroupType.FinancialReturn.name());
List<TemplateDto> templateDtos = new ArrayList<>();
templates.stream().filter(x -> x.getTemplateGroupId().equals(bspl)).collect(Collectors.toList()).forEach(a -> {
TemplateDto templateDto = new TemplateDto();
CommonUtils.copyProperties(a, templateDto);
templateDtos.add(templateDto);
});
bsplGroup.setChildren(templateDtos);
bsplGroup.setOrderIndex(1);
TemplateByGroupDto taxReturnGroup = new TemplateByGroupDto();
taxReturnGroup.setId(templateGroupID);
taxReturnGroup.setName(TemplateGroupType.TaxReturn.name());
List<TemplateDto> templateDtos2 = new ArrayList<>();
templates.stream().filter(x -> x.getTemplateGroupId().equals(templateGroupID)).collect(Collectors.toList()).forEach(a -> {
TemplateDto templateDto = new TemplateDto();
CommonUtils.copyProperties(a, templateDto);
templateDtos2.add(templateDto);
});
taxReturnGroup.setChildren(templateDtos2);
taxReturnGroup.setOrderIndex(2);
List<TemplateByGroupDto> wrappList = new ArrayList<>();
wrappList.add(bsplGroup);
wrappList.add(taxReturnGroup);
result.setResult(true);
result.setData(wrappList);
return result;
}
private Long getBSPLTemplateGroup(String projectID) {
ProjectExample example = new ProjectExample();
example.createCriteria().andIDEqualTo(projectID);
List<Project> projects = projectMapper.selectByExample(example);
Optional<String> industryID = projects.stream().map(Project::getIndustryID).findFirst();
if (industryID == null) {
return null;
}
List<TemplateGroup> allTemplateGroups = templateGroupMapper.selectByExample(new TemplateGroupExample());
Optional<TemplateGroup> bsplTemplateGroup = allTemplateGroups.stream().filter(a -> a.getIndustryIds().equals(industryID) && a.getGroupType().equals(TemplateGroupType.FinancialReturn.getCode())).findFirst();
if (bsplTemplateGroup == null) {
bsplTemplateGroup = allTemplateGroups.stream().filter(a -> a.getIndustryIds().contains(industryID.get()) && a.getGroupType().equals(TemplateGroupType.FinancialReturn.getCode())).findFirst();
}
if (bsplTemplateGroup == null) {
bsplTemplateGroup = industryMapper.getTemplateGroup().stream().findFirst();
}
if (bsplTemplateGroup == null) {
return null;
}
return bsplTemplateGroup.get().getId();
}
private void logicDeleteIsActiveAssociation(Template templateDb) {
templateDb.setIsActiveAssociation(false);
templateMapper.updateByPrimaryKeySelective(templateDb);
......
......@@ -59,7 +59,13 @@ public class ReportServiceImpl extends VatAbstractService implements ReportServi
String serviceTypeStr = serviceType.getCode().toString();
ProjectServiceTypeExample projectServiceTypeExample = new ProjectServiceTypeExample();
projectServiceTypeExample.createCriteria().andServiceTypeIDEqualTo(serviceTypeStr).andProjectIDEqualTo(projectID);
templateGroupID = projectServiceTypeMapper.selectByExample(projectServiceTypeExample).stream().map(ProjectServiceType::getTemplateGroupID).findFirst().get();
Optional<Long> tempVlaue = projectServiceTypeMapper.selectByExample(projectServiceTypeExample).stream().map(ProjectServiceType::getTemplateGroupID).findFirst();
if(tempVlaue.isPresent()){
templateGroupID = tempVlaue.get();
}
else{
templateGroupID = 0L;
}
}
String dbName = ShardingContextHolder.getDataSourceKey();
......
......@@ -11,7 +11,9 @@ import pwc.taxtech.atms.dto.vatdto.CellTemplatePerGroupDto;
import java.util.List;
import java.util.Optional;
/**
* Already unused
*/
public class SGSR implements FreeRefFunction {
private FormulaContext formulaContext;
......
......@@ -281,4 +281,34 @@
isActive = 1
AND Name IN ('通用行业' ,'房地产业', '资产管理', '银行及其他金融服务业')
</select>
<resultMap id="TemplateGroup" type="pwc.taxtech.atms.entitiy.Template">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<id column="id" jdbcType="BIGINT" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="code" jdbcType="VARCHAR" property="code" />
<result column="path" jdbcType="VARCHAR" property="path" />
<result column="report_type" jdbcType="INTEGER" property="reportType" />
<result column="template_group_id" jdbcType="BIGINT" property="templateGroupId" />
<result column="order_index" jdbcType="INTEGER" property="orderIndex" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
<result column="is_system_type" jdbcType="INTEGER" property="isSystemType" />
<result column="is_active_association" jdbcType="INTEGER" property="isActiveAssociation" />
<result column="parent_id" jdbcType="VARCHAR" property="parentId" />
<result column="create_by" jdbcType="VARCHAR" property="createBy" />
<result column="update_by" jdbcType="VARCHAR" property="updateBy" />
</resultMap>
<select id="getTemplateGroup" resultMap="TemplateGroup">
SELECT *
FROM Industry a
JOIN template_group b
ON a.ID = b.industry_ids
WHERE a.Name = '通用行业'
AND b.group_type = 2
LIMIT 1
</select>
</mapper>
\ No newline at end of file
commonModule.directive('vatReportSheet', ['$rootScope', '$log', '$timeout', '$q', 'templateService', 'enums', 'keyValueDataService', 'spreadJsTipService',
'$interval', 'vatSessionService',
function ($rootScope, $log, $timeout, $q, templateService, enums, keyValueDataService, spreadJsTipService, $interval, vatSessionService) {
'use strict';
$log.debug('vatReportSheet.ctor()...');
return {
restrict: 'E',
template: '<div class="report" style="height: 100%;"></div>',
replace: true,
scope: {
templateId: '=',
spread: '=',
reportSource: '=',
formulaBlocks: '=',
manualDataSources: '=',
isReadOnly: '=',
serviceType: '=',
initRow: '=?',
initCol: '=?',
reportApi: '=?', // In: onCellClick, onCellDoubleClick; Out: refreshReport
},
link: function (scope, element) {
$log.debug('vatReportSheet.link()...');
// Register api functions in internalApi
// If selectorApi passed is not undefined, we will use it as internalApi
scope.internalApi = scope.reportApi || {};
scope.projectYear = vatSessionService.year;
scope.projectPeriod = scope.serviceType === enums.serviceType.VAT ? vatSessionService.month : 0;
scope.$watch('templateId', function (newVal, oldValue) {
if (newVal !== oldValue) {
loadSheet(newVal);
}
});
scope.$watchGroup(['reportSource', 'formulaBlocks', 'manualDataSources', 'templateId', 'hasLoadSpread'], function (newVal, oldValue) {
if (scope.templateId && scope.reportSource && scope.hasLoadSpread) {
setData();
}
});
// 首次进入页面时,通过promise模式保证在加载完成后再调用locateCell以focus在特定单元格
// 如果是在当前页面要focus在特定单元格,通过watch行列号来完成
scope.$watchGroup(['initRow', 'initCol'], function (newVal, oldVal) {
if (_.isNumber(scope.initRow) && _.isNumber(scope.initCol)) {
var spreadCtrl = getSpreadControl();
if (spreadCtrl) {
locateCell(spreadCtrl);
}
spreadCtrl = null;
}
});
var locateCell = function (spread, forceCloseModal) {
if (_.isNumber(scope.initRow) && _.isNumber(scope.initCol)) {
var sheet = spread.getActiveSheet();
sheet.setSelection(scope.initRow, scope.initCol, 1, 1);
if (_.isFunction(scope.internalApi.onCellClick) && !forceCloseModal) {
scope.internalApi.onCellClick({
'args': { row: scope.initRow, col: scope.initCol },
'data': JSON.parse(sheet.getTag(scope.initRow, scope.initCol))
});
}
$log.debug(sheet.getTag(scope.initRow, scope.initCol));
scope.initRow = null;
scope.initCol = null;
sheet = null;
return $q.when();
}
};
var loadSheet = function (templateId) {
return templateService.getTemplateJson(templateId).success(function (reportSpread) {
var spreadCtrl = getSpreadControl();
if (spreadCtrl) {
spreadCtrl.destroy();
}
spreadCtrl = null;
if (!_.isEmpty(reportSpread)) {
initSpreadExcel(reportSpread).then(function (spread) {
return locateCell(spread, true);
});
}
}).error(function (data) {
$log.info(data);
});
};
var initSpreadExcel = function (reportSpread) {
var spread = new GcSpread.Sheets.Spread(getSpreadControlElement());
spread.showVerticalScrollbar(false);
spread.showHorizontalScrollbar(true);
spread.scrollbarMaxAlign(true);
spread.scrollbarShowMax(true);
spread.tabNavigationVisible(true);
spread.newTabVisible(false);
spread.tabEditable(false);
spread.tabStripVisible(false);
spread.newTabVisible(false);
spread.allowUndo(false);
spread.allowUserResize(false);
spread.canUserDragDrop(false);
spread.canUserDragFill(false);
spread.canUserEditFormula(false);
spread.isPaintSuspended(true);
spread.fromJSON(JSON.parse(reportSpread));
initInterFunction(spread);
var sheet = spread.getActiveSheet();
if (sheet != null) {
sheet.setRowHeaderVisible(true);
sheet.setColumnHeaderVisible(true);
sheet.setGridlineOptions({
showVerticalGridline: false, showHorizontalGridline: false
});
if (scope.isReadOnly) {
setEditable(spread, true, false);
}
//setCellFormula(template.id, sheet);
//给单元格增加双击事件
sheet.bind(GcSpread.Sheets.Events.CellDoubleClick, function (sender, args) {
scope.$apply(function () {
if (_.isFunction(scope.internalApi.onCellDoubleClick)) {
scope.internalApi.onCellDoubleClick({
'sender': sender,
'args': args,
'data': JSON.parse(args.sheet.getTag(args.row, args.col))
});
$log.debug(args.sheet.getTag(args.row, args.col));
}
});
});
//给单元格增加单击事件
sheet.bind(GcSpread.Sheets.Events.CellClick, function (sender, args) {
scope.$apply(function () {
if (window.event.ctrlKey) {
var data = JSON.parse(args.sheet.getTag(args.row, args.col));
if (!_.isEmpty(data) && !_.isEmpty(data.dataSourceList)) {
var reports = _.chain(data.dataSourceList)
.where({ type: enums.formulaDataSourceType.Report })
.map(function (x) {
return {
reportCode: x.reportCode,
year: x.year,
period: x.period
};
}).uniq(function (x) {
return x.reportCode + ',' + x.year + ',' + x.period;
}).value();
if (reports.length === 1) {
var drillDownArgs = _.findWhere(data.dataSourceList, { type: enums.formulaDataSourceType.Report });
if (drillDownArgs.period === scope.projectPeriod && drillDownArgs.year === scope.projectYear) {
drillDownArgs = {
reportID: drillDownArgs.reportID,
reportTemplateID: drillDownArgs.reportTemplateID,
reportName: drillDownArgs.reportName,
reportCode: drillDownArgs.reportCode,
cellName: PWC.numToExcelChar(drillDownArgs.rowIndex, drillDownArgs.columnIndex)
};
scope.$emit(enums.vatEvent.reportDrillDown, drillDownArgs);
}
}
}
}
else if (_.isFunction(scope.internalApi.onCellClick)) {
scope.internalApi.onCellClick({
'sender': sender,
'args': args,
'data': JSON.parse(args.sheet.getTag(args.row, args.col))
});
$log.debug(args.sheet.getTag(args.row, args.col));
}
});
});
// 编辑完成后记录更新的单元格,适用于isReadOnly为false时
sheet.bind(GcSpread.Sheets.Events.EditEnded, function (sender, args) {
scope.$apply(function () {
var cell = sheet.getCell(args.row, args.col);
var newVal = cell.value();
var cellInfo = _.find(scope.reportSource, { rowIndex: args.row, columnIndex: args.col });
if (cellInfo) {
cellInfo.value = newVal;
cellInfo.isDirty = true;
}
$log.debug("Edit cell (" + args.row + ", " + args.col + ")");
});
});
sheet.clearSelection();
}
spread.isPaintSuspended(false);
scope.spread = spread;
scope.hasLoadSpread = true;
return $q.when(spread);
};
var setEditable = function (spread, isReadOnly, ifSuspend) {
var sheet = spread.getActiveSheet();
if (sheet != null) {
if (ifSuspend) {
spread.isPaintSuspended(true);
}
}
// isReadOnly为true时,设置整个sheet不可编辑
if (isReadOnly) {
for (var row = 0; row < sheet.getRowCount() ; row++) {
for (var column = 0; column < sheet.getColumnCount() ; column++) {
sheet.getCell(row, column).locked(true);
}
}
}
else {
// isReadOnly为false时,设置无配置单元格不可编辑,有配置单元格可编辑
for (var i = 0; i < scope.reportSource.length; i++) {
var cell = scope.reportSource[i];
sheet.getCell(cell.rowIndex, cell.columnIndex).locked(false);
}
for (var x = 0; x < sheet.getRowCount() ; x++) {
for (var y = 0; y < sheet.getColumnCount() ; y++) {
var idx = _.findIndex(scope.reportSource, { rowIndex: x, columnIndex: y });
if (idx < 0) {
sheet.getCell(x, y).locked(true);
}
}
}
}
sheet.setIsProtected(true);
sheet.protectionOption({
allowEditObjects: false
});
if (sheet != null) {
if (ifSuspend) {
spread.isPaintSuspended(false);
}
}
};
// 每个单元格大致由以下部分构成:_SumAll(_Inter(...)+_Manual(...)+C1)
// _Inter: IronPython公式计算结果
// _Manual: 手工数据源值
// C1: 类似的Excel公式,通过SpreadJS公式引擎计算
var initInterFunction = function (spread) {
var interFunc = function () { };
interFunc.prototype = new GcSpread.Sheets.Calc.Functions.Function("_Inter", 1, 1);
interFunc.prototype.evaluate = function (args) {
if (args.length !== 1 || isNaN(parseInt(args))) {
return "#VALUE!";
}
var idx = args[0];
var b = _.findWhere(scope.formulaBlocks, { index: idx });
if (b) {
var rtn = b.data;
rtn = PWC.tryParseStringToNum(rtn);
return rtn;
}
return null;
};
var manualFunc = function () { };
manualFunc.prototype = new GcSpread.Sheets.Calc.Functions.Function("_Manual", 1, 1);
manualFunc.prototype.evaluate = function (args) {
if (args.length !== 1 || !_.isString(args[0])) {
return "#VALUE!";
}
var cellTemplateID = args[0];
var ds = _.where(scope.manualDataSources, { item1: cellTemplateID });
if (!_.isEmpty(ds)) {
return _.reduce(ds, function (memo, x) {
var rtn = x.item2.amount;
rtn = PWC.tryParseStringToNum(rtn);
// 如果是数值数据源,只有OperationType为2时,该数据源的数值应被减去;其他情况下应被加上
if (_.isNumber(rtn) && !isNaN(rtn)) {
var operationType = x.item2.operationType;
rtn = operationType === 2 ? (-rtn) : rtn;
}
return memo + rtn;
}, 0);
}
return null;
};
//var sumAllFunc = function () { };
//sumAllFunc.prototype = new GcSpread.Sheets.Calc.Functions.Function("_SumAll", 1, 255);
//sumAllFunc.prototype.evaluate = function (args) {
// if (args.length < 1) {
// return "";
// }
// var rtn = args[0];
// if (args.length === 1 && (_.isNull(rtn) || _.isUndefined(rtn))) {
// rtn = "";
// }
// else {
// // 下面这种奇怪的写法是为了保证在reduce过程中累计值的类型正确
// rtn = _.reduce(args.slice(1), function (memo, x) {
// return memo + x;
// }, rtn);
// }
// return rtn;
//};
spread.clearCustomFunctions();
spread.addCustomFunction(new interFunc());
spread.addCustomFunction(new manualFunc());
//spread.addCustomFunction(new sumAllFunc());
};
var layoutChangedFunc = scope.$on(enums.vatEvent.layoutChanged, function () {
repaintSpread();
});
// TODO: 手工修改单元格值之后,更新单元格状态
var cellValueModifiedFunc = $rootScope.$on('cellValueModified', function (event, args) {
var modifiedReportCell = args.modifiedReportCell;
var cell = scope.reportSource.filter(function (data) {
return data.rowIndex === modifiedReportCell.row && data.columnIndex === modifiedReportCell.col;
})[0];
cell.value = modifiedReportCell.value;
cell.isModified = true;
cell.modifiedReportCell = modifiedReportCell;
setData();
});
var cellValueResetFunc = $rootScope.$on('cellValueReset', function (event, args) {
var cell = scope.reportSource.filter(function (data) {
return data.rowIndex === args.row && data.columnIndex === args.col;
})[0];
cell.value = cell.modifiedReportCell.originalValue;
cell.isModified = false;
cell.modifiedReportCell = null;
setData();
});
scope.$on('$destroy', function () {
layoutChangedFunc();
cellValueModifiedFunc();
cellValueResetFunc();
});
// Get spreadJS control.
var getSpreadControl = function () {
return GcSpread.Sheets.findControl(getSpreadControlElement());
};
// Get spreadJS control element
var getSpreadControlElement = function () {
//var elem = document.getElementsByClassName('report-view');
var elem = document.getElementById('r_' + scope.templateId);
if (!elem) {
var elems = document.getElementsByClassName('report');
if (!elems || elems.length === 0) {
return undefined;
}
return elems[0];
}
return elem;
};
var repaintSpread = function () {
return $timeout(function () {
var spread = getSpreadControl();
if (spread && spread.refresh) {
spread.refresh();
}
}, 50);
};
// 根据已有信息通过spreadJS计算各单元格的值
var setData = function () {
var sheet = getSpreadControl().sheets[0];
var isExportData = false;
if (angular.isArray(scope.reportSource)) {
spreadJsTipService.initialize(sheet);
if (!scope.isReadOnly) {
setEditable(scope.spread, false, true);
}
scope.reportSource.forEach(function (data) {
//fix bug11737 导出需要显示千分位
// 避免直接使用data.value = parseFloat(data.value)导致非数字型value无法显示
data.value = PWC.tryParseStringToNum(data.value);
if (data.isExportData) {//导出报表时,设置单元格的公式信息
isExportData = true;
if (data.isFormula) {
//获取单元格除公式值之外的剩余值
var subValue = 0;
if (data.dataSourceList && data.dataSourceList.length > 0) {
data.dataSourceList.forEach(function (dataSource) {
var cellName = PWC.numToExcelChar(dataSource.rowIndex, dataSource.columnIndex);
if (dataSource.type != enums.formulaDataSourceType.Report && dataSource.amount) {
subValue += parseFloat(dataSource.amount + '');
}
});
}
sheet.setFormula(data.rowIndex, data.columnIndex, '=' + data.formula + (subValue ? ('+' + subValue) : ''));
} else {
sheet.setValue(data.rowIndex, data.columnIndex, data.value);
}
} else { // 显示报表时,设置单元格的值或公式
var cell = sheet.getCell(data.rowIndex, data.columnIndex);
if (data.isModified
|| (data.dataVoucherList && data.dataVoucherList.length)
|| (data.dataInvoiceList && data.dataInvoiceList.length)
|| (data.dataSourceList && data.dataSourceList.length
&& _.some(data.dataSourceList, function (dataSource) { return dataSource.dataSourceType === 6 && dataSource.amount }))
) { // 存在用户手工输入值,需要改变底色
cell.backColor('#fbe8cc');
}
if (!_.isEmpty(data.dataSourceList)) {
var reports = _.chain(data.dataSourceList)
.where({ type: enums.formulaDataSourceType.Report })
.map(function (x) {
return {
reportCode: x.reportCode,
year: x.year,
period: x.period
};
}).uniq(function (x) {
return x.reportCode + ',' + x.year + ',' + x.period;
}).value();
if (reports.length === 1) {
var drillDownArgs = _.findWhere(data.dataSourceList, { type: enums.formulaDataSourceType.Report });
if (drillDownArgs.period === scope.projectPeriod && drillDownArgs.year === scope.projectYear) {
cell.textDecoration(GcSpread.Sheets.TextDecorationType.Underline);
cell.foreColor('blue');
}
}
}
// 设置顺序: 非数值字符串 -> 单元格值覆盖修改 -> 公式或手工数据源 -> 数值
var ifShowParseFloat = true; // 用于标识单元格是否设置成数值
if (_.isString(data.value) && data.value.length > 0 && isNaN(Number(data.value))) {
sheet.setValue(data.rowIndex, data.columnIndex, data.value);
ifShowParseFloat = false; // 非数值字符串,单元格设置为字符串
}
else if (data.isModified) { // 覆盖修改,且新值是数字
if (_.isNumber(data.value) && !isNaN(data.value)) {
data.value = data.value.toFixed(4);
}
sheet.setValue(data.rowIndex, data.columnIndex, data.value);
ifShowParseFloat = false; // 单元格值覆盖修改
}
else if (!data.isReadOnly && !scope.isReadOnly) { // 非只读report(资料清单)且非只读单元格
ifShowParseFloat = true;
}
else if (data.cellTemplateConfig) {
var parsedFormula = data.cellTemplateConfig.parsedFormula;
if (data.cellTemplateConfig.hasInvoice || data.cellTemplateConfig.hasKeyIn
|| data.cellTemplateConfig.hasModel || data.cellTemplateConfig.hasVoucher) {
if (!_.isEmpty(parsedFormula)) {
parsedFormula = parsedFormula + '+_Manual("' + data.cellTemplateID + '")';
}
else {
parsedFormula = '_Manual("' + data.cellTemplateID + '")';
}
}
if (!_.isEmpty(parsedFormula)) {
parsedFormula = 'IFERROR(' + parsedFormula + ', "")';
sheet.setFormula(data.rowIndex, data.columnIndex, '=' + parsedFormula);
ifShowParseFloat = false; // 有公式或手工数据源,单元格设置为公式
}
}
if (ifShowParseFloat) {
if (_.isNumber(data.value) && !isNaN(data.value)) {
data.value = data.value.toFixed(4);
}
sheet.setValue(data.rowIndex, data.columnIndex, data.value); // 只有数值,设置为数值
}
}
sheet.setTag(data.rowIndex, data.columnIndex, JSON.stringify(data));
//设置 tooltip 和 图标信息
spreadJsTipService.setCellTipByCellData(sheet.getCell(data.rowIndex, data.columnIndex), data);
});
// 设置破折号单元格的值和显示格式,将其替换为带破折号格式的0值,这样引用到的其他单元格才能正常计算
var rowCount = sheet.getRowCount();
var columnCount = sheet.getColumnCount();
for (var r = 0; r < rowCount; r++) {
for (var c = 0; c < columnCount; c++) {
var cell = sheet.getCell(r, c);
if (cell.value() === '——') {
cell.value(0);
cell.formatter("[=0]——;0.00");
}
}
}
spreadJsTipService.paintSheet(sheet);
}
};
// 更新数据源后,通过调用该方法计算所有当前sheet单元格,并通过比较原数据列表与spreadJS计算的新值列表,获取保存时需要修改库中Value的单元格信息列表
var updateCells = function () {
setData();
var sheet = getSpreadControl().sheets[0];
var cells = [];
var reportDataSources = _.chain(scope.reportSource)
.pluck('dataSourceList')
.flatten(true).value();
angular.forEach(scope.reportSource, function (x) {
// 比较刷新前后报表中的值的变化
// 优先将单元格转换成数值比较,如果不能则转换为字符串比较
var cell = sheet.getCell(x.rowIndex, x.columnIndex);
var newVal = cell.value();
newVal = PWC.tryParseStringToNum(newVal);
if (_.isBoolean(newVal)) {
newVal = newVal.toString();
}
else if (_.isNumber(newVal) && !isNaN(newVal)) {
newVal = newVal.toFixed(4);
}
var oldVal = x.value;
oldVal = PWC.tryParseStringToNum(oldVal);
if (_.isBoolean(oldVal)) {
oldVal = oldVal.toString();
}
else if (_.isNumber(oldVal) && !isNaN(oldVal)) {
oldVal = oldVal.toFixed(4);
}
if (newVal !== oldVal) {
cells.push({ id: x.cellID, oldVal: oldVal, newVal: newVal });
x.value = newVal;
x.isDirty = true;
var dirtyDataSources = _.filter(reportDataSources, { cellDataID: x.cellID, name: 'ReportDataSource' });
angular.forEach(dirtyDataSources, function (ds) {
newVal = PWC.tryParseStringToNum(newVal);
ds.amount = newVal;
});
sheet.setTag(x.rowIndex, x.columnIndex, JSON.stringify(x));
}
});
return cells;
};
(function initialize() {
loadSheet(scope.templateId);
if (scope.internalApi) {
scope.internalApi.refreshReport = updateCells;
}
})();
}
};
}
]);
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
<div class='vat-report-view'>
<!--Report SpreadJS-->
<div ng-if="!isDocumentList" class="row">
<span ng-click="showOperateLogPop()"><i class="fa fa-file-excel-o" aria-hidden="true"></i>&nbsp;{{'Remarks' | translate}}</span>
<span ng-show="showRemarksBt" ng-click="showRemarks()"><i class="fa fa-lightbulb-o" aria-hidden="true"></i>&nbsp; {{'Memo' | translate}}</span>
<span ng-if="isBSPL" ng-click="exportExcel();"><i class="fa fa-download"></i>&nbsp;{{'ExportExcel' | translate}}</span>
<span ng-if="!isBSPL" ng-click="openExportPop();"><i class="fa fa-download"></i>&nbsp;{{'ExportExcel' | translate}}</span>
<span ng-click="submitReport(43)" ng-show="submitBtShow"><i class="fa fa-arrow-up" aria-hidden="true"></i>&nbsp;{{'ReportSubmitToApprove' | translate}}</span>
<span ng-click="withdrawReport(44)" ng-show="showWithdrawBt"><i class="fa fa-arrow-down" aria-hidden="true"></i>&nbsp;{{'ReportWithdrawToApprove' | translate}}</span>
<span ng-click="approve(45)" ng-show="approveBtShow && !submitBtShow"><i class="fa fa-check"
aria-hidden="true"></i>&nbsp;{{'ReportApprove' | translate}} {{approveLevelDesc}}</span>
<span ng-click="reject(46)" ng-show="approveBtShow && !submitBtShow"><i class="fa fa-times"
aria-hidden="true"></i>&nbsp;{{'ReportReject' | translate}} {{approveLevelDesc}}</span>
<span ng-click="declarationComplete(47)" ng-show="declareCompleteBtShow"><i class="fa fa-check-square"
aria-hidden="true"></i>&nbsp;{{'DeclarationComplete' | translate}}</span>
<span ng-click="uploadCertificate()" ng-show="approveBtShow && !submitBtShow"><i class="fa fa-cloud-upload"
aria-hidden="true"></i>&nbsp;{{'UploadCertificate' | translate}}</span>
<span ng-if="!isBSPL" ng-click="saveReportCache();"><i
class="fa fa-floppy-o"></i>&nbsp;{{'Save' | translate}}</span>
</div>
<div class='report-container' id="reportContainer">
<vat-report-sheet id='report-view' report-source="reportData" formula-blocks="formulaBlocks"
is-read-only="!isDocumentList"
manual-data-sources="manualDataSources" spread='spread' template-id='templateId'
report-api="reportApi"
service-type="serviceType" init-row="initRow" init-col="initCol">
</vat-report-sheet>
</div>
<cell-detail-panel detail="cellDetail" id="cell-detail" source-type="isBSPLSpecial"></cell-detail-panel>
<tax-report-cell-detail-modal on-confirm="confirm()" detail="taxCellDetail" id="tax-cell-detail"
service-type="serviceType"
on-update-data-source="updateCellByManualChange(manualData)"
on-delete-data-source="updateCellByManualSourceDelete(dataSourceId, cellId)"
on-delete-data-source-detail="updateCellBySourceDetailDelete(dataSource, detailId, opType)">
</tax-report-cell-detail-modal>
<vat-operate-log period="period" module-type="moduleid" is-show="isShowLog"></vat-operate-log>
<div class='export-container hidden'></div>
<div id="export" class="hidden"></div>
<!-- 报表审核弹出框 -->
<script type="text/ng-template" id="model-report-approve-log.html" class="model-report-approve-popup">
<div class="modal-header">
<div class="modal-title" style="margin-bottom:10px">
{{'ApproveProcess' | translate}}<i class="fa fa-times" aria-hidden="true"
style="float: right; font-size: 11px; color: #CF2D1B"
ng-click="closeModal()"></i>
</div>
</div>
<div class="modal-body">
<div style="margin-bottom:10px">{{ApproveTitle}}</div>
<table>
<tr>
<td style="vertical-align:text-top">{{'Memo'|translate}}</td>
<td><textarea id="txtRemarks" style="width:300px;height:100px"></textarea></td>
</tr>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-vat-primary" ng-click="popUpOnConfirm()">{{'Confirm' | translate }}
</button>
<button type="button" class="btn btn-vat-primary" ng-click="closeModal()">{{'CloseButton' | translate }}
</button>
</div>
</script>
<!-- 显示上一步操作的备注 -->
<script type="text/ng-template" id="model-report-remarks.html" class="model-report-remarks-popup">
<div class="modal-header">
<div class="modal-title" style="margin-bottom:10px">
{{remarksTitle}}<i class="fa fa-times" aria-hidden="true"
style="float: right; font-size: 11px; color: #CF2D1B" ng-click="closeModal()"></i>
</div>
</div>
<div class="modal-body">
<div>
<textarea id="txtLastProcessRemark" style="width:370px;height:100px" readonly></textarea>
</div>
</div>
</script>
<!--Select export report pop-->
<div id="exportReportFilesContainer">
<script type="text/ng-template" class="content" id="exportReport.html">
<div class="modal-header">
<h4 class="modal-title" style="float: left;width: 70%;">{{'SelectExportReport' | translate}}</h4>
<span ng-click="$dismiss();" style="width: 20px; float: right; cursor: pointer;">x</span>
</div>
<div class="modal-body process-bar-container">
<div id="report-tree-container">
<div dx-tree-view="exportReportTreeOptions"></div>
</div>
</div>
<div class="modal-footer">
<button ng-click="export();" class="btn btn-default" style="background-color: #c00; color: #fff;">
{{'Confirm' | translate}}
</button>
<button ng-click="$dismiss();" class="btn btn-default" style="background-color: #777; color: #fff;">
{{'ButtonCancel' | translate}}
</button>
</div>
</script>
</div>
<!-- File Vouchers Upload Popup -->
<div class="modal fade" id="showVoucherUploadPortal" tabindex="-1" role="dialog" aria-labelledby="myModal"
data-backdrop="static" data-keyboard="false">
<div class="modal-dialog" style="width:740px;" role="document">
<div class="modal-content">
<div class="modal-header">
<span class="close" data-dismiss="modal" aria-hidden="true" ng-click="closeModal()">×</span>
<span>上传凭证 {{selectedProject.organizationName}}</span>
</div>
<div class="modal-body">
导入凭证:
<button type="button" atms-permission permission-code="02.004.002.006" ngf-select=""
ng-model="voucherFile" ngf-drag-over-class="'dragover'"
accept=".pdf,.jpg,.jpeg,.xls,.xlsx,.csv" ngf-multiple="true" ngf-allow-dir="false"
class="btn btn-vat-third">
<i class="fa fa-upload" aria-hidden="true"></i>
{{'SelectFileToUpload' | translate}}
</button>
</div>
<br/>
<div class="row" ng-show="voucherList!==null && voucherList.length>0"
style="margin-left:12px; margin-right:12px;">
<div class="col-lg-12 col-md-12 col-sm-12">
<table class="table table-no-bordered">
<thead>
<tr>
<th>凭证</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="evidence in voucherList">
<td>{{evidence.creatorID}}</td>
<td><span style="cursor:pointer" atms-permission permission-code="02.004.002.001"
ng-click="openEvidenceFile(evidence)">{{evidence.fileName}}</span></td>
<td>{{evidence.createTime | date:'yyyy-MM-dd HH:mm'}}</td>
<td>{{evidence.comments}}</td>
<td>
<button class="btn btn-sm" atms-permission permission-code="02.004.002.006"
ng-click="showCommentsPopup(evidence);"><i class="fa fa-pencil-square-o"
</button>
<button class="btn btn-sm" atms-permission permission-code="02.004.002.006"
ng-click="deleteEvidenceFiles(evidence)"><i class="fa fa-times"
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="modal-footer">
</div>
</div>
</div>
</div>
<div class="modal fade" id="EditVoucherCommentsPortal" tabindex="-1" role="dialog" aria-labelledby="myModal"
data-backdrop="static" data-keyboard="false">
<div class="modal-dialog" style="" role="document">
<div class="modal-content">
<div class="modal-header">
<span class="close" data-dismiss="modal" aria-hidden="true" ng-click="closeModal()">×</span>
<span>{{voucherFileName}}</span>
</div>
<br/>
<div class="row" style="margin-left:12px; margin-right:12px;">
<div class="col-lg-12 col-md-12 col-sm-12">
<table class="table">
<caption>备注</caption>
<tr>
<td><textarea rows="3" class="form-control" ng-model="voucherComments">{{voucherComments}}</textarea>
</td>
</tr>
<tr>
<td style="float:right;border-top:none;">
<button class="btn btn-sm" ng-click="updateEvidencesComments(voucherFileID)">提交
</button>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
commonModule.directive('vatReportView', ['$log', 'enums',
function ($log, enums) {
'use strict';
$log.debug('vatReportView.ctor()...');
return {
restrict: 'E',
templateUrl: '/app/common/controls/vat-report-view/vat-report-view.html' + '?_=' + Math.random(),
scope: {
templateId: '=',
reportId: '=',
templateName:'=',
templateCode: '=',
isDocumentList: '=',
serviceType: '=',
initRow: '=?',
initCol: '=?'
},
controller: 'VatReportViewController',
link: function ($scope, $ele, $attr) {
$ele.find("#tax-cell-detail").draggable({
scroll: true,
cancel: '#dataSourceGrid,.hand-input-container,.add-voucher-range-propover,.add-invoice,.tab-type,.dx-texteditor-input,input,.btn'
});
var saveFunc = $scope.$on('saveReportSheet', function (event, args) {
$scope.saveReportCache();
});
$scope.$on('$destroy', function () {
saveFunc();
});
}
};
}
]);
\ No newline at end of file
@import "~/app-resources/less/theme.less";
@color-red:#e20;
@color-gray:#939598-#222;
.vat-report-view {
height: calc(~"100% - 20px");
min-height: 500px;
margin: 10px 10px 10px 20px;
.report-container {
border: @thin-border solid @color-border;
height: calc(~"100% - 36px");
margin: 0;
width: 100%;
white-space: normal;
display: inline-block;
}
.row {
margin-left: 0px;
margin-bottom:10px;
&>span {
float: right;
margin-right: 15px;
cursor: pointer;
}
}
#addCertificatePop {
.modal-dialog {
width: 700px;
.add-certificate-pop-body {
height: 240px;
#add-certificate-grid {
height: 210px;
}
}
.modal-footer {
.template-1-button {
background-color: @color-red;
color: white;
margin-right:30px;
}
.template-2-button {
background-color: @color-gray;
color: white;
margin-right: 30px;
}
}
}
}
}
.model-report-approve-popup {
width: 400px;
height:500px;
position:fixed;
top:25%;
left:40%;
.modal-dialog {
width: 100%;
height: 90%;
margin: 20px auto;
.modal-content {
width: 100%;
.modal-body {
height: 90%;
}
}
}
}
.model-report-remarks-popup {
width: 400px;
height:500px;
position:fixed;
top:25%;
left:40%;
.modal-dialog {
width: 100%;
height: 90%;
margin: 20px auto;
.modal-content {
width: 100%;
.modal-body {
height: 90%;
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment