Quellcode durchsuchen

Merge remote-tracking branch 'origin/master'

scr vor 8 Jahren
Ursprung
Commit
c1fbb870a8
22 geänderte Dateien mit 1934 neuen und 498 gelöschten Zeilen
  1. 19 0
      src/main/java/com/uas/erp/schedular/b2b/domain/PurchaseDetail.java
  2. 10 11
      src/main/java/com/uas/erp/schedular/b2b/task/InquiryTask.java
  3. 11 8
      src/main/java/com/uas/erp/schedular/b2b/task/MakeTask.java
  4. 0 57
      src/main/java/com/uas/erp/schedular/b2b/task/ProductSalerTask.java
  5. 0 80
      src/main/java/com/uas/erp/schedular/b2b/task/ProductTask.java
  6. 0 217
      src/main/java/com/uas/erp/schedular/b2b/task/PublicInquiryTask.java
  7. 28 12
      src/main/java/com/uas/erp/schedular/b2b/task/PurchaseTask.java
  8. 7 3
      src/main/java/com/uas/erp/schedular/b2b/task/SaleDownTask.java
  9. 68 0
      src/main/java/com/uas/erp/schedular/publicinquiry/domain/Attach.java
  10. 140 0
      src/main/java/com/uas/erp/schedular/publicinquiry/domain/BatchInProduct.java
  11. 228 0
      src/main/java/com/uas/erp/schedular/publicinquiry/domain/BatchInquiry.java
  12. 49 0
      src/main/java/com/uas/erp/schedular/publicinquiry/domain/Enterprise.java
  13. 327 0
      src/main/java/com/uas/erp/schedular/publicinquiry/task/AbstractTask.java
  14. 260 0
      src/main/java/com/uas/erp/schedular/publicinquiry/task/PubInquiryTask.java
  15. 181 0
      src/main/java/com/uas/erp/schedular/publicproduct/domain/Prod.java
  16. 14 1
      src/main/java/com/uas/erp/schedular/publicproduct/domain/ProductSaler.java
  17. 327 0
      src/main/java/com/uas/erp/schedular/publicproduct/task/AbstractTask.java
  18. 100 0
      src/main/java/com/uas/erp/schedular/publicproduct/task/ProdTask.java
  19. 53 0
      src/main/java/com/uas/erp/schedular/publicproduct/task/ProdUserTask.java
  20. 82 82
      src/main/resources/database/template/deputyOrder.xml
  21. 14 27
      src/main/resources/database/template/pubInquiryReply.xml
  22. 16 0
      src/main/resources/init/setting.json

+ 19 - 0
src/main/java/com/uas/erp/schedular/b2b/domain/PurchaseDetail.java

@@ -1,6 +1,7 @@
 package com.uas.erp.schedular.b2b.domain;
 
 import java.util.Date;
+import java.util.List;
 
 /**
  * ERP系统的采购订单明细
@@ -21,6 +22,8 @@ public class PurchaseDetail {
 	private String pd_factory;
 	private String pd_vendspec;
 	private Integer pd_beipin;
+	private String pd_prattach;
+	private List<Attach> attaches;
 
 	public String getPd_vendspec() {
 		return pd_vendspec;
@@ -109,4 +112,20 @@ public class PurchaseDetail {
 	public void setPd_beipin(Integer pd_beipin) {
 		this.pd_beipin = pd_beipin;
 	}
+
+	public String getPd_prattach() {
+		return pd_prattach;
+	}
+
+	public void setPd_prattach(String pd_prattach) {
+		this.pd_prattach = pd_prattach;
+	}
+
+	public List<Attach> getAttaches() {
+		return attaches;
+	}
+
+	public void setAttaches(List<Attach> attaches) {
+		this.attaches = attaches;
+	}
 }

+ 10 - 11
src/main/java/com/uas/erp/schedular/b2b/task/InquiryTask.java

@@ -24,11 +24,13 @@ public class InquiryTask extends AbstractTask {
 
     @TaskMapping(title = "上传询价单", fixedDelay = 30000)
     public void uploadInquiry() {
-        uploadProduct();
-        List<Inquiry> inquiries = getInquiryUpload();
-        if (!CollectionUtils.isEmpty(inquiries)) {
-            ContextHolder.setDataSize(inquiries.size());
-            new StatusBasedHandler<Inquiry>("inquiry", "in_id", "IN_SENDSTATUS", "/erp/purchase/inquiry", inquiries).run();
+        Integer size = uploadProduct();
+        if (size == 0) {
+            List<Inquiry> inquiries = getInquiryUpload();
+            if (!CollectionUtils.isEmpty(inquiries)) {
+                ContextHolder.setDataSize(inquiries.size());
+                new StatusBasedHandler<Inquiry>("inquiry", "in_id", "IN_SENDSTATUS", "/erp/purchase/inquiry", inquiries).run();
+            }
         }
     }
 
@@ -50,16 +52,13 @@ public class InquiryTask extends AbstractTask {
     /**
      * 上传物料资料
      */
-    private void uploadProduct() {
+    private Integer uploadProduct() {
         final List<Prod> prods = jdbcTemplate.queryForBeanList("select * from (select pr_id,pr_code,pr_detail,pr_spec,pr_unit,pr_zxbzs,pr_zxdhl,pr_leadtime,pr_ltinstock,pr_brand from product where exists (select 1 from inquirydetail left join vendor on id_vendcode=ve_code left join inquiry on in_id=id_inid where (IN_SENDSTATUS='待上传' or IN_SENDSTATUS='上传中') and nvl(in_class,' ')<>'主动报价' and ve_uu is not null and nvl(ve_b2benable,0)=1 and id_prodcode=pr_code) and nvl(pr_sendstatus,' ')<>'已上传') where rownum <= 500",
                 Prod.class);
         if (!CollectionUtils.isEmpty(prods)) {
-            new ProductHandler(prods).run();
-            if (prods.size() == DATA_SIZE_LIMIT) {
-                // 递归,直到相关物料全部传完
-                uploadProduct();
-            }
+            return prods.size();
         }
+        return 0;
     }
 
     /**

+ 11 - 8
src/main/java/com/uas/erp/schedular/b2b/task/MakeTask.java

@@ -27,12 +27,14 @@ public class MakeTask extends AbstractTask {
 
     @TaskMapping(title = "上传委外加工单", fixedDelay = 60000)
     public void uploadMake() {
-        uploadProduct();
-        List<Make> makes = jdbcTemplate.queryForBeanList("select * from (select make.*, ve_uu from make left join vendor on ma_vendcode=ve_code where nvl(ve_b2benable,0)=1 and ve_uu is not null and nvl(ma_tasktype, '')='OS' and ma_checkstatuscode='APPROVE' and (ma_sendstatus='待上传' or ma_sendstatus='上传中')) where rownum <= 100",
-                Make.class);
-        if (!CollectionUtils.isEmpty(makes)) {
-            ContextHolder.setDataSize(makes.size());
-            new StatusBasedHandler<Make>("make", "ma_id", "ma_sendstatus", "/erp/make", makes).run();
+        Integer size = uploadProduct();
+        if (size == 0) {
+            List<Make> makes = jdbcTemplate.queryForBeanList("select * from (select make.*, ve_uu from make left join vendor on ma_vendcode=ve_code where nvl(ve_b2benable,0)=1 and ve_uu is not null and nvl(ma_tasktype, '')='OS' and ma_checkstatuscode='APPROVE' and (ma_sendstatus='待上传' or ma_sendstatus='上传中')) where rownum <= 100",
+                    Make.class);
+            if (!CollectionUtils.isEmpty(makes)) {
+                ContextHolder.setDataSize(makes.size());
+                new StatusBasedHandler<Make>("make", "ma_id", "ma_sendstatus", "/erp/make", makes).run();
+            }
         }
     }
 
@@ -40,12 +42,13 @@ public class MakeTask extends AbstractTask {
     /**
      * 上传物料资料
      */
-    private void uploadProduct() {
+    private Integer uploadProduct() {
         final List<Prod> prods = jdbcTemplate.queryForBeanList("select * from (select pr_id,pr_code,pr_detail,pr_spec,pr_unit,pr_zxbzs,pr_zxdhl,pr_leadtime,pr_ltinstock,pr_brand from product where exists (select 1 from make left join vendor on ve_code = ma_vendcode where ma_tasktype='OS'  and ve_uu is not null and nvl(ve_b2benable,0)=1 and make.ma_prodcode = product.pr_code) and nvl(pr_sendstatus,' ')<>'已上传' order by pr_id) where rownum <= 500",
                 Prod.class);
         if (!CollectionUtils.isEmpty(prods)) {
-            new ProductHandler(prods).run();
+            return prods.size();
         }
+        return 0;
     }
 
     @TaskMapping(title = "从平台下载委外加工单的回复记录", fixedDelay = 60000, method = Method.DOWNLOAD)

+ 0 - 57
src/main/java/com/uas/erp/schedular/b2b/task/ProductSalerTask.java

@@ -1,57 +0,0 @@
-package com.uas.erp.schedular.b2b.task;
-
-import com.uas.erp.schedular.b2b.domain.Prod;
-import com.uas.erp.schedular.b2b.domain.ProductSaler;
-import com.uas.erp.schedular.entity.Master;
-import com.uas.erp.schedular.task.support.Method;
-import com.uas.erp.schedular.task.support.Role;
-import com.uas.erp.schedular.task.support.TaskMapping;
-import com.uas.erp.schedular.util.ContextHolder;
-import org.springframework.stereotype.Component;
-import org.springframework.util.CollectionUtils;
-
-import java.util.List;
-
-/**
- * 个人物料信息同步接口
- *
- * Created by hejq on 2018-01-12.
- */
-@Component
-@TaskMapping(title = "个人物料信息", role = Role.PLAIN)
-public class ProductSalerTask extends AbstractTask {
-
-    /**
-     * 同步ERP的个人物料信息到平台数据库
-     *
-     * @author hejq
-     * @date 2018-01-12 19:05
-     */
-    @TaskMapping(title = "同步ERP的个人物料信息到商务平台", fixedDelay = 60000, method = Method.UPLOAD)
-    public void uploadProductSaler() {
-        List<ProductSaler> prods = jdbcTemplate.queryForBeanList("select ps_id,ps_prcode,em_uu from productsaler left join employee on productsaler.ps_emcode = employee.em_code where em_uu is not null and nvl(ps_uploadstatus, 0) <> -1 and nvl(ps_emstatus, 0) < 0 and rownum <= 200",
-                ProductSaler.class);
-        if (!CollectionUtils.isEmpty(prods)) {
-            ContextHolder.increaseDataSize(prods.size());
-            new StatusBasedHandler<ProductSaler>("productsaler", "ps_id", "ps_uploadstatus", "/erp/product/produser", prods).run();
-        }
-    }
-
-    /**
-     * ERP个人物料删除同步状态到平台
-     *
-     * @author hejq
-     * @date 2018-01-12 19:05
-     */
-    @TaskMapping(title = "ERP个人物料删除同步状态到平台", fixedDelay = 60000, method = Method.UPLOAD)
-    public void uploadProductSalerForCancel() {
-        List<ProductSaler> prods = jdbcTemplate.queryForBeanList("select ps_id,ps_prcode,em_uu from productsaler left join employee " +
-                        "on productsaler.ps_emcode = employee.em_code " +
-                        "where em_uu is not null and nvl(ps_uploadstatus, 0) <> -1 and nvl(ps_emstatus, 0) = 0 and rownum <= 200",
-                ProductSaler.class);
-        if (!CollectionUtils.isEmpty(prods)) {
-            ContextHolder.increaseDataSize(prods.size());
-            new StatusBasedHandler<ProductSaler>("productsaler", "ps_id", "ps_uploadstatus", "/erp/product/produser/quit", prods).run();
-        }
-    }
-}

+ 0 - 80
src/main/java/com/uas/erp/schedular/b2b/task/ProductTask.java

@@ -1,80 +0,0 @@
-package com.uas.erp.schedular.b2b.task;
-
-import com.uas.erp.schedular.b2b.domain.Prod;
-import com.uas.erp.schedular.task.support.Method;
-import com.uas.erp.schedular.task.support.TaskMapping;
-import com.uas.erp.schedular.util.CollectionUtil;
-import com.uas.erp.schedular.util.ContextHolder;
-import org.springframework.stereotype.Component;
-import org.springframework.util.CollectionUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Created by Pro1 on 2017/8/2.
- */
-@Component
-@TaskMapping(title = "物料")
-public class ProductTask extends AbstractTask {
-
-    /**
-     * 默认8到21点间每小时执行一次
-     */
-    @TaskMapping(title = "上传物料", cron = "0 0 8-21 * * *")
-    public void uploadProduct() {
-        List<Prod> prods = jdbcTemplate.queryForBeanList("select * from (select pr_id,pr_code,pr_detail,pr_spec,pr_unit,pr_zxbzs,pr_zxdhl,pr_leadtime,pr_ltinstock,pr_brand,pr_issale,pr_ispurchase,pr_isshow,pr_ispubsale,pr_uuid,pr_orispeccode from product where  nvl(pr_sendstatus,' ')<>'已上传' and  nvl(pr_status, ' ') = '已审核' order by pr_id) where rownum <= 500",
-                Prod.class);
-        if (!CollectionUtils.isEmpty(prods)) {
-            ContextHolder.increaseDataSize(prods.size());
-            new StatusBasedHandler<Prod>("product", "pr_id", "PR_SENDSTATUS", "/erp/product/cycleupdate", prods).run();
-            if (prods.size() == DATA_SIZE_LIMIT) {
-                // 递归,直到没有需要上传的数据
-                uploadProduct();
-            }
-        }
-    }
-
-    /**
-     * 默认8到21点间每小时第15分钟执行一次
-     */
-    @TaskMapping(title = "下载更新物料信息", cron = "0 15 8-21 * * *", method = Method.DOWNLOAD)
-    public void downloadProduct() {
-        List<Prod> prods = getForList("/erp/product/backtouas", Prod.class);
-        if (!CollectionUtils.isEmpty(prods)) {
-            ContextHolder.setDataSize(prods.size());
-            saveProdDown(prods);
-            // 回执
-            downloadSuccess(prods);
-        }
-    }
-
-    /**
-     * 保存更新物料信息
-     *
-     * @param prods
-     */
-    private void saveProdDown(List<Prod> prods) {
-        List<String> sqls = new ArrayList<>();
-        for (Prod prod : prods) {
-            String sql = "update product set pr_uuid = '" + prod.getPr_uuid() + "' where pr_id = " + prod.getPr_id();
-            sqls.add(sql);
-        }
-        jdbcTemplate.batchExecute(sqls);
-    }
-
-    /**
-     * 更新平台的下载状态为已下载
-     * @param prods
-     */
-    private void downloadSuccess(List<Prod> prods) {
-        String idStr = CollectionUtil.getKeyString(prods, new CollectionUtil.KeyIterator<Prod>() {
-            @Override
-            public Object getKey(Prod obj) {
-                return obj.getB2b_id();
-            }
-        });
-        post("/erp/product/refreshDownloadstatus", dataWrap(idStr));
-    }
-
-}

+ 0 - 217
src/main/java/com/uas/erp/schedular/b2b/task/PublicInquiryTask.java

@@ -1,217 +0,0 @@
-package com.uas.erp.schedular.b2b.task;
-
-import com.uas.erp.schedular.b2b.domain.*;
-import com.uas.erp.schedular.database.SqlTemplate;
-import com.uas.erp.schedular.task.support.Method;
-import com.uas.erp.schedular.task.support.Role;
-import com.uas.erp.schedular.task.support.TaskMapping;
-import com.uas.erp.schedular.util.CollectionUtil;
-import com.uas.erp.schedular.util.ContextHolder;
-import org.springframework.stereotype.Component;
-import org.springframework.util.CollectionUtils;
-import org.springframework.util.StringUtils;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 关于公共询价的轮询操作
- *
- * Created by Pro1 on 2017/9/23.
- */
-@Component
-@TaskMapping(title = "公共询价", role = Role.BUYER)
-public class PublicInquiryTask extends AbstractTask {
-
-    /**
-     * 上传物料资料
-     */
-    private void uploadProduct() {
-        final List<Prod> prods = jdbcTemplate.queryForBeanList("select * from (select pr_id,pr_code,pr_detail,pr_spec,pr_unit,pr_zxbzs,pr_zxdhl,pr_leadtime,pr_ltinstock,pr_brand from product p left join batchinprod b on p.pr_code = b.bip_prodcode left join batchinquiry i on b.bip_biid = i.bi_id where p.pr_sendstatus = '待上传' and i.bi_sendstatus = '待上传') where rownum <= 500",
-                Prod.class);
-        if (!CollectionUtils.isEmpty(prods)) {
-            new ProductHandler(prods).run();
-            if (prods.size() == DATA_SIZE_LIMIT) {
-                // 递归,直到相关物料全部传完
-                uploadProduct();
-            }
-        }
-    }
-
-    @TaskMapping(title = "上传询价单", fixedDelay = 30000)
-    public void uploadInquiry() {
-        uploadProduct();
-        List<BatchInquiry> inquiries = getInquiryUpload();
-        if (!CollectionUtils.isEmpty(inquiries)) {
-            ContextHolder.setDataSize(inquiries.size());
-            logger.info("inquiries size: " + inquiries.size());
-            logger.info("inquiries keys: " + CollectionUtil.getKeyString(inquiries));
-            new StatusBasedHandler<BatchInquiry>("batchinquiry", "bi_id", "bi_sendstatus", "/erp/purchase/publicinquiry", inquiries).run();
-        }
-    }
-
-    /**
-     * 获取需要上传的询价单
-     *
-     * @return
-     */
-    private List<BatchInquiry> getInquiryUpload() {
-        List<BatchInquiry> inquiries = jdbcTemplate.queryForBeanList("select bi_id,bi_code,bi_date,bi_kind,bi_environment,bi_purpose,bi_pricekind,bi_recorder,bi_recorddate,bi_enddate,bi_remark,bi_pricetype,bi_recorduu,bi_attach from batchinquiry where bi_sendstatus = '待上传' and bi_status = '已审核' and bi_kind = '公开询价'",
-                BatchInquiry.class);
-        for (BatchInquiry inquiry : inquiries) {
-            // 获取询价单明细
-            List<BatchInProduct> details = jdbcTemplate.queryForBeanList("select * from batchinprod where bip_biid = ?",
-                    BatchInProduct.class, inquiry.getBi_id());
-            inquiry.setInProducts(details);
-            // 附件
-            if (StringUtils.hasText(inquiry.getIn_attach())) {
-                inquiry.setAttaches(getAttachs(inquiry.getIn_attach().split(";")));
-            }
-        }
-        return inquiries;
-    }
-
-    @TaskMapping(title = "上传已提交审核的公共询价单", fixedDelay = 30000)
-    public void uploadInquiryAfterCheck() {
-        List<BatchInquiry> inquiries = jdbcTemplate.queryForBeanList("select bi_id,bi_code from batchinquiry where bi_checksendstatus = '待上传'",
-                BatchInquiry.class);
-        if (!CollectionUtils.isEmpty(inquiries)) {
-            ContextHolder.setDataSize(inquiries.size());
-            new StatusBasedHandler<BatchInquiry>("batchinquiry", "bi_id", "bi_checksendstatus", "/erp/purchase/publicinquiry/check", inquiries).run();
-        }
-    }
-
-    /**
-     * 从平台获取供应商已经报价的公共询价单
-     *
-     * @author hejq
-     * @date 2018-01-10 16:32
-     * @throws Exception
-     */
-    @TaskMapping(title = "从平台下载供应商的询价单报价", fixedDelay = 60000, method = Method.DOWNLOAD)
-    public void downloadReply() throws Exception{
-        List<InquiryDetail> details = getForList("/erp/purchase/publicinquiry/infos", InquiryDetail.class);
-        if (!CollectionUtils.isEmpty(details)) {
-            ContextHolder.setDataSize(details.size());
-            saveInquiryReply(details);
-            // 回执
-            onReplySuccess(details);
-            // 附件
-            saveInquiryDetailAttach(details);
-        }
-    }
-
-    /**
-     * 保存供应商的报价信息,存到ERP
-     *
-     * @author hejq
-     * @date 2018-01-10 16:39
-     * @param details 询价明细
-     * @throws Exception
-     */
-    private void saveInquiryReply(List<InquiryDetail> details) throws Exception {
-        // 先获取状态(用于区分消息类型)
-        for (InquiryDetail detail : details) {
-            String status = jdbcTemplate.getString("select max(id_status) from inquirydetail,inquiry where id_inid=in_id and in_code=? and id_vendyyzzh=? and id_prodcode=?",
-                    detail.getIn_code(), detail.getId_vendyyzzh(), detail.getId_prodcode());
-            detail.setId_status(status);
-        }
-
-        Map<String, Object> model = new HashMap<>();
-        model.put("inquiryDetails", details);
-        // 解析sql模板
-        String sql = SqlTemplate.fromXmlFile("database/template/pubInquiryReply.xml", model);
-        jdbcTemplate.execute(sql);
-    }
-
-    /**
-     * 修改平台里面询价单的下载状态
-     *
-     * @author hejq
-     * @date 2018-01-10 16:40
-     * @param details 询价单明细
-     */
-    private void onReplySuccess(List<InquiryDetail> details) {
-        String idStr = CollectionUtil.getKeyString(details);
-        post("/erp/purchase/publicinquiry/reply/back", dataWrap(idStr));
-    }
-
-    /**
-     * 保存来自平台的公共询价单附件信息
-     *
-     * @author hejq
-     * @date 2018-01-10 16:41
-     * @param details 询价单明细
-     */
-    private void saveInquiryDetailAttach(List<InquiryDetail> details) {
-        List<String> sqls = new ArrayList<String>();
-        String remoteUrl = "B2B://file";
-        for (InquiryDetail detail : details) {
-            if (!CollectionUtils.isEmpty(detail.getFiles())) {
-                StringBuffer attachIds = new StringBuffer();
-                for (RemoteFile file : detail.getFiles()) {
-                    int id = jdbcTemplate.generate("filepath_seq");
-                    sqls.add(file.toSqlString(id, remoteUrl));
-                    attachIds.append(id).append(";");
-                }
-                sqls.add("update InquiryDetail set id_attach='" + attachIds.toString() + "' where id_id=" + detail.getId_id());
-            }
-        }
-        jdbcTemplate.batchExecute(sqls);
-    }
-
-    /**
-     * ERP询价单提交后,同步到平台进行状态更新
-     *
-     * @author hejq
-     * @date 2018-01-10 19:32
-     */
-    @TaskMapping(title = "询价单提交后,上传平台", fixedDelay = 60000)
-    public void uploadCheckInquiry() {
-        List<Inquiry> inquiries = jdbcTemplate.queryForBeanList("select * from (select in_id,in_code from inquiryAuto where in_checkStatus = '已提交' and in_checkSendStatus='待上传' and nvl(in_class,' ')<>'主动报价' and in_sendStatus='已上传' order by in_id) where rownum < 100", Inquiry.class);
-        if (!CollectionUtils.isEmpty(inquiries)) {
-            ContextHolder.setDataSize(inquiries.size());
-            new StatusBasedHandler<Inquiry>("inquiryAuto", "in_id", "in_checkSendStatus", "/erp/purchase/publicinquiry/checking", inquiries).run();
-        }
-    }
-
-    /**
-     * ERP针对卖家报价信息的采纳状态传回平台
-     *
-     * @author hejq
-     * @date 2018-01-10 19:34
-     */
-    @TaskMapping(title = "上传买家对报价信息是否采纳的决策到平台", fixedDelay = 60000)
-    public void uploadInquiryDecide() {
-        List<InquiryDecide> replies = jdbcTemplate.queryForBeanList("select id_id,in_code,id_detno,id_isagreed id_agreed from InquiryAutoDetail left join InquiryAuto on id_inid=in_id left join vendor on id_vendcode=ve_code where IN_SENDSTATUS='已上传' and nvl(in_class,' ')<>'主动报价' and ID_SENDSTATUS='待上传' and id_isagreed is not null and ve_uu is not null and nvl(ve_b2benable,0)=1 and rownum < 100 order by in_code,id_detno",
-                InquiryDecide.class);
-        if (!CollectionUtils.isEmpty(replies)) {
-            ContextHolder.setDataSize(replies.size());
-            post("/erp/purchase/publicinquiry/reply/decide", dataWrap(replies));
-            String idStr = CollectionUtil.getKeyString(replies);
-            logger.info("上传采纳决策到平台,ids: " + idStr);
-            jdbcTemplate.execute("update InquiryAutoDetail set id_sendstatus='已下载' where id_id in (" + idStr + ")");
-        }
-    }
-
-    /**
-     * ERP单据作废信息传回平台进行操作
-     *
-     * @author hejq
-     * @date 2018-01-10 19:34
-     */
-    @TaskMapping(title = "上传买家对报价信息作废的决策到平台", fixedDelay = 60000)
-    public void uploadInquiryInvalid() {
-        List<Inquiry> inquiries = jdbcTemplate.queryForBeanList("select * from InquiryAuto left join InquiryAutoDetail on id_inid=in_id left join vendor on id_vendcode=ve_code where in_status = '已作废' and in_sendStatus <> '作废已上传' and nvl(in_class,' ')<>'主动报价'  and ve_uu is not null and nvl(ve_b2benable,0)=1 and rownum <= 100 order by in_code",
-                Inquiry.class);
-        if (!CollectionUtils.isEmpty(inquiries)) {
-            ContextHolder.setDataSize(inquiries.size());
-            post("/erp/purchase/publicinquiry/invalid", dataWrap(inquiries));
-            String idStr = CollectionUtil.getKeyString(inquiries);
-            logger.info("公共询价单作废单据,ids: " + idStr);
-            jdbcTemplate.execute("update InquiryAuto set in_sendStatus='作废已上传' where in_id in (" + idStr + ")");
-        }
-    }
-}

+ 28 - 12
src/main/java/com/uas/erp/schedular/b2b/task/PurchaseTask.java

@@ -11,6 +11,7 @@ import com.uas.erp.schedular.util.DateUtil;
 import com.uas.erp.schedular.util.StringUtil;
 import org.springframework.stereotype.Component;
 import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
 
 import java.util.ArrayList;
 import java.util.Date;
@@ -35,16 +36,13 @@ public class PurchaseTask extends AbstractTask {
     /**
      * 上传物料资料
      */
-    private void uploadProduct() {
+    private Integer uploadProduct() {
         final List<Prod> prods = jdbcTemplate.queryForBeanList("select * from (select pr_id,pr_code,pr_detail,pr_spec,pr_unit,pr_zxbzs,pr_zxdhl,pr_leadtime,pr_ltinstock,pr_brand from product where exists (select 1 from purchase left join vendor on pu_vendcode=ve_code left join purchasedetail on pd_puid=pu_id where (PU_SENDSTATUS='待上传' or PU_SENDSTATUS='上传中' or pu_sendstatus='已上传') and nvl(pu_ordertype,' ')<>'B2C' and pu_statuscode='AUDITED' and ve_uu is not null and nvl(ve_b2benable,0)=1 and pd_prodcode=pr_code) and nvl(pr_sendstatus,' ')<>'已上传' order by pr_id) where rownum <= 500",
                 Prod.class);
         if (!CollectionUtils.isEmpty(prods)) {
-            new ProductHandler(prods).run();
-            if (prods.size() == DATA_SIZE_LIMIT) {
-                // 递归,直到相关物料全部传完
-                uploadProduct();
-            }
+            return prods.size();
         }
+        return 0;
     }
 
     /**
@@ -60,6 +58,13 @@ public class PurchaseTask extends AbstractTask {
         for (Purchase purchase : purchases) {
             List<PurchaseDetail> purchaseDetails = jdbcTemplate.queryForBeanList("select * from (select p.*,(select max(pv_vendprodspec) from productvendor where pv_prodcode=pd_prodcode and pv_vendcode=?) as pd_vendspec from purchasedetail p where pd_puid=?)",
                     PurchaseDetail.class, purchase.getPu_vendcode(), purchase.getPu_id());
+            if (!CollectionUtils.isEmpty(purchaseDetails)) {
+                for(PurchaseDetail detail : purchaseDetails) {
+                    if (StringUtils.hasText(detail.getPd_prattach())) {
+                        detail.setAttaches(getAttachs(detail.getPd_prattach().split(";")));
+                    }
+                }
+            }
             purchase.setPurchaseDetails(purchaseDetails);
             thisPost.add(purchase);
             if ((count = count + purchaseDetails.size()) >= DATA_SIZE_LIMIT)
@@ -68,6 +73,23 @@ public class PurchaseTask extends AbstractTask {
         return thisPost;
     }
 
+    /**
+     * 查找附件
+     * @param attachIds 附件ID
+     * @return
+     */
+    protected List<Attach> getAttachs(String[] attachIds) {
+        String erpUrl = settingService.getValue("api.uas.outer.url");
+        List<Attach> attaches = jdbcTemplate.queryForBeanList("select fp_id, fp_size, fp_name from filepath where fp_id in ("
+                + StringUtils.arrayToDelimitedString(attachIds, ",") + ")", Attach.class);
+        if (!CollectionUtils.isEmpty(attaches)) {
+            for (Attach attach : attaches) {
+                attach.setFp_url(erpUrl + Attach.DOWN_FILE_ACTION + attach.getFp_id());
+            }
+        }
+        return attaches;
+    }
+
     @TaskMapping(title = "从平台下载供应商的回复记录", fixedDelay = 30000, method = Method.DOWNLOAD)
     public void downloadReply() {
         List<PurchaseReply> replies = getForList("/erp/purchase/reply", PurchaseReply.class);
@@ -90,12 +112,6 @@ public class PurchaseTask extends AbstractTask {
         for (PurchaseReply reply : replies) {
             sqls.add("update PurchaseReply set pr_ifoverdate=-1 where pr_pucode='" + reply.getPr_pucode() + "' and pr_pddetno=" +
                 reply.getPr_pddetno() + " and nvl(pr_ifoverdate,0)<>-1");
-//            sqls.add("MERGE into PurchaseDetail a using (select count(1) c from PurchaseReply where b2b_pr_id=" + reply.getB2b_pr_id()
-//                    + ") b on (b.c=0) when MATCHED THEN update set pd_qtyreply = nvl(pd_qtyreply, 0) + " + reply.getPr_qty()
-//                    + ", pd_deliveryReply = '" + DateUtil.format(reply.getPr_delivery(), Constant.YMD) + "', pd_replydetail='"
-//                    + StringUtil.nvl(reply.getPr_remark(), "") + "',pd_vendoreplydate="
-//                    + DateUtil.parseDateToOracleString(Constant.YMD_HMS, new Date()) + " where pd_code='" + reply.getPr_pucode()
-//                    + "' and pd_detno=" + reply.getPr_pddetno());
             // 接口调整,reply.pr_qty表示最新的回复数量
             sqls.add("update PurchaseDetail set pd_qtyreply=" + reply.getPr_qty()
                     + ", pd_deliveryReply = '" + DateUtil.format(reply.getPr_delivery(), Constant.YMD) + "', pd_replydetail='"

+ 7 - 3
src/main/java/com/uas/erp/schedular/b2b/task/SaleDownTask.java

@@ -14,6 +14,7 @@ import com.uas.erp.schedular.util.DateUtil;
 import com.uas.erp.schedular.util.StringUtil;
 import org.springframework.stereotype.Component;
 import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -50,9 +51,12 @@ public class SaleDownTask extends AbstractTask {
             int count = jdbcTemplate.count("from SaleDown where sa_type='purchase' and b2b_pu_id=?", sale.getB2b_pu_id());
             if (count == 0) {
                 int saId = jdbcTemplate.generate("SaleDown_SEQ");
-                Float rate = jdbcTemplate.getFloat("select cm_crrate from currencysmonth left join Currencys on cr_name=cm_crname where cm_yearmonth = ? and cm_crname = ? and nvl(cr_statuscode,' ')='CANUSE'",
-                        Float.class, DateUtil.getYearmonth(sale.getSa_date()), sale.getSa_currency());
-                sale.setSa_rate(rate);
+                String rateStr = jdbcTemplate.getString("select cm_crrate from currencysmonth left join Currencys on cr_name=cm_crname where cm_yearmonth = ? and cm_crname = ? and nvl(cr_statuscode,' ')='CANUSE'",
+                        DateUtil.getYearmonth(sale.getSa_date()), sale.getSa_currency());
+                if (!StringUtils.isEmpty(rateStr)) {
+                    Float rate = Float.parseFloat(rateStr);
+                    sale.setSa_rate(rate);
+                }
                 sqls.add(sale.toSqlString(saId));
                 idList.add(Long.valueOf(saId));
                 if (!CollectionUtils.isEmpty(sale.getSaleDownDetails())) {

+ 68 - 0
src/main/java/com/uas/erp/schedular/publicinquiry/domain/Attach.java

@@ -0,0 +1,68 @@
+package com.uas.erp.schedular.publicinquiry.domain;
+
+import java.io.Serializable;
+
+/**
+ * 附件信息
+ * 
+ * @author suntg
+ * 
+ */
+public class Attach implements Serializable {
+
+	public static final String DOWN_FILE_ACTION = "/common/downloadbyId.action?id=";
+
+	/**
+	 * Default serialVersionUID
+	 */
+	private static final long serialVersionUID = 1L;
+	/**
+	 * ID
+	 */
+	private Long fp_id;
+	/**
+	 * 附件名称
+	 */
+	private String fp_name;
+	/**
+	 * 附件Url
+	 */
+	private String fp_url;
+	/**
+	 * 附件大小
+	 */
+	private Long fp_size;
+
+	public Long getFp_id() {
+		return fp_id;
+	}
+
+	public void setFp_id(Long fp_id) {
+		this.fp_id = fp_id;
+	}
+
+	public String getFp_name() {
+		return fp_name;
+	}
+
+	public void setFp_name(String fp_name) {
+		this.fp_name = fp_name;
+	}
+
+	public String getFp_url() {
+		return fp_url;
+	}
+
+	public void setFp_url(String fp_url) {
+		this.fp_url = fp_url;
+	}
+
+	public Long getFp_size() {
+		return fp_size;
+	}
+
+	public void setFp_size(Long fp_size) {
+		this.fp_size = fp_size;
+	}
+
+}

+ 140 - 0
src/main/java/com/uas/erp/schedular/publicinquiry/domain/BatchInProduct.java

@@ -0,0 +1,140 @@
+package com.uas.erp.schedular.publicinquiry.domain;
+
+/**
+ * 公共询价物料信息
+ *
+ * @author hejq
+ * @date 2018-01-17 14:30
+ */
+public class BatchInProduct {
+
+    /**
+     * 明细id
+     */
+    private Long bip_id;
+
+    /**
+     * 主表id
+     */
+    private Long bip_biid;
+
+    /**
+     * 序号
+     */
+    private Short bip_detno;
+
+    /**
+     * 物料编号
+     */
+    private String bip_prodcode;
+
+    /**
+     * 备注
+     */
+    private String bip_remark;
+
+    /**
+     * 币别
+     */
+    private String bip_currency;
+
+    /**
+     * 联系人编号
+     */
+    private String bip_buyercode;
+
+    /**
+     * 联系人电话
+     */
+    private String bip_mobile;
+
+    /**
+     * 联系人姓名
+     */
+    private String bip_buyername;
+
+    /**
+     * 联系人姓名
+     */
+    private String em_name;
+
+    public Long getBip_id() {
+        return bip_id;
+    }
+
+    public void setBip_id(Long bip_id) {
+        this.bip_id = bip_id;
+    }
+
+    public Long getBip_biid() {
+        return bip_biid;
+    }
+
+    public void setBip_biid(Long bip_biid) {
+        this.bip_biid = bip_biid;
+    }
+
+    public Short getBip_detno() {
+        return bip_detno;
+    }
+
+    public void setBip_detno(Short bip_detno) {
+        this.bip_detno = bip_detno;
+    }
+
+    public String getBip_prodcode() {
+        return bip_prodcode;
+    }
+
+    public void setBip_prodcode(String bip_prodcode) {
+        this.bip_prodcode = bip_prodcode;
+    }
+
+    public String getBip_remark() {
+        return bip_remark;
+    }
+
+    public void setBip_remark(String bip_remark) {
+        this.bip_remark = bip_remark;
+    }
+
+    public String getBip_currency() {
+        return bip_currency;
+    }
+
+    public void setBip_currency(String bip_currency) {
+        this.bip_currency = bip_currency;
+    }
+
+    public String getBip_buyercode() {
+        return bip_buyercode;
+    }
+
+    public void setBip_buyercode(String bip_buyercode) {
+        this.bip_buyercode = bip_buyercode;
+    }
+
+    public String getBip_mobile() {
+        return bip_mobile;
+    }
+
+    public void setBip_mobile(String bip_mobile) {
+        this.bip_mobile = bip_mobile;
+    }
+
+    public String getBip_buyername() {
+        return bip_buyername;
+    }
+
+    public void setBip_buyername(String bip_buyername) {
+        this.bip_buyername = bip_buyername;
+    }
+
+    public String getEm_name() {
+        return em_name;
+    }
+
+    public void setEm_name(String em_name) {
+        this.em_name = em_name;
+    }
+}

+ 228 - 0
src/main/java/com/uas/erp/schedular/publicinquiry/domain/BatchInquiry.java

@@ -0,0 +1,228 @@
+package com.uas.erp.schedular.publicinquiry.domain;
+
+import com.uas.erp.schedular.b2b.domain.KeyEntity;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 公共询价信息
+ * 
+ * @author hejq
+ * @date 2018-01-17 14:31
+ */
+public class BatchInquiry extends KeyEntity {
+
+    /**
+     * erp id
+     */
+    private Long bi_id;
+
+    /**
+     * 询价单号
+     */
+    private String bi_code;
+
+    /**
+     * 时间
+     */
+    private Date bi_date;
+
+    /**
+     * 询价类型
+     */
+    private String bi_kind;
+
+    /**
+     * 环保需求
+     */
+    private String bi_environment;
+
+    /**
+     * 使用范围
+     */
+    private String bi_purpose;
+
+    /**
+     * 价格类型
+     */
+    private String bi_pricekind;
+
+    /**
+     * 录入人
+     */
+    private String bi_recorder;
+
+    /**
+     * 录入人uu
+     */
+    private Long bi_recorduu;
+
+    /**
+     * 录入时间
+     */
+    private String bi_recorddate;
+
+    /**
+     * 报价截止日期
+     */
+    private Date bi_enddate;
+
+    /**
+     * 备注
+     */
+    private String bi_remark;
+
+    /**
+     * 价格种类
+     */
+    private String bi_pricetype;
+
+    /**
+     * 询价物料
+     */
+    private List<BatchInProduct> inProducts;
+
+    /**
+     * 附件
+     */
+    private String in_attach;
+
+    /**
+     *  所有的附件信息
+     */
+    private List<Attach> attaches;
+
+    public Long getBi_id() {
+        return bi_id;
+    }
+
+    public void setBi_id(Long bi_id) {
+        this.bi_id = bi_id;
+    }
+
+    public String getBi_code() {
+        return bi_code;
+    }
+
+    public void setBi_code(String bi_code) {
+        this.bi_code = bi_code;
+    }
+
+    public Date getBi_date() {
+        return bi_date;
+    }
+
+    public void setBi_date(Date bi_date) {
+        this.bi_date = bi_date;
+    }
+
+    public String getBi_kind() {
+        return bi_kind;
+    }
+
+    public void setBi_kind(String bi_kind) {
+        this.bi_kind = bi_kind;
+    }
+
+    public String getBi_environment() {
+        return bi_environment;
+    }
+
+    public void setBi_environment(String bi_environment) {
+        this.bi_environment = bi_environment;
+    }
+
+    public String getBi_purpose() {
+        return bi_purpose;
+    }
+
+    public void setBi_purpose(String bi_purpose) {
+        this.bi_purpose = bi_purpose;
+    }
+
+    public String getBi_pricekind() {
+        return bi_pricekind;
+    }
+
+    public void setBi_pricekind(String bi_pricekind) {
+        this.bi_pricekind = bi_pricekind;
+    }
+
+    public String getBi_recorder() {
+        return bi_recorder;
+    }
+
+    public void setBi_recorder(String bi_recorder) {
+        this.bi_recorder = bi_recorder;
+    }
+
+    public Long getBi_recorduu() {
+        return bi_recorduu;
+    }
+
+    public void setBi_recorduu(Long bi_recorduu) {
+        this.bi_recorduu = bi_recorduu;
+    }
+
+    public String getBi_recorddate() {
+        return bi_recorddate;
+    }
+
+    public void setBi_recorddate(String bi_recorddate) {
+        this.bi_recorddate = bi_recorddate;
+    }
+
+    public Date getBi_enddate() {
+        return bi_enddate;
+    }
+
+    public void setBi_enddate(Date bi_enddate) {
+        this.bi_enddate = bi_enddate;
+    }
+
+    public String getBi_remark() {
+        return bi_remark;
+    }
+
+    public void setBi_remark(String bi_remark) {
+        this.bi_remark = bi_remark;
+    }
+
+    public String getBi_pricetype() {
+        return bi_pricetype;
+    }
+
+    public void setBi_pricetype(String bi_pricetype) {
+        this.bi_pricetype = bi_pricetype;
+    }
+
+    public List<BatchInProduct> getInProducts() {
+        return inProducts;
+    }
+
+    public void setInProducts(List<BatchInProduct> inProducts) {
+        this.inProducts = inProducts;
+    }
+
+    public String getIn_attach() {
+        return in_attach;
+    }
+
+    public void setIn_attach(String in_attach) {
+        this.in_attach = in_attach;
+    }
+
+    public List<Attach> getAttaches() {
+        return attaches;
+    }
+
+    public void setAttaches(List<Attach> attaches) {
+        this.attaches = attaches;
+    }
+
+    @Override
+    public Object getKey() {
+        return bi_id;
+    }
+}

+ 49 - 0
src/main/java/com/uas/erp/schedular/publicinquiry/domain/Enterprise.java

@@ -0,0 +1,49 @@
+package com.uas.erp.schedular.publicinquiry.domain;
+
+/**
+ * 企业信息
+ *
+ * Created by hejq on 2018-01-19.
+ */
+public class Enterprise {
+
+    /**
+     * 企业地址
+     */
+    private String en_address;
+
+    /**
+     * 企业UU
+     */
+    private Long en_uu;
+
+    /**
+     * 企业名称
+     */
+    private String en_name;
+
+    public String getEn_address() {
+        return en_address;
+    }
+
+    public void setEn_address(String en_address) {
+        this.en_address = en_address;
+    }
+
+    public Long getEn_uu() {
+        return en_uu;
+    }
+
+    public void setEn_uu(Long en_uu) {
+        this.en_uu = en_uu;
+    }
+
+    public String getEn_name() {
+        return en_name;
+    }
+
+    public void setEn_name(String en_name) {
+        this.en_name = en_name;
+    }
+}
+

+ 327 - 0
src/main/java/com/uas/erp/schedular/publicinquiry/task/AbstractTask.java

@@ -0,0 +1,327 @@
+package com.uas.erp.schedular.publicinquiry.task;
+
+import com.alibaba.fastjson.JSON;
+import com.uas.erp.schedular.b2b.domain.KeyEntity;
+import com.uas.erp.schedular.core.Constant;
+import com.uas.erp.schedular.database.RestJdbcTemplate;
+import com.uas.erp.schedular.entity.Master;
+import com.uas.erp.schedular.publicproduct.domain.Prod;
+import com.uas.erp.schedular.publicinquiry.domain.Attach;
+import com.uas.erp.schedular.publicinquiry.domain.Enterprise;
+import com.uas.erp.schedular.service.SettingService;
+import com.uas.erp.schedular.util.CollectionUtil;
+import com.uas.erp.schedular.util.ContextHolder;
+import com.uas.erp.schedular.util.DateUtil;
+import com.uas.erp.schedular.util.HmacUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.util.StringUtils;
+import org.springframework.web.client.RestTemplate;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLEncoder;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 公共询价的轮询配置
+ * 
+ * @author hejq
+ * @date 2018-01-17 14:25
+ */
+public class AbstractTask {
+
+    // 数据传输单次大小限制
+    protected static final int DATA_SIZE_LIMIT = 500;
+
+    @Autowired
+    private RestTemplate restTemplate;
+
+    @Autowired
+    protected RestJdbcTemplate jdbcTemplate;
+
+    @Autowired
+    protected SettingService settingService;
+
+    protected Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    /**
+     * 按账套环境,使用不同接口地址
+     * @return
+     */
+    private String getApiDomain() {
+        String key = "test".equals(ContextHolder.getMaster().getMa_env()) ? "api.publicinquiry.test.url" : "api.publicinquiry.url";
+        return settingService.getValue(key);
+    }
+
+    /**
+     * UAS系统外网地址
+     * @return
+     */
+    private String getUASUrl() {
+        return settingService.getValue("api.uas.outer.url");
+    }
+
+    /**
+     * URI加身份签名
+     * @param url
+     * @param vars
+     * @return
+     */
+    private String getURI(String url, Object... vars) {
+        Master master = ContextHolder.getMaster();
+        if (null == master.getMa_uu() || StringUtils.isEmpty(master.getMa_accesssecret())) {
+            throw new RuntimeException("未设置企业UU和私钥");
+        }
+        StringBuffer accessUrl = new StringBuffer(url);
+        accessUrl.append(url.contains("?") ? "&" : "?");
+        // 身份ID
+        accessUrl.append("access_id=").append(master.getMa_uu());
+        // 时间戳
+        accessUrl.append("&_timestamp=").append(System.currentTimeMillis());
+        URI uri = restTemplate.getUriTemplateHandler().expand(getApiDomain() + accessUrl.toString(), vars);
+        url = uri.toString();
+        // 签名
+        return url + "&_signature=" + HmacUtils.encode(url, master.getMa_accesssecret());
+    }
+
+    protected <T> T getForObject(String url, Class<T> objectClass, Object... vars) {
+        return restTemplate.getForObject(getURI(url, vars), objectClass);
+    }
+
+    protected <T> List<T> getForList(String url, Class<T> objectClass, Object... vars) {
+        String resultStr = restTemplate.getForObject(getURI(url, vars), String.class);
+        return JSON.parseArray(resultStr, objectClass);
+    }
+
+    /**
+     * b2b当前版本的接口只支持以form-data方式提交,requestBody方式暂不支持
+     * @param url
+     * @param vars
+     */
+    protected void post(String url, MultiValueMap<String, String> vars) {
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(vars, headers);
+        restTemplate.postForLocation(getURI(url), request);
+    }
+
+    protected ResponseEntity postForEntity(String url, MultiValueMap<String, String> vars) {
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(vars, headers);
+        return restTemplate.postForEntity(getURI(url), request, String.class);
+    }
+
+    protected <T> List<T> postForList(String url, Class<T> objectClass, MultiValueMap<String, String> vars) {
+        ResponseEntity<String> resultEntity = postForEntity(url, vars);
+        return JSON.parseArray(resultEntity.getBody(), objectClass);
+    }
+
+    /**
+     * 封装成平台接口数据格式
+     * @param data
+     * @return
+     */
+    protected static MultiValueMap<String, String> dataWrap(Object data) {
+        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
+        String dataStr = null;
+        Class<?> cls = data.getClass();
+        if (cls.isAssignableFrom(String.class) || cls.isAssignableFrom(Number.class) ||
+                cls.isAssignableFrom(Character.class)) {
+            dataStr = data.toString();
+        } else {
+            dataStr = JSON.toJSONString(data);
+        }
+        try {
+            dataStr = URLEncoder.encode(dataStr, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+
+        }
+        map.set("data", dataStr);
+        return map;
+    }
+
+    /**
+     * 数据上传工具,封装了处理前、后置、错误处理方法
+     * @param <T>
+     */
+    protected abstract class AbstractHandler<T> {
+
+        private List<T> data;
+
+        public AbstractHandler(List<T> data) {
+            this.data = data;
+        }
+
+        /**
+         * onHandler方法前执行
+         */
+        protected void onBefore(){
+
+        }
+
+        protected abstract ResponseEntity onHandler(List<T> data);
+
+        /**
+         * onHandler方法执行成功后执行
+         */
+        protected void onSuccess(){
+
+        }
+
+        /**
+         * onHandler方法执行失败后执行
+         */
+        protected void onError(String message){
+            throw new RuntimeException(message);
+        }
+
+        /**
+         * 所有方法执行完成后执行
+         */
+        protected void onAfter(){
+
+        }
+
+        public void run() {
+            String errMsg = null;
+            onBefore();
+            try {
+                ResponseEntity response = onHandler(data);
+                if (!response.getStatusCode().is2xxSuccessful()) {
+                    errMsg = String.valueOf(response.getBody());
+                }
+            } catch (Exception e) {
+                errMsg = e.getMessage();
+            }
+            try {
+                if (null == errMsg) {
+                    onSuccess();
+                } else {
+                    onError(errMsg);
+                }
+            } finally {
+                onAfter();
+            }
+        }
+    }
+
+    /**
+     * POST方式处理工具
+     * @param <T>
+     */
+    protected class AbstractPostHandler<T> extends AbstractHandler<T> {
+        private String postUri;
+
+        public AbstractPostHandler(String postUri, List<T> data) {
+            super(data);
+            this.postUri = postUri;
+        }
+
+        @Override
+        protected ResponseEntity onHandler(List<T> data) {
+            return postForEntity(postUri, dataWrap(data));
+        }
+    }
+
+    /**
+     * 基于状态控制的处理工具
+     * @param <T>
+     */
+    protected abstract class AbstractStatusBasedHandler<T extends KeyEntity> extends AbstractPostHandler<T> {
+
+        private String idStr;
+        private String tableName;
+        private String idColumn;
+        private String statusColumn;
+
+        public AbstractStatusBasedHandler(String tableName, String idColumn, String statusColumn, String postUri, List<T> data) {
+            super(postUri, data);
+            this.idStr = CollectionUtil.getKeyString(data);
+            this.tableName = tableName;
+            this.idColumn = idColumn;
+            this.statusColumn = statusColumn;
+        }
+
+        @Override
+        protected void onBefore() {
+            jdbcTemplate.execute(String.format("update %s set %s='上传中' where %s in (%s)", tableName, statusColumn, idColumn, idStr));
+        }
+
+        @Override
+        protected void onSuccess() {
+            jdbcTemplate.execute(String.format("update %s set %s='已上传' where %s in (%s)", tableName, statusColumn, idColumn, idStr));
+        }
+
+        @Override
+        protected void onError(String message) {
+            jdbcTemplate.execute(String.format("update %s set %s='待上传' where %s in (%s) and %s='上传中'", tableName, statusColumn, idColumn, idStr, statusColumn));
+            super.onError(message);
+        }
+    }
+
+    /**
+     * 基于状态控制的处理工具
+     * @param <T>
+     */
+    protected class StatusBasedHandler<T extends KeyEntity> extends AbstractStatusBasedHandler<T> {
+
+        public StatusBasedHandler(String tableName, String idColumn, String statusColumn, String postUri, List<T> data) {
+            super(tableName, idColumn, statusColumn, postUri, data);
+        }
+    }
+
+    /**
+     * 处理物料上传的工具
+     */
+    protected final class ProductHandler extends StatusBasedHandler<Prod>{
+
+        public ProductHandler(List<Prod> data, Enterprise enterprise) {
+            super("product", "pr_id", "PR_SENDSTATUS", "/product/erp/save?enUU=" + enterprise.getEn_uu(), data);
+        }
+    }
+
+    /**
+     * 查找附件
+     * @param attachIds 附件ID
+     * @return
+     */
+    protected List<Attach> getAttachs(String[] attachIds) {
+        String erpUrl = getUASUrl();
+        List<Attach> attaches = jdbcTemplate.queryForBeanList("select fp_id, fp_size, fp_name from filepath where fp_id in ("
+                + StringUtils.arrayToDelimitedString(attachIds, ",") + ")", Attach.class);
+        if (!CollectionUtils.isEmpty(attaches)) {
+            for (Attach attach : attaches) {
+                attach.setFp_url(erpUrl + Attach.DOWN_FILE_ACTION + attach.getFp_id());
+            }
+        }
+        return attaches;
+    }
+
+    /**
+     * 创建消息
+     *
+     * @param caller
+     * @param sourceIds
+     * @param type
+     */
+    protected void createMessage(String caller, String sourceIds, String type) {
+        Integer mid = jdbcTemplate.getInt("select max(mm_id) from MESSAGEMODEL left join MESSAGEROLE on mm_id=mr_mmid where MR_ISUSED=-1 AND MM_ISUSED=-1 and mm_caller=? and MM_OPERATE='b2b' AND MM_ACTION=?",
+                caller, type);
+        if (null != mid) {
+            jdbcTemplate.callForString("{call SP_CREATEINFO(?,'ADMIN',?,?,?)}",
+                    mid, sourceIds, DateUtil.parseDateToOracleString(Constant.YMD_HMS, new Date()));
+        }
+    }
+
+}

+ 260 - 0
src/main/java/com/uas/erp/schedular/publicinquiry/task/PubInquiryTask.java

@@ -0,0 +1,260 @@
+package com.uas.erp.schedular.publicinquiry.task;
+
+import com.alibaba.fastjson.JSON;
+import com.uas.erp.schedular.b2b.domain.Inquiry;
+import com.uas.erp.schedular.b2b.domain.InquiryDecide;
+import com.uas.erp.schedular.b2b.domain.InquiryDetail;
+import com.uas.erp.schedular.b2b.domain.RemoteFile;
+import com.uas.erp.schedular.database.SqlTemplate;
+import com.uas.erp.schedular.publicproduct.domain.Prod;
+import com.uas.erp.schedular.publicinquiry.domain.BatchInProduct;
+import com.uas.erp.schedular.publicinquiry.domain.BatchInquiry;
+import com.uas.erp.schedular.publicinquiry.domain.Enterprise;
+import com.uas.erp.schedular.task.support.Method;
+import com.uas.erp.schedular.task.support.TaskMapping;
+import com.uas.erp.schedular.util.CollectionUtil;
+import com.uas.erp.schedular.util.ContextHolder;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 轮询上传数据到公共服务平台
+ *
+ * Created by hejq on 2018-01-17.
+ */
+@Component
+@TaskMapping(title = "公共询价")
+public class PubInquiryTask extends AbstractTask {
+
+    private org.slf4j.Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    /**
+     * 上传物料资料
+     */
+    private Integer uploadProduct(Enterprise enterprise) {
+        final List<Prod> prods = jdbcTemplate.queryForBeanList("select * from (select pr_id,pr_code,pr_detail,pr_spec,pr_unit,pr_zxbzs,pr_zxdhl,pr_leadtime,pr_ltinstock,pr_brand from product p left join batchinprod b on p.pr_code = b.bip_prodcode left join batchinquiry i on b.bip_biid = i.bi_id where p.pr_sendstatus = '待上传' and i.bi_sendstatus = '待上传') where rownum <= 500",
+                Prod.class);
+        logger.info("prods: " + prods.size());
+        if (!CollectionUtils.isEmpty(prods)) {
+            // 如果存在物料未上传,不进行单据上传
+            return prods.size();
+        }
+        return 0;
+    }
+
+    /**
+     * 处理物料上传的工具
+     */
+    protected final class ProductHandler extends AbstractTask.StatusBasedHandler<Prod> {
+
+        public ProductHandler(List<Prod> data, Enterprise enterprise) {
+            super("product", "pr_id", "PR_SENDSTATUS", "/product/erp/save?enUU=" + enterprise.getEn_uu(), data);
+        }
+    }
+
+    @TaskMapping(title = "上传询价单到公共服务", fixedDelay = 30000)
+    public void uploadInquiry() {
+        Enterprise enterprise = getEnterprise();
+        if (null != enterprise) {
+            Integer size = uploadProduct(enterprise);
+            if (size == 0) {
+                List<BatchInquiry> inquiries = getInquiryUpload();
+                if (!CollectionUtils.isEmpty(inquiries)) {
+                    ContextHolder.setDataSize(inquiries.size());
+                    logger.info("inquiries size: " + inquiries.size());
+                    logger.info("inquiries keys: " + CollectionUtil.getKeyString(inquiries));
+                    String url = "/inquiry/public?enuu=" + enterprise.getEn_uu() + "&address=" + enterprise.getEn_address();
+                    new AbstractTask.StatusBasedHandler<BatchInquiry>("batchinquiry", "bi_id", "bi_sendstatus", url, inquiries).run();
+                }
+            }
+        }
+    }
+
+    @TaskMapping(title = "从公共服务下载供应商的报价信息", fixedDelay = 60000, method = Method.DOWNLOAD)
+    public void downloadReply() throws Exception{
+        Enterprise enterprise = getEnterprise();
+        if (null != enterprise) {
+            List<InquiryDetail> details = getForList("/inquiry/public/quotation?enuu=" + enterprise.getEn_uu(), InquiryDetail.class);
+            if (!CollectionUtils.isEmpty(details)) {
+                ContextHolder.setDataSize(details.size());
+                saveInquiryReply(details);
+                // 回执
+                onReplySuccess(details, enterprise);
+                // 发消息
+                createMessageOnReplySuccess(details);
+                // 附件
+                saveInquiryDetailAttach(details);
+            }
+        }
+    }
+
+    /**
+     * 创建消息
+     * @param details
+     */
+    private void createMessageOnReplySuccess(List<InquiryDetail> details) {
+        String savedIdStr = CollectionUtil.getKeyString(details, new CollectionUtil.KeyIterator<InquiryDetail>() {
+            @Override
+            public Object getKey(InquiryDetail obj) {
+                return !"已报价".equals(obj.getId_status()) ? obj.getId_id() : null;
+            }
+        });
+        if (!savedIdStr.isEmpty()) {
+            createMessage("Inquiry", savedIdStr, "save");
+        }
+    }
+
+    /**
+     * 保存供应商的报价信息,存到ERP
+     *
+     * @author hejq
+     * @date 2018-01-10 16:39
+     * @param details 询价明细
+     * @throws Exception
+     */
+    private void saveInquiryReply(List<InquiryDetail> details) throws Exception {
+        Map<String, Object> model = new HashMap<>();
+        model.put("inquiryDetails", details);
+        // 解析sql模板
+        String sql = SqlTemplate.fromXmlFile("database/template/pubInquiryReply.xml", model);
+        jdbcTemplate.execute(sql);
+    }
+
+    /**
+     * 修改平台里面询价单的下载状态
+     *
+     * @author hejq
+     * @date 2018-01-10 16:40
+     * @param details 询价单明细
+     */
+    private void onReplySuccess(List<InquiryDetail> details, Enterprise enterprise) {
+        String idStr = CollectionUtil.getKeyString(details);
+        post("/inquiry/public/reply/back?enuu=" + enterprise.getEn_uu(), dataWrap(idStr));
+    }
+
+    /**
+     * 保存来自平台的公共询价单附件信息
+     *
+     * @author hejq
+     * @date 2018-01-10 16:41
+     * @param details 询价单明细
+     */
+    private void saveInquiryDetailAttach(List<InquiryDetail> details) {
+        List<String> sqls = new ArrayList<String>();
+        String remoteUrl = "B2B://file";
+        for (InquiryDetail detail : details) {
+            if (!CollectionUtils.isEmpty(detail.getFiles())) {
+                StringBuffer attachIds = new StringBuffer();
+                for (RemoteFile file : detail.getFiles()) {
+                    int id = jdbcTemplate.generate("filepath_seq");
+                    sqls.add(file.toSqlString(id, remoteUrl));
+                    attachIds.append(id).append(";");
+                }
+                sqls.add("update inquiryAutoDetail set id_attach='" + attachIds.toString() + "' where id_id=" + detail.getId_id());
+            }
+        }
+        jdbcTemplate.batchExecute(sqls);
+    }
+
+    /**
+     * ERP询价单提交后,同步到平台进行状态更新
+     *
+     * @author hejq
+     * @date 2018-01-10 19:32
+     */
+    @TaskMapping(title = "询价单提交后,上传到公共服务更新状态", fixedDelay = 60000)
+    public void uploadCheckInquiry() {
+        Enterprise enterprise = getEnterprise();
+        if (null != enterprise) {
+            List<Inquiry> inquiries = jdbcTemplate.queryForBeanList("select * from (select in_id,in_code from inquiryAuto where in_checkStatus = '已提交' and in_checkSendStatus='待上传' and nvl(in_class,' ')<>'主动报价' and in_sendStatus='已上传' order by in_id) where rownum < 100", Inquiry.class);
+            if (!CollectionUtils.isEmpty(inquiries)) {
+                ContextHolder.setDataSize(inquiries.size());
+                new StatusBasedHandler<Inquiry>("inquiryAuto", "in_id", "in_checkSendStatus", "/inquiry/public/checking?enuu=" + enterprise.getEn_uu(), inquiries).run();
+            }
+        }
+    }
+
+    /**
+     * ERP针对卖家报价信息的采纳状态传回平台
+     *
+     * @author hejq
+     * @date 2018-01-10 19:34
+     */
+    @TaskMapping(title = "上传买家对报价信息是否采纳的决策到公共服务", fixedDelay = 60000)
+    public void uploadInquiryDecide() {
+        Enterprise enterprise = getEnterprise();
+        if (null != enterprise) {
+            List<InquiryDecide> replies = jdbcTemplate.queryForBeanList("select id_id,in_code,id_detno,id_isagreed id_agreed from InquiryAutoDetail left join InquiryAuto on id_inid=in_id left join vendor on id_vendcode=ve_code where IN_SENDSTATUS='已上传' and nvl(in_class,' ')<>'主动报价' and ID_SENDSTATUS='待上传' and id_isagreed is not null and ve_uu is not null and nvl(ve_b2benable,0)=1 and rownum < 100 order by in_code,id_detno",
+                    InquiryDecide.class);
+            if (!CollectionUtils.isEmpty(replies)) {
+                ContextHolder.setDataSize(replies.size());
+                post("/inquiry/public/reply/decide?enuu=" + enterprise.getEn_uu(), dataWrap(replies));
+                String idStr = CollectionUtil.getKeyString(replies);
+                logger.info("上传采纳决策到平台,ids: " + idStr);
+                jdbcTemplate.execute("update InquiryAutoDetail set id_sendstatus='已下载' where id_id in (" + idStr + ")");
+            }
+        }
+    }
+
+    /**
+     * ERP单据作废信息传回平台进行操作
+     *
+     * @author hejq
+     * @date 2018-01-10 19:34
+     */
+    @TaskMapping(title = "上传买家对报价信息作废的决策到公共服务", fixedDelay = 60000)
+    public void uploadInquiryInvalid() {
+        Enterprise enterprise = getEnterprise();
+        if (null != enterprise) {
+            List<Inquiry> inquiries = jdbcTemplate.queryForBeanList("select * from InquiryAuto left join InquiryAutoDetail on id_inid=in_id left join vendor on id_vendcode=ve_code where in_status = '已作废' and in_sendStatus <> '作废已上传' and nvl(in_class,' ')<>'主动报价'  and ve_uu is not null and nvl(ve_b2benable,0)=1 and rownum <= 100 order by in_code",
+                    Inquiry.class);
+            if (!CollectionUtils.isEmpty(inquiries)) {
+                ContextHolder.setDataSize(inquiries.size());
+                post("/inquiry/public/invalid?enuu=" + enterprise.getEn_uu(), dataWrap(inquiries));
+                String idStr = CollectionUtil.getKeyString(inquiries);
+                logger.info("公共询价单作废单据,ids: " + idStr);
+                jdbcTemplate.execute("update InquiryAuto set in_sendStatus='作废已上传' where in_id in (" + idStr + ")");
+            }
+        }
+    }
+
+    /**
+     * 获取需要上传的询价单
+     *
+     * @return
+     */
+    private List<BatchInquiry> getInquiryUpload() {
+        List<BatchInquiry> inquiries = jdbcTemplate.queryForBeanList("select bi_id,bi_code,bi_date,bi_kind,bi_environment,bi_purpose,bi_pricekind,bi_recorder,bi_recorddate,bi_enddate,bi_remark,bi_pricetype,bi_recorduu,bi_attach from batchinquiry where bi_sendstatus = '待上传' and bi_status = '已审核' and bi_kind = '公开询价'",
+                BatchInquiry.class);
+        for (BatchInquiry inquiry : inquiries) {
+            // 获取询价单明细
+            List<BatchInProduct> details = jdbcTemplate.queryForBeanList("select batchinprod.*,em_name from batchinprod left join employee on batchinprod.bip_buyercode = employee.em_code where bip_biid = ?",
+                    BatchInProduct.class, inquiry.getBi_id());
+            inquiry.setInProducts(details);
+            // 附件
+            if (StringUtils.hasText(inquiry.getIn_attach())) {
+                inquiry.setAttaches(getAttachs(inquiry.getIn_attach().split(";")));
+            }
+        }
+        logger.info("inquiries: " + inquiries.size());
+        return inquiries;
+    }
+
+    /**
+     * 获取企业信息
+     *
+     * @return
+     */
+    public Enterprise getEnterprise() {
+        Enterprise enterprise = jdbcTemplate.queryForBean("select en_address, en_uu, en_name from enterprise where en_uu is not null", Enterprise.class);
+        logger.info("企业信息: " + JSON.toJSONString(enterprise));
+        return enterprise;
+    }
+}

+ 181 - 0
src/main/java/com/uas/erp/schedular/publicproduct/domain/Prod.java

@@ -0,0 +1,181 @@
+package com.uas.erp.schedular.publicproduct.domain;
+
+import com.uas.erp.schedular.b2b.domain.KeyEntity;
+
+/**
+ * ERP系统的产品
+ * 
+ * @author yingp
+ * 
+ */
+public class Prod extends KeyEntity{
+
+	private Long pr_id;
+	private String pr_code;
+	private String pr_detail;
+	private String pr_spec;
+	private String pr_unit;
+	private Float pr_zxbzs;
+	private Float pr_zxdhl;
+	private Float pr_leadtime;
+	private Float pr_ltinstock;//备料提前期,天数
+	private String pr_brand;
+	private String pr_orispeccode;// 原厂型号
+	private String pr_uuid; // 标准料号
+	private String pr_status; // 状态: ‘已审核’->有效;‘已禁用’->失效
+	private Short pr_issale; // 可销售
+	private Short pr_ispurchase; // 可采购
+	private Short pr_isshow; // 开放采购物料
+	private Short pr_ispubsale; // 开发销售物料
+	private Long b2b_id;//平台id
+
+	public Long getPr_id() {
+		return pr_id;
+	}
+
+	public void setPr_id(Long pr_id) {
+		this.pr_id = pr_id;
+	}
+
+	public String getPr_code() {
+		return pr_code;
+	}
+
+	public void setPr_code(String pr_code) {
+		this.pr_code = pr_code;
+	}
+
+	public String getPr_detail() {
+		return pr_detail;
+	}
+
+	public void setPr_detail(String pr_detail) {
+		this.pr_detail = pr_detail;
+	}
+
+	public String getPr_spec() {
+		return pr_spec;
+	}
+
+	public void setPr_spec(String pr_spec) {
+		this.pr_spec = pr_spec;
+	}
+
+	public String getPr_unit() {
+		return pr_unit;
+	}
+
+	public void setPr_unit(String pr_unit) {
+		this.pr_unit = pr_unit;
+	}
+
+	public Float getPr_zxbzs() {
+		return pr_zxbzs;
+	}
+
+	public void setPr_zxbzs(Float pr_zxbzs) {
+		this.pr_zxbzs = pr_zxbzs;
+	}
+
+	public Float getPr_zxdhl() {
+		return pr_zxdhl;
+	}
+
+	public void setPr_zxdhl(Float pr_zxdhl) {
+		this.pr_zxdhl = pr_zxdhl;
+	}
+
+	public Float getPr_leadtime() {
+		return pr_leadtime;
+	}
+
+	public void setPr_leadtime(Float pr_leadtime) {
+		this.pr_leadtime = pr_leadtime;
+	}
+
+	public Float getPr_ltinstock() {
+		return pr_ltinstock;
+	}
+
+	public void setPr_ltinstock(Float pr_ltinstock) {
+		this.pr_ltinstock = pr_ltinstock;
+	}
+
+	@Override
+	public Object getKey() {
+		return this.pr_id;
+	}
+
+	public String getPr_brand() {
+		return pr_brand;
+	}
+
+	public void setPr_brand(String pr_brand) {
+		this.pr_brand = pr_brand;
+	}
+
+	public String getPr_orispeccode() {
+		return pr_orispeccode;
+	}
+
+	public void setPr_orispeccode(String pr_orispeccode) {
+		this.pr_orispeccode = pr_orispeccode;
+	}
+
+	public String getPr_uuid() {
+		return pr_uuid;
+	}
+
+	public void setPr_uuid(String pr_uuid) {
+		this.pr_uuid = pr_uuid;
+	}
+
+	public String getPr_status() {
+		return pr_status;
+	}
+
+	public void setPr_status(String pr_status) {
+		this.pr_status = pr_status;
+	}
+
+	public Short getPr_issale() {
+		return pr_issale;
+	}
+
+	public void setPr_issale(Short pr_issale) {
+		this.pr_issale = pr_issale;
+	}
+
+	public Short getPr_ispurchase() {
+		return pr_ispurchase;
+	}
+
+	public void setPr_ispurchase(Short pr_ispurchase) {
+		this.pr_ispurchase = pr_ispurchase;
+	}
+
+	public Short getPr_isshow() {
+		return pr_isshow;
+	}
+
+	public void setPr_isshow(Short pr_isshow) {
+		this.pr_isshow = pr_isshow;
+	}
+
+	public Short getPr_ispubsale() {
+		return pr_ispubsale;
+	}
+
+	public void setPr_ispubsale(Short pr_ispubsale) {
+		this.pr_ispubsale = pr_ispubsale;
+	}
+
+	public Long getB2b_id() {
+		return b2b_id;
+	}
+
+	public void setB2b_id(Long b2b_id) {
+		this.b2b_id = b2b_id;
+	}
+
+}

+ 14 - 1
src/main/java/com/uas/erp/schedular/b2b/domain/ProductSaler.java → src/main/java/com/uas/erp/schedular/publicproduct/domain/ProductSaler.java

@@ -1,4 +1,6 @@
-package com.uas.erp.schedular.b2b.domain;
+package com.uas.erp.schedular.publicproduct.domain;
+
+import com.uas.erp.schedular.b2b.domain.KeyEntity;
 
 /**
  * ERP个人物料信息
@@ -21,6 +23,10 @@ public class ProductSaler extends KeyEntity {
      * 个人uu号
      */
     private Long em_uu;
+    /**
+     * 企业uu号
+     */
+    private Long en_uu;
 
     public Long getPs_id() {
         return ps_id;
@@ -46,6 +52,13 @@ public class ProductSaler extends KeyEntity {
         this.em_uu = em_uu;
     }
 
+    public Long getEn_uu() {
+        return en_uu;
+    }
+
+    public void setEn_uu(Long en_uu) {
+        this.en_uu = en_uu;
+    }
     /**
      * 主键值
      *

+ 327 - 0
src/main/java/com/uas/erp/schedular/publicproduct/task/AbstractTask.java

@@ -0,0 +1,327 @@
+package com.uas.erp.schedular.publicproduct.task;
+
+import com.alibaba.fastjson.JSON;
+import com.uas.erp.schedular.b2b.domain.KeyEntity;
+import com.uas.erp.schedular.core.Constant;
+import com.uas.erp.schedular.database.RestJdbcTemplate;
+import com.uas.erp.schedular.entity.Master;
+import com.uas.erp.schedular.publicproduct.domain.Prod;
+import com.uas.erp.schedular.publicinquiry.domain.Attach;
+import com.uas.erp.schedular.publicinquiry.domain.Enterprise;
+import com.uas.erp.schedular.service.SettingService;
+import com.uas.erp.schedular.util.CollectionUtil;
+import com.uas.erp.schedular.util.ContextHolder;
+import com.uas.erp.schedular.util.DateUtil;
+import com.uas.erp.schedular.util.HmacUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.util.StringUtils;
+import org.springframework.web.client.RestTemplate;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLEncoder;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 公共物料的轮询配置
+ * 
+ * @author hejq
+ * @date 2018-01-26 23:33
+ */
+public class AbstractTask {
+
+    // 数据传输单次大小限制
+    protected static final int DATA_SIZE_LIMIT = 500;
+
+    @Autowired
+    private RestTemplate restTemplate;
+
+    @Autowired
+    protected RestJdbcTemplate jdbcTemplate;
+
+    @Autowired
+    protected SettingService settingService;
+
+    protected Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    /**
+     * 按账套环境,使用不同接口地址
+     * @return
+     */
+    private String getApiDomain() {
+        String key = "test".equals(ContextHolder.getMaster().getMa_env()) ? "api.publicproduct.test.url" : "api.publicproduct.url";
+        return settingService.getValue(key);
+    }
+
+    /**
+     * UAS系统外网地址
+     * @return
+     */
+    private String getUASUrl() {
+        return settingService.getValue("api.uas.outer.url");
+    }
+
+    /**
+     * URI加身份签名
+     * @param url
+     * @param vars
+     * @return
+     */
+    private String getURI(String url, Object... vars) {
+        Master master = ContextHolder.getMaster();
+        if (null == master.getMa_uu() || StringUtils.isEmpty(master.getMa_accesssecret())) {
+            throw new RuntimeException("未设置企业UU和私钥");
+        }
+        StringBuffer accessUrl = new StringBuffer(url);
+        accessUrl.append(url.contains("?") ? "&" : "?");
+        // 身份ID
+        accessUrl.append("access_id=").append(master.getMa_uu());
+        // 时间戳
+        accessUrl.append("&_timestamp=").append(System.currentTimeMillis());
+        URI uri = restTemplate.getUriTemplateHandler().expand(getApiDomain() + accessUrl.toString(), vars);
+        url = uri.toString();
+        // 签名
+        return url + "&_signature=" + HmacUtils.encode(url, master.getMa_accesssecret());
+    }
+
+    protected <T> T getForObject(String url, Class<T> objectClass, Object... vars) {
+        return restTemplate.getForObject(getURI(url, vars), objectClass);
+    }
+
+    protected <T> List<T> getForList(String url, Class<T> objectClass, Object... vars) {
+        String resultStr = restTemplate.getForObject(getURI(url, vars), String.class);
+        return JSON.parseArray(resultStr, objectClass);
+    }
+
+    /**
+     * b2b当前版本的接口只支持以form-data方式提交,requestBody方式暂不支持
+     * @param url
+     * @param vars
+     */
+    protected void post(String url, MultiValueMap<String, String> vars) {
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(vars, headers);
+        restTemplate.postForLocation(getURI(url), request);
+    }
+
+    protected ResponseEntity postForEntity(String url, MultiValueMap<String, String> vars) {
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(vars, headers);
+        return restTemplate.postForEntity(getURI(url), request, String.class);
+    }
+
+    protected <T> List<T> postForList(String url, Class<T> objectClass, MultiValueMap<String, String> vars) {
+        ResponseEntity<String> resultEntity = postForEntity(url, vars);
+        return JSON.parseArray(resultEntity.getBody(), objectClass);
+    }
+
+    /**
+     * 封装成平台接口数据格式
+     * @param data
+     * @return
+     */
+    protected static MultiValueMap<String, String> dataWrap(Object data) {
+        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
+        String dataStr = null;
+        Class<?> cls = data.getClass();
+        if (cls.isAssignableFrom(String.class) || cls.isAssignableFrom(Number.class) ||
+                cls.isAssignableFrom(Character.class)) {
+            dataStr = data.toString();
+        } else {
+            dataStr = JSON.toJSONString(data);
+        }
+        try {
+            dataStr = URLEncoder.encode(dataStr, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+
+        }
+        map.set("data", dataStr);
+        return map;
+    }
+
+    /**
+     * 数据上传工具,封装了处理前、后置、错误处理方法
+     * @param <T>
+     */
+    protected abstract class AbstractHandler<T> {
+
+        private List<T> data;
+
+        public AbstractHandler(List<T> data) {
+            this.data = data;
+        }
+
+        /**
+         * onHandler方法前执行
+         */
+        protected void onBefore(){
+
+        }
+
+        protected abstract ResponseEntity onHandler(List<T> data);
+
+        /**
+         * onHandler方法执行成功后执行
+         */
+        protected void onSuccess(){
+
+        }
+
+        /**
+         * onHandler方法执行失败后执行
+         */
+        protected void onError(String message){
+            throw new RuntimeException(message);
+        }
+
+        /**
+         * 所有方法执行完成后执行
+         */
+        protected void onAfter(){
+
+        }
+
+        public void run() {
+            String errMsg = null;
+            onBefore();
+            try {
+                ResponseEntity response = onHandler(data);
+                if (!response.getStatusCode().is2xxSuccessful()) {
+                    errMsg = String.valueOf(response.getBody());
+                }
+            } catch (Exception e) {
+                errMsg = e.getMessage();
+            }
+            try {
+                if (null == errMsg) {
+                    onSuccess();
+                } else {
+                    onError(errMsg);
+                }
+            } finally {
+                onAfter();
+            }
+        }
+    }
+
+    /**
+     * POST方式处理工具
+     * @param <T>
+     */
+    protected class AbstractPostHandler<T> extends AbstractHandler<T> {
+        private String postUri;
+
+        public AbstractPostHandler(String postUri, List<T> data) {
+            super(data);
+            this.postUri = postUri;
+        }
+
+        @Override
+        protected ResponseEntity onHandler(List<T> data) {
+            return postForEntity(postUri, dataWrap(data));
+        }
+    }
+
+    /**
+     * 基于状态控制的处理工具
+     * @param <T>
+     */
+    protected abstract class AbstractStatusBasedHandler<T extends KeyEntity> extends AbstractPostHandler<T> {
+
+        private String idStr;
+        private String tableName;
+        private String idColumn;
+        private String statusColumn;
+
+        public AbstractStatusBasedHandler(String tableName, String idColumn, String statusColumn, String postUri, List<T> data) {
+            super(postUri, data);
+            this.idStr = CollectionUtil.getKeyString(data);
+            this.tableName = tableName;
+            this.idColumn = idColumn;
+            this.statusColumn = statusColumn;
+        }
+
+        @Override
+        protected void onBefore() {
+            jdbcTemplate.execute(String.format("update %s set %s='上传中' where %s in (%s)", tableName, statusColumn, idColumn, idStr));
+        }
+
+        @Override
+        protected void onSuccess() {
+            jdbcTemplate.execute(String.format("update %s set %s='已上传' where %s in (%s)", tableName, statusColumn, idColumn, idStr));
+        }
+
+        @Override
+        protected void onError(String message) {
+            jdbcTemplate.execute(String.format("update %s set %s='待上传' where %s in (%s) and %s='上传中'", tableName, statusColumn, idColumn, idStr, statusColumn));
+            super.onError(message);
+        }
+    }
+
+    /**
+     * 基于状态控制的处理工具
+     * @param <T>
+     */
+    protected class StatusBasedHandler<T extends KeyEntity> extends AbstractStatusBasedHandler<T> {
+
+        public StatusBasedHandler(String tableName, String idColumn, String statusColumn, String postUri, List<T> data) {
+            super(tableName, idColumn, statusColumn, postUri, data);
+        }
+    }
+
+    /**
+     * 处理物料上传的工具
+     */
+    protected final class ProductHandler extends StatusBasedHandler<Prod>{
+
+        public ProductHandler(List<Prod> data, Enterprise enterprise) {
+            super("product", "pr_id", "PR_SENDSTATUS", "/product/erp/save?enUU=" + enterprise.getEn_uu(), data);
+        }
+    }
+
+    /**
+     * 查找附件
+     * @param attachIds 附件ID
+     * @return
+     */
+    protected List<Attach> getAttachs(String[] attachIds) {
+        String erpUrl = getUASUrl();
+        List<Attach> attaches = jdbcTemplate.queryForBeanList("select fp_id, fp_size, fp_name from filepath where fp_id in ("
+                + StringUtils.arrayToDelimitedString(attachIds, ",") + ")", Attach.class);
+        if (!CollectionUtils.isEmpty(attaches)) {
+            for (Attach attach : attaches) {
+                attach.setFp_url(erpUrl + Attach.DOWN_FILE_ACTION + attach.getFp_id());
+            }
+        }
+        return attaches;
+    }
+
+    /**
+     * 创建消息
+     *
+     * @param caller
+     * @param sourceIds
+     * @param type
+     */
+    protected void createMessage(String caller, String sourceIds, String type) {
+        Integer mid = jdbcTemplate.getInt("select max(mm_id) from MESSAGEMODEL left join MESSAGEROLE on mm_id=mr_mmid where MR_ISUSED=-1 AND MM_ISUSED=-1 and mm_caller=? and MM_OPERATE='b2b' AND MM_ACTION=?",
+                caller, type);
+        if (null != mid) {
+            jdbcTemplate.callForString("{call SP_CREATEINFO(?,'ADMIN',?,?,?)}",
+                    mid, sourceIds, DateUtil.parseDateToOracleString(Constant.YMD_HMS, new Date()));
+        }
+    }
+
+}

+ 100 - 0
src/main/java/com/uas/erp/schedular/publicproduct/task/ProdTask.java

@@ -0,0 +1,100 @@
+package com.uas.erp.schedular.publicproduct.task;
+
+import com.uas.erp.schedular.publicproduct.domain.Prod;
+import com.uas.erp.schedular.publicinquiry.domain.Enterprise;
+import com.uas.erp.schedular.task.support.Method;
+import com.uas.erp.schedular.task.support.TaskMapping;
+import com.uas.erp.schedular.util.CollectionUtil;
+import com.uas.erp.schedular.util.ContextHolder;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 公共服务物料上传
+ *
+ * @author hejq
+ * @date 2018-01-19 10:53
+ */
+@Component
+@TaskMapping(title = "公共物料")
+public class ProdTask extends AbstractTask {
+
+    /**
+     * 默认8到21点间每小时执行一次
+     */
+    @TaskMapping(title = "上传物料到公共服务", fixedDelay = 60000)
+    public void uploadProduct() {
+        Enterprise enterprise = getEnterprise();
+        if (null != enterprise) {
+            List<Prod> prods = jdbcTemplate.queryForBeanList("select * from (select pr_id,pr_code,pr_detail,pr_spec,pr_unit,pr_zxbzs,pr_zxdhl,pr_leadtime,pr_ltinstock,pr_brand,pr_issale,pr_ispurchase,pr_isshow,pr_ispubsale,pr_uuid,pr_orispeccode from product where  nvl(pr_sendstatus,' ')<>'已上传' and  nvl(pr_status, ' ') = '已审核' order by pr_id) where rownum <= 500",
+                    Prod.class);
+            logger.info("上传物料: " + prods.size());
+            if (!CollectionUtils.isEmpty(prods)) {
+                ContextHolder.increaseDataSize(prods.size());
+                new StatusBasedHandler<Prod>("product", "pr_id", "PR_SENDSTATUS", "/product/cycleupdate?enUU=" + enterprise.getEn_uu(), prods).run();
+                if (prods.size() == DATA_SIZE_LIMIT) {
+                    // 递归,直到没有需要上传的数据
+                    uploadProduct();
+                }
+            }
+        }
+    }
+
+    /**
+     * 默认8到21点间每小时第15分钟执行一次
+     */
+    @TaskMapping(title = "从公共服务下载更新物料信息", cron = "0 15 8-21 * * *", method = Method.DOWNLOAD)
+    public void downloadProduct() {
+        Enterprise enterprise = getEnterprise();
+        if (null != enterprise) {
+            List<Prod> prods = getForList("/product/backtouas", Prod.class);
+            if (!CollectionUtils.isEmpty(prods)) {
+                ContextHolder.setDataSize(prods.size());
+                saveProdDown(prods);
+                // 回执
+                downloadSuccess(prods);
+            }
+        }
+    }
+
+    /**
+     * 保存更新物料信息
+     *
+     * @param prods
+     */
+    private void saveProdDown(List<Prod> prods) {
+        List<String> sqls = new ArrayList<>();
+        for (Prod prod : prods) {
+            String sql = "update product set pr_uuid = '" + prod.getPr_uuid() + "' where pr_id = " + prod.getPr_id();
+            sqls.add(sql);
+        }
+        jdbcTemplate.batchExecute(sqls);
+    }
+
+    /**
+     * 更新平台的下载状态为已下载
+     * @param prods
+     */
+    private void downloadSuccess(List<Prod> prods) {
+        String idStr = CollectionUtil.getKeyString(prods, new CollectionUtil.KeyIterator<Prod>() {
+            @Override
+            public Object getKey(Prod obj) {
+                return obj.getB2b_id();
+            }
+        });
+        post("/product/refreshDownloadstatus", dataWrap(idStr));
+    }
+
+    /**
+     * 获取企业信息
+     *
+     * @return
+     */
+    public Enterprise getEnterprise() {
+        Enterprise enterprise = jdbcTemplate.queryForBean("select en_address, en_uu, en_name from enterprise where en_uu is not null", Enterprise.class);
+        return enterprise;
+    }
+}

+ 53 - 0
src/main/java/com/uas/erp/schedular/publicproduct/task/ProdUserTask.java

@@ -0,0 +1,53 @@
+package com.uas.erp.schedular.publicproduct.task;
+
+import com.uas.erp.schedular.publicproduct.domain.ProductSaler;
+import com.uas.erp.schedular.task.support.Method;
+import com.uas.erp.schedular.task.support.Role;
+import com.uas.erp.schedular.task.support.TaskMapping;
+import com.uas.erp.schedular.util.ContextHolder;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * 个人物料信息同步接口
+ *
+ * Created by hejq on 2018-01-12.
+ */
+@Component
+@TaskMapping(title = "个人物料信息", role = Role.PLAIN)
+public class ProdUserTask extends AbstractTask {
+
+    /**
+     * 同步ERP的个人物料信息到公共服务
+     *
+     * @author hejq
+     * @date 2018-01-12 19:05
+     */
+    @TaskMapping(title = "同步ERP的个人物料信息到公共服务", fixedDelay = 60000, method = Method.UPLOAD)
+    public void uploadProductSaler() {
+        List<ProductSaler> prods = jdbcTemplate.queryForBeanList("select ps_id,ps_prcode ps_code,nvl(em_uu,0) em_uu,nvl((select en_uu from enterprise ),0) en_uu  from productSaler, employee, product where em_code = ps_emcode and nvl(em_uu, 0)<>0 and pr_code = ps_prcode and nvl(pr_sendstatus, ' ') = '已上传' and nvl(pr_status, ' ') = '已审核' and nvl(ps_emstatus,' ') = '是' and nvl(ps_uploadstatus, ' ') <> '已上传' and rownum <= 200",
+                ProductSaler.class);
+        if (!CollectionUtils.isEmpty(prods)) {
+            ContextHolder.increaseDataSize(prods.size());
+            new StatusBasedHandler<ProductSaler>("productsaler", "ps_id", "ps_uploadstatus", "/product/produser", prods).run();
+        }
+    }
+    /**
+     * 同步ERP的个人物料信息到公共服务(取消关联)
+     *
+     * @author wuyx
+     * @date 2018-01-30 08:16
+     */
+    @TaskMapping(title = "同步取消公共服务ERP的个人物料信息", fixedDelay = 60000, method = Method.UPLOAD)
+    public void uploadProductSalerQuit() {
+        List<ProductSaler> prods = jdbcTemplate.queryForBeanList("select ps_id,ps_prcode ps_code,nvl(em_uu,0) em_uu,nvl((select en_uu from enterprise ),0) en_uu from productSaler, employee, product where em_code = ps_emcode and nvl(em_uu, 0)<>0 and pr_code = ps_prcode and nvl(pr_sendstatus, ' ') = '已上传' and nvl(pr_status, ' ') = '已审核' and nvl(ps_emstatus,' ') = '否' and nvl(ps_uploadstatus, ' ') <> '已上传' and rownum <= 200",
+                ProductSaler.class);
+        if (!CollectionUtils.isEmpty(prods)) {
+            ContextHolder.increaseDataSize(prods.size());
+            new StatusBasedHandler<ProductSaler>("productsaler", "ps_id", "ps_uploadstatus", "/product/produser/quit", prods).run();
+        }
+    }
+
+}

+ 82 - 82
src/main/resources/database/template/deputyOrder.xml

@@ -14,99 +14,99 @@
         <iterator loop="orders" var="order">
             <block>
                 begin
-                select * into v_customer from customer where cu_uu=${order.enuu};
-                exception when no_data_found then
-                RAISE_APPLICATION_ERROR(-20010, '客户['||${order.enuu}||']不存在');
+                    select * into v_customer from customer where cu_uu=${order.enuu};
+                    exception when no_data_found then
+                    RAISE_APPLICATION_ERROR(-20010, '客户['||${order.enuu}||']不存在');
                 end;
                 begin
-                select * into v_employee from employee where em_code=v_customer.cu_sellercode;
-                exception when no_data_found then null;
+                    select * into v_employee from employee where em_code=v_customer.cu_sellercode;
+                    exception when no_data_found then null;
                 end;
                 begin
-                v_vecode := '';
-                select count(1) into v_ve_count from vendor where ve_name=${order.tervendor};
-                if v_ve_count > 0 then
-                    select * into v_vendor from vendor where ve_name=${order.tervendor};
-                    v_vecode := v_vendor.ve_code;
-                end if;
+                    v_vecode := '';
+                    select count(1) into v_ve_count from vendor where ve_name=${order.tervendor};
+                    if v_ve_count > 0 then
+                        select * into v_vendor from vendor where ve_name=${order.tervendor};
+                        v_vecode := v_vendor.ve_code;
+                    end if;
                 end;
                 begin
-                select * into v_sale from sale where sa_code=${order.salecode};
-                exception when no_data_found then null;
+                    select * into v_sale from sale where sa_code=${order.salecode};
+                    exception when no_data_found then v_sale.sa_id := '';
                 end;
                 if v_sale.sa_id is null or ${order.statuscode} = 222 then
-                if v_sale.sa_id is null then
-                v_sale.sa_id := sale_seq.nextval;
-                v_sale.sa_backstatus := '';
-                else
-                delete from saledetail where sd_said=v_sale.sa_id;
-                delete from sale where sa_id=v_sale.sa_id;
-                v_sale.sa_backstatus := '已下载';
-                end if;
-                v_sale.sa_code := ${order.salecode};
-                v_sale.sa_pocode := ${order.salepocode};
-                v_sale.sa_date := ${order.entrydate};
-                v_sale.sa_kind := '代采订单';
-                v_sale.sa_custcode := v_customer.cu_code;
-                v_sale.sa_custname := v_customer.cu_name;
-                v_sale.sa_currency := ${order.currency};
-                v_sale.sa_apcustcode := v_customer.cu_code;
-                v_sale.sa_apcustname := v_customer.cu_name;
-                v_sale.sa_shcustcode := v_customer.cu_code;
-                v_sale.sa_shcustname := v_customer.cu_name;
-                v_sale.sa_paymentscode := v_customer.cu_paymentscode;
-                v_sale.sa_payments := v_customer.cu_payments;
-                v_sale.sa_toplace := v_customer.cu_add1;
-                v_sale.sa_fromcode := ${order.code};
-                v_sale.sa_sellercode := v_customer.cu_sellercode;
-                v_sale.sa_departmentcode := v_employee.em_departmentcode;
-                v_sale.sa_departmentname := v_employee.em_depart;
-                v_sale.sa_recorder := '系统';
-                v_sale.sa_recorddate := sysdate;
-                v_sale.sa_statuscode := 'ENTERING';
-                v_sale.sa_status := '在录入';
-                v_sale.sa_vendcode := v_vecode;
-                v_sale.sa_vendname := ${order.tervendor};
-                v_sale.sa_a20_user := ${order.madealdate};
-                v_sale.sa_a19_user := ${order.madealcode};
-                v_sale.sa_a18_user := ${order.vendtel};
-                v_sale.sa_a17_user := ${order.venduser};
-                v_sale.sa_a14_user := ${order.shipdate};
-                v_sale.sa_a16_user := ${order.deliverymethod};
-                v_sale.sa_a15_user := ${order.pickupmethod};
-                v_sale.sa_a11_user := ${order.tervendaddress};
-                v_sale.sa_a9_user := ${order.companyname};
-                v_sale.sa_a10_user := ${order.requirepaydate};
-                v_sale.sa_a8_user := ${order.bankname};
-                v_sale.sa_a6_user := ${order.bankaccount};
-                v_sale.sa_a7_user := ${order.bankaddress};
-                v_sale.sa_a5_user := ${order.bankcode};
-                v_sale.sa_a4_user := ${order.otherdata};
-                v_sale.sa_a3_user := ${order.legalrepresent};
-                v_sale.sa_a24_user := ${order.deliverydate};
-                v_sale.sa_a22_user := ${order.paydate};
-                v_sale.sa_payername := ${order.paycomname};
-                v_sale.sa_payeraddress := ${order.paycomaddress};
-                v_sale.sa_a13_user := ${order.riskmethod};
-                v_sale.sa_a12_user := ${order.taxpaymentmethod};
-                v_sale.sa_a2_user := ${order.enfax};
-                v_sale.sa_a25_user := ${order.paycomaddress};
-                v_sale.sa_a10_user_2 := ${order.actualpaydate};
-                insert into sale values v_sale;
+                    if v_sale.sa_id is null then
+                        v_sale.sa_id := sale_seq.nextval;
+                        v_sale.sa_backstatus := '';
+                    else
+                        delete from saledetail where sd_said=v_sale.sa_id;
+                        delete from sale where sa_id=v_sale.sa_id;
+                        v_sale.sa_backstatus := '已下载';
+                    end if;
+                    v_sale.sa_code := ${order.salecode};
+                    v_sale.sa_pocode := ${order.salepocode};
+                    v_sale.sa_date := ${order.entrydate};
+                    v_sale.sa_kind := '代采订单';
+                    v_sale.sa_custcode := v_customer.cu_code;
+                    v_sale.sa_custname := v_customer.cu_name;
+                    v_sale.sa_currency := ${order.currency};
+                    v_sale.sa_apcustcode := v_customer.cu_code;
+                    v_sale.sa_apcustname := v_customer.cu_name;
+                    v_sale.sa_shcustcode := v_customer.cu_code;
+                    v_sale.sa_shcustname := v_customer.cu_name;
+                    v_sale.sa_paymentscode := v_customer.cu_paymentscode;
+                    v_sale.sa_payments := v_customer.cu_payments;
+                    v_sale.sa_toplace := v_customer.cu_add1;
+                    v_sale.sa_fromcode := ${order.code};
+                    v_sale.sa_sellercode := v_customer.cu_sellercode;
+                    v_sale.sa_departmentcode := v_employee.em_departmentcode;
+                    v_sale.sa_departmentname := v_employee.em_depart;
+                    v_sale.sa_recorder := '系统';
+                    v_sale.sa_recorddate := sysdate;
+                    v_sale.sa_statuscode := 'ENTERING';
+                    v_sale.sa_status := '在录入';
+                    v_sale.sa_vendcode := v_vecode;
+                    v_sale.sa_vendname := ${order.tervendor};
+                    v_sale.sa_a20_user := ${order.madealdate};
+                    v_sale.sa_a19_user := ${order.madealcode};
+                    v_sale.sa_a18_user := ${order.vendtel};
+                    v_sale.sa_a17_user := ${order.venduser};
+                    v_sale.sa_a14_user := ${order.shipdate};
+                    v_sale.sa_a16_user := ${order.deliverymethod};
+                    v_sale.sa_a15_user := ${order.pickupmethod};
+                    v_sale.sa_a11_user := ${order.tervendaddress};
+                    v_sale.sa_a9_user := ${order.companyname};
+                    v_sale.sa_a10_user := ${order.requirepaydate};
+                    v_sale.sa_a8_user := ${order.bankname};
+                    v_sale.sa_a6_user := ${order.bankaccount};
+                    v_sale.sa_a7_user := ${order.bankaddress};
+                    v_sale.sa_a5_user := ${order.bankcode};
+                    v_sale.sa_a4_user := ${order.otherdata};
+                    v_sale.sa_a3_user := ${order.legalrepresent};
+                    v_sale.sa_a24_user := ${order.deliverydate};
+                    v_sale.sa_a22_user := ${order.paydate};
+                    v_sale.sa_payername := ${order.paycomname};
+                    v_sale.sa_payeraddress := ${order.paycomaddress};
+                    v_sale.sa_a13_user := ${order.riskmethod};
+                    v_sale.sa_a12_user := ${order.taxpaymentmethod};
+                    v_sale.sa_a2_user := ${order.enfax};
+                    v_sale.sa_a25_user := ${order.paycomaddress};
+                    v_sale.sa_a10_user_2 := ${order.actualpaydate};
+                    insert into sale values v_sale;
             </block>
-            <iterator loop="order.deputyOrderItems" var="item">
-                v_sd_id := saledetail_seq.nextval;
-                v_pr_code := 'PROD'||to_char(sysdate,'yymmdd')||v_sd_id;
+                <iterator loop="order.deputyOrderItems" var="item">
+                    v_sd_id := saledetail_seq.nextval;
+                    v_pr_code := 'PROD'||to_char(sysdate,'yymmdd')||v_sd_id;
 
-                insert into product (pr_id, pr_detail, pr_spec, pr_speccs, pr_unit, pr_recordman, pr_docdate, pr_status, pr_statuscode, pr_remark,
-                pr_code, pr_orispeccode, pr_brand) values (product_seq.nextval, ${item.prodname},
-                ${item.prodcode}, ${item.prodspec}, 'PCS', '系统', sysdate, '已审核', 'AUDITED',
-                v_sale.sa_code||'平台代采订单产生', v_pr_code, ${item.prodcode}, ${item.prodbrand});
+                    insert into product (pr_id, pr_detail, pr_spec, pr_speccs, pr_unit, pr_recordman, pr_docdate, pr_status, pr_statuscode, pr_remark,
+                    pr_code, pr_orispeccode, pr_brand) values (product_seq.nextval, ${item.prodname},
+                    ${item.prodcode}, ${item.prodspec}, 'PCS', '系统', sysdate, '已审核', 'AUDITED',
+                    v_sale.sa_code||'平台代采订单产生', v_pr_code, ${item.prodcode}, ${item.prodbrand});
 
-                insert into saledetail (sd_id, sd_said, sd_detno, sd_code, sd_prodcode, sd_qty, sd_price, sd_total,sd_remark,
-                sd_delivery, SD_COSTINGPRICE) values (v_sd_id, v_sale.sa_id, ${item.detno}, v_sale.sa_code, v_pr_code, ${item.amount},
-                ${item.unitprice}, ${item.totalprice}, ${item.remark}, ${order.deliverydate}, ${item.purcprice});
-            </iterator>
+                    insert into saledetail (sd_id, sd_said, sd_detno, sd_code, sd_prodcode, sd_qty, sd_price, sd_total,sd_remark,
+                    sd_delivery, SD_COSTINGPRICE) values (v_sd_id, v_sale.sa_id, ${item.detno}, v_sale.sa_code, v_pr_code, ${item.amount},
+                    ${item.unitprice}, ${item.totalprice}, ${item.remark}, ${order.deliverydate}, ${item.purcprice});
+                </iterator>
             <block>
                 end if;
             </block>

+ 14 - 27
src/main/resources/database/template/pubInquiryReply.xml

@@ -1,45 +1,32 @@
 <?xml version="1.0" encoding="utf-8"?>
 <PLSQL>
     <declare>
-        v_in_id number;
         v_id_id number;
         v_id_detno number;
+        v_qu_count number;
     </declare>
     <body>
         <iterator loop="inquiryDetails" var="detail">
             <block>
-                -- 询价单
-                select max(in_id) into v_in_id from inquiryauto where in_code=${detail.in_code};
-                if v_in_id is null then
-                v_in_id := inquiryauto_seq.nextval;
-                insert into inquiryauto(in_id,in_code,in_date,in_recorddate,in_class,in_enddate,in_kind,in_recorder,in_prodtype,
-                in_pricetype,in_attach,in_cop,in_environment,in_purpose,in_source,in_sendstatus,in_status,in_statuscode)
-                select v_in_id,bi_code,bi_date,bi_recorddate,'公共询价',bi_enddate,bi_pricekind,bi_recorder,bi_kind,bi_pricetype,bi_attach,
-                bi_cop,bi_environment,bi_purpose,'公开询价单','已上传','已审核','AUDITED' from batchinquiry where bi_code=${detail.in_code};
-                end if;
                 -- 明细
-                select max(id_id) into v_id_id from inquiryautodetail where id_inid=v_in_id and id_vendyyzzh=${detail.id_vendyyzzh}
-                and id_prodcode=${detail.id_prodcode};
-                if v_id_id is null then
-                v_id_id := inquiryautodetail_seq.nextval;
-                select nvl(max(id_detno),0) + 1 into v_id_detno from inquiryautodetail where id_inid = v_in_id;
-                insert into inquiryautodetail(id_id,id_inid,id_detno,id_prodid,id_prodcode,id_vendname,id_vendyyzzh,id_currency,id_venduu,id_ptid)
-                select v_id_id,v_in_id,v_id_detno,pr_id,pr_code,${detail.id_vendname},${detail.id_vendyyzzh},${detail.id_currency},
-                ${detail.ve_uu},${detail.b2b_id_id} from product where pr_code=${detail.id_prodcode};
+                -- 判断报价信息是否已存在,公共询价不存在修改报价的情况,不做判断
+                select count(1) into v_qu_count from inquiryAutoDetail where id_incode = ${detail.in_code}
+                    and id_vendyyzzh = ${detail.id_vendyyzzh} and id_prodcode=${detail.id_prodcode};
+                if v_qu_count = 0 then
+                    v_id_id := inquiryAutoDetail_seq.nextval;
+                    -- 序号按返回先后顺序插入
+                    select nvl(max(id_detno), 1) into v_id_detno from inquiryAutoDetail where id_incode = ${detail.in_code};
+                    insert into inquiryAutoDetail(id_id,id_inid,id_detno,id_prodid,id_prodcode,id_vendname,id_vendyyzzh,id_currency,id_venduu,id_ptid,id_incode,id_leadtime,id_minbuyqty,id_minqty,id_rate)
+                    select v_id_id,0,v_id_detno,pr_id,pr_code,${detail.id_vendname},${detail.id_vendyyzzh},${detail.id_currency},
+                    ${detail.ve_uu},${detail.b2b_id_id},${detail.in_code},${detail.id_leadtime},${detail.id_minbuyqty},${detail.id_minqty},${detail.id_rate} from product where pr_code=${detail.id_prodcode};
                 end if;
-                update inquiryautodetail set id_fromdate=nvl(${detail.id_fromdate}, id_myfromdate),
-                id_todate=nvl(${detail.id_todate}, id_mytodate),id_minbuyqty=${detail.id_minbuyqty},id_minqty=${detail.id_minqty},
-                id_brand=${detail.id_brand},id_vendorprodcode=${detail.id_vendorprodcode},id_leadtime=nvl(${detail.id_leadtime},0),
-                id_vendname=${detail.id_vendname},id_vendyyzzh=${detail.id_vendyyzzh},id_rate=nvl(${detail.id_rate},id_rate),
-                id_ptid=${detail.b2b_id_id} where id_id=v_id_id;
-                -- 分段价格
-                delete from inquiryautodetaildet where idd_idid=v_id_id;
             </block>
             <iterator loop="detail.dets" var="det">
-                insert into inquiryautodetaildet(idd_id,idd_idid,idd_lapqty,idd_price) values (inquiryautodetaildet_SEQ.nextval,v_id_id,
+                -- 分段价格
+                insert into inquiryAutoDetailDet(idd_id,idd_idid,idd_lapqty,idd_price) values (inquiryAutoDetailDet_SEQ.nextval,v_id_id,
                 ${det.idd_lapqty},${det.idd_price});
                 if ${det.idd_lapqty} is null or ${det.idd_lapqty} = 0 then
-                update inquiryautodetail set id_status='已报价',id_lapqty=0,id_price=${det.idd_price} where id_id=v_id_id;
+                    update inquiryAutoDetail set id_status='已报价',id_lapqty=0,id_price=${det.idd_price} where id_id=v_id_id;
                 end if;
             </iterator>
         </iterator>

+ 16 - 0
src/main/resources/init/setting.json

@@ -40,4 +40,20 @@
   "key": "api.diymall.url",
   "description": "定制商城正式接口地址",
   "value": "http://10.10.100.23:20215"
+},{
+  "key": "api.publicinquiry.test.url",
+  "description": "公共询价测试地址",
+  "value": "http://192.168.253.12:24000/"
+},{
+  "key": "api.publicinquiry.url",
+  "description": "公共询价正式地址",
+  "value": "https://api-inquiry.usoftmall.com/"
+},{
+  "key": "api.publicproduct.test.url",
+  "description": "公共物料测试地址",
+  "value": "http://192.168.253.12:24000/"
+},{
+  "key": "api.publicproduct.url",
+  "description": "公共物料正式地址",
+  "value": "https://api-product.usoftmall.com/"
 }]