Commit 9d82081a authored by 前端-钟卫鹏's avatar 前端-钟卫鹏
parents 438c5643 95c8f37e
......@@ -103,6 +103,13 @@ const TranactionRoute = {
key: 'readyAddOrder',
component: '@/pages/transaction/purchaseOrder/readyAddOrder'
},
{
path: '/memberCenter/tranactionAbility/purchaseOrder/readyAddOrder/orderDetail',
name: 'orderDetail',
key: 'orderDetail',
hideInMenu: true,
component: '@/pages/transaction/purchaseOrder/readyAddOrder/detail'
},
]
}
]
......
......@@ -41,6 +41,10 @@ const serviceConfig = {
},
method: 'get'
},
orderMode: {
url: '/order/rule/configuration/all',
method: 'get'
}
// site: {
// url: '/manage/paas/site/all',
// method: 'get',
......
import React from 'react'
import { Slider, Input, Space } from 'antd'
import { Slider, Input, Space, InputNumber } from 'antd'
const CustomSlider = (props) => {
const value = props.value || 0
......@@ -16,7 +16,7 @@ const CustomSlider = (props) => {
{
isNumber ?
<div>
<Input type='number' className='underline_input' max={max} value={props.value} onChange={e => props.mutators.change(e.target.value)}/>
<InputNumber className='underline_input' min={0} max={max || 0} value={props.value} onChange={fieldValue => props.mutators.change(fieldValue)}/>
</div>
:
<Space>
......
......@@ -10,15 +10,17 @@
}
.underline_input {
max-width: 200px;
width: 200px;
background: none;
border: none;
outline: none;
font-size: 32px;
border-bottom: 1px solid #DFE1E6;
padding: 8px 19px;
text-align: center;
display: inline-block;
display: block;
input {
text-align: center;
}
&:focus{
box-shadow: none;
border-bottom: 1px solid #DFE1E6;
......
......@@ -28,8 +28,15 @@ export interface ShopInfo {
url: string;
}
export interface OrderMode {
value: number;
label: string;
platformType: number;
}
export interface Web {
shopInfo: ShopInfo[];
orderMode: OrderMode[];
}
export interface CountryList {
......
// 离开页面时,如果有编辑过表单,需要进行提示
import { useState } from 'react'
export const useLeavePageWarn = (initState = false) => {
const [isEditForm, setIsEditForm] = useState(initState)
return [isEditForm, setIsEditForm]
}
\ No newline at end of file
......@@ -107,6 +107,7 @@ export default {
'menu.tranactionAbility.purchaseOrder': '采购订单',
'menu.tranactionAbility.purchaseOrder.purchaseOrderSearch': '订单查询',
'menu.tranactionAbility.purchaseOrder.readyAddOrder': '待新增订单',
'menu.tranactionAbility.purchaseOrder.orderDetail': '订单详情',
//物流能力
'menu.logisticsAbility': '物流',
......
import React, {useState, useRef, useEffect} from 'react'
import { history } from 'umi'
import { history, Prompt } from 'umi'
import moment from 'moment'
import { Button, Card, Row, Tabs, Tag } from 'antd'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
......@@ -12,7 +12,7 @@ import './index.less'
import NiceForm from '@/components/NiceForm'
import { repositInSchema, repositOutSchema, repositTabOneSchema } from './schema'
import { createFormActions, FormEffectHooks, FormProvider, FormSpy, createAsyncFormActions } from '@formily/antd'
import { getStepNumber } from '@/utils'
import { getStepNumber, padRequiredMessage } from '@/utils'
import { PublicApi } from '@/services/api'
import { usePageStatus } from '@/hooks/usePageStatus'
import { useInitValue } from '@/formSchema/effects/useInitValue'
......@@ -20,6 +20,7 @@ import { useLinkageUtils } from '@/utils/formEffectUtils'
import { useUnitPreview } from './effects'
import PositionSetting from './components/PositionSetting'
import { useHttpRequest } from '@/hooks/useHttpRequest'
import { useLeavePageWarn } from '@/hooks/useLeavePageWarn'
const addSchemaAction = createFormActions()
const repositInAction = createAsyncFormActions()
......@@ -31,6 +32,7 @@ const AddRepository:React.FC<{}> = (props) => {
} = usePageStatus()
// 获取到的所有仓库, 用于选中后获得仓库库存
const [reposits, setReposits] = useState<any>([])
const [isEdit, setIsEdit] = useState(false)
const { data: foldValue, loading: foldLoading, run: foldFn } = useHttpRequest(PublicApi.postWarehouseFreightSpaceAllotFold)
const { data: exportValue, loading: exportLoading, run: exportFn } = useHttpRequest(PublicApi.postWarehouseFreightSpaceAllotExport)
......@@ -98,6 +100,7 @@ const AddRepository:React.FC<{}> = (props) => {
repositInAction.setFieldValue('NO_SUBMIT2', bringUpTheInventory)
repositInAction.setFieldValue('NO_SUBMIT1', callInInventory)
repositInAction.setFieldValue('foldInventory', '')
tableRecordRef.current.reload && tableRecordRef.current.reload()
}
......@@ -115,6 +118,7 @@ const AddRepository:React.FC<{}> = (props) => {
repositOutAction.setFieldValue('NO_SUBMIT1', bringUpTheInventory)
repositOutAction.setFieldValue('NO_SUBMIT2', callInInventory)
repositOutAction.setFieldValue('foldInventory', 0)
tableRecordRef.current.reload && tableRecordRef.current.reload()
}
......@@ -145,11 +149,16 @@ const AddRepository:React.FC<{}> = (props) => {
if (values['applyMember']) {
params['applyMember'] = values['applyMember'].map(v => v.memberId)
}
setIsEdit(false)
await PublicApi.postWarehouseFreightSpaceUpdata(params)
setTimeout(() => {
history.goBack(-1)
}, 1000)
}
const onPublicFieldChange = () => {
setIsEdit(true)
}
return (
<PageHeaderWrapper
onBack={() => history.goBack()}
......@@ -167,7 +176,7 @@ const AddRepository:React.FC<{}> = (props) => {
<Tabs type='card' defaultActiveKey='tab1' onChange={topTableChange}>
<Tabs.TabPane key='tab1' tab='仓位设置'>
<PositionSetting addSchemaAction={addSchemaAction} schema={repositTabOneSchema} formSubmit={formSubmit}/>
<PositionSetting onFieldChange={onPublicFieldChange} addSchemaAction={addSchemaAction} schema={repositTabOneSchema} formSubmit={formSubmit}/>
</Tabs.TabPane>
<Tabs.TabPane key='tab2' tab='库存调入\调拨'>
<Tabs defaultActiveKey='tab2-1' tabPosition='left'>
......@@ -182,6 +191,9 @@ const AddRepository:React.FC<{}> = (props) => {
onSubmit={handleRespotIn}
effects={async ($, {setFieldState}) => {
const utils = useLinkageUtils()
// FormEffectHooks.onFormInputChange$().subscribe(() => {
// setIsEdit(true)
// })
FormEffectHooks.onFormMount$().subscribe(() => {
const name = spyForm.getFieldValue('name')
const asyncEnums = reposits.map(v => ({
......@@ -190,8 +202,12 @@ const AddRepository:React.FC<{}> = (props) => {
}))
utils.enum('freightSpaceId', asyncEnums)
$('onFieldInputChange', 'freightSpaceId').subscribe(state => {
const numberValue = reposits.find(v => v.id === state.value).inventory || 0
const repositValue = reposits.find(v => v.id === state.value)
const numberValue = repositValue.inventory || 0
utils.value('NO_SUBMIT1', numberValue)
setFieldState('NO_SUBMIT1', state => {
state.props.title = `当前仓位库存(${repositValue.unit})`
})
setFieldState('foldInventory', state => {
state.props["x-component-props"].max = numberValue
state.props["x-component-props"].marks = getStepNumber(numberValue)
......@@ -202,6 +218,10 @@ const AddRepository:React.FC<{}> = (props) => {
{label: name, value: id}
])
utils.value('foldFreightSpaceId', id)
setFieldState('NO_SUBMIT2', state => {
state.props.title = `当前仓位库存(${initValue.unit})`
})
utils.value('NO_SUBMIT2', spyForm.getFieldValue('inventory'))
})
}}
......@@ -225,6 +245,9 @@ const AddRepository:React.FC<{}> = (props) => {
onSubmit={handleRespotOut}
effects={async ($, {setFieldState}) => {
const utils = useLinkageUtils()
// FormEffectHooks.onFormInputChange$().subscribe(() => {
// setIsEdit(true)
// })
FormEffectHooks.onFormMount$().subscribe(() => {
const name = spyForm.getFieldValue('name')
const inventoryNumber = spyForm.getFieldValue('inventory')
......@@ -271,7 +294,7 @@ const AddRepository:React.FC<{}> = (props) => {
</Tabs>
</FormProvider>
</Card>
<Prompt when={isEdit as boolean} message="有未提交的数据, 你确定要离开么?" />
</PageHeaderWrapper>
)
}
......
......@@ -3,7 +3,7 @@ import { usePageStatus, PageStatus } from '@/hooks/usePageStatus'
import { useInitValue } from '@/formSchema/effects/useInitValue'
import EyePreview from '@/components/EyePreview'
import { findItemAndDelete } from '@/utils'
import { ISchemaFormActions, ISchema } from '@formily/antd'
import { ISchemaFormActions, ISchema, FormEffectHooks } from '@formily/antd'
import { useRowSelectionTable } from '@/hooks/useRowSelectionTable'
import { createAddRepositoryEffect, useUnitPreview } from '../effects'
import { PublicApi } from '@/services/api'
......@@ -24,6 +24,7 @@ import Submit from '@/components/NiceForm/components/Submit'
export interface PositionSettingProps {
addSchemaAction: ISchemaFormActions,
schema: ISchema,
onFieldChange?(),
formSubmit?(values)
}
......@@ -35,7 +36,7 @@ const fetchMemberList = async (params) => {
const PositionSetting:React.FC<PositionSettingProps> = (props) => {
const { addSchemaAction, schema, formSubmit } = props
const { addSchemaAction, schema, formSubmit, onFieldChange = () => {} } = props
const [visibleChannelMember, setVisibleChannelMember] = useState(false)
const [visibleChannelRroduct, setVisibleChannelRroduct] = useState(false)
......@@ -296,12 +297,18 @@ const PositionSetting:React.FC<PositionSettingProps> = (props) => {
connectProduct
}}
effects={($, { setFieldState }) => {
FormEffectHooks.onFormInputChange$().subscribe(() => {
onFieldChange()
})
createAddRepositoryEffect(addSchemaAction)
$('onFieldValueChange', 'shopType').subscribe(parentState => {
if (parentState.value) {
console.log('review')
setFieldState('shopIds', state => {
state.props["x-component-props"].dataSource = GlobalConfig.web.shopInfo.filter(v => v.type === parentState.value)
state.props["x-component-props"].dataSource = pageStatus === PageStatus.PREVIEW ?
GlobalConfig.web.shopInfo.filter(v => v.type === parentState.value && state.value.includes(v.id))
:
GlobalConfig.web.shopInfo.filter(v => v.type === parentState.value)
})
}
})
......
......@@ -4,6 +4,7 @@ import { FORM_FILTER_PATH } from '@/formSchema/const';
import { GlobalConfig } from '@/global/config';
import { PublicApi } from '@/services/api';
import { SHOP_TYPES } from '@/constants';
import { padRequiredMessage } from '@/utils';
// 将获取的商城转化为可用类型
const getShopTypeMap = (() => {
......@@ -19,7 +20,7 @@ const getShopTypeMap = (() => {
}, [])
})()
export const repositSchema: ISchema = {
export const repositSchema: ISchema = padRequiredMessage({
type: 'object',
properties: {
megaLayout: {
......@@ -89,7 +90,7 @@ export const repositSchema: ISchema = {
type: 'string',
"x-component": 'SearchSelect',
"x-component-props": {
fetchSearch: PublicApi.getProductSelectGetSelectCategory,
fetchSearch: PublicApi.getProductSelectGetSelectCustomerCategory,
placeholder: '请选择品类',
style: {
width: 160,
......@@ -125,9 +126,9 @@ export const repositSchema: ISchema = {
}
}
}
}
})
export const repositMoreSchema: ISchema = {
export const repositMoreSchema: ISchema = padRequiredMessage({
type: 'object',
properties: {
REPOSIT_TABS: {
......@@ -336,10 +337,10 @@ export const repositMoreSchema: ISchema = {
}
}
}
}
})
// 新增仓位
export const repositDetailSchema: ISchema = {
export const repositDetailSchema: ISchema = padRequiredMessage({
type: 'object',
properties: {
REPOSIT_TABS: {
......@@ -371,7 +372,13 @@ export const repositDetailSchema: ISchema = {
title: '仓位名称',
"x-component-props": {
placeholder: '建议名称:商品名称+商城名称+渠道描述'
}
},
"x-rules": [
{
limitByte: true,
maxByte: 60
}
]
},
shopType: {
type: 'string',
......@@ -527,10 +534,10 @@ export const repositDetailSchema: ISchema = {
}
}
}
}
})
// 仓位设置
export const repositTabOneSchema: ISchema = {
export const repositTabOneSchema: ISchema = padRequiredMessage({
type: 'object',
properties: {
REPOSIT_TABS: {
......@@ -563,7 +570,13 @@ export const repositTabOneSchema: ISchema = {
editable: false,
"x-component-props": {
placeholder: '建议名称:商品名称+商城名称+渠道描述'
}
},
"x-rules": [
{
limitByte: true,
maxByte: 60
}
]
},
shopType: {
type: 'string',
......@@ -720,10 +733,10 @@ export const repositTabOneSchema: ISchema = {
}
}
}
}
})
// 库存调入
export const repositInSchema: ISchema = {
export const repositInSchema: ISchema = padRequiredMessage({
type: 'object',
properties: {
repos_layout: {
......@@ -761,14 +774,14 @@ export const repositInSchema: ISchema = {
'NO_SUBMIT1': {
type: 'object',
readOnly: true,
title: '当前仓位库存(尺)',
"x-component": 'CircleBox',
title: '当前仓位库存',
default: 0
},
'NO_SUBMIT2': {
type: 'object',
title: '当前仓位库存(尺)',
"x-component": 'CircleBox',
title: '当前仓位库存',
default: 0
},
"foldInventory": {
......@@ -801,10 +814,10 @@ export const repositInSchema: ISchema = {
}
}
}
}
})
// 库存调出
export const repositOutSchema: ISchema = {
export const repositOutSchema: ISchema = padRequiredMessage({
type: 'object',
properties: {
repos_layout: {
......@@ -842,14 +855,14 @@ export const repositOutSchema: ISchema = {
'NO_SUBMIT1': {
type: 'object',
readOnly: true,
title: '当前仓位库存(尺)',
"x-component": 'CircleBox',
title: '当前仓位库存',
default: 0
},
'NO_SUBMIT2': {
type: 'object',
title: '当前仓位库存(尺)',
"x-component": 'CircleBox',
title: '当前仓位库存',
default: 0
},
"foldInventory": {
......@@ -882,4 +895,4 @@ export const repositOutSchema: ISchema = {
}
}
}
}
})
export enum OrderModalType {
/**
* 需求报价下单
*/
DEMAND_QUOTATION_ORDER = 206,
/**
* 合并订单下单
*/
CONSOLIDATED_ORDER,
/**
* 渠道直采进货单下单
*/
CHANNEL_DIRECT_PURCHASE_ORDER,
/**
* 渠道直采手工下单
*/
CHANNEL_DIRECT_MINING_ORDER,
/**
* 渠道现货进货单下单
*/
CHANNEL_SPOT_PURCHASE_ORDER,
/**
* 渠道现货手工下单
*/
CHANNEL_SPOT_MANUAL_ORDER,
/**
* 询价报价下单
*/
INQUIRY_QUOTATION_ORDER,
/**
* 进货单下单
*/
PURCHASE_ORDER,
/**
* 手工下单
*/
HAND_ORDER
}
\ No newline at end of file
import React from 'react'
import { history } from 'umi'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import ReutrnEle from '@/components/ReturnEle'
import { usePageStatus, PageStatus } from '@/hooks/usePageStatus'
import { Button, Card } from 'antd'
import { createFormActions } from '@formily/antd'
import { SaveOutlined, LinkOutlined } from '@ant-design/icons'
import NiceForm from '@/components/NiceForm'
import { orderDetailSchema } from './schema'
import { useDetailOrder } from './model/useDetailOrder'
import ModalTable from '@/components/ModalTable'
export interface PurchaseOrderDetailProps {}
const addSchemaAction = createFormActions()
// 采购订单详情页. 包含新增和编辑
const PurchaseOrderDetail:React.FC<PurchaseOrderDetailProps> = (props) => {
const { productColumns } = useDetailOrder()
// 页面进入时, 当前所处的下单模式
const { orderModel } = history.location.query
const { pageStatus } = usePageStatus()
const handleOrderNo = () => {}
const handleOrderMember = () => {}
const orderNoPrice = pageStatus !== PageStatus.PREVIEW && <div className='connectBtn' onClick={handleOrderNo}><LinkOutlined style={{marginRight: 4}}/>选择</div>
const orderMember = pageStatus !== PageStatus.PREVIEW && <div className='connectBtn' onClick={handleOrderMember}><LinkOutlined style={{marginRight: 4}}/>选择</div>
const productAddButton = <Button block type='default' style={{margin: '24px auto'}}>选择订单商品</Button>
return (
<PageHeaderWrapper
onBack={() => history.goBack()}
backIcon={<ReutrnEle description="返回"/>}
className='addRepository'
title={pageStatus === PageStatus.PREVIEW ? '查看订单' : '新建订单'}
extra={[
<Button key="1" onClick={() => addSchemaAction.submit()} type="primary" icon={<SaveOutlined />}>
保存
</Button>,
]}
>
<Card className=''>
<NiceForm
actions={addSchemaAction}
schema={orderDetailSchema}
className='useConnectBtnWrapper'
expressionScope={{
orderNoPrice,
orderMember,
productColumns,
productAddButton
}}
/>
</Card>
<ModalTable
modalTitle='选择订单商品'
columns={productColumns}
/>
</PageHeaderWrapper>
)
}
PurchaseOrderDetail.defaultProps = {}
export default PurchaseOrderDetail
\ No newline at end of file
import React from 'react'
import { history } from 'umi'
import { Card, Button, Space, Dropdown, Menu } from 'antd'
import { StandardTable } from 'god'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
......@@ -67,7 +68,7 @@ const ReadyAddOrder:React.FC<ReadyAddOrderProps> = (props) => {
}}
formilyChilds={{
children: <Space>
<Button icon={<PlusCircleOutlined/>} type='primary'>新建</Button>
<Button icon={<PlusCircleOutlined/>} type='primary' onClick={() => history.push('/memberCenter/tranactionAbility/purchaseOrder/readyAddOrder/orderDetail')}>新建</Button>
<Button>批量提交审核</Button>
<DropDeleteDown>
<Menu onClick={(e) => handleMenuClick(e)}>
......
import React, { useState } from 'react'
export const useDetailOrder = () => {
// const [productDataSource, setProductDataSource] = useState
const productColumns: any[] = [
{
title: '商品ID',
dataIndex: 'id',
align: 'center',
key: 'id',
},
{
title: '商品名称',
dataIndex: 'name',
align: 'center',
key: 'name',
},
{
title: '品类',
dataIndex: 'customerCategoryName',
align: 'center',
key: 'customerCategoryName',
},
{
title: '品牌',
dataIndex: 'brandName',
align: 'center',
key: 'brandName',
},
]
return {
productColumns
}
}
\ No newline at end of file
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { GlobalConfig } from '@/global/config';
export const tableListSchema: ISchema = {
type: 'object',
......@@ -8,7 +9,7 @@ export const tableListSchema: ISchema = {
type: 'string',
"x-component": 'SearchFilter',
'x-component-props': {
placeholder: '搜索',
placeholder: '请输入订单编号',
align: 'flex-end',
},
},
......@@ -28,6 +29,12 @@ export const tableListSchema: ISchema = {
placeholder: '请输入订单摘要',
}
},
"supplyMembersName": {
type: 'string',
"x-component-props": {
placeholder: '请输入供应会员名称'
}
},
"[startCreateTime,endCreateTime]": {
type: 'array',
"x-component": 'daterangepicker',
......@@ -44,4 +51,142 @@ export const tableListSchema: ISchema = {
},
},
}
}
/**
* 订单详情(新增订单, 编辑订单)
*/
// 基本信息
const basicInfo: ISchema = {
type: 'object',
"x-component": 'tabpane',
"x-component-props": {
tab: '基本信息'
},
properties: {
NO_SUBMIT_LAYOUT: {
type: 'object',
"x-component": 'mega-layout',
"x-component-props": {
labelCol: 4,
labelAlign: 'left',
wrapperCol: 10
},
properties: {
orderModel: {
type: 'string',
enum: GlobalConfig.web.orderMode.map(v => { delete v.platformType ;return v}),
title: '下单模式'
},
orderThe: {
type: 'string',
title: '订单摘要',
"x-rules": [
{
limitByte: true,
maxByte: 60
}
]
},
quotationNo: {
type: 'string',
title: '对应报价单号',
"x-component-props": {
disabled: true,
addonAfter: "{{orderNoPrice}}"
},
},
supplyMembersName: {
type: 'string',
title: '供应会员',
"x-component-props": {
disabled: true,
addonAfter: "{{orderMember}}"
},
}
}
},
}
}
// 订单商品
const orderProduct: ISchema = {
type: 'object',
"x-component": 'tabpane',
"x-component-props": {
tab: '订单商品'
},
properties: {
orderProductRequests: {
type: 'array',
"x-component": 'MultTable',
"x-component-props": {
rowKey: 'id',
columns: "{{productColumns}}",
prefix: "{{productAddButton}}"
}
}
}
}
// 支付信息
const payInfo = {
type: 'object',
"x-component": 'tabpane',
"x-component-props": {
tab: '支付信息'
},
properties: {
}
}
// 交付信息
const submitInfo = {
type: 'object',
"x-component": 'tabpane',
"x-component-props": {
tab: '交付信息'
},
properties: {
}
}
// 其他信息
const ortherInfo = {
type: 'object',
"x-component": 'tabpane',
"x-component-props": {
tab: '其他信息'
},
properties: {
}
}
// 流转记录
const transformRecord = {
type: 'object',
"x-component": 'tabpane',
"x-component-props": {
tab: '流转记录'
},
properties: {
}
}
// 新增订单详情
export const orderDetailSchema: ISchema = {
type: 'object',
properties: {
NO_SUBMIT_TABS: {
type: 'object',
"x-component": 'tab',
properties: {
NO_SUBMIT_TABPANE1: basicInfo,
NO_SUBMIT_TABPANE2: orderProduct,
NO_SUBMIT_TABPANE3: payInfo,
NO_SUBMIT_TABPANE4: submitInfo,
NO_SUBMIT_TABPANE5: ortherInfo,
NO_SUBMIT_TABPANE6: transformRecord,
}
}
}
}
\ No newline at end of file
......@@ -203,6 +203,12 @@ export const dupliArr = (arr: any[]) => {
// 获取最小的差距值
export const getDistanceNumber = (target, step, min) => {
// 当递归到只能被1整除时, 直接返回target
if (step === 1) {
return {
[target]: target
}
}
const value = target / step
if (value >= min) {
let num = 0
......@@ -214,17 +220,17 @@ export const getDistanceNumber = (target, step, min) => {
result[target] = target
return result
} else {
return getDistanceNumber(target, step--, min)
return getDistanceNumber(target, --step, min)
}
}
// 将数字拆分成指定区间
export const getStepNumber = (target: number, step?: number) => {
if (target === 0) {
return null
return {}
}
// 最小相差10
const minDistance = 10
const minDistance = 4
step = step || 4
......@@ -392,6 +398,30 @@ export const getQueryStringParams = (url?: string) => {
return queryString.parse(searchParam)
}
// 填充必填的schema message提示
export const padRequiredMessage = (originSchema: ISchema) => {
const messageSwich = (type) => {
return type ? '请选择' : '请输入'
}
const todoFn = (targetSchema) => {
}
Object.entries(originSchema.properties).map(([key, value]) => {
if (value.required) {
const isSelect = value.enum
const message = messageSwich(isSelect) + (value.title || '')
value['x-rules'] = Array.isArray(value['x-rules']) ? value['x-rules'].concat([{ message, required: true }]) : [{message, required: true}]
}
if (value.properties) {
padRequiredMessage(value)
}
return value
})
return originSchema
}
export default {
isArray,
isObject,
......
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