Commit 7fd401c9 authored by Bill's avatar Bill

fix: 积分下单供应会员bug

parent 3eb9244c
......@@ -20,6 +20,7 @@ import ProcurementRoute from './procurementRoute';
import { callForBidsRoute } from './procurementRoute/callForBids';
import { purchaseInquiryRoute } from './procurementRoute/purchaseInquiry';
import contracRoute from './contracRoute';
const fuck = asyncRoutes.filter((_row) => !_row.path.includes('contract'));
// export const routes = [CommodityRoute, MemberRoute, ShopRoute, ChannelRoute, TranactionRoute, AfterService, PayandSettleRoute, LogisticsRoute, AuthConfigRoute, HandlingRoute, BalaceRoute]
const memberCenterRoute = {
......@@ -58,11 +59,11 @@ const memberCenterRoute = {
// ShopRoute,
// CommodityRoute,
// srm开发临时使用...
ProcurementRoute,
// ProcurementRoute,
// // 合同能力
// contracRoute,
//...
// ...asyncRoutes,
...fuck,
{
path: '/memberCenter/noAuth',
auth: false,
......
......@@ -4,9 +4,9 @@
* @Description: 应付账款结算
*/
import React, { useRef } from 'react';
import React, { useRef, useCallback, useEffect, useState } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { Button, Card, DatePicker} from 'antd';
import { Button, Card, DatePicker, Modal} from 'antd';
import NiceForm from '@/components/NiceForm';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { createFormActions } from '@formily/antd';
......@@ -21,11 +21,12 @@ import EyePreview from '@/components/EyePreview';
import { Moment } from 'moment';
import { payStatus } from '../../common';
import { fetchOptions } from '../../common'
import useFetchColumns from '../../hooks/useFetchColumns';
import UploadVoucherModal from '../../components/UploadVoucherModal';
import Voucher from '../../components/Voucher';
const { RangePicker } = DatePicker;
const formActions = createFormActions();
// 应付账款 - 付款方查看凭证, 能力中心
const PAYABLE_PAYER = 1;
interface SearchParams {
settlementName?: string,
payName?: string,
......@@ -41,12 +42,14 @@ interface SearchParams {
const SettlementList = () => {
const ref = useRef<any>({})
const { columns, manualStatus, payModalVisible, balanceInfo, payModalOnCancel, viewModalonCancel, viewVisible, payVoucherInfo } = useFetchColumns("payable");
const [files, setFiles] = useState<any>([]);
/**
* 分页查询
* @param {params: SearchParams}
*/
const fetchListData = async (params: any) => {
const fetchListData = useCallback(async (params: any) => {
const searchParams = {
...params,
orderType: params.orderType || 0,
......@@ -55,72 +58,36 @@ const SettlementList = () => {
// /settle/accounts/member/settlement/pagePayableSettlement
const { data } = await PublicApi.getSettleAccountsMemberSettlementPagePayableSettlement(searchParams);
return data
}
const columns = [
{
title: '结算单号',
dataIndex: 'settlementNo',
render: (text, record) => {
const prefix = `/memberCenter/balance/accountsPayable/settlementList/`;
const url = record.orderType === 2 ? `logisticsDetail` : `productNoticeSettlementDetail`;
return (
<EyePreview url={`${prefix}${url}?id=${record.id}`} >
{record.settlementNo}
</EyePreview>
)
}
},
{title: '结算日期', dataIndex: 'settlementDate'},
{title: '结算方式', dataIndex: 'settlementWayName'},
{title: '结算方', dataIndex: 'settlementName'},
{title: '结算单据类型', dataIndex: 'orderTypeName'},
{title: '总单数', dataIndex: 'totalCount'},
{title: '结算金额', dataIndex: 'amount'},
{title: '结算时间', dataIndex: 'settlementTime'},
{title: '支付方式', dataIndex: 'payWayName'},
{
title: '结算状态', dataIndex: 'status',
filters: payStatus,
onFilter: (value: number, record: any) => record.status == value,
render: (text: string, record: any) => {
return (
<StatusTag status={record.status} />
)
}
},
{
title: '操作',
render: (text: string, record: any) => {
if(record.status === 1) {
return <a onClick={() => handleManualsettlement(record.id)}>手动结算</a>
}
return (
<StatusActions
status={record.status <= 2 ? record.status : 4 }
id={record.id}
excludes={[1, 3]}
settlementId={record.memberId}
roleId={record.roleId}
handleUpload={handleUploadVoucher}
type={PAYABLE_PAYER}
/>
)
}
}
]
}, [])
/**
*
* @param params 手动结算
* 手动结算
*/
const handleManualsettlement = (id) => {
PublicApi.postReportSettlementMemberManualSettlement({id: id})
.then(({data, code}) => {
const fetchManualSettlement = useCallback(async (id: number) => {
const { code, data } = await PublicApi.postReportSettlementMemberManualSettlement({id})
if(code === 1000) {
formActions.submit();
}
})
}, [])
useEffect(() => {
if (manualStatus !== null) {
fetchManualSettlement(manualStatus)
}
}, [manualStatus])
const fetchVouchers = useCallback(async (id: number) => {
const { code, data } = await PublicApi.getSettleAccountsMemberSettlementGetPayablePayProve({id: id.toString()})
if (code === 1000) {
setFiles(data);
}
}, [])
useEffect(() => {
if (payVoucherInfo !== null) {
fetchVouchers(payVoucherInfo.id);
}
}, [payVoucherInfo])
/**
* 上传凭证
......@@ -183,6 +150,18 @@ const SettlementList = () => {
}
/>
</Card>
<UploadVoucherModal
visible={payModalVisible}
id={balanceInfo?.id}
roleId={balanceInfo?.roleId}
settlementId={balanceInfo?.settlementId}
handleUpload={handleUploadVoucher}
onCancel={payModalOnCancel}
/>
<Modal width={548} title="查看付款凭证" onCancel={viewModalonCancel} visible={viewVisible} footer={null}>
{/* <WrapVoucher id={props.id} type={props.type} /> */}
<Voucher files={files} />
</Modal>
</PageHeaderWrapper>
)
}
......
/*
* @Author: Bill
* @Date: 2020-10-20 10:54:00
* @Description: 积分结算详情页
*/
import React, { useRef, useState, useEffect } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { Card, PageHeader, Descriptions, Button, DatePicker} from 'antd';
import { history } from 'umi';
import AvatarWrap from '@/components/AvatarWrap';
import NiceForm from '@/components/NiceForm';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { createFormActions } from '@formily/antd';
import { StandardTable } from 'god';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { useAsyncInitSelect } from '@/formSchema/effects/useAsyncInitSelect';
import { detailSchema } from './schema'
import { usePageStatus } from '@/hooks/usePageStatus';
import { PublicApi } from '@/services/api';
import StatusTag from '../../components/StatusTag'
import { productNoticecolumns } from '../../common/columns';
import { priceFormat } from '@/utils/numberFomat';
import useFetchBillData from '../../hooks/useFetchBillData';
const RangePicker = DatePicker.RangePicker;
const formActions = createFormActions();
const OrderDetail: React.FC = () => {
const { ref, infoDetail, fetchListData, handleSearch } = useFetchBillData(PublicApi.getSettleAccountsMemberSettlementGetPayableDetail);
const { id } = usePageStatus();
return (
<PageHeaderWrapper
title={
<>
<PageHeader
style={{ padding: '0' }}
onBack={() => history.goBack()}
title={
<AvatarWrap
info={{
aloneTxt: '单',
name: ""
}}
extra={(
<span style={{ fontSize: 16, fontWeight: 'bold', color: "#303133" }}>结算单号:{infoDetail?.settlementNo}</span>
)}
/>
}
>
<Descriptions
column={3}
style={{
padding: '0 32px',
}}
>
<Descriptions.Item label="结算日期">{infoDetail?.settlementDate}</Descriptions.Item>
<Descriptions.Item label="结算单数">{infoDetail?.totalCount}</Descriptions.Item>
<Descriptions.Item label="结算金额">{priceFormat(infoDetail?.amount)}</Descriptions.Item>
<Descriptions.Item label="结算方">{infoDetail?.settlementName}</Descriptions.Item>
<Descriptions.Item label="结算方式">{infoDetail?.settlementWayName}</Descriptions.Item>
<Descriptions.Item label="外部状态"><StatusTag text={infoDetail?.statusName}></StatusTag></Descriptions.Item>
</Descriptions>
</PageHeader>
</>
}
>
<Card>
<StandardTable
tableProps={{
rowKey: 'orderNo',
}}
columns={productNoticecolumns}
currentRef={ref}
fetchTableData={(params: any) => fetchListData(PublicApi.getSettleAccountsMemberSettlementPagePayableOrderSettlement, { settlementId: id, ...params })}
controlRender={
<NiceForm
actions={formActions}
components={{RangePicker}}
expressionScope={{
exportBtn: (
<div>
<Button>导出</Button>
</div>
)
}}
effects={($, actions) => {
useStateFilterSearchLinkageEffect($, actions, 'megaLayout.topLayout.orderNo', FORM_FILTER_PATH);
// useAsyncInitSelect(
// ['innerStatus', 'outerStatus'],
// fetchSelectOptions,
// );
}}
schema={detailSchema}
onSubmit={handleSearch}
/>
}
/>
</Card>
</PageHeaderWrapper>
)
}
export default OrderDetail
......@@ -4,9 +4,9 @@
* @Description: 应付账款结算
*/
import React, { useRef } from 'react';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { Card, DatePicker} from 'antd';
import { Card, DatePicker, Modal, Space, Button} from 'antd';
import NiceForm from '@/components/NiceForm';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { createFormActions } from '@formily/antd';
......@@ -15,19 +15,19 @@ import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilte
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
import { schema } from './schema';
import { PublicApi } from '@/services/api';
import StatusActions from '../../components/StatusActions';
import StatusTag from '../../components/StatusTag';
import EyePreview from '@/components/EyePreview';
import { payStatus } from '../../common';
import { fetchOptions } from '../../common';
import useFetchColumns from '../../hooks/useFetchColumns'
import Voucher from '../../components/Voucher';
import ConfirmAccount from '../../components/ConfirmAccount';
const { RangePicker } = DatePicker;
const formActions = createFormActions();
// 应收账款管理-收款方查看凭证, 能力中心
const RECEIABLE_BENEFICIARY = 2;
const SettlementList = () => {
const ref = useRef<any>({})
const [files, setFiles] = useState<any>([]);
const { columns, confirmPayInfo, confirmPayVisible, reconciliationInfo, reconciliationVisible, viewVisible, payVoucherInfo, viewModalonCancel, confirmPayOnCancel, reconciliationOnCancel } = useFetchColumns("receiveable")
const fetchListData = async (params) => {
const searchParams = {
...params,
......@@ -38,99 +38,40 @@ const SettlementList = () => {
const { data } = await PublicApi.getSettleAccountsMemberSettlementPageReceivableSettlement(searchParams);
return data
}
const columns = [
{
title: '结算单号',
dataIndex: 'settlementNo',
render: (text, record) => {
const prefix = `/memberCenter/balance/accountsReceivable/settlementList/`;
const url = record.orderTypeName === '物流单' ? `logisticsDetail` : `productNoticeSettlementDetail`;
return (
<EyePreview url={`${prefix}${url}?id=${record.id}`} >
{record.settlementNo}
</EyePreview>
)
}
},
{title: '结算日期', dataIndex: 'settlementDate'},
{title: '结算方式', dataIndex: 'settlementWayName'},
{title: '付款方', dataIndex: 'payName'},
{title: '结算单据', dataIndex: 'orderTypeName'},
{title: '总单数', dataIndex: 'totalCount'},
{title: '结算金额', dataIndex: 'amount'},
{title: '结算时间', dataIndex: 'settlementTime'},
{title: '支付方式', dataIndex: 'payWayName'},
{
title: '结算状态', dataIndex: 'status',
filters: payStatus,
onFilter: (value: number, record: any) => record.status == value,
render: (text, record) => {
return (
<StatusTag status={record.status || 1} />
)
}
},
{
title: '操作',
render: (text, record) => {
return (
<StatusActions
excludes={[2]}
id={record.id}
type={RECEIABLE_BENEFICIARY}
status={record.status}
settlementDate={record.settlementDate}
payName={record.payName}
handleReconciledComfirm={handleConfirm}
handleComfirmInCompletePayment={handleComfirmInCompletePayment}
handleComfirmCompletePayment={handleComfirmCompletePayment}
/>
)
}
}
]
/**
* 确认对账
* @param {cancel: function, id: number} cancel 为关闭回调函数
* 确认对账完成
*/
const handleConfirm = (params: any) => {
PublicApi.postSettleAccountsMemberSettlementConfirmAccountComplete({settlementId: params.id})
.then((data) => {
if(data.code === 1000) {
params.onCancel();
const handleConfirm = async (params: { id: number }) => {
const { code, data } = await PublicApi.postSettleAccountsMemberSettlementConfirmAccountComplete({settlementId: params.id});
if (code === 1000) {
reconciliationOnCancel();
formActions.submit();
}
})
}
/**
* 确认未到款
* @param {onCancel:function, id: number, status: number}
* 确认付款凭证
*/
const handleComfirmInCompletePayment = (params: any) => {
PublicApi.postSettleAccountsMemberSettlementConfirmPayProve({id: params.id, status: params.status})
.then((data) => {
if(data.code === 1000) {
const handleConfirmPayStatus = async (params: { status: 0 | 1, id: number }) => {
const { code } = await PublicApi.postSettleAccountsMemberSettlementConfirmPayProve({id: params.id, status: params.status});
if (code) {
confirmPayOnCancel();
formActions.submit();
params.onCancel();
}
})
}
/**
* 确认到款
* @param {onCancel:function, id: number, status: number}
*/
const handleComfirmCompletePayment = (params: any) => {
PublicApi.postSettleAccountsMemberSettlementConfirmPayProve({id: params.id, status: params.status})
.then((data) => {
if(data.code === 1000) {
formActions.submit();
params.onCancel();
const fetchVouchers = useCallback(async (id: number) => {
const { code, data } = await PublicApi.getSettleAccountsMemberSettlementGetReceivablePayProve({id: id.toString()})
if (code === 1000) {
setFiles(data);
}
})
}, [])
useEffect(() => {
if (payVoucherInfo !== null) {
fetchVouchers(payVoucherInfo.id);
}
}, [payVoucherInfo])
/**
* 搜索
......@@ -179,6 +120,43 @@ const SettlementList = () => {
}
/>
</Card>
<Modal
width={400}
title="确认对账完成"
visible={reconciliationVisible}
onCancel={reconciliationOnCancel}
onOk={() => handleConfirm({ id: reconciliationInfo?.id})}
>
<ConfirmAccount settlementDate={reconciliationInfo?.settlementDate} payName={reconciliationInfo?.payName} />
</Modal>
<Modal width={548} title="查看付款凭证" onCancel={viewModalonCancel} visible={viewVisible} footer={null}>
<Voucher files={files} />
</Modal>
<Modal
width={548}
title="确认付款凭证"
onCancel={confirmPayOnCancel}
visible={confirmPayVisible}
footer={(
<Space>
<Button onClick={confirmPayOnCancel}>取消</Button>
<Button
danger
onClick={() => handleConfirmPayStatus({status: 0, id: confirmPayInfo.id})}
>
确认未到款
</Button>
<Button
type={"primary"}
onClick={() => handleConfirmPayStatus({status: 1, id: confirmPayInfo.id})}
>
确认到款
</Button>
</Space>
)}
>
<Voucher files={files} />
</Modal>
</PageHeaderWrapper>
)
}
......
/*
* @Author: Bill
* @Date: 2020-10-20 10:54:00
* @Description: 积分结算详情页
*/
import React, { useRef, useState, useEffect } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { Card, PageHeader, Descriptions, Button, DatePicker} from 'antd';
import { history } from 'umi';
import AvatarWrap from '@/components/AvatarWrap';
import NiceForm from '@/components/NiceForm';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { createFormActions } from '@formily/antd';
import { StandardTable } from 'god';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { useAsyncInitSelect } from '@/formSchema/effects/useAsyncInitSelect';
import { detailSchema } from './schema'
import { usePageStatus } from '@/hooks/usePageStatus';
import { PublicApi } from '@/services/api';
import StatusTag from '../../components/StatusTag'
import { productNoticecolumns } from '../../common/columns';
import { priceFormat } from '@/utils/numberFomat';
import useFetchBillData from '../../hooks/useFetchBillData';
const RangePicker = DatePicker.RangePicker;
const formActions = createFormActions();
interface infoType {
id: number, // 会员结算id
settlementNo: string, // 结算单号
settlementDate: string, // 结算日期
settlementWayName: string, // 结算方式名称
settlementName: string, // 结算方
payName: string, // 付款方
orderTypeName: string, // 结算单据类型名称
totalCount: number, // 总单数
amount: number, // 结算金额
statusName: string // 结算状态名称
}
const OrderDetail: React.FC = () => {
const { ref, infoDetail, fetchListData, handleSearch } = useFetchBillData(PublicApi.getSettleAccountsMemberSettlementGetPayableDetail);
const { id } = usePageStatus();
return (
<PageHeaderWrapper
title={
<>
<PageHeader
style={{ padding: '0' }}
onBack={() => history.goBack()}
title={
<AvatarWrap
info={{
aloneTxt: '单',
name: ""
}}
extra={(
<span style={{ fontSize: 16, fontWeight: 'bold', color: "#303133" }}>结算单号:{infoDetail?.settlementNo}</span>
)}
/>
}
>
<Descriptions
column={3}
style={{
padding: '0 32px',
}}
>
<Descriptions.Item label="结算日期">{infoDetail?.settlementDate}</Descriptions.Item>
<Descriptions.Item label="结算单数">{infoDetail?.totalCount}</Descriptions.Item>
<Descriptions.Item label="结算金额">{priceFormat(infoDetail?.amount)}</Descriptions.Item>
<Descriptions.Item label="结算方">{infoDetail?.settlementName}</Descriptions.Item>
<Descriptions.Item label="结算方式">{infoDetail?.settlementWayName}</Descriptions.Item>
<Descriptions.Item label="外部状态"><StatusTag text={infoDetail?.statusName}></StatusTag></Descriptions.Item>
</Descriptions>
</PageHeader>
</>
}
>
<Card>
<StandardTable
tableProps={{
rowKey: 'orderNo',
}}
columns={productNoticecolumns}
currentRef={ref}
fetchTableData={(params: any) => fetchListData(PublicApi.getSettleAccountsMemberSettlementPagePayableOrderSettlement, { settlementId: id, ...params })}
controlRender={
<NiceForm
actions={formActions}
components={{RangePicker}}
expressionScope={{
exportBtn: (
<div>
<Button>导出</Button>
</div>
)
}}
effects={($, actions) => {
useStateFilterSearchLinkageEffect($, actions, 'megaLayout.topLayout.orderNo', FORM_FILTER_PATH);
// useAsyncInitSelect(
// ['innerStatus', 'outerStatus'],
// fetchSelectOptions,
// );
}}
schema={detailSchema}
onSubmit={handleSearch}
/>
}
/>
</Card>
</PageHeaderWrapper>
)
}
export default OrderDetail
......@@ -24,7 +24,11 @@ export const productNoticecolumns = [
render: (text) => {
return (
<div style={{display: "flex", flexDirection: "row", alignItems: 'center'}}>
{
(text !== 0 && (
<img src={text > 0 ? add : subtraction} width={16} height={16} />
)) || null
}
<span style={{marginLeft: '8px'}}>{text}</span>
</div>
)
......@@ -33,13 +37,20 @@ export const productNoticecolumns = [
]
export const logisticsColumn = [
{title: '单据号', dataIndex: 'orderNo'},
{title: '单据摘要', dataIndex: 'orderAbstract'},
{title: '单据类型', dataIndex: 'orderTypeName'},
{title: '单据时间', dataIndex: 'orderTime'},
{title: '总箱数', dataIndex: 'totalCarton'},
{title: '总重量', dataIndex: 'totalWeight'},
{title: '总体积', dataIndex: 'totalVolume'},
{ title: '单据号', dataIndex: 'orderNo' },
{ title: '单据摘要', dataIndex: 'orderAbstract' },
{ title: '单据类型', dataIndex: 'orderTypeName' },
{ title: '单据时间', dataIndex: 'orderTime' },
{ title: '总箱数', dataIndex: 'totalCarton' },
{ title: '总重量', dataIndex: 'totalWeight' },
{ title: '总体积', dataIndex: 'totalVolume' },
{
title: '含税/税率',
dataIndex: 'tax',
render: (text, record) => {
return record.isHasTax ? `${record.isHasTaxName}/${record.taxRate}` : '否';
}
},
{
title: '接单金额',
dataIndex: 'orderAmount',
......@@ -59,7 +70,49 @@ export const logisticsColumn = [
render: (text) => {
return (
<div style={{display: "flex", flexDirection: "row", alignItems: 'center'}}>
{
(text !== 0 && (
<img src={text > 0 ? add : subtraction} width={16} height={16} />
)) || null
}
<span style={{marginLeft: '8px'}}>{text}</span>
</div>
)
}
},
]
export const orderColumns = [
{ title: '单据号', dataIndex: 'orderNo' },
{ title: '单据摘要', dataIndex: 'orderAbstract' },
{ title: '单据类型', dataIndex: 'orderTypeName' },
{ title: '单据时间', dataIndex: 'orderTime' },
{ title: '订单类型', dataIndex: 'orderTypeName' },
{ title: '单据总额', dataIndex: 'orderAmount' },
{ title: '支付次数', dataIndex: 'batch' },
{
title: '含税/税率',
dataIndex: 'tax',
render: (text, record) => {
return record.isHasTax ? `${record.isHasTaxName}/${record.taxRate}` : '否';
}
},
{
title: '支付金额',
dataIndex: 'amount',
},
{ title: '支付时间', dataIndex: '支付时间' },
{
title: '结算金额',
dataIndex: 'settlementAmount',
render: (text) => {
return (
<div style={{display: "flex", flexDirection: "row", alignItems: 'center'}}>
{
(text !== 0 && (
<img src={text > 0 ? add : subtraction} width={16} height={16} />
)) || null
}
<span style={{marginLeft: '8px'}}>{text}</span>
</div>
)
......
/**
* 结算单据装填
*/
/**
* 待对账
*/
export const TO_BE_RECONCILED = 1;
/**
* 待付款
*/
export const TO_BE_PAY = 2
/**
* 待收款
*/
export const TO_BE_COLLECTED = 3;
/**
* 已完成
*/
export const COMPLETED = 4
/**
* 应付账款 - 付款方查看凭证, 能力中心
*/
export const PAYABLE_PAYER = 1;
/**
* 应收账款管理-收款方查看凭证, 能力中心
*/
export const RECEIABLE_BENEFICIARY = 2;
/**
* 平台代收账款结算 - 收款方查看凭证 能力中心
*/
export const PLATFORM_BENEFICIARY = 3;
/**
* 平台代收账款结算 - 付款方查看凭证 这是平台后台
*/
export const PLATFORM_PAYER = 4;
/**
* 平台积分结算-收款方查看凭证, 能力中心
*/
export const SCORE_BENEFINCIARY = 5;
/**
* 平台积分结算-付款方查看凭证 ,这是平台后台
*/
export const SCORE_PAYER = 6;
......@@ -6,7 +6,7 @@ export const payStatus = [
{ text: '待对账', value: 1 },
{ text: '待付款', value: 2 },
{ text: '待收款', value: 3 },
{ text: '完成', value: 4 },
{ text: '完成', value: 4 },
];
......
......@@ -77,7 +77,6 @@ interface Iprops {
const StatusTag: React.FC<Iprops> = (props: Iprops) => {
const { status, text } = props
return (
<Tag
className="tag-out-border"
......
import React, { useState } from 'react';
import { Space, Modal, Popconfirm, Button, } from 'antd';
import UploadPayVoucher from '../UploadPayVoucher';
interface FileType {
name: string,
proveUrl: string,
}
interface UploadVocherProps {
/**
* 结算方id
*/
settlementId: number,
/**
* 结算单id
*/
id: number
roleId: number,
handleUpload: (params: any) => void,
visible: boolean,
onCancel: () => void,
}
// 待付款 状态 上传付款凭证
const UploadVoucherModal: React.FC<UploadVocherProps> = (props) => {
const { settlementId, roleId, visible, onCancel} = props;
const [fileList, setFileList] = useState<FileType[]>([]);
const [isUploading, setIsUploading] = useState(false)
const getFileList = (list: FileType[], status) => {
if(status === 'done') {
setFileList(list);
setIsUploading(false)
} else {
setIsUploading(true);
}
}
const handleComfirm = (params) => {
props.handleUpload({onCancel: params.onCancel, id: params.id, fileList: params.fileList})
}
return (
<Modal
width={548}
title="上传付款凭证"
onCancel={onCancel}
visible={visible}
destroyOnClose
footer={(
<Space>
<Button onClick={onCancel}>取消</Button>
{
isUploading
? <Popconfirm
title="还有文件正在上传,是否确认提交?"
okText="是"
cancelText="否"
onConfirm={() => handleComfirm({onCancel: onCancel, id: props.id, fileList: fileList})}
>
<Button type={"primary"}>确认</Button>
</Popconfirm>
: <Button
type={"primary"}
onClick={() => handleComfirm({onCancel: onCancel, id: props.id, fileList: fileList})}
>确认</Button>
}
</Space>
)}
>
<UploadPayVoucher roleId={roleId} id={settlementId} getFileList={getFileList} />
</Modal>
)
}
export default UploadVoucherModal
......@@ -11,7 +11,7 @@ import { VoucherFileProps } from '../../common/type';
interface Iprops {
files: VoucherFileProps[],
onRemove: (item) => void
onRemove?: (item) => void
}
const Voucher: React.FC<Iprops> = (props) => {
......
/**
* 结算单据,应收账款结算, 应付账款结算的物流单,订单,生产通知单hook
*/
import { usePageStatus } from "@/hooks/usePageStatus";
import { PublicApi } from "@/services/api";
import { useEffect, useRef, useState } from "react";
function useFetchBillData(getDetailApi) {
const ref = useRef<any>({});
const [infoDetail, setInfoDetail] = useState<any>(null);
const { id } = usePageStatus();
const fetchListData = async (api, params) => {
const { data } = await api(params)
return data
}
useEffect(() => {
if(id) {
// 获取详情
async function fetchDetail() {
const { data } = await getDetailApi({id})
setInfoDetail(data);
}
fetchDetail();
}
}, [id])
/**
* 搜索
*/
const handleSearch = (values) => {
const format = 'YYYY-MM-DD'
const startTime = values.startTime?.format(format);
const endTime = values.endTime ? values.endTime.format(format) + " 23:59:59" : "";
const receiveStartTime = values.receiveStartTime?.format(format);
const receiveEndTime = values.receiveEndTime ? values.receiveEndTime?.format(format) + " 23:59:59" : "";
ref.current.reload({...values, startTime, endTime, receiveStartTime, receiveEndTime});
}
return { ref, handleSearch, fetchListData, infoDetail }
}
export default useFetchBillData
import EyePreview from '@/components/EyePreview';
import StatusTag from '../components/StatusTag';
import { TO_BE_RECONCILED, TO_BE_PAY, TO_BE_COLLECTED, COMPLETED } from '../common/constants';
import { priceFormat } from '@/utils/numberFomat'
// import StatusTag from '@/components/StatusTag';
import React, { useState } from 'react';
import { payStatus } from '../common';
import moment from 'moment';
type BalanceInfoType = { id: number, settlementId: number, roleId: number }
const format = "YYYY-MM-DD HH:mm:ss"
function useFetchColumns(mode: 'payable' | 'receiveable') {
/**
* 手动结算状态
*/
const [manualStatus, setManualStatus] = useState<number | null>(null);
/**
* 付款弹框
*/
const [payModalVisible, setPayModalVisible] = useState<boolean>(false);
/**
* 查看付款凭证弹框
*/
const [viewVisible, setViewVisible] = useState<boolean>(false);
/**
*
* 获取当前结算单信息
*/
const [balanceInfo, setBalanceInfo] = useState<BalanceInfoType | null>(null);
/**
* 付款凭证info
*/
const [payVoucherInfo, setPayVoucherInfo] = useState<{ id: number } | null>(null);
/**
*
* 确认对账完成Info
*/
const [reconciliationVisible, setReconciliationVisible] = useState<boolean>(false);
/**
* 确认对账完成info
*/
const [reconciliationInfo, setReconciliationInfo] = useState<{payName: string, settlementDate: string, id: number} | null>(null)
/**
* 确认付款完成visible
*/
const [confirmPayVisible, setConfirmPayVisible] = useState<boolean>(false);
/**
* 确认付款完成Info
*/
const [confirmPayInfo, setConfirmPayInfo] = useState<{id: number} | null>(null);
/**
*
* @param id: 结算单id
* @param settlementId 结算方id
* @param roleId 结算方角色id
*
*/
const handlePay = (params: BalanceInfoType) => {
setBalanceInfo(params)
setPayModalVisible(true);
}
const handleManualsettlement = (id: number | null) => {
setManualStatus(id);
}
const payModalOnCancel = () => {
setPayModalVisible(false)
}
/**
* 查看支付凭证Cancel
*/
const viewModalonCancel = () => {
setViewVisible(false);
}
const handleViewPayModal = (params: { id: number }) => {
setPayVoucherInfo(params)
setViewVisible(true);
}
const handleReconciledComfirm = (params: any) => {
setReconciliationInfo(params);
setReconciliationVisible(true);
}
const reconciliationOnCancel = () => {
setReconciliationVisible(false);
}
/**
* 确认付款凭证
*/
const handleComfirmCompletePaymentStatus = (params: {id: number}) => {
setConfirmPayInfo(params);
/**
* 这里确认付款完成 收款方需要查看付款凭证
*/
setPayVoucherInfo(params);
setConfirmPayVisible(true);
}
const confirmPayOnCancel = () => {
setConfirmPayVisible(false)
}
const columns = [
{
title: '结算单号',
dataIndex: 'settlementNo',
render: (text, record) => {
const prefix = mode === 'payable' ? `/memberCenter/balance/accountsPayable/settlementList/` : '/memberCenter/balance/accountsReceivable/settlementList/`;';
const url = record.orderType === 2 ? `logisticsDetail` : `productNoticeSettlementDetail`;
return (
<EyePreview url={`${prefix}${url}?id=${record.id}`} >
{record.settlementNo}
</EyePreview>
)
}
},
{ title: '结算方式', dataIndex: 'settlementWayName' },
{ title: mode === 'receiveable' ? '付款方' : '结算方', dataIndex: mode === 'receiveable' ? 'payName' : 'settlementName'},
{
title: '结算单据类型',
dataIndex: 'orderTypeName',
filters: [
{
text: '生产通知单',
value: 1,
},
{
text: '物流单',
value: 2,
},
{
text: '订单',
value: 3,
},
{
text: '请款单',
value: 6
}
],
onFilter: (value: number, record: any) => record.orderType === value,
},
{
title: '结算金额',
dataIndex: 'amount',
sorter: (a, b) => a.amount - b.amount,
render: (text, record) => {
return (
<div>{`¥${priceFormat(record.amount)}`}</div>
)
}
},
{
title: '总单数',
dataIndex: 'totalCount',
sorter: (a, b) => a.totalCount - b.totalCount,
},
{
title: '结算时间',
dataIndex: 'settlementTime',
sorter: (a, b) => moment(a.settlementTime, format).valueOf() - moment(b.settlementTime, format).valueOf(),
},
// {title: '结算日期', dataIndex: 'settlementDate'},
{ title: '预计付款日期', dataIndex: 'prePayTime' },
{ title: '实际付款日期', dataIndex: 'payTime' },
{
title: '结算状态', dataIndex: 'status',
filters: payStatus,
onFilter: (value: number, record: any) => record.status == value,
render: (text: string, record: any) => {
return (
<StatusTag status={record.status as 0 | 1 | 2 | 3} />
)
}
},
{
title: '支付方式',
dataIndex: 'payWayName',
filters: [
{
text: '线上支付',
value: 1,
},
{
text: '线下转账线上确认',
value: 2,
},
{
text: '授信',
value: 3,
},
{
text: '货到付款',
value: 4
}
],
onFilter: (value: number, record: any) => record.payWay === value,
},
{
title: '操作',
render: (text: string, record: any) => {
if (mode === 'payable') {
// 待对账的时候可以手动结算
if (record.status === TO_BE_RECONCILED) {
return <a onClick={() => handleManualsettlement(record.id)}>手动结算</a>
}
if (record.status === TO_BE_PAY) {
return <a onClick={() => handlePay({id: record.id, settlementId: record.memberId, roleId: record.roleId})}>付款</a>
}
return <a onClick={() => handleViewPayModal({id: record.id})}>查看付款凭证</a>
}
// 待收张狂结算
if (record.status === TO_BE_RECONCILED) {
return <a onClick={() => handleReconciledComfirm({ id: record.id, payName: record.payName, settlementDate: record.settlementDate})}>确认对账完成</a>
}
if (record.status === TO_BE_COLLECTED) {
return <a onClick={() => handleComfirmCompletePaymentStatus({id: record.id})}>确认付款凭证</a>
}
if (record.status === COMPLETED) {
return <a onClick={() => handleViewPayModal({id: record.id})}>查看付款凭证</a>
}
}
}
];
return {
columns,
manualStatus,
handleManualsettlement,
viewVisible,
payModalVisible,
balanceInfo,
payModalOnCancel,
viewModalonCancel,
payVoucherInfo,
reconciliationVisible,
reconciliationInfo,
confirmPayInfo,
confirmPayVisible,
reconciliationOnCancel,
confirmPayOnCancel,
handleReconciledComfirm,
handleComfirmCompletePaymentStatus,
handleViewPayModal
}
}
export default useFetchColumns
......@@ -4,9 +4,9 @@
* @Description: 平台代收账款结算
*/
import React, { useRef } from 'react';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { Card, DatePicker } from 'antd';
import { Card, DatePicker, Modal, Space, Button } from 'antd';
import NiceForm from '@/components/NiceForm';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { createFormActions } from '@formily/antd';
......@@ -21,6 +21,10 @@ import { PublicApi } from '@/services/api'
import EyePreview from '@/components/EyePreview'
import { fetchOptions } from '../../common';
import useIsExistBrokerage from '../../hooks/useIsExistsBrokerage';
import ConfirmAccount from '../../components/ConfirmAccount';
import Voucher from '../../components/Voucher';
import { TO_BE_RECONCILED, TO_BE_COLLECTED, COMPLETED } from '../../common/constants';
import useFetchColumns from '../../hooks/useFetchColumns';
const formActions = createFormActions();
const { RangePicker } = DatePicker;
......@@ -30,15 +34,22 @@ const PLATFORM_BENEFICIARY = 3;
const AccountReceivable = () => {
const ref = useRef<any>({})
const fetchListData = async (params) => {
const searchData = {
...params,
status: typeof params.status == 'undefined' ? 0 : params.status,
}
///settle/accounts/platform/settlement/pageReceivableSettlement
const { data } = await PublicApi.getSettleAccountsPlatformSettlementPageReceivableSettlement(searchData);
return data
}
const {
confirmPayInfo,
confirmPayVisible,
reconciliationInfo,
reconciliationVisible,
viewVisible,
payVoucherInfo,
viewModalonCancel,
confirmPayOnCancel,
reconciliationOnCancel,
handleReconciledComfirm,
handleComfirmCompletePaymentStatus,
handleViewPayModal
} = useFetchColumns("receiveable");
const [files, setFiles] = useState([]);
const columns = [
{
title: '结算单号',
......@@ -72,66 +83,65 @@ const AccountReceivable = () => {
{
title: '操作',
render: (text, record) => {
return (
<StatusActions
excludes={[2]}
id={record.id}
type={PLATFORM_BENEFICIARY}
status={record.status}
settlementDate={record.settlementDate}
payName={"平台"}
handleReconciledComfirm={handleConfirm}
handleComfirmInCompletePayment={handleComfirmInCompletePayment}
handleComfirmCompletePayment={handleComfirmCompletePayment}
/>
)
// 待收张狂结算
if (record.status === TO_BE_RECONCILED) {
return <a onClick={() => handleReconciledComfirm({ id: record.id, payName: '平台', settlementDate: record.settlementDate})}>确认对账完成</a>
}
if (record.status === TO_BE_COLLECTED) {
return <a onClick={() => handleComfirmCompletePaymentStatus({id: record.id})}>确认付款凭证</a>
}
if (record.status === COMPLETED) {
return <a onClick={() => handleViewPayModal({id: record.id})}>查看付款凭证</a>
}
}
}
]
const { retColumn } = useIsExistBrokerage(columns, ["brokerage"]);
const fetchListData = async (params) => {
const searchData = {
...params,
status: typeof params.status == 'undefined' ? 0 : params.status,
}
const { data } = await PublicApi.getSettleAccountsPlatformSettlementPageReceivableSettlement(searchData);
return data
}
/**
* 确认对账
* @param {cancel: function, id: number} cancel 为关闭回调函数
*/
const handleConfirm = (params: any) => {
// /settle/accounts/platform/settlement/confirmAccountComplete
PublicApi.postSettleAccountsPlatformSettlementConfirmAccountComplete({settlementId: params.id})
.then((data) => {
if(data.code === 1000) {
params.onCancel();
const handleConfirm = async (params: {id: number}) => {
const { code } = await PublicApi.postSettleAccountsPlatformSettlementConfirmAccountComplete({settlementId: params.id})
if(code === 1000) {
reconciliationOnCancel();
formActions.submit();
}
})
}
/**
* 确认未到款
* @param {onCancel:function, id: number, status: number}
* 确认付款凭证
*/
const handleComfirmInCompletePayment = (params: any) => {
PublicApi.postSettleAccountsPlatformSettlementConfirmPayProve({id: params.id, status: params.status})
.then((data) => {
if(data.code === 1000) {
const handleConfirmPayStatus = async (params: { status: 0 | 1, id: number }) => {
const { code } = await PublicApi.postSettleAccountsPlatformSettlementConfirmPayProve({id: params.id, status: params.status});
if (code) {
confirmPayOnCancel();
formActions.submit();
params.onCancel();
}
})
}
/**
* 确认到款
* @param {onCancel:function, id: number, status: number}
*/
const handleComfirmCompletePayment = (params: any) => {
///settle/accounts/platform/settlement/confirmPayProve
PublicApi.postSettleAccountsPlatformSettlementConfirmPayProve({id: params.id, status: params.status})
.then((data) => {
if(data.code === 1000) {
formActions.submit();
params.onCancel();
const fetchVouchers = useCallback(async (id: number) => {
const { code, data } = await PublicApi.getSettleAccountsPlatformSettlementGetReceivablePayProve({id: id.toString()})
if (code === 1000) {
setFiles(data);
}
})
}, [])
useEffect(() => {
if (payVoucherInfo !== null) {
fetchVouchers(payVoucherInfo.id);
}
}, [payVoucherInfo])
/**
* 搜索
......@@ -176,6 +186,43 @@ const AccountReceivable = () => {
}
/>
</Card>
<Modal
width={400}
title="确认对账完成"
visible={reconciliationVisible}
onCancel={reconciliationOnCancel}
onOk={() => handleConfirm({ id: reconciliationInfo?.id})}
>
<ConfirmAccount settlementDate={reconciliationInfo?.settlementDate} payName={reconciliationInfo?.payName} />
</Modal>
<Modal width={548} title="查看付款凭证" onCancel={viewModalonCancel} visible={viewVisible} footer={null}>
<Voucher files={files} />
</Modal>
<Modal
width={548}
title="确认付款凭证"
onCancel={confirmPayOnCancel}
visible={confirmPayVisible}
footer={(
<Space>
<Button onClick={confirmPayOnCancel}>取消</Button>
<Button
danger
onClick={() => handleConfirmPayStatus({status: 0, id: confirmPayInfo.id})}
>
确认未到款
</Button>
<Button
type={"primary"}
onClick={() => handleConfirmPayStatus({status: 1, id: confirmPayInfo.id})}
>
确认到款
</Button>
</Space>
)}
>
<Voucher files={files} />
</Modal>
</PageHeaderWrapper>
)
}
......
......@@ -4,38 +4,45 @@
* @Description: 积分结算列表
*/
import React, { useRef } from 'react';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { Card, DatePicker } from 'antd';
import { Card, DatePicker, Modal, Space, Button } from 'antd';
import NiceForm from '@/components/NiceForm';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { createFormActions } from '@formily/antd';
import { StandardTable } from 'god';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { schema } from './schema/index';
import StatusActions from '../../components/StatusActions';
import StatusTag from '../../components/StatusTag';
import { payStatus } from '../../common';
import { PublicApi } from '@/services/api';
import EyePreview from '@/components/EyePreview';
import { fetchOptions } from '../../common';
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
import useFetchColumns from '../../hooks/useFetchColumns';
import Voucher from '../../components/Voucher';
import ConfirmAccount from '../../components/ConfirmAccount';
import { COMPLETED, TO_BE_COLLECTED, TO_BE_RECONCILED } from '../../common/constants';
const { RangePicker } = DatePicker;
// 平台积分结算-收款方查看凭证, 能力中心
const SCORE_BENEFINCIARY = 5;
const formActions = createFormActions();
const Integral: React.FC = () => {
const ref = useRef<any>({})
const fetchListData = async (params) => {
const searchData = {
...params,
status: typeof params.status == 'undefined' ? 0 : params.status,
}
// /settle/accounts/platform/score/settlement/pageReceivableSettlement
const { data } = await PublicApi.getSettleAccountsPlatformScoreSettlementPageReceivableSettlement(searchData);
return data
}
const {
confirmPayInfo,
confirmPayVisible,
reconciliationInfo,
reconciliationVisible,
viewVisible,
payVoucherInfo,
viewModalonCancel,
confirmPayOnCancel,
reconciliationOnCancel,
handleReconciledComfirm,
handleComfirmCompletePaymentStatus,
handleViewPayModal
} = useFetchColumns("receiveable");
const [files, setFiles] = useState([]);
const columns = [
{
title: '结算单号',
......@@ -75,66 +82,65 @@ const Integral: React.FC = () => {
{
title: '操作',
render: (text, record) => {
return (
<>
<StatusActions
excludes={[2]}
id={record.id}
type={SCORE_BENEFINCIARY}
status={record.status}
settlementDate={record.settlementDate}
payName={"平台"}
handleReconciledComfirm={handleConfirm}
handleComfirmInCompletePayment={handleComfirmInCompletePayment}
handleComfirmCompletePayment={handleComfirmCompletePayment}
/>
</>
)
// 待收张狂结算
if (record.status === TO_BE_RECONCILED) {
return <a onClick={() => handleReconciledComfirm({ id: record.id, payName: '平台', settlementDate: record.settlementDate})}>确认对账完成</a>
}
if (record.status === TO_BE_COLLECTED) {
return <a onClick={() => handleComfirmCompletePaymentStatus({id: record.id})}>确认付款凭证</a>
}
if (record.status === COMPLETED) {
return <a onClick={() => handleViewPayModal({id: record.id})}>查看付款凭证</a>
}
}
}
]
const fetchListData = async (params) => {
const searchData = {
...params,
status: typeof params.status == 'undefined' ? 0 : params.status,
}
// /settle/accounts/platform/score/settlement/pageReceivableSettlement
const { data } = await PublicApi.getSettleAccountsPlatformScoreSettlementPageReceivableSettlement(searchData);
return data
}
/**
* 确认对账
* @param {cancel: function, id: number} cancel 为关闭回调函数
*/
const handleConfirm = (params: any) => {
PublicApi.postSettleAccountsPlatformScoreSettlementConfirmAccountComplete({settlementId: params.id})
.then((data) => {
if(data.code === 1000) {
params.onCancel();
const handleConfirm = async (params: {id: number}) => {
const { code } = await PublicApi.postSettleAccountsPlatformScoreSettlementConfirmAccountComplete({settlementId: params.id})
if(code === 1000) {
reconciliationOnCancel();
formActions.submit();
}
})
}
/**
* 确认未到款
* @param {onCancel:function, id: number, status: number}
* 确认付款凭证
*/
const handleComfirmInCompletePayment = (params: any) => {
PublicApi.postSettleAccountsPlatformScoreSettlementConfirmPayProve({id: params.id, status: params.status})
.then((data) => {
if(data.code === 1000) {
const handleConfirmPayStatus = async (params: { status: 0 | 1, id: number }) => {
const { code } = await PublicApi.postSettleAccountsPlatformScoreSettlementConfirmPayProve({id: params.id, status: params.status});
if (code) {
confirmPayOnCancel();
formActions.submit();
params.onCancel();
}
})
}
/**
* 确认到款
* @param {onCancel:function, id: number, status: number}
*/
const handleComfirmCompletePayment = (params: any) => {
PublicApi.postSettleAccountsPlatformScoreSettlementConfirmPayProve({id: params.id, status: params.status})
.then((data) => {
if(data.code === 1000) {
formActions.submit();
params.onCancel();
const fetchVouchers = useCallback(async (id: number) => {
const { code, data } = await PublicApi.getSettleAccountsPlatformScoreSettlementGetReceivablePayProve({id: id.toString()})
if (code === 1000) {
setFiles(data);
}
})
}, [])
useEffect(() => {
if (payVoucherInfo !== null) {
fetchVouchers(payVoucherInfo.id);
}
}, [payVoucherInfo])
/**
* 搜索
*/
......@@ -177,6 +183,43 @@ const Integral: React.FC = () => {
}
/>
</Card>
<Modal
width={400}
title="确认对账完成"
visible={reconciliationVisible}
onCancel={reconciliationOnCancel}
onOk={() => handleConfirm({ id: reconciliationInfo?.id})}
>
<ConfirmAccount settlementDate={reconciliationInfo?.settlementDate} payName={reconciliationInfo?.payName} />
</Modal>
<Modal width={548} title="查看付款凭证" onCancel={viewModalonCancel} visible={viewVisible} footer={null}>
<Voucher files={files} />
</Modal>
<Modal
width={548}
title="确认付款凭证"
onCancel={confirmPayOnCancel}
visible={confirmPayVisible}
footer={(
<Space>
<Button onClick={confirmPayOnCancel}>取消</Button>
<Button
danger
onClick={() => handleConfirmPayStatus({status: 0, id: confirmPayInfo.id})}
>
确认未到款
</Button>
<Button
type={"primary"}
onClick={() => handleConfirmPayStatus({status: 1, id: confirmPayInfo.id})}
>
确认到款
</Button>
</Space>
)}
>
<Voucher files={files} />
</Modal>
</PageHeaderWrapper>
)
}
......
......@@ -14,6 +14,8 @@ import * as ReportApi from './ReportApi';
import * as PurchaseApi from './PurchaseApi';
import * as ContractApi from './ContractApi';
import * as PurchaseV2Api from './PurchaseV2Api';
import * as SettleV2Api from './SettleV2Api';
/**
* 可在这里写入自定义的接口
......@@ -40,4 +42,5 @@ export const PublicApi = {
...PurchaseApi,
...ContractApi,
...PurchaseV2Api,
...SettleV2Api,
}
......@@ -16,6 +16,7 @@ const tokenList = [
// { name: 'Purchase', token: 'a09e2b66e00079df9881fc660eb17db0265e33362c13f03f2003ba81d26f49d8', categoryIds: [0], }, // 采购服务
{ name: 'Purchase', token: 'a09e2b66e00079df9881fc660eb17db0265e33362c13f03f2003ba81d26f49d8', categoryIds: [0], }, // 采购服务
{ name: 'PurchaseV2', token: '84c81ef877863ad4e2c0ebb2c3b3e80f9539420f2fc0828ef33f5159e8423b2c', categoryIds: [0] }, // 采购服务V2
{ name: 'SettleV2', token: 'fed8d45aa92e7f0e382a3dcc5e0ef63f13f0badeabab76d6a6e2db49aa403346', categoryIds: [0] }
]
const getConfigMap = (tokens) => tokens.map(v => ({
......
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