From 4f39e676277d7a66e13d172288032ce16bb18e8c Mon Sep 17 00:00:00 2001
From: zss <zss@example.com>
Date: 星期三, 22 四月 2026 17:05:30 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_河南_鹤壁天沐钢化玻璃厂' into dev_河南_鹤壁天沐钢化玻璃厂

---
 src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java |  395 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 365 insertions(+), 30 deletions(-)

diff --git a/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java b/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
index 447ff45..6ccf2a6 100644
--- a/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
+++ b/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
@@ -25,8 +25,18 @@
 import com.ruoyi.project.system.mapper.SysDeptMapper;
 import com.ruoyi.project.system.mapper.SysUserMapper;
 import com.ruoyi.project.system.service.ISysNoticeService;
+import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
+import com.ruoyi.purchase.pojo.PurchaseLedger;
+import com.ruoyi.quality.mapper.QualityInspectMapper;
+import com.ruoyi.quality.pojo.QualityInspect;
 import com.ruoyi.sales.mapper.CommonFileMapper;
+import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
+import com.ruoyi.sales.mapper.ShippingInfoMapper;
+import com.ruoyi.sales.mapper.SalesLedgerMapper;
+import com.ruoyi.sales.pojo.SalesLedger;
+import com.ruoyi.sales.pojo.SalesLedgerProduct;
 import com.ruoyi.sales.pojo.CommonFile;
+import com.ruoyi.sales.pojo.ShippingInfo;
 import com.ruoyi.sales.service.impl.CommonFileServiceImpl;
 import lombok.AllArgsConstructor;
 import lombok.RequiredArgsConstructor;
@@ -46,27 +56,42 @@
 import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 @Service
-@RequiredArgsConstructor
+//@RequiredArgsConstructor
 public class ApproveProcessServiceImpl extends ServiceImpl<ApproveProcessMapper, ApproveProcess> implements IApproveProcessService {
     private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyyMMdd");
 
-    private final StringRedisTemplate redisTemplate;
+    @Autowired
+    private  StringRedisTemplate redisTemplate;
+    @Autowired
+    private  DailyRedisCounter dailyRedisCounter;
+    @Autowired
+    private  SysDeptMapper sysDeptMapper;
+    @Autowired
+    private  IApproveNodeService approveNodeService;
+    @Autowired
+    private  SysUserMapper sysUserMapper;
+    @Autowired
+    private  ApproveProcessMapper approveProcessMapper;
+    @Autowired
+    private  TempFileServiceImpl tempFileService;
+    @Autowired
+    private  CommonFileMapper commonFileMapper;
+    @Autowired
+    private  CommonFileServiceImpl commonFileService;
+    @Autowired
+    private  ISysNoticeService sysNoticeService;
 
-    private final DailyRedisCounter dailyRedisCounter;
-
-    private final SysDeptMapper sysDeptMapper;
-    private final IApproveNodeService approveNodeService;
-    private final SysUserMapper sysUserMapper;
-    private final ApproveProcessMapper approveProcessMapper;
-    private final TempFileServiceImpl tempFileService;
-    private final CommonFileMapper commonFileMapper;
-    private final CommonFileServiceImpl commonFileService;
-    private final ISysNoticeService sysNoticeService;
+    @Autowired
+    private SalesLedgerMapper salesLedgerMapper;
 
     @Override
     public void addApprove(ApproveProcessVO approveProcessVO) throws Exception {
@@ -95,6 +120,7 @@
         approveProcess.setApproveUserNames(sysUsers.stream().map(SysUser::getNickName).collect(Collectors.joining(",")));
         approveProcess.setApproveTime(StringUtils.isEmpty(approveProcessVO.getApproveTime()) ? null : dateFormat.parse(approveProcessVO.getApproveTime()));
         approveProcess.setApproveReason(approveProcessVO.getApproveReason());
+        approveProcess.setApproveRemark(approveProcessVO.getApproveRemark());
         approveProcess.setDeviceRepairId(approveProcessVO.getDeviceRepairId());
         approveProcess.setMaintenancePrice(approveProcessVO.getMaintenancePrice());
         approveProcess.setPrice(approveProcessVO.getPrice());
@@ -126,10 +152,17 @@
         tempFileService.migrateTempFilesToFormal(approveProcess.getId(), approveProcessVO.getTempFileIds(), FileNameType.ApproveProcess.getValue());
         /*娑堟伅閫氱煡*/
         String id = approveProcessVO.getApproveUserIds().split(",")[0];
-        sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcessVO.getApproveType()),
-                approveID + "娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
-                Arrays.asList(Long.valueOf(id)),
-                "/collaborativeApproval/approvalProcess?approveType=" + approveProcessVO.getApproveType() + "&approveId=" + approveID);
+        if (approveProcess.getApproveType()==8){
+            sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
+                    approveProcess.getApproveId() + "娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
+                    Arrays.asList(Long.valueOf(id)),
+                    "/safeProduction/safeWorkApproval?approveType=" + approveProcess.getApproveType() + "&approveId=" + approveProcess.getApproveId());
+        }else {
+            sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
+                    approveProcess.getApproveId() + "娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
+                    Arrays.asList(Long.valueOf(id)),
+                    "/collaborativeApproval/approvalProcess?approveType=" + approveProcess.getApproveType() + "&approveId=" + approveProcess.getApproveId());
+        }
     }
 
     @Override
@@ -142,15 +175,76 @@
         return sysDeptList;
     }
 
+    @Autowired
+    private PurchaseLedgerMapper purchaseLedgerMapper;
+
+    @Autowired
+    private ShippingInfoMapper shippingInfoMapper;
+
+    @Autowired
+    private SalesLedgerProductMapper salesLedgerProductMapper;
+
+    @Autowired
+    private QualityInspectMapper qualityInspectMapper;
+
     @Override
     public IPage<ApproveProcess> listAll(Page page, ApproveProcess approveProcess) {
         IPage<ApproveProcess> approveProcessIPage = approveProcessMapper.listPage(page, approveProcess);
         List<ApproveProcess> records = approveProcessIPage.getRecords();
+
         for (ApproveProcess record : records) {
-            List<CommonFile> commonFiles = commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>()
-                    .eq(CommonFile::getCommonId, record.getId())
-                    .eq(CommonFile::getType, FileNameType.ApproveProcess.getValue()));
-            record.setCommonFileList(commonFiles);
+            List<CommonFile> allFiles = new ArrayList<>();
+
+            //  閲囪喘瀹℃壒鏌ヨ
+            if (record.getApproveType() == 5) {
+                String contractNo = record.getApproveReason();
+                PurchaseLedger ledger = purchaseLedgerMapper.selectOne(new LambdaQueryWrapper<PurchaseLedger>()
+                        .eq(PurchaseLedger::getPurchaseContractNumber, contractNo)
+                        .last("limit 1"));
+
+                if (ledger != null) {
+                    allFiles = commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>()
+                            .eq(CommonFile::getCommonId, ledger.getId())
+                            .eq(CommonFile::getType, FileNameType.PURCHASE.getValue()));
+                }
+            }
+
+            //  鍙戣揣瀹℃壒鏌ヨ
+            else if (record.getApproveType() == 7) {
+                String reason = record.getApproveReason(); // 鏍煎紡涓� "xx:CONTRACT_NO"
+                if (StringUtils.hasText(reason) && reason.contains(":")) {
+                    // 鎻愬彇鍐掑彿鍚庨潰鐨勬爣璇嗙 (鍙兘鏄悎鍚屽彿鎴栧彂璐у崟鍙�)
+                    String identifier = reason.split(":")[1];
+                    // 1. 浼樺厛灏濊瘯鎵鹃攢鍞彴璐� (鏂伴�昏緫锛氬悎鍚屽彿鍚屾瀹℃壒)
+                    SalesLedger ledger = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>()
+                            .eq(SalesLedger::getSalesContractNo, identifier)
+                            .last("limit 1"));
+                    if (ledger != null) {
+                        allFiles = commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>()
+                                .eq(CommonFile::getCommonId, ledger.getId())
+                                .eq(CommonFile::getType, FileNameType.SALE.getValue()));
+                    } else {
+                        // 2. 鍥為��鍒版棫閫昏緫锛氬彂璐у崟鍙�
+                        ShippingInfo shippingInfo = shippingInfoMapper.selectOne(new LambdaQueryWrapper<ShippingInfo>()
+                                .eq(ShippingInfo::getShippingNo, identifier)
+                                .last("limit 1"));
+                        if (shippingInfo != null) {
+                            allFiles = commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>()
+                                    .eq(CommonFile::getCommonId, shippingInfo.getSalesLedgerId())
+                                    .eq(CommonFile::getType, FileNameType.SALE.getValue()));
+                        }
+                    }
+                }
+            }
+
+            //  鏌ヨ瀹℃壒鍗曡嚜韬殑闄勪欢
+            else {
+                allFiles = commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>()
+                        .eq(CommonFile::getCommonId, record.getId())
+                        .eq(CommonFile::getType, FileNameType.ApproveProcess.getValue()));
+            }
+
+            record.setCommonFileList(allFiles);
         }
         return approveProcessIPage;
     }
@@ -239,7 +333,230 @@
         return one;
     }
 
-    private final ApproveNodeMapper approveNodeMapper;
+    @Override
+    public Map<String, Object> getStockInOrderInfo(String approveId) {
+        ApproveProcess approveProcess = getStockInApproveProcess(approveId);
+        StockInBusinessContext context = parseStockInContext(approveProcess);
+        if (context == null) {
+            throw new RuntimeException("褰撳墠瀹℃壒鍗曟湭缁戝畾鍏ュ簱涓氬姟鏁版嵁");
+        }
+        Map<String, Object> result = new HashMap<>();
+        result.put("approveId", approveProcess.getApproveId());
+        result.put("approveType", approveProcess.getApproveType());
+        result.put("businessType", context.businessType);
+        if (context.purchaseLedgerId != null) {
+            PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(context.purchaseLedgerId);
+            if (purchaseLedger == null) {
+                throw new RuntimeException("鍏宠仈閲囪喘璁㈠崟涓嶅瓨鍦�");
+            }
+            result.put("orderInfo", purchaseLedger);
+            return result;
+        }
+        if (context.salesLedgerId != null) {
+            SalesLedger salesLedger = salesLedgerMapper.selectById(context.salesLedgerId);
+            if (salesLedger == null) {
+                throw new RuntimeException("鍏宠仈閿�鍞鍗曚笉瀛樺湪");
+            }
+            result.put("orderInfo", salesLedger);
+            return result;
+        }
+        throw new RuntimeException("鏈В鏋愬埌璁㈠崟淇℃伅");
+    }
+
+    @Override
+    public List<?> getStockInProductList(String approveId) {
+        ApproveProcess approveProcess = getStockInApproveProcess(approveId);
+        StockInBusinessContext context = parseStockInContext(approveProcess);
+        if (context == null) {
+            throw new RuntimeException("褰撳墠瀹℃壒鍗曟湭缁戝畾鍏ュ簱浜у搧鏁版嵁");
+        }
+        List<SalesLedgerProduct> matchedProducts;
+        if (context.purchaseLedgerId != null) {
+            matchedProducts = salesLedgerProductMapper.selectList(new LambdaQueryWrapper<SalesLedgerProduct>()
+                    .eq(SalesLedgerProduct::getSalesLedgerId, context.purchaseLedgerId)
+                    .eq(SalesLedgerProduct::getType, 2)
+                    .orderByAsc(SalesLedgerProduct::getId));
+            return matchedProducts;
+        }
+        if (context.salesLedgerId != null) {
+            LambdaQueryWrapper<SalesLedgerProduct> wrapper = new LambdaQueryWrapper<SalesLedgerProduct>()
+                    .eq(SalesLedgerProduct::getSalesLedgerId, context.salesLedgerId)
+                    .eq(SalesLedgerProduct::getType, 1)
+                    .orderByAsc(SalesLedgerProduct::getId);
+            if (!context.productIds.isEmpty()) {
+                wrapper.in(SalesLedgerProduct::getId, context.productIds);
+            }
+            matchedProducts = salesLedgerProductMapper.selectList(wrapper);
+            attachRequestedQty(matchedProducts, context);
+            return matchedProducts;
+        }
+        if (!context.productIds.isEmpty()) {
+            matchedProducts = salesLedgerProductMapper.selectList(new LambdaQueryWrapper<SalesLedgerProduct>()
+                    .in(SalesLedgerProduct::getId, context.productIds)
+                    .orderByAsc(SalesLedgerProduct::getId));
+            attachRequestedQty(matchedProducts, context);
+            return matchedProducts;
+        }
+        return Collections.emptyList();
+    }
+
+    private ApproveProcess getStockInApproveProcess(String approveId) {
+        if (!StringUtils.hasText(approveId)) {
+            throw new RuntimeException("瀹℃壒缂栧彿涓嶈兘涓虹┖");
+        }
+        ApproveProcess approveProcess = approveProcessMapper.selectOne(new LambdaQueryWrapper<ApproveProcess>()
+                .eq(ApproveProcess::getApproveId, approveId)
+                .eq(ApproveProcess::getApproveDelete, 0)
+                .orderByDesc(ApproveProcess::getCreateTime)
+                .last("limit 1"));
+        if (approveProcess == null) {
+            throw new RuntimeException("瀹℃壒鍗曚笉瀛樺湪");
+        }
+        if (!Objects.equals(approveProcess.getApproveType(), 9)) {
+            throw new RuntimeException("褰撳墠瀹℃壒鍗曚笉鏄叆搴撳鎵�");
+        }
+        return approveProcess;
+    }
+
+    private StockInBusinessContext parseStockInContext(ApproveProcess approveProcess) {
+        if (approveProcess == null) {
+            return null;
+        }
+        String remark = approveProcess.getApproveRemark();
+        if (StringUtils.hasText(remark) && remark.startsWith("qualityQualifiedInbound:")) {
+            String[] split = remark.split(":");
+            if (split.length >= 3) {
+                StockInBusinessContext context = new StockInBusinessContext();
+                context.businessType = "PURCHASE_QUALITY";
+                context.purchaseLedgerId = parseLongSafely(split[2]);
+                return context;
+            }
+        }
+        if (StringUtils.hasText(remark) && remark.startsWith("salesStock:")) {
+            String[] split = remark.split(":");
+            if (split.length >= 3) {
+                StockInBusinessContext context = new StockInBusinessContext();
+                context.businessType = "SALES_STOCK";
+                context.salesLedgerId = parseLongSafely(split[1]);
+                context.productIds = Arrays.stream(split[2].split(","))
+                        .filter(StringUtils::hasText)
+                        .map(this::parseLongSafely)
+                        .filter(Objects::nonNull)
+                        .collect(Collectors.toList());
+                return context;
+            }
+        }
+        if (StringUtils.hasText(remark) && (remark.startsWith("scanQualified:") || remark.startsWith("scanUnqualified:"))) {
+            String[] split = remark.split(":");
+            if (split.length >= 3) {
+                StockInBusinessContext context = new StockInBusinessContext();
+                context.businessType = remark.startsWith("scanQualified:") ? "SALES_SCAN_QUALIFIED" : "SALES_SCAN_UNQUALIFIED";
+                context.salesLedgerId = parseLongSafely(split[1]);
+                parseProductLineQty(split[2], context);
+                return context;
+            }
+        }
+        String reason = approveProcess.getApproveReason();
+        if (!StringUtils.hasText(reason)) {
+            return null;
+        }
+        if (reason.startsWith("鍘熸潗鏂欒川妫�鍏ュ簱瀹℃壒:")) {
+            String[] split = reason.split(":");
+            if (split.length >= 3) {
+                StockInBusinessContext context = new StockInBusinessContext();
+                context.businessType = "PURCHASE_QUALITY";
+                context.purchaseLedgerId = parseLongSafely(split[2]);
+                return context;
+            }
+            if (split.length >= 2) {
+                Long inspectId = parseLongSafely(split[1]);
+                if (inspectId != null) {
+                    QualityInspect inspect = qualityInspectMapper.selectById(inspectId);
+                    if (inspect != null) {
+                        StockInBusinessContext context = new StockInBusinessContext();
+                        context.businessType = "PURCHASE_QUALITY";
+                        context.purchaseLedgerId = inspect.getPurchaseLedgerId();
+                        return context;
+                    }
+                }
+            }
+        }
+        if (reason.startsWith("鍏ュ簱瀹℃壒:")) {
+            String[] split = reason.split(":");
+            if (split.length >= 4) {
+                StockInBusinessContext context = new StockInBusinessContext();
+                context.businessType = "SALES_STOCK";
+                context.salesLedgerId = parseLongSafely(split[2]);
+                context.productIds = Arrays.stream(split[3].split(","))
+                        .filter(StringUtils::hasText)
+                        .map(this::parseLongSafely)
+                        .filter(Objects::nonNull)
+                        .collect(Collectors.toList());
+                return context;
+            }
+        }
+        return null;
+    }
+
+    private void parseProductLineQty(String lines, StockInBusinessContext context) {
+        if (!StringUtils.hasText(lines) || context == null) {
+            return;
+        }
+        String[] items = lines.split(",");
+        for (String item : items) {
+            if (!StringUtils.hasText(item)) {
+                continue;
+            }
+            String[] pair = item.split("@");
+            Long lineId = parseLongSafely(pair[0]);
+            if (lineId == null) {
+                continue;
+            }
+            context.productIds.add(lineId);
+            if (pair.length >= 2 && StringUtils.hasText(pair[1])) {
+                context.requestedQtyByProductId.put(lineId, pair[1]);
+            }
+        }
+    }
+
+    private void attachRequestedQty(List<SalesLedgerProduct> products, StockInBusinessContext context) {
+        if (products == null || products.isEmpty() || context == null || context.requestedQtyByProductId.isEmpty()) {
+            return;
+        }
+        for (SalesLedgerProduct product : products) {
+            if (product == null || product.getId() == null) {
+                continue;
+            }
+            String requestedQty = context.requestedQtyByProductId.get(product.getId());
+            if (requestedQty != null) {
+                product.setRemark(StringUtils.hasText(product.getRemark())
+                        ? product.getRemark() + "锛涘鎵圭敵璇锋暟閲�:" + requestedQty
+                        : "瀹℃壒鐢宠鏁伴噺:" + requestedQty);
+            }
+        }
+    }
+
+    private Long parseLongSafely(String value) {
+        if (!StringUtils.hasText(value)) {
+            return null;
+        }
+        try {
+            return Long.valueOf(value);
+        } catch (Exception ignored) {
+            return null;
+        }
+    }
+
+    private static class StockInBusinessContext {
+        private String businessType;
+        private Long purchaseLedgerId;
+        private Long salesLedgerId;
+        private List<Long> productIds = new ArrayList<>();
+        private final Map<Long, String> requestedQtyByProductId = new HashMap<>();
+    }
+
+    @Autowired
+    private ApproveNodeMapper approveNodeMapper;
 
     // 鎶ヤ环瀹℃壒缂栬緫瀹℃牳浜�
     public void updateApproveUser(ApproveGetAndUpdateVo approveGetAndUpdateVo) {
@@ -276,10 +593,17 @@
         approveNodeService.initApproveNodes(approveGetAndUpdateVo.getApproveUserIds(), approveProcess.getApproveId(), approveProcess.getTenantId());
         /*娑堟伅閫氱煡*/
         String id = approveProcess.getApproveUserIds().split(",")[0];
-        sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
-                approveProcess.getApproveId() + "娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
-                Arrays.asList(Long.valueOf(id)),
-                "/collaborativeApproval/approvalProcess?approveType=" + approveProcess.getApproveType() + "&approveId=" + approveProcess.getApproveId());
+        if (approveProcess.getApproveType()==8){
+            sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
+                    approveProcess.getApproveId() + "娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
+                    Arrays.asList(Long.valueOf(id)),
+                    "/safeProduction/safeWorkApproval?approveType=" + approveProcess.getApproveType() + "&approveId=" + approveProcess.getApproveId());
+        }else {
+            sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
+                    approveProcess.getApproveId() + "娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
+                    Arrays.asList(Long.valueOf(id)),
+                    "/collaborativeApproval/approvalProcess?approveType=" + approveProcess.getApproveType() + "&approveId=" + approveProcess.getApproveId());
+        }
     }
 
 
@@ -334,10 +658,17 @@
         tempFileService.migrateTempFilesToFormal(approve.getId(), approveGetAndUpdateVo.getTempFileIds(), FileNameType.ApproveProcess.getValue());
         /*娑堟伅閫氱煡*/
         String id = approve.getApproveUserIds().split(",")[0];
-        sysNoticeService.simpleNoticeByUser(approveProcessType(approve.getApproveType()),
-                approve.getApproveId() + "娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
-                Arrays.asList(Long.valueOf(id)),
-                "/collaborativeApproval/approvalProcess?approveType=" + approve.getApproveType() + "&approveId=" + approve.getApproveId());
+        if (approve.getApproveType()==8){
+            sysNoticeService.simpleNoticeByUser(approveProcessType(approve.getApproveType()),
+                    approve.getApproveId() + "娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
+                    Arrays.asList(Long.valueOf(id)),
+                    "/safeProduction/safeWorkApproval?approveType=" + approve.getApproveType() + "&approveId=" + approve.getApproveId());
+        }else {
+            sysNoticeService.simpleNoticeByUser(approveProcessType(approve.getApproveType()),
+                    approve.getApproveId() + "娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
+                    Arrays.asList(Long.valueOf(id)),
+                    "/collaborativeApproval/approvalProcess?approveType=" + approve.getApproveType() + "&approveId=" + approve.getApproveId());
+        }
 
     }
 
@@ -358,7 +689,11 @@
             case 6:
                 return "鎶ヤ环瀹℃壒";
             case 7:
-                return "鍑哄簱瀹℃壒";
+                return "鍙戣揣瀹℃壒";
+            case 8:
+                return "鍗遍櫓浣滀笟瀹℃壒";
+            case 9:
+                return "鍏ュ簱瀹℃壒";
         }
         return null;
     }

--
Gitblit v1.9.3