Merge branch 'master' into package-details
This commit is contained in:
2
frontend/src/.gitignore
vendored
Normal file
2
frontend/src/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# devBuild
|
||||
*.css
|
||||
@@ -118,6 +118,7 @@ export const validateCredentials = (username, password) => {
|
||||
|
||||
// if(decodedAceessToken.data.wiaas_user_type === 'customer'){
|
||||
localStorage.setItem('accessToken', response.data.token);
|
||||
localStorage.setItem('username', username);
|
||||
const serverTime = decodedAceessToken.nbf || 1;
|
||||
// refreshToken = response.data.refreshToken;
|
||||
startRefreshTimer(dispatch, serverTime);
|
||||
|
||||
@@ -23,15 +23,12 @@ const recieveCustomerAcceptance = (json) => ({
|
||||
customerAcceptance: json
|
||||
});
|
||||
|
||||
export const fetchCustomerAcceptance = (idOrder) => {
|
||||
export const fetchCustomerAcceptance = (idEntry) => {
|
||||
return dispatch => {
|
||||
dispatch(requestCustomerAcceptance());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orders/api/getCustomerAcceptance`,
|
||||
method: 'post',
|
||||
data: {
|
||||
idOrder
|
||||
}
|
||||
url: `${API_SERVER}/wp-json/wiaas/customer-acceptance/${idEntry}`,
|
||||
method: 'get'
|
||||
})
|
||||
.then(response => {
|
||||
if (response.data) {
|
||||
@@ -48,18 +45,15 @@ const uploadAcceptanceAction = () => ({
|
||||
type: UPLOAD_CUSTOMER_ACCEPTANCE
|
||||
});
|
||||
|
||||
export const uploadAcceptance = (idOrder, file) => {
|
||||
export const uploadAcceptance = (idEntry, file) => {
|
||||
return dispatch => {
|
||||
dispatch(uploadAcceptanceAction());
|
||||
return htmlClient.uploadFile(file, {
|
||||
url: `${API_SERVER}/orders/api/uploadAcceptanceDocument`,
|
||||
data: {
|
||||
idOrder
|
||||
}
|
||||
url: `${API_SERVER}/wp-json/wiaas/customer-acceptance/${idEntry}/upload-file`
|
||||
}).then(response => {
|
||||
if (typeof response.data !== 'undefined' && 'messages' in response.data) {
|
||||
if (typeof response.data !== 'undefined') {
|
||||
dispatch(updateMessages(response.data.messages, orderMessages));
|
||||
dispatch(fetchCustomerAcceptance(idOrder));
|
||||
dispatch(fetchCustomerAcceptance(idEntry));
|
||||
}
|
||||
}).catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
@@ -77,14 +71,13 @@ const sendCustomerAcceptance = () => ({
|
||||
type: SEND_CUSTOMER_ACCEPTANCE
|
||||
});
|
||||
|
||||
export const acceptDeclineInstallation = (idOrder, actionType, declineReason) => {
|
||||
export const acceptDeclineInstallation = (idEntry, actionType, declineReason) => {
|
||||
return dispatch => {
|
||||
dispatch(sendCustomerAcceptance());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orders/api/acceptDeclineInstallation`,
|
||||
url: `${API_SERVER}/wp-json/wiaas/customer-acceptance/${idEntry}`,
|
||||
method: 'post',
|
||||
data: {
|
||||
idOrder,
|
||||
actionType,
|
||||
declineReason
|
||||
}
|
||||
@@ -92,7 +85,7 @@ export const acceptDeclineInstallation = (idOrder, actionType, declineReason) =>
|
||||
.then(response => {
|
||||
if (response.data) {
|
||||
dispatch(updateMessages(response.data.messages, orderMessages));
|
||||
dispatch(fetchCustomerAcceptance(idOrder));
|
||||
dispatch(fetchCustomerAcceptance(idEntry));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
|
||||
@@ -24,7 +24,9 @@ import {
|
||||
SET_SCHEDULING_DISABLED_FLAG
|
||||
} from '../../constants/ordersConstants';
|
||||
import HtmlClient from '../../helpers/HtmlClient';
|
||||
import {updateMessages} from '../notification/notificationActions';
|
||||
import { updateMessages } from '../notification/notificationActions';
|
||||
import { fromWCOrder } from '../../helpers/OrderHelper';
|
||||
import moment from 'moment';
|
||||
|
||||
const htmlClient = new HtmlClient();
|
||||
|
||||
@@ -42,15 +44,12 @@ export const fetchOrderInfo = (idOrder) => {
|
||||
return dispatch => {
|
||||
dispatch(requestOrderInfo());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orders/api/getOrderInfo`,
|
||||
method: 'post',
|
||||
data: {
|
||||
idOrder
|
||||
}
|
||||
})
|
||||
url: `${API_SERVER}/wp-json/wc/v2/orders/${idOrder}`,
|
||||
method: 'get'
|
||||
})
|
||||
.then(response => {
|
||||
if (response.data) {
|
||||
dispatch(recieveOrderInfo(response.data));
|
||||
dispatch(recieveOrderInfo(fromWCOrder(response.data)));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
@@ -63,22 +62,28 @@ const sendComment = () => ({
|
||||
type: SEND_ORDER_COMMENT
|
||||
})
|
||||
|
||||
export const addComment = (idOrder, comment) => {
|
||||
export const addComment = (idOrder, newComment) => {
|
||||
return dispatch => {
|
||||
dispatch(sendComment());
|
||||
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orders/api/addOrderComment`,
|
||||
method: 'post',
|
||||
data: {
|
||||
idOrder,
|
||||
comment
|
||||
}
|
||||
})
|
||||
url: `${API_SERVER}/wp-json/wc/v2/orders/${idOrder}/notes`,
|
||||
method: 'post',
|
||||
data: {
|
||||
note : newComment || 'Test comment',
|
||||
customer_note: true,
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
if (response.data) {
|
||||
dispatch(fetchOrderInfo(idOrder));
|
||||
}
|
||||
/*
|
||||
if (response.data && response.data.messages) {
|
||||
dispatch(updateMessages(response.data.messages, orderMessages));
|
||||
dispatch(fetchOrderInfo(idOrder));
|
||||
}
|
||||
*/
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
|
||||
@@ -50,13 +50,13 @@ export const orderMessages = {
|
||||
SYSTEM_ALLOWED_LANGUAGES_EMPTY: 'There are no languages added in the system.',
|
||||
ALLOWED_LANGUAGE: 'Allowed languages are:',
|
||||
ALLOWED_LANGUAGE_ERROR: 'There was an error while trying to detect the language:',
|
||||
SERVER_ERROR: 'There seems to be a problem and the comment was not added!',
|
||||
ERROR_ADDING_COMMENT: 'There seems to be a problem and the comment was not added!',
|
||||
ORDER_COMMENT_ADDED: 'Order comment updated!',
|
||||
FILE_UPLOADED : 'File has been uploaded and needs to be validated!',
|
||||
NOT_UPLOADED : 'There seems to be a problem and the file was not uploaded!',
|
||||
RE_UPLOAD_MAIL : 'Notify mail has been sent!',
|
||||
ACCEPTANCE_NOT_UPDATED : 'Acceptance status not updated!',
|
||||
ACCEPTANCE_NOT_UPLOADED: 'You need to uploade the acceptance document before you can agree with the installation!',
|
||||
ACCEPTANCE_NOT_UPLOADED: 'You need to upload the acceptance document before you can agree with the installation!',
|
||||
DECLINE_REASON_EMPTY : 'Please describe what is not to your satisfaction.',
|
||||
INSTALLATION_DECLINED : 'The implementation is not satisfactory.',
|
||||
ERROR_MAIL_SENT : 'Notify mail was not sent!',
|
||||
@@ -81,7 +81,13 @@ export const orderMessages = {
|
||||
EMPTY_VALUE: 'Field required: ',
|
||||
INSTALLATION_ACCEPTED: 'The implementation has been accepted!',
|
||||
ID_ORDER_NOT_SET: 'The id of the order is not set',
|
||||
SUPPORT_MAIL_SENT: 'Support mail sent!'
|
||||
SUPPORT_MAIL_SENT: 'Support mail sent!',
|
||||
|
||||
NO_FILES_UPLOADED: 'You need to upload the acceptance document',
|
||||
INTERNAL_SERVER_ERROR: 'Error occured. Please try again',
|
||||
ACCEPTANCE_STATUS_MISSING: 'Acceptance action not selected',
|
||||
ACCEPTANCE_STATUS_UPDATED: 'Acceptance status updated'
|
||||
|
||||
};
|
||||
|
||||
export const orderTexts = {
|
||||
@@ -161,7 +167,11 @@ export const orderTexts = {
|
||||
INSTALLATION_DATE: 'Installation date',
|
||||
INSTALLATION_NOT_REQUIRED:'Installation is not required for this package',
|
||||
PRELIMINARY_INSTALLATION_DATE_LABEL: 'Preliminary installation date',
|
||||
PROJECT: 'Project'
|
||||
PROJECT: 'Project',
|
||||
BILLING_FIRST_NAME: 'Billing first name',
|
||||
BILLING_LAST_NAME: 'Billing last name',
|
||||
BILLING_MAIL: 'Invoice mail',
|
||||
BILLING_ADDRESS: 'Billing address'
|
||||
},
|
||||
buttons: {
|
||||
ACCEPT_INSTALLATION: 'I agree',
|
||||
|
||||
@@ -44,7 +44,7 @@ class ProcessContainer extends Component {
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dispatch(fetchOrderInfo(this.props.idOrder));
|
||||
this.props.dispatch(getAllDataForInstallation(this.props.idOrder, usedForDirective, stepsNameForInstallation, fileType));
|
||||
//this.props.dispatch(getAllDataForInstallation(this.props.idOrder, usedForDirective, stepsNameForInstallation, fileType));
|
||||
const orderPackagePairs = [];
|
||||
const isSchedulingDisabled = {};
|
||||
isSchedulingDisabled[this.props.idOrder] = true;
|
||||
@@ -52,7 +52,7 @@ class ProcessContainer extends Component {
|
||||
|
||||
if(this.props.orderInfo) {
|
||||
this.props.orderInfo.packages.forEach(orderPackage => {
|
||||
orderPackagePairs.push(orderPackage.idOrder + '-' + orderPackage.idPackage);
|
||||
orderPackagePairs.push(this.props.orderInfo.id + '-' + orderPackage.id);
|
||||
});
|
||||
}
|
||||
this.setState({
|
||||
@@ -71,11 +71,11 @@ class ProcessContainer extends Component {
|
||||
|
||||
if(installCompanies && isComponentDisabled && earliestInstallDate) {
|
||||
if(nextProps.orderInfo) {
|
||||
const idOrder = nextProps.orderInfo.id;
|
||||
nextProps.orderInfo.packages.forEach(orderPackage => {
|
||||
const idOrder = orderPackage && orderPackage.idOrder;
|
||||
const idOrderPackagePair = orderPackage ? idOrder + '-' + orderPackage.idPackage : '';
|
||||
const idOrderPackagePair = orderPackage ? idOrder + '-' + orderPackage.id : '';
|
||||
orderPackage.idOrderPackagePair = idOrderPackagePair;
|
||||
areComponentsDisabled[idOrder] = this.checkIfComponentIsDisabled(orderPackage.idOrder, isComponentDisabled, earliestInstallDate);
|
||||
areComponentsDisabled[idOrder] = this.checkIfComponentIsDisabled(idOrder, isComponentDisabled, earliestInstallDate);
|
||||
|
||||
const availableCompanies = {};
|
||||
const selectedCompanies = {};
|
||||
@@ -101,7 +101,7 @@ class ProcessContainer extends Component {
|
||||
});
|
||||
|
||||
const isSchedulingDisabled = Object.assign({}, this.state.isSchedulingDisabled);
|
||||
isSchedulingDisabled[nextProps.orderInfo.info.id] = allPackagesScheduleInstallDisabled.every(isDisabled => {return isDisabled === true;});
|
||||
isSchedulingDisabled[nextProps.orderInfo.id] = allPackagesScheduleInstallDisabled.every(isDisabled => {return isDisabled === true;});
|
||||
this.setState({
|
||||
isSchedulingDisabled,
|
||||
areComponentsDisabled,
|
||||
@@ -126,16 +126,16 @@ class ProcessContainer extends Component {
|
||||
return true;
|
||||
}
|
||||
|
||||
calculatetTotalPrice(packages) {
|
||||
let fixedPrice = priceHelper.sumPrices(packages.map(pkg => { return pkg.units * pkg.packageFixedPrice}));
|
||||
let recurrentPrice = priceHelper.sumPrices(packages.map(pkg => { return pkg.units * pkg.packageRecuringPrice}));
|
||||
let servicesPrice = priceHelper.sumPrices(packages.map(pkg => { return pkg.units * pkg.packageServicePrice}));
|
||||
calculatetTotalPrice(packages, currency) {
|
||||
let fixedPrice = priceHelper.sumPrices(packages.map(pkg => { return pkg.quantity * pkg.price}));
|
||||
let recurrentPrice = priceHelper.sumPrices(packages.map(pkg => { return pkg.quantity * pkg.recurringPrice}));
|
||||
let servicesPrice = priceHelper.sumPrices(packages.map(pkg => { return pkg.quantity * pkg.servicePrice}));
|
||||
|
||||
return {
|
||||
fixedPrice,
|
||||
recurrentPrice: priceHelper.sumPrices([recurrentPrice, servicesPrice]),
|
||||
periodUnit: packages[0].periodUnit,
|
||||
currency: packages[0].packageCurrency.currency
|
||||
currency: currency
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,15 +158,10 @@ class ProcessContainer extends Component {
|
||||
if(this.state.packageNameFilter === 'all') {
|
||||
return true;
|
||||
}else{
|
||||
return orderPackage.packageName === this.state.packageNameFilter;
|
||||
return orderPackage.name === this.state.packageNameFilter;
|
||||
}
|
||||
}
|
||||
|
||||
getProcess(process){
|
||||
const processKeys = Object.keys(process) || [];
|
||||
return processKeys.length > 0 ? process[processKeys[0]] : {};
|
||||
}
|
||||
|
||||
getButtonClass() {
|
||||
if(this.props.orderInfo) {
|
||||
return this.state.isSchedulingDisabled[this.props.orderInfo.id] ? 'schedule-inactive' : 'schedule-active';
|
||||
@@ -187,18 +182,18 @@ class ProcessContainer extends Component {
|
||||
</div>
|
||||
}
|
||||
{
|
||||
(orderInfo && orderInfo.info && !isLoading) &&
|
||||
(orderInfo && !isLoading) &&
|
||||
<div>
|
||||
<WiaasBox
|
||||
customHeader={ProcessNavContainer}
|
||||
customHeaderParams={{
|
||||
orderInfo: orderInfo.info,
|
||||
orderInfo: orderInfo,
|
||||
packages: orderInfo.packages,
|
||||
onViewChange: this.onViewChange,
|
||||
getActiveView: this.getActiveView,
|
||||
installationData: this.state
|
||||
}}>
|
||||
<OrderInfo totalPrice={this.calculatetTotalPrice(orderInfo.packages)} orderDetails={orderInfo} installationData={this.state}/>
|
||||
<OrderInfo totalPrice={this.calculatetTotalPrice(orderInfo.packages, orderInfo.currency)} orderDetails={orderInfo} installationData={this.state}/>
|
||||
</WiaasBox>
|
||||
{
|
||||
this.state.activeView !== 'info' &&
|
||||
@@ -211,7 +206,7 @@ class ProcessContainer extends Component {
|
||||
<OrderProcess
|
||||
onViewChange={this.onViewChange}
|
||||
orderStatus={orderInfo.status}
|
||||
orderProcess={this.getProcess(orderInfo.process)}/>
|
||||
orderProcess={orderInfo.process}/>
|
||||
}
|
||||
{
|
||||
this.state.activeView === 'packages' &&
|
||||
@@ -221,9 +216,10 @@ class ProcessContainer extends Component {
|
||||
>
|
||||
{
|
||||
orderInfo.packages.filter(this.filterPackages).map(orderPackage =>
|
||||
<ProcessPackage key={orderPackage.idPackage}
|
||||
<ProcessPackage key={orderPackage.id}
|
||||
onViewChange={this.onViewChange}
|
||||
idCommercialLead={orderInfo.info.idCommercialLead}
|
||||
idCommercialLead={orderInfo.commercialLead.id}
|
||||
currency={orderInfo.currency}
|
||||
orderPackage={orderPackage}/>
|
||||
)
|
||||
}
|
||||
@@ -231,18 +227,18 @@ class ProcessContainer extends Component {
|
||||
}
|
||||
{
|
||||
this.state.activeView === 'comments' &&
|
||||
<OrderComments orderInfo={orderInfo.info} orderComments={orderInfo.orderComments} orderPackages={orderInfo.packages}/>
|
||||
<OrderComments orderInfo={orderInfo} orderComments={orderInfo.comments} orderPackages={orderInfo.packages}/>
|
||||
}
|
||||
|
||||
{
|
||||
this.state.activeView === 'documents' &&
|
||||
<OrderDocuments idOrder={orderInfo.info.id} />
|
||||
<OrderDocuments idOrder={orderInfo.id} />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
(orderInfo && !orderInfo.info && !isLoading) &&
|
||||
(!orderInfo && !isLoading) &&
|
||||
<div className="no-rigths">
|
||||
{orderTexts.labels.NOT_AVAILABLE}!
|
||||
</div>
|
||||
|
||||
@@ -18,7 +18,7 @@ class OrderComments extends Component {
|
||||
}
|
||||
|
||||
addNewComment(){
|
||||
this.props.dispatch(addComment(this.props.orderInfo.id, this.state.newComment));
|
||||
this.props.dispatch(addComment(this.props.orderInfo.id, this.state.newComment, this.props.orderComments));
|
||||
}
|
||||
|
||||
onEditorChange(newComment){
|
||||
@@ -26,11 +26,11 @@ class OrderComments extends Component {
|
||||
}
|
||||
|
||||
getOffset(isOwner){
|
||||
return isOwner ? 6 : 0;
|
||||
return (isOwner) ? 6 : 0;
|
||||
}
|
||||
|
||||
getClassByOwner(isOwner){
|
||||
return isOwner ? 'mine' : '';
|
||||
return (isOwner) ? 'mine' : '';
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -48,7 +48,7 @@ class OrderComments extends Component {
|
||||
<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 className="order-comment-header">{orderComment.username} - {orderComment.dateCreated}</div>
|
||||
<div dangerouslySetInnerHTML={{__html: orderComment.comment}}></div>
|
||||
</div>
|
||||
</Col>
|
||||
|
||||
@@ -10,10 +10,10 @@ class OrderDocuments extends Component {
|
||||
return (
|
||||
<div id="order-documents" className="order-documents">
|
||||
{
|
||||
orderInfo.packages.map(orderPackage => <OrderDocumentsGroup key={'order-package-' + orderPackage.idPackage} documentsGroup={orderPackage} />)
|
||||
orderInfo.packages.map(orderPackage => <OrderDocumentsGroup key={'order-package-' + orderPackage.id} documentsGroup={orderPackage} />)
|
||||
}
|
||||
{
|
||||
orderInfo.orderDocuments && <OrderDocumentsGroup key={'order-package-0'} documentsGroup={{documents: orderInfo.orderDocuments, packageName: orderTexts.labels.OTHER_DOCS}} />
|
||||
orderInfo.orderDocuments && <OrderDocumentsGroup key={'order-package-0'} documentsGroup={{documents: orderInfo.documents, packageName: orderTexts.labels.OTHER_DOCS}} />
|
||||
}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -57,6 +57,7 @@ class OrderDocumentsGroup extends Component {
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
documentsGroup.documents &&
|
||||
documentsGroup.documents.length > 0 &&
|
||||
<WiaasBox mainTitle={documentsGroup.packageName}>
|
||||
{
|
||||
|
||||
@@ -27,7 +27,7 @@ class OrderInfo extends Component {
|
||||
setInstallationData(props) {
|
||||
const acceptedDate = {};
|
||||
const proposedDate = {};
|
||||
const idOrder = props.orderDetails.info.id;
|
||||
const idOrder = props.orderDetails.id;
|
||||
const {isInstallationInPackage} = props.installationData;
|
||||
const {confirmationDates, areAllShippingDatesConfirmed} = props;
|
||||
const isPreliminaryInstallationDate = areAllShippingDatesConfirmed && idOrder in areAllShippingDatesConfirmed ? !areAllShippingDatesConfirmed[idOrder] : true;
|
||||
@@ -53,18 +53,28 @@ class OrderInfo extends Component {
|
||||
const {acceptedDate, proposedDate, isPreliminaryInstallationDate, isInstallationInOrder} = this.state;
|
||||
const orderPackages = installationData.packages;
|
||||
const isInstallationInPackage = installationData.isInstallationInPackage;
|
||||
const orderInfo = this.props.orderInfo.info;
|
||||
const orderInfo = this.props.orderInfo;
|
||||
|
||||
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>
|
||||
<span>{orderInfo.dateCreated}</span>
|
||||
<div className="subtitle"><h6>{orderTexts.labels.SOLD_BY}:</h6></div>
|
||||
<span>{orderInfo.commercialLead}</span>
|
||||
<span>{orderInfo.commercialLead.name}</span>
|
||||
|
||||
</Col>
|
||||
<Col xl="2">
|
||||
<div className="subtitle"><h6>{orderTexts.labels.BILLING_FIRST_NAME}:</h6></div>
|
||||
<span>{orderInfo.billing.firstName || '-'}</span>
|
||||
<div className="subtitle"><h6>{orderTexts.labels.BILLING_LAST_NAME}:</h6></div>
|
||||
<span>{orderInfo.billing.lastName || '-'}</span>
|
||||
<div className="subtitle"><h6>{orderTexts.labels.BILLING_MAIL}:</h6></div>
|
||||
<span>{orderInfo.billing.email || '-'}</span>
|
||||
<div className="subtitle"><h6>{orderTexts.labels.BILLING_ADDRESS}:</h6></div>
|
||||
<span>{orderInfo.billing.address || '-'}</span>
|
||||
</Col>
|
||||
<Col xl="2">
|
||||
<div>
|
||||
<div className="subtitle"><h6>{orderTexts.labels.REFERENCE}:</h6></div>
|
||||
|
||||
@@ -21,9 +21,9 @@ class PackageNav extends Component {
|
||||
<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>)
|
||||
packages.map((orderPackage) => <div key={'menu-package-' + orderPackage.id}
|
||||
onClick={()=>{onPackageFilter(orderPackage.name)}}
|
||||
className={this.getClass(orderPackage.name)}>{orderPackage.name}</div>)
|
||||
}
|
||||
</Col>
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@ class PackageInfo extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const {orderPackage, onViewChange} = this.props;
|
||||
const shouldShowPriceInfo = orderPackage.packageRecuringPrice > 0 || orderPackage.packageServicePrice > 0;
|
||||
const {orderPackage, currency, onViewChange} = this.props;
|
||||
const shouldShowPriceInfo = orderPackage.recurringPrice > 0 || orderPackage.servicePrice > 0;
|
||||
|
||||
return (
|
||||
<Container fluid={true} id="package-info" className="order-package-info">
|
||||
@@ -41,7 +41,7 @@ class PackageInfo extends Component {
|
||||
{orderTexts.labels.PACKAGE_PRICE}: {' '}
|
||||
{ shouldShowPriceInfo &&
|
||||
<i className="price-info-btn fa fa-info-circle"
|
||||
id={'price-info-' + orderPackage.idPackage}
|
||||
id={'price-info-' + orderPackage.id}
|
||||
onClick={this.toggle}></i>
|
||||
}
|
||||
</h6>
|
||||
@@ -49,43 +49,43 @@ class PackageInfo extends Component {
|
||||
</div>
|
||||
<div>
|
||||
{orderTexts.labels.TOTAL_DELVIERY_PRICE}: {' '}
|
||||
{(orderPackage.units * orderPackage.packageFixedPrice).toLocaleString() + ' ' + orderPackage.packageCurrency.currency}
|
||||
{(orderPackage.quantity * orderPackage.price).toLocaleString() + ' ' + currency}
|
||||
</div>
|
||||
{
|
||||
shouldShowPriceInfo &&
|
||||
<div>
|
||||
{orderTexts.labels.TOTAL_RECURRENT_PRICE}:{' '}
|
||||
{(orderPackage.units * (orderPackage.packageRecuringPrice + orderPackage.packageServicePrice)).toLocaleString()} {orderPackage.packageCurrency.currency}
|
||||
{(orderPackage.quantity * (orderPackage.recurringPrice + orderPackage.servicePrice)).toLocaleString()} {currency}
|
||||
</div>
|
||||
}
|
||||
|
||||
{ shouldShowPriceInfo &&
|
||||
<Popover placement="bottom"
|
||||
isOpen={this.state.popoverOpen}
|
||||
target={'price-info-' + orderPackage.idPackage}
|
||||
container={'price-info-' + orderPackage.idPackage}
|
||||
target={'price-info-' + orderPackage.id}
|
||||
container={'price-info-' + orderPackage.id}
|
||||
className="price-info-popover"
|
||||
toggle={this.toggle}>
|
||||
<PopoverHeader>{orderPackage.paymentType}</PopoverHeader>
|
||||
<PopoverBody>
|
||||
<div>
|
||||
{ orderPackage.packageRecuringPrice > 0 &&
|
||||
{ orderPackage.recurringPrice > 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.quantity * orderPackage.recurringPrice).toLocaleString()} {currency} / {orderPackage.periodUnit}
|
||||
{
|
||||
orderPackage.packagePayPeriod > 0 &&
|
||||
<span>
|
||||
for {orderPackage.packagePayPeriod} {orderPackage.periodUnit}
|
||||
for {orderPackage.payPeriod} {orderPackage.periodUnit}
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
{ orderPackage.packageServicePrice > 0 &&
|
||||
{ orderPackage.servicePrice > 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.quantity * orderPackage.servicePrice).toLocaleString()} {currency} / {orderPackage.periodUnit}
|
||||
{
|
||||
orderPackage.servicesContractPeriod > 0 &&
|
||||
<span>
|
||||
@@ -101,7 +101,7 @@ class PackageInfo extends Component {
|
||||
}
|
||||
</Col>
|
||||
{
|
||||
orderPackage.options.length > 0 &&
|
||||
orderPackage.options && orderPackage.options.length > 0 &&
|
||||
<Col xl="3">
|
||||
<div className="subtitle"><h6>{orderTexts.labels.OPTIONS}:</h6></div>
|
||||
{
|
||||
@@ -112,7 +112,7 @@ class PackageInfo extends Component {
|
||||
</Col>
|
||||
}
|
||||
{
|
||||
orderPackage.additionalPackages.length > 0 &&
|
||||
orderPackage.additionalPackages && orderPackage.additionalPackages.length > 0 &&
|
||||
<Col xl="3">
|
||||
<div className="subtitle"><h6>{orderTexts.labels.ADDITIONAL_PACKAGES}:</h6></div>
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ class PackageName extends Component {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Link to={'/co-market/' + idCommercialLead + '/' + orderPackage.idPackage } className="package-name-link">{orderPackage.units + ' x ' + orderPackage.packageName}</Link>
|
||||
<Link to={'/co-market/' + idCommercialLead + '/' + orderPackage.id } className="package-name-link">{orderPackage.quantity + ' x ' + orderPackage.name}</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@ import PackageName from './PackageName.jsx';
|
||||
|
||||
class ProcessPackage extends Component {
|
||||
render() {
|
||||
const {orderPackage, idCommercialLead} = this.props;
|
||||
const {orderPackage, currency, 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}/>
|
||||
<PackageInfo onViewChange={this.props.onViewChange} orderPackage={orderPackage} currency={currency}/>
|
||||
</Col>
|
||||
</Row>
|
||||
</WiaasBox>
|
||||
|
||||
@@ -5,7 +5,6 @@ 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';
|
||||
@@ -26,15 +25,16 @@ class CustomerAcceptance 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;
|
||||
//const fileUrl = `${API_SERVER}/utils/api/downloadFile?idDocument=${document.idDocument}&fileName=${document.documentName}.${document.extension}`
|
||||
const fileUrl = document.url;
|
||||
const fileName = document.name + '.' + document.extension;
|
||||
fileHandler.download(fileUrl, fileName);
|
||||
}
|
||||
|
||||
uploadFile(idOrder, acceptedFiles, rejectedFiles) {
|
||||
uploadFile(idEntry, acceptedFiles, rejectedFiles) {
|
||||
if(acceptedFiles && acceptedFiles.length){
|
||||
const file = acceptedFiles[0];
|
||||
this.props.dispatch(uploadAcceptance(idOrder, file));
|
||||
this.props.dispatch(uploadAcceptance(idEntry, file));
|
||||
}
|
||||
|
||||
if(rejectedFiles && rejectedFiles.length) {
|
||||
@@ -59,9 +59,9 @@ class CustomerAcceptance extends Component {
|
||||
}
|
||||
|
||||
acceptDeclineInstallation() {
|
||||
const {idOrder} = this.props.step;
|
||||
const {idProcess} = this.props.step;
|
||||
const {actionType, reason} = this.state;
|
||||
this.props.dispatch(acceptDeclineInstallation(idOrder, actionType, reason));
|
||||
this.props.dispatch(acceptDeclineInstallation(idProcess, actionType, reason));
|
||||
this.setState({reason: ''});
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ class CustomerAcceptance extends Component {
|
||||
'-1' : orderTexts.labels.DECLINED
|
||||
}
|
||||
|
||||
return messages[customerAcceptance.customerAccepted];
|
||||
return messages[customerAcceptance.status];
|
||||
}
|
||||
|
||||
onEditorChange(reason) {
|
||||
@@ -107,8 +107,8 @@ class CustomerAcceptance extends Component {
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
const {idOrder} = this.props.step;
|
||||
this.props.dispatch(fetchCustomerAcceptance(idOrder));
|
||||
const {idProcess} = this.props.step;
|
||||
this.props.dispatch(fetchCustomerAcceptance(idProcess));
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -121,14 +121,14 @@ class CustomerAcceptance extends Component {
|
||||
customerAcceptance &&
|
||||
<Row>
|
||||
<Col className="aceeptance-message">
|
||||
{this.getAcceptanceMessage(customerAcceptance)} <div className={'status-icon ' + this.getAcceptanceStatusClass(customerAcceptance.customerAccepted, customerAcceptance.daysDiff)}></div>
|
||||
{this.getAcceptanceMessage(customerAcceptance)} <div className={'status-icon ' + this.getAcceptanceStatusClass(customerAcceptance.status, customerAcceptance.daysDiff)}></div>
|
||||
</Col>
|
||||
</Row>
|
||||
}
|
||||
{
|
||||
(customerAcceptance && customerAcceptance.customerAccepted === -1) &&
|
||||
(customerAcceptance && customerAcceptance.status === -1) &&
|
||||
<Row>
|
||||
<Col>{orderTexts.labels.REASON}: {customerAcceptance.customerDeclineReason}</Col>
|
||||
<Col>{orderTexts.labels.REASON}: {customerAcceptance.decline_reason}</Col>
|
||||
</Row>
|
||||
}
|
||||
<Row className="acceptance-docs">
|
||||
@@ -137,19 +137,18 @@ class CustomerAcceptance extends Component {
|
||||
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)}}>
|
||||
onDrop={(acceptedFiles, rejectedFiles)=>{this.uploadFile(step.idProcess, 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) &&
|
||||
(customerAcceptance && customerAcceptance.documents && customerAcceptance.documents.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})
|
||||
customerAcceptance.documents.map((document, index) => <div key={'acceptance-documnet-' + index}>
|
||||
<span className="document-link">
|
||||
<i className={'fa fa-file'}></i> <a target="_blank" href={document.url}> {document.name} ({document.extension}) </a>
|
||||
</span>
|
||||
<span className="document-status">
|
||||
{document.validation} <div className={'status-icon ' + document.validation}></div>
|
||||
@@ -159,7 +158,7 @@ class CustomerAcceptance extends Component {
|
||||
</div>
|
||||
}
|
||||
{
|
||||
(customerAcceptance && !customerAcceptance.acceptanceDocuments) &&
|
||||
(customerAcceptance && (!customerAcceptance.documents || customerAcceptance.documents.length === 0) ) &&
|
||||
<div>
|
||||
{orderTexts.labels.NO_DOCUMENTS_UPLOADED}
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,7 @@ const completedOrdersStatuses = ['production', 'end-of-life'];
|
||||
|
||||
class OrderProcess extends Component {
|
||||
isStepVisible(step) {
|
||||
return (step.status === 'in-progress' || step.status === 'done') && step.isVisibleForCustomer === 1;
|
||||
return (step.status === 'pending' || step.status === 'complete') && step.isVisibleForCustomer === 1;
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -41,7 +41,7 @@ class OrderProcess extends Component {
|
||||
<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}/>)
|
||||
visibleSteps.reverse().map((step, index) => <ProcessStep isStepVisible={this.isStepVisible} stepNumber={visibleSteps.length - index} step={step} key={'step-' + step.idProcess + '-' + step.idProcessStep}/>)
|
||||
}
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@@ -11,7 +11,7 @@ const stepActions = {
|
||||
|
||||
class OrderStep extends Component {
|
||||
isActiveStep(status) {
|
||||
return status === 'in-progress' ;
|
||||
return status === 'pending' ;
|
||||
}
|
||||
|
||||
getStepTitle(step, stepNumber) {
|
||||
|
||||
@@ -8,8 +8,8 @@ class ValidateQuestionnaire extends Component {
|
||||
|
||||
componentDidMount(){
|
||||
const {idOrder, idProcessStep} = this.props.step;
|
||||
this.props.dispatch(fetchCustomerDocuments(idOrder, 'orderQuestionaire'));
|
||||
this.props.dispatch(fetchValidationComments(idOrder, idProcessStep, 'invalidQuestionnaireComment'));
|
||||
//this.props.dispatch(fetchCustomerDocuments(idOrder, 'orderQuestionaire'));
|
||||
//this.props.dispatch(fetchValidationComments(idOrder, idProcessStep, 'invalidQuestionnaireComment'));
|
||||
}
|
||||
|
||||
findById(orderPackage, idOrderPackagePair){
|
||||
|
||||
@@ -26,6 +26,7 @@ $link-line-height: 1.5rem;
|
||||
|
||||
.completed {
|
||||
border-left: $border-width $production-status-color solid;
|
||||
background: $production-status-color;
|
||||
}
|
||||
|
||||
.end-of-life {
|
||||
@@ -131,7 +132,7 @@ $link-line-height: 1.5rem;
|
||||
background: $canceled-status-color;
|
||||
}
|
||||
|
||||
.production {
|
||||
.completed {
|
||||
background: $production-status-color;
|
||||
}
|
||||
|
||||
@@ -139,11 +140,15 @@ $link-line-height: 1.5rem;
|
||||
background: $open-status-color;
|
||||
}
|
||||
|
||||
.done {
|
||||
.complete {
|
||||
background: $done-status-color;
|
||||
}
|
||||
|
||||
.in-progress {
|
||||
.processing {
|
||||
background: $in-progress-status-color;
|
||||
}
|
||||
|
||||
.pending {
|
||||
background: $in-progress-status-color;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,11 +45,14 @@ class HtmlClient {
|
||||
uploadFile(file, configParams = null) {
|
||||
let formData = new FormData();
|
||||
formData.append('file', file, file.name);
|
||||
/*
|
||||
if(configParams) {
|
||||
|
||||
Object.keys(configParams.data).forEach((paramKey) => {
|
||||
formData.append(paramKey, configParams.data[paramKey]);
|
||||
});
|
||||
}
|
||||
|
||||
}*/
|
||||
configParams.data = formData;
|
||||
const params = Object.assign({}, uploadParams(), configParams);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import moment from 'moment';
|
||||
import {fromWiaasProcessStep} from './ProcessHelper';
|
||||
|
||||
function formatDate(date) {
|
||||
return date ? moment(date).format("Do MMM, YYYY") : undefined;
|
||||
@@ -9,6 +10,10 @@ function formatAddress(addressObject) {
|
||||
}
|
||||
|
||||
export const fromWCOrder = (WCOrder) => {
|
||||
let processInfo = Object.assign({},WCOrder['delivery-process']);
|
||||
if (WCOrder['delivery-process']){
|
||||
processInfo.steps = WCOrder['delivery-process'].steps.map(step=>fromWiaasProcessStep(step));
|
||||
}
|
||||
return {
|
||||
id: WCOrder.id,
|
||||
number: WCOrder.number,
|
||||
@@ -22,6 +27,12 @@ export const fromWCOrder = (WCOrder) => {
|
||||
recurringPrice: 0,
|
||||
status: WCOrder.status,
|
||||
currency: WCOrder.currency,
|
||||
billing:{
|
||||
firstName: WCOrder.billing.first_name,
|
||||
lastName: WCOrder.billing.last_name,
|
||||
email: WCOrder.billing.email,
|
||||
address: formatAddress(WCOrder.billing)
|
||||
},
|
||||
packages: WCOrder['line_items'].map(packageLine => {
|
||||
return {
|
||||
id: packageLine['product_id'],
|
||||
@@ -48,6 +59,14 @@ export const fromWCOrder = (WCOrder) => {
|
||||
})),
|
||||
};
|
||||
}),
|
||||
process: processInfo,
|
||||
comments: WCOrder.comments ? WCOrder.comments.map(comment => ({
|
||||
id: comment.id,
|
||||
comment: comment.content,
|
||||
username: comment.username,
|
||||
dateCreated: formatDate(comment.date),
|
||||
isOwner: comment['is_owner']
|
||||
})) : [],
|
||||
deliveryAddress: formatAddress(WCOrder.shipping),
|
||||
customer: WCOrder.customer,
|
||||
commercialLead: WCOrder['commercial_lead'],
|
||||
|
||||
19
frontend/src/helpers/ProcessHelper.js
Normal file
19
frontend/src/helpers/ProcessHelper.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import moment from "moment";
|
||||
|
||||
export const fromWiaasProcessStep = (step) => {
|
||||
return {
|
||||
actionCode: step.action_code,
|
||||
actualDate: step.actual_date,
|
||||
comments: step.comments,
|
||||
fullDesc: step.full_desc,
|
||||
idOrder: step.order_id,
|
||||
idProcess: step.step_form_entry_id, //not sure about this
|
||||
idProcessStep: step.step_id, //not sure about this
|
||||
isNewCommentVisible: 1, //TODO : get this from backend
|
||||
isVisibleForCustomer: 1, //TODO : get this from backend
|
||||
now: moment().format("Do MMM YY"),
|
||||
shortDesc: step.short_desc,
|
||||
status: step.status,
|
||||
stepType: step.step_type,
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user