initial docker setup
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Button} from 'reactstrap';
|
||||
import {Link} from 'react-router-dom';
|
||||
import {WiaasTableRow, WiaasTableCol} from '../../../mainComponents/table/WiaasTable.jsx';
|
||||
import {orderTexts} from '../../../constants/ordersConstants';
|
||||
import '../style/Orders.css';
|
||||
import OrderPackage from './OrderPackage.jsx';
|
||||
|
||||
class ActiveOrderItem extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
showPackages: false
|
||||
};
|
||||
|
||||
this.toggle = this.toggle.bind(this);
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setState({
|
||||
showPackages: !this.state.showPackages
|
||||
});
|
||||
}
|
||||
|
||||
getIconClass(type) {
|
||||
return 'fa fa-angle-' + type + ' toggle-view-packages';
|
||||
}
|
||||
|
||||
render() {
|
||||
const {order, isViewAllOrdersChecked} = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<WiaasTableRow className={"order-central-row order-border-" + order.status}>
|
||||
<WiaasTableCol header="#">
|
||||
{!this.state.showPackages && <i className={this.getIconClass('down')} aria-hidden="true" onClick={this.toggle}></i>}
|
||||
{this.state.showPackages && <i className={this.getIconClass('up')} aria-hidden="true" onClick={this.toggle}></i>}
|
||||
<i className="fa fa-list-alt package-photo" aria-hidden="true" />
|
||||
<div className="order-number">{order.orderNumber}</div>
|
||||
</WiaasTableCol>
|
||||
<WiaasTableCol header={orderTexts.labels.REFERENCE}>{order.reference ? order.reference : '-'}</WiaasTableCol>
|
||||
{isViewAllOrdersChecked['active'] && <WiaasTableCol header={orderTexts.labels.PLACED_BY}>{order.customerName ? order.customerName : ''}</WiaasTableCol>}
|
||||
<WiaasTableCol header={orderTexts.labels.ORDER_DATE}>{order.orderDate ? order.orderDate : '-'}</WiaasTableCol>
|
||||
<WiaasTableCol header={orderTexts.labels.EST_DELIVERY}>{order.estimatedDeliveryDate ? order.estimatedDeliveryDate : '-'}</WiaasTableCol>
|
||||
<WiaasTableCol header="Catalogue">
|
||||
<div className="order-item-cl">
|
||||
<img className="cl-photo" src="static/img/man-icon.png" alt="Catalogue" />
|
||||
<div className="cl-details">
|
||||
<div className="cl-contact-name">{order.clContactName}</div>
|
||||
<div className="cl-name">{order.clName}</div>
|
||||
</div>
|
||||
</div>
|
||||
</WiaasTableCol>
|
||||
<WiaasTableCol header={orderTexts.labels.AMOUNT}>
|
||||
{order.orderCurrency && order.orderCurrency.currency
|
||||
? order.orderTotalPrice.toLocaleString() + ' ' + order.orderCurrency.currency
|
||||
: parseFloat(order.orderTotalPrice).toLocaleString()}
|
||||
</WiaasTableCol>
|
||||
<WiaasTableCol header={orderTexts.labels.STATUS}>
|
||||
<div className={'status-icon ' + order.status}></div>{order.status}
|
||||
</WiaasTableCol>
|
||||
<WiaasTableCol header="Buttons details">
|
||||
<Link to={'/orders/' + order.id} className="actions-link">
|
||||
<Button color="secondary" className="actions-button">{orderTexts.buttons.DELIVERY_DETAILS}</Button>
|
||||
</Link>
|
||||
|
||||
</WiaasTableCol>
|
||||
</WiaasTableRow>
|
||||
{ this.state.showPackages && <OrderPackage order={order} type="active"/> }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
isViewAllOrdersChecked: state.ordersReducer.isViewAllOrdersChecked
|
||||
});
|
||||
export default connect(mapStateToProps)(ActiveOrderItem);
|
||||
26
frontend/src/containers/orders/components/AddComment.jsx
Normal file
26
frontend/src/containers/orders/components/AddComment.jsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import React, {Component} from 'react';
|
||||
import { Editor } from '@tinymce/tinymce-react';
|
||||
|
||||
class AddComment extends Component {
|
||||
handleEditorChange = (e) => {
|
||||
const comment = e.target.getContent();
|
||||
this.props.onEditorChange(comment);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Editor
|
||||
init={{
|
||||
plugins: 'link textcolor lists colorpicker code',
|
||||
toolbar: 'undo redo | styleselect | bold italic underline forecolor fontsizeselect | link | alignleft aligncenter alignright | numlist bullist | outdent indent | code'
|
||||
}}
|
||||
onChange={this.handleEditorChange}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default AddComment;
|
||||
@@ -0,0 +1,81 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Dropdown, DropdownToggle, DropdownMenu, DropdownItem} from 'reactstrap';
|
||||
import {Link} from 'react-router-dom';
|
||||
import SupportMail from './SupportMail.jsx';
|
||||
import {setDialogContent, setDialogOpenFlag} from '../../../actions/dialog/dialogActions';
|
||||
import {sendSupportMail} from '../../../actions/orders/processActions';
|
||||
import {orderTexts} from '../../../constants/ordersConstants';
|
||||
|
||||
class HistoryOrdersButtons extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.toggle = this.toggle.bind(this);
|
||||
this.sendSupportMail = this.sendSupportMail.bind(this);
|
||||
this.openDialogContent = this.openDialogContent.bind(this);
|
||||
|
||||
this.state = {
|
||||
dropdownOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setState({
|
||||
dropdownOpen: !this.state.dropdownOpen
|
||||
});
|
||||
}
|
||||
|
||||
openDialogContent() {
|
||||
const dialogContent = {
|
||||
buttons: [
|
||||
{
|
||||
color: 'secondary',
|
||||
name: orderTexts.buttons.SEND,
|
||||
id: 'send-mail-to-support-btn',
|
||||
action: this.sendSupportMail
|
||||
},
|
||||
{
|
||||
color: 'secondary',
|
||||
name: orderTexts.buttons.CANCEL,
|
||||
id: 'cancel-send-mail-to-support-btn'
|
||||
}
|
||||
],
|
||||
header: orderTexts.labels.SUPPORT_MESSAGE_HEADER,
|
||||
TagName: SupportMail,
|
||||
params: {orderInfo: this.props.order, orderPackages: this.props.order.packages}
|
||||
};
|
||||
|
||||
this.props.dispatch(setDialogOpenFlag(true));
|
||||
this.props.dispatch(setDialogContent(dialogContent));
|
||||
}
|
||||
|
||||
sendSupportMail() {
|
||||
this.props.dispatch(sendSupportMail(this.props.order, this.props.order.packages, this.props.supportText));
|
||||
}
|
||||
|
||||
render() {
|
||||
const {order} = this.props;
|
||||
|
||||
return (
|
||||
<Dropdown size="sm" isOpen={this.state.dropdownOpen} toggle={this.toggle}>
|
||||
<DropdownToggle className="actions-button" caret>
|
||||
{orderTexts.buttons.ACTIONS}
|
||||
</DropdownToggle>
|
||||
<DropdownMenu right>
|
||||
<DropdownItem className="actions-item" onClick={this.openDialogContent}> {orderTexts.buttons.SUPPORT}
|
||||
</DropdownItem>
|
||||
<Link to={'/orders/' + order.id} className="actions-link">
|
||||
<DropdownItem className="actions-item">
|
||||
{orderTexts.buttons.DETAILS}
|
||||
</DropdownItem>
|
||||
</Link>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
supportText: state.processReducer.supportText
|
||||
});
|
||||
export default connect(mapStateToProps)(HistoryOrdersButtons);
|
||||
@@ -0,0 +1,77 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {WiaasTableRow, WiaasTableCol} from '../../../mainComponents/table/WiaasTable.jsx';
|
||||
import {orderTexts} from '../../../constants/ordersConstants';
|
||||
import '../style/Orders.css';
|
||||
import OrderPackage from './OrderPackage.jsx';
|
||||
import HistoryOrderButtons from './HistoryOrderButtons.jsx';
|
||||
|
||||
class HistoryOrdersItem extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
showPackages: false
|
||||
};
|
||||
|
||||
this.toggle = this.toggle.bind(this);
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setState({
|
||||
showPackages: !this.state.showPackages
|
||||
});
|
||||
}
|
||||
|
||||
getIconClass(type) {
|
||||
return 'fa fa-angle-' + type + ' toggle-view-packages';
|
||||
}
|
||||
|
||||
render() {
|
||||
const {order, isViewAllOrdersChecked} = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<WiaasTableRow className={"order-central-row order-border-" + order.status}>
|
||||
<WiaasTableCol header="#">
|
||||
{!this.state.showPackages && <i className={this.getIconClass('down')} aria-hidden="true" onClick={this.toggle}></i>}
|
||||
{this.state.showPackages && <i className={this.getIconClass('up')} aria-hidden="true" onClick={this.toggle}></i>}
|
||||
<i className="fa fa-list-alt package-photo" aria-hidden="true" />
|
||||
<div className="order-number">{order.orderNumber}</div>
|
||||
</WiaasTableCol>
|
||||
<WiaasTableCol header={orderTexts.labels.REFERENCE}>{order.reference ? order.reference : '-'}</WiaasTableCol>
|
||||
{isViewAllOrdersChecked['history'] && <WiaasTableCol header={orderTexts.labels.PLACED_BY}>{order.customerName ? order.customerName : ''}</WiaasTableCol>}
|
||||
<WiaasTableCol header={orderTexts.labels.ORDER_DATE}>{order.orderDate ? order.orderDate : '-'}</WiaasTableCol>
|
||||
<WiaasTableCol header={orderTexts.labels.DELIVERY_DATE}>{order.deliveryDate}</WiaasTableCol>
|
||||
<WiaasTableCol header="Catalogue">
|
||||
<div className="order-item-cl">
|
||||
<img className="cl-photo" src="static/img/man-icon.png" alt="Catalogue" />
|
||||
<div className="cl-details">
|
||||
<div className="cl-contact-name">{order.clContactName}</div>
|
||||
<div className="cl-name">{order.clName}</div>
|
||||
</div>
|
||||
</div>
|
||||
</WiaasTableCol>
|
||||
<WiaasTableCol header={orderTexts.labels.AMOUNT}>
|
||||
{order.orderCurrency && order.orderCurrency.currency
|
||||
? order.orderTotalPrice.toLocaleString() + ' ' + order.orderCurrency.currency
|
||||
: parseFloat(order.orderTotalPrice).toLocaleString()}
|
||||
</WiaasTableCol>
|
||||
<WiaasTableCol header={orderTexts.labels.STATUS}>
|
||||
<div className={'status-icon ' + order.status}></div>{orderTexts.statuses[order.status]}
|
||||
</WiaasTableCol>
|
||||
<WiaasTableCol header="End of life">{order.endOfLife}</WiaasTableCol>
|
||||
<WiaasTableCol header="Buttons details">
|
||||
<HistoryOrderButtons order={order}/>
|
||||
</WiaasTableCol>
|
||||
</WiaasTableRow>
|
||||
{ this.state.showPackages && <OrderPackage order={order} type="history"/> }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
isViewAllOrdersChecked: state.ordersReducer.isViewAllOrdersChecked
|
||||
});
|
||||
export default connect(mapStateToProps)(HistoryOrdersItem);
|
||||
72
frontend/src/containers/orders/components/OrderComments.jsx
Normal file
72
frontend/src/containers/orders/components/OrderComments.jsx
Normal file
@@ -0,0 +1,72 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Button, Container, Row, Col} from 'reactstrap';
|
||||
import WiaasBox from '../../../mainComponents/box/WiaasBox.jsx';
|
||||
import AddComment from './AddComment.jsx';
|
||||
import {addComment} from '../../../actions/orders/processActions';
|
||||
import {orderTexts} from '../../../constants/ordersConstants';
|
||||
|
||||
class OrderComments extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.onEditorChange = this.onEditorChange.bind(this);
|
||||
this.addNewComment = this.addNewComment.bind(this);
|
||||
this.state = {
|
||||
newComment: ''
|
||||
};
|
||||
}
|
||||
|
||||
addNewComment(){
|
||||
this.props.dispatch(addComment(this.props.orderInfo.id, this.state.newComment));
|
||||
}
|
||||
|
||||
onEditorChange(newComment){
|
||||
this.setState({newComment});
|
||||
}
|
||||
|
||||
getOffset(isOwner){
|
||||
return isOwner ? 6 : 0;
|
||||
}
|
||||
|
||||
getClassByOwner(isOwner){
|
||||
return isOwner ? 'mine' : '';
|
||||
}
|
||||
|
||||
render() {
|
||||
const {orderComments} = this.props;
|
||||
|
||||
return (
|
||||
<div id="order-comments" className="order-comments">
|
||||
<WiaasBox mainTitle="Comments">
|
||||
<Container fluid={true} className="order-coments-body">
|
||||
<Row>
|
||||
<Col xl="6">
|
||||
{
|
||||
orderComments &&
|
||||
orderComments.map((orderComment, index) =>
|
||||
<Row key={'order-comment-' + index}>
|
||||
<Col xl={{size:6, offset:this.getOffset(orderComment.isOwner)}}>
|
||||
<div className={'order-comment ' + this.getClassByOwner(orderComment.isOwner)} key={'order-comment-' + index}>
|
||||
<div className="order-comment-header">{orderComment.username} - {orderComment.addDate}</div>
|
||||
<div dangerouslySetInnerHTML={{__html: orderComment.comment}}></div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
)
|
||||
}
|
||||
</Col>
|
||||
<Col xl="6">
|
||||
<AddComment onEditorChange={this.onEditorChange}/>
|
||||
<Button onClick={()=>{this.addNewComment()}} className="new-comment-button" color="secondary">{orderTexts.buttons.ADD_COMMENT}</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
</WiaasBox>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default connect()(OrderComments);
|
||||
26
frontend/src/containers/orders/components/OrderDocuments.jsx
Normal file
26
frontend/src/containers/orders/components/OrderDocuments.jsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import OrderDocumentsGroup from './OrderDocumentsGroup.jsx';
|
||||
import {orderTexts} from '../../../constants/ordersConstants';
|
||||
|
||||
class OrderDocuments extends Component {
|
||||
render() {
|
||||
const {orderInfo} = this.props;
|
||||
|
||||
return (
|
||||
<div id="order-documents" className="order-documents">
|
||||
{
|
||||
orderInfo.packages.map(orderPackage => <OrderDocumentsGroup key={'order-package-' + orderPackage.idPackage} documentsGroup={orderPackage} />)
|
||||
}
|
||||
{
|
||||
orderInfo.orderDocuments && <OrderDocumentsGroup key={'order-package-0'} documentsGroup={{documents: orderInfo.orderDocuments, packageName: orderTexts.labels.OTHER_DOCS}} />
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
orderInfo: state.processReducer.orderInfo
|
||||
});
|
||||
export default connect(mapStateToProps)(OrderDocuments);
|
||||
@@ -0,0 +1,85 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Tooltip} from 'reactstrap';
|
||||
import WiaasBox from '../../../mainComponents/box/WiaasBox.jsx';
|
||||
import {API_SERVER} from '../../../config';
|
||||
import FileDownloader from '../../../helpers/FileDownloader';
|
||||
|
||||
const fileHandler = new FileDownloader();
|
||||
|
||||
const iconTypes = {
|
||||
doc: 'file-word-o',
|
||||
docx: 'file-word-o',
|
||||
odt: 'file-word-o',
|
||||
ods: 'file-excel-o',
|
||||
pdf: 'file-pdf-o',
|
||||
png: 'file-image-o',
|
||||
jpg: 'file-image-o',
|
||||
xls: 'file-excel-o',
|
||||
xlsx: 'file-excel-o',
|
||||
ppt: 'file-powerpoint-o',
|
||||
pptx: 'file-powerpoint-o'
|
||||
}
|
||||
|
||||
class OrderDocumentsGroup extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.toggle = this.toggle.bind(this);
|
||||
this.state = {};
|
||||
}
|
||||
|
||||
toggle(idDocument) {
|
||||
const obj = {}
|
||||
obj[idDocument] = !this.state[idDocument];
|
||||
|
||||
this.setState(obj);
|
||||
}
|
||||
|
||||
getDocumentIcon(documentType) {
|
||||
return iconTypes[documentType] || 'file';
|
||||
}
|
||||
|
||||
getDocumentText(document) {
|
||||
const name = document.documentName + '.' + document.extension;
|
||||
|
||||
return name.length > 9 ? name.substring(0, 10) + '...' : name;
|
||||
}
|
||||
|
||||
downloadDocument(document){
|
||||
const fileUrl = `${API_SERVER}/utils/api/downloadFile?idDocument=${document.idDocument}&fileName=${document.documentName}.${document.extension}&fileType=${document.documentTypeName}`
|
||||
const fileName = document.documentName + '.' + document.extension;
|
||||
fileHandler.download(fileUrl, fileName);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {documentsGroup} = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
documentsGroup.documents.length > 0 &&
|
||||
<WiaasBox mainTitle={documentsGroup.packageName}>
|
||||
{
|
||||
documentsGroup.documents.map(document => <a id={'document-' + document.idDocument} key={'order-document-' + document.idDocument}>
|
||||
<div onClick={() => {this.downloadDocument(document)}} className="document-link-big">
|
||||
<i className={'fa fa-4x fa-' + this.getDocumentIcon(document.extension)} aria-hidden="true"></i>
|
||||
<div>
|
||||
{this.getDocumentText(document)}
|
||||
<Tooltip placement="bottom"
|
||||
delay={{ show: 0, hide: 0}}
|
||||
container="order-documents"
|
||||
isOpen={this.state[document.idDocument]}
|
||||
target={'document-' + document.idDocument}
|
||||
toggle={()=>this.toggle(document.idDocument)}>
|
||||
{document.documentName} ({document.extension})
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div></a>)
|
||||
}
|
||||
</WiaasBox>
|
||||
}
|
||||
</div>)
|
||||
}
|
||||
}
|
||||
|
||||
export default OrderDocumentsGroup;
|
||||
152
frontend/src/containers/orders/components/OrderInfo.jsx
Normal file
152
frontend/src/containers/orders/components/OrderInfo.jsx
Normal file
@@ -0,0 +1,152 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import moment from 'moment';
|
||||
import {Container, Row, Col} from 'reactstrap';
|
||||
import TermsContainer from '../../terms/TermsContainer.jsx';
|
||||
import {orderTexts} from '../../../constants/ordersConstants';
|
||||
|
||||
class OrderInfo extends Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
acceptedDate: {},
|
||||
proposedDate: {},
|
||||
isPreliminaryInstallationDate: true
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setInstallationData(this.props);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
this.setInstallationData(nextProps);
|
||||
}
|
||||
|
||||
setInstallationData(props) {
|
||||
const acceptedDate = {};
|
||||
const proposedDate = {};
|
||||
const idOrder = props.orderDetails.info.id;
|
||||
const {isInstallationInPackage} = props.installationData;
|
||||
const {confirmationDates, areAllShippingDatesConfirmed} = props;
|
||||
const isPreliminaryInstallationDate = areAllShippingDatesConfirmed && idOrder in areAllShippingDatesConfirmed ? !areAllShippingDatesConfirmed[idOrder] : true;
|
||||
const isInstallationInOrder = Object.keys(isInstallationInPackage).some(idOrderPackage => {return isInstallationInPackage[idOrderPackage] === true;});
|
||||
|
||||
props.orderDetails.packages.forEach(orderPackage => {
|
||||
const idOrderPackagePair = idOrder + '-' + orderPackage.idPackage;
|
||||
|
||||
if(confirmationDates && confirmationDates[idOrderPackagePair]) {
|
||||
const packageDates = confirmationDates[idOrderPackagePair];
|
||||
const accepted = Object.keys(packageDates).find(installDate => {return packageDates[installDate].lastStatus === 'accepted'});
|
||||
acceptedDate[idOrderPackagePair] = accepted ? moment(accepted).format('Do MMM, YYYY') : '';
|
||||
const proposed = Object.keys(packageDates).find(installDate => {return packageDates[installDate].lastStatus === 'proposed'});
|
||||
proposedDate[idOrderPackagePair] = proposed ? moment(proposed).format('Do MMM, YYYY') : '';
|
||||
}
|
||||
});
|
||||
|
||||
this.setState({acceptedDate, proposedDate, isPreliminaryInstallationDate, isInstallationInOrder});
|
||||
}
|
||||
|
||||
render() {
|
||||
const {totalPrice, installationData} = this.props;
|
||||
const {acceptedDate, proposedDate, isPreliminaryInstallationDate, isInstallationInOrder} = this.state;
|
||||
const orderPackages = installationData.packages;
|
||||
const isInstallationInPackage = installationData.isInstallationInPackage;
|
||||
const orderInfo = this.props.orderInfo.info;
|
||||
|
||||
return (
|
||||
<Container fluid={true} id="order-info-description">
|
||||
<Row>
|
||||
<Col xl="2">
|
||||
<div className="subtitle"><h6>{orderTexts.labels.ORDER_DATE}:</h6></div>
|
||||
<span>{orderInfo.orderDate}</span>
|
||||
<div className="subtitle"><h6>{orderTexts.labels.SOLD_BY}:</h6></div>
|
||||
<span>{orderInfo.commercialLead}</span>
|
||||
|
||||
</Col>
|
||||
<Col xl="2">
|
||||
<div>
|
||||
<div className="subtitle"><h6>{orderTexts.labels.REFERENCE}:</h6></div>
|
||||
<span>{orderInfo.reference || '-'}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div className="subtitle"><h6>{orderTexts.labels.BID}:</h6></div>
|
||||
<span>{orderInfo.tender || '-'}</span>
|
||||
</div>
|
||||
</Col>
|
||||
{ isInstallationInOrder &&
|
||||
<Col xl="3">
|
||||
<div>
|
||||
<div className="subtitle">
|
||||
{ isPreliminaryInstallationDate
|
||||
? <h6>{orderTexts.labels.PRELIMINARY_INSTALLATION_DATE_LABEL}:</h6>
|
||||
: <h6>{orderTexts.labels.INSTALLATION_DATE}:</h6>
|
||||
}
|
||||
</div>
|
||||
{ orderPackages &&
|
||||
orderPackages.map(orderPackage =>
|
||||
<div key={'package-install-date-' + orderPackage.idOrderPackagePair}>
|
||||
{ isInstallationInPackage[orderPackage.idOrderPackagePair] &&
|
||||
<div>
|
||||
{ orderPackages.length > 1 &&
|
||||
<span>{orderPackage.packageName}: </span>
|
||||
}
|
||||
<span className="installation-date-per-package">
|
||||
{ acceptedDate && acceptedDate[orderPackage.idOrderPackagePair]
|
||||
? acceptedDate[orderPackage.idOrderPackagePair]
|
||||
: proposedDate && proposedDate[orderPackage.idOrderPackagePair]
|
||||
? proposedDate[orderPackage.idOrderPackagePair]
|
||||
: orderTexts.labels.NOT_SET
|
||||
}
|
||||
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</Col>
|
||||
}
|
||||
|
||||
<Col xl="2">
|
||||
<div className="subtitle"><h6>{orderTexts.labels.TOTAL_DELVIERY_PRICE}:</h6></div>
|
||||
<span>{totalPrice.fixedPrice.toLocaleString()} {totalPrice.currency}</span>
|
||||
|
||||
{
|
||||
totalPrice.recurrentPrice > 0 &&
|
||||
<div>
|
||||
<div className="subtitle"><h6>{orderTexts.labels.TOTAL_RECURRENT_PRICE}:</h6></div>
|
||||
<span>
|
||||
{totalPrice.recurrentPrice.toLocaleString() + ' ' + totalPrice.currency}
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
</Col>
|
||||
<Col xl="2">
|
||||
<div>
|
||||
<div className="subtitle"><h6>{orderTexts.labels.PROJECT}:</h6></div>
|
||||
<span>{orderInfo.projectName || '-'}</span>
|
||||
</div>
|
||||
|
||||
<div className="terms-link">
|
||||
<i className="fa fa-link"></i>
|
||||
<span className="terms-label">
|
||||
<TermsContainer idTerms={orderInfo.idTerms}/>
|
||||
</span>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
orderInfo: state.processReducer.orderInfo,
|
||||
confirmationDates: state.processReducer.confirmationDates,
|
||||
areAllShippingDatesConfirmed: state.processReducer.areAllShippingDatesConfirmed
|
||||
});
|
||||
export default connect(mapStateToProps)(OrderInfo);
|
||||
75
frontend/src/containers/orders/components/OrderList.jsx
Normal file
75
frontend/src/containers/orders/components/OrderList.jsx
Normal file
@@ -0,0 +1,75 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import ActiveOrderItem from './ActiveOrderItem.jsx';
|
||||
import HistoryOrderItem from './HistoryOrderItem.jsx';
|
||||
import {WiaasTable, WiaasTableHeader, WiaasTableBody} from '../../../mainComponents/table/WiaasTable.jsx';
|
||||
import {orderTexts} from '../../../constants/ordersConstants';
|
||||
|
||||
class OrderList extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.getHeadersByType = this.getHeadersByType.bind(this);
|
||||
}
|
||||
|
||||
getHeadersByType(type) {
|
||||
const activeOrdersHeader = [
|
||||
orderTexts.headers.ORDER,
|
||||
orderTexts.headers.REFERENCE,
|
||||
orderTexts.headers.ORDER_DATE,
|
||||
orderTexts.headers.ESTIMATED_DATE,
|
||||
orderTexts.headers.COMMERCIAL_LEAD,
|
||||
orderTexts.headers.AMOUNT,
|
||||
orderTexts.headers.STATUS,
|
||||
''
|
||||
];
|
||||
|
||||
const historyOrdersHeader = [
|
||||
orderTexts.headers.ORDER,
|
||||
orderTexts.headers.REFERENCE,
|
||||
orderTexts.headers.ORDER_DATE,
|
||||
orderTexts.headers.DELIVERY_DATE,
|
||||
orderTexts.headers.COMMERCIAL_LEAD,
|
||||
orderTexts.headers.AMOUNT,
|
||||
orderTexts.headers.STATUS,
|
||||
orderTexts.headers.END_OF_LIFE,
|
||||
''
|
||||
];
|
||||
|
||||
if(this.props.isCompanyAdmin && this.props.isViewAllOrdersChecked[type]) {
|
||||
activeOrdersHeader.splice(2, 0, orderTexts.headers.PLACED_BY);
|
||||
activeOrdersHeader.join();
|
||||
historyOrdersHeader.splice(2, 0, orderTexts.headers.PLACED_BY);
|
||||
historyOrdersHeader.join();
|
||||
}
|
||||
|
||||
return type === 'active' ? activeOrdersHeader : historyOrdersHeader;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {orders, type, isCompanyAdmin, isViewAllOrdersChecked} = this.props;
|
||||
const TagName = type && type === 'active' ? ActiveOrderItem : HistoryOrderItem;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<WiaasTable>
|
||||
<WiaasTableHeader headers={this.getHeadersByType(type)}/>
|
||||
<WiaasTableBody>
|
||||
{
|
||||
orders &&
|
||||
orders.map((order, index) =>
|
||||
(('isMyOrder' in order && order.isMyOrder) || (isCompanyAdmin && isViewAllOrdersChecked[type])) &&
|
||||
<TagName key={order.orderNumber} order={order} />
|
||||
)
|
||||
}
|
||||
</WiaasTableBody>
|
||||
</WiaasTable>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
isCompanyAdmin: state.auth.isCompanyAdmin,
|
||||
isViewAllOrdersChecked: state.ordersReducer.isViewAllOrdersChecked
|
||||
});
|
||||
export default connect(mapStateToProps)(OrderList);
|
||||
@@ -0,0 +1,56 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Row, Col, Input} from 'reactstrap';
|
||||
import '../style/OrdersList.css';
|
||||
import {setViewAllOrdersFlag} from '../../../actions/orders/ordersActions';
|
||||
import {orderTexts} from '../../../constants/ordersConstants';
|
||||
|
||||
class OrderListHeader extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
isViewAllOrdersChecked: false
|
||||
};
|
||||
this.handleInputChange = this.handleInputChange.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const isViewAllChecked = {};
|
||||
isViewAllChecked[this.props.params] = this.state.isViewAllOrdersChecked;
|
||||
this.props.dispatch(setViewAllOrdersFlag(isViewAllChecked));
|
||||
}
|
||||
|
||||
handleInputChange(e) {
|
||||
this.setState({
|
||||
isViewAllOrdersChecked: !this.state.isViewAllOrdersChecked
|
||||
});
|
||||
const isViewAllChecked = {};
|
||||
isViewAllChecked[this.props.params] = e.target.checked;
|
||||
this.props.dispatch(setViewAllOrdersFlag(isViewAllChecked));
|
||||
}
|
||||
|
||||
render() {
|
||||
const {isCompanyAdmin} = this.props;
|
||||
|
||||
return (
|
||||
<Row id="view-all-orders-checkbox">
|
||||
{isCompanyAdmin &&
|
||||
<Col xl="10">
|
||||
<Input type="checkbox"
|
||||
name="isViewAllOrdersChecked"
|
||||
checked={this.state.isViewAllOrdersChecked}
|
||||
onChange={this.handleInputChange}
|
||||
className="view-all-orders-checkbox" />
|
||||
<span className="view-all-orders-text">{orderTexts.labels.VIEW_ALL_ORDERS}</span>
|
||||
</Col>
|
||||
}
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
isCompanyAdmin: state.auth.isCompanyAdmin
|
||||
});
|
||||
export default connect(mapStateToProps)(OrderListHeader);
|
||||
92
frontend/src/containers/orders/components/OrderPackage.jsx
Normal file
92
frontend/src/containers/orders/components/OrderPackage.jsx
Normal file
@@ -0,0 +1,92 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Col} from 'reactstrap';
|
||||
import WiaasBox from '../../../mainComponents/box/WiaasBox.jsx';
|
||||
import {WiaasTable, WiaasTableHeader, WiaasTableBody, WiaasTableRow, WiaasTableCol} from '../../../mainComponents/table/WiaasTable.jsx';
|
||||
import {orderTexts} from '../../../constants/ordersConstants';
|
||||
import '../style/Orders.css';
|
||||
|
||||
class OrderPackage extends Component {
|
||||
calculateRecuringPrice(packageDetails) {
|
||||
return packageDetails.units * (parseFloat(packageDetails.packageRecuringPrice) + parseFloat(packageDetails.packageServicePrice));
|
||||
}
|
||||
|
||||
calculateQuantityPrice(quantity, price, recurringPrice = 0) {
|
||||
return quantity * parseFloat(price + recurringPrice);
|
||||
}
|
||||
|
||||
getHeadersByType(type) {
|
||||
if(type === 'active') {
|
||||
return ['Package', 'Price', 'Services and support', 'Delivery active step'];
|
||||
}
|
||||
|
||||
return ['Package', 'Price', 'Services and support', 'End of Life'];
|
||||
}
|
||||
|
||||
render() {
|
||||
const {order, type} = this.props;
|
||||
|
||||
return (
|
||||
<WiaasTableRow className={"order-border-" + order.status}>
|
||||
<Col lg="3" sm="12" xs="12">
|
||||
<WiaasBox mainTitle="Order Details">
|
||||
<div className="order-details-container">
|
||||
<WiaasTableRow id={'delivery-address-' + order.id}>
|
||||
<Col lg="4" sm="4" xs="4">{orderTexts.labels.DELIVERY_ADDRESS}:</Col>
|
||||
<Col lg="8" sm="8" xs="8">{order.deliveryAddress}</Col>
|
||||
</WiaasTableRow>
|
||||
<WiaasTableRow id={'phone-' + order.id}>
|
||||
<Col lg="4" sm="4" xs="4">{orderTexts.labels.PHONE_NUMBER}:</Col>
|
||||
<Col lg="8" sm="8" xs="8">{order.phone}</Col>
|
||||
</WiaasTableRow>
|
||||
<WiaasTableRow id={'mail-' + order.id}>
|
||||
<Col lg="4" sm="4" xs="4">{orderTexts.labels.MAIL}:</Col>
|
||||
<Col lg="8" sm="8" xs="8">{order.mail}</Col>
|
||||
</WiaasTableRow>
|
||||
<WiaasTableRow id={'commercial-lead-phone-' + order.id}>
|
||||
<Col lg="4" sm="4" xs="4">{order.clName} {orderTexts.labels.PHONE_NUMBER}:</Col>
|
||||
<Col lg="8" sm="8" xs="8">{order.commercialLeadPhone}</Col>
|
||||
</WiaasTableRow>
|
||||
<WiaasTableRow id={'mail-' + order.id}>
|
||||
<Col lg="4" sm="4" xs="4">{order.clName} {orderTexts.labels.MAIL}:</Col>
|
||||
<Col lg="8" sm="8" xs="8">{order.commercialLeadMail}</Col>
|
||||
</WiaasTableRow>
|
||||
</div>
|
||||
</WiaasBox>
|
||||
</Col>
|
||||
<Col lg="9" sm="12" xs="12">
|
||||
<WiaasBox mainTitle="Items">
|
||||
<WiaasTable>
|
||||
<WiaasTableHeader headers={this.getHeadersByType(type)}/>
|
||||
<WiaasTableBody>
|
||||
{order.packages.map((orderPackage, index) =>
|
||||
<WiaasTableRow className="order-central-row" key={orderPackage.idOrder + '-' + orderPackage.idPackage}>
|
||||
<WiaasTableCol header="Package" className="package-info-col">
|
||||
<div className="package-name">{orderPackage.units} x {orderPackage.packageName}</div>
|
||||
</WiaasTableCol>
|
||||
<WiaasTableCol header="Price">
|
||||
{this.calculateQuantityPrice(orderPackage.units, orderPackage.packageFixedPrice).toLocaleString()} {orderPackage.packageCurrency && orderPackage.packageCurrency.currency} {' '}
|
||||
({orderPackage.paymentType})
|
||||
</WiaasTableCol>
|
||||
<WiaasTableCol header="Services and support">
|
||||
{this.calculateQuantityPrice(orderPackage.units, orderPackage.packageServicePrice, orderPackage.packageRecuringPrice).toLocaleString() + ' / ' + orderPackage.periodUnit + ' '}
|
||||
{orderTexts.labels.EXTEND} {orderPackage.periodUnit} (Max {orderPackage.maxContractPeriod})
|
||||
</WiaasTableCol>
|
||||
<WiaasTableCol>
|
||||
{
|
||||
type === 'active'
|
||||
? orderPackage.shortDesc ? orderPackage.shortDesc : '-'
|
||||
: orderPackage.endOfLife ? orderPackage.endOfLife : '-'
|
||||
}
|
||||
</WiaasTableCol>
|
||||
</WiaasTableRow>
|
||||
)}
|
||||
</WiaasTableBody>
|
||||
</WiaasTable>
|
||||
</WiaasBox>
|
||||
</Col>
|
||||
</WiaasTableRow>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default OrderPackage;
|
||||
35
frontend/src/containers/orders/components/PackagesNav.jsx
Normal file
35
frontend/src/containers/orders/components/PackagesNav.jsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Row, Col} from 'reactstrap';
|
||||
import {orderTexts} from '../../../constants/ordersConstants';
|
||||
|
||||
class PackageNav extends Component {
|
||||
getClass(packageName) {
|
||||
return this.props.params.packageNameFilter === packageName ? 'process-nav-div selected-nav' : 'process-nav-div';
|
||||
}
|
||||
|
||||
render() {
|
||||
const {packages, onPackageFilter} = this.props.params;
|
||||
|
||||
return (
|
||||
<Row id="process-nav" className="process-nav">
|
||||
<Col xl="1" lg="2" md="3" sm="12" xs="12" className="process-nav-buttons">
|
||||
<div className="wiaas-main-title">
|
||||
{orderTexts.labels.PACKAGES}
|
||||
</div>
|
||||
</Col>
|
||||
<Col xl="9" lg="9" md="4" xs="12" className="process-menu">
|
||||
<div className={this.getClass('all')} onClick={()=>{onPackageFilter('all')}}>{orderTexts.buttons.ALL}</div>
|
||||
{
|
||||
packages.length > 0 &&
|
||||
packages.map((orderPackage) => <div key={'menu-package-' + orderPackage.idPackage}
|
||||
onClick={()=>{onPackageFilter(orderPackage.packageName)}}
|
||||
className={this.getClass(orderPackage.packageName)}>{orderPackage.packageName}</div>)
|
||||
}
|
||||
</Col>
|
||||
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default PackageNav;
|
||||
121
frontend/src/containers/orders/components/SupportMail.jsx
Normal file
121
frontend/src/containers/orders/components/SupportMail.jsx
Normal file
@@ -0,0 +1,121 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Row, Col, FormGroup, Label, Input} from 'reactstrap';
|
||||
import {setSupportMessage} from '../../../actions/orders/processActions';
|
||||
import {orderTexts} from '../../../constants/ordersConstants';
|
||||
|
||||
class SupportMail extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
supportText: ''
|
||||
};
|
||||
this.setSupportMessage = this.setSupportMessage.bind(this);
|
||||
}
|
||||
calculateFixedPrice(quantity, price) {
|
||||
return quantity*price;
|
||||
}
|
||||
|
||||
calculateRecurrentPrice(orderPackage) {
|
||||
return orderPackage.units*(orderPackage.packageRecuringPrice + orderPackage.packageServicePrice);
|
||||
}
|
||||
|
||||
handleInputChange(event) {
|
||||
this.setState({supportText: event.target.value});
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
setSupportMessage() {
|
||||
this.props.dispatch(setSupportMessage(this.state.supportText));
|
||||
}
|
||||
|
||||
render() {
|
||||
const {orderInfo, orderPackages} = this.props.params;
|
||||
|
||||
return (
|
||||
<span id="send-support-mail-container">
|
||||
{orderInfo && orderPackages &&
|
||||
<div>
|
||||
<div id="order-details">
|
||||
<Row>
|
||||
<Col>
|
||||
<h5>{orderTexts.labels.ORDER_DETAILS}</h5>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col xl="4">
|
||||
<span className="subtitle">{orderTexts.labels.ORDER_NUMBER}:</span>
|
||||
</Col>
|
||||
<Col xl="8">
|
||||
<span>{orderInfo.orderNumber}</span>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col xl="4">
|
||||
<span className="subtitle">{orderTexts.labels.LOCATION_DETAILS}:</span>
|
||||
</Col>
|
||||
<Col xl="8">
|
||||
<span>{orderInfo.reference || '-'}</span>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
<div id="order-items" className="support-details">
|
||||
<Row>
|
||||
<Col>
|
||||
<h5>{orderTexts.labels.ORDER_ITEMS}</h5>
|
||||
</Col>
|
||||
</Row>
|
||||
{ orderPackages.map((orderPackage, mapKey) =>
|
||||
<div key={'order-package-'+mapKey} className="order-package-details">
|
||||
<Row>
|
||||
<Col>
|
||||
<span className="fa fa-shopping-cart subtitle"></span>
|
||||
<span className="package-name"> {orderPackage.units} x {orderPackage.packageName}</span>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{orderPackage.endOfLife &&
|
||||
<Row>
|
||||
<Col>
|
||||
<span className="subtitle">{orderTexts.labels.END_OF_LIFE}:</span>
|
||||
</Col>
|
||||
<Col xl="8">
|
||||
<span>{orderPackage.endOfLife}</span>
|
||||
</Col>
|
||||
</Row>
|
||||
}
|
||||
<Row>
|
||||
<Col>
|
||||
<span className="subtitle">{orderTexts.labels.STATUS}:</span>
|
||||
</Col>
|
||||
<Col xl="8">
|
||||
<span>{orderPackage.status}</span>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div id="order-support-text" className="support-details">
|
||||
<Row>
|
||||
<Col>
|
||||
<FormGroup>
|
||||
<Label for="supportText">{orderTexts.labels.ENTER_TEXT}</Label>
|
||||
<Input id="my-support-mail-text"
|
||||
type="textarea"
|
||||
name="supportText"
|
||||
value={this.state.supportText}
|
||||
onChange={(e) => this.handleInputChange(e)}
|
||||
onBlur={this.setSupportMessage}/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default connect()(SupportMail);
|
||||
@@ -0,0 +1,165 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import 'react-datepicker/dist/react-datepicker.css';
|
||||
import moment from 'moment';
|
||||
import {Row, Col, Button, Popover, PopoverBody} from 'reactstrap';
|
||||
import '../../style/InstallationScheduling.css';
|
||||
import {updateInstallationDate, removeMyDate, setSchedulingFlag} from '../../../../actions/orders/processActions';
|
||||
import {setDialogContent, setDialogOpenFlag} from '../../../../actions/dialog/dialogActions';
|
||||
import {orderTexts} from '../../../../constants/ordersConstants';
|
||||
|
||||
class InstallationSchedulingDatesPerPackage extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
startDate: undefined,
|
||||
btnType: '',
|
||||
nestedModal: false,
|
||||
closeAll: false,
|
||||
popoverOpen: false
|
||||
};
|
||||
this.toggle = this.toggle.bind(this);
|
||||
this.openInstallationDialog = this.openInstallationDialog.bind(this);
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.handleBtnClick = this.handleBtnClick.bind(this);
|
||||
this.handleBtnAction = this.handleBtnAction.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dispatch(setSchedulingFlag(this.props.installationParams.isSchedulingDisabled));
|
||||
}
|
||||
|
||||
handleChange(date) {
|
||||
this.setState({startDate: date});
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setState({
|
||||
popoverOpen: !this.state.popoverOpen
|
||||
});
|
||||
}
|
||||
|
||||
canUserAcceptOrDecline(dateInfo, lastStatus) {
|
||||
let additionalCondition = false;
|
||||
if (lastStatus === 'declined') {
|
||||
additionalCondition = dateInfo.lastStatus === 'canceled' && dateInfo.isProposedByMe;
|
||||
}
|
||||
return !this.props.isComponentDisabled &&
|
||||
((dateInfo.lastStatus === 'proposed' && !dateInfo.isProposedByMe) ||
|
||||
(dateInfo.lastStatus === lastStatus && dateInfo.isProposedByMe) ||
|
||||
additionalCondition);
|
||||
}
|
||||
|
||||
isDateProposedByMe() {
|
||||
return this.props.dateInfo.lastStatus === 'proposed' && this.props.dateInfo.isProposedByMe === true;
|
||||
}
|
||||
|
||||
isRemoveBtnVisible(confirmationDate) {
|
||||
return !this.props.isComponentDisabled && this.isDateProposedByMe();
|
||||
}
|
||||
|
||||
handleBtnClick(type) {
|
||||
this.setState({type});
|
||||
const upperCaseType = type.charAt(0).toUpperCase() + type.slice(1);
|
||||
const dialogInstallationContent = {
|
||||
buttons: [
|
||||
{
|
||||
color: 'success',
|
||||
action: this.handleBtnAction,
|
||||
name: orderTexts.buttons.YES,
|
||||
id: type + '-installation-date-confirmation'
|
||||
}, {
|
||||
color: 'secondary',
|
||||
name: orderTexts.buttons.NO,
|
||||
action: this.openInstallationDialog,
|
||||
id: 'cancel-' + type + '-installation-date'
|
||||
}
|
||||
],
|
||||
header: upperCaseType + ' installation date confirmation',
|
||||
body: 'Are you sure you want to ' + type + ' the installation date proposed?'
|
||||
};
|
||||
|
||||
this.props.dispatch(setDialogOpenFlag(true));
|
||||
this.props.dispatch(setDialogContent(dialogInstallationContent));
|
||||
}
|
||||
|
||||
openInstallationDialog() {
|
||||
this.props.openDialogInstallContent(this.props.installationParams);
|
||||
}
|
||||
|
||||
handleBtnAction() {
|
||||
let handleFunction = this.state.type === 'remove' ? removeMyDate : updateInstallationDate;
|
||||
this.props.dispatch(handleFunction(this.props.orderPackage.idOrder, this.props.orderPackage.idPackage, this.props.confirmationDate, this.state.type));
|
||||
this.openInstallationDialog();
|
||||
}
|
||||
|
||||
getStatusIcon(status) {
|
||||
const statusesIcons = {
|
||||
proposed: 'clock-o',
|
||||
accepted: 'check',
|
||||
canceled: 'remove',
|
||||
declined: 'ban',
|
||||
invalid: 'remove'
|
||||
};
|
||||
|
||||
return 'status-icon-installation-dates fa fa-' + statusesIcons[status];
|
||||
}
|
||||
|
||||
render() {
|
||||
const {confirmationDate, dateInfo, orderPackage} = this.props;
|
||||
const idOrderPackageDatePair = orderPackage.idOrder + '-' + orderPackage.idPackage + '-' + confirmationDate;
|
||||
|
||||
return (
|
||||
<div id={"installation-scheduling-dates-container-" + idOrderPackageDatePair} className="installation-scheduling-dates-container">
|
||||
<span className="installation-date">
|
||||
<span className={this.getStatusIcon(dateInfo.lastStatus) + ' confirmation-' + dateInfo.lastStatus}></span>
|
||||
<span className="installation-date-proposed">{moment(confirmationDate).format('Do MMM, YYYY')}</span>
|
||||
<i className="dates-info-btn fa fa-info-circle"
|
||||
id={'dates-info-' + idOrderPackageDatePair}
|
||||
onClick={this.toggle}></i>
|
||||
<Popover placement="bottom"
|
||||
isOpen={this.state.popoverOpen}
|
||||
target={'dates-info-' + idOrderPackageDatePair}
|
||||
container={"installation-scheduling-dates-container-" + idOrderPackageDatePair}
|
||||
className="dates-info-popover"
|
||||
toggle={this.toggle}>
|
||||
<PopoverBody>
|
||||
{ dateInfo && dateInfo.details &&
|
||||
dateInfo.details.map((details) =>
|
||||
<Row key={'confirmation-date-details-' + details.currentDate}>
|
||||
<Col>
|
||||
{moment(details.currentDate).format('Do MMM, YYYY LT')}
|
||||
</Col>
|
||||
<Col className={"confirmation-" + details.status}>
|
||||
<span className={this.getStatusIcon(details.status)}></span>
|
||||
{details.status}
|
||||
</Col>
|
||||
<Col>
|
||||
{details.username} ({details.userType})
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
</PopoverBody>
|
||||
</Popover>
|
||||
</span>
|
||||
<span className="confirmation-dates-buttons">
|
||||
{ this.canUserAcceptOrDecline(dateInfo, 'declined') &&
|
||||
<Button id={"accept-date-"+idOrderPackageDatePair} className="installation-button install-btn-accept" onClick={() => {this.handleBtnClick('accept')}} >{orderTexts.buttons.ACCEPT}</Button>
|
||||
}
|
||||
{ this.canUserAcceptOrDecline(dateInfo, 'accepted') &&
|
||||
<Button id={"decline-date-"+idOrderPackageDatePair} className="installation-button install-btn-decline" onClick={() => {this.handleBtnClick('decline')}} >{orderTexts.buttons.DECLINE}</Button>
|
||||
}
|
||||
{ this.isRemoveBtnVisible(confirmationDate) &&
|
||||
<Button id={"cancel-remove-installation-dates-"+idOrderPackageDatePair} className="installation-button install-btn-remove" onClick={() => {this.handleBtnClick('remove')}} >{orderTexts.buttons.REMOVE}</Button>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
confirmationDates: state.processReducer.confirmationDates
|
||||
});
|
||||
export default connect(mapStateToProps)(InstallationSchedulingDatesPerPackage);
|
||||
@@ -0,0 +1,175 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import moment from 'moment';
|
||||
import {Row, Col, Popover, PopoverBody} from 'reactstrap';
|
||||
import '../../style/InstallationScheduling.css';
|
||||
import InstallationSchedulingPerPackage from './InstallationSchedulingPerPackage.jsx';
|
||||
import {orderTexts} from '../../../../constants/ordersConstants';
|
||||
import {setDialogContent, setDialogOpenFlag} from '../../../../actions/dialog/dialogActions';
|
||||
|
||||
class InstallationSchedulingForPackages extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
popoverOpen: false
|
||||
}
|
||||
|
||||
this.toggle = this.toggle.bind(this);
|
||||
this.setContentDialog = this.setContentDialog.bind(this);
|
||||
this.openDialogInstallContent = this.openDialogInstallContent.bind(this);
|
||||
}
|
||||
|
||||
setContentDialog(installationParams) {
|
||||
return {
|
||||
class: 'installation-scheduling',
|
||||
hasCloseIcon: true,
|
||||
header: orderTexts.labels.INSTALLATION_SCHEDULE_HEADER,
|
||||
TagName: InstallationSchedulingPerPackage,
|
||||
params: {installationParams, openDialogInstallContent: this.openDialogInstallContent}
|
||||
};
|
||||
}
|
||||
|
||||
openDialogInstallContent(installationParams) {
|
||||
const dialogContent = this.setContentDialog(installationParams);
|
||||
|
||||
this.props.dispatch(setDialogOpenFlag(true));
|
||||
this.props.dispatch(setDialogContent(dialogContent));
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setState({
|
||||
popoverOpen: !this.state.popoverOpen
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const {orderPackage, areComponentsDisabled, isInstallationSet, isInstallationInPackage, noOfPackages, installCompanies, isComponentDisabled, earliestInstallDate, confirmationDates, areAllShippingDatesConfirmed} = this.props;
|
||||
const idOrder = orderPackage ? orderPackage.idOrder : 0;
|
||||
const idOrderPackagePair = orderPackage ? idOrder + '-' + orderPackage.idPackage : '';
|
||||
const acceptedDate = {};
|
||||
const proposedDate = {};
|
||||
const installationCompany = {};
|
||||
const availableCompanies = {};
|
||||
const selectedCompanies = {};
|
||||
const isPreliminaryInstallationDate = {};
|
||||
|
||||
if(confirmationDates && confirmationDates[idOrderPackagePair]) {
|
||||
const packageDates = confirmationDates[idOrderPackagePair];
|
||||
const accepted = Object.keys(packageDates).find(installDate => {return packageDates[installDate].lastStatus === 'accepted'});
|
||||
acceptedDate[idOrderPackagePair] = accepted ? moment(accepted).format('Do MMM, YYYY') : '';
|
||||
const proposed = Object.keys(packageDates).find(installDate => {return packageDates[installDate].lastStatus === 'proposed'});
|
||||
proposedDate[idOrderPackagePair] = proposed ? moment(proposed).format('Do MMM, YYYY') : '';
|
||||
}
|
||||
|
||||
if(installCompanies) {
|
||||
availableCompanies[idOrderPackagePair] = idOrderPackagePair in installCompanies.available ? installCompanies.available[idOrderPackagePair] : [];
|
||||
selectedCompanies[idOrderPackagePair] = idOrderPackagePair in installCompanies.selected ? installCompanies.selected[idOrderPackagePair] : {};
|
||||
if (idOrderPackagePair in selectedCompanies && Object.keys(selectedCompanies[idOrderPackagePair]).length > 0) {
|
||||
installationCompany[idOrderPackagePair] = selectedCompanies[idOrderPackagePair];
|
||||
}
|
||||
}
|
||||
|
||||
isPreliminaryInstallationDate[idOrderPackagePair] = areAllShippingDatesConfirmed && orderPackage.idOrder in areAllShippingDatesConfirmed ? !areAllShippingDatesConfirmed[orderPackage.idOrder] : true;
|
||||
const isSchedulingDisabled = (idOrder in areComponentsDisabled && areComponentsDisabled[idOrder]) || (isInstallationSet && !isInstallationSet[idOrderPackagePair]);
|
||||
|
||||
const installationParams = {
|
||||
idOrder,
|
||||
idOrderPackagePair,
|
||||
orderPackage,
|
||||
installCompanies,
|
||||
isComponentDisabled,
|
||||
earliestInstallDate,
|
||||
confirmationDates,
|
||||
isThisComponentDisabled: areComponentsDisabled[idOrder],
|
||||
availableCompanies,
|
||||
selectedCompanies,
|
||||
installationCompany,
|
||||
isSchedulingDisabled,
|
||||
isInstallationSet,
|
||||
isPreliminaryInstallationDate,
|
||||
acceptedDate,
|
||||
proposedDate
|
||||
};
|
||||
|
||||
return (
|
||||
<span id="installation-scheduler-container">
|
||||
{ noOfPackages === 1
|
||||
? this.openDialogInstallContent(installationParams)
|
||||
: <Row className="package-installation-row">
|
||||
<Col xl="7" id={"package-name-" + orderPackage.idOrder + '-' + orderPackage.idPackage}>
|
||||
{orderPackage.packageName}
|
||||
</Col>
|
||||
<Col xl="5">
|
||||
<div className="subtitle">
|
||||
{
|
||||
isInstallationInPackage && isInstallationInPackage[idOrderPackagePair] === false
|
||||
? <span>{orderTexts.labels.INSTALLATION_NOT_REQUIRED}</span>
|
||||
: isPreliminaryInstallationDate[idOrderPackagePair]
|
||||
? <span>{orderTexts.labels.PRELIMINARY_INSTALLATION_DATE_LABEL}: </span>
|
||||
: <span>{orderTexts.labels.INSTALLATION_DATE}: </span>
|
||||
}
|
||||
</div>
|
||||
<div id={"installation-scheduler-container-" + idOrderPackagePair} className="install-date-text">
|
||||
{
|
||||
isSchedulingDisabled
|
||||
? acceptedDate[idOrderPackagePair]
|
||||
? acceptedDate[idOrderPackagePair]
|
||||
: proposedDate[idOrderPackagePair]
|
||||
? proposedDate[idOrderPackagePair]
|
||||
: (isInstallationInPackage[idOrderPackagePair] && !proposedDate[idOrderPackagePair] && !acceptedDate[idOrderPackagePair]) && orderTexts.labels.NOT_SET
|
||||
: <span className="check-installation-dates"
|
||||
onClick={() => this.openDialogInstallContent(installationParams)}>
|
||||
{
|
||||
acceptedDate[idOrderPackagePair]
|
||||
? acceptedDate[idOrderPackagePair]
|
||||
: proposedDate[idOrderPackagePair]
|
||||
? proposedDate[idOrderPackagePair]
|
||||
: (isInstallationInPackage[idOrderPackagePair] && !proposedDate[idOrderPackagePair] && !acceptedDate[idOrderPackagePair]) && orderTexts.labels.NOT_SET
|
||||
}
|
||||
</span>
|
||||
}
|
||||
{
|
||||
isInstallationInPackage[idOrderPackagePair] &&
|
||||
<span>
|
||||
<i className="scheduled-date-btn fa fa-info-circle"
|
||||
id={'scheduled-date-' + idOrderPackagePair}
|
||||
onClick={this.toggle}></i>
|
||||
<Popover placement="bottom"
|
||||
isOpen={this.state.popoverOpen}
|
||||
target={'scheduled-date-' + idOrderPackagePair}
|
||||
container={"installation-scheduler-container-" + idOrderPackagePair}
|
||||
className="scheduled-date-popover"
|
||||
toggle={this.toggle}>
|
||||
<PopoverBody>
|
||||
{
|
||||
isPreliminaryInstallationDate[idOrderPackagePair]
|
||||
? acceptedDate[idOrderPackagePair]
|
||||
? orderTexts.labels.PRELIMINARY_INSTALLATION_DATE
|
||||
: orderTexts.labels.INSTALLATION_DATE_NOT_SET
|
||||
: acceptedDate[idOrderPackagePair]
|
||||
? orderTexts.labels.INSTALLATION_DATE_ACCEPTED
|
||||
: orderTexts.labels.INSTALLATION_DATE_NOT_SET
|
||||
}
|
||||
</PopoverBody>
|
||||
</Popover>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
isNextStepWanted: state.processReducer.isNextStepWanted,
|
||||
isComponentDisabled: state.processReducer.isComponentDisabled,
|
||||
earliestInstallDate: state.processReducer.earliestInstallDate,
|
||||
confirmationDates: state.processReducer.confirmationDates,
|
||||
installCompanies: state.processReducer.installCompanies
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(InstallationSchedulingForPackages);
|
||||
@@ -0,0 +1,161 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import DatePicker from 'react-datepicker';
|
||||
import 'react-datepicker/dist/react-datepicker.css';
|
||||
import moment from 'moment';
|
||||
import {Col, Button, Popover, PopoverBody} from 'reactstrap';
|
||||
import '../../style/InstallationScheduling.css';
|
||||
import {API_SERVER} from '../../../../config';
|
||||
import FileDownloader from '../../../../helpers/FileDownloader';
|
||||
import InstallationSchedulingDatesPerPackage from './InstallationSchedulingDatesPerPackage.jsx';
|
||||
import {updateInstallationDate} from '../../../../actions/orders/processActions';
|
||||
import {orderTexts} from '../../../../constants/ordersConstants';
|
||||
|
||||
const fileHandler = new FileDownloader();
|
||||
const fileType = 'installationProtocol';
|
||||
const status = 'proposed';
|
||||
|
||||
class InstallationSchedulingPerPackage extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
startDate: undefined
|
||||
};
|
||||
this.toggle = this.toggle.bind(this);
|
||||
this.handleDateChange = this.handleDateChange.bind(this);
|
||||
this.handleSelect = this.handleSelect.bind(this);
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setState({
|
||||
popoverOpen: !this.state.popoverOpen
|
||||
});
|
||||
}
|
||||
|
||||
handleDateChange(startDate) {
|
||||
this.setState({startDate});
|
||||
}
|
||||
|
||||
handleSelect(date, idOrder, idPackage) {
|
||||
const newDate = new Date(moment(date).toISOString());
|
||||
this.handleDateChange(date);
|
||||
this.toggle();
|
||||
|
||||
if(Date.parse(newDate)) {
|
||||
const updateDate = moment(date).format('YYYY-MM-DD');
|
||||
this.props.dispatch(updateInstallationDate(idOrder, idPackage, updateDate, status, this.handleDateChange));
|
||||
}
|
||||
}
|
||||
|
||||
downloadDocument(document){
|
||||
const fileUrl = `${API_SERVER}/utils/api/downloadFile?idDocument=${document.idDocument}&fileName=${document.documentName}.${document.extension}&fileType=${fileType}`
|
||||
const fileName = document.documentName + '.' + document.extension;
|
||||
fileHandler.download(fileUrl, fileName);
|
||||
}
|
||||
|
||||
render() {
|
||||
const acceptedDate = {};
|
||||
const proposedDate = {};
|
||||
const {
|
||||
idOrder,
|
||||
idOrderPackagePair,
|
||||
orderPackage,
|
||||
earliestInstallDate,
|
||||
isThisComponentDisabled,
|
||||
isPreliminaryInstallationDate,
|
||||
installationCompany,
|
||||
isInstallationSet
|
||||
} = this.props.params.installationParams;
|
||||
const {confirmationDates} = this.props;
|
||||
const earliestInstallationDate = earliestInstallDate && moment(earliestInstallDate[idOrder]);
|
||||
if(confirmationDates && confirmationDates[idOrderPackagePair]) {
|
||||
const packageDates = confirmationDates[idOrderPackagePair];
|
||||
const accepted = Object.keys(packageDates).find(installDate => {return packageDates[installDate].lastStatus === 'accepted'});
|
||||
acceptedDate[idOrderPackagePair] = accepted ? moment(accepted).format('Do MMM, YYYY') : '';
|
||||
const proposed = Object.keys(packageDates).find(installDate => {return packageDates[installDate].lastStatus === 'proposed'});
|
||||
proposedDate[idOrderPackagePair] = proposed ? moment(proposed).format('Do MMM, YYYY') : '';
|
||||
}
|
||||
|
||||
return (
|
||||
<fieldset disabled={isThisComponentDisabled} className="set-installation-dates">
|
||||
<Col>
|
||||
<div className="subtitle">
|
||||
{
|
||||
isPreliminaryInstallationDate[idOrderPackagePair]
|
||||
? <h6>{orderTexts.labels.PRELIMINARY_INSTALLATION_DATE_LABEL}: </h6>
|
||||
: <h6>{orderTexts.labels.INSTALLATION_DATE}: </h6>
|
||||
}
|
||||
</div>
|
||||
<div id={"installation-scheduler-container-" + idOrderPackagePair} className="install-date-text">
|
||||
{
|
||||
acceptedDate[idOrderPackagePair]
|
||||
? acceptedDate[idOrderPackagePair]
|
||||
: proposedDate[idOrderPackagePair]
|
||||
? proposedDate[idOrderPackagePair]
|
||||
: (!proposedDate[idOrderPackagePair] && !acceptedDate[idOrderPackagePair]) && orderTexts.labels.NOT_SET
|
||||
}
|
||||
</div>
|
||||
</Col>
|
||||
|
||||
|
||||
<Col>
|
||||
<div className="subtitle"><h6>{orderTexts.labels.INSTALL_COMPANY}:</h6></div>
|
||||
<span id={"installation-company-name-" + idOrderPackagePair}>
|
||||
{ isInstallationSet[idOrderPackagePair] ? installationCompany[idOrderPackagePair].name : <span>{orderTexts.labels.INSTALL_COMPANY_NOT_SET}</span>}
|
||||
</span>
|
||||
</Col>
|
||||
<Col>
|
||||
<div className="subtitle"><h6>{orderTexts.labels.EARLIEST_INSTALLATION}:</h6></div>
|
||||
<span id={"earliest-installation-date-" + idOrderPackagePair}>
|
||||
{(earliestInstallDate && earliestInstallDate[idOrder])
|
||||
? moment(earliestInstallDate[idOrder]).format('Do MMM, YYYY')
|
||||
: '-'}
|
||||
</span>
|
||||
</Col>
|
||||
<Col>
|
||||
<div className="subtitle"><h6>{orderTexts.labels.PROPOSED_DATES}</h6></div>
|
||||
{
|
||||
confirmationDates && confirmationDates[idOrderPackagePair]
|
||||
&& Object.keys(confirmationDates[idOrderPackagePair]).map((confirmationDate) =>
|
||||
<InstallationSchedulingDatesPerPackage
|
||||
key={'order-package-installation-dates-' + confirmationDate}
|
||||
minDate={earliestInstallationDate}
|
||||
confirmationDate={confirmationDate}
|
||||
dateInfo={confirmationDates[idOrderPackagePair][confirmationDate]}
|
||||
orderPackage={orderPackage}
|
||||
openDialogInstallContent={this.props.params.openDialogInstallContent}
|
||||
installationParams={this.props.params.installationParams}
|
||||
isComponentDisabled={isThisComponentDisabled}/>)
|
||||
}
|
||||
</Col>
|
||||
<Col id={"installation-scheduling-propose-date-" + idOrderPackagePair}>
|
||||
<Button id={"propose-new-installation-date-" + idOrderPackagePair} disabled={isThisComponentDisabled} className="propose-new-date-btn" onClick={this.toggle}>Add optional date</Button>
|
||||
<Popover placement="bottom"
|
||||
isOpen={this.state.popoverOpen}
|
||||
target={"propose-new-installation-date-" + idOrderPackagePair}
|
||||
container={"installation-scheduling-propose-date-" + idOrderPackagePair}
|
||||
className="dates-info-popover"
|
||||
toggle={this.toggle}>
|
||||
<PopoverBody>
|
||||
<DatePicker
|
||||
inline
|
||||
id={"installation-date-propose-" + idOrderPackagePair}
|
||||
selected={this.state.startDate}
|
||||
onSelect={(date) => this.handleSelect(date, orderPackage.idOrder, orderPackage.idPackage)}
|
||||
minDate={earliestInstallationDate}
|
||||
dateFormat="Do MMM, YYYY"
|
||||
placeholderText="Choose a date" />
|
||||
</PopoverBody>
|
||||
</Popover>
|
||||
</Col>
|
||||
</fieldset>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
confirmationDates: state.processReducer.confirmationDates
|
||||
});
|
||||
export default connect(mapStateToProps)(InstallationSchedulingPerPackage);
|
||||
@@ -0,0 +1,142 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Row, Col, Container, Popover, PopoverBody, PopoverHeader} from 'reactstrap';
|
||||
import {API_SERVER} from '../../../../config';
|
||||
import FileDownloader from '../../../../helpers/FileDownloader';
|
||||
import {orderTexts} from '../../../../constants/ordersConstants';
|
||||
|
||||
const fileHandler = new FileDownloader();
|
||||
|
||||
class PackageInfo extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.toggle = this.toggle.bind(this);
|
||||
this.state = {
|
||||
popoverOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setState({
|
||||
popoverOpen: !this.state.popoverOpen
|
||||
});
|
||||
}
|
||||
|
||||
downloadDocument(document){
|
||||
const fileUrl = `${API_SERVER}/utils/api/downloadFile?idDocument=${document.idDocument}&fileName=${document.documentName}.${document.extension}&fileType=${document.documentTypeName}`
|
||||
const fileName = document.documentName + '.' + document.extension;
|
||||
fileHandler.download(fileUrl, fileName);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {orderPackage, onViewChange} = this.props;
|
||||
const shouldShowPriceInfo = orderPackage.packageRecuringPrice > 0 || orderPackage.packageServicePrice > 0;
|
||||
|
||||
return (
|
||||
<Container fluid={true} id="package-info" className="order-package-info">
|
||||
<Row>
|
||||
<Col xl="3">
|
||||
<div className="subtitle">
|
||||
<h6>
|
||||
{orderTexts.labels.PACKAGE_PRICE}: {' '}
|
||||
{ shouldShowPriceInfo &&
|
||||
<i className="price-info-btn fa fa-info-circle"
|
||||
id={'price-info-' + orderPackage.idPackage}
|
||||
onClick={this.toggle}></i>
|
||||
}
|
||||
</h6>
|
||||
|
||||
</div>
|
||||
<div>
|
||||
{orderTexts.labels.TOTAL_DELVIERY_PRICE}: {' '}
|
||||
{(orderPackage.units * orderPackage.packageFixedPrice).toLocaleString() + ' ' + orderPackage.packageCurrency.currency}
|
||||
</div>
|
||||
{
|
||||
shouldShowPriceInfo &&
|
||||
<div>
|
||||
{orderTexts.labels.TOTAL_RECURRENT_PRICE}:{' '}
|
||||
{(orderPackage.units * (orderPackage.packageRecuringPrice + orderPackage.packageServicePrice)).toLocaleString()} {orderPackage.packageCurrency.currency}
|
||||
</div>
|
||||
}
|
||||
|
||||
{ shouldShowPriceInfo &&
|
||||
<Popover placement="bottom"
|
||||
isOpen={this.state.popoverOpen}
|
||||
target={'price-info-' + orderPackage.idPackage}
|
||||
container={'price-info-' + orderPackage.idPackage}
|
||||
className="price-info-popover"
|
||||
toggle={this.toggle}>
|
||||
<PopoverHeader>{orderPackage.paymentType}</PopoverHeader>
|
||||
<PopoverBody>
|
||||
<div>
|
||||
{ orderPackage.packageRecuringPrice > 0 &&
|
||||
<div className="package-price-recurrent">
|
||||
<span className="price-info-title">{orderTexts.labels.RECURRENT_PRICE}: </span>
|
||||
{(orderPackage.units * orderPackage.packageRecuringPrice).toLocaleString()} {orderPackage.packageCurrency.currency} / {orderPackage.periodUnit}
|
||||
{
|
||||
orderPackage.packagePayPeriod > 0 &&
|
||||
<span>
|
||||
for {orderPackage.packagePayPeriod} {orderPackage.periodUnit}
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
{ orderPackage.packageServicePrice > 0 &&
|
||||
<div className="services-price-recurrent">
|
||||
<span className="price-info-title">{orderTexts.labels.SERVICES_PRICE}: </span>
|
||||
{(orderPackage.units * orderPackage.packageServicePrice).toLocaleString()} {orderPackage.packageCurrency.currency} / {orderPackage.periodUnit}
|
||||
{
|
||||
orderPackage.servicesContractPeriod > 0 &&
|
||||
<span>
|
||||
for {orderPackage.servicesContractPeriod} {orderPackage.periodUnit}
|
||||
</span>
|
||||
}
|
||||
<span> {orderTexts.labels.EXTEND} {orderPackage.periodUnit} (Max {orderPackage.maxContractPeriod} {orderPackage.periodUnit})</span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</PopoverBody>
|
||||
</Popover>
|
||||
}
|
||||
</Col>
|
||||
{
|
||||
orderPackage.options.length > 0 &&
|
||||
<Col xl="3">
|
||||
<div className="subtitle"><h6>{orderTexts.labels.OPTIONS}:</h6></div>
|
||||
{
|
||||
orderPackage.options.map((option, index) => <div key={'option-'+index}>
|
||||
{option.groupName}: {option.packageName}
|
||||
</div>)
|
||||
}
|
||||
</Col>
|
||||
}
|
||||
{
|
||||
orderPackage.additionalPackages.length > 0 &&
|
||||
<Col xl="3">
|
||||
<div className="subtitle"><h6>{orderTexts.labels.ADDITIONAL_PACKAGES}:</h6></div>
|
||||
{
|
||||
orderPackage.additionalPackages.map((additional, index) => <div key={'additional-'+index}>
|
||||
{additional.packageName}
|
||||
</div>)
|
||||
}
|
||||
</Col>
|
||||
}
|
||||
{
|
||||
orderPackage.documents &&
|
||||
<Col xl="2">
|
||||
<div className="subtitle"><h6>{orderTexts.labels.DOCUMENTS}:</h6></div>
|
||||
{
|
||||
orderPackage.documents.length > 0 ?
|
||||
<div className="link-to-docs" onClick={()=>onViewChange('documents')}>{orderTexts.buttons.SEE_DOCUMENTS}</div>:
|
||||
<span>{orderTexts.labels.NO_DOCUMENTS}</span>
|
||||
}
|
||||
</Col>
|
||||
}
|
||||
</Row>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default PackageInfo;
|
||||
@@ -0,0 +1,16 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Link} from 'react-router-dom';
|
||||
|
||||
class PackageName extends Component {
|
||||
render(){
|
||||
const {orderPackage, idCommercialLead} = this.props.params;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Link to={'/co-market/' + idCommercialLead + '/' + orderPackage.idPackage } className="package-name-link">{orderPackage.units + ' x ' + orderPackage.packageName}</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default PackageName;
|
||||
@@ -0,0 +1,23 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Row, Col} from 'reactstrap';
|
||||
import WiaasBox from '../../../../mainComponents/box/WiaasBox.jsx';
|
||||
import PackageInfo from './PackageInfo.jsx';
|
||||
import PackageName from './PackageName.jsx';
|
||||
|
||||
class ProcessPackage extends Component {
|
||||
render() {
|
||||
const {orderPackage, idCommercialLead} = this.props;
|
||||
|
||||
return (
|
||||
<WiaasBox customHeader={PackageName} customHeaderParams={{orderPackage, idCommercialLead}} className="order-package">
|
||||
<Row>
|
||||
<Col xl="12" lg="12" md="12" xs="12">
|
||||
<PackageInfo onViewChange={this.props.onViewChange} orderPackage={orderPackage}/>
|
||||
</Col>
|
||||
</Row>
|
||||
</WiaasBox>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ProcessPackage;
|
||||
@@ -0,0 +1,30 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Input} from 'reactstrap';
|
||||
import {orderTexts} from '../../../../constants/ordersConstants';
|
||||
|
||||
class AcceptanceDeclineReason extends Component {
|
||||
handleEditorChange = (e) => {
|
||||
const reason = e.target.value;
|
||||
this.props.params.onEditorChange(reason);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {actionType} = this.props.params;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
actionType === 'accept'
|
||||
? <div>{orderTexts.labels.ACCEPT_INSTALLATION_TEXT}</div>
|
||||
: <div>
|
||||
<div>{orderTexts.labels.DECLINE_REASON_TEXT}</div>
|
||||
<Input onChange={this.handleEditorChange} type="textarea" name="acceptance-decline-reason" id="installation-declined-reason" />
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default AcceptanceDeclineReason;
|
||||
@@ -0,0 +1,193 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import Dropzone from 'react-dropzone';
|
||||
import {Row, Col, Button} from 'reactstrap';
|
||||
import {fetchCustomerAcceptance, uploadAcceptance, acceptDeclineInstallation, badFile} from '../../../../actions/orders/customerAcceptanceActions';
|
||||
import {setDialogContent, setDialogOpenFlag} from '../../../../actions/dialog/dialogActions';
|
||||
import AcceptanceDeclineReason from './AcceptanceDeclineReason.jsx';
|
||||
import {API_SERVER} from '../../../../config';
|
||||
import FileDownloader from '../../../../helpers/FileDownloader';
|
||||
import {orderTexts} from '../../../../constants/ordersConstants';
|
||||
import '../../style/CustomerAcceptance.css';
|
||||
|
||||
const fileHandler = new FileDownloader();
|
||||
|
||||
class CustomerAcceptance extends Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
reason : '',
|
||||
actionType : ''
|
||||
}
|
||||
|
||||
this.acceptDeclineInstallation = this.acceptDeclineInstallation.bind(this);
|
||||
this.onEditorChange = this.onEditorChange.bind(this);
|
||||
}
|
||||
|
||||
downloadDocument(document){
|
||||
const fileUrl = `${API_SERVER}/utils/api/downloadFile?idDocument=${document.idDocument}&fileName=${document.documentName}.${document.extension}`
|
||||
const fileName = document.documentName + '.' + document.extension;
|
||||
fileHandler.download(fileUrl, fileName);
|
||||
}
|
||||
|
||||
uploadFile(idOrder, acceptedFiles, rejectedFiles) {
|
||||
if(acceptedFiles && acceptedFiles.length){
|
||||
const file = acceptedFiles[0];
|
||||
this.props.dispatch(uploadAcceptance(idOrder, file));
|
||||
}
|
||||
|
||||
if(rejectedFiles && rejectedFiles.length) {
|
||||
this.props.dispatch(badFile());
|
||||
}
|
||||
}
|
||||
|
||||
getAcceptanceStatusClass(acceptance, daysDiff) {
|
||||
const statuses = {
|
||||
0 : 'waiting',
|
||||
1 : 'accepted',
|
||||
'-1' : 'declined'
|
||||
};
|
||||
|
||||
if(acceptance === 0 && daysDiff <= 0){
|
||||
return 'danger';
|
||||
} else if(acceptance === 0 && daysDiff <= 3) {
|
||||
return 'warning';
|
||||
}else{
|
||||
return statuses[acceptance];
|
||||
}
|
||||
}
|
||||
|
||||
acceptDeclineInstallation() {
|
||||
const {idOrder} = this.props.step;
|
||||
const {actionType, reason} = this.state;
|
||||
this.props.dispatch(acceptDeclineInstallation(idOrder, actionType, reason));
|
||||
this.setState({reason: ''});
|
||||
}
|
||||
|
||||
getAcceptanceMessage(customerAcceptance){
|
||||
const messages = {
|
||||
0 : orderTexts.labels.NOT_ACCEPTED + (customerAcceptance.acceptanceDueDate || orderTexts.labels.NOT_SET),
|
||||
1 : orderTexts.labels.ACCEPTED,
|
||||
'-1' : orderTexts.labels.DECLINED
|
||||
}
|
||||
|
||||
return messages[customerAcceptance.customerAccepted];
|
||||
}
|
||||
|
||||
onEditorChange(reason) {
|
||||
this.setState({reason});
|
||||
}
|
||||
|
||||
openDialog(actionType) {
|
||||
const dialogContent = this.getAcceptanceDialog(actionType);
|
||||
this.setState({actionType});
|
||||
this.props.dispatch(setDialogOpenFlag(true));
|
||||
this.props.dispatch(setDialogContent(dialogContent));
|
||||
}
|
||||
|
||||
getAcceptanceDialog(actionType) {
|
||||
return {
|
||||
buttons: [
|
||||
{
|
||||
color: 'success',
|
||||
action: this.acceptDeclineInstallation,
|
||||
name: orderTexts.buttons.SEND,
|
||||
id: 'confirm-acceptance'
|
||||
}, {
|
||||
color: 'secondary',
|
||||
name: orderTexts.buttons.CANCEL,
|
||||
id: 'cancel-acceptance'
|
||||
}
|
||||
],
|
||||
header: orderTexts.labels.ACCEPTANCE_HEADER,
|
||||
TagName: AcceptanceDeclineReason,
|
||||
params: {onEditorChange: this.onEditorChange, actionType}
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
const {idOrder} = this.props.step;
|
||||
this.props.dispatch(fetchCustomerAcceptance(idOrder));
|
||||
}
|
||||
|
||||
render() {
|
||||
const {step} = this.props;
|
||||
const customerAcceptance = this.props.customerAcceptance || null;
|
||||
|
||||
return (
|
||||
<div id="customer-acceptance" className="validate-questionnaire">
|
||||
{
|
||||
customerAcceptance &&
|
||||
<Row>
|
||||
<Col className="aceeptance-message">
|
||||
{this.getAcceptanceMessage(customerAcceptance)} <div className={'status-icon ' + this.getAcceptanceStatusClass(customerAcceptance.customerAccepted, customerAcceptance.daysDiff)}></div>
|
||||
</Col>
|
||||
</Row>
|
||||
}
|
||||
{
|
||||
(customerAcceptance && customerAcceptance.customerAccepted === -1) &&
|
||||
<Row>
|
||||
<Col>{orderTexts.labels.REASON}: {customerAcceptance.customerDeclineReason}</Col>
|
||||
</Row>
|
||||
}
|
||||
<Row className="acceptance-docs">
|
||||
<Col xl="4" lg="5" md="4">
|
||||
<Dropzone className="upload-file-drop-zone"
|
||||
multiple={false}
|
||||
accept=".pdf,.docx,.doc,.xlsx,.xls,.odt,.ods,.jpg,.png,.jpeg"
|
||||
activeClassName="upload-file-accept"
|
||||
onDrop={(acceptedFiles, rejectedFiles)=>{this.uploadFile(step.idOrder, acceptedFiles, rejectedFiles)}}>
|
||||
<h5 className="drop-zone-text">{orderTexts.labels.UPLOAD_ACCEPTANCE_LABEL}</h5>
|
||||
</Dropzone>
|
||||
</Col>
|
||||
<Col xl="4" lg="7" md="8">
|
||||
{
|
||||
(customerAcceptance && customerAcceptance.acceptanceDocuments && customerAcceptance.acceptanceDocuments.length > 0) &&
|
||||
<div>
|
||||
{
|
||||
customerAcceptance.acceptanceDocuments.map(document => <div key={'acceptance-documnet-' + document.idDocument}>
|
||||
<span className="document-link"
|
||||
onClick={() => {this.downloadDocument(document)}}>
|
||||
<i className={'fa fa-file'}></i> {document.documentName} ({document.extension})
|
||||
</span>
|
||||
<span className="document-status">
|
||||
{document.validation} <div className={'status-icon ' + document.validation}></div>
|
||||
</span>
|
||||
</div>)
|
||||
}
|
||||
</div>
|
||||
}
|
||||
{
|
||||
(customerAcceptance && !customerAcceptance.acceptanceDocuments) &&
|
||||
<div>
|
||||
{orderTexts.labels.NO_DOCUMENTS_UPLOADED}
|
||||
</div>
|
||||
}
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col className="acceptance-label" xl="12" lg="12" md="12" xs="12">
|
||||
{orderTexts.labels.ACCEPTANCE_LABEL}
|
||||
</Col>
|
||||
<Col lg="7">
|
||||
<Button onClick={()=>{this.openDialog('accept')}}
|
||||
id="acceptance-accept"
|
||||
color="secondary"
|
||||
className="acceptance-button acceptance-accept">{orderTexts.buttons.ACCEPT_INSTALLATION}</Button>
|
||||
<Button onClick={()=>{this.openDialog('decline')}}
|
||||
id="acceptance-decline"
|
||||
color="secondary"
|
||||
className="acceptance-button acceptance-decline">{orderTexts.buttons.DECLINE_INSTALLATION}</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
customerAcceptance: state.processReducer.customerAcceptance
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(CustomerAcceptance);
|
||||
@@ -0,0 +1,54 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Row, Col} from 'reactstrap';
|
||||
import ProcessStep from './ProcessStep.jsx';
|
||||
import {orderTexts} from '../../../../constants/ordersConstants';
|
||||
|
||||
const completedOrdersStatuses = ['production', 'end-of-life'];
|
||||
|
||||
class OrderProcess extends Component {
|
||||
isStepVisible(step) {
|
||||
return (step.status === 'in-progress' || step.status === 'done') && step.isVisibleForCustomer === 1;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {orderProcess, orderStatus} = this.props;
|
||||
const visibleSteps = (orderProcess && orderProcess.steps) ? orderProcess.steps.filter(this.isStepVisible) : [];
|
||||
|
||||
if(orderProcess && completedOrdersStatuses.find((status) => {return status === orderStatus;})) {
|
||||
const processCompleted = {
|
||||
shortDesc: orderTexts.labels.COMPLETED,
|
||||
status: 'done',
|
||||
isVisibleForCustomer: 1,
|
||||
actualDate: visibleSteps[0].actualDate
|
||||
};
|
||||
if(visibleSteps) {
|
||||
visibleSteps.unshift(processCompleted);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="order-process">
|
||||
{
|
||||
(!orderProcess || !orderProcess.steps) &&
|
||||
<Row>
|
||||
<Col xl="12" lg="12" md="12" xs="12">
|
||||
<div className="no-process-info">{orderTexts.labels.WILL_BE_PROCESS}</div>
|
||||
</Col>
|
||||
</Row>
|
||||
}
|
||||
{
|
||||
(orderProcess && orderProcess.steps) &&
|
||||
<Row>
|
||||
<Col xl="12" lg="12" md="12" xs="12" className="order-package-process">
|
||||
{
|
||||
visibleSteps.map((step, index) => <ProcessStep isStepVisible={this.isStepVisible} stepNumber={visibleSteps.length - index} step={step} key={'step-' + step.idProcess + '-' + step.idProcessStep}/>)
|
||||
}
|
||||
</Col>
|
||||
</Row>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default OrderProcess;
|
||||
@@ -0,0 +1,76 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Row, Col, Container} from 'reactstrap';
|
||||
import WiaasBox from '../../../../mainComponents/box/WiaasBox.jsx';
|
||||
import ValidateQuestionnaire from './ValidateQuestionnaire.jsx';
|
||||
import CustomerAcceptance from './CustomerAcceptance.jsx';
|
||||
|
||||
const stepActions = {
|
||||
'validate-questionnaire' : ValidateQuestionnaire,
|
||||
'customer-acceptance' : CustomerAcceptance
|
||||
}
|
||||
|
||||
class OrderStep extends Component {
|
||||
isActiveStep(status) {
|
||||
return status === 'in-progress' ;
|
||||
}
|
||||
|
||||
getStepTitle(step, stepNumber) {
|
||||
return stepNumber + '. ' + step.shortDesc;
|
||||
}
|
||||
|
||||
getDayFromActual(step) {
|
||||
const date = step.actualDate || step.now;
|
||||
const dateParts = date.split(' ');
|
||||
|
||||
return dateParts[0];
|
||||
}
|
||||
|
||||
getMonthFromActual(step) {
|
||||
const date = step.actualDate || step.now;
|
||||
const dateParts = date.split(' ');
|
||||
const dateParts2 = dateParts[1].split(',');
|
||||
|
||||
return dateParts2[0];
|
||||
}
|
||||
|
||||
render() {
|
||||
const {step, stepNumber, isStepVisible} = this.props;
|
||||
const TagName = step.actionCode !== 'manual' && stepActions[step.actionCode] ? stepActions[step.actionCode] : null;
|
||||
|
||||
return (
|
||||
<Container fluid={true} className="order-step">
|
||||
{
|
||||
isStepVisible(step) &&
|
||||
<Row className="step-layer">
|
||||
<Col xl="1" lg="1" md="2" xs="2" className="step-circle-layer">
|
||||
<div className="step-line"></div>
|
||||
<div className={'step-circle ' + step.status}>
|
||||
{!this.isActiveStep(step.status) &&
|
||||
<span>
|
||||
<div>{this.getDayFromActual(step)}</div>
|
||||
<div>{this.getMonthFromActual(step)}</div>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
</Col>
|
||||
<Col xl="11" lg="11" md="10" xs="10" className="step-box-layer">
|
||||
<WiaasBox isContentVisible={this.isActiveStep(step.status)} className={'step-box'} mainTitle={this.getStepTitle(step, stepNumber)}>
|
||||
{
|
||||
(this.isActiveStep(step.status) && TagName) &&
|
||||
<Col>
|
||||
{
|
||||
(TagName && this.isActiveStep(step.status)) && <TagName step={step}/>
|
||||
}
|
||||
</Col>
|
||||
}
|
||||
</WiaasBox>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default OrderStep;
|
||||
@@ -0,0 +1,46 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {fetchCustomerDocuments, fetchValidationComments} from '../../../../actions/orders/processActions';
|
||||
import ValidateQuestionnaireItem from './ValidateQuestionnaireItem.jsx';
|
||||
import '../../style/ValidateQuestionnaire.css';
|
||||
|
||||
class ValidateQuestionnaire extends Component {
|
||||
|
||||
componentDidMount(){
|
||||
const {idOrder, idProcessStep} = this.props.step;
|
||||
this.props.dispatch(fetchCustomerDocuments(idOrder, 'orderQuestionaire'));
|
||||
this.props.dispatch(fetchValidationComments(idOrder, idProcessStep, 'invalidQuestionnaireComment'));
|
||||
}
|
||||
|
||||
findById(orderPackage, idOrderPackagePair){
|
||||
const idPackage = idOrderPackagePair.split('-')[1];
|
||||
return orderPackage.idPackage === parseInt(idPackage, 10);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {customerDocuments, validationComments, orderPackages} = this.props;
|
||||
|
||||
return (
|
||||
<div id="validate-questionnaire" className="validate-questionnaire">
|
||||
{
|
||||
customerDocuments &&
|
||||
Object.keys(customerDocuments).map((idOrderPackagePair) =>
|
||||
<ValidateQuestionnaireItem
|
||||
customerDocuments={customerDocuments[idOrderPackagePair]}
|
||||
validationComments={validationComments && validationComments[idOrderPackagePair] ? validationComments[idOrderPackagePair] : []}
|
||||
orderPackage={orderPackages.find((orderPackage)=>{ return this.findById(orderPackage, idOrderPackagePair)})}
|
||||
key={'validate-questionnaire-' + idOrderPackagePair}/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
customerDocuments: state.processReducer.customerDocuments,
|
||||
validationComments: state.processReducer.validationComments,
|
||||
orderPackages: state.processReducer.orderInfo.packages
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(ValidateQuestionnaire);
|
||||
@@ -0,0 +1,99 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import Dropzone from 'react-dropzone';
|
||||
import {Row, Col} from 'reactstrap';
|
||||
import {reUploadOrderDocument, badFile} from '../../../../actions/orders/processActions';
|
||||
import {API_SERVER} from '../../../../config';
|
||||
import FileDownloader from '../../../../helpers/FileDownloader';
|
||||
import {orderTexts} from '../../../../constants/ordersConstants';
|
||||
|
||||
const fileHandler = new FileDownloader();
|
||||
|
||||
class ValidateQuestionnaireItem extends Component {
|
||||
downloadDocument(document){
|
||||
const fileUrl = `${API_SERVER}/utils/api/downloadFile?idDocument=${document.idDocument}&fileName=${document.documentName}.${document.extension}`
|
||||
const fileName = document.documentName + '.' + document.extension;
|
||||
fileHandler.download(fileUrl, fileName);
|
||||
}
|
||||
|
||||
uploadFile(idPackage, idOrder, idDocument,acceptedFiles, rejectedFiles) {
|
||||
if(acceptedFiles && acceptedFiles.length){
|
||||
const file = acceptedFiles[0];
|
||||
this.props.dispatch(reUploadOrderDocument(idPackage, idOrder, idDocument, file));
|
||||
}
|
||||
|
||||
if(rejectedFiles && rejectedFiles.length) {
|
||||
this.props.dispatch(badFile());
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {customerDocuments, validationComments, orderPackage} = this.props;
|
||||
|
||||
return (
|
||||
<div id="validate-questionnaire" className="validate-questionnaire">
|
||||
{
|
||||
customerDocuments &&
|
||||
<div>
|
||||
{orderPackage.packageName}
|
||||
{
|
||||
customerDocuments.map(document => <div key={'package-document-' + document.idDocument}>
|
||||
{
|
||||
document.validation === 'invalid'
|
||||
? <div className="package-document">
|
||||
<Row>
|
||||
<Col xl="7" lg="8">
|
||||
<div>
|
||||
<span className="document-link"
|
||||
onClick={() => {this.downloadDocument(document)}}>
|
||||
<i className={'fa fa-file'}></i> {document.documentName} ({document.extension}) {' '}
|
||||
</span>
|
||||
<span className="document-status">
|
||||
{document.validation.replace(/-/g,' ')} <div className={'status-icon ' + document.validation}></div>
|
||||
</span>
|
||||
</div>
|
||||
{
|
||||
(validationComments && validationComments.length > 0) &&
|
||||
<div>
|
||||
{validationComments.map((comment, key) => <div key={'step-comment-' + document.idDocument + '-' + key} className="step-comment">
|
||||
<div>{comment.user} - {comment.addDate}</div>
|
||||
<div>{comment.comment}</div>
|
||||
</div>)}
|
||||
</div>
|
||||
}
|
||||
</Col>
|
||||
<Col xl="5">
|
||||
<Dropzone className="upload-file-drop-zone"
|
||||
multiple={false}
|
||||
accept=".pdf,.docx,.doc,.xlsx,.xls,.odt,.ods"
|
||||
activeClassName="upload-file-accept"
|
||||
onDrop={(acceptedFiles, rejectedFiles)=>{this.uploadFile(document.idPackage, document.idOrder, document.idDocument, acceptedFiles, rejectedFiles)}}>
|
||||
<h5 className="drop-zone-text">{orderTexts.labels.SELECT_OR_DROP}</h5>
|
||||
</Dropzone>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
: <div className="package-document">
|
||||
<Row>
|
||||
<Col>
|
||||
<span className="document-link"
|
||||
onClick={() => {this.downloadDocument(document)}}>
|
||||
<i className={'fa fa-file'}></i> {document.documentName} ({document.extension}) {' '}
|
||||
</span>
|
||||
<span className="document-status">
|
||||
{document.validation.replace(/-/g,' ')} <div className={'status-icon ' + document.validation}></div>
|
||||
</span>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
}
|
||||
</div>)
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default connect()(ValidateQuestionnaireItem);
|
||||
Reference in New Issue
Block a user