Commit 15e919c3 by wuqian

出库单

parent fb2d8f76
......@@ -438,6 +438,12 @@ export function getInRecordLogApi(inRecordId?: number) {
)
}
// 出库单
export function warehouseOutRecordExport(data: ExportInWarehouseInfo) {
return axios.post<never, BasePaginationData<never>>(
'factory/warehouseOutRecord/export',
data,
)
}
export function getOutRecordStatusTree() {
return axios.get<never, BaseRespData<InterWarehouseTree[]>>(
'factory/warehouseOutRecord/status_tree',
......
......@@ -14,6 +14,7 @@ export interface warehouseSearchForm {
export interface InterProductList {
createTime?: string
id?: number
inventoryId?: number | null
inId?: number
productNo?: string | null //custom的货号
buyStored?: number | null //入库数量
......@@ -87,6 +88,9 @@ export interface InterProductList {
warehouseSku?: string
locationId?: number | null
locationCode?: string | null
inventory?: {
usableInventory?: number
}
}
export interface InterskuList {
id?: number
......
......@@ -108,7 +108,6 @@ export function checkUpdateParams(
removeList = arr1.map((item) => item['id'] as IdType)
}
if (isBackKeyName) {
console.log(isBackKeyName)
// 将列表直接添加到 params 顶层
if (addList.length > 0) params['addList'] = addList || undefined
if (updateList.length > 0)
......
......@@ -31,7 +31,7 @@
<template #top>
<div class="header-filter-form">
<ElForm :model="searchForm" inline>
<ElFormItem label="采购仓库">
<ElFormItem label="仓库">
<ElSelect
v-model="searchForm.warehouseId"
clearable
......@@ -117,10 +117,10 @@
>
删除
</el-button>
<!-- <el-button type="success" @click="handleExport"> 导出 </el-button>
<el-button type="success" @click="handleExport"> 导出 </el-button>
<el-button type="primary" @click="printProductTag">
打印商品SKU标签
</el-button> -->
</el-button>
<el-button
v-if="nodeCode === 'PENDING_AUDIT'"
type="warning"
......@@ -211,14 +211,6 @@
align="center"
></ElTableColumn>
<ElTableColumn
label="物流单号"
show-overflow-tooltip
prop="shipmentNumber"
width="200"
header-align="center"
align="center"
></ElTableColumn>
<ElTableColumn
label="总金额(¥)"
show-overflow-tooltip
width="120"
......@@ -259,6 +251,7 @@
align="center"
></ElTableColumn>
<ElTableColumn
v-if="nodeCode === 'PENDING_SUBMIT'"
width="100"
align="center"
header-align="center"
......@@ -572,13 +565,13 @@
<div class="product-dialog-footer">
<div>
<el-input
v-model="selectSku"
v-model.trim="selectSku"
placeholder="商品SKU"
style="width: 200px; margin: 0 10px"
clearable
size="small"
></el-input>
<el-popover placement="top-start" width="900" trigger="click">
<el-popover placement="top-start" width="1000" trigger="click">
<div v-if="skuData.length > 0" style="height: 50vh">
<ElTable size="small" :data="skuData" height="100%" border>
<ElTableColumn
......@@ -658,14 +651,14 @@
</el-button>
</template>
</el-popover>
<!-- <el-button
<el-button
style="margin-left: 6px"
type="success"
size="small"
@click="addPurchase"
>
批量新增
</el-button> -->
</el-button>
<el-button
type="danger"
style="margin-left: 10px"
......@@ -754,7 +747,7 @@
<el-table-column align="center" prop="number" label="打印数量">
<template #default="{ row }">
<el-input
v-model="row.number"
v-model.number="row.number"
oninput="value=value.replace(/[^\-?\d.]/g,'')"
placeholder="打印数量"
clearable
......@@ -767,6 +760,33 @@
<el-button type="primary" @click="handlePrintProductTag">打印</el-button>
</template>
</el-dialog>
<ElDialog
v-model="addPurchaseVisible"
title="批量添加"
width="500px"
:close-on-click-modal="false"
>
<div>
<el-input
v-model.trim="purchaseTextarea"
type="textarea"
placeholder="请输入库存 SKU"
:rows="5"
minlength="1"
maxlength="1000"
show-word-limit
/>
<div style="margin-top: 12px; color: #777">
{{ '多个字段使用_##_,_##_隔开' }}
</div>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="addPurchaseVisible = false">取消</el-button>
<el-button type="primary" @click="submitPurchase">确认</el-button>
</span>
</template>
</ElDialog>
</template>
<script setup lang="ts">
......@@ -793,9 +813,10 @@ import {
rejectOutRecordApi,
LogListData,
warehouseInfo,
warehouseOutRecordExport,
} from '@/api/warehouse'
// factoryWarehouseInventoryPrint,
// import { filePath } from '@/api/axios.ts'
import { filePath } from '@/api/axios.ts'
import BigNumber from 'bignumber.js'
import { ref, onMounted, watch, nextTick } from 'vue'
import 'element-plus/dist/index.css'
......@@ -962,8 +983,8 @@ const {
{
...searchForm.value,
billStatus: nodeCode.value == 'all' ? 'all' : nodeCode.value,
createTimeStart: tradingTime.value && tradingTime.value[0],
createTimeEnd: tradingTime.value && tradingTime.value[1],
startTime: tradingTime.value && tradingTime.value[0],
endTime: tradingTime.value && tradingTime.value[1],
},
page,
pageSize,
......@@ -1025,42 +1046,120 @@ async function handlePrintProductTag() {
// showPrintDialog.value = false
// window.open(filePath + res.message, '_blank')
}
const batchAddCommodity = async (sku: string): Promise<InterskuList[]> => {
if (!editForm.value.warehouseId) {
ElMessage.error('请选择仓库')
return []
}
try {
const res = await getBySkuAndWarehouseIdApi(editForm.value.warehouseId, sku)
const arr: InterskuList[] = res.data || []
const ids: Record<string, boolean> = {}
// 过滤掉商品列表已经加了的
for (const item of otherPurchaseData.value) {
if (item.warehouseSku !== undefined) {
ids[item.warehouseSku] = true
}
}
// 使用 filter 方法过滤掉已经存在的 SKU
const filteredArr = arr.filter((currentItem: InterskuList) => {
return (
currentItem.warehouseSku === undefined || !ids[currentItem.warehouseSku]
)
})
return filteredArr
} catch (e) {
console.error(e)
return []
}
}
interface InterImportData {
warehouseSku: string
remark?: string | null
[key: string]: unknown
}
// 前端导入Excel
const excelFieldMap: Record<string, keyof InterProductList> = {
SKU图片: 'skuImage',
const excelFieldMap: Record<string, keyof InterImportData> = {
// SKU图片: 'skuImage',
商品SKU: 'warehouseSku',
SKU名称: 'skuName',
出库数量: 'outCount',
可用库存数量: 'usableInventory',
'成本价(¥)': 'costPrice',
'总成本(¥)': 'totalPrice',
库位: 'locationCode',
// SKU名称: 'skuName',
// 出库数量: 'outCount',
// 可用库存数量: 'usableInventory',
// '成本价(¥)': 'costPrice',
// '总成本(¥)': 'totalPrice',
// 库位: 'locationCode',
备注: 'remark',
}
const handleLocalImport = ({
const handleLocalImport = async ({
path,
data,
}: {
path: string
data: InterProductList[]
data: InterImportData[]
}) => {
const result: InterProductList[] = data.map((item) => {
const obj = {} as InterProductList
Object.keys(excelFieldMap).forEach((excelKey) => {
const field = excelFieldMap[excelKey] as keyof InterProductList
const value = item[excelKey]
// // 类型转换和默认值
// if (['outCount', 'costPrice', 'totalPrice'].includes(field)) {
// value = value == null || value === '' ? 0 : Number(value)
// } else {
// value = value == null ? '' : value
// }
obj[field] = value as InterProductList[typeof field]
// 1. 将原始导入数据映射到 InterImportData[]
const importedData: InterImportData[] = data
.map((item) => {
const obj: InterImportData = { warehouseSku: '' }
Object.keys(excelFieldMap).forEach((excelKey) => {
const field = excelFieldMap[excelKey]
const value = item[excelKey]
// 根据目标字段进行可能的类型转换或处理
if (field === 'warehouseSku') {
obj[field] = typeof value === 'string' ? value : String(value ?? '') // 转换为字符串,处理 null/undefined
} else if (field === 'remark') {
obj[field] =
typeof value === 'string'
? value
: value === null || value === undefined
? null
: String(value) // 备注可以是 string | null
} else {
// 处理其他字段
obj[field] = value
}
})
return obj
})
return obj
.filter((item) => item.warehouseSku) // 过滤掉没有 SKU 的行
if (importedData.length === 0) {
ElMessage.warning('导入数据中没有有效的商品SKU')
importDialogVisible.value = false
return
}
// 2. 提取导入的 SKU 列表
const importedSkus = importedData.map((item) => item.warehouseSku).join(',')
// 3. 调用 batchAddCommodity 获取商品的完整信息并过滤掉已有的 SKU
const filteredSkusList = await batchAddCommodity(importedSkus) // 使用 await 等待结果
if (filteredSkusList.length === 0) {
ElMessage.warning('导入的商品SKU已存在或无效')
importedFileUrl.value = path
importDialogVisible.value = false
return
}
// 4. 将备注信息合并到获取到的商品列表中
const mergedProductList = filteredSkusList.map((skuItem) => {
// 在导入数据中找到匹配的备注信息
const importedItem = importedData.find(
(item) => item.warehouseSku === skuItem.warehouseSku,
)
return {
skuImage: skuItem.image,
warehouseSku: skuItem.warehouseSku,
skuName: skuItem.skuName,
productNo: skuItem.productNumber,
locationCode: skuItem.locationCode ?? '',
locationId: skuItem.locationId ?? null,
costPrice: skuItem.price,
outCount: null, // 出库数量初始为 null
totalPrice: null,
usableInventory: skuItem.usableInventory,
inventoryId: skuItem.id,
remark: importedItem?.remark ?? null,
} as InterProductList // 明确类型
})
otherPurchaseData.value = result
// 5. 更新 otherPurchaseData
otherPurchaseData.value = [...otherPurchaseData.value, ...mergedProductList]
importedFileUrl.value = path
importDialogVisible.value = false
}
......@@ -1069,10 +1168,42 @@ const exportForm = ref({
delivery: false,
resource: '',
})
// const handleExport = () => {
// exportVisible.value = true
// }
const submitExportForm = () => {}
const handleExport = () => {
exportVisible.value = true
}
const submitExportForm = async () => {
if (exportForm.value.resource === '') {
return ElMessage.error('请选择导出类型')
}
let purchaseIds = []
let exportTotal: number | undefined = undefined
const params: AnyObject = {}
const resourceType = Number(exportForm.value.resource)
if (resourceType === 0) {
purchaseIds = tableData.value.map((el: InterWarehousePage) => el.id)
} else if (resourceType === 1) {
purchaseIds = selections.value.map((el: InterWarehousePage) => el.id)
} else if (resourceType === 2) {
purchaseIds = []
exportTotal = total.value
params.billStatus = nodeCode.value == 'all' ? 'all' : nodeCode.value
}
params.idList = purchaseIds
if (exportTotal !== undefined) {
params.total = exportTotal
}
try {
const res = await warehouseOutRecordExport({
showDetail: exportForm.value.delivery,
...params,
...searchForm.value,
})
window.open(filePath + res.message, '_blank')
exportVisible.value = false
} catch (e) {
exportVisible.value = false
}
}
const getWarehouseList = async () => {
try {
const res = await warehouseInfoGetAll()
......@@ -1099,7 +1230,25 @@ const selectbySku = async () => {
editForm.value.warehouseId,
selectSku.value,
)
skuData.value = res.data || []
const arr: InterskuList[] = res.data || []
const ids: Record<string, boolean> = {}
// 过滤掉商品列表已经加了的
for (const item of otherPurchaseData.value) {
if (item.warehouseSku !== undefined) {
ids[item.warehouseSku] = true
}
}
for (let i = 0; i < arr.length; i++) {
const currentItem: InterskuList = arr[i]
if (
currentItem.warehouseSku !== undefined &&
ids[currentItem.warehouseSku]
) {
arr.splice(i, 1)
i--
}
}
skuData.value = arr || []
} catch (e) {
console.error(e)
}
......@@ -1115,6 +1264,7 @@ const skudblclick = (val: InterskuList) => {
image = '',
locationId = null,
usableInventory = null,
id = null,
} = val || {}
otherPurchaseData.value = [
...otherPurchaseData.value,
......@@ -1129,6 +1279,7 @@ const skudblclick = (val: InterskuList) => {
outCount: null, //出库数量
totalPrice: null,
usableInventory, //可用库存数量
inventoryId: id,
},
]
// 使用filter代替forEach+splice,时间复杂度从O(n^2)降到O(n)
......@@ -1203,8 +1354,21 @@ const addDialog = async (i: number, v: InterWarehousePage | null) => {
const getProduct = async (id: number | undefined) => {
try {
const res = await getWarehouseOutRecordDetailApi(id)
const productList = res.data?.productList
const newProductList = (Array.isArray(productList) ? productList : []).map(
(item: InterProductList) => {
const { inventory, ...rest } = item
return {
...rest,
usableInventory: inventory?.usableInventory ?? null,
}
},
)
if (res.data) {
res.data.productList = newProductList
}
editForm.value = JSON.parse(JSON.stringify(res.data))
otherPurchaseData.value = res.data?.productList || []
otherPurchaseData.value = newProductList || []
} catch (e) {
console.error(e)
}
......@@ -1415,7 +1579,7 @@ const upSection = async () => {
editForm.value as unknown as AnyObject,
'id',
{
productList: 'warehouseSku',
productList: 'id',
},
)
try {
......@@ -1428,9 +1592,36 @@ const upSection = async () => {
console.error(e)
}
}
// const addPurchase = async () => {
// if (!editForm.value.warehouseId) return ElMessage.error('请选择仓库')
// }
const addPurchaseVisible = ref(false)
const purchaseTextarea = ref(null)
const addPurchase = async () => {
addPurchaseVisible.value = true
}
const submitPurchase = async () => {
if (!purchaseTextarea.value) {
ElMessage.warning('请输入库存 SKU')
return
}
const filteredSkusList = await batchAddCommodity(purchaseTextarea.value)
const mergedProductList = filteredSkusList.map((skuItem) => {
return {
skuImage: skuItem.image,
warehouseSku: skuItem.warehouseSku,
skuName: skuItem.skuName,
productNo: skuItem.productNumber,
locationCode: skuItem.locationCode ?? '',
locationId: skuItem.locationId ?? null,
costPrice: skuItem.price,
outCount: null,
totalPrice: null,
usableInventory: skuItem.usableInventory,
inventoryId: skuItem.id,
remark: null,
} as InterProductList
})
otherPurchaseData.value = [...otherPurchaseData.value, ...mergedProductList]
addPurchaseVisible.value = false
}
const deleteOtherWarehousing = () => {
const arr = otherWarehouseSelection.value
if (arr.length === 0) return
......@@ -1442,8 +1633,8 @@ const deleteOtherWarehousing = () => {
const importDialogVisible = ref(false)
const importedFileUrl = ref('')
const importData = async () => {
// if (!editForm.value.warehouseId) return ElMessage.error('请选择仓库')
importDialogVisible.value = true
importedFileUrl.value = ''
}
const handleBatchDelete = async () => {
if (!selections.value.length) {
......@@ -1465,11 +1656,6 @@ const nodeClick = (data: InterWarehouseTree) => {
sessionStorage.setItem('InRecord_NodeCode', data.code ?? '')
search()
}
// const detailPager = ref({
// page: 1,
// rows: 100,
// total: 0,
// })
const searchDetail = async () => {
try {
const res = await getItemListByIdApi(currentRow.value?.id)
......@@ -1490,10 +1676,6 @@ const locationList = ref<ILocation[]>([])
const locationLoading = ref(false)
const fetchLocationList = async (query: string) => {
// if (!query) {
// locationList.value = []
// return
// }
if (!editForm.value.warehouseId) return
locationLoading.value = true
try {
......
......@@ -446,12 +446,6 @@
/>
</div>
</div>
<!-- <template #footer>
<span class="dialog-footer">
<el-button @click="importDialogVisible = false">取消</el-button>
<el-button type="primary" @click="packedData">确认</el-button>
</span>
</template> -->
</ElDialog>
<ElDialog
v-model="newDialogVisible"
......@@ -607,7 +601,7 @@
<div class="product-dialog-footer">
<div>
<el-input
v-model="selectSku"
v-model.trim="selectSku"
placeholder="商品SKU"
style="width: 200px; margin: 0 10px"
clearable
......@@ -693,14 +687,14 @@
</el-button>
</template>
</el-popover>
<!-- <el-button
<el-button
style="margin-left: 6px"
type="success"
size="small"
@click="addPurchase"
>
批量新增
</el-button> -->
</el-button>
<el-button
type="danger"
style="margin-left: 10px"
......@@ -789,7 +783,7 @@
<el-table-column align="center" prop="number" label="打印数量">
<template #default="{ row }">
<el-input
v-model="row.number"
v-model.number="row.number"
oninput="value=value.replace(/[^\-?\d.]/g,'')"
placeholder="打印数量"
clearable
......@@ -802,6 +796,33 @@
<el-button type="primary" @click="handlePrintProductTag">打印</el-button>
</template>
</el-dialog>
<ElDialog
v-model="addPurchaseVisible"
title="批量添加"
width="500px"
:close-on-click-modal="false"
>
<div>
<el-input
v-model.trim="purchaseTextarea"
type="textarea"
placeholder="请输入库存 SKU"
:rows="5"
minlength="1"
maxlength="1000"
show-word-limit
/>
<div style="margin-top: 12px; color: #777">
{{ '多个字段使用_##_,_##_隔开' }}
</div>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="addPurchaseVisible = false">取消</el-button>
<el-button type="primary" @click="submitPurchase">确认</el-button>
</span>
</template>
</ElDialog>
</template>
<script setup lang="ts">
......@@ -1078,41 +1099,107 @@ async function handlePrintProductTag() {
showPrintDialog.value = false
window.open(filePath + res.message, '_blank')
}
const batchAddCommodity = async (sku: string): Promise<InterskuList[]> => {
if (!editForm.value.warehouseId) {
ElMessage.error('请选择仓库')
return []
}
try {
const res = await getBySkuApi(editForm.value.warehouseId, sku)
const arr: InterskuList[] = res.data || []
const ids: Record<string, boolean> = {}
// 过滤掉商品列表已经加了的
for (const item of otherPurchaseData.value) {
if (item.warehouseSku !== undefined) {
ids[item.warehouseSku] = true
}
}
// 使用 filter 方法过滤掉已经存在的 SKU
const filteredArr = arr.filter((currentItem: InterskuList) => {
return currentItem.sku === undefined || !ids[currentItem.sku]
})
return filteredArr
} catch (e) {
console.error(e)
return []
}
}
interface InterImportData {
warehouseSku: string
remark?: string | null
[key: string]: unknown
}
// 前端导入Excel
const excelFieldMap: Record<string, keyof InterProductList> = {
SKU图片: 'skuImage',
// SKU图片: 'skuImage',
商品SKU: 'warehouseSku',
SKU名称: 'skuName',
// SKU名称: 'skuName',
入库数量: 'buyStored',
'成本价(¥)': 'costPrice',
'总成本(¥)': 'totalPrice',
库位: 'locationCode',
// '成本价(¥)': 'costPrice',
// '总成本(¥)': 'totalPrice',
// 库位: 'locationCode',
备注: 'remark',
}
const handleLocalImport = ({
const handleLocalImport = async ({
path,
data,
}: {
path: string
data: InterProductList[]
data: InterImportData[]
}) => {
const result: InterProductList[] = data.map((item) => {
const obj = {} as InterProductList
Object.keys(excelFieldMap).forEach((excelKey) => {
const field = excelFieldMap[excelKey] as keyof InterProductList
const value = item[excelKey]
// // 类型转换和默认值
// if (['buyStored', 'costPrice', 'totalPrice'].includes(field)) {
// value = value == null || value === '' ? 0 : Number(value)
// } else {
// value = value == null ? '' : value
// }
obj[field] = value as InterProductList[typeof field]
// 1. 将原始导入数据映射到 InterImportData[]
const importedData: InterImportData[] = data
.map((item) => {
const obj: InterImportData = { warehouseSku: '' }
Object.keys(excelFieldMap).forEach((excelKey) => {
const field = excelFieldMap[excelKey]
const value = item[excelKey]
obj[field] = value
})
return obj
})
return obj
.filter((item) => item.warehouseSku) // 过滤掉没有 SKU 的行
if (importedData.length === 0) {
ElMessage.warning('导入数据中没有有效的商品SKU')
importDialogVisible.value = false
return
}
// 2. 提取导入的 SKU 列表
const importedSkus = importedData.map((item) => item.warehouseSku).join(',')
// 3. 调用 batchAddCommodity 获取商品的完整信息并过滤掉已有的 SKU
const filteredSkusList = await batchAddCommodity(importedSkus) // 使用 await 等待结果
if (filteredSkusList.length === 0) {
ElMessage.warning('导入的商品SKU已存在或无效')
importedFileUrl.value = path
importDialogVisible.value = false
return
}
// 4. 将备注信息合并到获取到的商品列表中
const mergedProductList = filteredSkusList.map((skuItem) => {
// 在导入数据中找到匹配的备注信息
const importedItem = importedData.find(
(item) => item.warehouseSku === skuItem.sku,
)
const amount = new BigNumber(importedItem?.buyStored)
.multipliedBy(skuItem.factoryPrice)
.toFixed(2)
return {
skuImage: skuItem.image,
warehouseSku: skuItem.sku,
skuName: skuItem.skuName,
productNo: skuItem.productNo,
locationCode: skuItem.locationCode ?? '',
locationId: skuItem.locationId ?? null,
costPrice: skuItem.factoryPrice,
buyStored: importedItem?.buyStored ?? null,
totalPrice: Number(amount),
usableInventory: skuItem.usableInventory,
remark: importedItem?.remark ?? null,
} as InterProductList // 明确类型
})
otherPurchaseData.value = result
// 5. 更新 otherPurchaseData
otherPurchaseData.value = [...otherPurchaseData.value, ...mergedProductList]
importedFileUrl.value = path
importDialogVisible.value = false
}
......@@ -1416,31 +1503,6 @@ const addOtherCurrency = async () => {
return
}
}
// 看新增后要不要打印标签
// try {
// if (!editId.value) {
// await addUserApi({
// ...editForm.value,
// supperMark: Number(editForm.value.supperMark),
// status: Number(editForm.value.status),
// })
// } else {
// await updateUserApi({
// ...editForm.value,
// supperMark: Number(editForm.value.supperMark),
// status: Number(editForm.value.status),
// })
// }
// ElMessage({
// message: '保存成功',
// type: 'success',
// offset: window.innerHeight / 2,
// })
// newDialogVisible.value = false
// search()
// } catch (e) {
// return
// }
if (!formId.value) {
addSection()
} else {
......@@ -1508,9 +1570,35 @@ const upSection = async () => {
console.error(e)
}
}
// const addPurchase = async () => {
// if (!editForm.value.warehouseId) return ElMessage.error('请选择仓库')
// }
const addPurchaseVisible = ref(false)
const purchaseTextarea = ref(null)
const addPurchase = async () => {
addPurchaseVisible.value = true
}
const submitPurchase = async () => {
if (!purchaseTextarea.value) {
ElMessage.warning('请输入库存 SKU')
return
}
const filteredSkusList = await batchAddCommodity(purchaseTextarea.value)
const mergedProductList = filteredSkusList.map((skuItem) => {
return {
skuImage: skuItem.image,
warehouseSku: skuItem.sku,
skuName: skuItem.skuName,
productNo: skuItem.productNo,
locationCode: skuItem.locationCode ?? '',
locationId: skuItem.locationId ?? null,
costPrice: skuItem.factoryPrice,
buyStored: null,
totalPrice: null,
usableInventory: skuItem.usableInventory,
remark: null,
} as InterProductList
})
otherPurchaseData.value = [...otherPurchaseData.value, ...mergedProductList]
addPurchaseVisible.value = false
}
const deleteOtherWarehousing = () => {
const arr = otherWarehouseSelection.value
if (arr.length === 0) return
......@@ -1522,8 +1610,8 @@ const deleteOtherWarehousing = () => {
const importDialogVisible = ref(false)
const importedFileUrl = ref('')
const importData = async () => {
// if (!editForm.value.warehouseId) return ElMessage.error('请选择仓库')
importDialogVisible.value = true
importedFileUrl.value=''
}
const handleBatchDelete = async () => {
if (!selections.value.length) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment