package kingdee
|
|
import (
|
"bytes"
|
"encoding/json"
|
"fmt"
|
"io/ioutil"
|
"mime/multipart"
|
"net/http"
|
"strconv"
|
"time"
|
|
"kingdee-dbapi/config"
|
"kingdee-dbapi/logger"
|
"kingdee-dbapi/nsqclient"
|
)
|
|
var JoHeadTemplate = `
|
{
|
"fdate": "%s", //日期 当天日期
|
"ftype": 1054, //固定值
|
"forderinterid": 0, //固定值
|
"fpporderinterid": 0, //固定值
|
"fparentinterid": 0, //固定值
|
"fsupplyid": 0, //固定值
|
"fplanconfirmed": 0, //计划确认
|
"fplanmode": 14036, //计划模式
|
"fworktypeid": 55, //生产类型
|
"fmrp": 1052, //单据来源
|
"fbomcategory": 36820, //BOM 类别
|
"fcardclosed": 1059, //流转卡关联关闭
|
"fprintcount": 0, //打印次数
|
"ffinclosed": 0, //财务结算标志
|
"ffinclosedate": "", //财务结算日期
|
"ffincloseer": 0, //财务结算人
|
"fmtono": " ", //计划跟踪号:
|
"fauxqtyforitem": 0, //因料报废数量
|
"funitid": 0, //单位 接口自动获取, 设置成0就可以
|
"fcostobjid": 0, //成本对象 , 接口自动获取, 设置成0就可以
|
"fbominterid": 0, //BOM编号 接口自动获取, 设置成0就可以
|
"fbillerid": 16394, //与制单人一致
|
"fplancategory": 2, //计划类别
|
"fcheckdate": "%s", //制单日期
|
"fstartdate": "%s", //开工日期
|
"ffinishdate": "%s", //完工日期
|
"fplancommitdate": "%s", //计划开工日期
|
"fplanfinishdate": "%s", //计划完工日期
|
"fitemid": "%s->", //物料编码 *
|
"fworkshop": "%s->", //生产车间编号
|
"fauxqty": %d, //计划生产数量
|
"fauxinhighlimitqty": %d, //完工入库上限
|
"fauxinlowlimitqty": %d, //完工入库下限
|
"finhighlimit": 0, //完工入库超收比例
|
"finlowlimit": 0 //完工入库欠收比例
|
}
|
`
|
|
type CSTNsqQuery struct {
|
FBillNo string `json:"FBillNo"` // 订单编号
|
FNumber string `json:"FNumber"` // 物料代码
|
FSource string `json:"FSource"` // 生产车间代码
|
FStartDate string `json:"FStartDate"` // 开工日期
|
FFinishDate string `json:"FFinishDate"` // 完工日期
|
UseAmount float64 `json:"UseAmount"` // 使用数量
|
}
|
|
type CSTNsqReply struct {
|
FBillNo string `json:"FBillNo"` // 订单编号
|
FNumber string `json:"FNumber"` // 物料代码
|
ICMONo string `json:"ICMONo"` // 金蝶系统的生产任务单编号
|
Code int `json:"code"` // CST接口返回的code, 成功200
|
Message string `json:"message"` // 失败的错误信息
|
}
|
|
type CSTServiceResponse struct {
|
ErrCode int `json:"errcode"`
|
ErrMsg string `json:"errmsg"`
|
Data struct {
|
FBillNo string `json:"fbillno"`
|
FBillId string `json:"fbillid"`
|
FTranType string `json:"ftrantype"`
|
FClassTypeId int `json:"fclasstypeid"`
|
} `json:"data"`
|
}
|
|
func CSTQueryHandle(msg []byte) error {
|
var query []CSTNsqQuery
|
var reply []CSTNsqReply
|
|
if err := json.Unmarshal(msg, &query); err != nil {
|
logger.Warn("解析请求失败, %s", err.Error())
|
return err
|
}
|
logger.Debug("接收到创建生产任务单请求, 共%d条订单", len(query))
|
|
for _, q := range query {
|
ret := Commit2CSTService(q)
|
reply = append(reply, ret)
|
}
|
|
replyData, _ := json.Marshal(reply)
|
ok := nsqclient.Produce(config.Options.CSTReplyTopic, replyData)
|
logger.Warn("应答查询请求结果:%t, key:%s", ok, replyData)
|
|
return nil
|
}
|
|
func Commit2CSTService(order CSTNsqQuery) (result CSTNsqReply) {
|
result.Code = -1
|
result.FBillNo = order.FBillNo
|
result.FNumber = order.FNumber
|
|
if result.FBillNo == "" || result.FNumber == "" {
|
result.Message = "订单编号或物料编号不能为空"
|
return
|
}
|
|
today := time.Now().Format("2006-01-02")
|
joHead := fmt.Sprintf(JoHeadTemplate,
|
today, // 日期
|
today, // 制单日期
|
order.FStartDate, // 开工日期
|
order.FFinishDate, // 完工日期
|
order.FStartDate, // 计划开工日期
|
order.FFinishDate, // 计划完工日期
|
order.FNumber, // 物料编码
|
order.FSource, // 生产车间编码
|
int(order.UseAmount), // 生产数量
|
int(order.UseAmount), // 完工入库上限
|
int(order.UseAmount), // 完工入库下限
|
)
|
//fmt.Println(joHead)
|
params := map[string]string{
|
"action": "生产任务单.新增",
|
"fuserid": "16394",
|
"jo_head": joHead,
|
"ja_body": "[{}]",
|
}
|
|
request, err := newMultipartRequest(config.Options.CSTWebApi, params)
|
if err != nil {
|
result.Message = err.Error()
|
return
|
}
|
|
client := &http.Client{}
|
resp, err := client.Do(request)
|
if err != nil {
|
result.Message = err.Error()
|
return
|
}
|
|
defer resp.Body.Close()
|
|
body, err := ioutil.ReadAll(resp.Body)
|
if err != nil {
|
result.Message = err.Error()
|
return
|
}
|
|
var rspMsg CSTServiceResponse
|
err = json.Unmarshal(body, &rspMsg)
|
if err != nil {
|
result.Message = err.Error()
|
return
|
}
|
|
if rspMsg.ErrCode == 0 {
|
result.Code = 200
|
result.ICMONo = rspMsg.Data.FBillNo
|
} else {
|
result.Code = rspMsg.ErrCode
|
result.Message = rspMsg.ErrMsg
|
}
|
|
return
|
}
|
|
func newMultipartRequest(url string, params map[string]string) (*http.Request, error) {
|
body := &bytes.Buffer{}
|
writer := multipart.NewWriter(body)
|
|
// 设置Boundary, 接口验证了六个-
|
if err := writer.SetBoundary("------basicHttpClient" + strconv.Itoa(int(time.Now().Unix()))); err != nil {
|
fmt.Println(err.Error())
|
}
|
|
for key, val := range params {
|
_ = writer.WriteField(key, val)
|
}
|
|
writer.Close()
|
|
req, err := http.NewRequest("POST", url, body)
|
if err != nil {
|
return nil, err
|
}
|
|
req.Header.Set("Content-Type", writer.FormDataContentType())
|
req.Header.Set("User-Agent", "basicHttpClient/0.0.1")
|
req.Header.Set("Connection", "keep-alive")
|
req.Header.Set("Accept", "*/*")
|
|
return req, err
|
}
|