From b195295f2007d52f4a22e679f8ca591b042de27a Mon Sep 17 00:00:00 2001
From: 小小儁爺 <1694218219@qq.com>
Date: 星期五, 31 十月 2025 13:40:19 +0800
Subject: [PATCH] 1.生产入库、入库记录开发
---
src/views/produce/productWarehouse.vue | 464 +++++++++++++++++++++++++++++++++-------------------------
1 files changed, 264 insertions(+), 200 deletions(-)
diff --git a/src/views/produce/productWarehouse.vue b/src/views/produce/productWarehouse.vue
index 5311a21..0f12a78 100644
--- a/src/views/produce/productWarehouse.vue
+++ b/src/views/produce/productWarehouse.vue
@@ -32,6 +32,21 @@
>
<div class="elForm" style="display: flex;flex-direction: column;justify-content: flex-start">
<div style="display: flex">
+ <el-form-item label="鍗曟嵁绫诲瀷" required style=" display: flex;">
+ <el-select
+ v-model="form.issouceorder"
+ :popper-append-to-body="false"
+ :style="{minWidth:'100px',width:formItemWidth+'px'}"
+ placeholder="璇烽�夋嫨"
+ >
+ <el-option
+ v-for="item in issouceorderTypeArr"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value"
+ />
+ </el-select>
+ </el-form-item>
<el-form-item label="鐢熶骇杞﹂棿" required style=" display: flex;">
<el-select
v-model="form.wkshopcode"
@@ -69,6 +84,10 @@
:style="{minWidth:'100px',width:formItemWidth+'px'}"
/>
</el-form-item>
+
+ </div>
+
+ <div style="display: flex">
<el-form-item
label="閿�鍞鍗�"
style="display: flex;"
@@ -79,17 +98,26 @@
:style="{minWidth:'100px',width:formItemWidth+'px'}"
/>
</el-form-item>
- </div>
-
- <div style="display: flex">
<el-form-item label="浜у搧缂栫爜" style=" display: flex;">
- <el-input v-model="form.partcode" placeholder="璇疯緭鍏�" :style="{minWidth:'100px',width:formItemWidth+'px'}" />
+ <el-input
+ v-model="form.partcode"
+ placeholder="璇疯緭鍏�"
+ :style="{minWidth:'100px',width:formItemWidth+'px'}"
+ />
</el-form-item>
<el-form-item label="浜у搧鍚嶇О" style=" display: flex;">
- <el-input v-model="form.partname" :style="{minWidth:'100px',width:formItemWidth+'px'}" placeholder="璇疯緭鍏�" />
+ <el-input
+ v-model="form.partname"
+ :style="{minWidth:'100px',width:formItemWidth+'px'}"
+ placeholder="璇疯緭鍏�"
+ />
</el-form-item>
<el-form-item label="浜у搧瑙勬牸" style=" display: flex;">
- <el-input v-model="form.partspec" :style="{minWidth:'100px',width:formItemWidth+'px'}" placeholder="璇疯緭鍏�" />
+ <el-input
+ v-model="form.partspec"
+ :style="{minWidth:'100px',width:formItemWidth+'px'}"
+ placeholder="璇疯緭鍏�"
+ />
</el-form-item>
</div>
@@ -221,30 +249,15 @@
highlight-current-row
:header-cell-style="this.$headerCellStyle"
:cell-style="this.$cellStyle"
- @row-click="rowClick"
+ @selection-change="handleSelectionChange"
>
- <!-- @selection-change="handleSelectionChange"-->
<!-- @cell-dblclick="cellDblclick"-->
<!-- @cell-click="cellClick"-->
- <!-- <el-table-column-->
- <!-- type="selection"-->
- <!-- width="50"-->
- <!-- fixed-->
- <!-- />-->
-
<el-table-column
+ type="selection"
width="50"
fixed
- >
- <template slot-scope="{row}">
- <el-radio
- v-model="radioSelected"
- :label="row.sbid"
- style="color: transparent;padding-left: 10px;"
- />
- </template>
- </el-table-column>
-
+ />
<el-table-column
type="index"
width="50"
@@ -585,8 +598,10 @@
import { PrentOrganizationNoCompany, WareHouse } from '@/api/GeneralBasicData'
import {
+ DeptSelectData,
ProductInHouseOrderCodeSearch,
- ProductInHouseOrderSearch, TProductInHouseOrderSpSeave
+ ProductInHouseOrderSearch,
+ InHouseOrderSpSeave
} from '@/api/WorkOrder'
import { TSecLocaTree } from '@/api/basicSettings'
import { getTPlusToken, handleDatetime, handleDatetime2 } from '@/utils/global'
@@ -613,6 +628,8 @@
partname: '', // 浜у搧鍚嶇О
partspec: '', // 瑙勬牸鍨嬪彿
+ issouceorder: 'Y', // 鏄惁鏈夋簮鍗�
+
deptno: '', // 鍏ュ簱閮ㄩ棬
saleOrderCode: '', // 閿�鍞鍗�
stockcode: '' // 鍏ュ簱浠撳簱
@@ -633,26 +650,33 @@
buttonSize: '',
formItemWidth: 0,
- radioSelected: ''
+ issouceorderTypeArr: [
+ { value: 'Y', label: '鏈夋簮鍗�' },
+ { value: 'N', label: '鏃犳簮鍗�' }
+ ]
}
},
watch: {},
created() {
},
- mounted() {
+ async mounted() {
window.addEventListener('resize', this.getHeight)
this.getHeight()
- this.getPrentOrganizationNoCompany()
- this.getTSecLocaTree()
- this.getProductInHouseOrderCodeSearch()
+ await this.getPrentOrganizationNoCompany()
+ await this.getTSecLocaTree()
+ await this.getProductInHouseOrderCodeSearch()
+ // this.getDeptSelectData()
// this.getProductInHouseOrderSearch()
},
methods: {
// 鑾峰彇鍏ュ簱閮ㄩ棬
-
+ async getDeptSelectData() {
+ const { data: res } = await DeptSelectData()
+ this.departmentArr = res
+ },
// 鑾峰彇鍗曟嵁缂栧彿(鍏ュ簱鍗曞彿)銆佹祦姘村彿
async getProductInHouseOrderCodeSearch() {
const { data: res } = await ProductInHouseOrderCodeSearch({ rightcode: '0604' })
@@ -677,6 +701,7 @@
return this.$message.info('鐢熶骇杞﹂棿涓嶈兘涓虹┖锛�')
}
const data = {
+ issouceorder: this.form.issouceorder,
saleordercode: this.form.saleordercode, // 閿�鍞崟鍙�
wkshopcode: this.form.wkshopcode, // 鐢熶骇杞﹂棿
erpordercode: this.form.erpordercode, // 璁㈠崟缂栧彿
@@ -710,98 +735,8 @@
handleSelectionChange(val) {
this.multipleSelection = val
},
- // 琛岀偣鍑讳簨浠�
- async rowClick(row, event, column) {
- this.radioSelected = row.sbid
- // const { data: res } = await SearchWorkStep({ wo_code: row.wo_code })
- // this.tableDataDetail = res
- },
// 閫掍氦
- async submit() {
- if (this.form.stockcode === '') {
- return this.$message.info('鍏ュ簱浠撳簱涓嶈兘涓虹┖锛�')
- }
-
- const openToken = await getTPlusToken() // 鑾峰彇TPlus token
-
- const obj = this.tableDataDetail.find(i => i.sbid === this.radioSelected)
-
- // 鏃犳簮鍗�
- if (!obj.saleOrderCode) {
- // const RDRecordDetails = []
- // this.tableDataSummary.forEach((i, index) => {
- // RDRecordDetails.push({
- // Code: index + 1, // 琛屽彿锛屼粠1寮�濮嬭嚜澧為暱
- // Inventory: {
- // Code: i.materiel_code // 瀛樿揣缂栫爜
- // },
- // BaseQuantity: i.stinhouseqty, // 涓昏閲忓崟浣嶆暟閲�
- // SNObject: {
- // SnAccountDetails: [
- // {
- // SNCode: index.toString().padStart(4, '0')
- // }
- // ]
- // }
- // })
- // })
- const data = {
- 'dto': {
- 'IsModifiedCode': true,
- 'ExternalCode': this.form.hbillno,
- 'Code': this.form.hbillno,
- 'VoucherType': {
- 'Code': 'ST1002'
- },
- 'VoucherDate': handleDatetime(new Date().getTime()),
- 'BusiType': {
- 'Code': '03'
- },
- 'Warehouse': {
- 'Code': this.form.stockcode
- },
- // 'Department': {
- // 'Code': this.form.wkshopcode,
- // 'Name': this.WorkShopArr.find(i => i.code === this.form.wkshopcode).name
- // },
- 'RDRecordDetails': [
- {
- Code: 1, // 琛屽彿锛屼粠1寮�濮嬭嚜澧為暱
- Inventory: {
- Code: obj.partcode // 瀛樿揣缂栫爜
- },
- BaseQuantity: obj.stinhouseqty, // 涓昏閲忓崟浣嶆暟閲�
- SNObject: {
- SnAccountDetails: [
- {
- // SNCode: index.toString().padStart(4, '0')
- SNCode: '0001'
- }
- ]
- }
- }
- ]
- }
- }
-
- console.log(JSON.parse(JSON.stringify(data)))
-
- const res = await axios.post(Vue.prototype.$chanjetBaseUrl + '/tplus/api/v2/productReceive/Create',
- data, {
- headers: {
- 'openToken': openToken,
- 'appKey': Vue.prototype.$AppKey,
- 'appSecret': Vue.prototype.$AppSecret,
- 'Content-Type': 'application/json'
- }
- }
- )
- console.log(res)
- console.log(res.status)
- }
- },
- // 閫掍氦
- async submitBack() {
+ async submit() {
// usercode
// console.log(localStorage.getItem('username'))
@@ -814,81 +749,218 @@
if (this.multipleSelection.find(i => i.stockid === '' || i.stockid === null)) {
return this.$message.info('琛ㄦ牸鍐呭叆搴撲粨搴撲笉鑳戒负绌猴紒')
}
-
- const TableDetailData = []
- this.multipleSelection.forEach((i, index) => {
- TableDetailData.push({
- 'hbillno': this.form.hbillno, // 鍏ュ簱鍗曞彿
- 'wocode': i.wo_code, // 宸ュ崟鍙�
- 'rownumber': (index + 1).toString(), // 琛屽彿
- 'sourceVoucherId': i.mpoid.toString(), // 鏉ユ簮鍗曟嵁id
- 'sourceVoucherCode': i.m_po, // 鏉ユ簮鍗曟嵁缂栧彿
- 'SourceVoucherDetailId': i.sbid.toString(), // 鏉ユ簮鍗曟嵁鏄庣粏id
- 'inbarcode': i.inbarcode, // 鍏ュ簱鏉$爜
- 'idinventory': i.materiel_id.toString(), // 瀛樿揣id
- 'inventorycode': i.partcode, // 瀛樿揣缂栫爜
- 'idunit': i.unitid.toString(), // 璁¢噺鍗曚綅id
- 'unitcode': i.unitcode, // 璁¢噺鍗曚綅缂栫爜
- idwarehouse: i.stockid.toString(), // 浠撳簱id
- warehousecode: i.stockcode, // 浠撳簱缂栫爜
- 'saleOrderId': i.saleOrderid.toString(), // 閿�鍞崟id
- 'saleOrderCode': i.saleOrderCode, // 閿�鍞崟鍙�
- 'saleOrderDetailId': i.saleOrderDetailId.toString(), // 閿�鍞崟鏄庣粏id
- 'qty': i.good_qty.toString(), // 鍏ュ簱鏁伴噺
- 'stepcode': i.step_code, // 宸ュ簭缂栫爜
- 'style': i.style, // 鎶ュ伐绫诲瀷锛欱(鑷埗) S(澶栧崗)
- 'status': '0' // 鍏ュ簱鍗曠姸鎬侊細0(鏈鏍�) 1(宸插鏍�)
- })
- })
-
- const data = {
- 'rightcode': '0604', // 鍔熻兘缂栧彿
- 'incbit': this.form.incbit, // 娴佹按鍙�
- 'TableData': [
- [
- {
- 'hbillno': this.form.hbillno, // 鍏ュ簱鍗曞彿
- 'madedate': handleDatetime(this.form.hbdate) + ' 00:00:00', // 鍒跺崟鏃ユ湡锛堝勾鏈堟棩 00:00:00锛�
- 'hbdate': this.multipleSelection[this.multipleSelection.length - 1].voucherdate,
-
- sourceVoucherId: [...new Set(this.multipleSelection.map(i => i.mpoid))].length > 1 ? '' : this.multipleSelection[0].mpoid,
- sourceVoucherCode: [...new Set(this.multipleSelection.map(i => i.m_po))].length > 1 ? '' : this.multipleSelection[0].m_po,
- saleOrderCode: [...new Set(this.multipleSelection.map(i => i.saleOrderCode))].length > 1 ? '' : this.multipleSelection[0].saleOrderCode,
-
- 'iddepartment': this.multipleSelection[0].dept_id, // 閮ㄩ棬id
- 'departmentcode': this.multipleSelection[0].dept_code, // 閮ㄩ棬缂栫爜
-
- 'idwarehouse': this.stockcodeArr.find(i => i.code === this.form.stockcode).noid, // 浠撳簱id
- 'warehousecode': this.form.stockcode, // 浠撳簱缂栫爜
- 'status': '0', // 鍏ュ簱鍗曠姸鎬侊細0(鏈鏍�) 1(宸插鏍�)
- PurchaseOrderCode: '', // 閲囪喘璁㈠崟鍙�
- 'remark': '', // 澶囨敞
- 'create_user': localStorage.getItem('username'), // 鍒涘缓浜哄憳
- 'create_date': handleDatetime2(new Date()),
- 'check_user': '', // 瀹℃牳浜哄憳
- 'check_date': ''// 瀹℃牳鏃堕棿
- }
- ],
- TableDetailData// 琛ㄤ綋
- ]
- }
-
- // console.log(JSON.stringify(data))
this.$store.state.app.buttonIsDisabled = true
- const res = await TProductInHouseOrderSpSeave(data)
- this.$store.state.app.buttonIsDisabled = false
- if (res.code === '200') {
- this.$message.success('鍏ュ簱鎴愬姛锛�')
- this.multipleSelection = []
- // this.form.deptno = ''
- // this.form.stockcode = ''
- this.reset()
- // await this.getProductInHouseOrderSearch()
- await this.getProductInHouseOrderCodeSearch()
+ const openToken = await getTPlusToken() // 鑾峰彇TPlus token
+
+ // console.log(openToken)
+
+ let res
+ const a = 1
+ if (openToken) {
+ if (a === 2) {
+ const RDRecordDetails = []
+ this.multipleSelection.forEach((i, index) => {
+ RDRecordDetails.push({
+ Code: index + 1, // 琛屽彿锛屼粠1寮�濮嬭嚜澧為暱
+ Warehouse: {
+ Code: i.stockcode
+ },
+ Inventory: {
+ Code: i.partcode // 瀛樿揣缂栫爜
+ },
+ BaseQuantity: i.stinhouseqty // 涓昏閲忓崟浣嶆暟閲�
+ // SNObject: {
+ // SnAccountDetails: [
+ // {
+ // SNCode: '00001'
+ // },
+ // {
+ // SNCode: '00002'
+ // }
+ // ]
+ // }
+ })
+ })
+ const D1 = {
+ 'dto': {
+ 'IsModifiedCode': true,
+ 'ExternalCode': this.form.hbillno,
+ 'Code': this.form.hbillno,
+ 'VoucherType': {
+ 'Code': 'ST1002'
+ },
+ 'VoucherDate': handleDatetime(new Date().getTime()),
+ 'BusiType': {
+ 'Code': '03'
+ },
+ 'Warehouse': {
+ 'Code': this.form.stockcode
+ },
+ 'Department': {
+ 'Code': this.form.wkshopcode,
+ 'Name': this.WorkShopArr.find(i => i.torg_code === this.form.wkshopcode).torg_name
+ },
+ 'RDRecordDetails': RDRecordDetails
+ }
+ }
+ res = await axios.post(Vue.prototype.$chanjetBaseUrl + '/tplus/api/v2/productReceive/Create',
+ D1, {
+ headers: {
+ 'openToken': openToken,
+ 'appKey': Vue.prototype.$AppKey,
+ 'appSecret': Vue.prototype.$AppSecret,
+ 'Content-Type': 'application/json'
+ }
+ }
+ )
+ }
+
+ // 鐩墠閮芥墽琛岀殑杩欎釜
+ if (a === 1) {
+ const RDRecordDetails = []
+ this.multipleSelection.forEach((i, index) => {
+ RDRecordDetails.push({
+ Code: index + 1, // 琛屽彿锛屼粠1寮�濮嬭嚜澧為暱
+ SourceVoucherId: i.mpoid ? i.mpoid : '', // 鏉ユ簮鍗曟嵁鐨勫崟鎹甀D
+ BaseQuantity: i.stinhouseqty, // 涓昏閲忓崟浣嶆暟閲�
+ // SourceVoucherDetailId: i.sourceVoucherDetailId, // 鏉ユ簮鍗曟嵁鐨勫搴旀槑缁咺D
+ SourceVoucherDetailId: i.sbid ? i.sbid : '', // 鏉ユ簮鍗曟嵁鐨勫搴旀槑缁咺D
+ Inventory: {
+ Code: i.partcode // 瀛樿揣缂栫爜
+ },
+ IdSourceVoucherType: i.sbid ? 69 : ''
+ })
+ })
+ const D2 = {
+ 'dto': {
+ 'Warehouse': {
+ 'Code': this.form.stockcode// 浠撳簱缂栫爜
+ },
+ 'Code': this.form.hbillno, // 鍗曟嵁缂栫爜
+ 'IsModifiedCode': true,
+ 'BusiType': {
+ 'Code': '03'// 涓氬姟绫诲瀷缂栫爜
+ },
+ 'Department': {
+ 'Code': this.form.wkshopcode// 閮ㄩ棬缂栫爜
+ },
+ 'VoucherDate': handleDatetime(new Date().getTime()), // 鍗曟嵁鏃ユ湡
+ 'RdStyle': {
+ 'Code': '21'// 鍑哄簱绫诲埆缂栫爜
+ },
+ 'RDRecordDetails': RDRecordDetails,
+ // 'Clerk': {
+ // 'Code': this.userArr.find(i => i.name === getCookie('username')).code // 涓氬姟鍛榗ode
+ // // 'Code': '001' // 涓氬姟鍛榗ode
+ // // 'Name': getCookie('username')
+ // },
+ 'ExternalCode': this.form.hbillno,
+ 'VoucherType': {
+ 'Code': 'ST1002'
+ }
+ }
+ }
+ res = await axios.post(Vue.prototype.$chanjetBaseUrl + '/tplus/api/v2/ProductReceiveOpenApi/Create',
+ D2, {
+ headers: {
+ 'openToken': openToken,
+ 'appKey': Vue.prototype.$AppKey,
+ 'appSecret': Vue.prototype.$AppSecret,
+ 'Content-Type': 'application/json'
+ }
+ }
+ )
+ }
+
+ // console.log(res)
+ // console.log(res.data.code)
+ // || res.data === null
+ if (res.data.code === 0) {
+ const TableDetailData = []
+ this.multipleSelection.forEach((i, index) => {
+ TableDetailData.push({
+ 'hbillno': this.form.hbillno, // 鍏ュ簱鍗曞彿
+ 'wocode': i.wo_code, // 宸ュ崟鍙�
+ 'rownumber': (index + 1).toString(), // 琛屽彿
+ 'sourceVoucherId': i.mpoid ? i.mpoid.toString() : '', // 鏉ユ簮鍗曟嵁id
+ 'sourceVoucherCode': i.m_po, // 鏉ユ簮鍗曟嵁缂栧彿
+ 'SourceVoucherDetailId': i.sbid ? i.sbid.toString() : '', // 鏉ユ簮鍗曟嵁鏄庣粏id
+ 'inbarcode': i.inbarcode, // 鍏ュ簱鏉$爜
+ 'idinventory': i.materiel_id ? i.materiel_id.toString() : '', // 瀛樿揣id
+ 'inventorycode': i.partcode, // 瀛樿揣缂栫爜
+ 'idunit': i.unitid ? i.unitid.toString() : '', // 璁¢噺鍗曚綅id
+ 'unitcode': i.unitcode, // 璁¢噺鍗曚綅缂栫爜
+ idwarehouse: i.stockid, // 浠撳簱id
+ warehousecode: i.stockcode, // 浠撳簱缂栫爜
+ 'saleOrderId': i.saleOrderid ? i.saleOrderid.toString() : '', // 閿�鍞崟id
+ 'saleOrderCode': i.saleOrderCode, // 閿�鍞崟鍙�
+ 'saleOrderDetailId': i.saleOrderDetailId ? i.saleOrderDetailId.toString() : '', // 閿�鍞崟鏄庣粏id
+ 'qty': i.good_qty.toString(), // 鍏ュ簱鏁伴噺
+ 'stepcode': i.step_code, // 宸ュ簭缂栫爜
+ 'style': i.style, // 鎶ュ伐绫诲瀷锛欱(鑷埗) S(澶栧崗)
+ 'status': '0' // 鍏ュ簱鍗曠姸鎬侊細0(鏈鏍�) 1(宸插鏍�)
+ })
+ })
+
+ const data = {
+ 'rightcode': '0604', // 鍔熻兘缂栧彿
+ 'incbit': this.form.incbit, // 娴佹按鍙�
+ 'TableData': [
+ [
+ {
+ 'hbillno': this.form.hbillno, // 鍏ュ簱鍗曞彿
+ 'madedate': handleDatetime(this.form.hbdate) + ' 00:00:00', // 鍒跺崟鏃ユ湡锛堝勾鏈堟棩 00:00:00锛�
+ 'hbdate': this.multipleSelection[this.multipleSelection.length - 1].voucherdate,
+
+ sourceVoucherId: [...new Set(this.multipleSelection.map(i => i.mpoid))].length > 1 ? '' : this.multipleSelection[0].mpoid,
+ sourceVoucherCode: [...new Set(this.multipleSelection.map(i => i.m_po))].length > 1 ? '' : this.multipleSelection[0].m_po,
+ saleOrderCode: [...new Set(this.multipleSelection.map(i => i.saleOrderCode))].length > 1 ? '' : this.multipleSelection[0].saleOrderCode,
+
+ 'iddepartment': this.multipleSelection[0].dept_id, // 閮ㄩ棬id
+ 'departmentcode': this.multipleSelection[0].dept_code, // 閮ㄩ棬缂栫爜
+
+ 'idwarehouse': this.stockcodeArr.find(i => i.code === this.form.stockcode).noid, // 浠撳簱id
+ 'warehousecode': this.form.stockcode, // 浠撳簱缂栫爜
+ 'status': '0', // 鍏ュ簱鍗曠姸鎬侊細0(鏈鏍�) 1(宸插鏍�)
+ PurchaseOrderCode: '', // 閲囪喘璁㈠崟鍙�
+ 'remark': '', // 澶囨敞
+ 'create_user': localStorage.getItem('username'), // 鍒涘缓浜哄憳
+ 'create_date': handleDatetime2(new Date()),
+ 'check_user': '', // 瀹℃牳浜哄憳
+ 'check_date': ''// 瀹℃牳鏃堕棿
+ }
+ ],
+ TableDetailData// 琛ㄤ綋
+ ]
+ }
+
+ // console.log(JSON.stringify(data))
+
+ // this.$store.state.app.buttonIsDisabled = true
+ const res = await InHouseOrderSpSeave(data)
+ this.$store.state.app.buttonIsDisabled = false
+ if (res.code === '200') {
+ this.$message.success('鍏ュ簱鎴愬姛锛�')
+ this.multipleSelection = []
+ // this.form.deptno = ''
+ // this.form.stockcode = ''
+ this.reset()
+ // await this.getProductInHouseOrderSearch()
+ await this.getProductInHouseOrderCodeSearch()
+ }
+ } else {
+ // console.log(res.data)
+
+ this.$store.state.app.buttonIsDisabled = false
+ this.$message.error(res.data.message)
+ }
+ } else {
+ this.$store.state.app.buttonIsDisabled = false
}
},
// 閲嶇疆
reset() {
+ // this.form.issouceorder = 'Y'
this.form.saleordercode = '' // 閿�鍞崟鍙�
this.form.wkshopcode = '' // 鐢熶骇杞﹂棿
this.form.erpordercode = ''// 璁㈠崟缂栧彿
@@ -1058,14 +1130,6 @@
::v-deep .el-tabs__item {
padding-right: 0;
-}
-
-::v-deep .el-radio.is-bordered + .el-radio.is-bordered {
- margin: 10px 30px 0 0;
-}
-
-::v-deep .el-radio__label{
- display: none;
}
</style>
<style>
--
Gitblit v1.9.3