核算导入导出
This commit is contained in:
parent
88caca1d04
commit
5df55a6724
|
|
@ -353,13 +353,73 @@ export const saveAcctResult = (params) => {
|
|||
}).then(res => res.json())
|
||||
}
|
||||
|
||||
// 核算结果--导入核算结果前生成导入模板时可选的薪资项目
|
||||
export const getImportField = (params) => {
|
||||
return WeaTools.callApi('/api/bs/hrmsalary/salaryacct/acctresult/importField', 'GET', params);
|
||||
}
|
||||
|
||||
|
||||
// 核算结果-导入模板
|
||||
export const getImportTemplate = (salaryItemIds, salaryAcctRecordId) => {
|
||||
fetch('/api/bs/hrmsalary/salaryacct/acctresult/importtemplate/export?salaryItemIds=' + salaryItemIds + "&salaryAcctRecordId=" + salaryAcctRecordId).then(res => res.blob().then(blob => {
|
||||
var filename=`薪资核算.xlsx`
|
||||
var a = document.createElement('a');
|
||||
var url = window.URL.createObjectURL(blob);
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
}))
|
||||
}
|
||||
|
||||
// 核算结果-导入预览
|
||||
export const previewAcctResult= (params) => {
|
||||
return fetch('/api/bs/hrmsalary/salaryacct/acctresult/preview', {
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
}).then(res => res.json())
|
||||
}
|
||||
|
||||
// 核算结果-导入
|
||||
export const importAcctResult = (params) => {
|
||||
return fetch('/api/bs/hrmsalary/salaryacct/acctresult/importSalaryAcctResult', {
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
}).then(res => res.json())
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 核算结果-导出全部
|
||||
export const exportAcctResult = (salaryAcctRecordId) => {
|
||||
fetch('/api/bs/hrmsalary/salaryacct/acctresult/export?salaryAcctRecordId=' + salaryAcctRecordId ).then(res => res.blob().then(blob => {
|
||||
var filename=`薪资核算.xlsx`
|
||||
var a = document.createElement('a');
|
||||
var url = window.URL.createObjectURL(blob);
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
}))
|
||||
}
|
||||
|
||||
// 线下对比-列表
|
||||
export const comparisonResultList = (params) => {
|
||||
return fetch('/api/bs/hrmsalary/salaryacct/comparisonresult/list', {
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
}).then(res => res.json())
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,145 @@
|
|||
import React from 'react'
|
||||
import ImportModal from '../../../../components/importModal'
|
||||
import { Button } from 'antd'
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import SelectFieldModal from './selectFieldModal';
|
||||
|
||||
@inject('calculateStore')
|
||||
@observer
|
||||
export default class AcctResultImportModal extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
modalParam: {
|
||||
salaryAcctRecordId: "",
|
||||
salaryItemIds: ""
|
||||
},
|
||||
step: 0,
|
||||
selectFieldVisible: false
|
||||
}
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
const { id } = this.props;
|
||||
let modalParam = { ...this.state.modalParam }
|
||||
modalParam.salaryAcctRecordId = id
|
||||
this.setState({
|
||||
modalParam
|
||||
})
|
||||
}
|
||||
|
||||
// 获取模板
|
||||
handleAccResultTemplateLink() {
|
||||
const { calculateStore: { getImportTemplate }} = this.props;
|
||||
getImportTemplate(this.state.modalParam.salaryItemIds, this.state.modalParam.salaryAcctRecordId)
|
||||
}
|
||||
|
||||
// 设置步骤
|
||||
setStep(step) {
|
||||
this.setState({step})
|
||||
}
|
||||
|
||||
// 完成
|
||||
handleFinish() {
|
||||
this.setState({step: 0})
|
||||
this.props.onCancel()
|
||||
const { calculateStore: { acctResultList } } = this.props;
|
||||
acctResultList(this.props.id)
|
||||
}
|
||||
|
||||
// 关闭
|
||||
handleCancel() {
|
||||
this.setState({
|
||||
modalVisiable: false,
|
||||
step: 0
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 渲染第一步表单
|
||||
renderFormComponent() {
|
||||
return <Button onClick={() => {
|
||||
this.handleSelectedField()
|
||||
}}>请选择表单字段</Button>
|
||||
}
|
||||
|
||||
// 选择表单字段
|
||||
handleSelectedField() {
|
||||
this.setState({
|
||||
selectFieldVisible: true
|
||||
})
|
||||
}
|
||||
|
||||
// 添加表头字段
|
||||
handleAdd(fieldDate) {
|
||||
let salaryItemIdsList = []
|
||||
fieldDate.formulaItems.map(item => {
|
||||
if(item.checked) {
|
||||
salaryItemIdsList.push(item.salaryItemId)
|
||||
}
|
||||
})
|
||||
|
||||
fieldDate.inputItems.map(item => {
|
||||
if(item.checked) {
|
||||
salaryItemIdsList.push(item.salaryItemId)
|
||||
}
|
||||
})
|
||||
|
||||
let salaryItemIds = ""
|
||||
if(salaryItemIdsList.length > 0) {
|
||||
salaryItemIds = salaryItemIdsList.join(",")
|
||||
}
|
||||
|
||||
let modalParam = { ...this.state.modalParam }
|
||||
modalParam.salaryItemIds = salaryItemIds
|
||||
this.setState({
|
||||
modalParam
|
||||
})
|
||||
this.props.onAdd(fieldDate)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { calculateStore } = this.props;
|
||||
const { fetchPreviewAcctResult, previewAcctResultColumns, previewAcctResultDataSource, importAcctResult, fetchImportAcctResult } = calculateStore
|
||||
const { step, selectFieldVisible, modalParam } = this.state;
|
||||
const { visiable } = this.props;
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
visiable && <ImportModal
|
||||
params={modalParam}
|
||||
columns={previewAcctResultColumns}
|
||||
step={step}
|
||||
setStep={this.setStep.bind(this)}
|
||||
slideDataSource={previewAcctResultDataSource}
|
||||
importResult={importAcctResult}
|
||||
onFinish={() => {
|
||||
this.handleFinish()
|
||||
}}
|
||||
previewImport={(params) => {fetchPreviewAcctResult(params)}}
|
||||
importFile={(params) => {fetchImportAcctResult(params)}}
|
||||
templateLink={ () => { this.handleAccResultTemplateLink()}}
|
||||
renderFormComponent={() => this.renderFormComponent()}
|
||||
visiable={visiable}
|
||||
onCancel={() => { this.props.onCancel() }}
|
||||
/>
|
||||
}
|
||||
{
|
||||
selectFieldVisible && <SelectFieldModal
|
||||
id={this.props.id}
|
||||
visible={selectFieldVisible}
|
||||
fieldData={this.props.fieldData}
|
||||
onAdd={(fieldDate) => {
|
||||
this.handleAdd(fieldDate)
|
||||
}}
|
||||
onCancel={() => {
|
||||
this.setState({
|
||||
selectFieldVisible: false
|
||||
})
|
||||
}}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
import React from 'react'
|
||||
import { Modal, Row, Col, Button } from 'antd'
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { WeaCheckbox } from 'ecCom'
|
||||
|
||||
@inject('calculateStore')
|
||||
@observer
|
||||
export default class SelectFieldModal extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
fieldData: {}
|
||||
}
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
const {calculateStore: { getImportField } } = this.props;
|
||||
getImportField(this.props.id).then(data => {
|
||||
let fieldData = {};
|
||||
let formulaItems = []
|
||||
formulaItems = data.formulaItems
|
||||
if(this.props.fieldData.formulaItems) {
|
||||
formulaItems = this.props.fieldData.formulaItems
|
||||
}
|
||||
let inputItems = []
|
||||
inputItems = data.inputItems
|
||||
if(this.props.fieldData.inputItems) {
|
||||
inputItems = this.props.fieldData.inputItems
|
||||
}
|
||||
fieldData.formulaItems = formulaItems;
|
||||
fieldData.inputItems = inputItems;
|
||||
|
||||
this.setState({
|
||||
fieldData
|
||||
})
|
||||
this.fieldData = fieldData
|
||||
})
|
||||
}
|
||||
|
||||
// 公式项改变
|
||||
handleFormalChange(item, value, flag) {
|
||||
item.checked = value == 1 ? true: false
|
||||
if(flag) { // 公式项
|
||||
this.fieldData.formulaItems.map(fieldItem => {
|
||||
if(item.salaryItemId == fieldItem.salaryItemId) {
|
||||
fieldItem.checked = item.checked
|
||||
}
|
||||
})
|
||||
} else { // 输入项
|
||||
this.fieldData.inputItems.map(fieldItem => {
|
||||
if(item.salaryItemId == fieldItem.salaryItemId) {
|
||||
fieldItem.checked = item.checked
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 添加按钮点击回调
|
||||
handleAddClick() {
|
||||
this.props.onAdd(this.fieldData)
|
||||
this.props.onCancel()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { fieldData } = this.state;
|
||||
return (
|
||||
<Modal visible={this.props.visible} width={800} onCancel={() =>{this.props.onCancel()}}
|
||||
footer={null}
|
||||
>
|
||||
<div style={{height: "50px", lineHeight: "50px"}}>
|
||||
<span style={{fontSize: "14px", fontWeight: "600"}}>添加表头字段</span>
|
||||
<Button type="primary" style={{float: "right", marginRight: "50px"}} onClick={() => {this.handleAddClick()}}>添加</Button>
|
||||
</div>
|
||||
<div style={{marginTop: "20px"}}>
|
||||
<div style={{height: "40px", lineHeight: "40px"}}>
|
||||
<WeaCheckbox content="公式项"/>
|
||||
</div>
|
||||
<div style={{height: "100px", border: "1px solid #f2f2f2", margin: "10px", padding: "10px", overflowY: 'scroll'}}>
|
||||
<Row>
|
||||
{ fieldData.formulaItems && fieldData.formulaItems.map(item => (
|
||||
<Col span={6}><WeaCheckbox value={item.checked ? 1 : 0} content={item.salaryItemName} onChange={(value) => {
|
||||
this.handleFormalChange(item, value, true)
|
||||
}}/></Col>
|
||||
))}
|
||||
</Row>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{marginTop: "20px"}}>
|
||||
<div style={{height: "50px", lineHeight: "50px"}}>
|
||||
<WeaCheckbox content="输入项"/>
|
||||
</div>
|
||||
<div style={{height: "100px", border: "1px solid #f2f2f2", margin: "10px", padding: "10px", overflowY: "scroll"}}>
|
||||
<Row>
|
||||
{ fieldData.inputItems && fieldData.inputItems.map(item => (
|
||||
<Col span={6}><WeaCheckbox value={item.checked ? 1 : 0} content={item.salaryItemName} onChange={(value) => {
|
||||
this.handleFormalChange(item, value, true)
|
||||
}}/></Col>
|
||||
))}
|
||||
</Row>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{marginTop: "20px"}}>
|
||||
<WeaCheckbox content="只显示已选中"/>
|
||||
</div>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,33 @@
|
|||
import React from 'react'
|
||||
import { Button, Table } from "antd"
|
||||
import { WeaInputSearch, WeaCheckbox } from 'ecCom'
|
||||
import { WeaInputSearch, WeaCheckbox, WeaTable } from 'ecCom'
|
||||
import { mergeDetailColumns, dataSource } from './columns'
|
||||
import { getQueryString } from '../../util/url'
|
||||
import CustomTab from '../../components/customTab'
|
||||
import { inject, observer } from 'mobx-react';
|
||||
|
||||
@inject('calculateStore')
|
||||
@observer
|
||||
export default class CompareDetail extends React.Component {
|
||||
render() {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.id = ""
|
||||
this.state = {
|
||||
onlyDiffEmployee: true,
|
||||
onlyDiffSalaryItem: true,
|
||||
}
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
let id = getQueryString("id");
|
||||
this.id = id;
|
||||
|
||||
const { calculateStore: {fetchComparisonResultList}} = this.props;
|
||||
const { onlyDiffEmployee, onlyDiffSalaryItem} = this.state;
|
||||
fetchComparisonResultList(onlyDiffEmployee, onlyDiffSalaryItem, this.id)
|
||||
}
|
||||
|
||||
render() {
|
||||
const renderRightOperation = () => {
|
||||
return (
|
||||
<div style={{display: "inline-block"}}>
|
||||
|
|
@ -20,8 +41,18 @@ export default class CompareDetail extends React.Component {
|
|||
const renderLeftOperation = () => {
|
||||
return (
|
||||
<div>
|
||||
<WeaCheckbox content="只显示有差异的人员" />
|
||||
<WeaCheckbox content="只显示有差异的薪资项目" />
|
||||
<WeaCheckbox content="只显示有差异的人员" value={this.state.onlyDiffEmployee ? 1 : 0}
|
||||
onChange={(value) => {
|
||||
this.setState({
|
||||
onlyDiffEmployee: value == 1
|
||||
})
|
||||
}}
|
||||
/>
|
||||
<WeaCheckbox content="只显示有差异的薪资项目" value={this.state.onlyDiffSalaryItem ? 1 : 0} onChange={(value) => {
|
||||
this.setState({
|
||||
onlyDiffSalaryItem: value == 1
|
||||
})
|
||||
}}/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -43,7 +74,7 @@ export default class CompareDetail extends React.Component {
|
|||
</div>
|
||||
|
||||
<div className="tableWrapper">
|
||||
<Table dataSource={dataSource} columns={mergeDetailColumns}/>
|
||||
<WeaTable dataSource={dataSource} columns={mergeDetailColumns}/>
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import SalaryDetail from './salaryDetail'
|
|||
import { Button, Menu, Dropdown, Modal } from 'antd'
|
||||
import { WeaInputSearch } from "ecCom"
|
||||
import { getQueryString } from '../../util/url'
|
||||
|
||||
import AcctResultImportModal from './acctResult/importModal/acctResultImportModal';
|
||||
|
||||
@inject('calculateStore')
|
||||
@observer
|
||||
|
|
@ -14,7 +14,9 @@ export default class CalculateDetail extends React.Component {
|
|||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
selectedKey: "0"
|
||||
selectedKey: "0",
|
||||
fieldData: {},
|
||||
acctResultImportVisiable: false
|
||||
}
|
||||
this.id = ""
|
||||
}
|
||||
|
|
@ -23,7 +25,9 @@ export default class CalculateDetail extends React.Component {
|
|||
let id = getQueryString("id");
|
||||
this.id = id;
|
||||
const { calculateStore: {checkTaxAgent}} = this.props;
|
||||
checkTaxAgent(id)
|
||||
checkTaxAgent(this.id)
|
||||
let modalParam = {...this.state.modalParam , salaryAcctRecordId: id}
|
||||
this.setState({modalParam})
|
||||
}
|
||||
|
||||
// 核算点击事件
|
||||
|
|
@ -41,17 +45,34 @@ export default class CalculateDetail extends React.Component {
|
|||
onCancel() {}
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { selectedKey } = this.state;
|
||||
|
||||
const handleMenuClick = (e) => {
|
||||
if(e.key == "2") {
|
||||
window.open("/spa/hrmSalary/static/index.html#/main/hrmSalary/compareDetail")
|
||||
}
|
||||
|
||||
// 更多选项点击
|
||||
handleMenuClick = (e) => {
|
||||
if(e.key == "1") { // 导入
|
||||
this.setState({
|
||||
acctResultImportVisiable: true
|
||||
})
|
||||
} else if(e.key == "2") {
|
||||
window.open("/spa/hrmSalary/static/index.html#/main/hrmSalary/compareDetail?id=" + this.id)
|
||||
} else if(e.key == "3") {
|
||||
const {calculateStore: {exportAll}} = this.props;
|
||||
exportAll(this.id)
|
||||
}
|
||||
}
|
||||
|
||||
// 导入表单添加表头回调
|
||||
handleAcctModalAdd(fieldData) {
|
||||
this.setState({
|
||||
fieldData
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const { selectedKey, modalParam, acctResultImportVisiable } = this.state;
|
||||
|
||||
const menu = (
|
||||
<Menu onClick={handleMenuClick}>
|
||||
<Menu onClick={this.handleMenuClick.bind(this)}>
|
||||
<Menu.Item key="1">导入</Menu.Item>
|
||||
<Menu.Item key="2">线下对比</Menu.Item>
|
||||
<Menu.Item key="3">导出全部</Menu.Item>
|
||||
|
|
@ -97,7 +118,21 @@ export default class CalculateDetail extends React.Component {
|
|||
{
|
||||
selectedKey == 1 && <SalaryDetail />
|
||||
}
|
||||
|
||||
{
|
||||
acctResultImportVisiable && <AcctResultImportModal
|
||||
visiable={acctResultImportVisiable}
|
||||
fieldData={this.state.fieldData}
|
||||
onAdd={(fieldData) => {
|
||||
this.handleAcctModalAdd(fieldData)
|
||||
}}
|
||||
onCancel={() => this.setState({
|
||||
acctResultImportVisiable: false,
|
||||
fieldData: {}
|
||||
})}
|
||||
id={this.id}
|
||||
/>
|
||||
}
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ export default class Payroll extends React.Component {
|
|||
}
|
||||
|
||||
// 预览
|
||||
handlePreview() {
|
||||
handlePreview() {
|
||||
window.open("/spa/hrmSalary/static/index.html#/main/hrmSalary/templatePreview")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,13 @@ export class calculateStore {
|
|||
@observable acctResultListColumns = []; // 列
|
||||
@observable acctresultDetailForm = {}; // 编辑薪资表单数据
|
||||
@observable acctResultListTableStore = new TableStore()
|
||||
// 导入
|
||||
@observable importFieldData = {}; // 表头选择列表
|
||||
@observable acctResultImportPreview = {}; // 核算结果预览
|
||||
@observable previewAcctResultList = {}; //预览数据
|
||||
@observable previewAcctResultColumns = []; // 预览列表
|
||||
@observable previewAcctResultDataSource = []; // 预览DataSource
|
||||
@observable importAcctResult = {}; // 导入结果
|
||||
|
||||
//*** 线下比对 ***
|
||||
@observable comparisonresultListDataSource = [];// dataSource
|
||||
|
|
@ -391,4 +398,88 @@ export class calculateStore {
|
|||
|
||||
}
|
||||
|
||||
// 获取导入字段设置
|
||||
@action
|
||||
getImportField = (salaryAcctRecordId) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
API.getImportField({salaryAcctRecordId}).then(res => {
|
||||
if(res.status) {
|
||||
this.importFieldData = res.data
|
||||
resolve(res.data)
|
||||
} else {
|
||||
message.error(res.errormsg || "获取失败")
|
||||
reject()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// 下载薪资导入核算模板
|
||||
@action
|
||||
getImportTemplate = (salaryItemIds, salaryAcctRecordId) => {
|
||||
API.getImportTemplate(salaryItemIds, salaryAcctRecordId)
|
||||
}
|
||||
|
||||
// 核算结果-导入预览
|
||||
@action
|
||||
fetchPreviewAcctResult = (params) => {
|
||||
API.previewAcctResult(params).then((res) => {
|
||||
if(res.status) {
|
||||
this.previewAcctResultList = res.data
|
||||
this.previewAcctResultColumns = res.data.headers.map((item, index) => {
|
||||
let column = {}
|
||||
column.title = item;
|
||||
column.dataIndex = "" + index;
|
||||
column.key = index + ""
|
||||
return column
|
||||
})
|
||||
|
||||
this.previewAcctResultDataSource = res.data.list.map((item) => {
|
||||
let data = {}
|
||||
item.map((i, index) => {
|
||||
data[index + ''] = i
|
||||
})
|
||||
return data
|
||||
})
|
||||
} else {
|
||||
message.error(res.errormsg || "获取失败")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 核算结果-导入
|
||||
@action
|
||||
fetchImportAcctResult = (params) => {
|
||||
API.importAcctResult(params).then(res=> {
|
||||
if(res.status) {
|
||||
this.importAcctResult = res.data
|
||||
} else {
|
||||
message.error(res.errormsg || "导入失败")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 核算结果-导出全部
|
||||
@action
|
||||
exportAll = (salaryAcctRecordId) => {
|
||||
API.exportAcctResult(salaryAcctRecordId)
|
||||
}
|
||||
|
||||
// 线下对比-列表
|
||||
@action
|
||||
fetchComparisonResultList = (onlyDiffEmployee, onlyDiffSalaryItem, salaryAcctRecordId) => {
|
||||
let params = {
|
||||
onlyDiffEmployee,
|
||||
onlyDiffSalaryItem,
|
||||
salaryAcctRecordId
|
||||
}
|
||||
API.comparisonResultList(params).then(res => {
|
||||
if(res.status) {
|
||||
this.comparisonResultList = res.data
|
||||
} else {
|
||||
message.error(res.errormsg || "获取失败")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -133,7 +133,7 @@ export class payrollStore {
|
|||
if(res.status) {
|
||||
let response = res.data.salaryTemplateBaseSet
|
||||
let templateBaseData = response.data
|
||||
templateBaseData.salarySob = templateBaseData.salarySob !== undefined ? templateBaseData.salarySob : null;
|
||||
templateBaseData.salarySob = templateBaseData.salarySob !== undefined ? templateBaseData.salarySob + "": null;
|
||||
this.templateBaseData = templateBaseData // 基础信息表单数据
|
||||
|
||||
this.salarySobOptions = response.salarySobOptions ?
|
||||
|
|
|
|||
Loading…
Reference in New Issue