SyncService.java 159 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022
  1. package com.malk.service.sync;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONArray;
  4. import com.alibaba.fastjson.JSONObject;
  5. import com.malk.model.H3yunResponse;
  6. import com.malk.model.KingdeeSaveResponse;
  7. import com.malk.model.WangdianResponse;
  8. import com.malk.service.h3yun.H3yunService;
  9. import com.malk.service.kingdee.KingdeeService;
  10. import com.malk.service.wangdian.WangdianService;
  11. import org.slf4j.Logger;
  12. import org.slf4j.LoggerFactory;
  13. import org.springframework.beans.factory.annotation.Autowired;
  14. import org.springframework.stereotype.Service;
  15. import cn.hutool.core.util.StrUtil;
  16. import java.text.SimpleDateFormat;
  17. import java.util.*;
  18. /**
  19. * 数据同步服务
  20. *
  21. * 功能说明:实现三大系统之间的数据同步逻辑
  22. *
  23. * 同步方向:
  24. * 1. 氚云 -> 金蝶:API主动推送
  25. * 2. 金蝶 -> 氚云:Webhook事件触发
  26. * 3. 氚云 -> 旺店通:定时任务/触发推送
  27. *
  28. * 异常处理机制(需求文档4.1):
  29. * - 重试机制:网络超时或返回"系统繁忙"时,采用指数退避重试(1s, 5s, 30s)
  30. * - 日志记录:所有接口调用记录完整请求报文和响应报文
  31. *
  32. * 幂等性设计(需求文档4.2):
  33. * - 金蝶 -> 氚云:利用单据编号查询氚云是否已存在,防止重复写入
  34. * - 氚云 -> 金蝶:利用金蝶Save接口"编码相同即修改"特性,保证数据不重复
  35. */
  36. @Service
  37. public class SyncService {
  38. private static final Logger log = LoggerFactory.getLogger(SyncService.class);
  39. @Autowired
  40. private KingdeeService kingdeeService;
  41. @Autowired
  42. private H3yunService h3yunService;
  43. @Autowired
  44. private WangdianService wangdianService;
  45. // ==================== Webhook数据解析辅助方法 ====================
  46. /**
  47. * 从webhook数据中获取单据详情
  48. * 如果webhookData为空,则调用Kingdee API查询
  49. */
  50. private JSONObject getBillDetailFromWebhook(JSONObject webhookData, String formId, String billNo) {
  51. if (webhookData != null) {
  52. JSONObject data = webhookData.getJSONObject("data");
  53. if (data != null) {
  54. log.info("使用webhook数据, billNo: {}", billNo);
  55. return data;
  56. }
  57. }
  58. // fallback: 调用API查询
  59. log.info("webhook数据为空,调用API查询, formId: {}, billNo: {}", formId, billNo);
  60. return kingdeeService.queryBillDetail(formId, billNo);
  61. }
  62. /**
  63. * 从单据明细中计算总数量
  64. */
  65. private Integer getTotalQtyFromBillEntry(JSONObject billDetail) {
  66. JSONArray entryArray = billDetail.getJSONArray("billentry");
  67. if (entryArray != null && !entryArray.isEmpty()) {
  68. double totalQty = 0;
  69. for (int i = 0; i < entryArray.size(); i++) {
  70. JSONObject entry = entryArray.getJSONObject(i);
  71. Double qty = entry.getDouble("qty");
  72. if (qty != null) {
  73. totalQty += qty;
  74. }
  75. }
  76. return (int) totalQty;
  77. }
  78. return 0;
  79. }
  80. // ==================== 氚云 -> 金蝶同步 ====================
  81. /**
  82. * 同步供应商档案到金蝶
  83. */
  84. public KingdeeSaveResponse syncSupplierToKingdee(String code, String name, String createOrgId,
  85. String useOrgId, String creditCode) {
  86. try {
  87. Map<String, Object> data = new HashMap<>();
  88. data.put("code", code);
  89. data.put("name", name);
  90. data.put("createOrgId", createOrgId);
  91. data.put("useOrgId", useOrgId);
  92. data.put("creditCode", creditCode);
  93. return kingdeeService.saveSupplier(data);
  94. } catch (Exception e) {
  95. log.error("同步供应商档案到金蝶异常, code: {}", code, e);
  96. throw e;
  97. }
  98. }
  99. /**
  100. * 同步客户档案到金蝶
  101. */
  102. public KingdeeSaveResponse syncCustomerToKingdee(String code, String name, String group, String taxNo) {
  103. try {
  104. Map<String, Object> data = new HashMap<>();
  105. data.put("code", code);
  106. data.put("name", name);
  107. data.put("group", group);
  108. data.put("taxNo", taxNo);
  109. return kingdeeService.saveCustomer(data);
  110. } catch (Exception e) {
  111. log.error("同步客户档案到金蝶异常, code: {}", code, e);
  112. throw e;
  113. }
  114. }
  115. /**
  116. * 同步物料档案到金蝶
  117. */
  118. public KingdeeSaveResponse syncMaterialToKingdee(String code, String name, String baseUnitId,
  119. String materialGroup, String createOrgId) {
  120. try {
  121. Map<String, Object> data = new HashMap<>();
  122. data.put("code", code);
  123. data.put("name", name);
  124. data.put("baseUnitId", baseUnitId);
  125. data.put("materialGroup", materialGroup);
  126. data.put("createOrgId", createOrgId);
  127. return kingdeeService.saveMaterial(data);
  128. } catch (Exception e) {
  129. log.error("同步物料档案到金蝶异常, code: {}", code, e);
  130. throw e;
  131. }
  132. }
  133. /**
  134. * 同步仓库档案到金蝶
  135. */
  136. public KingdeeSaveResponse syncStockToKingdee(String code, String name, String useOrgId, String stockProperty) {
  137. try {
  138. Map<String, Object> data = new HashMap<>();
  139. data.put("code", code);
  140. data.put("name", name);
  141. data.put("useOrgId", useOrgId);
  142. data.put("stockProperty", stockProperty);
  143. return kingdeeService.saveStock(data);
  144. } catch (Exception e) {
  145. log.error("同步仓库档案到金蝶异常, code: {}", code, e);
  146. throw e;
  147. }
  148. }
  149. /**
  150. * 同步采购申请单到金蝶
  151. */
  152. public KingdeeSaveResponse syncPurchaseRequisitionToKingdee(String applicationOrgId, String date,
  153. String materialId, Double reqQty) {
  154. try {
  155. Map<String, Object> data = new HashMap<>();
  156. data.put("applicationOrgId", applicationOrgId);
  157. data.put("date", date);
  158. data.put("materialId", materialId);
  159. data.put("reqQty", reqQty);
  160. return kingdeeService.savePurchaseRequisition(data);
  161. } catch (Exception e) {
  162. log.error("同步采购申请单到金蝶异常", e);
  163. throw e;
  164. }
  165. }
  166. /**
  167. * 同步销售订单到金蝶
  168. */
  169. public KingdeeSaveResponse syncSaleOrderToKingdee(String saleOrgId, String customerId,
  170. String materialId, Double qty) {
  171. try {
  172. Map<String, Object> data = new HashMap<>();
  173. data.put("saleOrgId", saleOrgId);
  174. data.put("customerId", customerId);
  175. data.put("materialId", materialId);
  176. data.put("qty", qty);
  177. return kingdeeService.saveSaleOrder(data);
  178. } catch (Exception e) {
  179. log.error("同步销售订单到金蝶异常", e);
  180. throw e;
  181. }
  182. }
  183. /**
  184. * 全量同步金蝶银行行名行号到氚云表
  185. * - F0000001: union_number
  186. * - F0000002: name
  187. * - F0000004: 默认“可用”
  188. */
  189. public Map<String, Object> syncKingdeeBankListToH3yun() {
  190. Map<String, Object> result = new LinkedHashMap<>();
  191. String startCreateTime = "2024-08-05 16:42:32";
  192. int pageNo = 1;
  193. int pageSize = 200;
  194. boolean lastPage = false;
  195. int totalRows = 0;
  196. int successCount = 0;
  197. int failCount = 0;
  198. List<String> errors = new ArrayList<>();
  199. result.put("startCreateTime", startCreateTime);
  200. while (!lastPage) {
  201. JSONObject pageResult = kingdeeService.getBankList(startCreateTime, pageNo, pageSize);
  202. JSONObject data = pageResult.getJSONObject("data");
  203. if (data == null) {
  204. break;
  205. }
  206. JSONArray rows = data.getJSONArray("rows");
  207. int currentRowCount = rows == null ? 0 : rows.size();
  208. totalRows += currentRowCount;
  209. log.info("开始同步金蝶银行行名行号第 {} 页, 本页 {} 条", pageNo, currentRowCount);
  210. if (rows != null) {
  211. for (int i = 0; i < rows.size(); i++) {
  212. JSONObject row = rows.getJSONObject(i);
  213. try {
  214. String unionNumber = row.getString("union_number");
  215. String name = row.getString("name");
  216. if (StrUtil.isBlank(unionNumber)) {
  217. failCount++;
  218. errors.add(String.format("跳过银行行名行号:name=%s,union_number为空", name));
  219. continue;
  220. }
  221. String existingObjectId = findExistingBankObjectId(unionNumber);
  222. Map<String, Object> formData = new LinkedHashMap<>();
  223. formData.put("F0000001", unionNumber);
  224. formData.put("F0000002", name);
  225. formData.put("F0000004", "可用");
  226. if (StrUtil.isNotBlank(existingObjectId)) {
  227. h3yunService.updateFormData("D293655sn1gizwncl0ulfdqwcll", existingObjectId, formData);
  228. } else {
  229. h3yunService.createBizObject("D293655sn1gizwncl0ulfdqwcll", formData);
  230. }
  231. successCount++;
  232. } catch (Exception e) {
  233. failCount++;
  234. errors.add("处理银行行名行号异常: " + e.getMessage());
  235. log.error("同步银行行名行号到氚云异常, row: {}", row.toJSONString(), e);
  236. }
  237. }
  238. }
  239. Boolean pageLast = data.getBoolean("lastPage");
  240. lastPage = Boolean.TRUE.equals(pageLast);
  241. if (pageLast == null && currentRowCount < pageSize) {
  242. lastPage = true;
  243. }
  244. pageNo++;
  245. }
  246. result.put("totalRows", totalRows);
  247. result.put("success", failCount == 0);
  248. result.put("successCount", successCount);
  249. result.put("failCount", failCount);
  250. result.put("errors", errors);
  251. return result;
  252. }
  253. private String findExistingBankObjectId(String unionNumber) {
  254. String filter = String.format("F0000001 = '%s'", unionNumber);
  255. JSONObject result = h3yunService.queryBizObjects("D293655sn1gizwncl0ulfdqwcll", filter, 1, 0);
  256. JSONObject returnData = result.getJSONObject("ReturnData");
  257. if (returnData != null) {
  258. JSONArray bizObjectArray = returnData.getJSONArray("BizObjectArray");
  259. if (bizObjectArray != null && !bizObjectArray.isEmpty()) {
  260. return bizObjectArray.getJSONObject(0).getString("ObjectId");
  261. }
  262. }
  263. return null;
  264. }
  265. /**
  266. * 全量同步金蝶库存汇总到氚云分仓库存表
  267. * 默认映射:
  268. * - F0000100: 物料ID(按K3 material主数据ID匹配氚云物料表)
  269. * - F0000106: 物料编码
  270. * - F0000101: 仓库ID(按仓库编码匹配氚云仓库表)
  271. * - F0000102: 默认0
  272. * - F0000105: 库存数量 qty
  273. * - F0000104: 可用数量 avbqty
  274. */
  275. public Map<String, Object> syncKingdeeInventorySumToH3yun() {
  276. Map<String, Object> result = new LinkedHashMap<>();
  277. List<String> orgList = getEnabledInventoryOrgList();
  278. result.put("orgList", orgList);
  279. if (orgList.isEmpty()) {
  280. result.put("success", false);
  281. result.put("totalRows", 0);
  282. result.put("successCount", 0);
  283. result.put("failCount", 0);
  284. result.put("errors", Collections.singletonList("未查询到可用的库存组织编码"));
  285. return result;
  286. }
  287. int totalRows = 0;
  288. int successCount = 0;
  289. int failCount = 0;
  290. List<String> errors = new ArrayList<>();
  291. for (String org : orgList) {
  292. try {
  293. List<JSONObject> rows = kingdeeService.getAllInventorySumRows(org, 100);
  294. totalRows += rows.size();
  295. log.info("开始同步库存组织 {}, 共 {} 条库存汇总数据", org, rows.size());
  296. for (JSONObject row : rows) {
  297. try {
  298. String materialK3Id = row.getString("material");
  299. String materialNumber = row.getString("material.number");
  300. String warehouseNumber = row.getString("warehouse.number");
  301. String qty = row.getString("qty");
  302. String avbqty = row.getString("avbqty");
  303. String materialObjectId = h3yunService.getObjectIdByFieldValue(
  304. "D293655fc1a38f7956f400a886f376911a54a30", "K3id", materialK3Id);
  305. String warehouseObjectId = h3yunService.getObjectIdByFieldValue(
  306. "D293655scvrhqr64jemxdkqk6gf", "SeqNo", warehouseNumber);
  307. String orgID = h3yunService.getObjectIdByFieldValue(
  308. "D29365537feb4e5e8644b21b7fd938dd322dab3", "F0000002", org);
  309. if (StrUtil.isBlank(materialObjectId) || StrUtil.isBlank(warehouseObjectId)) {
  310. failCount++;
  311. errors.add(String.format("跳过库存行:org=%s material=%s warehouse=%s,氚云档案未匹配", org, materialNumber, warehouseNumber));
  312. continue;
  313. }
  314. String existingObjectId = findExistingStockDetailObjectId(orgID, materialObjectId, warehouseObjectId);
  315. Map<String, Object> formData = new LinkedHashMap<>();
  316. formData.put("F0000102", org);
  317. formData.put("F0000100", materialObjectId);
  318. formData.put("F0000106", materialNumber);
  319. formData.put("F0000101", warehouseObjectId);
  320. formData.put("F0000105", parseDecimalOrZero(qty));
  321. formData.put("F0000104", parseDecimalOrZero(avbqty));
  322. formData.put("F0000107", orgID);
  323. if (StrUtil.isNotBlank(existingObjectId)) {
  324. h3yunService.updateFormData("D293655sukswvxwuqus2tdbygynr", existingObjectId, formData);
  325. } else {
  326. h3yunService.createBizObject("D293655sukswvxwuqus2tdbygynr", formData);
  327. }
  328. successCount++;
  329. } catch (Exception e) {
  330. failCount++;
  331. errors.add(String.format("处理库存行异常: org=%s, %s", org, e.getMessage()));
  332. log.error("同步单行库存到氚云异常, org: {}, row: {}", org, row.toJSONString(), e);
  333. }
  334. }
  335. } catch (Exception e) {
  336. failCount++;
  337. errors.add(String.format("同步库存组织异常: org=%s, %s", org, e.getMessage()));
  338. log.error("同步库存组织异常, org: {}", org, e);
  339. }
  340. }
  341. result.put("success", failCount == 0);
  342. result.put("totalRows", totalRows);
  343. result.put("successCount", successCount);
  344. result.put("failCount", failCount);
  345. result.put("errors", errors);
  346. return result;
  347. }
  348. private List<String> getEnabledInventoryOrgList() {
  349. JSONObject result = h3yunService.queryBizObjects(
  350. "D29365537feb4e5e8644b21b7fd938dd322dab3",
  351. "F0000003 = '可用'",
  352. 200,
  353. 0
  354. );
  355. List<String> orgList = new ArrayList<>();
  356. JSONObject returnData = result.getJSONObject("ReturnData");
  357. if (returnData == null) {
  358. return orgList;
  359. }
  360. JSONArray bizObjectArray = returnData.getJSONArray("BizObjectArray");
  361. if (bizObjectArray == null) {
  362. return orgList;
  363. }
  364. for (int i = 0; i < bizObjectArray.size(); i++) {
  365. JSONObject bizObject = bizObjectArray.getJSONObject(i);
  366. String org = bizObject.getString("F0000002");
  367. if (StrUtil.isNotBlank(org) && !orgList.contains(org)) {
  368. orgList.add(org);
  369. }
  370. }
  371. return orgList;
  372. }
  373. private String findExistingStockDetailObjectId(String org, String materialObjectId, String warehouseObjectId) {
  374. String filter = String.format("F0000107 = '%s' AND F0000100 = '%s' AND F0000101 = '%s'", org, materialObjectId, warehouseObjectId);
  375. JSONObject result = h3yunService.queryBizObjects("D293655sukswvxwuqus2tdbygynr", filter, 1, 0);
  376. JSONObject returnData = result.getJSONObject("ReturnData");
  377. if (returnData != null) {
  378. JSONArray bizObjectArray = returnData.getJSONArray("BizObjectArray");
  379. if (bizObjectArray != null && !bizObjectArray.isEmpty()) {
  380. return bizObjectArray.getJSONObject(0).getString("ObjectId");
  381. }
  382. }
  383. return null;
  384. }
  385. private Double parseDecimalOrZero(String value) {
  386. if (StrUtil.isBlank(value)) {
  387. return 0D;
  388. }
  389. try {
  390. return Double.parseDouble(value);
  391. } catch (Exception e) {
  392. return 0D;
  393. }
  394. }
  395. // ==================== 金蝶 -> 氚云同步 ====================
  396. /**
  397. * 同步采购入库单(金蝶->氚云)
  398. * @param billNo 单据编号
  399. * @param webhookData 可选的webhook原始数据,如果传入则直接使用,避免再次查询
  400. */
  401. public boolean syncPurchaseInstockFromKingdee(String billtypeId, String billNo, JSONObject webhookData, String finalBilltypeName) {
  402. try {
  403. // 1. 检查是否已存在(幂等性)
  404. if (h3yunService.checkBillExists(H3yunService.SCHEMA_PURCHASE_INSTOCK, billNo, "F0000041")) {
  405. log.info("采购入库单已存在,跳过同步, billNo: {}", billNo);
  406. return true;
  407. }
  408. // // 2. 获取单据详情(优先使用webhook数据,其次查询API)
  409. // JSONObject billDetail = getBillDetailFromWebhook(webhookData, "STK_InStock", billNo);
  410. //
  411. // // 3. 解析数据并写入氚云
  412. // String customerId = billDetail.getJSONObject("supplier") != null ? billDetail.getJSONObject("supplier").getString("number") : null;
  413. // Integer qty = getTotalQtyFromBillEntry(billDetail);
  414. H3yunResponse response = h3yunService.createPurchaseInstock(billNo, billtypeId, webhookData, finalBilltypeName);
  415. return response.isSuccess();
  416. } catch (Exception e) {
  417. log.error("同步采购入库单异常, billNo: {}", billNo, e);
  418. return false;
  419. }
  420. }
  421. /**
  422. * 同步采购退料单(金蝶->氚云)
  423. * @param billNo 单据编号
  424. * @param webhookData 可选的webhook原始数据,如果传入则直接使用,避免再次查询
  425. */
  426. public boolean syncPurchaseReturnFromKingdee(String billtypeId, String billNo, JSONObject webhookData, String finalBilltypeName) {
  427. try {
  428. if (h3yunService.checkBillExists(H3yunService.SCHEMA_PURCHASE_RETURN, billNo, "F0000042")) {
  429. log.info("采购退料单已存在,跳过同步, billNo: {}", billNo);
  430. return true;
  431. }
  432. // JSONObject billDetail = getBillDetailFromWebhook(webhookData, "STK_MisDelivery", billNo);
  433. // String customerId = billDetail.getJSONObject("supplier") != null ? billDetail.getJSONObject("supplier").getString("number") : null;
  434. // Integer qty = getTotalQtyFromBillEntry(billDetail);
  435. H3yunResponse response = h3yunService.createPurchaseReturn(billNo, billtypeId, webhookData, finalBilltypeName);
  436. return response.isSuccess();
  437. } catch (Exception e) {
  438. log.error("同步采购退料单异常, billNo: {}", billNo, e);
  439. return false;
  440. }
  441. }
  442. /**
  443. * 同步采购退料单(兼容旧方法)
  444. */
  445. /**
  446. * 同步销售出库单(金蝶->氚云)
  447. * @param billNo 单据编号
  448. * @param webhookData 可选的webhook原始数据,如果传入则直接使用,避免再次查询
  449. */
  450. public boolean syncSaleOutstockFromKingdee(String billtypeId, String billNo, JSONObject webhookData, String finalBilltypeName) {
  451. try {
  452. if (h3yunService.checkBillExists(H3yunService.SCHEMA_SALE_OUTSTOCK, billNo, "K3id")) {
  453. log.info("销售出库单已存在,跳过同步, billNo: {}", billNo);
  454. return true;
  455. }
  456. // JSONObject billDetail = getBillDetailFromWebhook(webhookData, "SAL_OUTSTOCK", billNo);
  457. // String customerId = billDetail.getJSONObject("customer") != null ? billDetail.getJSONObject("customer").getString("number") : null;
  458. // Integer qty = getTotalQtyFromBillEntry(billDetail);
  459. H3yunResponse response = h3yunService.createSaleOutstock(billNo, billtypeId, webhookData, finalBilltypeName);
  460. return response.isSuccess();
  461. } catch (Exception e) {
  462. log.error("同步销售出库单异常, billNo: {}", billNo, e);
  463. return false;
  464. }
  465. }
  466. /**
  467. * 同步销售出库单(兼容旧方法)
  468. */
  469. /**
  470. * 同步销售退货单(金蝶->氚云)
  471. * @param billNo 单据编号
  472. * @param webhookData 可选的webhook原始数据,如果传入则直接使用,避免再次查询
  473. */
  474. public boolean syncSaleReturnFromKingdee(String billtypeId, String billNo, JSONObject webhookData, String finalBilltypeName) {
  475. try {
  476. if (h3yunService.checkBillExists(H3yunService.SCHEMA_SALE_RETURN, billNo, "K3id")) {
  477. log.info("销售退货单已存在,跳过同步, billNo: {}", billNo);
  478. return true;
  479. }
  480. //
  481. // JSONObject billDetail = getBillDetailFromWebhook(webhookData, "SAL_RETURNSTOCK", billNo);
  482. // String customerId = billDetail.getJSONObject("customer") != null ? billDetail.getJSONObject("customer").getString("number") : null;
  483. // Integer qty = getTotalQtyFromBillEntry(billDetail);
  484. H3yunResponse response = h3yunService.createSaleReturn(billNo, billtypeId, webhookData, finalBilltypeName);
  485. return response.isSuccess();
  486. } catch (Exception e) {
  487. log.error("同步销售退货单异常, billNo: {}", billNo, e);
  488. return false;
  489. }
  490. }
  491. // ==================== 氚云 -> 旺店通同步 ====================
  492. /**
  493. * 同步盘点单到旺店通(氚云->旺店通)
  494. */
  495. public boolean syncInventoryToWangdian(String warehouseNo, List<Map<String, Object>> profitItems,
  496. List<Map<String, Object>> lossItems) {
  497. try {
  498. boolean allSuccess = true;
  499. // 同步盘盈单
  500. if (profitItems != null && !profitItems.isEmpty()) {
  501. WangdianResponse profitResponse = wangdianService.createProfitOrder(warehouseNo, profitItems);
  502. if (!profitResponse.isSuccess()) {
  503. log.error("同步盘盈单失败, error: {}", profitResponse.getErrorMessage());
  504. allSuccess = false;
  505. }
  506. }
  507. // 同步盘亏单
  508. if (lossItems != null && !lossItems.isEmpty()) {
  509. WangdianResponse lossResponse = wangdianService.createLossOrder(warehouseNo, lossItems);
  510. if (!lossResponse.isSuccess()) {
  511. log.error("同步盘亏单失败, error: {}", lossResponse.getErrorMessage());
  512. allSuccess = false;
  513. }
  514. }
  515. return allSuccess;
  516. } catch (Exception e) {
  517. log.error("同步盘点单到旺店通异常, warehouseNo: {}", warehouseNo, e);
  518. return false;
  519. }
  520. }
  521. /**
  522. * 同步单个盘盈物料
  523. */
  524. public WangdianResponse syncSingleProfitToWangdian(String warehouseNo, String specNo, Integer num, String remark) {
  525. return wangdianService.createProfitOrder(warehouseNo, specNo, num, remark);
  526. }
  527. /**
  528. * 同步单个盘亏物料
  529. */
  530. public WangdianResponse syncSingleLossToWangdian(String warehouseNo, String specNo, Integer num, String remark) {
  531. return wangdianService.createLossOrder(warehouseNo, specNo, num, remark);
  532. }
  533. // ==================== 氚云 -> 金蝶统一同步接口 ====================
  534. /**
  535. * 统一同步方法(氚云->金蝶)
  536. *
  537. * 功能说明:根据对接类型,从氚云查询数据并同步到金蝶
  538. *
  539. * @param schemaCode 氚云表单编码
  540. * @param objectId 氚云数据ID
  541. * @param syncType 对接类型(SUPPLIER/CUSTOMER/MATERIAL/STOCK等)
  542. * @return 同步结果
  543. */
  544. public KingdeeSaveResponse syncToKingdeeByType(String schemaCode, String objectId, String syncType) {
  545. log.info("开始氚云->金蝶同步, schemaCode: {}, objectId: {}, syncType: {}", schemaCode, objectId, syncType);
  546. // 1. 查询氚云数据
  547. JSONObject bizData = h3yunService.getBizObjectById(schemaCode, objectId);
  548. if (bizData == null) {
  549. throw new RuntimeException("未查询到氚云数据, objectId: " + objectId);
  550. }
  551. // 2. 根据对接类型执行同步
  552. switch (syncType) {
  553. case H3yunService.SYNC_TYPE_SUPPLIER:
  554. //供应商
  555. return syncSupplierToKingdeeFromH3yun(bizData);
  556. case H3yunService.SYNC_TYPE_CUSTOMER:
  557. //客户
  558. return syncCustomerToKingdeeFromH3yun(bizData);
  559. case H3yunService.SYNC_TYPE_MATERIAL:
  560. //物料
  561. return syncMaterialToKingdeeFromH3yun(bizData);
  562. case H3yunService.SYNC_TYPE_STOCK:
  563. //仓库
  564. return syncStockToKingdeeFromH3yun(bizData);
  565. case H3yunService.SYNC_TYPE_PURCHASE_REQUISITION:
  566. //采购订单
  567. return syncPurchaseRequisitionToKingdeeFromH3yun(bizData);
  568. case H3yunService.SYNC_TYPE_SALE_ORDER:
  569. //销售订单
  570. return syncSaleOrderToKingdeeFromH3yun(bizData);
  571. case H3yunService.SYNC_TYPE_PURCHASE_RECEIVE:
  572. //收料通知单
  573. return syncPurchaseReceiveToKingdeeFromH3yun(bizData);
  574. case H3yunService.SYNC_TYPE_PURCHASE_RETURN:
  575. //采购退料申请
  576. return syncPurchaseReturnToKingdeeFromH3yun(bizData);
  577. case H3yunService.SYNC_TYPE_DELIVERY_NOTICE:
  578. //发货通知单
  579. return syncDeliveryNoticeToKingdeeFromH3yun(bizData);
  580. case H3yunService.SYNC_TYPE_RETURN_REQUEST:
  581. //退货申请单
  582. return syncReturnRequestToKingdeeFromH3yun(bizData);
  583. case H3yunService.SYNC_TYPE_PAYABLE_BILL:
  584. //财务应付单
  585. return syncPayableBillToKingdeeFromH3yun(bizData);
  586. case H3yunService.SYNC_TYPE_PAYMENT_REQUEST:
  587. //采购付款申请单@采购付款单
  588. return syncPaymentRequestToKingdeeFromH3yun(bizData);
  589. case H3yunService.SYNC_TYPE_PURCHASE_INVOICE:
  590. return syncPurchaseInvoiceToKingdeeFromH3yun(bizData);
  591. case H3yunService.SYNC_TYPE_SALES_INVOICE:
  592. return syncSalesInvoiceToKingdeeFromH3yun(bizData);
  593. case H3yunService.SYNC_TYPE_RECEIVE_BILL:
  594. //销售收款单
  595. return syncReceiveBillToKingdeeFromH3yun(bizData);
  596. case H3yunService.SYNC_TYPE_INVOICE_APPLY:
  597. //开票申请@财务应收单
  598. return syncInvoiceApplyToKingdeeFromH3yun(bizData);
  599. case H3yunService.SYNC_TYPE_PROJECT:
  600. //项目立项
  601. return syncProjectToKingdeeFromH3yun(bizData);
  602. default:
  603. throw new RuntimeException("不支持的对接类型: " + syncType);
  604. }
  605. }
  606. /***
  607. 提供金蝶关联关系: 收料通知单关联采购订单 退料申请单关联采购入库单 发货通知单关联销售订单 退货申请单关联销售出库单 付款申请单关联财务应付单 销售收款单关联销售订单 销售出库单关联销售订单 开票申请单关联销售出库单
  608. 金蝶回复:API中已经变更,注意使用新的API
  609. 关联关系 billentry_lk_stableid 备注
  610. 收料通知单关联采购订单 602924326097811460
  611. 退料申请单关联采购入库单 602924315385558018
  612. 发货通知单关联销售订单 602924332909361155
  613. 退货申请单关联销售出库单 602924300688717826
  614. 付款申请单关联财务应付单 577639813562251264 注意:这个关联的是付款计划,不是物料明细
  615. 销售收款单关联销售订单 602924332909361152 注意:这个关联的是收款款计划,而且收款计划明细中是预收,不是物料明细
  616. 销售出库单关联销售订单 602924332909361155
  617. 关联销售出库单 602924300688717826
  618. 待金蝶确认:
  619. 事件订阅发生的入库申请参数中有无收料通知单信息
  620. 事件订阅发生的采购退料单参数中有无退料申请单信息
  621. 事件订阅发生的销售出库单参数中有无发货通知单信息
  622. 事件订阅发生的销售退货单参数中有无退货申请单信息
  623. 金蝶回复:
  624. 在订阅的参数中 billhead_lk 中的信息是关联的单据信息 */
  625. /**
  626. * 从氚云数据同步供应商到金蝶
  627. */
  628. private KingdeeSaveResponse syncSupplierToKingdeeFromH3yun(JSONObject bizData) {
  629. Map<String, Object> data = extractSupplierData(bizData);
  630. String k3Id = bizData.getString("K3id");
  631. KingdeeSaveResponse response;
  632. if (k3Id != null && !k3Id.trim().isEmpty()) {
  633. // 已有K3ID,执行修改流程:反审核 -> 修改 -> 提交 -> 审核
  634. log.info("供应商已存在K3ID: {},执行修改流程", k3Id);
  635. response = kingdeeService.batchUpdateSupplierWithSubmit(data, k3Id);
  636. } else {
  637. // 无K3ID,执行新增流程:新增 -> 提交 -> 审核
  638. log.info("供应商无K3ID,执行新增流程");
  639. response = kingdeeService.batchAddSupplierWithSubmit(data);
  640. }
  641. writeBackSupplierBankEntryIds(bizData, response);
  642. return response;
  643. }
  644. public void writeBackSupplierBankEntryIds(JSONObject bizData, KingdeeSaveResponse response) {
  645. if (response == null || !response.isSuccess()) {
  646. return;
  647. }
  648. JSONArray bankEntryIds = extractSupplierBankEntryIds(response);
  649. if (bankEntryIds == null || bankEntryIds.isEmpty()) {
  650. return;
  651. }
  652. JSONArray sourceRows = bizData.getJSONArray("D293655Fb2deb81ad33c41e4bac91630e399d141");
  653. if (sourceRows == null || sourceRows.isEmpty()) {
  654. return;
  655. }
  656. JSONArray targetRows = new JSONArray();
  657. int count = Math.min(sourceRows.size(), bankEntryIds.size());
  658. for (int i = 0; i < count; i++) {
  659. JSONObject sourceRow = sourceRows.getJSONObject(i);
  660. JSONObject targetRow = new JSONObject(true);
  661. targetRow.put("F0000022", sourceRow.getString("F0000022"));
  662. targetRow.put("F0000023", sourceRow.getString("F0000023"));
  663. targetRow.put("F0000025", sourceRow.getString("F0000025"));
  664. targetRow.put("F0000024", sourceRow.getString("F0000024"));
  665. targetRow.put("F0000026", sourceRow.getString("F0000026"));
  666. targetRow.put("F0000027", bankEntryIds.getString(i));
  667. targetRows.add(targetRow);
  668. }
  669. Map<String, Object> updateData = new LinkedHashMap<>();
  670. updateData.put("D293655Fb2deb81ad33c41e4bac91630e399d141", targetRows);
  671. h3yunService.updateBizObject("D293655b4a0a34e44914aee9613a7bd3957df83", bizData.getString("ObjectId"), updateData);
  672. }
  673. private JSONArray extractSupplierBankEntryIds(KingdeeSaveResponse response) {
  674. JSONObject data = response.getData();
  675. if (data == null) {
  676. return null;
  677. }
  678. JSONArray resultArray = data.getJSONArray("result");
  679. if (resultArray == null || resultArray.isEmpty()) {
  680. return null;
  681. }
  682. for (int i = 0; i < resultArray.size(); i++) {
  683. JSONObject resultItem = resultArray.getJSONObject(i);
  684. if (resultItem == null) {
  685. continue;
  686. }
  687. JSONObject entryIds = resultItem.getJSONObject("entryIds");
  688. if (entryIds == null) {
  689. continue;
  690. }
  691. JSONArray entryBank = entryIds.getJSONArray("entry_bank");
  692. if (entryBank != null && !entryBank.isEmpty()) {
  693. return entryBank;
  694. }
  695. }
  696. return null;
  697. }
  698. /**
  699. * 从氚云数据同步客户到金蝶
  700. */
  701. private KingdeeSaveResponse syncCustomerToKingdeeFromH3yun(JSONObject bizData) {
  702. Map<String, Object> data = extractCustomerData(bizData);
  703. String k3Id = bizData.getString("K3id");
  704. if (k3Id != null && !k3Id.trim().isEmpty()) {
  705. // 已有K3ID,执行修改流程:反审核 -> 修改 -> 提交 -> 审核
  706. log.info("客户已存在K3ID: {},执行修改流程", k3Id);
  707. return kingdeeService.batchUpdateCustomerWithSubmit(data, k3Id);
  708. } else {
  709. // 无K3ID,执行新增流程:新增 -> 提交 -> 审核
  710. log.info("客户无K3ID,执行新增流程");
  711. return kingdeeService.batchAddCustomerWithSubmit(data);
  712. }
  713. }
  714. /**
  715. * 从氚云数据同步物料到金蝶
  716. */
  717. private KingdeeSaveResponse syncMaterialToKingdeeFromH3yun(JSONObject bizData) {
  718. Map<String, Object> data = extractMaterialData(bizData);
  719. // 判断是否已有K3ID,有则修改,无则新增
  720. String k3Id = bizData.getString("K3id");
  721. if (k3Id != null && !k3Id.trim().isEmpty()) {
  722. // 已有K3ID,执行修改流程:反审核 -> 修改 -> 提交 -> 审核
  723. log.info("物料已存在K3ID: {},执行修改流程", k3Id);
  724. return kingdeeService.batchUpdateMaterialWithSubmit(data, k3Id, bizData);
  725. } else {
  726. // 无K3ID,执行新增流程:新增 -> 提交 -> 审核
  727. log.info("物料无K3ID,执行新增流程");
  728. return kingdeeService.batchAddMaterialWithSubmit(data, bizData);
  729. }
  730. }
  731. /**
  732. * 从氚云数据同步仓库到金蝶
  733. */
  734. private KingdeeSaveResponse syncStockToKingdeeFromH3yun(JSONObject bizData) {
  735. Map<String, Object> data = extractStockData(bizData);
  736. String k3Id = bizData.getString("K3id");
  737. String numbersss = bizData.getString("SeqNo");
  738. if (k3Id != null && !k3Id.trim().isEmpty()) {
  739. // 已有K3ID,执行修改流程:反审核 -> 修改 -> 提交 -> 审核
  740. log.info("仓库已存在K3ID: {},执行修改流程,仓库编码{}", k3Id, numbersss);
  741. return kingdeeService.batchUpdateStockWithSubmit(data, numbersss);
  742. } else {
  743. // 无K3ID,执行新增流程:新增 -> 提交 -> 审核
  744. log.info("仓库无K3ID,执行新增流程");
  745. return kingdeeService.batchAddStockWithSubmit(data);
  746. }
  747. }
  748. /**
  749. * 从氚云数据同步采购订单到金蝶
  750. */
  751. private KingdeeSaveResponse syncPurchaseRequisitionToKingdeeFromH3yun(JSONObject bizData) {
  752. Map<String, Object> data = extractPurchaseRequisitionData(bizData);
  753. String k3Id = bizData.getString("K3id");
  754. if (k3Id != null && !k3Id.trim().isEmpty()) {
  755. log.info("采购订单已存在K3ID: {},执行修改流程", k3Id);
  756. return kingdeeService.batchUpdatePurchaseRequisitionWithSubmit(data, k3Id);
  757. } else {//AP-20260508-000009
  758. log.info("采购订单无K3ID,执行新增流程");
  759. return kingdeeService.batchAddPurchaseRequisitionWithSubmit(data);
  760. }
  761. }
  762. /**
  763. * 从氚云数据同步销售订单到金蝶
  764. */
  765. private KingdeeSaveResponse syncSaleOrderToKingdeeFromH3yun(JSONObject bizData) {
  766. Map<String, Object> data = extractSaleOrderData(bizData);
  767. String k3Id = bizData.getString("K3id");
  768. if (k3Id != null && !k3Id.trim().isEmpty()) {
  769. log.info("销售订单已存在K3ID: {},执行修改流程", k3Id);
  770. return kingdeeService.batchUpdateSaleOrderWithSubmit(data, k3Id);
  771. } else {
  772. log.info("销售订单无K3ID,执行新增流程");
  773. return kingdeeService.batchAddSaleOrderWithSubmit(data);
  774. }
  775. }
  776. // 以下为扩展方法,可以根据实际氚云表单字段配置
  777. private KingdeeSaveResponse syncPurchaseReceiveToKingdeeFromH3yun(JSONObject bizData) {
  778. Map<String, Object> data = extractPurchaseReceiveData(bizData);
  779. String k3Id = bizData.getString("K3id");
  780. if (k3Id != null && !k3Id.trim().isEmpty()) {
  781. log.info("收料通知单已存在K3ID: {},执行修改流程", k3Id);
  782. return kingdeeService.batchUpdatePurchaseReceiveWithSubmit(data, k3Id);
  783. } else {
  784. log.info("收料通知单无K3ID,执行新增流程");
  785. return kingdeeService.batchAddPurchaseReceiveWithSubmit(data);
  786. }
  787. }
  788. private KingdeeSaveResponse syncPurchaseReturnToKingdeeFromH3yun(JSONObject bizData) {
  789. Map<String, Object> data = extractPurchaseReturnData(bizData);
  790. String k3Id = bizData.getString("K3id");
  791. if (k3Id != null && !k3Id.trim().isEmpty()) {
  792. log.info("采购退料申请已存在K3ID: {},执行修改流程", k3Id);
  793. return kingdeeService.batchUpdatePurchaseReturnWithSubmit(data, k3Id);
  794. } else {
  795. log.info("采购退料申请无K3ID,执行新增流程");
  796. return kingdeeService.batchAddPurchaseReturnWithSubmit(data);
  797. }
  798. }
  799. private KingdeeSaveResponse syncDeliveryNoticeToKingdeeFromH3yun(JSONObject bizData) {
  800. Map<String, Object> data = extractDeliveryNoticeData(bizData);
  801. String k3Id = bizData.getString("K3id");
  802. if (k3Id != null && !k3Id.trim().isEmpty()) {
  803. log.info("发货通知单已存在K3ID: {},执行修改流程", k3Id);
  804. return kingdeeService.batchUpdateDeliveryNoticeWithSubmit(data, k3Id);
  805. } else {
  806. log.info("发货通知单无K3ID,执行新增流程");
  807. return kingdeeService.batchAddDeliveryNoticeWithSubmit(data);
  808. }
  809. }
  810. private KingdeeSaveResponse syncReturnRequestToKingdeeFromH3yun(JSONObject bizData) {
  811. Map<String, Object> data = extractReturnRequestData(bizData);
  812. String k3Id = bizData.getString("K3id");
  813. if (k3Id != null && !k3Id.trim().isEmpty()) {
  814. log.info("退货申请单已存在K3ID: {},执行修改流程", k3Id);
  815. return kingdeeService.batchUpdateReturnRequestWithSubmit(data, k3Id);
  816. } else {
  817. log.info("退货申请单无K3ID,执行新增流程");
  818. return kingdeeService.batchAddReturnRequestWithSubmit(data);
  819. }
  820. }
  821. private KingdeeSaveResponse syncPaymentRequestToKingdeeFromH3yun(JSONObject bizData) {
  822. Map<String, Object> data = extractPaymentRequestData(bizData);
  823. String k3Id = bizData.getString("K3id");
  824. if (k3Id != null && !k3Id.trim().isEmpty()) {
  825. log.info("付款申请单已存在K3ID: {},执行修改流程", k3Id);
  826. return kingdeeService.batchUpdatePaymentRequestWithSubmit(data, k3Id);
  827. } else {
  828. log.info("付款申请单无K3ID,执行新增流程");
  829. return kingdeeService.batchAddPaymentRequestWithSubmit(data);
  830. }
  831. }
  832. private KingdeeSaveResponse syncPayableBillToKingdeeFromH3yun(JSONObject bizData) {
  833. Map<String, Object> data = extractPayableBillData(bizData);
  834. String k3Id = bizData.getString("K3id");
  835. if (k3Id != null && !k3Id.trim().isEmpty()) {
  836. log.info("财务应付单已存在K3ID: {},执行修改流程", k3Id);
  837. return kingdeeService.batchUpdatePayableBillWithSubmit(data, k3Id);
  838. } else {
  839. log.info("财务应付单无K3ID,执行新增流程");
  840. return kingdeeService.batchAddPayableBillWithSubmit(data);
  841. }
  842. }
  843. private KingdeeSaveResponse syncPurchaseInvoiceToKingdeeFromH3yun(JSONObject bizData) {
  844. Map<String, Object> data = extractPurchaseInvoiceData(bizData);
  845. String k3Id = bizData.getString("K3id");
  846. if (k3Id != null && !k3Id.trim().isEmpty()) {
  847. log.info("采购发票已存在K3ID: {},执行修改流程", k3Id);
  848. return kingdeeService.batchUpdatePurchaseInvoiceWithSubmit(data, k3Id);
  849. } else {
  850. log.info("采购发票无K3ID,执行新增流程");
  851. return kingdeeService.batchAddPurchaseInvoiceWithSubmit(data);
  852. }
  853. }
  854. private KingdeeSaveResponse syncSalesInvoiceToKingdeeFromH3yun(JSONObject bizData) {
  855. Map<String, Object> data = extractSalesInvoiceData(bizData);
  856. String k3Id = bizData.getString("K3id");
  857. if (k3Id != null && !k3Id.trim().isEmpty()) {
  858. log.info("销售发票已存在K3ID: {},执行修改流程", k3Id);
  859. return kingdeeService.batchUpdateSalesInvoiceWithSubmit(data, k3Id);
  860. } else {
  861. log.info("销售发票无K3ID,执行新增流程");
  862. return kingdeeService.batchAddSalesInvoiceWithSubmit(data);
  863. }
  864. }
  865. private KingdeeSaveResponse syncReceiveBillToKingdeeFromH3yun(JSONObject bizData) {
  866. Map<String, Object> data = extractReceiveBillData(bizData);
  867. String k3Id = bizData.getString("K3id");
  868. if (k3Id != null && !k3Id.trim().isEmpty()) {
  869. log.info("收款单已存在K3ID: {},执行修改流程", k3Id);
  870. return kingdeeService.batchUpdateReceiveBillWithSubmit(data, k3Id);
  871. } else {
  872. log.info("收款单无K3ID,执行新增流程");
  873. return kingdeeService.batchAddReceiveBillWithSubmit(data);
  874. }
  875. }
  876. private KingdeeSaveResponse syncInvoiceApplyToKingdeeFromH3yun(JSONObject bizData) {
  877. Map<String, Object> data = extractInvoiceApplyData(bizData);
  878. String k3Id = bizData.getString("K3id");
  879. if (k3Id != null && !k3Id.trim().isEmpty()) {
  880. log.info("开票申请单已存在K3ID: {},执行修改流程", k3Id);
  881. return kingdeeService.batchUpdateInvoiceApplyWithSubmit(data, k3Id);
  882. } else {
  883. log.info("开票申请单无K3ID,执行新增流程");
  884. return kingdeeService.batchAddInvoiceApplyWithSubmit(data);
  885. }
  886. }
  887. private KingdeeSaveResponse syncProjectToKingdeeFromH3yun(JSONObject bizData) {
  888. Map<String, Object> data = extractProjectData(bizData);
  889. String k3Id = bizData.getString("K3id");
  890. if (k3Id != null && !k3Id.trim().isEmpty()) {
  891. log.info("项目立项已存在K3ID: {},执行修改流程", k3Id);
  892. return kingdeeService.batchUpdateProjectWithSubmit(data, k3Id);
  893. } else {
  894. log.info("项目立项无K3ID,执行新增流程");
  895. return kingdeeService.batchAddProjectWithSubmit(data);
  896. }
  897. }
  898. // ==================== 数据提取方法 ====================
  899. /**
  900. * 提取供应商数据
  901. *
  902. * 字段映射(可根据实际氚云表单字段名称调整):
  903. * - F0000001: 供应商编码 -> code
  904. * - F0000002: 供应商名称 -> name
  905. * - F0000003: 创建组织 -> createOrgId
  906. * - F0000004: 使用组织 -> useOrgId
  907. * - F0000005: 社会信用代码 -> creditCode
  908. */
  909. private Map<String, Object> extractSupplierData(JSONObject bizData) {
  910. Map<String, Object> root = new LinkedHashMap<>();
  911. List<Object> dataList = new ArrayList<>();
  912. root.put("data", dataList);
  913. Map<String, Object> supplier = new LinkedHashMap<>();
  914. dataList.add(supplier);
  915. // 基本信息
  916. supplier.put("number", bizData.getString("SeqNo")); // 供应商编码
  917. supplier.put("name", bizData.getString("F0000001")); // 供应商名称
  918. supplier.put("simplename", bizData.getString("F0000003")); // 简称
  919. supplier.put("type", extractSupplierType(bizData.getString("F0000008"))); // 供应商伙伴类型
  920. supplier.put("societycreditcode", bizData.getString("F0000012")); // 社会信用代码
  921. supplier.put("bizfunction", extractBizFunction(bizData.getString("F0000006"))); // 业务职能
  922. supplier.put("tx_register_no", bizData.getString("F0000013")); // 纳税人识别号
  923. supplier.put("artificialperson", bizData.getString("F0000014")); // 法人代表
  924. supplier.put("regcapital", bizData.getString("F0000015")); // 注册资本
  925. supplier.put("curegcapital_number", "CNY"); // 注册资本币别
  926. supplier.put("businessterm", bizData.getString("F0000016")); // 营业期限
  927. supplier.put("businessscope", bizData.getString("F0000017")); // 经营范围
  928. if (bizData.getString("F0000018") != null && !bizData.getString("F0000018").trim().isEmpty()) {
  929. supplier.put("establishdate", formatDate(bizData.getString("F0000018"))); // 成立时间
  930. }
  931. supplier.put("createorg_number", bizData.getString("F0000007") == "" ? "001" : bizData.getString("F0000007")); // 创建组织
  932. supplier.put("country_number", "001"); // 国家
  933. supplier.put("creator_number", bizData.getString("UserID") == "" ? "43007523" : bizData.getString("UserID")); // 创建人
  934. supplier.put("modifier_number", bizData.getString("UserID") == "" ? "43007523" : bizData.getString("UserID")); // 修改人
  935. // 地址相关
  936. supplier.put("bizpartner_address", bizData.getString("F0000009")); // 供应商地址
  937. supplier.put("bizpartner_fax", bizData.getString("F0000009")); // 传真
  938. // 联系人信息
  939. supplier.put("linkman", bizData.getString("F0000010")); // 联系人
  940. supplier.put("bizpartner_phone", bizData.getString("F0000011")); // 电话】
  941. supplier.put("paycond_number", h3yunService.getFieldValueById("D293655sxvsttpe7re2tep6gvsdg", bizData.getString("F0000019"), "F0000001"));
  942. supplier.put("idno", bizData.getString("F0000028")); // 身份证号
  943. // 银行账户信息
  944. List<Map<String, Object>> bankList = new ArrayList<>();
  945. JSONArray billentryArray = bizData.getJSONArray("D293655Fb2deb81ad33c41e4bac91630e399d141");
  946. if (billentryArray != null && !billentryArray.isEmpty()) {
  947. for (int i = 0; i < billentryArray.size(); i++) {
  948. JSONObject entryData = billentryArray.getJSONObject(i);
  949. Map<String, Object> bank = new LinkedHashMap<>();
  950. String uuidHex = entryData.getString("F0000027");
  951. if (uuidHex != null && !uuidHex.isEmpty()) {
  952. bank.put("id", uuidHex);
  953. } else {
  954. bank.put("id", "0");
  955. }
  956. bank.put("bank_number", h3yunService.getFieldValueById("D293655sn1gizwncl0ulfdqwcll", entryData.getString("F0000025"), "F0000001")); // 银行编码
  957. bank.put("accountname", entryData.getString("F0000023")); // 开户名称
  958. bank.put("bankaccount", entryData.getString("F0000022")); // 银行账号
  959. bank.put("currency_number", h3yunService.getFieldValueById("D293655f08d8524a8254d35b3681ea527ce2c59", entryData.getString("F0000024"), "F0000001")); // 币别
  960. if (i == 0) {
  961. bank.put("isdefault_bank", true);
  962. }
  963. bankList.add(bank);
  964. }
  965. }
  966. supplier.put("entry_bank", bankList);
  967. // List<Map<String, Object>> linkmanList = new ArrayList<>();
  968. // Map<String, Object> linkman = new LinkedHashMap<>();
  969. // linkman.put("contactperson", bizData.getString("F0000010")); // 联系人姓名
  970. // linkman.put("phone", bizData.getString("F0000011")); // 联系人电话
  971. // linkman.put("isdefault_linkman", true);
  972. // linkmanList.add(linkman);
  973. // supplier.put("entry_linkman", linkmanList);
  974. // 税号信息
  975. // List<Map<String, Object>> taxList = new ArrayList<>();
  976. // Map<String, Object> tax = new LinkedHashMap<>();
  977. // tax.put("taxcertificate_number", bizData.getString("F0000015")); // 税号
  978. // taxList.add(tax);
  979. // supplier.put("entry_tax", taxList);
  980. // 分组信息
  981. // List<Map<String, Object>> groupList = new ArrayList<>();
  982. // Map<String, Object> group = new LinkedHashMap<>();
  983. // group.put("standardid_number", bizData.getString("F0000016")); // 组内标准编码
  984. // groupList.add(group);
  985. // supplier.put("entry_groupstandard", groupList);
  986. // 其他字段
  987. // supplier.put("duns", bizData.getString("F0000021")); // DUNS编码
  988. // supplier.put("paycond_number", bizData.getString("F0000022")); // 付款条件编码
  989. // supplier.put("taxrate_number", bizData.getString("F0000023")); // 税率编码
  990. // supplier.put("paymentcurrency_number", bizData.getString("F0000024")); // 付款币别
  991. // supplier.put("settlementcyid_number", bizData.getString("F0000025")); // 结算币别
  992. // supplier.put("settlementtypeid_number", bizData.getString("F0000026")); // 结算方式
  993. // supplier.put("internal_company_number", bizData.getString("F0000027")); // 内账公司
  994. //
  995. //
  996. // supplier.put("taxregistplace_number", bizData.getString("F0000030")); // 税务登记地
  997. // 如果有K3ID则设置,用于修改
  998. String k3Id = bizData.getString("K3id");
  999. if (k3Id != null && !k3Id.isEmpty()) {
  1000. supplier.put("id", k3Id);
  1001. // supplier.put("masterid", k3Id);
  1002. }
  1003. return root;
  1004. }
  1005. /**
  1006. * 提取客户数据(金蝶API格式)
  1007. * 返回格式: {"data":[{"number":"CUS-001","name":"客户名称",...}]}
  1008. */
  1009. @SuppressWarnings("unchecked")
  1010. private Map<String, Object> extractCustomerData(JSONObject bizData) {
  1011. Map<String, Object> data = new HashMap<>();
  1012. List<Map<String, Object>> dataList = new ArrayList<>();
  1013. Map<String, Object> customer = new LinkedHashMap<>();
  1014. // 基础字段
  1015. customer.put("number", bizData.getString("SeqNo")); // 客户编码
  1016. customer.put("name", bizData.getString("F0000001")); // 客户名称
  1017. customer.put("simplename", bizData.getString("F0000002")); // 简称
  1018. customer.put("type", extractCustomerType(bizData.getString("F0000016"))); // 客户类型
  1019. customer.put("bizfunction", extractBizFunction(bizData.getString("F0000015"))); // 业务职能
  1020. // 社会信息
  1021. customer.put("societycreditcode", bizData.getString("F0000020")); // 社会信用代码
  1022. customer.put("tx_register_no", bizData.getString("F0000021")); // 纳税人识别号
  1023. customer.put("artificialperson", bizData.getString("F0000022")); // 法人代表
  1024. customer.put("regcapital", bizData.getString("F0000023")); // 注册资本
  1025. customer.put("curegcapital_number", "CNY"); // 注册资本币别
  1026. customer.put("businessterm", bizData.getString("F0000024")); // 营业期限
  1027. customer.put("businessscope", bizData.getString("F0000025")); // 经营范围
  1028. if (bizData.getString("F0000026") != null && !bizData.getString("F0000026").trim().isEmpty()) {
  1029. customer.put("establishdate", formatDate(bizData.getString("F0000026"))); // 成立时间
  1030. }
  1031. // 组织相关
  1032. customer.put("createorg_number", StrUtil.blankToDefault(bizData.getString("F0000019"), "001")); // 创建组织
  1033. // customer.put("country_number", "001"); // 国家
  1034. // customer.put("admindivision", bizData.getString("F0000014")); // 行政区域
  1035. // 联系方式
  1036. customer.put("linkman", bizData.getString("F0000004")); // 联系人
  1037. customer.put("bizpartner_phone", bizData.getString("F0000005")); // 电话
  1038. customer.put("bizpartner_address", bizData.getString("F0000011")); // 地址
  1039. // customer.put("bizpartner_fax", bizData.getString("F0000018")); // 传真
  1040. // customer.put("postal_code", bizData.getString("F0000019")); // 邮编
  1041. // 财务相关
  1042. // customer.put("taxrate_number", bizData.getString("F0000020")); // 税率
  1043. // customer.put("taxno", bizData.getString("F0000021")); // 税务登记号
  1044. // customer.put("duns", bizData.getString("F0000022")); // 数据唯一标识
  1045. // 结算相关
  1046. customer.put("settlementcyid_number", "CNY"); // 结算币别
  1047. customer.put("paymentcurrency_number", "CNY"); // 收付款币别
  1048. // 创建人/修改人
  1049. customer.put("creator_number", StrUtil.blankToDefault(bizData.getString("UserID"), "43007523")); // 创建人
  1050. customer.put("modifier_number", StrUtil.blankToDefault(bizData.getString("UserID"), "43007523")); // 修改人
  1051. customer.put("receivingcondid_number", h3yunService.getFieldValueById("D293655sv6bv8bozikwrkze3rk1", bizData.getString("F0000028"), "F0000001"));
  1052. //身份证号
  1053. customer.put("idno", bizData.getString("F0000032"));
  1054. ////发票类型-无异议
  1055. // customer.put("invoicecategory_number", h3yunService.getFieldValueById("D293655sdzbyn4yqt0ub0k8e9euc", bizData.getString("F0000033"), "F0000001"));
  1056. String k3Id = bizData.getString("K3id");
  1057. if (k3Id != null && !k3Id.isEmpty()) {
  1058. customer.put("id", k3Id);
  1059. // supplier.put("masterid", k3Id);
  1060. }
  1061. List<Map<String, Object>> groupStandardList = new ArrayList<>();//分类标准
  1062. Map<String, Object> groupStandard = new LinkedHashMap<>();
  1063. groupStandard.put("standardid_number", "JBFLBZ"); // 组内编码
  1064. groupStandard.put("groupid_number", h3yunService.getFieldValueById("D293655syoqw97qcuoxuxbhjkzo", bizData.getString("F0000027"), "F0000001")); // 组合号
  1065. groupStandardList.add(groupStandard);
  1066. customer.put("entry_groupstandard", groupStandardList);
  1067. dataList.add(customer);
  1068. data.put("data", dataList);
  1069. return data;
  1070. }
  1071. /**
  1072. * 提取客户类型
  1073. * 格式如 "普通客户-1" -> "1"
  1074. */
  1075. private String extractCustomerType(String typeStr) {
  1076. if (typeStr == null || typeStr.trim().isEmpty()) {
  1077. return "1"; // 默认值
  1078. }
  1079. int index = typeStr.lastIndexOf("-");
  1080. if (index >= 0 && index < typeStr.length() - 1) {
  1081. return typeStr.substring(index + 1);
  1082. }
  1083. return "1";
  1084. }
  1085. /**
  1086. * 格式化日期为 yyyy-MM-dd 格式
  1087. * 输入格式如 "2026/4/17 0:00:00" -> "2026-04-17"
  1088. */
  1089. private String formatDate(String dateStr) {
  1090. if (dateStr == null || dateStr.trim().isEmpty()) {
  1091. return "";
  1092. }
  1093. try {
  1094. return cn.hutool.core.date.DateUtil.parse(dateStr).toString("yyyy-MM-dd");
  1095. } catch (Exception e) {
  1096. log.warn("日期解析失败: {}, 返回原值", dateStr);
  1097. return dateStr;
  1098. }
  1099. }
  1100. /**
  1101. * 提取项目立项数据(金蝶API格式)
  1102. * 默认映射如下,后续可按实际氚云字段调整:
  1103. * - number: SeqNo
  1104. * - name: F0000001
  1105. * - createorg_number: F0000002,默认001
  1106. * - group_number: F0000003
  1107. * - parent_number: F0000004
  1108. * - planbegindate: F0000005
  1109. * - planenddate: F0000006
  1110. * - proaddress: F0000007
  1111. * - sourcetype: 固定A
  1112. */
  1113. private Map<String, Object> extractProjectData(JSONObject bizData) {
  1114. Map<String, Object> root = new LinkedHashMap<>();
  1115. List<Map<String, Object>> dataList = new ArrayList<>();
  1116. Map<String, Object> project = new LinkedHashMap<>();
  1117. project.put("number", bizData.getString("SeqNo"));//项目编码
  1118. project.put("name", bizData.getString("F0000002"));//项目名称
  1119. project.put("createorg_number", h3yunService.getFieldValueById("D29365537feb4e5e8644b21b7fd938dd322dab3", bizData.getString("F0000042"), "F0000002"));
  1120. if (bizData.getString("F0000043") != "") {
  1121. project.put("group_number", h3yunService.getFieldValueById("D293655sgawiua6uedgcpglojm", bizData.getString("F0000043"), "F0000001"));
  1122. }
  1123. // project.put("parent_number", bizData.getString("F0000004"));
  1124. project.put("planbegindate", formatDate(bizData.getString("F0000050")));
  1125. project.put("planenddate", formatDate(bizData.getString("F0000051")));
  1126. // project.put("proaddress", bizData.getString("F0000007"));
  1127. project.put("sourcetype", "C");
  1128. String k3Id = bizData.getString("K3id");
  1129. if (StrUtil.isNotBlank(k3Id)) {
  1130. project.put("id", k3Id);
  1131. }
  1132. dataList.add(project);
  1133. root.put("data", dataList);
  1134. return root;
  1135. }
  1136. /**
  1137. * 提取物料数据(按金蝶物料接口格式)
  1138. */
  1139. private Map<String, Object> extractMaterialData(JSONObject bizData) {
  1140. // 1. 构建根节点 Map
  1141. Map<String, Object> root = new LinkedHashMap<>();
  1142. List<Object> materialsList = new ArrayList<>();
  1143. root.put("materials", materialsList);
  1144. // 2. 构建 materials 数组中的第一个对象
  1145. Map<String, Object> materialItem = new LinkedHashMap<>();
  1146. materialsList.add(materialItem);
  1147. // 3. 构建 commonInfoVo 对象
  1148. Map<String, Object> commonInfoVo = new LinkedHashMap<>();
  1149. // commonInfoVo.put("enableproduct", false);
  1150. // commonInfoVo.put("createorg", bizData.getString("F0000005")); // 创建组织
  1151. // commonInfoVo.put("bondcontrol", ""); // 可根据业务配置
  1152. //
  1153. // // serviceattribute 是数组
  1154. // // commonInfoVo.put("serviceattribute", Collections.singletonList(bizData.getString("F0000010")));
  1155. //
  1156. //
  1157. //
  1158. //
  1159. // commonInfoVo.put("enableinv", false);
  1160. // commonInfoVo.put("enableinspect", false);
  1161. // commonInfoVo.put("group", bizData.getString("F0000004")); // 物料分组
  1162. // commonInfoVo.put("taxrate", bizData.getString("F0000007")); // 税率
  1163. //
  1164. //
  1165. // commonInfoVo.put("enablesale", false);
  1166. // commonInfoVo.put("atpcheck", "");
  1167. //
  1168. // commonInfoVo.put("enablepur", false);
  1169. //
  1170. // commonInfoVo.put("enableoutsource", false);
  1171. //
  1172. //
  1173. // commonInfoVo.put("enableasset", false);
  1174. // 4. 构建 materialInfoVo 对象
  1175. Map<String, Object> materialInfoVo = new LinkedHashMap<>();
  1176. // 4.1 构建 auxptyentry 数组
  1177. // List<Map<String, Object>> auxptyentryList = new ArrayList<>();
  1178. // Map<String, Object> auxptyEntry = new LinkedHashMap<>();
  1179. // auxptyEntry.put("isaffectprice", false);
  1180. // auxptyEntry.put("auxpty_id", bizData.getString("F0000011")); // 辅助属性ID
  1181. // auxptyEntry.put("iscomcontrol", false);
  1182. // auxptyEntry.put("id", bizData.getString("F0000012")); // 辅助属性项ID
  1183. // auxptyEntry.put("auxptynumber", bizData.getString("F0000013")); // 辅助属性编码
  1184. // auxptyEntry.put("isaffectinv", false);
  1185. // auxptyEntry.put("isaffectplan", false);
  1186. // auxptyEntry.put("seq", 235);
  1187. // auxptyentryList.add(auxptyEntry);
  1188. // materialInfoVo.put("auxptyentry", auxptyentryList);
  1189. // 4.3 填充 materialInfoVo 其他字段
  1190. String K3id = bizData.getString("K3id");
  1191. if (K3id != null && !K3id.isEmpty()) {
  1192. materialInfoVo.put("id", K3id); // 物料ID(仅在SeqNo不为空时设置)
  1193. }
  1194. materialInfoVo.put("name", bizData.getString("F0000001")); // 物料名称
  1195. materialInfoVo.put("number", bizData.getString("SeqNo")); // 物料编码
  1196. materialInfoVo.put("createorg", bizData.getString("F0000027") == "" ? "001" : bizData.getString("F0000027")); // 创建组织ID为空默认吾流
  1197. materialInfoVo.put("baseunit", bizData.getString("F0000026") == "" ? "pcs" : bizData.getString("F0000026")); // 基本单位ID
  1198. materialInfoVo.put("unitconvertdir", bizData.getString("F0000008") == "逆向换算" ? "B" : "A"); // 单位换算方向
  1199. materialInfoVo.put("modelnum", bizData.getString("F0000010")); // 规格型号
  1200. commonInfoVo.put("materialtype", mapMaterialType(bizData.getString("F0000011"))); // 物料类型
  1201. commonInfoVo.put("materialattr", mapMaterialAttr(bizData.getString("F0000012"))); // 物料属性
  1202. materialInfoVo.put("creator_number", bizData.getString("UserID") == "" ? "43007523" : bizData.getString("UserID"));//创建人ID 为空默认金小蝶
  1203. // 4.2 构建 entry_groupstandard 数组
  1204. List<Map<String, Object>> groupStandardList = new ArrayList<>();
  1205. Map<String, Object> groupStandard = new LinkedHashMap<>();
  1206. groupStandard.put("groupStrandardNumber", "JBFLBZ"); // 组内编码
  1207. // groupStandard.put("id", bizData.getString("F0000015")); // 组内标准ID
  1208. // groupStandard.put("groupStrandardCreateOrg", bizData.getString("F0000016")); // 组内标准创建组织
  1209. groupStandard.put("groupNumber", extractGroupNumber(bizData.getString("F0000028"))); // 组合号
  1210. groupStandardList.add(groupStandard);
  1211. materialInfoVo.put("entry_groupstandard", groupStandardList);
  1212. commonInfoVo.put("controlpur", "是".equals(bizData.getString("F0000015")));//可采购
  1213. commonInfoVo.put("controlsale", "是".equals(bizData.getString("F0000016")));//可销售
  1214. commonInfoVo.put("enablesale", "是".equals(bizData.getString("F0000016")));//可销售
  1215. commonInfoVo.put("controlinv", "是".equals(bizData.getString("F0000017")));//可库存
  1216. commonInfoVo.put("enableself", "是".equals(bizData.getString("F0000018")));//可自制
  1217. commonInfoVo.put("enableoutsource", "是".equals(bizData.getString("F0000019")));//可委外
  1218. commonInfoVo.put("controlplan", "是".equals(bizData.getString("F0000020")));//可计划
  1219. commonInfoVo.put("controlinspect", "是".equals(bizData.getString("F0000021")));//可质检
  1220. commonInfoVo.put("enablebom", "是".equals(bizData.getString("F0000022")));//可BOM
  1221. commonInfoVo.put("enablevmi", "是".equals(bizData.getString("F0000023")));//可VMI
  1222. commonInfoVo.put("enableconsign", "是".equals(bizData.getString("F0000024")));//可委托代销
  1223. commonInfoVo.put("enableqtyctrl", "是".equals(bizData.getString("F0000025")));//可发量控制
  1224. // commonInfoVo.put("enableplan", "是".equals(bizData.getString("F0000016")));
  1225. //
  1226. //
  1227. // commonInfoVo.put("controlsale", "是".equals(bizData.getString("F0000016")));//可销售
  1228. // commonInfoVo.put("controlsale", "是".equals(bizData.getString("F0000016")));//可销售
  1229. // commonInfoVo.put("controlsale", "是".equals(bizData.getString("F0000016")));//可销售
  1230. // materialInfoVo.put("isversionaffectplan", false);
  1231. // materialInfoVo.put("volumnunit", bizData.getString("F0000018")); // 体积单位
  1232. // materialInfoVo.put("isversionaffectinv", false);
  1233. // materialInfoVo.put("auxptyunit", bizData.getString("F0000019")); // 辅助单位
  1234. // materialInfoVo.put("length", bizData.getDouble("F0000021")); // 长度
  1235. // materialInfoVo.put("lengthunit", bizData.getString("F0000022")); // 长度单位
  1236. // materialInfoVo.put("isenablematerialversion", false);
  1237. // materialInfoVo.put("weightunit", bizData.getString("F0000023")); // 重量单位
  1238. // materialInfoVo.put("volume", bizData.getDouble("F0000025")); // 体积
  1239. //
  1240. // materialInfoVo.put("isuseauxpty", false);
  1241. // materialInfoVo.put("grossweight", bizData.getDouble("F0000026")); // 毛重
  1242. // materialInfoVo.put("netweight", bizData.getDouble("F0000027")); // 净重
  1243. //
  1244. // materialInfoVo.put("width", bizData.getDouble("F0000028")); // 宽度
  1245. //
  1246. // materialInfoVo.put("auxptyunit2", bizData.getString("F0000030")); // 辅助单位2
  1247. // materialInfoVo.put("height", bizData.getDouble("F0000031")); // 高度
  1248. // 5. 组装最终结构
  1249. materialItem.put("commonInfoVo", commonInfoVo);
  1250. materialItem.put("materialInfoVo", materialInfoVo);
  1251. return root;
  1252. }
  1253. /**
  1254. * 映射物料类型
  1255. * 物资->1, 费用->7, 资产->8, 服务->9
  1256. */
  1257. private String mapMaterialType(String type) {
  1258. if (type == null) {
  1259. return "1"; // 默认物资
  1260. }
  1261. switch (type.trim()) {
  1262. case "物资":
  1263. return "1";
  1264. case "费用":
  1265. return "7";
  1266. case "资产":
  1267. return "8";
  1268. case "服务":
  1269. return "9";
  1270. default:
  1271. return "1"; // 默认物资
  1272. }
  1273. }
  1274. /**
  1275. * 映射物料属性
  1276. * 自制->10030, 外购->10040, 委外->10050, 虚拟->10020
  1277. */
  1278. private String mapMaterialAttr(String attr) {
  1279. if (attr == null) {
  1280. return "10040"; // 默认外购
  1281. }
  1282. switch (attr.trim()) {
  1283. case "自制":
  1284. return "10030";
  1285. case "外购":
  1286. return "10040";
  1287. case "委外":
  1288. return "10050";
  1289. case "虚拟":
  1290. return "10020";
  1291. default:
  1292. return "10040"; // 默认外购
  1293. }
  1294. }
  1295. /**
  1296. * 提取组内编码
  1297. * 格式如 "资产-05" -> "05","物资-01" -> "01"
  1298. * 为空时默认 "05"
  1299. */
  1300. private String extractGroupNumber(String groupStrandardNumber) {
  1301. if (groupStrandardNumber == null || groupStrandardNumber.trim().isEmpty()) {
  1302. return "05"; // 默认值
  1303. }
  1304. // 按 "-" 分割,取后半部分
  1305. int index = groupStrandardNumber.indexOf("-");
  1306. if (index >= 0 && index < groupStrandardNumber.length() - 1) {
  1307. return groupStrandardNumber.substring(index + 1);
  1308. }
  1309. return "05"; // 默认值
  1310. }
  1311. /**
  1312. * 提取供应商类型
  1313. * 格式如 "法人企业-1" -> "1","个体工商户-2" -> "2"
  1314. */
  1315. private String extractSupplierType(String typeStr) {
  1316. if (typeStr == null || typeStr.trim().isEmpty()) {
  1317. return "1"; // 默认值
  1318. }
  1319. int index = typeStr.indexOf("-");
  1320. if (index >= 0 && index < typeStr.length() - 1) {
  1321. return typeStr.substring(index + 1);
  1322. }
  1323. return "1"; // 默认值
  1324. }
  1325. /**
  1326. * 提取业务职能
  1327. * 格式如 "采购-1;结算-2" -> ",1,2,"
  1328. */
  1329. private String extractBizFunction(String funcStr) {
  1330. if (funcStr == null || funcStr.trim().isEmpty()) {
  1331. return ",,"; // 默认空值
  1332. }
  1333. StringBuilder result = new StringBuilder(",");
  1334. String[] parts = funcStr.split(";");
  1335. for (String part : parts) {
  1336. int index = part.lastIndexOf("-");
  1337. if (index >= 0 && index < part.length() - 1) {
  1338. result.append(part.substring(index + 1)).append(",");
  1339. }
  1340. }
  1341. return result.toString();
  1342. }
  1343. /**
  1344. * 提取仓库数据(金蝶API格式)
  1345. * 返回格式: {"data":[{"number":"CK001","name":"仓库001",...}]}
  1346. */
  1347. @SuppressWarnings("unchecked")
  1348. private Map<String, Object> extractStockData(JSONObject bizData) {
  1349. Map<String, Object> data = new HashMap<>();
  1350. List<Map<String, Object>> dataList = new ArrayList<>();
  1351. Map<String, Object> stock = new LinkedHashMap<>();
  1352. // 基础字段
  1353. stock.put("number", bizData.getString("SeqNo")); // 仓库编码
  1354. stock.put("name", bizData.getString("F0000003")); // 仓库名称
  1355. stock.put("description", bizData.getString("F0000017")); // 描述
  1356. // 组织相关
  1357. stock.put("createorg_number", bizData.getString("F0000012") == "" ? "001" : bizData.getString("F0000012")); // 创建组织
  1358. stock.put("principal_number", bizData.getString("F0000019") == "" ? "43007523" : bizData.getString("F0000019")); // 负责人
  1359. // 地址相关
  1360. //stock.put("address", bizData.getString("F0000007")); // 地址
  1361. stock.put("detailaddress", bizData.getString("F0000011")); // 详细地址
  1362. // stock.put("telephone", bizData.getString("F0000009")); // 电话
  1363. // 仓库属性(布尔值)
  1364. stock.put("isallowallneginv", "是".equals(bizData.getString("F0000013"))); // 允许全部物料负库存
  1365. stock.put("isallowpartialneginv", "是".equals(bizData.getString("F0000014")));//仅允许部分物料负库存
  1366. stock.put("isopenlocation", false); // 启用库位
  1367. stock.put("isentrustverifyware", "是".equals(bizData.getString("F0000016"))); // 委托代销仓
  1368. stock.put("issuptransvirtualware", "是".equals(bizData.getString("F0000015"))); // 直运虚拟仓
  1369. // 货主信息
  1370. // stock.put("ownerid", bizData.getString("F0000010")); // 货主
  1371. dataList.add(stock);
  1372. data.put("data", dataList);
  1373. return data;
  1374. }
  1375. /**
  1376. * 提取采购订单数据(金蝶API格式)
  1377. * 返回格式: {"data":[{"supplier_number":"...","billentry":[...]}]}
  1378. */
  1379. @SuppressWarnings("unchecked")
  1380. private Map<String, Object> extractPurchaseRequisitionData(JSONObject bizData) {
  1381. Map<String, Object> data = new HashMap<>();
  1382. List<Map<String, Object>> dataList = new ArrayList<>();
  1383. Map<String, Object> purchaseOrder = new LinkedHashMap<>();
  1384. // 头部信息
  1385. String K3id = bizData.getString("K3id");
  1386. if (K3id != null && !K3id.isEmpty()) {
  1387. purchaseOrder.put("id", K3id); // 物料ID(仅在SeqNo不为空时设置)
  1388. }
  1389. purchaseOrder.put("billno", bizData.getString("SeqNo")); // 单据编号
  1390. purchaseOrder.put("trdbillno", bizData.getString("SeqNo")); // 单据编号
  1391. purchaseOrder.put("org_number", bizData.getString("F0000038") == "" ? "001" : bizData.getString("F0000038"));//#采购组织编码
  1392. purchaseOrder.put("billtype_number", bizData.getString("F0000021") == "" ? "pm_PurOrderBill_STD_BT_S" : "pm_PurOrderBill_STD_BT_S"); // 单据类型
  1393. purchaseOrder.put("biztype_number", bizData.getString("F0000022")); // 业务类型
  1394. purchaseOrder.put("biztime", formatDate(bizData.getString("F0000023"))); // 订单日期
  1395. purchaseOrder.put("supplier_number", bizData.getString("F0000039")); //订货供应商编码
  1396. purchaseOrder.put("settlecurrency_number", bizData.getString("F0000040")); // 结算币别
  1397. purchaseOrder.put("paycondition_number", h3yunService.getFieldValueById("D293655sxvsttpe7re2tep6gvsdg", bizData.getString("F0000025"), "F0000001")); // 付款条件
  1398. purchaseOrder.put("settletype_number", h3yunService.getFieldValueById("D293655skrwqen4wv0g7je4itf", bizData.getString("F0000035"), "F0000001")); // 结算币别.货币代码
  1399. purchaseOrder.put("operator_operatornumber", bizData.getString("F0000042"));//采购员
  1400. purchaseOrder.put("comment", bizData.getString("F0000031")); // 备注
  1401. // 付款方式: 现购->CASH, 赊购->CREDIT
  1402. String paymodeValue = bizData.getString("F0000034");
  1403. if ("现购".equals(paymodeValue)) {
  1404. purchaseOrder.put("paymode", "CASH");
  1405. } else if ("赊购".equals(paymodeValue)) {
  1406. purchaseOrder.put("paymode", "CREDIT");
  1407. } else {
  1408. purchaseOrder.put("paymode", paymodeValue); // 其他值原样传递
  1409. }
  1410. purchaseOrder.put("exratetable_number", "ERT-01"); // 汇率表
  1411. purchaseOrder.put("exchangerate", "1"); // 汇率
  1412. // purchaseOrder.put("operator_operatornumber", bizData.getString("F0000019") == "" ? "43007523" : bizData.getString("F0000019") ); // 采购员.业务员编码
  1413. // purchaseOrder.put("istax", true); // 是否含税
  1414. //purchaseOrder.put("ispayrate", false); // 按比例(%)
  1415. // 分录信息 billentry (D293655F1ba2412b43504c2cb5edc37874c75d2b)
  1416. List<Map<String, Object>> entryList = new ArrayList<>();
  1417. JSONArray billentryArray = bizData.getJSONArray("D293655F1ba2412b43504c2cb5edc37874c75d2b");
  1418. if (billentryArray != null && !billentryArray.isEmpty()) {
  1419. for (int i = 0; i < billentryArray.size(); i++) {
  1420. JSONObject entryData = billentryArray.getJSONObject(i);
  1421. Map<String, Object> entry = new LinkedHashMap<>();
  1422. String uuidHex = entryData.getString("ObjectId").replace("-", "");
  1423. // 取后16位(64bit),解析为无符号long,避免溢出和负数问题
  1424. long id = Long.parseUnsignedLong(uuidHex.substring(uuidHex.length() - 16), 16);
  1425. entry.put("id", id); // id
  1426. entry.put("linetype_number", entryData.getString("F0000026")); // 行类型.编码
  1427. entry.put("material_number", entryData.getString("F0000005")); // 物料编码
  1428. entry.put("unit_number", h3yunService.getFieldValueById("D293655248b1d9bf6c448f0a291341ec58bb943", entryData.getString("F0000027"), "F0000001")); // 单位
  1429. entry.put("qty", entryData.getDouble("F0000012")); // 数量
  1430. entry.put("price", entryData.getDouble("F0000013")); // 单价
  1431. entry.put("priceandtax", entryData.getDouble("F0000013")); // 含税单价
  1432. entry.put("discounttype", "NULL"); // 物料明细.折扣方式 A:折扣率(%), B:单位折扣额, NULL:无
  1433. entry.put("entryrecorg_number", bizData.getString("F0000038") == "" ? "001" : bizData.getString("F0000038")); // 收料组织
  1434. entry.put("entrysettleorg_number", bizData.getString("F0000038") == "" ? "001" : bizData.getString("F0000038")); // 结算组织
  1435. entry.put("entryreqorg_number", bizData.getString("F0000038") == "" ? "001" : bizData.getString("F0000038")); // 要货组织
  1436. entry.put("warehouse_number", entryData.getString("F0000044")); // #仓库编码
  1437. entry.put("ownertype", "bos_org"); // 物料明细.货主类型 bos_org:业务组织, bd_supplier:供应商, bd_customer:客户
  1438. entry.put("owner_number", bizData.getString("F0000038") == "" ? "001" : bizData.getString("F0000038"));
  1439. entry.put("taxrateid_number", h3yunService.getFieldValueById(
  1440. "D293655sl91vt6h8d0qg1heqw5aq", entryData.getString("F0000045"), "F0000001"));//税率.编码
  1441. entry.put("deliverdate", formatDate(entryData.getString("F0000015"))); // 交货日期
  1442. // entry.put("deliveraddress", entryData.getString("F0000014")); // 交货地址
  1443. // entry.put("entrycomment", entryData.getString("F0000007")); // 分录备注
  1444. // entry.put("warehouse_number", entryData.getString("F0000027")); // 仓库
  1445. // entry.put("location_number", entryData.getString("F0000010")); // 库位
  1446. // entry.put("project_number", entryData.getString("F0000011")); // 项目
  1447. entryList.add(entry);
  1448. }
  1449. }
  1450. purchaseOrder.put("billentry", entryList);
  1451. // 付款计划分录 purbillentry_pay (D293655F8151b3b1b0f345ba9a957cb57c7f5064)
  1452. List<Map<String, Object>> payList = new ArrayList<>();
  1453. JSONArray payArray = bizData.getJSONArray("D293655F8151b3b1b0f345ba9a957cb57c7f5064");
  1454. if (payArray != null && !payArray.isEmpty()) {
  1455. for (int i = 0; i < payArray.size(); i++) {
  1456. JSONObject payData = payArray.getJSONObject(i);
  1457. Map<String, Object> payEntry = new LinkedHashMap<>();
  1458. // entry.put("id", entryData.getString("ObjectId").replace("-", ""));//id
  1459. String uuidHex = payData.getString("ObjectId").replace("-", "");
  1460. // 取后16位(64bit),解析为无符号long,避免溢出和负数问题
  1461. long id = Long.parseUnsignedLong(uuidHex.substring(uuidHex.length() - 16), 16);
  1462. payEntry.put("id", id);
  1463. payEntry.put("paydate", formatDate(payData.getString("F0000028"))); // 付款日期
  1464. payEntry.put("payrate", payData.getDouble("F0000029")); // 付款比例
  1465. payEntry.put("payamount", payData.getDouble("F0000030")); // 付款金额
  1466. payEntry.put("planentrysettleorg_number", bizData.getString("F0000038") == "" ? "001" : bizData.getString("F0000038")); // 结算组织.编码
  1467. String r_needrecadvance = payData.getString("F0000055");
  1468. if ("是".equals(r_needrecadvance)) {
  1469. r_needrecadvance = "true";
  1470. } else {
  1471. r_needrecadvance = "false";
  1472. }
  1473. payEntry.put("isprepay", r_needrecadvance);
  1474. payList.add(payEntry);
  1475. }
  1476. }
  1477. purchaseOrder.put("purbillentry_pay", payList);
  1478. dataList.add(purchaseOrder);
  1479. data.put("data", dataList);
  1480. return data;
  1481. }
  1482. /**
  1483. * 提取销售订单数据(金蝶API格式)
  1484. * 返回格式: {"data":[{"billno":"...","customer_number":"...","salebillentry":[...]}]}
  1485. */
  1486. @SuppressWarnings("unchecked")
  1487. private Map<String, Object> extractSaleOrderData(JSONObject bizData) {
  1488. Map<String, Object> data = new HashMap<>();
  1489. List<Map<String, Object>> dataList = new ArrayList<>();
  1490. Map<String, Object> saleOrder = new LinkedHashMap<>();
  1491. // ========== 头部信息 ==========
  1492. saleOrder.put("billno", bizData.getString("SeqNo")); // 单据编号
  1493. saleOrder.put("bizdate", formatDate(bizData.getString("F0000021"))); // 订单日期
  1494. // 销售组织编码(复用查询结果)
  1495. String saleOrgNumber = (String) h3yunService.getFieldValueById(
  1496. "D29365537feb4e5e8644b21b7fd938dd322dab3", bizData.getString("F0000018"), "F0000002");
  1497. saleOrder.put("org_number", saleOrgNumber); // 销售组织
  1498. // 订货客户编码
  1499. saleOrder.put("customer_number", h3yunService.getFieldValueById(
  1500. "D293655shuyz9ttzgkgmhaa4rglr", bizData.getString("F0000024"), "SeqNo"));
  1501. saleOrder.put("billtype_number", "sm_SalesOrder_STD_BT_S"); // 单据类型
  1502. saleOrder.put("biztype_number", "210"); // 业务类型.编码
  1503. saleOrder.put("al95_customer_number", h3yunService.getFieldValueById(
  1504. "D293655shuyz9ttzgkgmhaa4rglr", bizData.getString("F0000023"), "SeqNo"));//店铺
  1505. saleOrder.put("al95_assistantfield_number", h3yunService.getFieldValueById(
  1506. "D293655sdfmyisqk1us9gqj1bljt", bizData.getString("F0000052"), "F0000001"));//物流公司.编码
  1507. saleOrder.put("al95_assistantfield_name", h3yunService.getFieldValueById(
  1508. "D293655sdfmyisqk1us9gqj1bljt", bizData.getString("F0000052"), "F0000011"));//物流公司.编码
  1509. // 结算币别
  1510. saleOrder.put("settlecurrency_number", h3yunService.getFieldValueById(
  1511. "D293655f08d8524a8254d35b3681ea527ce2c59", bizData.getString("F0000025"), "F0000001"));
  1512. saleOrder.put("comment", bizData.getString("F0000047")); // 备注
  1513. saleOrder.put("istax", bizData.getString("F0000041")); // 是否含税
  1514. // 操作员(默认43007523)
  1515. String operator = (String) h3yunService.getFieldValueById(
  1516. "D2936556a05fbb0350545cc9d8bd70901b1ed3b", bizData.getString("F0000048"), "F0000001");
  1517. saleOrder.put("operator_operatornumber", cn.hutool.core.util.StrUtil.blankToDefault(operator, "43007523"));
  1518. saleOrder.put("creator_number", bizData.getString("UserID") == "" ? "43007523" : bizData.getString("UserID"));//创建人ID 为空默认金小蝶
  1519. saleOrder.put("reccondition_number", h3yunService.getFieldValueById(
  1520. "D293655sv6bv8bozikwrkze3rk1", bizData.getString("F0000038"), "F0000001"));//收款条件.编号
  1521. // ========== 分录信息 salebillentry ==========
  1522. List<Map<String, Object>> entryList = new ArrayList<>();
  1523. JSONArray billentryArray = bizData.getJSONArray("D293655Fb301a6f03145402d84f56d4493e6e764");
  1524. if (billentryArray != null && !billentryArray.isEmpty()) {
  1525. for (int i = 0; i < billentryArray.size(); i++) {
  1526. JSONObject entryData = billentryArray.getJSONObject(i);
  1527. Map<String, Object> entry = new LinkedHashMap<>();
  1528. String uuidHex = entryData.getString("ObjectId").replace("-", "");
  1529. // 取后16位(64bit),解析为无符号long,避免溢出和负数问题
  1530. long id = Long.parseUnsignedLong(uuidHex.substring(uuidHex.length() - 16), 16);
  1531. entry.put("id", id); // id
  1532. entry.put("linetype_number", "010"); // 行类型.编码
  1533. // 物料编码(通过物料基础档案查询)
  1534. entry.put("material_number", h3yunService.getFieldValueById(
  1535. "D293655fc1a38f7956f400a886f376911a54a30", entryData.getString("F0000027"), "SeqNo"));
  1536. // 销售单位
  1537. entry.put("unit_number", h3yunService.getFieldValueById(
  1538. "D293655248b1d9bf6c448f0a291341ec58bb943", entryData.getString("F0000030"), "F0000001"));
  1539. entry.put("e_stockorg_number", saleOrgNumber); // 发货组织(复用)
  1540. entry.put("entrysettleorg_number", saleOrgNumber); // 结算组织(复用)
  1541. //entry.put("price", entryData.getDouble("F0000032")/(1+(entryData.getDouble("F0000078")/100)) ); // 单价
  1542. entry.put("priceandtax", entryData.getDouble("F0000032")); // h含税单价
  1543. entry.put("qty", entryData.getDouble("F0000031")); // 数量
  1544. entry.put("amount", entryData.getDouble("F0000033")); // 金额
  1545. entry.put("al95_textfield", entryData.getString("F0000053")); // 物料明细.收货人
  1546. entry.put("al95_textfield1", entryData.getString("F0000054")); // 物料明细.收货人地址
  1547. entry.put("al95_textfield2", entryData.getString("F0000055")); // 物料明细.收货人联系电话
  1548. // 仓库编码
  1549. entry.put("warehouse_number", h3yunService.getFieldValueById(
  1550. "D293655scvrhqr64jemxdkqk6gf", entryData.getString("F0000049"), "SeqNo"));
  1551. // 税率
  1552. entry.put("taxrateid_number", h3yunService.getFieldValueById(
  1553. "D293655sl91vt6h8d0qg1heqw5aq", entryData.getString("F0000077"), "F0000001"));
  1554. entryList.add(entry);
  1555. }
  1556. }
  1557. saleOrder.put("billentry", entryList);
  1558. // ========== 收款计划分录 recplanentry ==========
  1559. List<Map<String, Object>> recPlanList = new ArrayList<>();
  1560. JSONArray recplanentryArray = bizData.getJSONArray("D293655F3becd42e6bc4432889c35589bcab20e7");
  1561. if (recplanentryArray != null && !recplanentryArray.isEmpty()) {
  1562. for (int i = 0; i < recplanentryArray.size(); i++) {
  1563. JSONObject recData = recplanentryArray.getJSONObject(i);
  1564. Map<String, Object> recPlan = new LinkedHashMap<>();
  1565. // 销售组织编码(复用查询结果)
  1566. Map<String, Object> entry = new LinkedHashMap<>();
  1567. String uuidHex = recData.getString("ObjectId").replace("-", "");
  1568. // 取后16位(64bit),解析为无符号long,避免溢出和负数问题
  1569. long id = Long.parseUnsignedLong(uuidHex.substring(uuidHex.length() - 16), 16);
  1570. recPlan.put("id", id); // id
  1571. String r_recsettleorg_number = (String) h3yunService.getFieldValueById(
  1572. "D29365537feb4e5e8644b21b7fd938dd322dab3", recData.getString("F0000051"), "F0000002");
  1573. recPlan.put("r_recsettleorg_number", r_recsettleorg_number); // 结算组织
  1574. String r_needrecadvance = recData.getString("F0000050");
  1575. if ("是".equals(r_needrecadvance)) {
  1576. r_needrecadvance = "true";
  1577. } else {
  1578. r_needrecadvance = "false";
  1579. }
  1580. recPlan.put("r_needrecadvance", r_needrecadvance);
  1581. recPlan.put("r_duedate", formatDate(recData.getString("F0000037"))); // 到期日
  1582. recPlan.put("r_recadvancerate", recData.getDouble("F0000035")); // 应收比例%
  1583. recPlan.put("r_recadvanceamount", recData.getDouble("F0000036")); // 应收金额
  1584. recPlanList.add(recPlan);
  1585. }
  1586. }
  1587. saleOrder.put("recplanentry", recPlanList);
  1588. dataList.add(saleOrder);
  1589. data.put("data", dataList);
  1590. return data;
  1591. }
  1592. /**
  1593. * 提取收料通知单数据(金蝶API格式)
  1594. * 返回格式: {"data":[{"billno":"...","supplier_number":"...","purbillentry":[...]}]}
  1595. */
  1596. @SuppressWarnings("unchecked")
  1597. private Map<String, Object> extractPurchaseReceiveData(JSONObject bizData) {
  1598. Map<String, Object> data = new HashMap<>();
  1599. List<Map<String, Object>> dataList = new ArrayList<>();
  1600. Map<String, Object> receiveNotice = new LinkedHashMap<>();
  1601. // 头部信息
  1602. receiveNotice.put("billno", bizData.getString("SeqNo")); // 单据编号
  1603. receiveNotice.put("trdbillno", bizData.getString("SeqNo")); // 单据编号
  1604. receiveNotice.put("biztype_number", "110"); // 业务类型.编码
  1605. receiveNotice.put("biztype_name", "物料类采购");
  1606. receiveNotice.put("billstatus", "C");//单据状态
  1607. receiveNotice.put("biztime", formatDate(bizData.getString("F0000024"))); // 业务日期
  1608. receiveNotice.put("bookdate", formatDate(bizData.getString("F0000040"))); // 记账日期
  1609. receiveNotice.put("exchangerate", "1");//汇率
  1610. receiveNotice.put("istax", "true");//含税
  1611. receiveNotice.put("exratedate", new SimpleDateFormat("yyyy-MM-dd").format(new Date())); // 汇率日期(取今天)
  1612. // 付款方式: 现购->CASH, 赊购->CREDIT
  1613. String paymodeValue = bizData.getString("F0000044");
  1614. if ("现购".equals(paymodeValue)) {
  1615. receiveNotice.put("paymode", "CASH");
  1616. } else if ("赊购".equals(paymodeValue)) {
  1617. receiveNotice.put("paymode", "CREDIT");
  1618. } else {
  1619. receiveNotice.put("paymode", paymodeValue); // 其他值原样传递
  1620. }
  1621. receiveNotice.put("paycondition_number", h3yunService.getFieldValueById(
  1622. "D293655sxvsttpe7re2tep6gvsdg", bizData.getString("F0000049"), "F0000001"));//付款条件
  1623. receiveNotice.put("paycondition_name", h3yunService.getFieldValueById(
  1624. "D293655sxvsttpe7re2tep6gvsdg", bizData.getString("F0000049"), "F0000002"));//付款条件.名称
  1625. receiveNotice.put("supplier_name", h3yunService.getFieldValueById(
  1626. "D293655b4a0a34e44914aee9613a7bd3957df83", bizData.getString("F0000035"), "F0000001")); // 供应商名称
  1627. receiveNotice.put("supplier_number", h3yunService.getFieldValueById(
  1628. "D293655b4a0a34e44914aee9613a7bd3957df83", bizData.getString("F0000035"), "SeqNo")); // 供应商编码
  1629. //
  1630. // receiveNotice.put("stockorg_number", bizData.getString("F0000005")); // 收料组织
  1631. // receiveNotice.put("dept_number", bizData.getString("F0000006")); // 部门
  1632. // receiveNotice.put("purchaser_number", bizData.getString("F0000007")); // 采购员
  1633. // receiveNotice.put("billtype_number", bizData.getString("F0000008")); // 单据类型
  1634. // receiveNotice.put("comment", bizData.getString("F0000009")); // 备注
  1635. // receiveNotice.put("operator_operatornumber", bizData.getString("CreatedBy")); // 操作人
  1636. String purorderbillnumber = bizData.getString("F0000046"); //物料明细.采购订单号
  1637. // String project_number = "001"; //项目编码.项目编码
  1638. String r_recsettleorg_number = (String) h3yunService.getFieldValueById(
  1639. "D29365537feb4e5e8644b21b7fd938dd322dab3", bizData.getString("F0000025"), "F0000002");
  1640. receiveNotice.put("org_number", r_recsettleorg_number); // 收料组织.编码
  1641. String bizorg_number = (String) h3yunService.getFieldValueById(
  1642. "D29365537feb4e5e8644b21b7fd938dd322dab3", bizData.getString("F0000036"), "F0000002");
  1643. String bizorg_name = (String) h3yunService.getFieldValueById(
  1644. "D29365537feb4e5e8644b21b7fd938dd322dab3", bizData.getString("F0000036"), "F0000001");
  1645. receiveNotice.put("bizorg_number", bizorg_number);// 采购组织.编码
  1646. receiveNotice.put("bizorg_name", bizorg_name);// 采购组织.名称
  1647. receiveNotice.put("org_name", bizorg_name);//收料组织.名称
  1648. String currency_name = (String) h3yunService.getFieldValueById(
  1649. "D293655f08d8524a8254d35b3681ea527ce2c59", bizData.getString("F0000028"), "F0000002");
  1650. receiveNotice.put("currency_name", currency_name);//本位币.名称
  1651. receiveNotice.put("settlecurrency_name", currency_name);//结算币种.名称
  1652. String settlecurrency_number = (String) h3yunService.getFieldValueById(
  1653. "D293655f08d8524a8254d35b3681ea527ce2c59", bizData.getString("F0000028"), "F0000001"); //结算币种.货币代码
  1654. receiveNotice.put("settlecurrency_number", settlecurrency_number);//结算币种.货币代码
  1655. receiveNotice.put("currency_number", settlecurrency_number);//本位币.货币代码
  1656. receiveNotice.put("operatorgroup_name", "库管组");//库管组.名称
  1657. receiveNotice.put("operatorgroup_number", "KG-01");//库管组.编码
  1658. receiveNotice.put("billtype_name", "标准采购收料单");//单据类型.名称
  1659. receiveNotice.put("settletype_number", h3yunService.getFieldValueById(
  1660. "D293655skrwqen4wv0g7je4itf", bizData.getString("F0000050"), "F0000001"));//结算方式.编码
  1661. receiveNotice.put("settletype_name", h3yunService.getFieldValueById(
  1662. "D293655skrwqen4wv0g7je4itf", bizData.getString("F0000050"), "F0000002"));//结算方式.名称
  1663. receiveNotice.put("bizoperator_operatornumber", h3yunService.getFieldValueById(
  1664. "D2936556a05fbb0350545cc9d8bd70901b1ed3b", bizData.getString("F0000042"), "F0000001"));//采购员;
  1665. receiveNotice.put("invscheme_name", "普通采购收料待检入库");//库存事务.名称
  1666. receiveNotice.put("invscheme_number", "113");//库存事务.编码
  1667. receiveNotice.put("bizdept_name", "采购部");//采购部门.名称
  1668. receiveNotice.put("bizdept_number", "Org-00011");// 采购部门.编码
  1669. receiveNotice.put("dept_name", "采购部");//库管部门.名称
  1670. receiveNotice.put("dept_number", "Org-00011");// 库管部门.编码
  1671. receiveNotice.put("billtype_number", "im_purreceivebill_STD_BT_S"); // 单据类型.编码
  1672. // receiveNotice.put("billtype_name", "标准采购收料单");//单据类型.名称
  1673. // 物料明细
  1674. List<Map<String, Object>> entryList = new ArrayList<>();
  1675. JSONArray billentryArray = bizData.getJSONArray("D293655sjorvnmku3t3cpdup");
  1676. if (billentryArray != null && !billentryArray.isEmpty()) {
  1677. for (int i = 1; i <= billentryArray.size(); i++) {
  1678. JSONObject entryData = billentryArray.getJSONObject(i - 1);
  1679. Map<String, Object> entry = new LinkedHashMap<>();
  1680. String uuidHex = entryData.getString("ObjectId").replace("-", "");
  1681. // 取后16位(64bit),解析为无符号long,避免溢出和负数问题
  1682. long id = Long.parseUnsignedLong(uuidHex.substring(uuidHex.length() - 16), 16);
  1683. entry.put("id", id);
  1684. // entry.put("seq", i);
  1685. entry.put("qty", entryData.getDouble("F0000017")); // 数量
  1686. entry.put("baseqty", entryData.getDouble("F0000017")); // 物料明细.基本数量
  1687. entry.put("linetype_number", "010");
  1688. entry.put("discounttype", "NULL"); //物料明细.折扣方式 A:折扣率(%), B:单位折扣额, NULL:无
  1689. entry.put("ownertype", "bd_supplier");//物料明细.入库货主类型 bos_org:业务组织, bd_supplier:供应商, bd_customer:客户
  1690. entry.put("keepertype", "bos_org");//物料明细.入库保管者类型 bos_org:库存组织, bd_supplier:供应商, bd_customer:客户
  1691. entry.put("outownertype", "bd_supplier");//物料明细.出库货主库货主类型 bos_org:业务组织, bd_supplier:供应商, bd_customer:客户
  1692. entry.put("outkeepertype", "bos_org");//物料明细.出库保管者类型 bos_org:库存组织, bd_supplier:供应商, bd_customer:客户
  1693. entry.put("unit_number", h3yunService.getFieldValueById("D293655248b1d9bf6c448f0a291341ec58bb943", entryData.getString("F0000032"), "F0000001")); // 单位
  1694. entry.put("baseunit_number", h3yunService.getFieldValueById(
  1695. "D293655248b1d9bf6c448f0a291341ec58bb943", entryData.getString("F0000032"), "F0000001"));//基本单位.编码
  1696. entry.put("baseunit_name", h3yunService.getFieldValueById(
  1697. "D293655248b1d9bf6c448f0a291341ec58bb943", entryData.getString("F0000032"), "F0000002"));//基本单位.名称
  1698. // entry.put("price", entryData.getDouble("F0000043")); // 物料明细.单价
  1699. entry.put("priceandtax", entryData.getDouble("F0000043")); // 物料明细.含税单价
  1700. //entry.put("taxrate", entryData.getDouble("F0000016"));//物料明细.税率%
  1701. // entry.put("amount", entryData.getDouble("F0000018"));//物料明细.金额
  1702. // entry.put("amountandtax", entryData.getDouble("F0000018"));//物料明细.价税合计
  1703. // entry.put("taxamount", entryData.getDouble("F0000045"));//物料明细.税额
  1704. entry.put("purorderbillnumber", purorderbillnumber); //物料明细.采购订单号
  1705. // entry.put("project_number", project_number);//项目编码.项目编码invstatus_number
  1706. // entry.put("mpmtaskno_number", project_number);
  1707. ;//项目任务号.项目任务号
  1708. entry.put("invtype_number", "112");//入库库存类型.编码
  1709. entry.put("invstatus_number", "111");//入库库存状态.编码
  1710. entry.put("invtype_name", "供应商待检");//入库库存类型.名称
  1711. entry.put("invstatus_name", "待检");//入库库存状态.名称
  1712. // entry.put("location_number", "默认仓位");
  1713. entry.put("owner_number", h3yunService.getFieldValueById(
  1714. "D293655b4a0a34e44914aee9613a7bd3957df83", bizData.getString("F0000035"), "SeqNo")); // 入库货主.编码
  1715. entry.put("keeper_number", r_recsettleorg_number);// 入库保管者.编码
  1716. // entry.put("ecostcenter_number", h3yunService.getFieldValueById(
  1717. // "D293655swtap3brxkofsiqxb8q7", bizData.getString("F0000052"), "F0000001"));//成本中心.编码
  1718. entry.put("entrysettleorg_number", r_recsettleorg_number);//结算组织.编码
  1719. entry.put("entryreqorg_number", r_recsettleorg_number);//需求组织.编码
  1720. entry.put("outowner_number", h3yunService.getFieldValueById(
  1721. "D293655b4a0a34e44914aee9613a7bd3957df83", bizData.getString("F0000035"), "SeqNo"));//出库货主.编码
  1722. entry.put("outkeeper_number", r_recsettleorg_number);//出库保管者.编码
  1723. // entry.put("unit3rd_number", h3yunService.getFieldValueById(
  1724. // "D293655248b1d9bf6c448f0a291341ec58bb943", entryData.getString("F0000032"), "F0000001"));//辅助单位(2).编码
  1725. entry.put("purunit_number", h3yunService.getFieldValueById(
  1726. "D293655248b1d9bf6c448f0a291341ec58bb943", entryData.getString("F0000032"), "F0000001"));//采购单位.编码
  1727. entry.put("unit_number", h3yunService.getFieldValueById(
  1728. "D293655248b1d9bf6c448f0a291341ec58bb943", entryData.getString("F0000032"), "F0000001"));//库存单位.编码
  1729. entry.put("warehouse_number", h3yunService.getFieldValueById(
  1730. "D293655scvrhqr64jemxdkqk6gf", entryData.getString("F0000033"), "SeqNo"));//仓库
  1731. entry.put("taxrateid_number", h3yunService.getFieldValueById(
  1732. "D293655sl91vt6h8d0qg1heqw5aq", entryData.getString("F0000047"), "F0000001"));//税率.编码
  1733. entry.put("providersupplier_number", h3yunService.getFieldValueById(
  1734. "D293655b4a0a34e44914aee9613a7bd3957df83", bizData.getString("F0000035"), "SeqNo"));//订货供应商.编码
  1735. entry.put("invoicesupplier_number", h3yunService.getFieldValueById(
  1736. "D293655b4a0a34e44914aee9613a7bd3957df83", bizData.getString("F0000035"), "SeqNo"));//结算供应商.编码
  1737. entry.put("receivesupplier_number", h3yunService.getFieldValueById(
  1738. "D293655b4a0a34e44914aee9613a7bd3957df83", bizData.getString("F0000035"), "SeqNo"));//收款供应商.编码
  1739. entry.put("insporg_number", r_recsettleorg_number);//质检组织.编码
  1740. entry.put("material_masterid_number", h3yunService.getFieldValueById(
  1741. "D293655fc1a38f7956f400a886f376911a54a30", entryData.getString("F0000030"), "SeqNo"));//物料编码.编码
  1742. // entry.put("outkeeper_number", h3yunService.getFieldValueById(
  1743. // "D2936556a05fbb0350545cc9d8bd70901b1ed3b", entryData.getString("F0000051"), "F0000001"));//出库保管者.编码
  1744. //收料通知单关联采购订单
  1745. entry.put("srcbillentity", "pm_purorderbill");//物料明细.来源单据实体
  1746. entry.put("srcbillid", h3yunService.getFieldValueById(
  1747. "D2936559700b1d66a0e4ee69a84e13da8dbbe95", bizData.getString("F0000037"), "K3id"));//物料明细.来源单据ID
  1748. String uuidHexa = entryData.getString("F0000053").replace("-", "");
  1749. // 取后16位(64bit),解析为无符号long,避免溢出和负数问题
  1750. long ida = Long.parseUnsignedLong(uuidHexa.substring(uuidHexa.length() - 16), 16);
  1751. entry.put("srcbillentryid", ida);//物料明细.来源系统单据分录ID
  1752. entry.put("srcbillnumber", h3yunService.getFieldValueById(
  1753. "D2936559700b1d66a0e4ee69a84e13da8dbbe95", bizData.getString("F0000037"), "SeqNo"));//物料明细.来源单据编号
  1754. // entry.put("srcbillentryseq", i);//物料明细.来源单据分录序号 "1"
  1755. entry.put("mainbillentity", "pm_purorderbill");//物料明细.来源单据实体
  1756. entry.put("mainbillid", h3yunService.getFieldValueById(
  1757. "D2936559700b1d66a0e4ee69a84e13da8dbbe95", bizData.getString("F0000037"), "K3id"));//物料明细.来源单据ID
  1758. entry.put("mainbillentryid", ida);//物料明细.来源系统单据分录ID
  1759. entry.put("mainbillnumber", h3yunService.getFieldValueById(
  1760. "D2936559700b1d66a0e4ee69a84e13da8dbbe95", bizData.getString("F0000037"), "SeqNo"));//物料明细.来源单据编号
  1761. // entry.put("srcsystem", "8upAr");
  1762. // entry.put("srcsysbillid", "pt08C");
  1763. // entry.put("srcsysbillentryid", "sYtFo");
  1764. // entry.put("srcsysbillno", "DyiB7");//物料明细.来源单据编号
  1765. List<Map<String, Object>> lkList = new ArrayList<>();
  1766. Map<String, Object> lkEntry = new LinkedHashMap<>();
  1767. lkEntry.put("billentry_lk_stableid", "602924326097811460");
  1768. lkEntry.put("billentry_lk_sbillid", h3yunService.getFieldValueById(
  1769. "D2936559700b1d66a0e4ee69a84e13da8dbbe95", bizData.getString("F0000037"), "K3id"));
  1770. lkEntry.put("billentry_lk_sid", ida);
  1771. lkList.add(lkEntry);
  1772. entry.put("billentry_lk", lkList);
  1773. entryList.add(entry);
  1774. }
  1775. }
  1776. receiveNotice.put("billentry", entryList);
  1777. dataList.add(receiveNotice);
  1778. data.put("data", dataList);
  1779. return data;
  1780. }
  1781. /**
  1782. * 提取采购退料申请数据(金蝶API格式)
  1783. * 返回格式: {"data":[{"billno":"...","supplier_number":"...","purreturnentry":[...]}]}
  1784. */
  1785. @SuppressWarnings("unchecked")
  1786. private Map<String, Object> extractPurchaseReturnData(JSONObject bizData) {
  1787. Map<String, Object> data = new HashMap<>();
  1788. List<Map<String, Object>> dataList = new ArrayList<>();
  1789. Map<String, Object> returnRequest = new LinkedHashMap<>();
  1790. // 头部信息
  1791. returnRequest.put("billno", bizData.getString("SeqNo")); // 单据编号
  1792. returnRequest.put("trdbillno", bizData.getString("SeqNo")); // 单据编号
  1793. returnRequest.put("org_number", bizData.getString("F0000049")); // 采购组织编码
  1794. returnRequest.put("billtype_number", bizData.getString("F0000023")); // 单据类型.编码
  1795. returnRequest.put("biztype_number", bizData.getString("F0000022")); // 业务类型.编码
  1796. returnRequest.put("supplier_number", bizData.getString("F0000050")); // 订货供应商.编码
  1797. String paymodeValue = bizData.getString("F0000055");// 付款方式 CASH:现购, CREDIT:赊购
  1798. if ("现购".equals(paymodeValue)) {
  1799. returnRequest.put("paymode", "CASH");
  1800. } else if ("赊购".equals(paymodeValue)) {
  1801. returnRequest.put("paymode", "CREDIT");
  1802. } else {
  1803. returnRequest.put("paymode", paymodeValue); // 其他值原样传递
  1804. }
  1805. returnRequest.put("settlecurrency_number", bizData.getString("F0000057")); // 结算币别.货币代码
  1806. returnRequest.put("exratetable_number", "ERT-01"); // 汇率表.编码
  1807. returnRequest.put("exchangerate", "1"); // 汇率
  1808. returnRequest.put("biztime", formatDate(bizData.getString("F0000024"))); // 申请日期
  1809. returnRequest.put("comment", bizData.getString("F0000054")); // 备注
  1810. // 分录信息 purreturnentry
  1811. List<Map<String, Object>> entryList = new ArrayList<>();
  1812. JSONArray billentryArray = bizData.getJSONArray("D293655slxu6vngtqkcopxf6fl");
  1813. if (billentryArray != null && !billentryArray.isEmpty()) {
  1814. for (int i = 0; i < billentryArray.size(); i++) {
  1815. JSONObject entryData = billentryArray.getJSONObject(i);
  1816. Map<String, Object> entry = new LinkedHashMap<>();
  1817. entry.put("linetype_number", "010");
  1818. String returnmaterialtype = entryData.getString("F0000046");
  1819. if ("退料".equals(returnmaterialtype)) {
  1820. entry.put("returnmaterialtype", "1");
  1821. } else if ("退补料".equals(returnmaterialtype)) {
  1822. entry.put("returnmaterialtype", "2");
  1823. }
  1824. entry.put("discounttype", "NULL"); // 物料明细.折扣方式 A:折扣率(%), B:单位折扣额, NULL:无
  1825. entry.put("qty", entryData.getDouble("F0000060")); // 退料数量
  1826. entry.put("material_number", entryData.getString("F0000031")); // 商品编码
  1827. entry.put("unit_number", entryData.getString("F0000058")); // 采购单位.编码
  1828. entry.put("entryinvcorg_number", bizData.getString("F0000049")); // 库存组织.编码
  1829. entry.put("entrysettleorg_number", bizData.getString("F0000049")); // 库存组织.编码
  1830. entry.put("entryreqorg_number", bizData.getString("F0000049")); // 库存组织.编码
  1831. //退料申请单关联采购入库单
  1832. entry.put("srcbillentity", "im_purinbill");//物料明细.来源单据实体
  1833. entry.put("srcbillid", h3yunService.getFieldValueById(
  1834. "D293655srqj5uui3keso9oraeqm", bizData.getString("F0000044"), "F0000038"));//物料明细.来源单据ID
  1835. entry.put("srcbillnumber", h3yunService.getFieldValueById(
  1836. "D293655srqj5uui3keso9oraeqm", bizData.getString("F0000044"), "F0000041"));//物料明细.来源单据编号
  1837. long ida = Long.parseUnsignedLong(entryData.getString("F0000061"));
  1838. entry.put("srcbillentryid", ida);//物料明细.来源系统单据分录ID
  1839. entry.put("mainbillentity", "im_purinbill");
  1840. entry.put("mainbillid", h3yunService.getFieldValueById(
  1841. "D293655srqj5uui3keso9oraeqm", bizData.getString("F0000044"), "F0000038"));
  1842. entry.put("mainbillnumber", ida);
  1843. entry.put("mainbillentryid", h3yunService.getFieldValueById(
  1844. "D293655srqj5uui3keso9oraeqm", bizData.getString("F0000044"), "F0000041"));//物料明细.来源单据编号
  1845. entry.put("price", entryData.getDouble("F0000066"));//单价
  1846. entry.put("priceandtax", entryData.getDouble("F0000066"));//含税单价
  1847. entry.put("taxrateid_number", h3yunService.getFieldValueById(
  1848. "D293655sl91vt6h8d0qg1heqw5aq", entryData.getString("F0000065"), "F0000001"));//F0000065
  1849. List<Map<String, Object>> lkList = new ArrayList<>();
  1850. Map<String, Object> lkEntry = new LinkedHashMap<>();
  1851. lkEntry.put("billentry_lk_stableid", "602924315385558018");
  1852. lkEntry.put("billentry_lk_sbillid", h3yunService.getFieldValueById(
  1853. "D293655srqj5uui3keso9oraeqm", bizData.getString("F0000044"), "F0000038"));
  1854. lkEntry.put("billentry_lk_sid", ida);
  1855. lkList.add(lkEntry);
  1856. entry.put("billentry_lk", lkList);
  1857. entryList.add(entry);
  1858. }
  1859. }
  1860. returnRequest.put("billentry", entryList);
  1861. dataList.add(returnRequest);
  1862. data.put("data", dataList);
  1863. return data;
  1864. }
  1865. /**
  1866. * 提取发货通知单数据(金蝶API格式)
  1867. * 返回格式: {"data":[{"billno":"...","customer_number":"...","deliverynoticeentry":[...]}]}
  1868. */
  1869. @SuppressWarnings("unchecked")
  1870. private Map<String, Object> extractDeliveryNoticeData(JSONObject bizData) {
  1871. Map<String, Object> data = new HashMap<>();
  1872. List<Map<String, Object>> dataList = new ArrayList<>();
  1873. Map<String, Object> deliveryNotice = new LinkedHashMap<>();
  1874. // 头部信息
  1875. deliveryNotice.put("billno", bizData.getString("SeqNo")); // 单据编号
  1876. // deliveryNotice.put("trdbillno", bizData.getString("SeqNo"));
  1877. deliveryNotice.put("deliverorg_number", h3yunService.getFieldValueById(
  1878. "D29365537feb4e5e8644b21b7fd938dd322dab3", bizData.getString("F0000018"), "F0000002")); // 发货组织.编码
  1879. deliveryNotice.put("billtype_number", "sm_delivernotice_STD_BT_S"); // 单据类型.编码
  1880. deliveryNotice.put("bizdate", formatDate(bizData.getString("F0000021"))); // 通知日期
  1881. deliveryNotice.put("customer_number", h3yunService.getFieldValueById(
  1882. "D293655shuyz9ttzgkgmhaa4rglr", bizData.getString("F0000024"), "SeqNo")); // 订货客户.编码
  1883. deliveryNotice.put("org_number", h3yunService.getFieldValueById(
  1884. "D29365537feb4e5e8644b21b7fd938dd322dab3", bizData.getString("F0000049"), "F0000002")); // 销售组织.编码
  1885. deliveryNotice.put("al95_customer_number", h3yunService.getFieldValueById(//店铺.编码
  1886. "D293655shuyz9ttzgkgmhaa4rglr", bizData.getString("F0000023"), "SeqNo"));
  1887. deliveryNotice.put("al95_customer_name", h3yunService.getFieldValueById(//店铺.名称
  1888. "D293655shuyz9ttzgkgmhaa4rglr", bizData.getString("F0000023"), "F0000001"));
  1889. deliveryNotice.put("al95_assistantfield_number", h3yunService.getFieldValueById(//物流公司.编码
  1890. "D293655sdfmyisqk1us9gqj1bljt", bizData.getString("F0000053"), "F0000001"));
  1891. deliveryNotice.put("al95_assistantfield_name", h3yunService.getFieldValueById(//物流公司.名称
  1892. "D293655sdfmyisqk1us9gqj1bljt", bizData.getString("F0000053"), "F0000001"));
  1893. deliveryNotice.put("al95_textfield2", bizData.getString("F0000060"));//收货人联系电话
  1894. deliveryNotice.put("al95_textfield1", bizData.getString("F0000058"));//收货人
  1895. deliveryNotice.put("al95_textfield", bizData.getString("F0000059"));//收货人地址
  1896. deliveryNotice.put("reccondition_number", h3yunService.getFieldValueById(//物流公司.名称
  1897. "D293655sv6bv8bozikwrkze3rk1", bizData.getString("F0000067"), "F0000001"));//收款条件.编号
  1898. // deliveryNotice.put("saleser_number", bizData.getString("F0000007")); // 销售员
  1899. // deliveryNotice.put("srcbillno", bizData.getString("F0000008")); // 源单编号
  1900. // deliveryNotice.put("comment", bizData.getString("F0000009")); // 备注
  1901. // deliveryNotice.put("operator_operatornumber", bizData.getString("CreatedBy")); // 操作人
  1902. // 分录信息 deliverynoticeentry
  1903. List<Map<String, Object>> entryList = new ArrayList<>();
  1904. JSONArray billentryArray = bizData.getJSONArray("D293655sbvihadlhlkeoi30zoi8n");
  1905. if (billentryArray != null && !billentryArray.isEmpty()) {
  1906. for (int i = 0; i < billentryArray.size(); i++) {
  1907. JSONObject entryData = billentryArray.getJSONObject(i);
  1908. Map<String, Object> entry = new LinkedHashMap<>();
  1909. entry.put("qty", entryData.getDouble("F0000031")); // 数量
  1910. entry.put("producttype", "standard");//物料明细.产品类别 standard:标准产品, kitparent:套件父项, kitchild:套件子项
  1911. entry.put("linetype_number", "010"); // 物料编码
  1912. entry.put("deliverydate1", formatDate(entryData.getString("F0000052")));//物料明细.要货日期
  1913. entry.put("material_number", h3yunService.getFieldValueById(
  1914. "D293655fc1a38f7956f400a886f376911a54a30", entryData.getString("F0000027"), "SeqNo"));//物料编码.编码
  1915. entry.put("unit_number", h3yunService.getFieldValueById(
  1916. "D293655248b1d9bf6c448f0a291341ec58bb943", entryData.getString("F0000030"), "F0000001"));//单位编码.编码
  1917. entry.put("warehouse_number", h3yunService.getFieldValueById(
  1918. "D293655scvrhqr64jemxdkqk6gf", entryData.getString("F0000061"), "SeqNo"));//仓库.编码
  1919. entry.put("price", entryData.getDouble("F0000062"));//
  1920. entry.put("priceandtax", entryData.getDouble("F0000062"));//
  1921. entry.put("discounttype", "NULL");
  1922. //发货通知单关联销售订单
  1923. String uuidHex = entryData.getString("F0000054").replace("-", "");
  1924. long ida = Long.parseUnsignedLong(uuidHex.substring(uuidHex.length() - 16), 16);
  1925. entry.put("srcbillentity", "sm_salorder");//物料明细.来源单据实体
  1926. entry.put("srcbillid", h3yunService.getFieldValueById(
  1927. "D29365523b214414c2b4e50b9bdca110a9a5951", bizData.getString("F0000050"), "K3id"));//物料明细.来源单据ID
  1928. entry.put("srcbillnumber", h3yunService.getFieldValueById(
  1929. "D29365523b214414c2b4e50b9bdca110a9a5951", bizData.getString("F0000050"), "SeqNo"));//物料明细.来源单据编号
  1930. entry.put("srcbillentryid", ida);//物料明细.来源系统单据分录ID
  1931. entry.put("mainbillentity", "sm_salorder");
  1932. entry.put("mainbillid", h3yunService.getFieldValueById(
  1933. "D29365523b214414c2b4e50b9bdca110a9a5951", bizData.getString("F0000050"), "K3id"));
  1934. entry.put("mainbillentryid", ida);
  1935. entry.put("mainbillnumber", h3yunService.getFieldValueById(
  1936. "D29365523b214414c2b4e50b9bdca110a9a5951", bizData.getString("F0000050"), "SeqNo"));//物料明细.来源单据编号
  1937. List<Map<String, Object>> lkList = new ArrayList<>();
  1938. Map<String, Object> lkEntry = new LinkedHashMap<>();
  1939. lkEntry.put("billentry_lk_stableid", "602924332909361155");
  1940. lkEntry.put("billentry_lk_sbillid", h3yunService.getFieldValueById(
  1941. "D29365523b214414c2b4e50b9bdca110a9a5951", bizData.getString("F0000050"), "K3id"));
  1942. lkEntry.put("billentry_lk_sid", ida);
  1943. lkList.add(lkEntry);
  1944. entry.put("billentry_lk", lkList);
  1945. //
  1946. // entry.put("deliverydate", formatDate(entryData.getString("F0000014"))); // 交货日期
  1947. // entry.put("deliveryaddress", entryData.getString("F0000015")); // 交货地址
  1948. // entry.put("warehouse_number", entryData.getString("F0000016")); // 仓库
  1949. // entry.put("entrycomment", entryData.getString("F0000017")); // 分录备注
  1950. entryList.add(entry);
  1951. }
  1952. }
  1953. deliveryNotice.put("billentry", entryList);
  1954. dataList.add(deliveryNotice);
  1955. data.put("data", dataList);
  1956. return data;
  1957. }
  1958. /**
  1959. * 提取退货申请单数据(金蝶API格式)
  1960. * 返回格式: {"data":[{"billno":"...","customer_number":"...","returnrequestentry":[...]}]}
  1961. */
  1962. @SuppressWarnings("unchecked")
  1963. private Map<String, Object> extractReturnRequestData(JSONObject bizData) {
  1964. Map<String, Object> data = new HashMap<>();
  1965. List<Map<String, Object>> dataList = new ArrayList<>();
  1966. Map<String, Object> returnRequest = new LinkedHashMap<>();
  1967. // 头部信息
  1968. returnRequest.put("billno", bizData.getString("SeqNo")); // 单据编号
  1969. returnRequest.put("trdbillno", bizData.getString("SeqNo")); // 单据编号
  1970. returnRequest.put("billtype_number", "sm_returnapply_BT_S"); // 单据类型.编码
  1971. returnRequest.put("bizdate", formatDate(bizData.getString("F0000021"))); // 申请日期
  1972. returnRequest.put("org_number", h3yunService.getFieldValueById(
  1973. "D29365537feb4e5e8644b21b7fd938dd322dab3", bizData.getString("F0000018"), "F0000002")); // 销售组织.编码
  1974. returnRequest.put("biztype_number", "2101"); //业务类型.编码 物料类销售退货-2101
  1975. returnRequest.put("settlecurrency_number", h3yunService.getFieldValueById(
  1976. "D293655f08d8524a8254d35b3681ea527ce2c59", bizData.getString("F0000025"), "F0000001")); // 结算币别.货币代码
  1977. returnRequest.put("customer_number", h3yunService.getFieldValueById(
  1978. "D293655shuyz9ttzgkgmhaa4rglr", bizData.getString("F0000024"), "SeqNo")); //退货客户.编码
  1979. // returnRequest.put("reason", bizData.getString("F0000008")); // 退货原因
  1980. // returnRequest.put("comment", bizData.getString("F0000009")); // 备注
  1981. // returnRequest.put("operator_operatornumber",
  1982. returnRequest.put("al95_assistantfield_number", h3yunService.getFieldValueById(
  1983. "D293655sdfmyisqk1us9gqj1bljt", bizData.getString("F0000063"), "F0000001")); //物流公司.编码
  1984. returnRequest.put("al95_assistantfield_name", h3yunService.getFieldValueById(
  1985. "D293655sdfmyisqk1us9gqj1bljt", bizData.getString("F0000063"), "F0000011"));//物流公司.名称
  1986. returnRequest.put("al95_customer_number", h3yunService.getFieldValueById(
  1987. "D293655shuyz9ttzgkgmhaa4rglr", bizData.getString("F0000023"), "SeqNo")); //退货店铺.编码
  1988. returnRequest.put("al95_customer_name", h3yunService.getFieldValueById(
  1989. "D293655shuyz9ttzgkgmhaa4rglr", bizData.getString("F0000023"), "F0000001"));// 退货店铺.名称
  1990. // 分录信息 returnrequestentry
  1991. List<Map<String, Object>> entryList = new ArrayList<>();
  1992. JSONArray billentryArray = bizData.getJSONArray("D293655svwzidlwioks0vvylbsxl");
  1993. if (billentryArray != null && !billentryArray.isEmpty()) {
  1994. for (int i = 0; i < billentryArray.size(); i++) {
  1995. JSONObject entryData = billentryArray.getJSONObject(i);
  1996. Map<String, Object> entry = new LinkedHashMap<>();
  1997. // entry.put("id", entryData.getString("ObjectId").replace("-", ""));//id
  1998. String uuidHex = entryData.getString("ObjectId").replace("-", "");
  1999. // 取后16位(64bit),解析为无符号long,避免溢出和负数问题
  2000. long id = Long.parseUnsignedLong(uuidHex.substring(uuidHex.length() - 16), 16);
  2001. entry.put("id", id);
  2002. entry.put("qty", entryData.getDouble("F0000031")); // 数量
  2003. entry.put("linetype_number", entryData.getString("F0000026")); // 行类型-物资编码
  2004. entry.put("material_number", h3yunService.getFieldValueById(
  2005. "D293655fc1a38f7956f400a886f376911a54a30", entryData.getString("F0000027"), "SeqNo")); // 物料编码.编码
  2006. entry.put("unit_number", h3yunService.getFieldValueById(
  2007. "D293655248b1d9bf6c448f0a291341ec58bb943", entryData.getString("F0000030"), "F0000001")); //销售单位.编码
  2008. entry.put("entryinvorg_number", h3yunService.getFieldValueById(
  2009. "D29365537feb4e5e8644b21b7fd938dd322dab3", bizData.getString("F0000049"), "F0000002")); // 库存组织.编码
  2010. entry.put("entrysettleorg_number", h3yunService.getFieldValueById(
  2011. "D29365537feb4e5e8644b21b7fd938dd322dab3", bizData.getString("F0000049"), "F0000002")); // 结算组织.编码
  2012. entry.put("al95_", entryData.getString("F0000069"));//物料明细.明细-订单号
  2013. entry.put("al95_1", entryData.getString("F0000068"));
  2014. ;//物料明细.明细-原始单号
  2015. //退货申请单关联销售出库单
  2016. entry.put("srcbillentity", "im_saloutbill");//物料明细.来源单据实体
  2017. entry.put("srcbillid", h3yunService.getFieldValueById(
  2018. "D293655suomjudbplkoxrgs42dqj", bizData.getString("F0000058"), "K3id"));//物料明细.来源单据ID
  2019. entry.put("srcbillnumber", h3yunService.getFieldValueById(
  2020. "D293655suomjudbplkoxrgs42dqj", bizData.getString("F0000058"), "F0000053"));//物料明细.来源单据编号
  2021. long ida = Long.parseUnsignedLong(entryData.getString("F0000064"));
  2022. entry.put("srcbillentryid", ida);//物料明细.来源系统单据分录ID
  2023. entry.put("mainbillentity", "im_saloutbill");
  2024. entry.put("mainbillid", h3yunService.getFieldValueById(
  2025. "D293655suomjudbplkoxrgs42dqj", bizData.getString("F0000058"), "K3id"));
  2026. entry.put("mainbillnumber", ida);
  2027. entry.put("mainbillentryid", h3yunService.getFieldValueById(
  2028. "D293655suomjudbplkoxrgs42dqj", bizData.getString("F0000058"), "F0000053"));//物料明细.来源单据编号
  2029. List<Map<String, Object>> lkList = new ArrayList<>();
  2030. Map<String, Object> lkEntry = new LinkedHashMap<>();
  2031. lkEntry.put("billentry_lk_stableid", "602924300688717826");
  2032. lkEntry.put("billentry_lk_sbillid", h3yunService.getFieldValueById(
  2033. "D293655suomjudbplkoxrgs42dqj", bizData.getString("F0000058"), "K3id"));
  2034. lkEntry.put("billentry_lk_sid", ida);
  2035. lkList.add(lkEntry);
  2036. entry.put("billentry_lk", lkList);
  2037. entryList.add(entry);
  2038. }
  2039. }
  2040. returnRequest.put("billentry", entryList);
  2041. dataList.add(returnRequest);
  2042. data.put("data", dataList);
  2043. return data;
  2044. }
  2045. /**
  2046. * 提取付款申请单数据(金蝶API格式)
  2047. * 返回格式: {"data":[{"billno":"...","payerorg_number":"...","cn_payableentry":[...]}]}
  2048. */
  2049. @SuppressWarnings("unchecked")
  2050. private Map<String, Object> extractPaymentRequestData(JSONObject bizData) {
  2051. Map<String, Object> data = new HashMap<>();
  2052. List<Map<String, Object>> dataList = new ArrayList<>();
  2053. Map<String, Object> paymentRequest = new LinkedHashMap<>();
  2054. // 头部信息
  2055. paymentRequest.put("billno", bizData.getString("SeqNo")); // 单据编号
  2056. paymentRequest.put("trdbillno", bizData.getString("SeqNo"));//第三方业务编码(防止重复新增,每次新增需要传入唯一值)
  2057. paymentRequest.put("bizdate", formatDate(bizData.getString("F0000016"))); // 业务日期
  2058. // paymentRequest.put("applydate", formatDate(bizData.getString("F0000037"))); // 申请日期
  2059. paymentRequest.put("payeetype", "bd_supplier"); // 收款单位类型:bos_org:公司,bd_supplier:供应商,bd_customer:客户,bos_user:人员,other:其他,cas_ot\
  2060. paymentRequest.put("itempayeetype", "bd_supplier"); // 收款单位类型(多类别基础资料类型):bos_org:公司,bd_supplier:供应商,bd_customer:客户,bos_user:人员,cas_other:其他,cas_othercontactunit:其他往来单位
  2061. paymentRequest.put("billtype_number", "cas_paybill_pur_BT_S");//单据类型.编码
  2062. // paymentRequest.put("applyorg_number", h3yunService.getFieldValueById(
  2063. // "D29365537feb4e5e8644b21b7fd938dd322dab3", bizData.getString("F0000014"), "F0000002"));//结算组织.编码
  2064. paymentRequest.put("settleorg_number", h3yunService.getFieldValueById(
  2065. "D29365537feb4e5e8644b21b7fd938dd322dab3", bizData.getString("F0000019"), "F0000002"));//结算组织.编码
  2066. paymentRequest.put("currency_number", h3yunService.getFieldValueById(
  2067. "D293655f08d8524a8254d35b3681ea527ce2c59", bizData.getString("F0000031"), "F0000001"));//付款币别.id
  2068. paymentRequest.put("payeebanknum", h3yunService.getFieldValueById(
  2069. "D293655Fb2deb81ad33c41e4bac91630e399d141", bizData.getString("F0000042"), "F0000027"));//收款账号
  2070. paymentRequest.put("usage", bizData.getString("F0000043"));//转账附言
  2071. String exratetable_number = bizData.getString("F0000038");
  2072. if ("预算汇率".equals(exratetable_number)) {
  2073. exratetable_number = "BMERT-01_SYS";
  2074. } else {
  2075. exratetable_number = "ERT-01";
  2076. }
  2077. paymentRequest.put("exratetable_number", exratetable_number);
  2078. paymentRequest.put("payeenumber", h3yunService.getFieldValueById(
  2079. "D293655b4a0a34e44914aee9613a7bd3957df83", bizData.getString("F0000002"), "SeqNo"));//收款单位编码
  2080. paymentRequest.put("itempayee_number", h3yunService.getFieldValueById(
  2081. "D293655b4a0a34e44914aee9613a7bd3957df83", bizData.getString("F0000002"), "SeqNo"));//收款单位.编码
  2082. paymentRequest.put("actpayamt", bizData.getDouble("F0000012")); // 付款金额
  2083. paymentRequest.put("paymentidentify_id", "1307961534361723904");//FKBS01
  2084. paymentRequest.put("exchangerate", "1");//付款汇率
  2085. paymentRequest.put("settletype_number", h3yunService.getFieldValueById(
  2086. "D293655skrwqen4wv0g7je4itf", bizData.getString("F0000028"), "F0000001"));//结算方式.编码
  2087. // paymentRequest.put("settlecurrency_number", h3yunService.getFieldValueById(
  2088. // "D293655f08d8524a8254d35b3681ea527ce2c59", bizData.getString("F0000031"), "F0000001"));//结算币别.货币代码
  2089. // paymentRequest.put("paycurrency_number", h3yunService.getFieldValueById(
  2090. // "D293655f08d8524a8254d35b3681ea527ce2c59", bizData.getString("F0000031"), "F0000001"));//付款币别.货币代码
  2091. //
  2092. paymentRequest.put("description", bizData.getString("F0000018")); // 摘要-备注
  2093. //
  2094. // paymentRequest.put("supplier_number", bizData.getString("F0000004")); // 供应商编码
  2095. //
  2096. //
  2097. // paymentRequest.put("paymode", bizData.getString("F0000007")); // 付款方式
  2098. // paymentRequest.put("bank_number", bizData.getString("F0000008")); // 银行编码
  2099. // paymentRequest.put("bankaccount", bizData.getString("F0000009")); // 银行账号
  2100. // paymentRequest.put("comment", bizData.getString("F0000010")); // 备注
  2101. // paymentRequest.put("operator_operatornumber", bizData.getString("CreatedBy")); // 操作人
  2102. // 分录信息 cn_payableentry
  2103. List<Map<String, Object>> entryList = new ArrayList<>();
  2104. JSONArray billentryArray = bizData.getJSONArray("D293655F51615cc524e746388f8ac7fe290b57a3");
  2105. if (billentryArray != null && !billentryArray.isEmpty()) {
  2106. for (int i = 0; i < billentryArray.size(); i++) {
  2107. JSONObject entryData = billentryArray.getJSONObject(i);
  2108. Map<String, Object> entry = new LinkedHashMap<>();
  2109. // entry.put("id", i);
  2110. // entry.put("e_paymenttype_number", "180908615723421696"); // 付款用途.id
  2111. entry.put("e_paymenttype_number", "201"); // 付款用途.编码
  2112. entry.put("e_actamt", entryData.getDouble("F0000024")); // 分录.实付金额
  2113. entry.put("e_payableamt", entryData.getDouble("F0000024"));//分录.应付金额
  2114. // entry.put("taxrate", h3yunService.getFieldValueById(
  2115. // "D293655sl91vt6h8d0qg1heqw5aq", entryData.getString("F0000044"), "F0000001"));//分录.税率(%)
  2116. entry.put("taxrate", entryData.getDouble("F0000029"));//分录.税率(%)
  2117. entry.put("taxamt", entryData.getDouble("F0000030"));//分录.税额
  2118. entry.put("expectdate", formatDate(entryData.getString("F0000026")));//期望付款日期
  2119. String uuidHex = entryData.getString("F0000034").replace("-", "");
  2120. long id = Long.parseUnsignedLong(uuidHex.substring(uuidHex.length() - 16), 16);
  2121. if ("货到付款".equals(bizData.getString("F0000032"))) {
  2122. List<Map<String, Object>> lkList = new ArrayList<>();
  2123. Map<String, Object> lkEntry = new LinkedHashMap<>();
  2124. lkEntry.put("entry_lk_stableid", "577639813562251264");
  2125. lkEntry.put("entry_lk_sbillid", h3yunService.getFieldValueById(
  2126. "D293655sykmx68818kivnjmwwgus", bizData.getString("F0000001"), "K3id"));
  2127. lkEntry.put("entry_lk_sid", id);
  2128. lkList.add(lkEntry);
  2129. entry.put("entry_lk", lkList);
  2130. } else if ("预付款".equals(bizData.getString("F0000032"))) {
  2131. entry.put("e_corebilltype", "pm_purorderbill");//分录.核心单据类型 sctm_scpo:委外采购订单, ec_contract:建筑支出合同, conm_salcontract:销售合同, er_dailyloanbill:借款单, conm_purcontract:采购合同, sm_salorder:销售订单, pm_purorderbill:采购订单
  2132. entry.put("e_corebilltype_title", "采购订单");//固定
  2133. entry.put("e_corebillentryseq", 0);//固定
  2134. entry.put("e_corebillno", h3yunService.getFieldValueById(
  2135. "D2936559700b1d66a0e4ee69a84e13da8dbbe95", bizData.getString("F0000033"), "SeqNo"));//采购订单编号
  2136. entry.put("e_corebillid", h3yunService.getFieldValueById(
  2137. "D2936559700b1d66a0e4ee69a84e13da8dbbe95", bizData.getString("F0000033"), "K3id"));//采购订单主表ID
  2138. entry.put("e_corebillentryid", id);//采购订单明细ID
  2139. List<Map<String, Object>> lkList = new ArrayList<>();
  2140. Map<String, Object> lkEntry = new LinkedHashMap<>();
  2141. lkEntry.put("entry_lk_stableid", "602924326097811460");
  2142. lkEntry.put("entry_lk_sbillid", h3yunService.getFieldValueById(
  2143. "D2936559700b1d66a0e4ee69a84e13da8dbbe95", bizData.getString("F0000033"), "K3id"));
  2144. lkEntry.put("entry_lk_sid", id);
  2145. lkList.add(lkEntry);
  2146. entry.put("entry_lk", lkList);
  2147. }
  2148. // entry.put("e_asstacttype", "bd_supplier");//明细.往来单位类型 bd_supplier:供应商, bos_user:人员, bos_org:公司, bd_customer:客户, cas_othercontactunit:其他往来单位
  2149. // entry.put("e_asstact_number", h3yunService.getFieldValueById(
  2150. // "D293655b4a0a34e44914aee9613a7bd3957df83", bizData.getString("F0000002"), "SeqNo"));//明细.往来单位
  2151. // entry.put("e_rectunittype", "bd_supplier");//明细.往来单位类型 bd_supplier:供应商, bos_user:人员, bos_org:公司, bd_customer:客户, cas_othercontactunit:其他往来单位
  2152. // entry.put("e_rectunit_number", h3yunService.getFieldValueById(
  2153. // "D293655b4a0a34e44914aee9613a7bd3957df83", bizData.getString("F0000002"), "SeqNo"));//明细.往来单位
  2154. // entry.put("e_appseleamount", entryData.getDouble("F0000024"));//明细.申请金额
  2155. // entry.put("e_approvedseleamt", entryData.getDouble("F0000024"));//明细.核准金额
  2156. // String uuidHex = entryData.getString("F0000034").replace("-", "");
  2157. // long id = Long.parseUnsignedLong(uuidHex.substring(uuidHex.length() - 16), 16);
  2158. // if ("货到付款".equals(bizData.getString("F0000032"))) {
  2159. // List<Map<String, Object>> lkList = new ArrayList<>();
  2160. // Map<String, Object> lkEntry = new LinkedHashMap<>();
  2161. // lkEntry.put("entry_lk_stableid", "577639813562251264");
  2162. //
  2163. // lkEntry.put("entry_lk_sbillid", h3yunService.getFieldValueById("D293655sykmx68818kivnjmwwgus", bizData.getString("F0000074"), "K3id"));//
  2164. // lkEntry.put("entry_lk_sid", id);//
  2165. //
  2166. // lkList.add(lkEntry);
  2167. // entry.put("entry_lk", lkList);
  2168. // entry.put("e_corebilltype", "pm_purorderbill");
  2169. // entry.put("e_corebillno",h3yunService.getFieldValueById("D2936559700b1d66a0e4ee69a84e13da8dbbe95", bizData.getString("F0000001"), "K3id"));
  2170. //
  2171. // } else if ("预付款".equals(bizData.getString("F0000032"))) {
  2172. // List<Map<String, Object>> lkList = new ArrayList<>();
  2173. // Map<String, Object> lkEntry = new LinkedHashMap<>();
  2174. // lkEntry.put("entry_lk_stableid", "602924326097811460");
  2175. // lkEntry.put("entry_lk_sbillid", h3yunService.getFieldValueById("D2936559700b1d66a0e4ee69a84e13da8dbbe95", bizData.getString("F0000001"), "K3id"));//
  2176. // lkEntry.put("entry_lk_sid", id);//
  2177. //
  2178. // lkList.add(lkEntry);
  2179. // entry.put("entry_lk", lkList);
  2180. // entry.put("e_corebilltype", "pm_purorderbill");
  2181. // entry.put("e_corebillno",h3yunService.getFieldValueById("D2936559700b1d66a0e4ee69a84e13da8dbbe95", bizData.getString("F0000033"), "SeqNo"));
  2182. // }
  2183. entryList.add(entry);
  2184. }
  2185. }
  2186. paymentRequest.put("entry", entryList);
  2187. dataList.add(paymentRequest);
  2188. data.put("data", dataList);
  2189. return data;
  2190. }
  2191. /**
  2192. * 提取财务应付单数据(金蝶API格式)
  2193. * 返回格式: {"data":[{"billno":"...","supplier_number":"...","ap_payableentry":[...]}]}
  2194. */
  2195. @SuppressWarnings("unchecked")
  2196. private Map<String, Object> extractPayableBillData(JSONObject bizData) {
  2197. Map<String, Object> data = new HashMap<>();
  2198. List<Map<String, Object>> dataList = new ArrayList<>();
  2199. Map<String, Object> payableBill = new LinkedHashMap<>();
  2200. // ========== 头部信息 ==========
  2201. payableBill.put("billno", bizData.getString("SeqNo")); // 单据编号
  2202. payableBill.put("trdbillno", bizData.getString("SeqNo"));//第三方业务编码(防止重复新增,每次新增需要传入唯一值)
  2203. payableBill.put("billtypeid_number", bizData.getString("F0000019")); // 单据类型编码
  2204. // 结算组织(复用查询结果)
  2205. String settleOrgNumber = (String) h3yunService.getFieldValueById(
  2206. "D29365537feb4e5e8644b21b7fd938dd322dab3", bizData.getString("F0000018"), "F0000002");
  2207. payableBill.put("org_number", settleOrgNumber);
  2208. payableBill.put("isincludetax", true);//录入含税单价
  2209. // 付款组织
  2210. String payOrgNumber = (String) h3yunService.getFieldValueById(
  2211. "D29365537feb4e5e8644b21b7fd938dd322dab3", bizData.getString("F0000049"), "F0000002");
  2212. payableBill.put("payorg_number", payOrgNumber);
  2213. payableBill.put("bizdate", formatDate(bizData.getString("F0000021"))); // 业务日期
  2214. payableBill.put("bookdate", formatDate(bizData.getString("F0000048"))); // 记账日期
  2215. // ========== 付款计划分录 planentity(先处理以获取最大日期) ==========
  2216. List<Map<String, Object>> recPlanList = new ArrayList<>();
  2217. JSONArray recplanentryArray = bizData.getJSONArray("D293655st5tmoistukggjookxut");
  2218. String maxPlanDueDate = ""; // 记录明细中最大的到期日
  2219. if (recplanentryArray != null && !recplanentryArray.isEmpty()) {
  2220. for (int i = 0; i < recplanentryArray.size(); i++) {
  2221. JSONObject recData = recplanentryArray.getJSONObject(i);
  2222. Map<String, Object> recPlan = new LinkedHashMap<>();
  2223. String uuidHex = recData.getString("ObjectId").replace("-", "");
  2224. // 取后16位(64bit),解析为无符号long,避免溢出和负数问题
  2225. long id = Long.parseUnsignedLong(uuidHex.substring(uuidHex.length() - 16), 16);
  2226. recPlan.put("id", id);
  2227. String planDueDate = formatDate(recData.getString("F0000037"));
  2228. recPlan.put("planduedate", planDueDate); // 到期日
  2229. recPlan.put("planpricerate", recData.getDouble("F0000035")); // 应付比例%
  2230. recPlan.put("planpricetax", recData.getDouble("F0000036")); // 应付金额
  2231. recPlanList.add(recPlan);
  2232. // 取最大日期
  2233. if (maxPlanDueDate.isEmpty() || planDueDate.compareTo(maxPlanDueDate) > 0) {
  2234. maxPlanDueDate = planDueDate;
  2235. }
  2236. }
  2237. }
  2238. payableBill.put("planentity", recPlanList);
  2239. // 最后到期日:取F0000047和明细中最大日期的较大值
  2240. String dueDate = formatDate(bizData.getString("F0000047"));
  2241. if (!maxPlanDueDate.isEmpty() && maxPlanDueDate.compareTo(dueDate) > 0) {
  2242. dueDate = maxPlanDueDate;
  2243. }
  2244. payableBill.put("duedate", dueDate); // 最后到期日
  2245. payableBill.put("asstacttype", "bd_supplier"); // 往来类型
  2246. // 往来供应商单位
  2247. payableBill.put("asstact_number", h3yunService.getFieldValueById(
  2248. "D293655b4a0a34e44914aee9613a7bd3957df83", bizData.getString("F0000024"), "SeqNo"));
  2249. // 结算币别
  2250. payableBill.put("currency_number", h3yunService.getFieldValueById(
  2251. "D293655f08d8524a8254d35b3681ea527ce2c59", bizData.getString("F0000052"), "F0000001"));
  2252. payableBill.put("al95__number", h3yunService.getFieldValueById(
  2253. "D293655skiralyrkoearso23dgyg", bizData.getString("F0000081"), "F0000001"));//发票类型.编码
  2254. payableBill.put("al95__name", h3yunService.getFieldValueById(
  2255. "D293655skiralyrkoearso23dgyg", bizData.getString("F0000081"), "F0000002"));//发票类型.名称
  2256. payableBill.put("ivnumber", bizData.getString("F0000082"));//发票号码
  2257. // 汇率表(格式如 "预算汇率-BMERT-01_SYS" -> "BMERT-01_SYS")
  2258. String exratetable_number = bizData.getString("F0000053");
  2259. if ("预算汇率".equals(exratetable_number)) {
  2260. exratetable_number = "BMERT-01_SYS";
  2261. } else {
  2262. exratetable_number = "ERT-01";
  2263. }
  2264. payableBill.put("exratetable_number", exratetable_number);
  2265. // 付款条件
  2266. payableBill.put("paycond_number", h3yunService.getFieldValueById(
  2267. "D293655sxvsttpe7re2tep6gvsdg", bizData.getString("F0000050"), "F0000001"));
  2268. payableBill.put("remark", bizData.getString("F0000051")); // 备注
  2269. // ========== 明细分录 detailentry ==========
  2270. List<Map<String, Object>> entryList = new ArrayList<>();
  2271. JSONArray billentryArray = bizData.getJSONArray("D293655sgomjaqmtouk80lfxhwlk");
  2272. // detailentry_lk 关联子表(D293655sdetailentrylkxxx 需根据实际编码替换)
  2273. if (billentryArray != null && !billentryArray.isEmpty()) {
  2274. for (int i = 0; i < billentryArray.size(); i++) {
  2275. JSONObject entryData = billentryArray.getJSONObject(i);
  2276. Map<String, Object> entry = new LinkedHashMap<>();
  2277. // 物料编码
  2278. entry.put("material_number", h3yunService.getFieldValueById(
  2279. "D293655fc1a38f7956f400a886f376911a54a30", entryData.getString("F0000027"), "SeqNo"));
  2280. entry.put("quantity", entryData.getDouble("F0000031")); // 数量
  2281. entry.put("price", entryData.getDouble("F0000032")); // 单价
  2282. entry.put("pricetax", entryData.getDouble("F0000080"));//明细.含税单价
  2283. entry.put("e_amount", entryData.getDouble("F0000084")); // 金额
  2284. entry.put("e_pricetaxtotal", entryData.getDouble("F0000033"));//价税合计
  2285. entry.put("discountmode", "NULL"); // 折扣方式默认写死无
  2286. // 单位
  2287. entry.put("measureunit_number", h3yunService.getFieldValueById(
  2288. "D293655248b1d9bf6c448f0a291341ec58bb943", entryData.getString("F0000030"), "F0000001"));
  2289. entry.put("taxrateid_number", h3yunService.getFieldValueById(
  2290. "D293655sl91vt6h8d0qg1heqw5aq", entryData.getString("F0000078"), "F0000001"));//明细.税率.编码(为空时,默认取物料组织公共信息下的默认税率)
  2291. entry.put("e_tax", entryData.getDouble("F0000079"));//税额
  2292. String F0000085 = entryData.getString("F0000085");
  2293. if (F0000085.equals("是")) {
  2294. entry.put("ispresent", true);
  2295. } else {
  2296. entry.put("ispresent", false);
  2297. }
  2298. List<Map<String, Object>> lkList = new ArrayList<>();
  2299. Map<String, Object> lkEntry = new LinkedHashMap<>();
  2300. lkEntry.put("detailentry_lk_stableid", "602924315385558018");
  2301. // lkEntry.put("detailentry_lk_sbillid","2474808901552334848" );//h3yunService.getFieldValueById( "D293655srqj5uui3keso9oraeqm", bizData.getString("F0000074"), "F0000038")
  2302. // lkEntry.put("detailentry_lk_sid", "2474809546787280896" );//entryData.getString("F0000075")
  2303. lkEntry.put("detailentry_lk_sbillid", h3yunService.getFieldValueById("D293655srqj5uui3keso9oraeqm", bizData.getString("F0000074"), "F0000038"));//
  2304. lkEntry.put("detailentry_lk_sid", entryData.getString("F0000075"));//
  2305. lkList.add(lkEntry);
  2306. entry.put("detailentry_lk", lkList);
  2307. entryList.add(entry);
  2308. }
  2309. }
  2310. payableBill.put("detailentry", entryList);
  2311. // // ========== 付款计划分录 planentity ==========
  2312. // List<Map<String, Object>> recPlanList = new ArrayList<>();
  2313. // JSONArray recplanentryArray = bizData.getJSONArray("D293655st5tmoistukggjookxut");
  2314. // if (recplanentryArray != null && !recplanentryArray.isEmpty()) {
  2315. // for (int i = 0; i < recplanentryArray.size(); i++) {
  2316. // JSONObject recData = recplanentryArray.getJSONObject(i);
  2317. // Map<String, Object> recPlan = new LinkedHashMap<>();
  2318. // recPlan.put("planduedate", formatDate(recData.getString("F0000037"))); // 到期日
  2319. // recPlan.put("planpricerate", recData.getDouble("F0000035")); // 应付比例%
  2320. // recPlan.put("planpricetax", recData.getDouble("F0000036")); // 应付金额
  2321. // recPlanList.add(recPlan);
  2322. // }
  2323. // }
  2324. // payableBill.put("planentity", recPlanList);
  2325. dataList.add(payableBill);
  2326. data.put("data", dataList);
  2327. return data;
  2328. }
  2329. /**
  2330. * 提取采购发票数据(金蝶API格式)
  2331. * 返回格式: {"data":[{"billno":"...","supplier_number":"...","iv_purchaseentry":[...]}]}
  2332. */
  2333. @SuppressWarnings("unchecked")
  2334. private Map<String, Object> extractPurchaseInvoiceData(JSONObject bizData) {
  2335. Map<String, Object> data = new HashMap<>();
  2336. List<Map<String, Object>> dataList = new ArrayList<>();
  2337. Map<String, Object> purchaseInvoice = new LinkedHashMap<>();
  2338. // 头部信息
  2339. purchaseInvoice.put("billno", bizData.getString("SeqNo")); // 单据编号
  2340. purchaseInvoice.put("supplier_number", bizData.getString("F0000002")); // 供应商编码
  2341. purchaseInvoice.put("supplier_name", bizData.getString("F0000003")); // 供应商名称
  2342. purchaseInvoice.put("biztime", formatDate(bizData.getString("F0000004"))); // 业务日期
  2343. purchaseInvoice.put("invoice_no", bizData.getString("F0000005")); // 发票号
  2344. purchaseInvoice.put("invoice_date", formatDate(bizData.getString("F0000006"))); // 发票日期
  2345. purchaseInvoice.put("settleorg_number", bizData.getString("F0000007")); // 结算组织
  2346. purchaseInvoice.put("billtype_number", bizData.getString("F0000008")); // 单据类型
  2347. purchaseInvoice.put("settlecurrency_number", bizData.getString("F0000009")); // 结算币别
  2348. purchaseInvoice.put("exchangerate", bizData.getDouble("F0000010")); // 汇率
  2349. purchaseInvoice.put("istax", true); // 是否含税
  2350. purchaseInvoice.put("comment", bizData.getString("F0000011")); // 备注
  2351. purchaseInvoice.put("operator_operatornumber", bizData.getString("CreatedBy")); // 操作人
  2352. // 分录信息 iv_purchaseentry
  2353. List<Map<String, Object>> entryList = new ArrayList<>();
  2354. JSONArray billentryArray = bizData.getJSONArray("F0000012");
  2355. if (billentryArray != null && !billentryArray.isEmpty()) {
  2356. for (int i = 0; i < billentryArray.size(); i++) {
  2357. JSONObject entryData = billentryArray.getJSONObject(i);
  2358. Map<String, Object> entry = new LinkedHashMap<>();
  2359. entry.put("material_number", entryData.getString("F0000013")); // 物料编码
  2360. entry.put("qty", entryData.getDouble("F0000014")); // 数量
  2361. entry.put("unit_number", entryData.getString("F0000015")); // 单位
  2362. entry.put("price", entryData.getDouble("F0000016")); // 单价
  2363. entry.put("taxprice", entryData.getDouble("F0000017")); // 含税单价
  2364. entry.put("taxrate", entryData.getDouble("F0000018")); // 税率
  2365. entry.put("amount", entryData.getDouble("F0000019")); // 金额
  2366. entry.put("taxamount", entryData.getDouble("F0000020")); // 税额
  2367. entry.put("entrycomment", entryData.getString("F0000021")); // 分录备注
  2368. entryList.add(entry);
  2369. }
  2370. }
  2371. purchaseInvoice.put("iv_purchaseentry", entryList);
  2372. dataList.add(purchaseInvoice);
  2373. data.put("data", dataList);
  2374. return data;
  2375. }
  2376. /**
  2377. * 提取销售发票数据(金蝶API格式)
  2378. * 返回格式: {"data":[{"billno":"...","customer_number":"...","iv_salesentry":[...]}]}
  2379. */
  2380. @SuppressWarnings("unchecked")
  2381. private Map<String, Object> extractSalesInvoiceData(JSONObject bizData) {
  2382. Map<String, Object> data = new HashMap<>();
  2383. List<Map<String, Object>> dataList = new ArrayList<>();
  2384. Map<String, Object> salesInvoice = new LinkedHashMap<>();
  2385. // 头部信息
  2386. salesInvoice.put("billno", bizData.getString("SeqNo")); // 单据编号
  2387. salesInvoice.put("customer_number", bizData.getString("F0000002")); // 客户编码
  2388. salesInvoice.put("customer_name", bizData.getString("F0000003")); // 客户名称
  2389. salesInvoice.put("biztime", formatDate(bizData.getString("F0000004"))); // 业务日期
  2390. salesInvoice.put("invoice_no", bizData.getString("F0000005")); // 发票号
  2391. salesInvoice.put("invoice_date", formatDate(bizData.getString("F0000006"))); // 发票日期
  2392. salesInvoice.put("saleorg_number", bizData.getString("F0000007")); // 销售组织
  2393. salesInvoice.put("billtype_number", bizData.getString("F0000008")); // 单据类型
  2394. salesInvoice.put("settlecurrency_number", bizData.getString("F0000009")); // 结算币别
  2395. salesInvoice.put("exchangerate", bizData.getDouble("F0000010")); // 汇率
  2396. salesInvoice.put("istax", true); // 是否含税
  2397. salesInvoice.put("comment", bizData.getString("F0000011")); // 备注
  2398. salesInvoice.put("operator_operatornumber", bizData.getString("CreatedBy")); // 操作人
  2399. // 分录信息 iv_salesentry
  2400. List<Map<String, Object>> entryList = new ArrayList<>();
  2401. JSONArray billentryArray = bizData.getJSONArray("F0000012");
  2402. if (billentryArray != null && !billentryArray.isEmpty()) {
  2403. for (int i = 0; i < billentryArray.size(); i++) {
  2404. JSONObject entryData = billentryArray.getJSONObject(i);
  2405. Map<String, Object> entry = new LinkedHashMap<>();
  2406. entry.put("material_number", entryData.getString("F0000013")); // 物料编码
  2407. entry.put("qty", entryData.getDouble("F0000014")); // 数量
  2408. entry.put("unit_number", entryData.getString("F0000015")); // 单位
  2409. entry.put("price", entryData.getDouble("F0000016")); // 单价
  2410. entry.put("taxprice", entryData.getDouble("F0000017")); // 含税单价
  2411. entry.put("taxrate", entryData.getDouble("F0000018")); // 税率
  2412. entry.put("amount", entryData.getDouble("F0000019")); // 金额
  2413. entry.put("taxamount", entryData.getDouble("F0000020")); // 税额
  2414. entry.put("entrycomment", entryData.getString("F0000021")); // 分录备注
  2415. entryList.add(entry);
  2416. }
  2417. }
  2418. salesInvoice.put("iv_salesentry", entryList);
  2419. dataList.add(salesInvoice);
  2420. data.put("data", dataList);
  2421. return data;
  2422. }
  2423. /**
  2424. * 提取收款单数据(金蝶API格式)
  2425. * 返回格式: {"data":[{"billno":"...","receiveorg_number":"...","ar_receivableentry":[...]}]}
  2426. */
  2427. @SuppressWarnings("unchecked")
  2428. private Map<String, Object> extractReceiveBillData(JSONObject bizData) {
  2429. Map<String, Object> data = new HashMap<>();
  2430. List<Map<String, Object>> dataList = new ArrayList<>();
  2431. Map<String, Object> receiveBill = new LinkedHashMap<>();
  2432. // 头部信息
  2433. // ========== 头部信息 ==========
  2434. receiveBill.put("billno", bizData.getString("SeqNo")); // 单据编号
  2435. receiveBill.put("trdbillno", bizData.getString("SeqNo"));//第三方业务编码(防止重复新增,每次新增需要传入唯一值)
  2436. receiveBill.put("payertype", "bd_customer"); // 付款单位类型:bos_org:公司,bd_supplier:供应商,bd_customer:客户,bos_user:人员,other:其他,cas_othercontactunit:其他往来单位
  2437. receiveBill.put("actrecamt", bizData.getDouble("F0000034")); // 收款金额
  2438. receiveBill.put("exchangerate", bizData.getDouble("F0000051")); // 汇率
  2439. receiveBill.put("localamt", bizData.getDouble("F0000052")); // 汇率
  2440. receiveBill.put("currency_number", h3yunService.getFieldValueById("D293655f08d8524a8254d35b3681ea527ce2c59", bizData.getString("F0000048"), "F0000001"));// 收款币别.货币代码
  2441. receiveBill.put("accountbank_number", h3yunService.getFieldValueById("D293655sat05benxoeg1hhgy81h", bizData.getString("F0000055"), "F0000001"));//收款账号
  2442. String exratetable_number = bizData.getString("F0000035");
  2443. if ("预算汇率".equals(exratetable_number)) {
  2444. exratetable_number = "BMERT-01_SYS";
  2445. } else {
  2446. exratetable_number = "ERT-01";
  2447. }
  2448. receiveBill.put("exratetable_number", exratetable_number);// 汇率表.编码
  2449. // receiveBill.put("customer_name", bizData.getString("F0000004")); // 客户名称
  2450. receiveBill.put("bizdate", formatDate(bizData.getString("F0000021"))); // 业务日期
  2451. receiveBill.put("payername", h3yunService.getFieldValueById("D293655shuyz9ttzgkgmhaa4rglr", bizData.getString("F0000058"), "F0000001")); // 付款单位名称
  2452. receiveBill.put("bizdate", formatDate(bizData.getString("F0000021"))); // 业务日期
  2453. receiveBill.put("settletype_number", h3yunService.getFieldValueById("D293655skrwqen4wv0g7je4itf", bizData.getString("F0000049"), "F0000001")); // 结算方式.编码
  2454. // receiveBill.put("bankaccount", bizData.getString("F0000009")); // 银行账号
  2455. // receiveBill.put("settlecurrency_number", bizData.getString("F0000010")); // 结算币别
  2456. // receiveBill.put("comment", bizData.getString("F0000012")); // 备注
  2457. // receiveBill.put("operator_operatornumber", bizData.getString("CreatedBy")); // 操作人
  2458. // 分录信息 ar_receivableentry
  2459. List<Map<String, Object>> entryList = new ArrayList<>();
  2460. JSONArray billentryArray = bizData.getJSONArray("D293655stemflt5ee0gjvlbvvj5n");
  2461. if (billentryArray != null && !billentryArray.isEmpty()) {
  2462. for (int i = 0; i < billentryArray.size(); i++) {
  2463. JSONObject entryData = billentryArray.getJSONObject(i);
  2464. Map<String, Object> entry = new LinkedHashMap<>();
  2465. // String uuidHex = entryData.getString("ObjectId").replace("-", "");
  2466. // long id = Long.parseUnsignedLong(uuidHex.substring(uuidHex.length() - 16), 16);
  2467. // entry.put("id", id);
  2468. entry.put("e_receivingtype_number", "100");
  2469. entry.put("e_actamt", entryData.getDouble("F0000057")); // 实收金额
  2470. entry.put("e_receivableamt", entryData.getDouble("F0000057"));//应收金额
  2471. entry.put("e_localamt", entryData.getDouble("F0000059")); // 收款明细.实收折本币
  2472. entry.put("e_sourcebillid", h3yunService.getFieldValueById("D29365523b214414c2b4e50b9bdca110a9a5951", bizData.getString("F0000060"), "K3id"));
  2473. entry.put("e_settleorg_number", h3yunService.getFieldValueById("D29365537feb4e5e8644b21b7fd938dd322dab3", entryData.getString("F0000056"), "F0000002"));//收款明细.结算组织.编码
  2474. entry.put("e_contactunittype", "bd_customer");//收款明细.(必录)往来单位类型 bd_customer:客户, bd_supplier:供应商, bos_org:公司, bos_user:人员, cas_othercontactunit:其他往来单位, cas_other:其他
  2475. entry.put("e_contactunit_number", h3yunService.getFieldValueById("D293655shuyz9ttzgkgmhaa4rglr", entryData.getString("F0000030"), "SeqNo"));//收款明细.结算组织.编码
  2476. /////////收款单关联销售订单
  2477. String uuidHex = entryData.getString("F0000061").replace("-", "");
  2478. long id = Long.parseUnsignedLong(uuidHex.substring(uuidHex.length() - 16), 16);
  2479. entry.put("e_corebilltype", "sm_salorder");// 收款明细.核心单据类型 ar_finarbill:财务应收单, fr_glreim_paybill:总账付款单, conm_salcontract:销售合同, ec_contract:建筑收入合同, er_repaymentbill:还款单, fr_glreim_recbill:总账收款单, sm_salorder:销售订单, PO:采购订单, cas_paybill:付款单
  2480. entry.put("e_corebilltype_title", "销售订单");//固定
  2481. entry.put("e_corebillentryseq", 1);//固定
  2482. entry.put("e_corebillno", h3yunService.getFieldValueById(
  2483. "D29365523b214414c2b4e50b9bdca110a9a5951", bizData.getString("F0000060"), "SeqNo"));//销售订单编号
  2484. entry.put("e_corebillid", h3yunService.getFieldValueById(
  2485. "D29365523b214414c2b4e50b9bdca110a9a5951", bizData.getString("F0000060"), "K3id"));//销售订单主表ID
  2486. entry.put("e_corebillentryid", id);//销售订单应付行明细ID
  2487. List<Map<String, Object>> lkList = new ArrayList<>();
  2488. Map<String, Object> lkEntry = new LinkedHashMap<>();
  2489. lkEntry.put("entry_lk_stableid", "602924332909361152");
  2490. lkEntry.put("entry_lk_sbillid", h3yunService.getFieldValueById("D29365523b214414c2b4e50b9bdca110a9a5951", bizData.getString("F0000060"), "K3id"));//
  2491. lkEntry.put("entry_lk_sid", id);//
  2492. lkList.add(lkEntry);
  2493. entry.put("entry_lk", lkList);
  2494. entryList.add(entry);
  2495. }
  2496. }
  2497. receiveBill.put("entry", entryList);//收款明细
  2498. dataList.add(receiveBill);
  2499. data.put("data", dataList);
  2500. return data;
  2501. }
  2502. /**
  2503. * 提取
  2504. * 开票申请@财务应收单 数据(金蝶API格式)
  2505. * 返回格式: {"data":[{"billno":"...","customer_number":"...","iv_invoiceapplyentry":[...]}]}
  2506. */
  2507. @SuppressWarnings("unchecked")
  2508. private Map<String, Object> extractInvoiceApplyData(JSONObject bizData) {
  2509. Map<String, Object> data = new HashMap<>();
  2510. List<Map<String, Object>> dataList = new ArrayList<>();
  2511. Map<String, Object> invoiceApply = new LinkedHashMap<>();
  2512. // 头部信息
  2513. invoiceApply.put("billno", bizData.getString("SeqNo")); // 单据编号
  2514. invoiceApply.put("trdbillno", bizData.getString("SeqNo"));//第三方业务编码(防止重复新增,每次新增需要传入唯一值)
  2515. invoiceApply.put("billtype_number", "arfin_standard_BT_S");//单据类型.编码(arfin_borrowar_BT_S-应收款项调整、arfin_other_BT_S-其他应收、arfin_project_BT_S-项目应收、arfin_salefee_BT_S-销售费用应收、arfin_sersal_BT_S-服务销售应收、arfin_standard_BT_S-标准销售应收、arfin_transfer_BT_S-资产调拨应收)
  2516. invoiceApply.put("org_number", h3yunService.getFieldValueById("D29365537feb4e5e8644b21b7fd938dd322dab3", bizData.getString("F0000003"), "F0000002")); // 结算组织.编码
  2517. invoiceApply.put("bizdate", formatDate(bizData.getString("F0000005"))); // 业务日期
  2518. invoiceApply.put("bookdate", formatDate(bizData.getString("F0000007")));//记账日期
  2519. // invoiceApply.put("duedate", formatDate(bizData.getString("F0000006")));//最后到期日
  2520. invoiceApply.put("paycond_number", h3yunService.getFieldValueById("D293655sv6bv8bozikwrkze3rk1", bizData.getString("F0000010"), "F0000001"));//收款条件.编码
  2521. invoiceApply.put("settlementtype_number", h3yunService.getFieldValueById("D293655skrwqen4wv0g7je4itf", bizData.getString("F0000011"), "F0000001"));//结算方式.编码
  2522. invoiceApply.put("asstacttype", "bd_customer"); // 往来类型 bd_supplier:供应商, bos_user:人员, bd_customer:客户, cas_othercontactunit:其他往来单位
  2523. invoiceApply.put("asstact_number", h3yunService.getFieldValueById("D293655shuyz9ttzgkgmhaa4rglr", bizData.getString("F0000002"), "SeqNo")); // 往来单位.编码(结合往来类型动态改变,显示的名称有:结算客户、往来单位)
  2524. invoiceApply.put("recorg_number", h3yunService.getFieldValueById("D29365537feb4e5e8644b21b7fd938dd322dab3", bizData.getString("F0000009"), "F0000002"));//收款组织.编码
  2525. invoiceApply.put("currency_number", h3yunService.getFieldValueById("D293655f08d8524a8254d35b3681ea527ce2c59", bizData.getString("F0000013"), "F0000001"));//结算币别.货币代码
  2526. String exratetable_number = bizData.getString("F0000014");
  2527. if ("预算汇率".equals(exratetable_number)) {
  2528. exratetable_number = "BMERT-01_SYS";
  2529. } else {
  2530. exratetable_number = "ERT-01";
  2531. }
  2532. invoiceApply.put("exratetable_number", exratetable_number);//汇率表.编码
  2533. //开票类型
  2534. invoiceApply.put("al95_fp_number", h3yunService.getFieldValueById("D293655sdzbyn4yqt0ub0k8e9euc", bizData.getString("F0000032"), "F0000001"));
  2535. //
  2536. //
  2537. // invoiceApply.put("invoicetype", bizData.getString("F0000006")); // 发票类型
  2538. // invoiceApply.put("taxnum", bizData.getString("F0000007")); // 税号
  2539. // invoiceApply.put("bank_number", bizData.getString("F0000008")); // 开户银行
  2540. // invoiceApply.put("bankaccount", bizData.getString("F0000009")); // 银行账号
  2541. // invoiceApply.put("address", bizData.getString("F0000010")); // 地址
  2542. // invoiceApply.put("phone", bizData.getString("F0000011")); // 电话
  2543. invoiceApply.put("remark", bizData.getString("F0000012")); // 备注
  2544. // invoiceApply.put("operator_operatornumber", bizData.getString("CreatedBy")); // 操作人
  2545. // 分录信息 iv_invoiceapplyentry
  2546. List<Map<String, Object>> entryList = new ArrayList<>();
  2547. JSONArray billentryArray = bizData.getJSONArray("D293655F95117110d28044aa81b904ec6bafb8d9");
  2548. if (billentryArray != null && !billentryArray.isEmpty()) {
  2549. for (int i = 0; i < billentryArray.size(); i++) {
  2550. JSONObject entryData = billentryArray.getJSONObject(i);
  2551. Map<String, Object> entry = new LinkedHashMap<>();
  2552. entry.put("e_quantity", entryData.getDouble("F0000022")); // 数量
  2553. entry.put("e_unitprice", entryData.getDouble("F0000027")); // 单价
  2554. // entry.put("e_unitprice", entryData.getDouble("F0000027")); // 含税单价
  2555. entry.put("e_amount", entryData.getDouble("F0000028")); // 金额
  2556. entry.put("e_discountmode", "NULL"); // 明细.折扣方式 PERCENT:折扣率(%), PERUNIT:单位折扣额, NULL:无, TOTAL:固定折扣额
  2557. entry.put("e_material_number", entryData.getString("F0000026")); // 物料编码
  2558. /////这里
  2559. /////////应收单关联销售出库单
  2560. String uuidHex = entryData.getString("F0000030").replace("-", "");
  2561. long id = Long.parseUnsignedLong(uuidHex.substring(uuidHex.length() - 16), 16);
  2562. // entry.put("e_corebilltype", "sm_salorder");// 收款明细.核心单据类型 ar_finarbill:财务应收单, fr_glreim_paybill:总账付款单, conm_salcontract:销售合同, ec_contract:建筑收入合同, er_repaymentbill:还款单, fr_glreim_recbill:总账收款单, sm_salorder:销售订单, PO:采购订单, cas_paybill:付款单
  2563. // entry.put("e_corebilltype_title", "销售订单");//固定
  2564. // entry.put("e_corebillentryseq", 1);//固定
  2565. // entry.put("e_corebillno", h3yunService.getFieldValueById(
  2566. // "D29365523b214414c2b4e50b9bdca110a9a5951", bizData.getString("F0000060"), "SeqNo"));//销售订单编号
  2567. //
  2568. // entry.put("e_corebillid", h3yunService.getFieldValueById(
  2569. // "D29365523b214414c2b4e50b9bdca110a9a5951", bizData.getString("F0000060"), "K3id"));//销售订单主表ID
  2570. // entry.put("e_corebillentryid", id);//销售订单应付行明细ID
  2571. List<Map<String, Object>> lkList = new ArrayList<>();
  2572. Map<String, Object> lkEntry = new LinkedHashMap<>();
  2573. lkEntry.put("entry_lk_stableid", "602924300688717826");
  2574. lkEntry.put("entry_lk_sbillid", h3yunService.getFieldValueById("D293655suomjudbplkoxrgs42dqj", bizData.getString("F0000029"), "K3id"));//
  2575. lkEntry.put("entry_lk_sid", id);//
  2576. lkList.add(lkEntry);
  2577. entry.put("entry_lk", lkList);
  2578. //
  2579. // entry.put("taxrate", entryData.getDouble("F0000018")); // 税率
  2580. //
  2581. // entry.put("taxamount", entryData.getDouble("F0000020")); // 税额
  2582. // entry.put("entrycomment", entryData.getString("F0000021")); // 分录备注
  2583. entryList.add(entry);
  2584. }
  2585. }
  2586. invoiceApply.put("entry", entryList);
  2587. dataList.add(invoiceApply);
  2588. data.put("data", dataList);
  2589. return data;
  2590. }
  2591. /**
  2592. * 提取通用单据数据
  2593. */
  2594. private Map<String, Object> extractBillData(JSONObject bizData, String idField1, String idField2) {
  2595. Map<String, Object> data = new HashMap<>();
  2596. if (idField1 != null) {
  2597. data.put(idField1, bizData.getString("F0000002"));
  2598. }
  2599. if (idField2 != null) {
  2600. data.put(idField2, bizData.getString("F0000003"));
  2601. }
  2602. // 提取明细数据
  2603. JSONArray entityList = bizData.getJSONArray("F0000010");
  2604. if (entityList != null && !entityList.isEmpty()) {
  2605. JSONObject firstItem = entityList.getJSONObject(0);
  2606. data.put("materialId", firstItem.getString("F0000011")); // 明细物料
  2607. data.put("qty", firstItem.getDouble("F0000012")); // 明细数量
  2608. }
  2609. return data;
  2610. }
  2611. }