Initial commit

This commit is contained in:
Rifqy Zacky Ariadhy
2019-01-02 18:39:53 +07:00
commit 1a000700e6
781 changed files with 95892 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
import React from 'react';
import {observer, inject} from 'mobx-react';
import {Dialog, FlatButton, Stepper, Step, StepLabel, Snackbar} from "material-ui";
import {DIALOG} from "../../../../stores/global_ui";
@inject('appstate')
@observer
export default class CancelPaymentDialog extends React.Component {
constructor(props) {
super(props);
this.props = props;
this.state = {
currentStep: 0,
prevText: "Cancel",
nextText: "Submit"
};
this.defaultState = Object.assign({}, this.state);
this.globalUI = props.appstate.globalUI;
this.order = props.appstate.order;
this.http = props.appstate.http;
}
componentDidMount() {
}
makePayment() {
return this.http.post("payments/cancel", {
package_transaction_id: this.order.selectedOrder.id
})
.then(res => {
this.order.getDetail(this.order.selectedOrder.id);
this.globalUI.hideDialog(DIALOG.ORDER.CANCEL_PAYMENT);
})
}
handleNext = () => this.makePayment();
handleClose = () => this.globalUI.hideDialog(DIALOG.ORDER.CANCEL_PAYMENT);
render() {
const actions = [
<FlatButton
label={this.state.prevText}
primary={true}
onClick={() => this.globalUI.hideDialog(DIALOG.ORDER.CANCEL_PAYMENT)}
/>,
<FlatButton
label={this.state.nextText}
primary={true}
onClick={() => this.handleNext().catch(err => this.props.appstate.globalUI.openSnackbar(err.message))}
/>,
];
const actionsCancelOnly = [
<FlatButton
label={"Ok"}
primary={true}
onClick={() => this.globalUI.hideDialog(DIALOG.ORDER.CANCEL_PAYMENT)}
/>,
]
return (
<Dialog
title="Cancel a Payment"
modal={false}
actions={actions}
open={this.globalUI[DIALOG.ORDER.CANCEL_PAYMENT]}
onRequestClose={this.handleClose}>
Are you sure want to cancel this book?
</Dialog>
)
}
}

View File

@@ -0,0 +1,124 @@
import React from 'react';
import {observer, inject} from 'mobx-react';
import {Dialog, FlatButton, TextField} from "material-ui";
import {DIALOG} from "../../../../stores/global_ui";
import NumberFormat from 'react-number-format';
import get from 'lodash/get';
@inject('appstate')
@observer
export default class GojekDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
value: ''
};
this.props = props;
this.order = props.appstate.order;
}
// componentDidUpdate(prevState, prevProps){
// if(this.props !== prevProps){
// console.log(this.order.gojekPrice, 'this.order.gojekPrice this.order.gojekPrice')
// }
// }
render() {
const actions = [
<FlatButton
label="Cancel"
primary={true}
onClick={() => {
this.props.appstate.globalUI.hideDialog(DIALOG.ORDER.GOJEK_DELIVERY);
this.setState({
value: ''
});
}}
/>,
<FlatButton
label="Submit"
primary={true}
keyboardFocused={true}
onClick={() => {
this.props.appstate.order.bookingGojek();
this.props.appstate.odoo.createSales(this.props.appstate.order.selectedOrder.id);
this.props.appstate.globalUI.hideDialog(DIALOG.ORDER.GOJEK_DELIVERY);
this.setState({
value: ''
});
}}
/>,
];
const actionsError = [
<FlatButton
label="Cancel"
primary={true}
onClick={() => {
this.props.appstate.globalUI.hideDialog(DIALOG.ORDER.GOJEK_DELIVERY);
this.setState({
value: ''
});
}}
/>
];
return (<Dialog
title="Booking Gojek Delivery"
actions={(this.order.gojekPrice.serviceable) ? actions : actionsError}
modal={false}
open={this.props.appstate.globalUI[DIALOG.ORDER.GOJEK_DELIVERY]}
onRequestClose={() => {
this.props.appstate.globalUI.hideDialog(DIALOG.ORDER.GOJEK_DELIVERY);
this.setState({
value: ''
});
}}
>
{(this.order.gojekPrice.serviceable) ? <div>
<div>
<div className="center-align"><p style={{ lineHeight: "1.6rem" }}>You will find driver to pick up and send your package</p></div>
<div className="center-align"><p style={{ lineHeight: "1.6rem", marginTop: "0px", marginBottom: "0px" }}>Total Amount</p></div>
<div className="center-align"><h4 className="black-text" style={{ lineHeight: "1.6rem", marginTop: "0px", fontSize: "26px", marginBottom: "0px" }}><NumberFormat value={get(this.order.gojekPrice, 'price.total_price',0)} displayType={'text'} thousandSeparator={true} prefix={'IDR '} /></h4></div>
<div className="row" style={{marginTop: 20}}>
<div className="col s12">
<h4 className="center-align" style={{ fontSize: '14px', marginBottom: "8px" }}>To</h4>
<div style={{
boxShadow: "none",
border: "1px solid #d4d4d4",
backgroundColor: "#f9f9f9",
padding: "10px 10px 10px 20px",
marginTop: 0,
marginBottom: 0,
textAlign: 'center'
}} className="card-panel">
<p className="black-text" style={{ lineHeight: '1.0rem', fontSize: 11 }}>
Shipment Method: {get(this.order.gojekPrice, 'shipment_method','-')}
</p>
<p className="black-text" style={{ lineHeight: '1.0rem', fontSize: 11 }}>
Estimate time: {get(this.order.gojekPrice, 'shipment_method_description','-')}
</p>
<p className="black-text" style={{ lineHeight: '1.0rem', fontSize: 11 }}>
Distance : {get(this.order.gojekPrice, 'distance',0)} KM
</p>
</div>
</div>
</div>
</div>
</div> : <div>
<div className="center-align"><p style={{ lineHeight: "1.6rem" }}>GO-SEND Service are <strong>Unavailable</strong> because</p></div>
{/*<div className="center-align"><p style={{ lineHeight: "1.6rem", marginTop: "0px", marginBottom: "0px" }}>Total Amount</p></div>*/}
<div className="center-align"><h4 className="black-text" style={{ lineHeight: "1.6rem", marginTop: "0px", fontSize: "26px", marginBottom: "0px" }}>
{get(this.order.gojekPrice, 'shipment_method_description','-')}
</h4></div>
</div>}
</Dialog>);
}
}

View File

@@ -0,0 +1,49 @@
import React from 'react';
import {observer, inject} from 'mobx-react';
import {DIALOG} from "../../../../stores/global_ui";
import NumberFormat from 'react-number-format';
@inject('appstate')
@observer
export default class BookedOrder extends React.Component {
constructor(props) {
super(props);
this.props = props;
this.state = {};
this.defaultState = Object.assign({}, this.state);
this.http = props.appstate.http;
this.order = props.appstate.order;
this.globalUI = props.appstate.globalUI;
}
makePayment() {
return this.http.post("payments/add_payment", {
package_transaction_id: this.order.selectedOrder.id
})
.then(res => {
this.order.getDetail(this.order.selectedOrder.id);
this.globalUI.hideDialog(DIALOG.ORDER.MAKE_PAYMENT);
})
}
componentDidMount() {
const {parent} = this.props;
setTimeout(() => {
parent.setState({
handleNext: () => this.makePayment()
});
}, 1000);
}
render() {
return (
<div>
You'll pay <NumberFormat value={this.order.selectedOrder.installment_amount} displayType={'text'} thousandSeparator={true} prefix={'IDR '}/>
</div>
)
}
}

View File

@@ -0,0 +1,49 @@
import React from 'react';
import {observer, inject} from 'mobx-react';
import {DIALOG} from "../../../../stores/global_ui";
import NumberFormat from 'react-number-format';
@inject('appstate')
@observer
export default class CompletedOrder extends React.Component {
constructor(props) {
super(props);
this.props = props;
this.state = {};
this.defaultState = Object.assign({}, this.state);
this.http = props.appstate.http;
this.order = props.appstate.order;
this.globalUI = props.appstate.globalUI;
}
// makePayment() {
// this.http.post("payments/add_payment", {
// package_transaction_id: this.order.selectedOrder.id
// })
// .then(res => {
// this.order.getDetail(this.order.selectedOrder.id);
// this.globalUI.hideDialog(DIALOG.ORDER.MAKE_PAYMENT);
// })
// }
componentDidMount() {
const {parent} = this.props;
setTimeout(() => {
parent.setState({
handleNext: () => {return true}
});
}, 1000);
}
render() {
return (
<div>
Your payment is already completed
</div>
)
}
}

View File

@@ -0,0 +1,62 @@
import React from 'react';
import {observer, inject} from 'mobx-react';
import {DIALOG} from "../../../../stores/global_ui";
import NumberFormat from 'react-number-format';
@inject('appstate')
@observer
export default class OrderedOrder extends React.Component {
constructor(props) {
super(props);
this.props = props;
this.state = {
amount: 0,
isLoading: true
};
this.defaultState = Object.assign({}, this.state);
this.http = props.appstate.http;
this.order = props.appstate.order;
this.globalUI = props.appstate.globalUI;
}
makePayment() {
return this.http.post("payments/initial_payment", {
package_transaction_id: this.order.selectedOrder.id
})
.then(res => {
this.order.getDetail(this.order.selectedOrder.id);
this.globalUI.hideDialog(DIALOG.ORDER.MAKE_PAYMENT);
})
}
componentDidMount() {
const {parent} = this.props;
this.setState({isLoading: true});
this.http.post("payments/initial_payment_preview", {
package_transaction_id: this.order.selectedOrder.id
})
.then(res => {
parent.setState({
handleNext: () => this.makePayment()
});
this.setState({
isLoading: false,
amount: res.amount
})
});
}
render() {
return (
<div>
You'll pay <NumberFormat value={this.state.amount} displayType={'text'} thousandSeparator={true} prefix={'IDR '}/> as DownPayment
</div>
)
}
}

View File

@@ -0,0 +1,29 @@
import React from 'react';
import {observer, inject} from 'mobx-react';
import {MenuItem, SelectField} from "material-ui";
@inject('appstate')
@observer
export default class SelectPaymentType extends React.Component {
constructor(props) {
super(props);
this.props = props;
this.state = {};
this.defaultState = Object.assign({}, this.state);
}
componentDidMount() {
}
render() {
return (
<div>
<SelectField>
<MenuItem value={"cash"} primaryText="Cash" />
</SelectField>
</div>
)
}
}

View File

@@ -0,0 +1,80 @@
import React from 'react';
import {observer, inject} from 'mobx-react';
import {Dialog, FlatButton, Stepper, Step, StepLabel, Snackbar} from "material-ui";
import {DIALOG} from "../../../../stores/global_ui";
import SelectPaymentType from "./SelectPaymentType";
import BookedOrder from './BookedOrder';
import OrderedOrder from './OrderedOrder';
import CompleteOrder from './CompleteOrder';
@inject('appstate')
@observer
export default class MakePaymentDialog extends React.Component {
constructor(props) {
super(props);
this.props = props;
this.state = {
currentStep: 0,
handleNext: () => {},
prevText: "Cancel",
nextText: "Submit"
};
this.defaultState = Object.assign({}, this.state);
this.globalUI = props.appstate.globalUI;
this.order = props.appstate.order;
}
componentDidMount() {
}
getContent() {
switch (this.order.selectedOrder.status) {
case "ordered":
return <OrderedOrder parent={this} />;
case "booked":
return <BookedOrder parent={this} />;
case "payment_complete":
return <CompleteOrder parent={this} />;
default:
return <div/>;
}
}
render() {
const actions = [
<FlatButton
label={this.state.prevText}
primary={true}
onClick={() => this.globalUI.hideDialog(DIALOG.ORDER.MAKE_PAYMENT)}
/>,
<FlatButton
label={this.state.nextText}
primary={true}
onClick={() => this.state.handleNext().catch(err => this.props.appstate.globalUI.openSnackbar(err.message))}
/>,
];
const actionsCancelOnly = [
<FlatButton
label={"Ok"}
primary={true}
onClick={() => this.globalUI.hideDialog(DIALOG.ORDER.MAKE_PAYMENT)}
/>,
];
return (
<Dialog
title="Make a Payment"
modal={false}
actions={(this.order.selectedOrder.status === 'payment_complete') ? actionsCancelOnly : actions}
open={this.globalUI[DIALOG.ORDER.MAKE_PAYMENT]}
onRequestClose={this.handleClose}>
{this.getContent()}
</Dialog>
)
}
}

View File

@@ -0,0 +1,66 @@
import React from 'react';
import {observer, inject} from 'mobx-react';
import {Dialog, FlatButton, TextField} from "material-ui";
import {DIALOG} from "../../../../stores/global_ui";
@inject('appstate')
@observer
export default class MerchantInputShippingCodeDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
value: ''
};
this.props = props;
}
componentWillReceiveProps() {
}
render() {
const actions = [
<FlatButton
label="Cancel"
primary={true}
onClick={() => {
this.props.appstate.globalUI.hideDialog(DIALOG.ORDER.INPUT_SHIPPING_CODE);
this.setState({
value: ''
});
}}
/>,
<FlatButton
label="Submit"
primary={true}
keyboardFocused={true}
onClick={() => {
this.props.appstate.order.inputShippingCode(this.state.value);
this.props.appstate.globalUI.hideDialog(DIALOG.ORDER.INPUT_SHIPPING_CODE);
this.setState({
value: ''
});
}}
/>,
];
return (<Dialog
title="Input shipping code"
actions={actions}
modal={false}
open={this.props.appstate.globalUI[DIALOG.ORDER.INPUT_SHIPPING_CODE]}
onRequestClose={() => {
this.props.appstate.globalUI.hideDialog(DIALOG.ORDER.INPUT_SHIPPING_CODE);
this.setState({
value: ''
});
}}
>
<TextField
hintText="Shipping Code"
value={this.state.value}
onChange={(event) => this.setState({value: event.target.value})}
/>
</Dialog>);
}
}

View File

@@ -0,0 +1,217 @@
import React from 'react';
import {inject, observer} from 'mobx-react';
import {DatePicker, MenuItem, SelectField, TextField, Checkbox, } from 'material-ui';
import { Upload, Icon, Modal, Input, Select, Switch, message, Button as ButtonAntd } from 'antd';
import schema from 'async-validator'
import startCase from 'lodash.startcase';
import moment from 'moment';
import get from 'lodash.get';
import NumberFormat from 'react-number-format';
@inject('appstate')
@observer
export default class FormData extends React.Component {
constructor(props) {
super(props);
this.props = props;
this.state = {
formData: Object.assign({
name : '',
// icon : '',
// background_image : ''
},props.defaultValue ) || {},
checked: true,
errorText: {},
onChangeTimeoutId: false,
countries: [],
};
this.http = props.appstate.http;
this.orderStore = props.appstate.order;
}
// componentWillUnmount(){
// }
componentDidMount() {
const {defaultValue={}} = this.props;
this.setState({
formData : {
...this.state.formData,
...defaultValue
}
})
}
triggerOnChange() {
this.props.onChangeData(this.state.formData);
// if (this.state.onChangeTimeoutId) {
// this.setState({
// onChangeTimeoutId: false
// });
// return clearTimeout(this.state.onChangeTimeoutId);
// }
// const onChangeTimeoutId = setTimeout(() => {
// if (this.props.onChangeData && typeof this.props.onChangeData === 'function') {
// this.props.onChangeData(this.state.formData);
// }
// this.setState({
// onChangeTimeoutId: false
// });
// }, 322);
// this.setState({onChangeTimeoutId});
}
updateCheck() {
this.setState((oldState) => {
return {
checked: !oldState.checked,
};
});
}
render() {
const wrapperText = key => ele => React.cloneElement(ele, {
value: this.state.formData[key],
errorText: this.state.errorText[key],
onChange: (e) => {
if(["preorder_price", "preorder_weight"].includes(key)){
let data = this.state.formData;
let weight = (e.target.value.indexOf("-") > -1) ? 0 : parseInt(e.target.value.replace(/,/g,''),10);
data.preorder_price = parseInt(data.regular_price * (weight/1000));
this.setState({
formData: {
...data,
[key]: weight,
}
}, () => this.triggerOnChange());
}
else{
this.setState({
formData: {
...this.state.formData,
[key]: e.target.value,
}
}, () => this.triggerOnChange());
}
}
});
const wrapperSelect = key => ele => React.cloneElement(ele, {
value: this.state.formData[key],
errorText: this.state.errorText[key],
onChange: (e, k, v) => {
this.setState({
formData: {
...this.state.formData,
[key]: v,
}
}, () => this.triggerOnChange());
}
});
const wrapperSwitch = key => ele => React.cloneElement(ele, {
checked: this.state.formData[key],
errorText: this.state.errorText[key],
onCheck: (e, v) => {
this.setState({
formData: {
...this.state.formData,
[key]: v,
}
}, () => this.triggerOnChange());
}
});
const {mode="create"} = this.props;
return(
<div style={{
paddingTop: 10
}}>
<div className="row">
<div className="col s6 m6 l6">
<div style={{backgroundColor:'#f3f3f7', padding:'8px 12px 0', borderRadius:'4px'}}>
<p className="label-form" style={{margin:0, color: '#3E4B5B', fontWeight:'500',fontSize:'.9rem'}}>Quantity request by gram</p>
{wrapperText("preorder_buyer_note")(
<TextField
fullWidth={true}
underlineDisabledStyle={{display:'none'}}
multiLine={true}
textareaStyle={{fontSize:'.9rem', color: '#3E4B5B'}}
rows={1}
disabled={true}/>
)}
</div>
</div>
<div className="col s6 m6 l6">
<div style={{backgroundColor:'#f3f3f7', padding:'8px 12px 0', borderRadius:'4px'}}>
<p className="label-form" style={{margin:0, color: '#3E4B5B', fontWeight:'500',fontSize:'.9rem'}}>Stock Available (Gram)</p>
{wrapperText("item_stock_available")(
<TextField
fullWidth={true}
underlineDisabledStyle={{display:'none'}}
multiLine={true}
textareaStyle={{fontSize:'.9rem', color: '#3E4B5B'}}
rows={1}
disabled={true}/>
)}
</div>
</div>
</div>
<div className="row">
<div className="col s12 m12 l12">
<div style={{}}>
<p className="label-form" style={{margin:0, color: '#3E4B5B', fontWeight:'500', marginBottom:4, fontSize:'.9rem'}}>Your Note</p>
{wrapperText("preorder_store_note")(
<TextField
fullWidth={true}
multiLine={true}
rows={1}
style={{border: "2px solid #dde2ec", borderRadius:'4px', padding:'0px 8px 0 8px', fontSize:14, minheight: '32px'}}
textareaStyle={{marginTop:8, fontSize:14, minheight: '32px'}}
underlineShow={false}
hintText="Add notes for buyer"/>
)}
</div>
</div>
</div>
<div className="row">
<div className="col s6 m6 l6">
<div>
<p className="label-form" style={{margin:0, color: '#3E4B5B', fontWeight:'500', marginBottom:4, fontSize:'.9rem'}}>Price @kilogram</p>
{wrapperText("preorder_price")(
<NumberFormat disabled={true} thousandSeparator={true} style={{ width:'100%', color: '#3E4B5B', padding: '4px 11px', height: '32px', fontSize: '14px', border: "2px solid #dde2ec", borderRadius:'4px', backgroundColor:'#f3f3f7' }} placeholder="E.g. 50000" />
)}
</div>
</div>
<div className="col s6 m6 l6">
<div>
<p className="label-form" style={{margin:0, color: '#3E4B5B', fontWeight:'500', marginBottom:4, fontSize:'.9rem'}}>Quantity by gram</p>
{wrapperText("preorder_weight")(
<NumberFormat thousandSeparator={true} style={{width:'100%', padding: '4px 11px', color: '#3E4B5B', height: '32px', fontSize: '14px', border: "2px solid #dde2ec", borderRadius:'4px'}} placeholder="E.g. 5" />
)}
</div>
</div>
</div>
</div>
);
}
}

View File

@@ -0,0 +1,302 @@
import React from 'react';
import {observer, inject} from 'mobx-react';
import {
Dialog, FlatButton, RaisedButton,
Step,
StepLabel,
Stepper,
IconButton
} from "material-ui";
import {DIALOG} from "../../../../stores/global_ui";
import FormData from './FormData';
import ArrowForwardIcon from 'material-ui/svg-icons/navigation/arrow-forward';
import NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back';
import {constant} from "../../../../config/const";
import schema from 'async-validator'
@inject('appstate')
@observer
export default class PreorderNotesDialog extends React.Component {
constructor(props) {
super(props);
this.props = props;
this.state = {
stepIndex: 0,
formData: {},
finished: false,
openedDialog: false,
errorMessage: ''
};
this.defaultState = Object.assign({}, this.state);
this.globalUI = props.appstate.globalUI;
this.orderStore = props.appstate.order;
}
componentDidMount() {
console.log(this.state.formData,'ini men')
this.setState({
stepIndex: 0
});
}
onChangeForm(formData) {
this.setState({formData});
}
getStepContent(stepIndex) {
const {mode = "create", defaultValue = {}} = this.props;
switch (stepIndex) {
case 0:
return (
<FormData
mode={mode}
defaultValue={defaultValue}
onChangeData={formData => this.setState({formData})}/>
);
// case 1:
// return <IdentificationPassport/>;
}
}
handleOpen = () => {
this.setState({confirmationDialog: true})
};
handleNext = () => {
const {stepIndex} = this.state;
const {mode = "create", defaultValue = {}} = this.props;
if (stepIndex === 0) {
const rules = {
preorder_store_note: [
{
required: true,
message: 'Please input your note'
}
],
preorder_price: [
{
required: true,
message: 'Please input price'
}
],
preorder_weight: [
{
required: true,
message: 'Please input weight'
}
]
};
const validator = new schema(rules);
if (mode === "create") {
console.log(this.state.formData, 'this is form data');
validator.validate(this.state.formData, (errs, f) => {
console.log(errs);
if (errs) {
this.globalUI.showNotification("Something's Wrong", errs[0].message);
} else {
if(this.state.formData.preorder_weight > this.state.formData.item_stock_available){
this.globalUI.showNotification("Something's Wrong", 'Stock Not Enough');
}
else if (this.state.formData.preorder_price > 0 && this.state.formData.preorder_weight > 0) {
this.setState({
stepIndex: stepIndex + 1,
});
}
else{
this.globalUI.showNotification("Something's Wrong", 'Price or weight cannot be 0');
}
}
});
}
else if (mode === "update") {
this.setState({
stepIndex: stepIndex + 1,
});
}
}
}
handlePrev = () => {
const {stepIndex} = this.state;
if (stepIndex > 0) {
this.setState({stepIndex: stepIndex - 1});
}
}
handleClose = () => {
this.setState({confirmationDialog: false})
};
save = () => {
this.globalUI.hideDialog(DIALOG.ORDER.PREORDER_ADD_NOTES);
this.globalUI.showDialogLoading();
const {mode = "create", defaultValue = {}} = this.props;
if (mode === "create") {
let data = this.state.formData;
this.orderStore.addStoreNotes(data)
.then(res => {
this.globalUI.hideDialogLoading();
this.globalUI.openSnackbar("Success Added Notes");
this.orderStore.getDetail(data.order_store_id);
this.setState({
stepIndex: 0
})
})
.catch(err => {
console.error(err);
});
} else if (mode === "update") {
// let data = this.state.formData;
// // data.image = {
// // icon : this.state.formData.icon,
// // background_image : this.state.formData.background_image
// // }
// // delete data.icon;
// // delete data.background_image;
// this.categoriesStore.putCategory(defaultValue.id, data)
// .then(res => {
// // this.globalUI.hideDialog(DIALOG.EMPLOYEE.CREATE);
// this.globalUI.hideDialogLoading();
// this.globalUI.openSnackbar("Success Updated Category")
// this.setState({
// stepIndex: 0
// })
// // this.categoriesStore.getAll();
// })
// .catch(err => {
// this.globalUI.openSnackbar("Error, Check log for detail");
// console.error(err);
// });
}
}
handlePost = () => {
// this.agentStore.post().then(res => {
// this.props.history.push(LINKS.SETTING);
// this.globalUI.openSnackbar("Successfull Added Employee");
// });
};
continueButton() {
console.log(this.props.defaultValue,'iniiiiiii')
if (!!this.props.defaultValue.preorder_store_note) {
console.log('ALREADY ADDED');
return;
}
if (this.state.stepIndex === 1) {
return (
<RaisedButton
label="Finish"
primary={true}
onClick={this.save}
/>
);
} else {
return (
<RaisedButton
label="Next"
primary={true}
onClick={this.handleNext}
/>
);
}
}
render() {
const {finished, stepIndex} = this.state;
const {mode = "create", defaultValue = {}} = this.props;
const actions = [
<RaisedButton
label="OK"
primary={true}
style={{marginRight: 10}}
onClick={this.handleClose}
/>,
]
const title =
<div>
<h4 style={{
fontSize: 26,
marginBottom: 0,
marginTop: 0,
fontWeight: 500,
color: "black"
}}>{(mode === "create") ? "Preorder Request" : "Update Preorder Request"} </h4>
</div>
;
return (
<div>
<Dialog
title={<div>
<div>{title}</div>
<div style={{padding: "0px 14px 0px 0px", marginTop: 10}}>
<Stepper activeStep={stepIndex}>
<Step>
<StepLabel style={{padding: "0px 14px 0px 0px", height: 52}}>Confirmation</StepLabel>
</Step>
<Step>
<StepLabel style={{padding: "0px 0px 0px 14px", height: 52}}>Confirm</StepLabel>
</Step>
</Stepper>
</div>
</div>}s
titleStyle={{paddingBottom: 10}}
modal={false}
actions={<div style={{marginTop: 12}}>
<FlatButton
label={(stepIndex === 0) ? "Cancel" : "Back"}
style={{marginRight: 10}}
primary={true}
onClick={() => (stepIndex === 0) ? this.globalUI.hideDialog(DIALOG.ORDER.PREORDER_ADD_NOTES) : this.handlePrev()}
/>
{this.continueButton()}
</div>}
autoScrollBodyContent={true}
repositionOnUpdate={true}
open={this.globalUI[DIALOG.ORDER.PREORDER_ADD_NOTES]}
onRequestClose={this.handleClose}
bodyStyle={{padding:'0 8px 8px 8px'}}
overlayStyle={{zIndex: 999}}
style={{zIndex: 9999}}
paperClassName={'radius6'}
contentClassName={'marketplace-dialog-small'}
>
<div>
{this.getStepContent(stepIndex)}
</div>
<Dialog
title="Warning"
actions={actions}
modal={false}
style={{zIndex:99999}}
autoScrollBodyContent={false}
contentStyle={{width: 350, zIndex:99999}}
open={this.state.confirmationDialog}
onRequestClose={() => this.handleClose()}
>
{this.state.errorMessage}
</Dialog>
</Dialog>
</div>
)
}
}

View File

@@ -0,0 +1,964 @@
import React from 'react';
import {observer, inject} from 'mobx-react';
import {
Card, CardTitle, CardText,
Divider,
MenuItem,
FlatButton,
RaisedButton,
Table,
TableBody,
TableHeader,
TableHeaderColumn,
TableRow,
TableRowColumn,
TextField,
Toolbar,
ToolbarGroup,
ToolbarSeparator, ToolbarTitle, CardHeader, Dialog, FontIcon, Avatar, ListItem
} from 'material-ui';
import {Link} from 'react-router-dom';
import {LINKS} from "../../../routes";
import {DIALOG} from "../../../stores/global_ui";
import AddIcon from 'material-ui/svg-icons/content/add';
import RemoveIcon from 'material-ui/svg-icons/content/remove';
import NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back';
import {Timeline, Icon, Affix} from 'antd';
import MakePaymentDialog from './MakePaymentDialog/index';
import CancelPaymentDialog from './CancelPaymentDialog/index';
import moment from "moment";
import get from 'lodash.get';
import DC from 'decimal.js-light';
import NumberFormat from 'react-number-format';
import EmptyComponent from '../../EmptyComponent';
import confirm from '../../../util/confirm';
import {constant} from "../../../config/const";
import MerchantInputShippingCodeDialog from "./MerchantInputShippingCodeDialog";
import GojekDelivery from "./GojekDelivery";
import LoadingDialog from '../../LoadingDialog/index';
import PreorderAddNotes from './PreorderAddNotes';
import '../style.scss'
import {uniqBy,startCase,upperCase,reverse} from 'lodash';
import PrintProvider, {Print, NoPrint} from 'react-easy-print';
import PrintIcon from 'material-ui/svg-icons/action/print';
@inject('appstate')
@observer
export default class OrderDetailComponent extends React.Component {
constructor(props) {
super(props);
this.props = props;
this.state = {
value: 1,
searchText: '',
slideIndex: 0,
tabSelected: 'gi',
openModal: false,
errorBook: false,
errorMessage: '',
itemData: {}
};
this.defaultState = Object.assign({}, this.state);
this.http = props.appstate.http;
this.authStore = props.appstate.auth;
this.globalUI = props.appstate.globalUI;
this.order = props.appstate.order;
}
componentDidMount() {
this.order.getDetail(this.props.match.params.id);
}
handleUpdateInput = (searchText) => {
this.setState({
searchText: searchText,
});
};
handleNewRequest = () => {
this.setState({
searchText: '',
});
};
tabsHandleChange = (value) => {
this.setState({
slideIndex: value,
});
};
closeError = () => {
this.setState({
errorBook: false
})
}
handleChange = (tabSelected) => {
this.setState({
tabSelected: tabSelected,
});
// this.props.history.push(tabSelected);
};
handleCloseModal = () => {
this.setState({
openModal: false
})
};
calculatePrice = () => {
this.globalUI.openLoading();
this.order.calculatePrice().then(res => {
this.globalUI.closeLoading();
this.props.appstate.globalUI.showDialog(DIALOG.ORDER.GOJEK_DELIVERY);
}).catch(err => {
this.globalUI.closeLoading();
this.setState({
errorBook: true,
errorMessage: err.message
});
})
}
handleOpenModal = () => {
this.setState({
openModal: true
})
}
openPreorderDialog = (data) => {
console.log(data, 'ini data');
this.setState({
itemData: {
preorder_store_note: data.preorder_store_note,
preorder_buyer_note: data.preorder_buyer_note,
//preorder_price: data.preorder_price || 0,
preorder_price: data.item.regular_price || 0,
regular_price: data.item.regular_price,
preorder_weight: data.preorder_weight || 0,
user_order_item_id: data.id,
order_store_id: this.order.selectedOrder.id,
order_status_id: this.order.selectedOrder.order_status_id,
item_stock_available : data.item.stock
}
}, () => this.props.appstate.globalUI.showDialog(DIALOG.ORDER.PREORDER_ADD_NOTES));
}
orderHistoryText = (history)=>{
if(history.order_status_id == constant.ORDER_STATUSES.PREORDER_WAITING_STORE_RESPONSE){
return (
<div>
Buyer waiting for store response for order items
</div>
)
}
else if(history.order_status_id == constant.ORDER_STATUSES.PREORDER_WAITING_BUYER_CONFIRMATION){
return (
<div>
Waiting for buyer for confirm new weight and price
</div>
)
}
else if(history.order_status_id == constant.ORDER_STATUSES.PREORDER_WAITING_PAYMENT){
return (
<div>
Waiting buyer to pay the order
</div>
)
}
else if(history.order_status_id == constant.ORDER_STATUSES.PENDING_PAYMENT){
return (
<div>
Payment from buyer pending
</div>
)
}
else if(history.order_status_id == constant.ORDER_STATUSES.PROCESSING){
return (
<div>
Order ready to process
</div>
)
}
else if(history.order_status_id == constant.ORDER_STATUSES.ON_SHIPPING){
return (
<div>
Order is on shipping
</div>
)
}
else if(history.order_status_id == constant.ORDER_STATUSES.COMPLETED){
return (
<div>
Order is complete, package accepted by buyer
</div>
)
}
else if(history.order_status_id == constant.ORDER_STATUSES.PREORDER_BUYER_DECLINE){
return (
<div>
Preorder new weight and price decline by buyer
</div>
)
}
else{
return (
<div>
{history.status.name}
</div>
)
}
}
handlePrint() {
window.print();
}
getStatusDeliveryColor = (type) =>{
if(type == "delivered"){
return 'green'
}else if(type == "on_hold"){
return 'orange'
}
else if(type == "cancelled" || type=='rejected'){
return 'red'
}
else {
return 'green'
}
}
getShipmentTrackingMessage = (tracking)=>{
let message = tracking.cancellation_reason.split(' - ');
let statusColor = 'green';
let shipmentStatus = '';
let object = 'Item';
if(tracking.status == "on_hold"){
statusColor= 'orange';
shipmentStatus = 'On Hold'
}
else if(tracking.status == 'delivered'){
shipmentStatus = 'Finished';
}
else if(tracking.status == "cancelled" || tracking.status=='rejected' || tracking.status == 'no_driver'){
statusColor = 'red';
shipmentStatus = 'Finished'
}
if(tracking.type == 'CREATED' || tracking.type =='COMPLETED' || tracking.type == 'SYSTEM_CANCELLED' || tracking.type == 'DRIVER_NOT_FOUND')
{
object = 'Booking'
}else if(tracking.type == 'DRIVER_FOUND'){
object = 'Driver'
}
else if(tracking.type == 'PICKED_UP'){
object = 'Item'
}
return {
title : upperCase(startCase(tracking.type))+ ` - ${object} `+startCase(tracking.status),
is_cancelled : !!tracking.cancellation_reason,
cancellation_reason : message[1]+' - '+startCase(message[0]),
status : shipmentStatus,
status_color : statusColor
}
}
_renderShipmentTracking = (data)=>{
if(data.length > 0 ){
return (
<div className="row itenary ">
<ul>
{data.map((it,index)=>{
let shipment_track = this.getShipmentTrackingMessage(it.tracking);
return (
<li key={index}><span/>
<div>
<div className="title">{shipment_track.title}</div>
<div className="info">{moment(it.created_at).format('DD-MM-YYYY HH:mm')}</div>
{(shipment_track.is_cancelled) && <div className="info">{shipment_track.cancellation_reason}</div>}
<div className="type" style={{color: shipment_track.status_color}}>{shipment_track.status}</div>
</div>
</li>
)
})}
</ul>
</div>
)
}
else{
return <EmptyComponent width="" image="default4" type="empty" header="" content="No history of shipment yet!"/>
}
}
getOrderColor = (statusId) =>{
const {ORDER_STATUSES} = constant;
// {(this.order.selectedOrder.order_status.name === "Preorder Buyer Decline") ? 'status red' : (this.order.selectedOrder.order_status.name === 'Processing') ? 'status process' : 'status pending'}
if(statusId == ORDER_STATUSES.CANCELLED || statusId == ORDER_STATUSES.FAILED || statusId == ORDER_STATUSES.CANCELLED_BY_STORE || statusId == ORDER_STATUSES.PREORDER_BUYER_DECLINE){
return 'status red'
}
else if( statusId == ORDER_STATUSES.ON_SHIPPING_RETRY ||
statusId == ORDER_STATUSES.WAITING_STORE_RESPONSE || statusId == ORDER_STATUSES.PROCESSING ||
statusId == ORDER_STATUSES.ON_HOLD || statusId == ORDER_STATUSES.PREORDER_WAITING_STORE_RESPONSE|| statusId == ORDER_STATUSES.PENDING_PAYMENT || statusId == ORDER_STATUSES.PREORDER_WAITING_PAYMENT || statusId == ORDER_STATUSES.WAITING_PAYMENT_APPROVAL || statusId == ORDER_STATUSES.PREORDER_WAITING_BUYER_CONFIRMATION
) {
return 'status pending';
}
else if(statusId == ORDER_STATUSES.COMPLETED || statusId == ORDER_STATUSES.SHIPPING_COMPLETE
||statusId == ORDER_STATUSES.ON_SHIPPING ){
return 'status process'
}
}
orderStatusDesc = (statusId) =>{
const {ORDER_STATUSES} = constant;
if(statusId == ORDER_STATUSES.WAITING_PAYMENT_APPROVAL){
return 'Payment is still waiting for approval, please wait'
}
else if(statusId == ORDER_STATUSES.ON_SHIPPING){
return 'Order is on delivery to buyer'
}
else if(statusId == ORDER_STATUSES.ON_SHIPPING_RETRY){
return 'Something wrong in delivery process, please retry or rebook courier'
}
else if(statusId == ORDER_STATUSES.SHIPPING_COMPLETE){
return 'Buyer has accept the order and delivery is completed'
}
else if(statusId == ORDER_STATUSES.WAITING_STORE_RESPONSE){
return 'Order is waiting for you to response'
}
else if(statusId == ORDER_STATUSES.CANCELLED_BY_STORE){
return 'Order is cancelled by you'
}
else if(statusId == ORDER_STATUSES.PENDING_PAYMENT){
return 'Order is waiting buyer to complete the payment'
}
else if(statusId == ORDER_STATUSES.FAILED){
return 'Order is failed for some reason'
}
else if(statusId == ORDER_STATUSES.PROCESSING){
return 'Order is ready to processing'
}
else if(statusId == ORDER_STATUSES.COMPLETED){
return 'Order is completed'
}
else if(statusId == ORDER_STATUSES.ON_HOLD){
return 'Order is on hold'
}
else if(statusId == ORDER_STATUSES.CANCELLED){
return 'Order is cancelled'
}
else if(statusId == ORDER_STATUSES.PREORDER_WAITING_STORE_RESPONSE){
return 'Order is waiting for you to response'
}
else if(statusId == ORDER_STATUSES.PREORDER_WAITING_BUYER_CONFIRMATION){
return 'Order is waiting buyer to confirm the order'
}
else if(statusId == ORDER_STATUSES.PREORDER_BUYER_DECLINE){
return 'Order is decline by buyer'
}
else if(statusId == ORDER_STATUSES.PREORDER_WAITING_PAYMENT){
return 'Order is waiting buyer to complete the payment'
}
else {
return 'This status order to define flow of order';
}
}
render() {
const customer = {
name: 'Ridwan Abadi',
identity_number: '98261536156313561',
email: 'welove6215@einrot.com',
address: 'Jalan Pramuka No. 81, Marga Jaya, Bekasi Selatan, Marga Jaya, Bekasi Sel., Kota Bks, Jawa Barat 17141',
handphone: '081190876',
phone: '0',
place_birth: 'Jakarta',
birth_date: moment().format('DD MMM YYYY'),
gender: 'Male',
tax_id: '98261536156313561',
martial_status: 'Married'
}
const order = {
id: '467d6b50-ade0-4dd0-98ca-35cd083e16e0',
order_id: 'book_461a1df5',
package: 'The Exoticsm Of Minang',
description: 'Feel the joy of wonderful world of exotic, culture, and outstanding view that will amaze you to the bone. Enjoy your holiday in very nice and peaceful place to clear your mind. With great hotel and profesional tour guide, we ensure you that you will have a unforgetable memories and happiness.\n',
registered: moment(),
detail_package: [
{
name: 'Destination',
value: 'Bukittinggi, Minangkabau'
},
{
name: 'Transport',
value: 'Custom'
},
{
name: 'Duration',
value: '4 day 3 night'
}
],
payment_type: 'Instalment',
status: 'active'
}
const totalPaid = get(this.order.selectedOrder, 'payments', [])
.map(pay => (pay.type == 'cancel_payment') ? pay.amount = 0 : pay.amount)
.reduce((total, v) => total.add(v), new DC(0));
const priceAfterDisc = get(this.order.selectedOrder, 'price_after_discount', 0);
const disc = new DC(get(this.order.selectedOrder, 'price') || 0).minus(priceAfterDisc || 0);
const amountDue = new DC(priceAfterDisc || 0).minus(totalPaid);
// const amountDue = new DC(0);
const actionsModals = [
<FlatButton
label="Cancel"
primary={true}
onClick={this.handleCloseModal}
/>,
<FlatButton
label="Ok"
primary={true}
onClick={() => {
this.order.payAirlineTicket().then((airlineTicket) => {
this.order.setOrderStatus('ticketed');
this.globalUI.openSnackbar('Payment success');
});
}}
/>,
];
return (
<PrintProvider>
<NoPrint>
<div className="orderDetail containerMiddle animated fadeIn">
<Dialog
title="Are you sure that all data is correct?"
actions={actionsModals}
modal={true}
open={this.state.openModal}
>
You will be charged
</Dialog>
<div style={{marginBottom: '10px'}}>
<FlatButton
className="headerMenu"
hoverColor="#f1f5f9"
style={{background: '#ffffff00'}}
onClick={() => this.props.history.goBack()}
label="Back"
primary={true}
icon={<NavigationArrowBack/>}
/>
</div>
<MakePaymentDialog/>
<CancelPaymentDialog/>
<MerchantInputShippingCodeDialog/>
<GojekDelivery/>
<PreorderAddNotes defaultValue={this.state.itemData}/>
<div className="row">
<div className="col s12 m9 l9" style={{marginBottom: 0}}>
<Card className="cardLite cardDashboard row alert">
<CardHeader
title={
<Toolbar style={{backgroundColor: '#fff', padding: 0}}>
<ToolbarGroup>
<CardHeader
style={{padding: 0}}
subtitle={<p>{this.orderStatusDesc(this.order.selectedOrder.order_status_id)}</p>}
title={(this.order.selectedOrder.order_status === null) ? "No Status" : <div style={{
fontWeight: '500', fontSize: "1.25rem",
lineHeight: 1.2,
color: " #334152"
}}>
<span
className={this.getOrderColor(this.order.selectedOrder.order_status_id)}/> {(this.order.selectedOrder.order_status.name).split('Preorder')}
</div>}
/>
</ToolbarGroup>
<ToolbarGroup>
<RaisedButton label="Print" icon={<PrintIcon/>} primary={true} onClick={() => this.handlePrint()}/>
</ToolbarGroup>
<ToolbarGroup>
{this.order.selectedOrder.order_status_id === constant.ORDER_STATUSES.WAITING_STORE_RESPONSE &&
<RaisedButton label="Accept Order" primary={true} onClick={() => {
confirm('Are you sure want to accept this order').then(() => {
this.order.acceptOrder();
});
}}/>}
{this.order.selectedOrder.order_status_id === constant.ORDER_STATUSES.WAITING_STORE_RESPONSE &&
<RaisedButton label="Decline Order" primary={true} onClick={() => {
this.order.declineOrder();
}}/>}
{(this.order.selectedOrder.order_status_id === constant.ORDER_STATUSES.PROCESSING && (this.order.selectedOrder.shipping_method_id !== constant.SHIPPING_METHOD.GOJEK_SAME_DAY && this.order.selectedOrder.shipping_method_id !== constant.SHIPPING_METHOD.GOJEK_INSTANT)) &&
<RaisedButton label="Input Shipping Code" primary={true} onClick={() => {
this.props.appstate.globalUI.showDialog(DIALOG.ORDER.INPUT_SHIPPING_CODE);
}}/>}
{((this.order.selectedOrder.order_status_id === constant.ORDER_STATUSES.PROCESSING || this.order.selectedOrder.order_status_id === constant.ORDER_STATUSES.ON_SHIPPING_RETRY) && (this.order.selectedOrder.shipping_method_id === constant.SHIPPING_METHOD.GOJEK_SAME_DAY || this.order.selectedOrder.shipping_method_id === constant.SHIPPING_METHOD.GOJEK_INSTANT)) &&
<RaisedButton label="Booking Gojek" primary={true} onClick={() => {
this.calculatePrice()
}}/>}
</ToolbarGroup>
</Toolbar>
}
/>
</Card>
<Print main name=" foo">
<Card className="cardLite cardDashboard row">
<div className="flexSpaceBetween">
<div className="orderContainerHeader">
<CardTitle style={{padding: 0, fontSize: 20}}
titleStyle={{fontSize: 20, color: '#334152', margin: 0}}
title={<div className={'orderFormHeading'}>
<h3 style={{margin: 0}}>Order Details</h3>
<p className={'orderFormDate'}
style={{margin: 0}}>{moment(this.order.selectedOrder.created_at).format("DD MMMM YYYY, HH:mm:ss")}</p>
</div>}
/>
<div>
{/*<div className="orderFormLabel">Order #</div>*/}
<div className="orderFormLabelNumber">
<span style={{color : '#3E4B5B',fontWeight : 'bold'}}>Order #</span> <span>INV/{moment(this.order.selectedOrder.created_at).format("YYYYMMDD")}/XVII/{this.order.selectedOrder.id.split('-')[0]}</span></div>
</div>
<div>
<div className="orderFormLabelNumber">
<span style={{color : '#3E4B5B',fontWeight : 'bold'}}>Shipping By</span> : <span>{this.order.selectedOrder.shipping_method.name}</span></div>
</div>
</div>
<ToolbarGroup>
{
this.order.orderDetail.type === 'packages' && this.order.orderDetail.status !== 'canceled' && (
<RaisedButton icon={<AddIcon/>} label="Make Payment" primary={true}
onClick={() => this.globalUI.showDialog(DIALOG.ORDER.MAKE_PAYMENT)}/>)
}
{
this.order.orderDetail.type === 'packages' && this.order.orderDetail.status !== 'canceled' && (
<RaisedButton icon={<RemoveIcon/>} label="Cancel Booking" primary={false}
onClick={() => this.globalUI.showDialog(DIALOG.ORDER.CANCEL_PAYMENT)}/>)
}
{
this.order.orderDetail.type === 'airline' && this.order.orderDetail.status === 'booked' &&
(<RaisedButton icon={<AddIcon/>} label="Pay" primary={true}
onClick={() => this.handleOpenModal()}/>)
}
{
this.order.orderDetail.type === 'airline' && this.order.orderDetail.status === 'ticketed' &&
(<RaisedButton icon={<AddIcon/>} label="Print Ticket" primary={true}
onClick={() => this.globalUI.showDialog(DIALOG.ORDER.MAKE_PAYMENT)}/>)
}{
this.order.orderDetail.type === 'packages' && this.order.orderDetail.status === 'canceled' && (
<p>This order is already Cancelled</p>)
}
</ToolbarGroup>
</div>
<Divider/>
<CardHeader style={{paddingBottom: 0, paddingTop: 18, paddingLeft: 18, paddingRight: 18}}
subtitle={<h2 style={{fontSize: 12}}>CUSTOMER INFORMATION</h2>}/>
<CardText style={{paddingBottom: 0, padding: '8px 18px 0 18px'}}>
<div style={{
boxShadow: "none",
border: "1px solid #d4d4d4",
backgroundColor: "#f9f9f9",
padding: "10px 10px 10px 20px",
marginTop: 0,
marginBottom: 0,
textAlign: ''
}} className="card-panel">
<div className="row no-margin">
<div className="col s12 m12 l6">
<div className="listCustDetail">
<div className="listCustDetailItem flex">
<p className="listCustomerDetailItemKey">Name</p>
<p
className="listCustomerDetailItemValue">{(this.order.selectedOrder.user_orders.user.profile.firstname == null) ? 'empty first name' : this.order.selectedOrder.user_orders.user.profile.firstname} {(this.order.selectedOrder.user_orders.user.profile.lastname == null) ? 'empty last name' : this.order.selectedOrder.user_orders.user.profile.lastname}</p>
</div>
<div className="listCustDetailItem flex">
<span className="listCustomerDetailItemKey">Email</span>
<p
className="listCustomerDetailItemValue" style={{display:'flex',flexWrap: 'wrap'}}>{this.order.selectedOrder.user_orders.user.email}</p>
</div>
<div className="listCustDetailItem flex">
<p className="listCustomerDetailItemKey">Phone</p>
<p
className="listCustomerDetailItemValue">{(this.order.selectedOrder.user_orders.user.profile.phone == null) ? 'empty phone number' : this.order.selectedOrder.user_orders.user.profile.phone}</p>
</div>
<div className="listCustDetailItem flex">
<p className="listCustomerDetailItemKey">Gender</p>
<p className="listCustomerDetailItemValue">{(this.order.selectedOrder.user_orders.user.profile.gender == null) ? 'empty gender' : this.order.selectedOrder.user_orders.user.profile.gender }</p>
</div>
</div>
</div>
<div className="col s12 m12 l6">
<div className="listCustDetail">
<div className="listCustDetailItem flex">
<p className="listCustomerDetailItemKey">Receiver's Name</p>
<p
className="listCustomerDetailItemValue">{this.order.selectedOrder.user_address_buyer.receiver_name}</p>
</div>
<div className="listCustDetailItem flex">
<p className="listCustomerDetailItemKey">Name of Address</p>
<p
className="listCustomerDetailItemValue">{this.order.selectedOrder.user_address_buyer.name}</p>
</div>
<div className="listCustDetailItem flex">
<p className="listCustomerDetailItemKey">Phone of Address</p>
<p
className="listCustomerDetailItemValue">{this.order.selectedOrder.user_address_buyer.phone_number}</p>
</div>
<div className="listCustDetailItem flex">
<p className="listCustomerDetailItemKey">City</p>
<p
className="listCustomerDetailItemValue">{this.order.selectedOrder.user_address_buyer.city.name}</p>
</div>
<div className="listCustDetailItem flex">
<p className="listCustomerDetailItemKey">Province</p>
<p
className="listCustomerDetailItemValue">{this.order.selectedOrder.user_address_buyer.province.name}</p>
</div>
<div className="listCustDetailItem flex">
<p className="listCustomerDetailItemKey">Address</p>
<p
className="listCustomerDetailItemValue">{this.order.selectedOrder.user_address_buyer.address}</p>
</div>
</div>
</div>
</div>
</div>
</CardText>
<div className={' no-hover'} style={{marginTop: 18, marginBottom: 15}}>
<Table selectable={false} className="TableOrder">
<TableHeader displaySelectAll={false}
adjustForCheckbox={false}
enableSelectAll={false}>
<TableRow style={{height: 38, background: '#f6f9fc'}}>
<TableHeaderColumn className="TableHeaderColumnAkun"
style={{height: 'auto'}}>Items</TableHeaderColumn>
<TableHeaderColumn className="TableHeaderColumnAkun"
style={{height: 'auto'}}>Quantity Request</TableHeaderColumn>
<TableHeaderColumn className="TableHeaderColumnAkun align-center"
style={{height: 'auto'}}>Quantity</TableHeaderColumn>
<TableHeaderColumn className="TableHeaderColumnAkun align-right"
style={{height: 'auto'}}>Price</TableHeaderColumn>
<TableHeaderColumn className="TableHeaderColumnAkun"
style={{height: 'auto'}}>Subtotal</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody displayRowCheckbox={false}>
{
(this.order.selectedOrder.user_order_items) ?
this.order.selectedOrder.user_order_items.map((data, index) => (
<TableRow>
<TableRowColumn style={{whiteSpace : 'normal !important'}} key={data.id}>
{data.item.name}
<p style={{margin: '2px 0', fontSize: 10,}}>
Detail: <Link className={'viewDetailLink'}
style={{fontWeight: 'bold', textDecoration: 'underline'}}
to={`${LINKS.FORM_ITEMS}/edit/${data.item.id}`} target="_blank">View details</Link>
</p>
</TableRowColumn>
{data.is_preorder ?
<TableRowColumn key={data.id}>
{data.preorder_store_note ?
<p style={{margin: 0}}>{(data.preorder_buyer_note)} <span style={{
fontSize: '.72rem',
color: '#71c21a',
fontWeight: 'bold'
}} className={'smaller lighter'}>Responded</span></p> :
<p style={{margin: 0}}>{data.preorder_buyer_note}gr <span style={{
fontSize: '.72rem',
color: 'red',
fontWeight: 'bold'
}} className={'smaller lighter'}>Need Response</span>
</p>}
{data.preorder_buyer_note ?
<div>
<p style={{margin: '2px 0', fontSize: 10}}>
Detail: <a className={'viewDetailLink'} style={{
cursor: 'pointer',
fontWeight: 'bold',
textDecoration: 'underline'
}}
onClick={() => this.openPreorderDialog(data)}>View notes</a>
</p></div> : <div>-</div>}</TableRowColumn>
:
<TableRowColumn key={data.id}>-</TableRowColumn>
}
<TableRowColumn key={data.id}
className={'align-center'}>{data.quantity !== 0 ? data.quantity + "pcs" :
<NumberFormat value={data.preorder_weight} displayType={'text'}
suffix={'gr'}/>}</TableRowColumn>
<TableRowColumn className="align-right"><NumberFormat value={data.price}
displayType={'text'}
thousandSeparator={true}
prefix={'Rp '}/></TableRowColumn>
<TableRowColumn><NumberFormat value={data.subtotal} displayType={'text'}
thousandSeparator={true} prefix={'Rp '}/></TableRowColumn>
</TableRow>
)) : <EmptyComponent type="empty" header="" content="There is no data in sight"/>
}
<TableRow displayBorder={false} className="TableRowCondensed TableRowCondensedFirst">
<TableRowColumn colSpan={3} className="TableRowColumnCondensed TableRowColumnCondensedFirst"/>
<TableRowColumn
className="align-right font-500 TableRowColumnCondensed TableRowColumnCondensedFirst">Subtotal</TableRowColumn>
<TableRowColumn className="TableRowColumnCondensed TableRowColumnCondensedFirst"><NumberFormat
value={this.order.selectedOrder.subtotal} displayType={'text'} thousandSeparator={true}
prefix={'Rp '}/></TableRowColumn>
</TableRow>
<TableRow displayBorder={false} className="TableRowCondensed">
<TableRowColumn colSpan={3} className="TableRowColumnCondensed"/>
<TableRowColumn className="align-right font-500 TableRowColumnCondensed">Discount</TableRowColumn>
<TableRowColumn className="TableRowColumnCondensed"><NumberFormat value={0.00}
displayType={'text'}
thousandSeparator={true}
prefix={'Rp '}/></TableRowColumn>
</TableRow>
<TableRow displayBorder={false} className="TableRowCondensed">
<TableRowColumn colSpan={3} className="TableRowColumnCondensed"/>
<TableRowColumn className="align-right font-500 TableRowColumnCondensed">Shipping
Fee</TableRowColumn>
<TableRowColumn className="TableRowColumnCondensed"><NumberFormat
value={this.order.selectedOrder.shipping_price} displayType={'text'} thousandSeparator={true}
prefix={'Rp '}/></TableRowColumn>
</TableRow>
<TableRow displayBorder={false} className="TableRowCondensed">
<TableRowColumn colSpan={3} className="TableRowColumnCondensed"/>
<TableRowColumn className="align-right font-500 TableRowColumnCondensed">Total</TableRowColumn>
<TableRowColumn className="TableRowColumnCondensed "><NumberFormat
value={(+this.order.selectedOrder.shipping_price) + (+this.order.selectedOrder.subtotal)}
displayType={'text'} thousandSeparator={true} prefix={'Rp '}/>.00</TableRowColumn>
</TableRow>
</TableBody>
</Table>
</div>
</Card>
</Print>
<Card className="cardLite cardDashboard" style={{marginBottom: 20}}>
<CardHeader
title={
<Toolbar className="toolbarCard" style={{backgroundColor: '#fff'}}>
<ToolbarGroup>
<CardHeader
title="Send Service Information"
subtitle="Tracking shipping information"
avatar={<Icon type="car" style={{fontSize: 25, color: '#555'}}/>}
style={{marginLeft: -25}}
/>
</ToolbarGroup>
</Toolbar>
}
actAsExpander={true}
showExpandableButton={true}
/>
<Divider/>
<CardText className="" expandable={true}>
<div className="">
<div className="header-text-mini" style={{fontSize: '1.23em', marginBottom: '20px'}}>{this.order.selectedOrder.shipping_method.name} <a>{this.order.selectedOrder.courier_booking_id}</a>
</div>
{console.log(get(this.order.selectedOrder,'response_courier', 'kosong'), "get(this.order.selectedOrder,'response_courier', 'kosong') get(this.order.selectedOrder,'response_courier', 'kosong')")}
{!!get(this.order.selectedOrder,'response_courier.total_distance_in_kms',false) &&
<Card style={{marginBottom : '20px',padding:'20px'}}>
{/*{get(this.order.selectedOrder,'response_courier.driver_name',false) && <CardHeader*/}
{/*title={`${this.order.selectedOrder.response_courier.driver_name} - Driver`}*/}
{/*subtitle={this.order.selectedOrder.response_courier.driver_phone}*/}
{/*avatar={this.order.selectedOrder.response_courier.driver_photo_url}*/}
{/*/>}*/}
<CardHeader
title={'Courier Information'}
/>
<div style={{display: 'flex', flexDirection: 'row', justifyContent: 'space-around', marginTop: 15}}>
<div>
<Avatar
src={this.order.selectedOrder.response_courier.driver_photo_url}
size={120}
/>
</div>
<div>
<ListItem
disabled={true}
leftAvatar={
<Avatar backgroundColor={'#6772e5'} icon={<Icon type="user" />} />
}
style={{}}
>
{get(this.order, 'selectedOrder.response_courier.driver_name', 'John Doe')}
</ListItem>
<ListItem
disabled={true}
leftAvatar={
<Avatar backgroundColor={'#6772e5'} icon={<Icon type="phone" />} />
}
style={{}}
>
{get(this.order, 'selectedOrder.response_courier.driver_phone', '08888xxxxx')}
</ListItem>
<ListItem
disabled={true}
leftAvatar={
<Avatar backgroundColor={'#6772e5'} icon={<Icon type="environment-o" />} />
}
style={{}}
>
<a href={get(this.order, 'selectedOrder.response_courier.live_tracking_url', '#')} target="_blank">{get(this.order, 'selectedOrder.response_courier.live_tracking_url', 'No URL')}</a>
</ListItem>
</div>
<div style={{
width: 1,
height: 160,
backgroundColor: '#ccc'
}}></div>
<div>
<p style={{textAlign: 'center', fontSize: 20}}>Price ({get(this.order, 'selectedOrder.response_courier.total_distance_in_kms', 0).toFixed(2)} KM)</p>
<p style={{textAlign: 'center', color: '#6772e5', fontSize: 25}}><NumberFormat value={get(this.order, 'selectedOrder.response_courier.price', 0)} displayType={'text'} thousandSeparator={true} prefix={'Rp '}/></p>
</div>
</div>
{/*<div className="title">Price : <NumberFormat value={this.order.selectedOrder.response_courier.price} displayType={'text'} thousandSeparator={true} prefix={'Rp '}/></div> */}
{/*<div className="title">Total Distance : {this.order.selectedOrder.response_courier.total_distance_in_kms.toFixed(2)} KM</div> */}
{/*<div className="title">Driver : {get(this.order.selectedOrder,'response_courier.driver_name','-')}</div> */}
{/*<div className="title">No. Handphone : {get(this.order.selectedOrder,'response_courier.driver_phone','-')}</div> */}
</Card>
}
<div className="itenaryBody" style={{marginLeft: -20}}>
{this._renderShipmentTracking(this.order.selectedOrder.tracking)}
</div>
</div>
</CardText>
</Card>
</div>
<div className="col s12 m3 l3" style={{marginBottom: 0}}>
<section className='row element-wrapper'>
<Card className="cardLite cardDashboard padding">
{/*<Affix style={{position: 'sticky', top: 1}} offsetTop={80}/>*/}
<div className='element-header'>
<h3>Activities</h3>
</div>
{this.order.selectedOrder.histories.length > 0 ?
uniqBy(this.order.selectedOrder.histories,'order_status_id').map(it=>(
<div className="timed-activities compact">
<div className="timed-activity">
<div className="ta-date">
<span>{moment(it.created_at).format("DD MMMM YYYY")}</span></div>
<div className="ta-record-w">
<div className="ta-record">
<div className="ta-timestamp"><Icon className="ta-timestamp-icon"
type="right"/><strong>{moment(it.created_at).format("HH:mm:ss")}</strong>
</div>
<div className="ta-activity">
{this.orderHistoryText(it)}
</div>
</div>
{/*<div className="ta-record">*/}
{/*<div className="ta-timestamp"><strong>2:34</strong> pm</div>*/}
{/*<div className="ta-activity">Commented on story <a*/}
{/*href="users_profile_small.html#">How to be a leader</a> in*/}
{/*<a href="users_profile_small.html#">Financial</a> category*/}
{/*</div>*/}
{/*</div>*/}
{/*<div className="ta-record">*/}
{/*<div className="ta-timestamp"><strong>7:12</strong> pm</div>*/}
{/*<div className="ta-activity">Added <a href="users_profile_small.html#">John*/}
{/*Silver</a> as a friend*/}
{/*</div>*/}
{/*</div>*/}
</div>
</div>
</div>
)) :
<div className="timed-activities compact">
<div className="timed-activity">
<div className="ta-date">
<span>{moment(this.order.selectedOrder.created_at).format("DD MMMM YYYY")}</span></div>
<div className="ta-record-w">
<div className="ta-record">
<div className="ta-timestamp"><Icon className="ta-timestamp-icon"
type="right"/><strong>{moment(this.order.selectedOrder.created_at).format("HH:mm:ss")}</strong>
</div>
<div className="ta-activity">
{this.orderHistoryText({status:this.order.selectedOrder.order_status,order_status_id:this.order.selectedOrder.order_status_id})}
</div>
</div>
</div>
</div>
</div>
}
</Card>
</section>
</div>
</div>
<Dialog
style={
{
margin: 'auto'
}
}
open={this.globalUI.loadingVisibility
}>
<div
style={
{
textAlign: 'center'
}
}>
<LoadingDialog/>
</div>
</Dialog>
<Dialog
title="Error"
style={{margin: 'auto'}}
actions={[<FlatButton primary={false} label="Ok" onClick={this.closeError}/>]}
open={this.state.errorBook}>
{this.state.errorMessage}
</Dialog>
</div>
</NoPrint>
</PrintProvider>
)
}
}

View File

@@ -0,0 +1,378 @@
import React from 'react';
import {observer, inject} from 'mobx-react';
import bind from 'bind-decorator';
import {
Card,
CardActions,
CardHeader,
CardMedia,
CardTitle,
AutoComplete,
CardText,
FlatButton,
List,
ListItem,
Divider,
Snackbar,
Tabs, Tab,
RaisedButton,
Toolbar,
DatePicker,
FontIcon,
Table,
TableBody,
TableHeader,
TableHeaderColumn,
TableRow,
SelectField,
TableRowColumn,
MenuItem,
Toggle,
ToolbarGroup,
FloatingActionButton,
ToolbarSeparator,
IconButton,
ToolbarTitle,
RadioButton,
TextField,
Paper,
RadioButtonGroup
} from 'material-ui';
import {Row, Icon, Button, notification, Table as TableAntd, Tooltip as TooltipAntd} from 'antd';
import {yellow500} from 'material-ui/styles/colors';
import StarBorder from 'material-ui/svg-icons/toggle/star-border';
import SwipeableViews from 'react-swipeable-views';
import SearchIcon from 'material-ui/svg-icons/action/search';
import DC from 'decimal.js-light';
import {Link} from 'react-router-dom';
import {LINKS} from "../../routes";
import './style.scss';
import {appConfig} from "../../config/app";
import NumberFormat from 'react-number-format';
import LoadingDialog from "../LoadingDialog";
import Loader from 'react-loader-advanced';
import {constant} from "../../config/const";
const {Column, ColumnGroup} = Table;
@inject('appstate')
@observer
export default class OrderComponent extends React.Component {
constructor(props) {
super(props);
this.props = props;
this.orderStore = props.appstate.order;
this.state = {
expanded: false,
value: 1,
snackbarOpen: false,
snackbarMessage: '',
filteredInfo: null,
searchText: '',
filter : 'active',
sortedInfo: null,
filtered: false,
data: []
};
this.defaultState = Object.assign({}, this.state);
this.http = props.appstate.http;
this.authStore = props.appstate.auth;
this.globalUI = props.appstate.globalUI;
}
componentDidMount() {
this.orderStore.isSearching = false;
this.globalUI.openLoading();
this.orderStore.getAllOrder().then(res => {
console.log(res)
this.globalUI.closeLoading();
});
}
componentWillUnmount() {
this
.globalUI
.changeBackgroundColor("#fff");
}
onInputChange = (e) => {
this.setState({searchText: e.target.value});
}
search = (event) => {
console.log("dataSearch", event.target.value);
if (event.target.value.length === 0) {
this.orderStore.isSearching = false;
}
else {
this.orderStore.isSearching = true;
this.orderStore.search(event.target.value);
}
}
handleExpandChange = (expanded) => {
this.setState({expanded: expanded});
};
handleClickItem = (key) => {
if (key === this.state.expanded) {
this.setState({
expanded: 'x!0-2#',
})
}
else {
this.setState({
expanded: key,
})
}
};
handleChangeSorter = (pagination, filters, sorter) => {
console.log('Various parameters', pagination, filters, sorter);
this.setState({
filteredInfo: filters,
sortedInfo: sorter,
});
};
clearFilters = () => {
this.setState({filteredInfo: null});
};
clearAll = () => {
this.setState({
filteredInfo: null,
sortedInfo: null,
});
};
handleAccept = (task) => {
this.setState({
expanded: 'x!0-2#',
snackbarMessage: task + ' Accepted',
snackbarOpen: true,
})
};
handleDecline = (task) => {
this.setState({
expanded: 'x!0-2#',
snackbarMessage: task + ' Declined',
snackbarOpen: true,
})
};
handleClose = () => {
this.setState({
snackbarOpen: false
})
};
setCustomerSort = () => {
this.setState({
sortedInfo: {
order: 'descend',
columnKey: ['user_orders.user.email'],
},
});
};
filterOrder =(it)=>{
if(this.orderStore.filterBy === 'active'){
return it.order_status_id == constant.ORDER_STATUSES.PREORDER_WAITING_STORE_RESPONSE || it.order_status_id == constant.ORDER_STATUSES.PROCESSING || it.order_status_id == constant.ORDER_STATUSES.ON_SHIPPING_RETRY;
}
else if(this.orderStore.filterBy === 'completed'){
return it.order_status_id === constant.ORDER_STATUSES.COMPLETED || it.order_status_id === constant.ORDER_STATUSES.SHIPPING_COMPLETE
}
else{
return true
}
}
getOrderColor = (statusId) =>{
const {ORDER_STATUSES} = constant;
// {(this.order.selectedOrder.order_status.name === "Preorder Buyer Decline") ? 'status red' : (this.order.selectedOrder.order_status.name === 'Processing') ? 'status process' : 'status pending'}
if(statusId == ORDER_STATUSES.CANCELLED || statusId == ORDER_STATUSES.FAILED || statusId == ORDER_STATUSES.CANCELLED_BY_STORE || statusId == ORDER_STATUSES.PREORDER_BUYER_DECLINE){
return 'status red'
}
else if( statusId == ORDER_STATUSES.ON_SHIPPING_RETRY ||
statusId == ORDER_STATUSES.WAITING_STORE_RESPONSE || statusId == ORDER_STATUSES.PROCESSING ||
statusId == ORDER_STATUSES.ON_HOLD || statusId == ORDER_STATUSES.PREORDER_WAITING_STORE_RESPONSE|| statusId == ORDER_STATUSES.PENDING_PAYMENT || statusId == ORDER_STATUSES.PREORDER_WAITING_PAYMENT || statusId == ORDER_STATUSES.WAITING_PAYMENT_APPROVAL || statusId == ORDER_STATUSES.PREORDER_WAITING_BUYER_CONFIRMATION
) {
return 'status pending';
}
else if(statusId == ORDER_STATUSES.COMPLETED || statusId == ORDER_STATUSES.SHIPPING_COMPLETE
||statusId == ORDER_STATUSES.ON_SHIPPING ){
return 'status process'
}
}
handleChange = (event, index, value) => this.setState({value});
render() {
let {sortedInfo, filteredInfo} = this.state;
sortedInfo = sortedInfo || {};
filteredInfo = filteredInfo || {};
const columns = [{
title: 'Id',
dataIndex: 'this.orderStore.orderList.id',
key: 'this.orderStore.orderList.id',
className: 'recentOrder-noOrder',
render: (text, data) => <Link to={`${LINKS.ORDER}/${data.id}`}
key={data.order_id}>{<span>{(data.id.split("-")[0])}</span>}</Link>,
},
{
title: 'Date',
dataIndex: 'created_at',
key: 'created_at',
className: 'recentOrder-noOrder',
render: (text) => (
<div>
<span>{moment(text).format('MMM DD, YYYY')}</span> <span className='smaller lighter'>{moment(text).format('hh:mm')}</span>
</div>
)
},
{
title: 'Customer',
dataIndex: 'user_orders.user.profile',
key: 'user_orders.user.profile',
className: 'recentOrder-noOrder',
sorter: (a, b) => (a.user_orders.user.profile && a.user_orders.user.profile.firstname) - (b.user_orders.user.profile && b.user_orders.user.profile.firstname),
sortOrder: sortedInfo.columnKey === 'user_orders.user.profile.firstname' && sortedInfo.order,
render: (text, data) => {
if(data.user_orders && data.user_orders.user && data.user_orders.user.profile && data.user_orders.user.profile.firstname) {
return (<span>{data.user_orders.user.profile.firstname+' '+data.user_orders.user.profile.lastname}</span>);
}
return <span>{data.user_orders.user.email}</span>
}
},
{
title: 'Type',
dataIndex: 'is_preorder',
key: 'is_preorder',
className: 'recentOrder-noOrder',
render: (text, data) => (data.is_preorder === true) ? "Pre Order" : <span>Order</span>
},
{
title: 'Status',
dataIndex: 'this.orderStore.orderList.order_status.name',
key: 'this.orderStore.orderList.order_status.name',
className: 'recentOrder-status',
render: (text, data) =>
(data.order_status === null) ? "No Status" : <div><span
className={this.getOrderColor(data.order_status_id)}/><span>{(data.order_status.name).split('Preorder')}</span>
</div>
},
{
title: 'Total',
dataIndex: 'this.orderStore.orderList.subtotal',
key: 'this.orderStore.orderList.subtotal',
className: 'recentOrder-customer bolder green',
render: (text, data, value) => {
return <NumberFormat
style={{color: ((data.order_status.name) === 'Preorder Buyer Decline') ? 'red' : '#000'}}
value={new DC(data.subtotal).add(data.shipping_price).toNumber()} displayType={'text'}
thousandSeparator={true} prefix={'Rp. '}/>
}
}];
/*() => {
(this.orderStore.orderList.length > 0) ? (this.orderStore.isSearching ? this.orderStore.dataFiltered : this.orderStore.orderList).map((item, index) => (
)) : <EmptyComponent type="empty" header="" content="There is no data in sight"/>
};*/
return (
<div className="order containerMiddle">
<div className="row">
<div className="col l12 m12 s12">
<div style={{marginBottom: '16px'}}>
<h3 className="headerMenu">Order</h3>
</div>
<Card className="animated fadeIn no-shadow" style={{backgroundColor: 'transparent'}}>
<Toolbar className="toolbarCard" style={{backgroundColor: '#fff'}}>
<ToolbarGroup>
<SearchIcon style={{marginRight: 8, color: "#999"}}/>
<TextField
hintText="Search Order ID"
style={{fontSize: 14}}
hintStyle={{fontSize: 14}}
underlineShow={false}
onChange={this.search}
/>
</ToolbarGroup>
</Toolbar>
<Divider/>
<div className="row">
<div className="col l12 m12 s12">
<SelectField
floatingLabelText="Filter"
value={this.orderStore.filterBy}
onChange={(e,i,v)=>this.orderStore.changeFilterBy(v)}
floatingLabelStyle={{color : '#6772e5'}}
underlineStyle={{border:0}}
>
<MenuItem value={'active'} primaryText="Only Active Order" />
<MenuItem value={'completed'} primaryText="Completed" />
<MenuItem value={'all'} primaryText="All Order" />
</SelectField>
</div>
</div>
<Loader show={this.globalUI.loadingVisibility} message={<LoadingDialog/>}
messageStyle={{textAlign: 'center'}}
backgroundStyle={{backgroundColor: 'rgba(255,255,255,0.5)'}}>
<TableAntd
pagination={true}
className='table-padded'
dataSource={this.orderStore.isSearching ? this.orderStore.dataFiltered : this.orderStore.orderList.filter(this.filterOrder)}
onChange={this.handleChangeSorter}
columns={columns}
onRow={(record) => {
return {
onClick: () => {
this.props.history.push(`${LINKS.ORDER}/${record.id}`);
}, // click row
};
}}
/>
</Loader>
</Card>
<Snackbar
open={this.state.snackbarOpen}
message={this.state.snackbarMessage}
action="OK"
autoHideDuration={4000}
onActionClick={this.handleClose}
onRequestClose={this.handleClose}
/>
</div>
</div>
</div>
)
}
}

View File

@@ -0,0 +1,39 @@
.order {
margin-top: 35px;
}
.viewDetailLink {
font-weight: bold;
text-decoration: underline !important;
}
.orderDetail {
margin-top: 35px;
.orderContainerHeader{
padding: 18px;
}
.orderFormHeading {
margin-bottom: 4rem;
position: relative;
z-index: 2;
}
.orderFormDate {
font-size: .9rem;
font-weight: 400;
line-height: 1.5;
color: #3E4B5B;
text-align: left;
}
.orderFormLabel {
font-size: 18px;
font-weight: 500;
line-height: 1.5;
color: #3E4B5B;
}
.orderFormLabelNumber {
font-size: 16px;
color: #636c72 !important;
}
}