\r\n
\r\n
\r\n \r\n {process.env.REACT_APP_NAME}\r\n \r\n
\r\n \r\n
\r\n \r\n
Billing QR Scanner \r\n
\r\n
\r\n
\r\n \r\n {\r\n Object.entries(qrData).length ? \r\n
\r\n {\r\n qrData.status === 2 ? \r\n เอกสารเลขที่ {qrData.documentNumber} เอกสารนี้ทำซ้ำ หรือ มีการวางเอกสารเรียบร้อยแล้ว\r\n กรุณาตรวจสอบเลขที่เอกสาร หรือ ติดต่อกลับบริษัทของท่าน :\r\n เอกสารเลขที่ {qrData.documentNumber} ทำการส่งเอกสารเรียบร้อยแล้ว \r\n }\r\n \r\n \r\n
Document Number:
\r\n
{qrData.documentNumber}
\r\n
\r\n \r\n
Billing Date:
\r\n
{qrData.billingDate}
\r\n
\r\n \r\n \r\n ข้อมูล Vendor \r\n \r\n
ชื่อบริษัท
\r\n
{qrData.vendorName}
\r\n
\r\n \r\n
ที่อยู่
\r\n
{qrData.vendorAddress}
\r\n
\r\n \r\n \r\n ข้อมูลบริษัท \r\n \r\n
ชื่อบริษัท
\r\n
{qrData.companyName}
\r\n
\r\n \r\n
ที่อยู่
\r\n
{qrData.companyAddress}
\r\n
\r\n \r\n :\r\n
กรุณาสแกน QR CODE เพื่อนำส่งเอกสารสำหรับวางบิล \r\n }\r\n
\r\n \r\n
\r\n \r\n )\r\n}\r\n\r\nconst mapStateToProps = (state) => ({\r\n qrData: state.qr.qrData\r\n})\r\n\r\nconst mapDispatchToProps = { \r\n submitQrCode,\r\n clearQrData,\r\n}\r\n\r\nQRScanner.propTypes = {}\r\n\r\nQRScanner.defaultProps = {}\r\n\r\nconst QRForm = reduxForm({\r\n form: 'formQR',\r\n})(QRScanner)\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(QRForm)","export default \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPAAAADwCAYAAAA+VemSAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAP9klEQVR42u3dT0wbVx4H8PHEA5I1QcWma2MJC1di6wPE1hIFI1lslEQULtuSbpFSeuBoc2JXe84BzsGVosh7zcFK2bSqolw42PxbqgSzLOCGiC4qJjWYPxvjSkNaOYPFHuLstmmateHNvPnZ34/0vUUzzw++GTN+fmMSDG5zc7N5ZWXFt7a29tv19fV30+m0K5PJOHK5nDWbzTaoqlpzdHTEe5hAkNlsFiRJem6z2Z7W19cfOJ3O3aampu9aWlq+8Xg8//J6vcvNzc2bvMf5JibeA3jVysqKLxaLXZmdnf393NycP5vNNvAeE1Qvm832NBAIPOzq6pq5fPlyzOfzLfMek6EUCgVxdna2KxQK3XS5XGlBEI4RxKhxuVzbQ0NDt6anp7sKhYKoXTMMLp1OO0dHR6+73e5UKROHIEaL2+1OjYyMXE+n004tOmJIS0tLvoGBgagkSaoek4wgWkeSJHVgYCC6tLTkY90Xw0gmk+d6enrumUwm7hOOIFrEZDIdd3d330smk+dYdoer7e1tx+Dg4G1RFAu8JxhB9IgoioXBwcHbpN9aq6oqhsPh4bq6OoX3hCIIj9TV1SnhcHhYVVVaN7tWV1c9fr9/nvcEIogR4vf75x8/fuw5ba90EYlEghaL5RnvSUMQI8VisTyLRCLB07VLQ4qiyNeuXbvDe6IQxMjp7++/oyiKfPKmaWBjY6O5ra1thffkIAiFeL3elVQq1XzCurGVSCTO2+32Hd6TgiCU8vbbb+8sLCycP1nrGJmamrokyzLuMiPICSLLsjI5OXnlJN07tXg83m2xWH7kPQkIQjkWi+XHWCzWXX4DT2FqauoSyosg7Eo8NTV1qdwensjCwsJ5vG1GELaRZVlJJBLa/k28sbHhwg0rBNEmdrt9R7O704qiyF6vFx8VIYiG8Xq9K+V8Tnym1H+4ubl5OxaLXS713wNA+fb29uzffvvtO6urq1+U8u9L2lInEokEQ6FQhOcLk2X5h46Ojoft7e3/bG1t/drtdm80NjZmrFbroSRJ3589e/Y5z/EBLYqi1Kiq+tbBwYG8s7PjTKVS7zx69KhtcXHxd/Pz8/7Dw0MLz/FFIpFQKBT666kPtLq66uG1ttnhcOwFg8Gb8Xj8Uj6fr+E5oVA98vl8TTwevxQMBm86HI49gcPvvsVieXbqL0Coqiry+FZRIBD4anx8/Go+nzfz/mFCdcvn8+bx8fGrgUDgK0HnHvj9/vlTfRUxHA4P6zzgB/F4/CLvHxrA68Tj8Yt+v/+BoGMnxsbGhk802K2tLYdeX8a32+170Wj0E94/IIBSRKPRT+x2uy5vrevq6pQT7ewxODh4W48B9vX1fbm/v4+9n4GU/f39hr6+vi8FHTpS7GLpksnkOa33sDKbzWrxLToAWeFweNhsNmu6w6ooioWyNsrr7u6+p+WAZFlWJiYmenhPPgALExMTPVovL+7t7b1X0mCSyaRPy61frVZrLpFIXOA96QAsJRKJC1arNSdo1BuTyXRc0r7TH3/8cVSrQRQXbKO8UJESicQFLa/EAwMD0TcOYGtry6nVExPMZrOKt81Q6SYmJnq0+ptYkiR1a2vr1+9Ij46OXtfixIIgHOOGFVQLLddPjIyMXH/tSQuFgqjVg8aKt9sBqoZWHzG53e7Ua5+KODMz06XFCe12+x4+54Vqs7+/36DVYo/p6emuX5wwFArd1OJkWGEF1ar4u8+8U0NDQ7d+cTItHq7d2dn5gPckAvCkxdrpYlf/Z3l52cf6JIIgHOOLCVDtYrHYRUGDbhU7+8KNGzf+zPoEgUDg77wnD8AIil1g2q8bN2785b8neP/99++zPsH4+PgfeU8cgBF8/vnnVwXG/Sp29gWbzfZvlgd3OBx7+DI+wAv5fN7MemePYmcF8cmTJ83ZbJbpxzxXr179W21t7RGjwzH/+4FTeL1e1ufFz61MtbW1Rx988MHfWBzrpWw22/DkyZNmcXl5ufSvKZXoww8/xMINgJ/46KOPmHdieXn5nLi2tsb0yeGyLP8QCATm9JsaAOMLBAJzsiz/wPKYa2trHnF9ff1dlgft6Oh4WFtbiy1eAX6itrb2eUdHx0OWx1xfX39XTKfTLpYHbW9v/6e+UwNAA+tupNNpl5jJZBwsD9ra2vq1vtMCQAPrbmQyGYfI+g602+3e0HdaAGhg3Y1sNtsg5nI5K8uDNjY2ZvSdFgAanE4n027kcjmrqKoq00eWWK3WQ32nBYCG+vp6pt1QVbVGPDpitd7iBUmSvtd1VgCIYN2No6MjwSQwWm3yEyU98bAMpY6P9XmNPj7W5zX68Vgz+s+tJCd/cBIAcIcCAxCGAgMQhgIDEIYCAxCGAgMQhgIDEIYCAxCGAgMQVo0bz2GFEE2Yl9fAFRiAMBQYgDAUGIAwFBiAMBQYgDAUGIAwFBiAMBQYgDAUGICwalyJVSkrdYy+lxlrRh8fF7gCAxCGAgMQhgIDEIYCAxCGAgMQhgIDEIYCAxCGAgMQhgIDEFZJK7FYr0zipdqeJlgpPzcucAUGIAwFBiAMBQYgDAUGIAwFBiAMBQYgDAUGIAwFBiAMBQYgzCRU395KvODpesZSESvPcAUGIAwFBiAMBQYgDAUGIAwFBiAMBQYgDAUGIAwFBiAMBQYgjMKeWEZfKcZ6fLz2iGK9d1alnNfQcAUGIAwFBiAMBQYgDAUGIAwFBiAMBQYgDAUGIAwFBiAMBQYgrBr3xKqIvZDgV1XV0xhxBQYgDAUGIAwFBiAMBQYgDAUGIAwFBiAMBQYgDAUGIAwFBiCsGvfEMjqjryQqFevxlXo8o88LU7gCAxCGAgMQhgIDEIYCAxCGAgMQhgIDEIYCAxCGAgMQhgIDEEZhJVapeD3lrlJW/hh9xRtWbL0GrsAAhKHAAIShwACEocAAhKHAAIShwACEocAAhKHAAIShwACEUViJxXoljNGPx2svKUM/hU8Dhl5hVSpcgQEIQ4EBCEOBAQhDgQEIQ4EBCEOBAQhDgQEIQ4EBCEOBAQijsBLL6Ct6SmX0lT+s55nXSjGjr1BjCldgAMJQYADCUGAAwlBgAMJQYADCUGAAwlBgAMJQYADCUGAAwiisxCoVrxUzRl/BxFql7ClWEXAFBiAMBQYgDAUGIAwFBiAMBQYgDAUGIAwFBiAMBQYgDAUGIKySVmKVyuh7IRl9JZHRn55o9JVsTOEKDEAYCgxAGAoMQBgKDEAYCgxAGAoMQBgKDEAYCgxAGAoMQFg1rsQy9NPmCLzeUlcwsV7pxGvvMUPDFRiAMBQYgDAUGIAwFBiAMBQYgDAUGIAwFBiAMBQYgDAUGIAw5gVWFKWG02s55hReTCWG1+sodXxVMy+su2EymQTRbGa7mlJV1beYHhCgQrDuxpkzZwRRkqTnLA96cHAg6zstADTkcjmm3ZAk6blYX19/wPKgOzs7Tn2nBYCGTCbDtBv19fUHos1me8ryoKlU6h19pwWABtbdsNlsT0Wn07nL8qCPHj1q03daAGhg3Q2n07krNjU1fcfyoIuLi7/Td1oAaGDdjaampu/MLS0t37A86Pz8vD+fz9fU1tYyvTkGQFk+n6+x2Wx+lsdsaWn5RvR4PGssD3p4eGiZm5sL6Ds9AMY2NzcXODw8tLA8psfjWRN9Pl+S9WC/+OKLPv2mBsD47t69y7wT/+2uzWb7t8BwdZLD4djL5/PVuN8WwC/k83mzw+HYExh2rNjZF0spA4HAQ5YD3t3d/c39+/f/wHviAIzg/v37f9jd3f0Ny2O+7KwoCILQ1dU1w3rQn3766Z/0mR4AY9OiCz/r7PLysk/QYKF/LBa7yHvyAHgqdoB5t4qd/R+Xy5VmfZLOzs4HvCcQgCe/3/9AYNyrYld/bmho6BbrEwmCcByNRj/hPYkAPBR/95l3qtjVn5uZmenS4mR2u31vf3+/gfdkAuhpf3+/wW63M73z/DLT09NdvzhhoVAQ3W53SosT9vX1fcl7QgH0VPydZ94lt9udKhQKr9+IY3R09LoWJxUE4TgcDg/znlQAPRR/1zXp0cjIyPVfPfHW1pZTkiRVixObzWZ1YmKih/fkAmhpYmKix2w2a9IhSZLUra2tN3+neGBgIKrFyQVBOJZlWUkkEhd4TzKAFubn5y/IsqwIGvWn2M03SyaTPpPJpMkABEE4tlqtOZQYKk0ikbhgtVpzgka9MZlMx0tLS76SBtPd3X1Pq4EIxSsx3k5DpZiYmOjR8sorCMJxb2/vvZIHlEwmz4miWNByQGazWcWNLaAuHA4Pa/U378uIolhIJpPnyhrY4ODgbS0H9TJ9fX1f4nNioGZ/f79Bq4+KXk2xi+XZ3t521tXVafq24GXsdvseVmwBFdFo9BOtFmm8mrq6OiWdTp9sN8uxsTHNPs96XTo7Ox/E4/GLvH9AAK8Tj8cvFtf369aJYgdPRlVV0e/3z+s5YEEQjgOBwFefffbZVWwKALzl83nz3bt3rwYCga8EnXvg9/vnVVU93eOPVldXPRaL5ZnegxeEFzt7BIPBm/F4/FI+n+f1zCWoMvl8viYej18KBoM3We+kUWosFsuzx48fe/7fWEt6uFQkEgmGQqEIz0mVZfmHjo6Oh+3t7f9obW392u12bzY2NmasVuuhJEnfnz17FrtgQskURalRVfWtg4MDeWdnx5lKpZofPXrUtri4eH5+ft7PegO6ckUikVAoFPorswNeu3btjsDhfyIEqbb09/ffKbWXJVMURW5ra1vh/eIQpJLj9XpXFEXR5gGBGxsbLrvdvsP7RSJIJcZut++kUqnmMipZvoWFhfNaLxtDkGpL8Ys+58tr4wlNTk5eslgsP/J+0QhSCbFYLD9OTk5eKbeHpxKPx7tRYgQ5fXljsVh3+Q1kYHJy8greTiPIySLLsqL7lfdViUTiPG5sIUh5sdvtOwsLC/r8zfv/bGxsNOMjJgQpLV6vd0Xzu83lUhRFxmIPBHlz+vv772j2OS8LkUgkyGvtNIIYNRaL5VkkEgmerl06WV1d9fD4FhOCGDF+v3++lC8mGIqqquLY2NiwXpsCIIjRUldXp4TD4eFTfyWQp+3tbcfg4OBtrffYQhCjRBTFwuDg4O0T76RhRMlk8tx77713T8staxGEZ0wm03Fvb++9sjego2Rpack3MDAQ1eoJEAiidyRJUgcGBqIl79tcCdLptHN0dPS6Vg9UQxCt43a7UyMjI9cr6q1yuQqFgjg7O9s1NDR0y+VybZcycQjCKy6Xa3toaOjW9PR0168+JVBHJW2po6eVlRVfLBa7Mjs7+/u5uTl/NpvFntHAjc1mexoIBB52dXXNXL58Oebz+ZZ5j+mnDFfgV21ubjavrKz41tbWfru+vv5uOp12ZTIZRy6Xs2az2QZVVWuOjo54DxOIMZlMwpkzZwRJkp7bbLan9fX1B06nc7epqem7lpaWbzwez7+8Xu9yc3PzJu+xvsl/APSPzgpQu+scAAAAAElFTkSuQmCC\"","import React from 'react'\r\nimport NumberFormat from 'react-number-format'\r\n\r\nexport const numberFormat = (value, allowNegative = false,decimalScale=2) => {\r\n return (\r\n
\r\n )\r\n}","import styled from '@emotion/styled'\r\nimport * as v from 'variables/styles'\r\n\r\nexport const TrackingListCont = styled.div((props) => ({\r\n marginTop:'1rem',\r\n // width:'80vw',\r\n // maxWidth:'90vw',\r\n\r\n '.ui.table':{\r\n borderWidth:0\r\n },\r\n\r\n '.ReactTable .rt-thead.-header':{\r\n boxShadow:'none',\r\n background: '#eaeff5'\r\n },\r\n\r\n '.ReactTable':{\r\n borderRadius:'0.5rem'\r\n },\r\n\r\n '.ReactTable .rt-thead .rt-th':{\r\n borderRight: 0\r\n },\r\n\r\n '.ReactTable .rt-tbody .rt-td':{\r\n borderRight: 0\r\n },\r\n\r\n '.-padRow':{\r\n cursor:'default !important'\r\n },\r\n\r\n '.ReactTable .rt-tr':{\r\n cursor:'pointer'\r\n },\r\n\r\n '@media only screen and (min-width: 600px)': {\r\n // width: '100vw',\r\n },\r\n\r\n '@media only screen and (min-width: 769px)': {\r\n width: '80vw',\r\n },\r\n\r\n}))\r\n\r\nexport const DivText = styled.div((props) => ({\r\n display:'flex',\r\n justifyContent:`${props.left?'flex-start':props.right?'flex-end':'center'}`,\r\n\r\n 'div.priority.urgent': {\r\n background: '#FF0000',\r\n borderRadius: '2px',\r\n color: '#FFF',\r\n fontWeight: 'bold',\r\n padding: '2px 5px',\r\n }\r\n}))\r\n\r\nexport const RowFields = styled.div({\r\n display: 'flex',\r\n flex: 1,\r\n flexDirection: 'row',\r\n})\r\n","import React from 'react'\r\nimport Moment from 'react-moment'\r\nimport { lower } from 'change-case'\r\n\r\nimport { StatusTag } from 'components'\r\nimport { numberFormat } from './helper'\r\n\r\nimport { DivText } from './styled'\r\n\r\nexport const pouStatus = {0:'Draft',1:'New',2:'In Progress',3:'Revise',4:'Completed',5:'Reject',6:'Cancelled'}\r\n\r\nexport const columns = { \r\n tPOUs:[\r\n {\r\n Header: 'PR No.',\r\n accessor: 'documentNumber',\r\n width: 100,\r\n Cell:row=>(
{row.value} )\r\n },\r\n {\r\n Header: ()=>(
Title ),\r\n accessor : row =>(row.title.trim()),\r\n id:'title',\r\n }, \r\n {\r\n Header: 'Priority',\r\n accessor: 'priority',\r\n width: 70,\r\n Cell: row => (\r\n row.value && \r\n
{row.value.toUpperCase()}
)\r\n },\r\n {\r\n Header: ()=>(
Project name ),\r\n accessor: 'projectName',\r\n width: 100,\r\n Cell:row=>(
{row.value} )\r\n },\r\n {\r\n Header: ()=>(
Requester ),\r\n accessor: 'requesterName',\r\n width: 100,\r\n Cell: row => (row.value&&
{`${row.value||'-'}`} )\r\n },\r\n {\r\n Header: 'Company',\r\n accessor : 'companyName',\r\n width: 100,\r\n Cell:row=>(
{row.value} )\r\n },\r\n {\r\n Header: 'Current Process',\r\n accessor: 'currencyProcess',\r\n width: 180,\r\n Cell:row=>(
{row.value} )\r\n }\r\n ],\r\n\r\n tPOItem:[\r\n {\r\n Header: 'No',\r\n accessor: 'lineNo',\r\n width: 100,\r\n Cell: row => (
{row.value} )\r\n },\r\n {\r\n Header: 'Material No.',\r\n accessor: 'materialNo',\r\n width: 120,\r\n Cell: row => (
{row.value} )\r\n },\r\n {\r\n Header: 'Item Name',\r\n accessor: 'itemName',\r\n width: 100,\r\n },\r\n {\r\n Header: 'Description',\r\n accessor: 'itemDescription',\r\n },\r\n {\r\n Header: 'Quantity',\r\n accessor: 'sapQtyRemain',\r\n width: 100,\r\n Cell: row => (
{numberFormat(row.value,false,3)} )\r\n },\r\n {\r\n Header: 'Unit Price',\r\n accessor : 'netPrice',\r\n width: 100,\r\n Cell: row => (
{numberFormat(row.value)} )\r\n },\r\n {\r\n Header: 'Currency',\r\n accessor: 'currency',\r\n width: 100,\r\n Cell: row => (
{row.value} )\r\n },\r\n {\r\n Header: 'Amount',\r\n accessor: 'sapAmount',\r\n width: 100,\r\n Cell: row => (
{numberFormat(row.value)} )\r\n },\r\n ]\r\n}","import { takeLatest, put } from 'redux-saga/effects'\r\nimport { createReducer, makeAction, makeKeys } from './helper'\r\nimport { httpGet } from '../core/restClient'\r\n// import { appLoading, appLoaded, toastError, toastSuccess } from './app'\r\n\r\nconst GET_HRMS_MEMBERS = makeKeys('GET_HRMS_MEMBERS')\r\nconst ADD_OTHER_MEMBER = 'ADD_OTHER_MEMBER'\r\nconst GET_PURCHASE_USERS = makeKeys('GET_PURCHASE_USERS')\r\n\r\nexport const getHrmsMembers = makeAction(GET_HRMS_MEMBERS.REQUEST,'callBack')\r\nexport const addOtherMember = makeAction(ADD_OTHER_MEMBER)\r\nexport const getPurchaseUsers = makeAction(GET_PURCHASE_USERS.REQUEST,'companyCode','purchGroup')\r\n\r\nconst getHrmsMembersSuccess = makeAction(GET_HRMS_MEMBERS.SUCCESS, 'data')\r\nconst getPurchaseUsersSuccess = makeAction(GET_PURCHASE_USERS.SUCCESS, 'data')\r\n\r\nconst initial = {\r\n memberLoading: false,\r\n members: [],\r\n purchaseUsers: { data:[], loading:false },\r\n membersSelectView: []\r\n}\r\n\r\nfunction* getHrmsMembersRequest(action) {\r\n const {callBack} = action.payload\r\n try {\r\n const response = yield httpGet('members/hrms')\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getHrmsMembersSuccess(response.data))\r\n if (callBack !== null) callBack(response.data)\r\n }\r\n }\r\n } catch (e) {\r\n }\r\n}\r\n\r\nfunction* getPurchaseUsersRequest(action) {\r\n const { companyCode, purchGroup } = action.payload\r\n try {\r\n const response = yield httpGet(`members/roleOfficerPurchaseUsers/${companyCode}/${purchGroup}`)\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getPurchaseUsersSuccess(response.data))\r\n }\r\n }\r\n } catch (e) {\r\n yield put(getPurchaseUsersSuccess([]))\r\n }\r\n}\r\n\r\nexport function* watchMembersSaga() {\r\n yield takeLatest(GET_HRMS_MEMBERS.REQUEST, getHrmsMembersRequest)\r\n yield takeLatest(GET_PURCHASE_USERS.REQUEST, getPurchaseUsersRequest)\r\n}\r\n\r\nexport default createReducer(initial, state => ({\r\n [GET_HRMS_MEMBERS.REQUEST]: () => ({\r\n ...state,\r\n memberLoading: true\r\n }),\r\n [GET_HRMS_MEMBERS.SUCCESS]: (data) => ({\r\n ...state,\r\n members: data.data,\r\n memberLoading: false\r\n }),\r\n [GET_PURCHASE_USERS.REQUEST]: () => ({\r\n ...state,\r\n purchaseUsers: { data:[], loading:true }\r\n }),\r\n [GET_PURCHASE_USERS.SUCCESS]: (data) => ({\r\n ...state,\r\n purchaseUsers: { data:data.data, loading:false }\r\n }),\r\n [ADD_OTHER_MEMBER]: (data) => ({\r\n ...state,\r\n members: [\r\n ...state.members,\r\n { username: data, firstnameEn: data, lastnameEn: '', companyCode: 320, costCenterCode: '', mainDepartmentEn: '' }\r\n ]\r\n }),\r\n}))","import { takeLatest, put } from 'redux-saga/effects'\r\nimport { createReducer, makeAction, makeKeys } from './helper'\r\nimport { httpGet } from '../core/restClient'\r\n// import { appLoading, appLoaded, toastError, toastSuccess } from './app'\r\n// import r from 'reactotron-react-js'\r\n\r\nconst GET_GOA_BY_COMPANY = makeKeys('GET_GOA_BY_COMPANY')\r\nconst GET_GOA_ITEMS = makeKeys('GET_GOA_ITEMS')\r\nconst GET_PROJECT_BY_COMPANY = makeKeys('GET_PROJECT_BY_COMPANY')\r\nconst ADD_OTHER_PROJECT = 'ADD_OTHER_PROJECT'\r\nconst CLEAR_OTHER_PROJECT = 'CLEAR_OTHER_PROJECT'\r\nconst GET_SPECIAL_APPROVAL= makeKeys('GET_SPECIAL_APPROVAL')\r\n\r\nconst FETCH_GOAS_PROJECT = makeKeys('FETCH_GOAS_PROJECT')\r\nconst FETCH_GOAS = makeKeys('FETCH_GOAS')\r\n\r\nexport const getGoaByCompany = makeAction(GET_GOA_BY_COMPANY.REQUEST, 'company')\r\nexport const getGoaItem = makeAction(GET_GOA_ITEMS.REQUEST, 'goaId', 'processCode')\r\nexport const getProjectByCompany = makeAction(GET_PROJECT_BY_COMPANY.REQUEST, 'company')\r\nexport const addOtherProject = makeAction(ADD_OTHER_PROJECT, 'name')\r\nexport const clearOtherProject = makeAction(CLEAR_OTHER_PROJECT)\r\nexport const getSpecialApproval = makeAction(GET_SPECIAL_APPROVAL.REQUEST, 'projectId')\r\nexport const fetchGoasProject = makeAction(FETCH_GOAS_PROJECT.REQUEST)\r\nexport const fetchGoas = makeAction(FETCH_GOAS.REQUEST)\r\n\r\nconst getGoaByCompanySuccess = makeAction(GET_GOA_BY_COMPANY.SUCCESS, 'company', 'data')\r\nconst getGoaItemSuccess = makeAction(GET_GOA_ITEMS.SUCCESS, 'goaId', 'data')\r\nconst getProjectByCompanySuccess = makeAction(GET_PROJECT_BY_COMPANY.SUCCESS, 'company', 'data')\r\nconst getSpecialApprovalSuccess = makeAction(GET_SPECIAL_APPROVAL.SUCCESS, 'projectId', 'data')\r\nconst fetchGoasProjectSuccess = makeAction(FETCH_GOAS_PROJECT.SUCCESS,'data')\r\nconst fetchGoasSuccess = makeAction(FETCH_GOAS.SUCCESS,'data')\r\n\r\nconst initial = {\r\n goa: {},\r\n goas:{ data:[], loading:false},\r\n goaCompanyLoading: undefined,\r\n goaLoading: false,\r\n goaItems: {},\r\n goaItemByGoaIdLoading: undefined,\r\n goaItemLoading: false,\r\n projects: {\r\n other: []\r\n },\r\n projectCompanyLoading: undefined,\r\n projectLoading: false,\r\n specialApprovals: {},\r\n specialApprovalProjectIdLoading: undefined,\r\n specialApprovalLoading: false,\r\n goasProject: [],\r\n}\r\n\r\nfunction* getGoaByCompanyRequest(action) {\r\n const { company } = action.payload\r\n try {\r\n const response = yield httpGet('goas/default', { companyCode: company })\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getGoaByCompanySuccess(company, response.data))\r\n }\r\n }\r\n } catch (e) {\r\n }\r\n}\r\n\r\nfunction* getGoaItemRequest(action) {\r\n const { goaId, processCode } = action.payload\r\n try {\r\n const response = yield httpGet(`goas/${goaId}/items`, { processCode })\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getGoaItemSuccess(goaId, response.data))\r\n }\r\n }\r\n } catch (e) {\r\n }\r\n}\r\n\r\nfunction* getProjectByCompanyRequest(action) {\r\n const { company } = action.payload\r\n try {\r\n const response = yield httpGet('goas/default/projects', { companyCode: company })\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getProjectByCompanySuccess(company, response.data))\r\n }else{\r\n yield put(getProjectByCompanySuccess('other', []))\r\n }\r\n }\r\n } catch (e) {\r\n }\r\n}\r\n\r\nfunction* getSpecialApprovalRequest(action) {\r\n const { projectId } = action.payload\r\n try {\r\n const response = yield httpGet('goas/specialApprovals', { projectId })\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getSpecialApprovalSuccess(projectId, response.data))\r\n }\r\n }\r\n } catch (e) {\r\n }\r\n}\r\n\r\nfunction* fetchGoasProjectRequest() {\r\n try {\r\n const response = yield httpGet('goas/projects')\r\n if (response.status === 200) {\r\n if (response.data) {\r\n yield put(fetchGoasProjectSuccess(response.data))\r\n }\r\n }\r\n } catch (e) {\r\n }\r\n}\r\n\r\nfunction* fetchGoasProjecRequest() {\r\n try {\r\n const response = yield httpGet('goas')\r\n if (response.status === 200) {\r\n if (response.data) {\r\n yield put(fetchGoasSuccess(response.data))\r\n }\r\n }\r\n } catch (e) {\r\n }\r\n}\r\n\r\nexport function* watchGoaSaga() {\r\n yield takeLatest(GET_GOA_BY_COMPANY.REQUEST, getGoaByCompanyRequest)\r\n yield takeLatest(GET_GOA_ITEMS.REQUEST, getGoaItemRequest)\r\n yield takeLatest(GET_PROJECT_BY_COMPANY.REQUEST, getProjectByCompanyRequest)\r\n yield takeLatest(GET_SPECIAL_APPROVAL.REQUEST, getSpecialApprovalRequest)\r\n\r\n yield takeLatest(FETCH_GOAS_PROJECT.REQUEST, fetchGoasProjectRequest)\r\n yield takeLatest(FETCH_GOAS.REQUEST, fetchGoasProjecRequest)\r\n}\r\n\r\nexport default createReducer(initial, state => ({\r\n [GET_GOA_BY_COMPANY.REQUEST]: (data) => ({\r\n ...state,\r\n goaCompanyLoading: data.company,\r\n goaLoading: true\r\n }),\r\n [GET_GOA_BY_COMPANY.SUCCESS]: (data) => ({\r\n ...state,\r\n goa: {\r\n ...state.goa,\r\n [data.company]: data.data\r\n },\r\n goaCompanyLoading: undefined,\r\n goaLoading: false\r\n }),\r\n [GET_GOA_ITEMS.REQUEST]: (data) => ({\r\n ...state,\r\n goaItemByGoaIdLoading: data.goaId,\r\n goaItemLoading: true\r\n }),\r\n [GET_GOA_ITEMS.SUCCESS]: (data) => ({\r\n ...state,\r\n goaItems: {\r\n ...state.goaItems,\r\n [data.goaId]: data.data\r\n },\r\n goaItemByGoaIdLoading: undefined,\r\n goaItemLoading: false\r\n }),\r\n [GET_PROJECT_BY_COMPANY.REQUEST]: (data) => ({\r\n ...state,\r\n projectCompanyLoading: data.company,\r\n projectLoading: true\r\n }),\r\n [GET_PROJECT_BY_COMPANY.SUCCESS]: (data) => ({\r\n ...state,\r\n projects: {\r\n ...state.projects,\r\n [data.company]: data.data\r\n },\r\n projectCompanyLoading: undefined,\r\n projectLoading: false\r\n }),\r\n [GET_SPECIAL_APPROVAL.REQUEST]: (data) => ({\r\n ...state,\r\n specialApprovalProjectIdLoading: data.projectId,\r\n specialApprovalLoading: true\r\n }),\r\n [GET_SPECIAL_APPROVAL.SUCCESS]: (data) => ({\r\n ...state,\r\n specialApprovals: {\r\n ...state.specialApprovals,\r\n [data.projectId]: data.data\r\n },\r\n specialApprovalProjectIdLoading: undefined,\r\n specialApprovalLoading: false\r\n }),\r\n [ADD_OTHER_PROJECT]: (data) => ({\r\n ...state,\r\n projects: {\r\n ...state.projects,\r\n other: [ ...state.projects.other, { id: data.name, projectName: data.name }]\r\n }\r\n }),\r\n [CLEAR_OTHER_PROJECT]: (data) => ({\r\n ...state,\r\n projects: {\r\n ...state.projects,\r\n other: []\r\n }\r\n }),\r\n [FETCH_GOAS_PROJECT.REQUEST]: () => ({\r\n ...state,\r\n specialApprovalLoading: true\r\n }),\r\n [FETCH_GOAS_PROJECT.SUCCESS]: (data) => ({\r\n ...state,\r\n goasProject: data.data,\r\n specialApprovalLoading: false\r\n }),\r\n [FETCH_GOAS.REQUEST]: () => ({\r\n ...state,\r\n goas: { data: [], loading: true }\r\n }),\r\n [FETCH_GOAS.SUCCESS]: (data) => ({\r\n ...state,\r\n goas: { data: data.data, loading: false }\r\n }),\r\n}))","import { takeLatest, put, select } from 'redux-saga/effects'\r\n\r\nimport { createReducer, makeAction, makeKeys } from './helper'\r\nimport { httpPost, httpGet, httpDelete, httpPut } from '../core/restClient'\r\nimport { appLoading, appLoaded, toastError, toastSuccess } from './app'\r\nimport {\r\n getHrmsMembers\r\n} from './member'\r\nimport {\r\n fetchGoas\r\n} from './goa'\r\nimport {\r\n getPurchasingGroups,\r\n getCompanies,\r\n} from './options'\r\nimport r from 'reactotron-react-js'\r\n\r\nconst INITIALIZE_TRACKING = 'INITIALIZE_TRACKING'\r\nconst CLEAR_TRACKINGDATA = 'CLEAR_TRACKINGDATA'\r\nconst FETCH_TRACKINGS = makeKeys('FETCH_TRACKINGS')\r\nconst GET_TRACKING_DETAIL = makeKeys('GET_TRACKING_DETAIL')\r\nconst SET_TRACKING_DETAIL = 'SET_TRACKING_DETAIL'\r\n\r\nexport const initializeTracking = makeAction(INITIALIZE_TRACKING)\r\nexport const clearTrackingData = makeAction(CLEAR_TRACKINGDATA)\r\nexport const fetchTrackings = makeAction(FETCH_TRACKINGS.REQUEST, 'dataSearch')\r\nexport const getTrackingDetail = makeAction(GET_TRACKING_DETAIL.REQUEST, 'tkId')\r\nexport const setTrackingDetail = makeAction(SET_TRACKING_DETAIL, 'data')\r\n\r\nconst fetchTrackingsSuccess = makeAction(FETCH_TRACKINGS.SUCCESS, 'data')\r\nconst getTrackingDetailSuccess = makeAction(GET_TRACKING_DETAIL.SUCCESS, 'data')\r\n\r\n\r\nconst initial = {\r\n trackingList: {},\r\n trackingDetail: { data:{}, loading:false },\r\n}\r\n\r\nfunction* initializePOUpdateRequest() {\r\n try {\r\n const state = yield select()\r\n if (!state.goa.goas.length) {\r\n yield put(fetchGoas())\r\n }\r\n if (!state.member.members.length) {\r\n yield put(getHrmsMembers())\r\n }\r\n if(!state.options.companies.data.length){\r\n yield put(getCompanies())\r\n }\r\n if(!state.options.purchasingGroups.data.length){\r\n yield put(getPurchasingGroups())\r\n }\r\n } catch (e) {\r\n console.log('eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee')\r\n console.log(e)\r\n }\r\n}\r\n\r\nfunction* fetchTrackingsRequest( action ) {\r\n const { dataSearch } = action.payload\r\n try {\r\n yield put(appLoading())\r\n const response = yield httpGet('trackings',dataSearch)\r\n if (response.status >= 200 && response.status < 300) {\r\n yield put(fetchTrackingsSuccess(response.data))\r\n }\r\n yield put(appLoaded())\r\n } catch (e) {\r\n yield put(appLoaded())\r\n yield put(fetchTrackingsSuccess({}))\r\n }\r\n}\r\n\r\nfunction* getTrackingDetailRequest( action ) {\r\n const { tkId } = action.payload\r\n try {\r\n yield put(appLoading())\r\n const response = yield httpGet(`trackings/${tkId}`)\r\n // const response = yield httpGet(`mobile/trackings/pr/${tkId}`)\r\n if (response.status >= 200 && response.status < 300) {\r\n yield put(getTrackingDetailSuccess(response.data))\r\n }\r\n yield put(appLoaded())\r\n } catch (e) {\r\n if(e.data){\r\n yield put(toastError(e.data.message))\r\n }else{\r\n yield put(toastError('Can not connect to server.'))\r\n }\r\n yield put(appLoaded())\r\n }\r\n}\r\n\r\nexport function* watchTrackingSaga() {\r\n yield takeLatest(INITIALIZE_TRACKING, initializePOUpdateRequest)\r\n yield takeLatest(FETCH_TRACKINGS.REQUEST, fetchTrackingsRequest)\r\n yield takeLatest(GET_TRACKING_DETAIL.REQUEST, getTrackingDetailRequest)\r\n}\r\n\r\nexport default createReducer(initial, state => ({\r\n [CLEAR_TRACKINGDATA]: () => ({\r\n ...state,\r\n trackingDetail:{ data:{}, loading:false }\r\n }),\r\n [FETCH_TRACKINGS.REQUEST]: () => ({\r\n ...state\r\n }),\r\n [FETCH_TRACKINGS.SUCCESS]: (data) => ({\r\n ...state,\r\n trackingList: data.data\r\n }),\r\n [GET_TRACKING_DETAIL.REQUEST]: () => ({\r\n ...state,\r\n trackingDetail:{ data:{}, loading:true}\r\n }),\r\n [GET_TRACKING_DETAIL.SUCCESS]: (data) => ({\r\n ...state,\r\n trackingDetail:{ data:data.data, loading:false}\r\n }),\r\n [SET_TRACKING_DETAIL]: (data) => ({\r\n ...state,\r\n trackingDetail:{ data:data.data, loading:false}\r\n }),\r\n}))","import React from 'react'\r\nimport { connect } from 'react-redux'\r\nimport { Icon } from 'semantic-ui-react'\r\nimport ReactTable from 'react-table'\r\nimport { getFormValues, reduxForm } from 'redux-form'\r\n\r\nimport { \r\n MainBodyContent,\r\n SearchList,\r\n TablePagination\r\n} from 'components'\r\nimport { \r\n trackingDetailPath,\r\n} from 'routes'\r\nimport {\r\n columns\r\n} from './AttributeData'\r\nimport { \r\n fetchTrackings,\r\n setTrackingDetail,\r\n} from 'ducks/tracking'\r\n\r\nimport { TrackingListCont } from './styled'\r\nimport { ProcurementContainer, ProcurementBody } from '../styled'\r\n\r\nconst TrackingList = (props) => {\r\n\r\n const { \r\n trackingList,\r\n valueForm \r\n } = props\r\n\r\n const userPageSize = parseInt(localStorage.getItem('userPageSize') || '10')\r\n const [pageSize, setPageSize] = React.useState(userPageSize)\r\n\r\n React.useEffect(() => {\r\n props.fetchTrackings()\r\n },[])\r\n\r\n return (\r\n
\r\n \r\n \r\n \r\n \r\n 0?trackingList.data:[]}\r\n columns={columns.tPOUs}\r\n defaultPageSize={userPageSize}\r\n noDataText=\"No Tracking found\"\r\n previousText={ }\r\n nextText={ }\r\n className=\"-striped -highlight\"\r\n\r\n PaginationComponent={TablePagination}\r\n pages={Object.keys(trackingList).length>0?trackingList.totalPage:0}\r\n currentPage={Object.keys(trackingList).length>0?trackingList.page:0}\r\n onPageChange={(pageIndex) => {\r\n props.fetchTrackings({...valueForm,page:pageIndex+1,size:pageSize})\r\n }}\r\n onPageSizeChange={(pageSize, pageIndex) => {\r\n setPageSize(pageSize)\r\n localStorage.setItem('userPageSize', pageSize)\r\n props.fetchTrackings({...valueForm,page:pageIndex+1,size:pageSize})\r\n }}\r\n \r\n getTdProps={(state, rowInfo, column, instance) => {\r\n return {\r\n onClick: (e, handleOriginal) => {\r\n if (rowInfo && column && column.Header !== '') {\r\n props.setTrackingDetail(rowInfo.original)\r\n window.open(trackingDetailPath(rowInfo.original.id))\r\n }\r\n if (handleOriginal) {\r\n handleOriginal()\r\n }\r\n },\r\n }\r\n }}\r\n />\r\n \r\n \r\n \r\n \r\n )\r\n}\r\n\r\nconst mapStateToProps = state => ({\r\n trackingList: state.tracking.trackingList,\r\n valueForm: getFormValues('formSearchTracking')(state),\r\n})\r\n\r\nconst mapDispatchToProps = {\r\n fetchTrackings,\r\n setTrackingDetail,\r\n}\r\n\r\nconst contForm = reduxForm({\r\n form: 'formSearchTracking',\r\n enableReinitialize: true,\r\n})(TrackingList)\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(contForm)\r\n","import styled from '@emotion/styled'\r\nimport * as v from 'variables/styles'\r\n\r\nexport const Container = styled.div({\r\n})\r\n\r\nexport const THeader = styled.div({\r\n display:'flex', \r\n alignItems:'center',\r\n 'span':{\r\n fontWeight:'bold'\r\n }\r\n})\r\n\r\nexport const TList = styled.div({\r\n display:'flex',\r\n})\r\n\r\nexport const TListLine = styled.div((props)=>({\r\n marginLeft:'0.9rem', \r\n height:`${props.isLast?'0':'auto'}`, \r\n minHeight:`${props.isLast?'0':'1rem'}`, \r\n width:3, \r\n background:v.ezMainColor\r\n}))\r\n\r\nexport const TItemCont = styled.div({\r\n display:'flex', \r\n marginBottom:'1rem',\r\n \r\n '.lineV1':{\r\n marginLeft:'2rem', \r\n height:'2rem', \r\n width:2, \r\n background:v.ezMainColor\r\n },\r\n '.lineV2':{\r\n position:'relative', \r\n top:'-1rem', \r\n height:'1rem', \r\n width:2, \r\n background:v.ezMainColor\r\n },\r\n '.lineH':{\r\n alignSelf:'flex-end',\r\n height:2, \r\n width:'2rem', \r\n background:v.ezMainColor\r\n },\r\n\r\n '.label':{\r\n position:'relative', top:'0.9rem'\r\n },\r\n '.labelNotFound':{\r\n fontStyle:'italic', \r\n position:'relative', \r\n top:'0.6rem',\r\n marginLeft:'0.2rem', \r\n marginRight:'1rem', \r\n alignSelf:'flex-end'\r\n },\r\n})\r\n\r\nexport const TItemData = styled.div({\r\n display:'flex',\r\n\r\n '.docNum':{\r\n marginLeft:'0.2rem', \r\n marginRight:'1rem', \r\n alignSelf:'flex-end'\r\n }\r\n})","import React from 'react'\r\nimport { connect } from 'react-redux'\r\nimport { Fade, Collapse } from '@material-ui/core'\r\nimport { Icon, Label } from 'semantic-ui-react'\r\n\r\nimport { StatusTag } from 'components'\r\n\r\nimport { \r\n Container,\r\n THeader,\r\n TList,\r\n TListLine,\r\n TItemCont,\r\n TItemData\r\n} from './styled'\r\n\r\nconst TrackingItem = props => {\r\n const {\r\n data,\r\n title,\r\n icon='',\r\n redirect=null,\r\n isLast=false,\r\n onCollapse=null,\r\n activeCollapse=true\r\n } = props\r\n\r\n return (\r\n
\r\n \r\n onCollapse?onCollapse():null}/>\r\n {title} \r\n \r\n {data&&data.items&&data.items.length>0?\r\n \r\n {data.items.map((x,i)=>{\r\n return(\r\n
\r\n \r\n \r\n \r\n \r\n \r\n {i>0?\r\n
\r\n :null\r\n }\r\n
\r\n
\r\n window.open(redirect&&redirect(x.id),\"_blank\")}>\r\n \r\n \r\n {x.documentNumber}
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n )\r\n })}\r\n
\r\n :\r\n \r\n
\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n Process not found
\r\n \r\n \r\n \r\n \r\n
\r\n }\r\n \r\n )\r\n}\r\n\r\nconst mapStateToProps = state => {\r\n return {\r\n }\r\n}\r\n\r\nconst mapDispatchToProps = {}\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(TrackingItem)\r\n","import styled from '@emotion/styled'\r\nimport * as v from 'variables/styles'\r\n\r\nexport const Container = styled.div({\r\n display: 'flex',\r\n flexDirection: 'column',\r\n \r\n '.rowFields': {\r\n display: 'flex',\r\n flex: 1,\r\n flexDirection: 'row',\r\n },\r\n})\r\n","import React from 'react'\r\nimport { connect } from 'react-redux'\r\nimport { lower } from 'change-case'\r\nimport { Field, getFormValues } from 'redux-form'\r\nimport { Fade } from '@material-ui/core'\r\n\r\nimport FieldInput, { InputType as type } from 'components/SemanticForm'\r\nimport { StdCard } from 'components'\r\n\r\nimport { ProcurementBody } from 'routes/ProcurementSystem/styled'\r\nimport { Container } from './styled'\r\n\r\nconst RequestInfo = props => {\r\n\r\n return (\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n \r\n \r\n
\r\n \r\n \r\n \r\n \r\n )\r\n}\r\n\r\nconst mapStateToProps = state => {\r\n return {\r\n }\r\n}\r\n\r\nconst mapDispatchToProps = {}\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(RequestInfo)\r\n","import React from 'react'\r\nimport { connect } from 'react-redux'\r\nimport { reduxForm, getFormValues } from 'redux-form'\r\nimport { Breadcrumb } from 'semantic-ui-react'\r\n\r\nimport { trackingPath } from 'routes'\r\nimport TrackingItem from '../Shareds/TrackingItem'\r\nimport RequestInfo from '../Shareds/RequestInfo'\r\nimport { StdCard } from 'components'\r\nimport { \r\n MainBodyContent, \r\n} from 'components'\r\nimport { \r\n initializeTracking,\r\n getTrackingDetail,\r\n} from 'ducks/tracking'\r\nimport { \r\n purchaseRequisitionDetailPath,\r\n requestForQuotationDetailPath,\r\n purchaseOrderDetailPath,\r\n purchaseOrderUpdateDetailPath,\r\n contractDetailPath,\r\n downPaymentDetailPath,\r\n goodsServiceReceiptDetailPath,\r\n BillformDetailPath\r\n} from 'routes'\r\nimport r from 'reactotron-react-js'\r\n\r\nconst DetailTracking = props => {\r\n\r\n const { \r\n history,\r\n trackingDetail,\r\n } = props\r\n\r\n const [collapse, setCollapse] = React.useState({})\r\n\r\n React.useEffect(() => {\r\n const { match } = props\r\n window.scrollTo(0,0)\r\n props.initializeTracking()\r\n if (match && match.params && match.params.tkId) {\r\n if(!Object.keys(trackingDetail).length){\r\n props.getTrackingDetail(match.params.tkId, history)\r\n }\r\n }\r\n },[])\r\n\r\n const onCollapse = (index) =>{\r\n let clone = JSON.parse(JSON.stringify(collapse))\r\n clone[index] = collapse[index]!=undefined?!collapse[index]:false\r\n setCollapse(clone)\r\n }\r\n\r\n return (\r\n
{`Tracking PR ${trackingDetail?trackingDetail.documentNumber?`- #${trackingDetail.documentNumber}`:'':''}`}}\r\n breadcrumbs={\r\n history.push(trackingPath),\r\n },\r\n { key: 'trackingDetail', content: 'Detail', active: true },\r\n ]}\r\n />\r\n }\r\n >\r\n \r\n \r\n {Object.keys(trackingDetail).length>0?\r\n
\r\n \r\n onCollapse(0)}/>\r\n onCollapse(1)}/>\r\n onCollapse(2)}/>\r\n onCollapse(3)}/>\r\n onCollapse(4)}/>\r\n onCollapse(5)}/>\r\n onCollapse(6)}/>\r\n onCollapse(7)}/>\r\n onCollapse(8)}/>\r\n
\r\n \r\n :\r\n null\r\n }\r\n \r\n )\r\n\r\n}\r\n\r\nconst mapStateToProps = (state) => {\r\n let trackingDetail = state.tracking.trackingDetail\r\n return ({\r\n initialValues: {\r\n ...trackingDetail.data,\r\n },\r\n trackingDetail: trackingDetail.data,\r\n })\r\n}\r\nconst mapDispatchToProps = {\r\n initializeTracking,\r\n getTrackingDetail,\r\n}\r\n\r\nconst contForm = reduxForm({\r\n form: 'formTracking',\r\n enableReinitialize: true,\r\n})(DetailTracking)\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(contForm)\r\n","import styled from '@emotion/styled'\r\nimport * as v from '../../../variables/styles'\r\n\r\nexport const PRListCont = styled.div((props) => ({\r\n marginTop:'1rem',\r\n // width:'80vw',\r\n\r\n '.ui.table':{\r\n borderWidth:0\r\n },\r\n\r\n '.ReactTable .rt-thead.-header':{\r\n boxShadow:'none',\r\n background: '#eaeff5'\r\n },\r\n\r\n '.ReactTable':{\r\n borderRadius:'0.5rem'\r\n },\r\n\r\n '.ReactTable .rt-thead .rt-th':{\r\n borderRight: 0\r\n },\r\n\r\n '.ReactTable .rt-tbody .rt-td':{\r\n borderRight: 0\r\n },\r\n\r\n '.-padRow':{\r\n cursor:'default !important'\r\n },\r\n\r\n '.ReactTable .rt-tr':{\r\n cursor:'pointer'\r\n },\r\n\r\n '@media only screen and (min-width: 600px)': {\r\n // width: '100vw',\r\n },\r\n\r\n '@media only screen and (min-width: 769px)': {\r\n width: '80vw',\r\n },\r\n\r\n}))\r\n\r\nexport const StatusTag = styled.div((props) => ({\r\n fontFamily: 'DB-Airy',\r\n fontWeight: 'bold',\r\n fontSize: '0.75rem',\r\n color: '#FFF',\r\n padding: '0px 12px',\r\n background: `${props.status ? v.tagColors[props.status] : v.tagDraft}`,\r\n width: 'fit-content',\r\n borderRadius: `${props.allRadius ? '10px' : '10px 0px'}`,\r\n lineHeight:'1.5em',\r\n height:'1.5em',\r\n marginLeft:`${props.marginLeft||0}`\r\n}))\r\n\r\nexport const DivText = styled.div((props) => ({\r\n display:'flex',\r\n justifyContent:`${props.left?'flex-start':'center'}`,\r\n\r\n 'div.priority.urgent': {\r\n background: '#FF0000',\r\n borderRadius: '2px',\r\n color: '#FFF',\r\n fontWeight: 'bold',\r\n padding: '2px 5px',\r\n }\r\n}))\r\n","import { httpGet, httpPost, httpPut, httpDelete } from '../core/restClient'\r\nimport { takeLatest, put } from 'redux-saga/effects'\r\nimport { createReducer, makeAction, makeKeys } from './helper'\r\nimport { appLoading, appLoaded, toastError, toastSuccess } from './app'\r\n// import { appLoading, appLoaded, toastError, toastSuccess } from './app'\r\n\r\nconst GET_COMPANY_DATA = makeKeys('GET_COMPANY_DATA')\r\nconst GET_MP_PURCHASING_GROUPS = makeKeys('GET_MP_PURCHASING_GROUPS')\r\nconst GET_MP_COMPANY_PLANTS = makeKeys('GET_MP_COMPANY_PLANTS')\r\nconst GET_MP_PLANT_STORAGE_LOCATIONS = makeKeys('GET_MP_PLANT_STORAGE_LOCATIONS')\r\nconst GET_MP_PR_ITEM_FIELDS = makeKeys('GET_MP_PR_ITEM_FIELDS')\r\nconst GET_MP_ORDER_GL_ACCOUNT = makeKeys('GET_MP_ORDER_GL_ACCOUNT')\r\nconst CREATE_MP_ORDER_GL_ACCOUNT = 'CREATE_MP_ORDER_GL_ACCOUNT'\r\nconst UPDATE_MP_ORDER_GL_ACCOUNT = 'UPDATE_MP_ORDER_GL_ACCOUNT'\r\nconst DELETE_MP_ORDER_GL_ACCOUNT = 'DELETE_MP_ORDER_GL_ACCOUNT'\r\nconst SET_FORM_ORDER_GL_ACCOUNT = 'SET_FORM_ORDER_GL_ACCOUNT'\r\nconst GET_MP_WBS_ASSETS = makeKeys('GET_MP_WBS_ASSETS')\r\nconst CREATE_MP_WBS_ASSET = 'CREATE_MP_WBS_ASSET'\r\nconst UPDATE_MP_WBS_ASSET = 'UPDATE_MP_WBS_ASSET'\r\nconst DELETE_MP_WBS_ASSET = 'DELETE_MP_WBS_ASSET'\r\nconst SET_FORM_WBS_ASSET = 'SET_FORM_WBS_ASSET'\r\nconst GET_ASSET_TYPES = makeKeys('GET_ASSET_TYPES')\r\nconst GET_ALL_WBS = makeKeys('GET_ALL_WBS')\r\n\r\nexport const getCompanyData = makeAction(GET_COMPANY_DATA.REQUEST, 'companyCode')\r\nexport const getMappingPurchasingGroups = makeAction(GET_MP_PURCHASING_GROUPS.REQUEST)\r\nexport const getMappingCompanyPlants = makeAction(GET_MP_COMPANY_PLANTS.REQUEST)\r\nexport const getMappingPlantStorageLocations = makeAction(GET_MP_PLANT_STORAGE_LOCATIONS.REQUEST)\r\nexport const getMappingPrItemFields = makeAction(GET_MP_PR_ITEM_FIELDS.REQUEST, 'retry')\r\nexport const getMappingOderGlAccounts = makeAction(GET_MP_ORDER_GL_ACCOUNT.REQUEST, 'withInactive', 'retry')\r\nexport const createMappingOderGlAccount = makeAction(CREATE_MP_ORDER_GL_ACCOUNT, 'data', 'onSuccess')\r\nexport const updateMappingOderGlAccount = makeAction(UPDATE_MP_ORDER_GL_ACCOUNT, 'data', 'onSuccess')\r\nexport const deleteMappingOderGlAccount = makeAction(DELETE_MP_ORDER_GL_ACCOUNT, 'id', 'onSuccess')\r\nexport const setFormOrderGlAccount = makeAction(SET_FORM_ORDER_GL_ACCOUNT, 'data')\r\nexport const getMappingWbsAssets = makeAction(GET_MP_WBS_ASSETS.REQUEST, 'withInactive', 'retry')\r\nexport const createMappingWbsAsset = makeAction(CREATE_MP_WBS_ASSET, 'data', 'onSuccess')\r\nexport const updateMappingWbsAsset = makeAction(UPDATE_MP_WBS_ASSET, 'data', 'onSuccess')\r\nexport const deleteMappingWbsAsset = makeAction(DELETE_MP_WBS_ASSET, 'id', 'onSuccess')\r\nexport const setFormWbsAsset = makeAction(SET_FORM_WBS_ASSET, 'data')\r\nexport const getAssetTypes = makeAction(GET_ASSET_TYPES.REQUEST, 'withInactive', 'retry')\r\nexport const getAllWbs = makeAction(GET_ALL_WBS.REQUEST, 'retry')\r\n\r\nconst getMappingPurchasingGroupsSuccess = makeAction(GET_MP_PURCHASING_GROUPS.SUCCESS, 'data')\r\nconst getMappingCompanyPlantsSuccess = makeAction(GET_MP_COMPANY_PLANTS.SUCCESS, 'data')\r\nconst getCompanyDataSuccess = makeAction(GET_COMPANY_DATA.SUCCESS, 'data')\r\nconst getMappingPlantStorageLocationsSuccess = makeAction(GET_MP_PLANT_STORAGE_LOCATIONS.SUCCESS, 'data')\r\nconst getMappingPrItemFieldsSuccess = makeAction(GET_MP_PR_ITEM_FIELDS.SUCCESS, 'data')\r\nconst getMappingOderGlAccountsSuccess = makeAction(GET_MP_ORDER_GL_ACCOUNT.SUCCESS, 'data', 'withInactive')\r\nconst getMappingWbsAssetsSuccess = makeAction(GET_MP_WBS_ASSETS.SUCCESS, 'data', 'withInactive')\r\nconst getAssetTypesSuccess = makeAction(GET_ASSET_TYPES.SUCCESS, 'data')\r\nconst getAllWbsSuccess = makeAction(GET_ALL_WBS.SUCCESS, 'data')\r\n\r\nconst getMappingPrItemFieldsFailure = makeAction(GET_MP_PR_ITEM_FIELDS.FAILURE)\r\n\r\nfunction* getMappingPurchasingGroupsRequest(action) {\r\n try {\r\n const response = yield httpGet('mappingData/purchasingGroups')\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getMappingPurchasingGroupsSuccess(response.data))\r\n }\r\n }\r\n } catch (e) {\r\n yield put(getMappingPurchasingGroupsSuccess([]))\r\n }\r\n}\r\n\r\nfunction* getMappingCompanyPlantsRequest(action) {\r\n try {\r\n const response = yield httpGet('mappingData/companyPlants')\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getMappingCompanyPlantsSuccess(response.data))\r\n }\r\n }\r\n } catch (e) {\r\n yield put(getMappingCompanyPlantsSuccess([]))\r\n }\r\n}\r\n\r\nfunction* getCompanyDataRequest(action) {\r\n const { companyCode } = action.payload\r\n try {\r\n const response = yield httpGet(`mappingData/companyData/${companyCode}`)\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getCompanyDataSuccess(response.data))\r\n }\r\n }\r\n } catch (e) {\r\n yield put(getCompanyDataSuccess([]))\r\n }\r\n}\r\n\r\nfunction* getMappingPlantStorageLocationsRequest(action) {\r\n try {\r\n const response = yield httpGet('mappingData/plantStorageLocations')\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getMappingPlantStorageLocationsSuccess(response.data))\r\n }\r\n }\r\n } catch (e) {\r\n yield put(getMappingPlantStorageLocationsSuccess([]))\r\n }\r\n}\r\n\r\nfunction* getMappingPrItemFieldsRequest(action) {\r\n const { retry } = action.payload\r\n try {\r\n const response = yield httpGet('mappingData/prItemMappings')\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getMappingPrItemFieldsSuccess(response.data))\r\n }\r\n }\r\n } catch (e) {\r\n if (retry && retry > 3) {\r\n yield put(getMappingPrItemFieldsFailure())\r\n } else {\r\n yield put(getMappingPrItemFields(retry ? (retry + 1) : 1))\r\n }\r\n }\r\n}\r\n\r\nfunction* getMappingOderGlAccountsRequest(action) {\r\n let { withInactive, retry } = action.payload\r\n if (!withInactive) withInactive = false\r\n try {\r\n const response = yield httpGet('mappingData/orderGLAccounts', { withInactive })\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getMappingOderGlAccountsSuccess(response.data, withInactive))\r\n }\r\n }\r\n } catch (e) {\r\n if (retry && retry > 3) {\r\n yield put(getMappingOderGlAccountsSuccess([], withInactive))\r\n } else {\r\n yield put(getMappingOderGlAccounts(withInactive, retry ? (retry + 1) : 1))\r\n }\r\n }\r\n}\r\n\r\nfunction* createMappingOderGlAccountsRequest(action) {\r\n const { data, onSuccess } = action.payload\r\n try {\r\n yield put(appLoading('Create mapping data.'))\r\n const response = yield httpPost('mappingData/orderGLAccounts', { ...data })\r\n yield put(appLoaded())\r\n if (response.status >= 200 && response.status < 300) {\r\n yield put(toastSuccess('Create mapping data success'))\r\n yield put(getMappingOderGlAccounts(true))\r\n onSuccess()\r\n }\r\n } catch (e) {\r\n if (e && e.data && e.data.message) {\r\n yield put(toastError(e.data.message))\r\n } else {\r\n yield put(toastError('Create mapping data error!'))\r\n }\r\n yield put(appLoaded())\r\n }\r\n}\r\n\r\nfunction* updateMappingOderGlAccountsRequest(action) {\r\n const { data, onSuccess } = action.payload\r\n try {\r\n yield put(appLoading('Update mapping data.'))\r\n const response = yield httpPut(`mappingData/orderGLAccounts/${data.id}`, { ...data })\r\n yield put(appLoaded())\r\n if (response.status >= 200 && response.status < 300) {\r\n yield put(toastSuccess('Update mapping data success'))\r\n yield put(getMappingOderGlAccounts(true))\r\n onSuccess()\r\n }\r\n } catch (e) {\r\n if (e && e.data && e.data.message) {\r\n yield put(toastError(e.data.message))\r\n } else {\r\n yield put(toastError('Update mapping data error!'))\r\n }\r\n yield put(appLoaded())\r\n }\r\n}\r\n\r\nfunction* deleteMappingOderGlAccountsRequest(action) {\r\n const { id, onSuccess } = action.payload\r\n try {\r\n yield put(appLoading('Delete mapping data.'))\r\n const response = yield httpDelete(`mappingData/orderGLAccounts/${id}`)\r\n yield put(appLoaded())\r\n if (response.status >= 200 && response.status < 300) {\r\n yield put(toastSuccess('Delete mapping data success'))\r\n yield put(getMappingOderGlAccounts(true))\r\n onSuccess()\r\n }\r\n } catch (e) {\r\n if (e && e.data && e.data.message) {\r\n yield put(toastError(e.data.message))\r\n } else {\r\n yield put(toastError('Delete mapping data error!'))\r\n }\r\n yield put(appLoaded())\r\n }\r\n}\r\n\r\nfunction* getMappingWbsAssetsRequest(action) {\r\n let { withInactive, retry } = action.payload\r\n if (!withInactive) withInactive = false\r\n \r\n try {\r\n const response = yield httpGet('mappingData/wbsAssets', { withInactive })\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getMappingWbsAssetsSuccess(response.data, withInactive))\r\n }\r\n }\r\n } catch (e) {\r\n if (retry && retry > 3) {\r\n yield put(getMappingWbsAssetsSuccess([], withInactive))\r\n } else {\r\n yield put(getMappingWbsAssets(withInactive, retry ? (retry + 1) : 1))\r\n }\r\n }\r\n}\r\n\r\nfunction* createMappingWbsAssetRequest(action) {\r\n const { data, onSuccess } = action.payload\r\n try {\r\n yield put(appLoading('Create mapping data.'))\r\n const response = yield httpPost('mappingData/wbsAssets', { ...data })\r\n yield put(appLoaded())\r\n if (response.status >= 200 && response.status < 300) {\r\n yield put(toastSuccess('Create mapping data success'))\r\n yield put(getMappingWbsAssets(true))\r\n onSuccess()\r\n }\r\n } catch (e) {\r\n if (e && e.data && e.data.message) {\r\n yield put(toastError(e.data.message))\r\n } else {\r\n yield put(toastError('Create mapping data error!'))\r\n }\r\n yield put(appLoaded())\r\n }\r\n}\r\n\r\nfunction* updateMappingWbsAssetRequest(action) {\r\n const { data, onSuccess } = action.payload\r\n try {\r\n yield put(appLoading('Update mapping data.'))\r\n const response = yield httpPut(`mappingData/wbsAssets/${data.id}`, { ...data })\r\n yield put(appLoaded())\r\n if (response.status >= 200 && response.status < 300) {\r\n yield put(toastSuccess('Update mapping data success'))\r\n yield put(getMappingWbsAssets(true))\r\n onSuccess()\r\n }\r\n } catch (e) {\r\n if (e && e.data && e.data.message) {\r\n yield put(toastError(e.data.message))\r\n } else {\r\n yield put(toastError('Update mapping data error!'))\r\n }\r\n yield put(appLoaded())\r\n }\r\n}\r\n\r\nfunction* deleteMappingWbsAssetRequest(action) {\r\n const { id, onSuccess } = action.payload\r\n try {\r\n yield put(appLoading('Delete mapping data.'))\r\n const response = yield httpDelete(`mappingData/wbsAssets/${id}`)\r\n yield put(appLoaded())\r\n if (response.status >= 200 && response.status < 300) {\r\n yield put(toastSuccess('Delete mapping data success'))\r\n yield put(getMappingWbsAssets(true))\r\n onSuccess()\r\n }\r\n } catch (e) {\r\n if (e && e.data && e.data.message) {\r\n yield put(toastError(e.data.message))\r\n } else {\r\n yield put(toastError('Delete mapping data error!'))\r\n }\r\n yield put(appLoaded())\r\n }\r\n}\r\n\r\nfunction* getAssetTypesRequest(action) {\r\n let { withInactive, retry } = action.payload\r\n if (!withInactive) withInactive = false\r\n try {\r\n const response = yield httpGet('mappingData/assetTypes', { withInactive })\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getAssetTypesSuccess(response.data))\r\n }\r\n }\r\n } catch (e) {\r\n if (retry && retry > 3) {\r\n yield put(getAssetTypesSuccess([]))\r\n } else {\r\n yield put(getAssetTypes(retry ? (retry + 1) : 1))\r\n }\r\n }\r\n}\r\n\r\nfunction* getAllWbsRequest(action) {\r\n let { retry } = action.payload\r\n\r\n try {\r\n const response = yield httpGet('share/master/wbsElements')\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getAllWbsSuccess(response.data))\r\n }\r\n }\r\n } catch (e) {\r\n if (retry && retry > 3) {\r\n yield put(getAllWbsSuccess([]))\r\n } else {\r\n yield put(getAllWbs(retry ? (retry + 1) : 1))\r\n }\r\n }\r\n}\r\n\r\nexport function* watchMappingDataSaga() {\r\n yield takeLatest(GET_MP_PURCHASING_GROUPS.REQUEST, getMappingPurchasingGroupsRequest)\r\n yield takeLatest(GET_MP_COMPANY_PLANTS.REQUEST, getMappingCompanyPlantsRequest)\r\n yield takeLatest(GET_COMPANY_DATA.REQUEST, getCompanyDataRequest)\r\n yield takeLatest(GET_MP_PLANT_STORAGE_LOCATIONS.REQUEST, getMappingPlantStorageLocationsRequest)\r\n yield takeLatest(GET_MP_PR_ITEM_FIELDS.REQUEST, getMappingPrItemFieldsRequest)\r\n yield takeLatest(GET_MP_ORDER_GL_ACCOUNT.REQUEST, getMappingOderGlAccountsRequest)\r\n yield takeLatest(CREATE_MP_ORDER_GL_ACCOUNT, createMappingOderGlAccountsRequest)\r\n yield takeLatest(UPDATE_MP_ORDER_GL_ACCOUNT, updateMappingOderGlAccountsRequest)\r\n yield takeLatest(DELETE_MP_ORDER_GL_ACCOUNT, deleteMappingOderGlAccountsRequest)\r\n yield takeLatest(GET_MP_WBS_ASSETS.REQUEST, getMappingWbsAssetsRequest)\r\n yield takeLatest(CREATE_MP_WBS_ASSET, createMappingWbsAssetRequest)\r\n yield takeLatest(UPDATE_MP_WBS_ASSET, updateMappingWbsAssetRequest)\r\n yield takeLatest(DELETE_MP_WBS_ASSET, deleteMappingWbsAssetRequest)\r\n yield takeLatest(GET_ASSET_TYPES.REQUEST, getAssetTypesRequest)\r\n yield takeLatest(GET_ALL_WBS.REQUEST, getAllWbsRequest)\r\n}\r\n\r\nconst initial = {\r\n purchasingGroups: { data: [], loading: false },\r\n companyPlants: { data: [], loading: false },\r\n companyData: { data: {}, loading: false },\r\n plantStorageLocations: { data: [], loading: false },\r\n allOrderGlAccounts: { data: [], loading: false },\r\n orderGlAccounts: { data: [], loading: false },\r\n wbsAssets: { data: [], loading: false },\r\n allWbsAssets: { data: [], loading: false },\r\n assetTypes: { data: [], loading: false },\r\n allWbs: { data: [], loading: false },\r\n prItemFields: { \r\n data: {\r\n itemName: { '': { require: true, display: 'edit' } },\r\n itemDescription: { '': { require: false, display: 'edit' } },\r\n quantity: { '': { require: true, display: 'edit' } },\r\n unit: { '': { require: true, display: 'edit' } },\r\n unitPrice: { '': { require: true, display: 'edit' } },\r\n totalAmount: { '': { require: true, display: 'show' } },\r\n currency: { '': { require: true, display: 'edit' } },\r\n startDate: { '': { require: true, display: 'edit' } },\r\n deliveryDate: { '': { require: true, display: 'edit' } },\r\n materialGroup: { '': { require: true, display: 'edit' } },\r\n plant: { '': { require: true, display: 'edit' } },\r\n storageLocation: { '': { require: false, display: 'edit' } },\r\n purchasingOrg: { '': { require: true, display: 'edit' } },\r\n glAccountCode: { '': { require: false, display: 'hide' } },\r\n asset: { '': { require: false, display: 'hide' } },\r\n orderNo: { '': { require: false, display: 'hide' } },\r\n orderType: { '': { require: false, display: 'hide' } },\r\n costCenter: { '': { require: false, display: 'hide' } },\r\n wbsElement: { '': { require: false, display: 'hide' } },\r\n controllingArea: { '': { require: false, display: 'hide' } },\r\n profitCenter: { '': { require: false, display: 'hide' } },\r\n salesOrder: { '': { require: false, display: 'hide' } },\r\n salesOrderItemNo: { '': { require: false, display: 'hide' } },\r\n network: { '': { require: false, display: 'hide' } },\r\n productHierarchyLv2: { '': { require: false, display: 'hide' } },\r\n customer: { '': { require: false, display: 'hide' } },\r\n budgetType: { '': { require: true, display: 'edit' } },\r\n accountAssignment: { '': { require: true, display: 'edit' } }\r\n }, loading: false },\r\n formOrderGlAccount: { \r\n id: 0, \r\n orderNo: '', \r\n glAccount: '', \r\n active: true \r\n },\r\n formWbsAsset: { \r\n id: 0, \r\n company: '', \r\n wbsElementCode: '', \r\n assetCode: '',\r\n assetType: '',\r\n active: true \r\n }\r\n}\r\n\r\nexport default createReducer(initial, state => ({\r\n [GET_MP_PURCHASING_GROUPS.REQUEST]: () => ({\r\n ...state,\r\n purchasingGroups: { data: [], loading: true }\r\n }),\r\n [GET_MP_PURCHASING_GROUPS.SUCCESS]: (data) => ({\r\n ...state,\r\n purchasingGroups: { data: data.data, loading: false }\r\n }),\r\n [GET_MP_COMPANY_PLANTS.REQUEST]: () => ({\r\n ...state,\r\n companyPlants: { data: [], loading: true }\r\n }),\r\n [GET_MP_COMPANY_PLANTS.SUCCESS]: (data) => ({\r\n ...state,\r\n companyPlants: { data: data.data, loading: false }\r\n }),\r\n [GET_COMPANY_DATA.REQUEST]: () => ({\r\n ...state,\r\n companyData: { data: {}, loading: true }\r\n }),\r\n [GET_COMPANY_DATA.SUCCESS]: (data) => ({\r\n ...state,\r\n companyData: { data: data.data, loading: false }\r\n }),\r\n [GET_MP_PLANT_STORAGE_LOCATIONS.REQUEST]: () => ({\r\n ...state,\r\n plantStorageLocations: { data: [], loading: true }\r\n }),\r\n [GET_MP_PLANT_STORAGE_LOCATIONS.SUCCESS]: (data) => ({\r\n ...state,\r\n plantStorageLocations: { data: data.data, loading: false }\r\n }),\r\n [GET_MP_PR_ITEM_FIELDS.REQUEST]: () => ({\r\n ...state,\r\n prItemFields: { data: state.prItemFields.data, loading: true }\r\n }),\r\n [GET_MP_PR_ITEM_FIELDS.SUCCESS]: (data) => ({\r\n ...state,\r\n prItemFields: { data: data.data, loading: false }\r\n }),\r\n [GET_MP_ORDER_GL_ACCOUNT.REQUEST]: (data) => ({\r\n ...state,\r\n orderGlAccounts: { data: data.withInactive ? state.orderGlAccounts.data : [], loading: true },\r\n allOrderGlAccounts: { data: data.withInactive ? [] : state.allOrderGlAccounts.data, loading: true },\r\n }),\r\n [GET_MP_ORDER_GL_ACCOUNT.SUCCESS]: (data) => ({\r\n ...state,\r\n orderGlAccounts: { data: data.withInactive ? state.orderGlAccounts.data : data.data, loading: false },\r\n allOrderGlAccounts: { data: data.withInactive ? data.data : state.allOrderGlAccounts.data, loading: false },\r\n }),\r\n [GET_MP_WBS_ASSETS.REQUEST]: (data) => ({\r\n ...state,\r\n wbsAssets: { data: data.withInactive ? state.wbsAssets.data : [], loading: true },\r\n allWbsAssets: { data: data.withInactive ? [] : state.allWbsAssets.data, loading: true },\r\n }),\r\n [GET_MP_WBS_ASSETS.SUCCESS]: (data) => ({\r\n ...state,\r\n wbsAssets: { data: data.withInactive ? state.wbsAssets.data : data.data, loading: false },\r\n allWbsAssets: { data: data.withInactive ? data.data : state.allWbsAssets.data, loading: false },\r\n }),\r\n [SET_FORM_ORDER_GL_ACCOUNT]: (data) => ({\r\n ...state,\r\n formOrderGlAccount: data.data || { id: 0, orderNo: '', glAccount: '', active: true }\r\n }),\r\n [GET_ASSET_TYPES.REQUEST]: () => ({\r\n ...state,\r\n assetTypes: { data: [], loading: true }\r\n }),\r\n [GET_ASSET_TYPES.SUCCESS]: (data) => ({\r\n ...state,\r\n assetTypes: { data: data.data, loading: false }\r\n }),\r\n [SET_FORM_WBS_ASSET]: (data) => ({\r\n ...state,\r\n formWbsAsset: data.data || { \r\n id: 0, \r\n company: '', \r\n wbsElementCode: '', \r\n assetCode: '',\r\n assetType: '',\r\n active: true \r\n }\r\n }),\r\n [GET_ALL_WBS.REQUEST]: () => ({\r\n ...state,\r\n allWbs: { data: [], loading: true }\r\n }),\r\n [GET_ALL_WBS.SUCCESS]: (data) => ({\r\n ...state,\r\n allWbs: { data: data.data, loading: false }\r\n }),\r\n}))\r\n","import { takeLatest, put, select } from 'redux-saga/effects'\r\nimport { createReducer, makeAction, makeKeys, urlWithPrefix } from './helper'\r\nimport { httpPost, httpGet, httpDelete, httpPut } from '../core/restClient'\r\nimport { appLoading, appLoaded, toastError, toastSuccess } from './app'\r\nimport { homePath, purchaseRequisitionPath, purchaseRequisitionEditPath, purchaseRequisitionDetailPath } from '../routes'\r\nimport { clearOtherProject, getProjectByCompany } from './goa'\r\nimport {\r\n getUnits,\r\n getCurrencies,\r\n getPrTypes,\r\n getPrCategories,\r\n getMaterialGroups,\r\n getBudgetTypes as getBudgetTypesOption,\r\n getAccountAssignments,\r\n getPurchasingOrgs,\r\n getPlants,\r\n getStorageLocations,\r\n getPurchasingGroups,\r\n getGlAccounts,\r\n getCostCenter,\r\n getOrders,\r\n getCompanies,\r\n getCustomers,\r\n getAssets,\r\n getProfitCenters,\r\n} from './options'\r\nimport {\r\n getMappingWbsAssets,\r\n getMappingOderGlAccounts,\r\n getMappingPrItemFields,\r\n getMappingPurchasingGroups,\r\n getMappingCompanyPlants,\r\n getMappingPlantStorageLocations\r\n} from './mappingData'\r\nimport {\r\n getHrmsMembers\r\n} from './member'\r\nimport {\r\n getGoaItem\r\n} from './goa'\r\nimport r from 'reactotron-react-js'\r\n\r\nconst GET_PR_MENUS = makeKeys('GET_PR_MENUS')\r\nconst GET_GL_ACCOUNT = makeKeys('GET_GL_ACCOUNT')\r\nconst GET_ATTACHMENT_TYPES = makeKeys('GET_ATTACHMENT_TYPES')\r\nconst GET_PR_DETAIL = makeKeys('GET_PR_DETAIL')\r\nconst GET_PR_APPROVER_ACTION = makeKeys('GET_PR_APPROVER_ACTION')\r\nconst GET_PR_WORKFLOW_APPROVER_VIEW = makeKeys('GET_PR_WORKFLOW_APPROVER_VIEW')\r\nconst FETCH_PR_LIST = makeKeys('FETCH_PR_LIST')\r\nconst SHOW_PR_ITEM_MODAL = 'SHOW_PR_ITEM_MODAL'\r\nconst USER_SN = 'USER_SN'\r\nconst K2_ERROR = 'K2_ERROR'\r\nconst EMAIL_LOOP = 'EMAIL_LOOP'\r\nconst SELECT_SUBCATEGORY = 'SELECT_SUBCATEGORY'\r\nconst GET_PR_WORKFLOW_APPROVER = makeKeys('GET_PR_WORKFLOW_APPROVER')\r\nconst CREATE_PR = makeKeys('CREATE_PR')\r\nconst UPDATE_PR = makeKeys('UPDATE_PR')\r\nconst UPLOAD_PR_ATTACHMENTS = makeKeys('UPLOAD_PR_ATTACHMENTS')\r\nconst APPROVER_PR_ACTION = makeKeys('APPROVER_PR_ACTION')\r\nconst SUBMIT_PR = makeKeys('SUBMIT_PR')\r\nconst RE_SUBMIT_PR = makeKeys('RE_SUBMIT_PR')\r\nconst GET_PR_FORM_DATA = makeKeys('GET_PR_FORM_DATA')\r\nconst DELETE_PR = makeKeys('DELETE_PR')\r\nconst VALIDATE_BUDGET = makeKeys('VALIDATE_BUDGET')\r\nconst INITIALIZE_EDIT_PR = makeKeys('INITIALIZE_EDIT_PR')\r\nconst INITIALIZE_DETAIL_PR = makeKeys('INITIALIZE_DETAIL_PR')\r\nconst GET_RECOMMEND_ITEMS = makeKeys('GET_RECOMMEND_ITEMS')\r\nconst GET_MATERIAL_DETAIL = makeKeys('GET_MATERIAL_DETAIL')\r\nconst PRDETAIL_CLEAR_DATA = 'PRDETAIL_CLEAR_DATA'\r\nconst ADD_PR_SPECIAL_COMMENT = 'ADD_PR_SPECIAL_COMMENT'\r\n\r\nexport const getPrMenus = makeAction(GET_PR_MENUS.REQUEST)\r\nexport const getPRDetail = makeAction(GET_PR_DETAIL.REQUEST, 'prId', 'history', 'isRefresh')\r\nexport const clearPRDetailData = makeAction(PRDETAIL_CLEAR_DATA)\r\nexport const getPRApproverAction = makeAction(GET_PR_APPROVER_ACTION.REQUEST, 'prDocNumber')\r\nexport const getWorkflowApproverView = makeAction(GET_PR_WORKFLOW_APPROVER_VIEW.REQUEST, 'prId')\r\nexport const getWorkflowApprover = makeAction(GET_PR_WORKFLOW_APPROVER.REQUEST, 'data')\r\nexport const fetchPRList = makeAction(FETCH_PR_LIST.REQUEST, 'search')\r\nexport const getGlAccount = makeAction(GET_GL_ACCOUNT.REQUEST, 'subCategory')\r\nexport const getAttachmentTypes = makeAction(GET_ATTACHMENT_TYPES.REQUEST)\r\nexport const showPrItemModal = makeAction(SHOW_PR_ITEM_MODAL, 'show', 'isNew', 'data', 'submitData')\r\nexport const selectSubCategory = makeAction(SELECT_SUBCATEGORY, 'subCategory')\r\nexport const createPr = makeAction(CREATE_PR.REQUEST, 'data', 'submit', 'history', 'showAppLoading')\r\nexport const updatePr = makeAction(UPDATE_PR.REQUEST, 'data', 'submit', 'history', 'showAppLoading')\r\nexport const uploadPrAttachments = makeAction(UPLOAD_PR_ATTACHMENTS.REQUEST, 'id', 'data', 'submit', 'comment', 'history', 'showAppLoading')\r\nexport const approverPRAction = makeAction(APPROVER_PR_ACTION.REQUEST, 'data')\r\nexport const submitPr = makeAction(SUBMIT_PR.REQUEST, 'id', 'history')\r\nexport const reSubmitPr = makeAction(RE_SUBMIT_PR.REQUEST, 'comment', 'history')\r\nexport const getPrFormData = makeAction(GET_PR_FORM_DATA.REQUEST, 'id', 'history')\r\nexport const clearPrFormData = makeAction(GET_PR_FORM_DATA.SUCCESS, 'data')\r\nexport const deletePr = makeAction(DELETE_PR.REQUEST, 'id', 'data', 'history')\r\nexport const validateBudget = makeAction(VALIDATE_BUDGET.REQUEST, 'data', 'onGetBudgetSuccess')\r\nexport const initializeEditPR = makeAction(INITIALIZE_EDIT_PR.REQUEST)\r\nexport const initializeDetailPR = makeAction(INITIALIZE_DETAIL_PR.REQUEST)\r\nexport const getRecommendItems = makeAction(GET_RECOMMEND_ITEMS.REQUEST, 'retry')\r\nexport const getMaterialDetail = makeAction(GET_MATERIAL_DETAIL.REQUEST, 'code', 'onGetMaterialSuccess', 'retry')\r\nexport const addSpecialComment = makeAction(ADD_PR_SPECIAL_COMMENT, 'id', 'data', 'history')\r\n\r\nconst getPrMenusSuccess = makeAction(GET_PR_MENUS.SUCCESS, 'data')\r\nconst getPRDetailSuccess = makeAction(GET_PR_DETAIL.SUCCESS, 'data')\r\nconst getPRApproverActionItemSuccess = makeAction(GET_PR_APPROVER_ACTION.SUCCESS, 'data')\r\nconst getWorkflowApproverViewSuccess = makeAction(GET_PR_WORKFLOW_APPROVER_VIEW.SUCCESS, 'data')\r\nconst fetchPRListSuccess = makeAction(FETCH_PR_LIST.SUCCESS, 'data')\r\nconst getGlAccountSuccess = makeAction(GET_GL_ACCOUNT.SUCCESS, 'data')\r\nconst getAttachmentTypesSuccess = makeAction(GET_ATTACHMENT_TYPES.SUCCESS, 'data')\r\nconst getWorkflowApproverSuccess = makeAction(GET_PR_WORKFLOW_APPROVER.SUCCESS, 'data')\r\nconst createPrSuccess = makeAction(CREATE_PR.SUCCESS, 'data')\r\nconst updatePrSuccess = makeAction(UPDATE_PR.SUCCESS, 'data')\r\nconst uploadPrAttachmentsSuccess = makeAction(UPLOAD_PR_ATTACHMENTS.SUCCESS)\r\nconst approverPRActionSuccess = makeAction(APPROVER_PR_ACTION.SUCCESS)\r\nconst setUserSN = makeAction(USER_SN, 'data')\r\nconst setCheckK2Error = makeAction(K2_ERROR, 'data')\r\nconst setEmailLoop = makeAction(EMAIL_LOOP, 'data')\r\nconst submitPrSuccess = makeAction(SUBMIT_PR.SUCCESS, 'data')\r\nconst reSubmitPrSuccess = makeAction(RE_SUBMIT_PR.SUCCESS, 'data')\r\nconst getPrFormDataSuccess = makeAction(GET_PR_FORM_DATA.SUCCESS, 'data')\r\nconst validateBudgetSuccess = makeAction(VALIDATE_BUDGET.SUCCESS, 'data')\r\nconst getRecommendItemsSuccess = makeAction(GET_RECOMMEND_ITEMS.SUCCESS, 'data')\r\n\r\nconst getWorkflowApproverFailure = makeAction(GET_PR_WORKFLOW_APPROVER.FAILURE)\r\nconst getWorkflowApproverViewFailure = makeAction(GET_PR_WORKFLOW_APPROVER_VIEW.FAILURE)\r\n\r\nconst initial = {\r\n loading: false,\r\n menuLoading: false,\r\n menus: [],\r\n showPrItemModal: false,\r\n isNewPrItem: true,\r\n prDetail: { data: {}, loading: true },\r\n prItem: {},\r\n prList: {},\r\n approverAction: null,\r\n prEmailLoop: [],\r\n userSN: '',\r\n checkK2Error: null,\r\n glAccounts: [],\r\n glLoading: false,\r\n attachmentTypes: [],\r\n attachmentTypeLoading: false,\r\n subCategory: {},\r\n approvers: [],\r\n approverLoading: false,\r\n onSubmitItem: () => { },\r\n prFormData: {},\r\n budgets: [],\r\n validatingBudget: true,\r\n recommendItems: { data: [], loading: false },\r\n}\r\n\r\nconst prApiPath = path => path ? urlWithPrefix(`purchaseRequisitions/${path}`) : urlWithPrefix('purchaseRequisitions')\r\nconst multipartHeader = { 'Content-Type': 'multipart/form-data', }\r\n\r\nfunction* getPRDetailRequest(action) {\r\n const { prId, history } = action.payload\r\n let prDetail\r\n let username = localStorage.getItem('username').toLowerCase()\r\n try {\r\n yield put(appLoading())\r\n prDetail = yield httpGet(urlWithPrefix(`purchaseRequisitions/${prId}`))\r\n if (prDetail.status === 200) {\r\n if (prDetail.data) {\r\n if (prDetail.data.deleted) {\r\n yield put(appLoaded())\r\n yield put(setCheckK2Error({ isError: false, msg: '' }))\r\n yield put(getPRDetailSuccess({}))\r\n yield put(getPRApproverActionItemSuccess(null))\r\n yield put(setUserSN(''))\r\n yield put(toastError('Document does not exist or document is deleted'))\r\n history.push(purchaseRequisitionPath)\r\n } else if ([0, '0'].indexOf(prDetail.data.status) >= 0 && (username === prDetail.data.createdByUser.toLowerCase())) {\r\n yield put(appLoaded())\r\n yield put(setCheckK2Error({ isError: false, msg: '' }))\r\n yield put(getPRDetailSuccess({}))\r\n yield put(getPRApproverActionItemSuccess(null))\r\n yield put(setUserSN(''))\r\n yield put(getPrFormData(prId, history))\r\n history.push(purchaseRequisitionEditPath(prId))\r\n } else if ([5, '5'].indexOf(prDetail.data.status) >= 0 && (username === prDetail.data.createdByUser.toLowerCase() || username === prDetail.data.requesterUser.toLowerCase())) {\r\n yield put(appLoaded())\r\n yield put(setCheckK2Error({ isError: false, msg: '' }))\r\n yield put(getPRDetailSuccess({}))\r\n yield put(getPRApproverActionItemSuccess(null))\r\n yield put(setUserSN(''))\r\n yield put(getPrFormData(prId, history))\r\n history.push(purchaseRequisitionEditPath(prId))\r\n } else {\r\n const attachmentTypes = yield httpGet(prApiPath('attachmentTypes'))\r\n prDetail.data['attachmentTypes'] = attachmentTypes.data\r\n // const resApproverView = yield httpGet(prApiPath(`workflowApproverView?prID=${prId}`))\r\n // yield put(getWorkflowApproverViewSuccess(resApproverView.data))\r\n yield put(getWorkflowApproverView(prDetail.data.id))\r\n // yield put(setEmailLoop(setDupEmailLoop(resApproverView.data)))\r\n //check K2 Error\r\n const checkK2Error = yield httpGet(`share/workflow/getErrorWorkflow?procInstID=${prDetail.data.procInstId}&subProcInstID=${prDetail.data.subProcInstId || 0}`)\r\n if (checkK2Error.status === 200) {\r\n if (checkK2Error.data.success) {\r\n //Get SN\r\n const resSN = yield httpGet(`share/workflow/getK2SN?refDocNumber=${prDetail.data.documentNumber}`)\r\n if (resSN.status === 200) {\r\n if (resSN.data.success) {\r\n yield put(setCheckK2Error({ isError: false, msg: '' }))\r\n yield put(setUserSN(resSN.data.message))\r\n //Get Action\r\n const resWorkflowAction = yield httpGet(`share/workflow/getWorkflowActionItem?serialNumber=${resSN.data.message}`)\r\n if (resWorkflowAction.data) {\r\n yield put(getPRApproverActionItemSuccess(resWorkflowAction.data))\r\n }\r\n }\r\n }\r\n } else {\r\n yield put(setCheckK2Error({ isError: true, msg: checkK2Error.data.message }))\r\n yield put(getPRDetailSuccess(prDetail.data))\r\n yield put(getPRApproverActionItemSuccess(null))\r\n yield put(setUserSN(''))\r\n }\r\n }\r\n yield put(getPRDetailSuccess(prDetail.data))\r\n yield put(appLoaded())\r\n }\r\n }\r\n }\r\n } catch (e) {\r\n if (e && e.config && e.config.headers && e.config.headers.Authorization === 'Bearer null') {\r\n yield put(appLoaded())\r\n yield put(getPRDetail(prId, history))\r\n } else {\r\n if (prDetail && prDetail.status === 200) {\r\n if (prDetail.data) {\r\n yield put(setCheckK2Error({ isError: false, msg: '' }))\r\n yield put(getPRDetailSuccess(prDetail.data))\r\n }\r\n } else {\r\n yield put(setCheckK2Error({ isError: false, msg: '' }))\r\n yield put(getPRDetailSuccess({}))\r\n yield put(toastError('Could not connect to server, please try again in a few minutes'))\r\n }\r\n yield put(getPRApproverActionItemSuccess(null))\r\n yield put(setUserSN(''))\r\n yield put(appLoaded())\r\n }\r\n }\r\n}\r\n\r\nfunction setDupEmailLoop(data) {\r\n const result = [];\r\n const map = new Map();\r\n let emailLoop = []\r\n data.forEach((item, i) => {\r\n item.approval.forEach((iItem, ii, iArray) => {\r\n if (iItem.email.length > 0) {\r\n emailLoop.push(\r\n {\r\n key: `${i}|${ii}`,\r\n text: `${iItem.displayName}${iItem.position ? `(${iItem.position})` : ''}`,\r\n value: iItem.email\r\n },\r\n )\r\n }\r\n })\r\n })\r\n for (const item of emailLoop) {\r\n if (!map.has(item.value)) {\r\n map.set(item.value, true); // set any value to Map\r\n result.push({\r\n key: item.key,\r\n text: item.text,\r\n value: item.value\r\n });\r\n }\r\n }\r\n return result\r\n}\r\n\r\nfunction* fetchPRListRequest(action) {\r\n const { search } = action.payload\r\n try {\r\n yield put(appLoading())\r\n\r\n yield put(getWorkflowApproverViewSuccess([]))\r\n yield put(setEmailLoop([]))\r\n yield put(setCheckK2Error(null))\r\n yield put(getPRDetailSuccess({}))\r\n yield put(getPRApproverActionItemSuccess(null))\r\n yield put(setUserSN(''))\r\n\r\n const response = yield httpGet(prApiPath(), search)\r\n yield put(appLoaded())\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(fetchPRListSuccess(response.data))\r\n }\r\n }\r\n } catch (e) {\r\n if (e && e.config && e.config.headers && e.config.headers.Authorization === 'Bearer null') {\r\n yield put(fetchPRList(search))\r\n }\r\n\r\n if (e.data && e.data.message) {\r\n yield put(toastError(e.data.message))\r\n } \r\n\r\n yield put(appLoaded())\r\n }\r\n}\r\n\r\nfunction* getPrMenusRequest(action) {\r\n try {\r\n const response = yield httpGet(urlWithPrefix('purchaseRequisitions/menus'))\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getPrMenusSuccess(response.data))\r\n }\r\n }\r\n } catch (e) {\r\n }\r\n}\r\n\r\nfunction* getGlAccountRequest(action) {\r\n const { subCategory } = action.payload\r\n try {\r\n const response = yield httpGet(prApiPath(`glAccounts/${subCategory}`))\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getGlAccountSuccess(response.data))\r\n }\r\n }\r\n } catch (e) {\r\n }\r\n}\r\n\r\nfunction* getAttachmentTypesRequest(action) {\r\n try {\r\n const response = yield httpGet(prApiPath(`attachmentTypes`))\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getAttachmentTypesSuccess(response.data))\r\n }\r\n }\r\n } catch (e) {\r\n }\r\n}\r\n\r\nfunction* getWorkflowApproverRequest(action) {\r\n const { data } = action.payload\r\n const { createdByUser, requesterUser, companyCode, items, goaItemCode, isAsset, isIt, totalAmount,\r\n goaId, specialApprovalId,rentDays, specialReason, } = data\r\n\r\n const purchasingGroup = (items && items.length) ? items[0].purchasingGroup : null\r\n const currency = (items && items.length) ? items[0].currency : null\r\n\r\n try {\r\n let itemDel = items ? items.filter(x => x.deleted === true) : []\r\n if (items && items.length && (itemDel.length !== items.length)) {\r\n const response = yield httpGet(prApiPath(`workflowApprover`), {\r\n creater: createdByUser,\r\n requester: requesterUser,\r\n companycode: companyCode,\r\n purchGroup: purchasingGroup,\r\n goaItemCode,\r\n currency,\r\n isAsset,\r\n isIT: isIt,\r\n amount: totalAmount,\r\n goaId,\r\n specialApprovalId,\r\n days: rentDays,\r\n alternativeUser:'',\r\n specialReason,\r\n })\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getWorkflowApproverSuccess(response.data))\r\n }\r\n }\r\n } else {\r\n yield put(getWorkflowApproverFailure())\r\n }\r\n } catch (e) {\r\n yield put(toastError('Get workflow approver error'))\r\n yield put(getWorkflowApproverFailure())\r\n }\r\n}\r\n\r\nfunction* createPrRequest(action) {\r\n const { data, submit, history, showAppLoading } = action.payload\r\n try {\r\n yield put(appLoading('Save data.'))\r\n const response = yield httpPost(prApiPath(), data)\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(clearOtherProject())\r\n yield put(getProjectByCompany(data.companyCode))\r\n yield put(createPrSuccess(response.data))\r\n\r\n const { id } = response.data\r\n var attachmentsData = {}\r\n if (data.pr01) attachmentsData.pr01 = data.pr01\r\n if (data.pr02) attachmentsData.pr02 = data.pr02\r\n if (data.pr03) attachmentsData.pr03 = data.pr03\r\n if (data.pr04) attachmentsData.pr04 = data.pr04\r\n if (data.pr05) attachmentsData.pr05 = data.pr05\r\n if (data.pr06) attachmentsData.pr06 = data.pr06\r\n if (data.pr07) attachmentsData.pr07 = data.pr07\r\n if (data.pr08) attachmentsData.pr08 = data.pr08\r\n if (data.pr09) attachmentsData.pr09 = data.pr09\r\n if (data.pr10) attachmentsData.pr10 = data.pr10\r\n if (data.pr11) attachmentsData.pr11 = data.pr11\r\n if (data.pr12) attachmentsData.pr12 = data.pr12\r\n if (data.pr13) attachmentsData.pr13 = data.pr13\r\n if (data.pr14) attachmentsData.pr14 = data.pr14\r\n if (data.pr15) attachmentsData.pr15 = data.pr15\r\n\r\n yield put(uploadPrAttachments(id, attachmentsData, submit, '', history, showAppLoading))\r\n }\r\n }\r\n } catch (e) {\r\n yield put(appLoaded())\r\n }\r\n}\r\n\r\nfunction* updatePrRequest(action) {\r\n const { data, submit, history, showAppLoading } = action.payload\r\n try {\r\n yield put(appLoading('Save data.'))\r\n const response = yield httpPut(prApiPath(data.id), data)\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(clearOtherProject())\r\n yield put(getProjectByCompany(data.companyCode))\r\n yield put(updatePrSuccess(response.data))\r\n\r\n const { id } = data\r\n var attachmentsData = {}\r\n if (data.pr01) attachmentsData.pr01 = data.pr01\r\n if (data.pr02) attachmentsData.pr02 = data.pr02\r\n if (data.pr03) attachmentsData.pr03 = data.pr03\r\n if (data.pr04) attachmentsData.pr04 = data.pr04\r\n if (data.pr05) attachmentsData.pr05 = data.pr05\r\n if (data.pr06) attachmentsData.pr06 = data.pr06\r\n if (data.pr07) attachmentsData.pr07 = data.pr07\r\n if (data.pr08) attachmentsData.pr08 = data.pr08\r\n if (data.pr09) attachmentsData.pr09 = data.pr09\r\n if (data.pr10) attachmentsData.pr10 = data.pr10\r\n if (data.pr11) attachmentsData.pr11 = data.pr11\r\n if (data.pr12) attachmentsData.pr12 = data.pr12\r\n if (data.pr13) attachmentsData.pr13 = data.pr13\r\n if (data.pr14) attachmentsData.pr14 = data.pr14\r\n if (data.pr15) attachmentsData.pr15 = data.pr15\r\n\r\n yield put(uploadPrAttachments(id, { ...attachmentsData, status: data.status }, submit, data.comment, history, showAppLoading))\r\n }\r\n }\r\n } catch (e) {\r\n yield put(appLoaded())\r\n }\r\n}\r\n\r\nfunction* uploadPrDocRequest(action) {\r\n const { id, data, submit, history, comment, showAppLoading } = action.payload\r\n let fileCount = 0\r\n let countUploading = 1\r\n let fileName = ''\r\n Object.keys(data).forEach(x=>{\r\n let object = data[x]\r\n if(Array.isArray(object)){\r\n fileCount += object.length\r\n }\r\n })\r\n\r\n try {\r\n let keys = Object.keys(data)\r\n for(let i=0;i
= 0) {\r\n yield put(reSubmitPr(comment, history)) // case re-submit\r\n } else {\r\n yield put(submitPr(id, history))\r\n }\r\n } else {\r\n yield put(toastSuccess('Save purchase requisition success.'))\r\n yield put(appLoaded())\r\n history.push(purchaseRequisitionPath)\r\n }\r\n yield put(appLoaded())\r\n } catch (e) {\r\n yield put(toastError(`Upload Attachments fail on '${fileName}' (${countUploading}/${fileCount})`,true))\r\n history.push(purchaseRequisitionEditPath(id))\r\n yield put(appLoaded())\r\n }\r\n}\r\n\r\nfunction* getWorkflowApproverViewRequest(action) {\r\n const { prId } = action.payload\r\n try {\r\n const response = yield httpGet(prApiPath(`workflowApproverView?prID=${prId}`))\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(getWorkflowApproverViewSuccess(response.data))\r\n }\r\n }\r\n } catch (e) {\r\n yield put(toastError('Get workflow approver error'))\r\n yield put(getWorkflowApproverViewFailure())\r\n }\r\n}\r\n\r\nfunction* approverPRActionRequest(action) {\r\n const { data } = action.payload\r\n try {\r\n yield put(appLoading())\r\n const response = yield httpPost(prApiPath(`${data.prId}/actionApproval`), {\r\n docId: data.prId,\r\n sn: data.SN,\r\n action: data.action,\r\n comment: data.comment,\r\n commentAttachments: data.commentAttachments\r\n }, multipartHeader)\r\n yield put(appLoaded())\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data.success) {\r\n yield put(approverPRActionSuccess())\r\n yield put(getPRApproverActionItemSuccess(null))\r\n yield put(setUserSN(''))\r\n yield put(setCheckK2Error(null))\r\n yield put(getWorkflowApproverViewSuccess([]))\r\n yield put(setEmailLoop([]))\r\n if (data.history.location.search.includes('h=true')) {\r\n data.history.push(homePath)\r\n } else {\r\n data.history.push(purchaseRequisitionPath)\r\n }\r\n yield put(toastSuccess('Purchase requisition action success'))\r\n } else {\r\n }\r\n }\r\n } catch (e) {\r\n yield put(appLoaded())\r\n yield put(toastError('Purchase requisition action fail.'))\r\n }\r\n}\r\n\r\nfunction* getPRApproverActionRequest(action) {\r\n const { prDocNumber } = action.payload\r\n try {\r\n yield put(appLoading())\r\n const response = yield httpGet(`share/workflow/getK2SN?refDocNumber=${prDocNumber}`)\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data.success) {\r\n const response2 = yield httpGet(`share/workflow/getWorkflowActionItem?serialNumber=${response.data.message}`)\r\n if (response2.data) {\r\n yield put(getPRApproverActionItemSuccess(response.data))\r\n }\r\n }\r\n }\r\n yield put(appLoaded())\r\n } catch (e) {\r\n yield put(appLoaded())\r\n }\r\n}\r\n\r\nfunction* submitPrRequest(action) {\r\n const { id, history } = action.payload\r\n try {\r\n yield put(appLoading('Submitting data to approval.'))\r\n const response = yield httpPost(prApiPath(`${id}/submit`))\r\n yield put(appLoaded())\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n yield put(submitPrSuccess(response.data))\r\n history.push(purchaseRequisitionPath)\r\n yield put(toastSuccess('Submit purchase requisition success.'))\r\n }\r\n }\r\n } catch (e) {\r\n if (e && e.data && e.data.message) {\r\n yield put(toastError(e.data.message))\r\n history.push(purchaseRequisitionEditPath(id))\r\n } else {\r\n yield put(toastError('Submit data error!'))\r\n history.push(purchaseRequisitionEditPath(id))\r\n }\r\n yield put(appLoaded())\r\n }\r\n}\r\n\r\nfunction* reSubmitPrRequest(action) {\r\n const { comment, history } = action.payload\r\n const state = yield select()\r\n\r\n try {\r\n yield put(appLoading('Submitting data to approval.'))\r\n const response = yield httpPost(prApiPath('reSubmit'), {\r\n docId: state.pr.prFormData.pr.id,\r\n sn: state.pr.prFormData.sn,\r\n comment: comment\r\n })\r\n yield put(appLoaded())\r\n if (response.status === 200) {\r\n if (response.data) {\r\n yield put(reSubmitPrSuccess(response.data))\r\n history.push(purchaseRequisitionPath)\r\n yield put(toastSuccess('Submit purchase requisition success.'))\r\n }\r\n }\r\n } catch (e) {\r\n if (e && e.data && e.data.message) {\r\n yield put(toastError(e.data.message))\r\n } else {\r\n yield put(toastError('Submit data error!'))\r\n }\r\n yield put(appLoaded())\r\n }\r\n}\r\n\r\nfunction* deletePrRequest(action) {\r\n const { id, data, history } = action.payload\r\n try {\r\n yield put(appLoading('Deleting purchase requisition.'))\r\n const response = yield httpDelete(prApiPath(`${id}`), data)\r\n yield put(appLoaded())\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n history.push(purchaseRequisitionPath)\r\n yield put(toastSuccess('Delete purchase requisition success.'))\r\n }\r\n }\r\n } catch (e) {\r\n if (e && e.data && e.data.message) {\r\n yield put(toastError(e.data.message))\r\n } else {\r\n yield put(toastError('Delete purchase requisition error!'))\r\n }\r\n yield put(appLoaded())\r\n }\r\n}\r\n\r\nfunction* getPrFormDataRequest(action) {\r\n const { id, history } = action.payload\r\n let username = localStorage.getItem('username').toLowerCase()\r\n try {\r\n yield put(appLoading('Load purchase requisition data.'))\r\n const response = yield httpGet(prApiPath(`${id}/formData`))\r\n yield put(appLoaded())\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n if (response.data.pr.deleted) {\r\n history.push(purchaseRequisitionPath)\r\n yield put(toastError('Document does not exist or document is deleted'))\r\n }\r\n if (([0, '0'].indexOf(response.data.pr.status) >= 0 && (username === response.data.pr.createdByUser.toLowerCase())) ||\r\n ([5, '5'].indexOf(response.data.pr.status) >= 0 && (username === response.data.pr.createdByUser.toLowerCase() || username === response.data.pr.requesterUser.toLowerCase()))) {\r\n yield put(getPrFormDataSuccess(response.data))\r\n yield put(getGoaItem(response.data.pr.goaId, 'PurchaseRequisition'))\r\n yield put(getGlAccount(response.data.pr.menuSubCategory))\r\n } else {\r\n yield put(getPRDetail(response.data.pr.id, history))\r\n history.push(purchaseRequisitionDetailPath(response.data.pr.id))\r\n }\r\n }\r\n }\r\n } catch (e) {\r\n yield put(appLoaded())\r\n if (e && e.config && e.config.headers && e.config.headers.Authorization === 'Bearer null') {\r\n yield put(appLoaded())\r\n yield put(getPrFormData(id, history))\r\n } else {\r\n if (e && e.data && e.data.message) {\r\n yield put(toastError(`FormData:${e.data.message}`))\r\n } else {\r\n yield put(toastError('Get purchase requisition data error!'))\r\n }\r\n }\r\n }\r\n}\r\n\r\nfunction* validateBudgetRequest(action) {\r\n const { data, onGetBudgetSuccess } = action.payload\r\n try {\r\n const response = yield httpPost(prApiPath(`validateBudgetPR`), data)\r\n if (response.status >= 200 && response.status < 300) {\r\n if (response.data) {\r\n onGetBudgetSuccess(response.data)\r\n yield put(validateBudgetSuccess(response.data))\r\n }\r\n }\r\n } catch (e) {\r\n onGetBudgetSuccess([])\r\n yield put(validateBudgetSuccess([]))\r\n }\r\n}\r\n\r\nfunction* initializeEditPRRequest() {\r\n try {\r\n const state = yield select()\r\n if (!state.member.members.length) {\r\n yield put(getHrmsMembers())\r\n }\r\n if (!state.options.costCenters.data.length) {\r\n yield put(getCostCenter())\r\n }\r\n if (!state.options.orders.data.length) {\r\n yield put(getOrders())\r\n }\r\n if (!state.options.purchasingGroups.data.length) {\r\n yield put(getPurchasingGroups())\r\n }\r\n if (!state.options.glAccounts.data.length) {\r\n yield put(getGlAccounts())\r\n }\r\n if (!state.pr.attachmentTypes.length) {\r\n yield put(getAttachmentTypes())\r\n }\r\n if (!state.mappingData.companyPlants.data.length) {\r\n yield put(getMappingCompanyPlants())\r\n }\r\n if (!state.mappingData.plantStorageLocations.data.length) {\r\n yield put(getMappingPlantStorageLocations())\r\n }\r\n if (!state.mappingData.wbsAssets.data.length) {\r\n yield put(getMappingWbsAssets())\r\n }\r\n if (!state.mappingData.orderGlAccounts.data.length) {\r\n yield put(getMappingOderGlAccounts())\r\n }\r\n if (!state.pr.menus.length) {\r\n yield put(getPrMenus())\r\n }\r\n if (!state.options.units.data.length) {\r\n yield put(getUnits())\r\n }\r\n if (!state.options.currencies.data.length) {\r\n yield put(getCurrencies())\r\n }\r\n if (!state.options.prTypes.data.length) {\r\n yield put(getPrTypes())\r\n }\r\n if (!state.options.prCategories.data.length) {\r\n yield put(getPrCategories())\r\n }\r\n if (!state.options.materialGroups.data.length) {\r\n yield put(getMaterialGroups())\r\n }\r\n if (!state.options.budgetTypes.data.length) {\r\n yield put(getBudgetTypesOption())\r\n }\r\n if (!state.options.accountAssignments.data.length) {\r\n yield put(getAccountAssignments())\r\n }\r\n if (!state.options.purchasingOrgs.data.length) {\r\n yield put(getPurchasingOrgs())\r\n }\r\n if (!state.options.plants.data.length) {\r\n yield put(getPlants())\r\n }\r\n if (!state.options.storageLocations.data.length) {\r\n yield put(getStorageLocations())\r\n }\r\n if (!state.options.companies.data.length) {\r\n yield put(getCompanies())\r\n }\r\n if (!state.options.customers.data.length) {\r\n yield put(getCustomers())\r\n }\r\n if (!state.options.assets.data.length) {\r\n yield put(getAssets())\r\n }\r\n if (!state.mappingData.purchasingGroups.data.length) {\r\n yield put(getMappingPurchasingGroups())\r\n }\r\n if (state.mappingData.prItemFields.data.itemName.K === undefined) {\r\n yield put(getMappingPrItemFields())\r\n }\r\n if (!state.pr.recommendItems.data.length) {\r\n yield put(getRecommendItems())\r\n }\r\n if (!state.options.profitCenters.data.length) {\r\n yield put(getProfitCenters())\r\n }\r\n } catch (e) {\r\n console.log('eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee')\r\n console.log(e)\r\n }\r\n}\r\n\r\nfunction* initializeDetailPRRequest() {\r\n try {\r\n const state = yield select()\r\n if (!state.options.budgetTypes.data.length) {\r\n yield put(getBudgetTypesOption())\r\n }\r\n if (!state.options.assets.data.length) {\r\n yield put(getAssets())\r\n }\r\n if (!state.options.purchasingOrgs.data.length) {\r\n yield put(getPurchasingOrgs())\r\n }\r\n if (!state.options.purchasingGroups.data.length) {\r\n yield put(getPurchasingGroups())\r\n }\r\n if (!state.options.units.data.length) {\r\n yield put(getUnits())\r\n }\r\n if (!state.options.currencies.data.length) {\r\n yield put(getCurrencies())\r\n }\r\n if (!state.options.accountAssignments.data.length) {\r\n yield put(getAccountAssignments())\r\n }\r\n if (!state.options.materialGroups.data.length) {\r\n yield put(getMaterialGroups())\r\n }\r\n if (!state.options.plants.data.length) {\r\n yield put(getPlants())\r\n }\r\n if (!state.options.storageLocations.data.length) {\r\n yield put(getStorageLocations())\r\n }\r\n if (!state.options.glAccounts.data.length) {\r\n yield put(getGlAccounts())\r\n }\r\n if (!state.options.costCenters.data.length) {\r\n yield put(getCostCenter())\r\n }\r\n if (!state.options.orders.data.length) {\r\n yield put(getOrders())\r\n }\r\n if (!state.options.profitCenters.data.length) {\r\n yield put(getProfitCenters())\r\n }\r\n } catch (e) {\r\n console.log(e)\r\n }\r\n}\r\n\r\nfunction* getRecommendItemsRequest(action) {\r\n const { retry } = action.payload\r\n try {\r\n const response = yield httpGet(prApiPath(`recommendItems`))\r\n if (response.data) {\r\n yield put(getRecommendItemsSuccess(response.data))\r\n }\r\n } catch (e) {\r\n if (retry && retry > 3) {\r\n yield put(getRecommendItemsSuccess([]))\r\n } else {\r\n yield put(getRecommendItems(retry ? (retry + 1) : 1))\r\n }\r\n }\r\n}\r\n\r\nfunction* getMaterialDetailRequest(action) {\r\n const { code, onGetMaterialSuccess, retry } = action.payload\r\n\r\n try {\r\n yield put(appLoading('Loading material data.'))\r\n const response = yield httpGet('share/master/materialDetails', { materialCode: code })\r\n if (response.data) {\r\n yield put(appLoaded())\r\n onGetMaterialSuccess(response.data)\r\n }\r\n } catch (e) {\r\n if (retry && retry > 3) {\r\n yield put(appLoaded())\r\n yield put(toastError('Get material data failure!'))\r\n } else {\r\n yield put(getMaterialDetail(code, onGetMaterialSuccess, retry ? (retry + 1) : 1))\r\n }\r\n }\r\n}\r\n\r\nfunction* addSpecialCommentRequest(action) {\r\n const { id, data, history } = action.payload\r\n try {\r\n yield put(appLoading())\r\n const response = yield httpPost(`purchaseRequisitions/${id}/comment`, data, multipartHeader)\r\n if (response.status === 200) {\r\n yield put(appLoaded())\r\n yield put(toastSuccess('Add comment success'))\r\n yield put(getPRDetail(id, history, true))\r\n }\r\n }\r\n catch (e) {\r\n yield put(appLoaded())\r\n yield put(toastError('Add comment fail'))\r\n }\r\n}\r\n\r\nexport function* watchPurchaseRequisitionSaga() {\r\n yield takeLatest(GET_PR_MENUS.REQUEST, getPrMenusRequest)\r\n yield takeLatest(GET_PR_DETAIL.REQUEST, getPRDetailRequest)\r\n yield takeLatest(GET_PR_APPROVER_ACTION.REQUEST, getPRApproverActionRequest)\r\n yield takeLatest(GET_PR_WORKFLOW_APPROVER_VIEW.REQUEST, getWorkflowApproverViewRequest)\r\n yield takeLatest(GET_PR_WORKFLOW_APPROVER.REQUEST, getWorkflowApproverRequest)\r\n yield takeLatest(FETCH_PR_LIST.REQUEST, fetchPRListRequest)\r\n yield takeLatest(GET_GL_ACCOUNT.REQUEST, getGlAccountRequest)\r\n yield takeLatest(GET_ATTACHMENT_TYPES.REQUEST, getAttachmentTypesRequest)\r\n yield takeLatest(CREATE_PR.REQUEST, createPrRequest)\r\n yield takeLatest(UPDATE_PR.REQUEST, updatePrRequest)\r\n yield takeLatest(UPLOAD_PR_ATTACHMENTS.REQUEST, uploadPrDocRequest)\r\n yield takeLatest(APPROVER_PR_ACTION.REQUEST, approverPRActionRequest)\r\n yield takeLatest(SUBMIT_PR.REQUEST, submitPrRequest)\r\n yield takeLatest(RE_SUBMIT_PR.REQUEST, reSubmitPrRequest)\r\n yield takeLatest(DELETE_PR.REQUEST, deletePrRequest)\r\n yield takeLatest(GET_PR_FORM_DATA.REQUEST, getPrFormDataRequest)\r\n yield takeLatest(VALIDATE_BUDGET.REQUEST, validateBudgetRequest)\r\n yield takeLatest(INITIALIZE_EDIT_PR.REQUEST, initializeEditPRRequest)\r\n yield takeLatest(INITIALIZE_DETAIL_PR.REQUEST, initializeDetailPRRequest)\r\n yield takeLatest(GET_RECOMMEND_ITEMS.REQUEST, getRecommendItemsRequest)\r\n yield takeLatest(GET_MATERIAL_DETAIL.REQUEST, getMaterialDetailRequest)\r\n yield takeLatest(ADD_PR_SPECIAL_COMMENT, addSpecialCommentRequest)\r\n}\r\n\r\nexport default createReducer(initial, state => ({\r\n [GET_PR_DETAIL.REQUEST]: (data) => {\r\n if (data.isRefresh) {\r\n return ({ ...state })\r\n } else {\r\n return ({\r\n ...state,\r\n prDetail: { data: {}, loading: true },\r\n loading: true\r\n })\r\n }\r\n },\r\n [GET_PR_DETAIL.SUCCESS]: (data) => {\r\n let username = localStorage.getItem('username').toLowerCase()\r\n let x = data.data\r\n if (Object.keys(x).length) {\r\n if (x.status == 2 && x.requesterUser.toLowerCase() == username) {\r\n x.canComment = true\r\n }\r\n }\r\n return ({\r\n ...state,\r\n prDetail: { data: x, loading: false },\r\n loading: false\r\n })\r\n },\r\n [USER_SN]: (data) => ({\r\n ...state,\r\n userSN: data.data\r\n }),\r\n [K2_ERROR]: (data) => ({\r\n ...state,\r\n checkK2Error: data.data\r\n }),\r\n [EMAIL_LOOP]: (data) => ({\r\n ...state,\r\n prEmailLoop: data.data\r\n }),\r\n [FETCH_PR_LIST.REQUEST]: () => ({\r\n ...state,\r\n loading: true\r\n }),\r\n [FETCH_PR_LIST.SUCCESS]: (data) => ({\r\n ...state,\r\n prList: data.data,\r\n loading: false\r\n }),\r\n [GET_PR_APPROVER_ACTION.REQUEST]: () => ({\r\n ...state\r\n }),\r\n [GET_PR_APPROVER_ACTION.SUCCESS]: (data) => ({\r\n ...state,\r\n approverAction: data.data\r\n }),\r\n [GET_PR_WORKFLOW_APPROVER_VIEW.REQUEST]: () => ({\r\n ...state,\r\n approverLoading: true\r\n }),\r\n [GET_PR_WORKFLOW_APPROVER_VIEW.SUCCESS]: (data) => ({\r\n ...state,\r\n approvers: data.data,\r\n approverLoading: false\r\n }),\r\n [GET_PR_WORKFLOW_APPROVER_VIEW.FAILURE]: (data) => ({\r\n ...state,\r\n approvers: [],\r\n approverLoading: false\r\n }),\r\n [GET_PR_MENUS.REQUEST]: () => ({\r\n ...state,\r\n menuLoading: true\r\n }),\r\n [GET_PR_MENUS.SUCCESS]: (data) => ({\r\n ...state,\r\n menus: data.data,\r\n menuLoading: false\r\n }),\r\n [GET_PR_MENUS.FAILURE]: () => ({\r\n ...state,\r\n menuLoading: false\r\n }),\r\n [GET_GL_ACCOUNT.REQUEST]: () => ({\r\n ...state,\r\n glAccounts: [],\r\n glLoading: true\r\n }),\r\n [GET_GL_ACCOUNT.SUCCESS]: (data) => ({\r\n ...state,\r\n glAccounts: data.data,\r\n glLoading: false\r\n }),\r\n [GET_ATTACHMENT_TYPES.REQUEST]: () => ({\r\n ...state,\r\n attachmentTypes: [],\r\n attachmentTypeLoading: true\r\n }),\r\n [GET_ATTACHMENT_TYPES.SUCCESS]: (data) => ({\r\n ...state,\r\n attachmentTypes: data.data,\r\n attachmentTypeLoading: false\r\n }),\r\n [SHOW_PR_ITEM_MODAL]: (data) => ({\r\n ...state,\r\n showPrItemModal: data.show,\r\n isNewPrItem: data.isNew !== undefined ? data.isNew : true,\r\n onSubmitItem: data.submitData || (() => { }),\r\n prItem: data.data || {},\r\n }),\r\n [GET_PR_WORKFLOW_APPROVER.REQUEST]: () => ({\r\n ...state,\r\n approverLoading: true,\r\n }),\r\n [GET_PR_WORKFLOW_APPROVER.SUCCESS]: (data) => ({\r\n ...state,\r\n approvers: data.data,\r\n approverLoading: false,\r\n }),\r\n [GET_PR_WORKFLOW_APPROVER.FAILURE]: () => ({\r\n ...state,\r\n approvers: [],\r\n approverLoading: false,\r\n }),\r\n [CREATE_PR.REQUEST]: () => ({\r\n ...state,\r\n loading: true\r\n }),\r\n [CREATE_PR.SUCCESS]: () => ({\r\n ...state,\r\n loading: false\r\n }),\r\n [UPDATE_PR.REQUEST]: () => ({\r\n ...state,\r\n loading: true\r\n }),\r\n [UPDATE_PR.SUCCESS]: () => ({\r\n ...state,\r\n loading: false\r\n }),\r\n [UPLOAD_PR_ATTACHMENTS.REQUEST]: () => ({\r\n ...state,\r\n loading: true\r\n }),\r\n [UPLOAD_PR_ATTACHMENTS.SUCCESS]: () => ({\r\n ...state,\r\n loading: false\r\n }),\r\n [APPROVER_PR_ACTION.REQUEST]: () => ({\r\n ...state,\r\n loading: true\r\n }),\r\n [APPROVER_PR_ACTION.SUCCESS]: () => ({\r\n ...state,\r\n loading: false\r\n }),\r\n [SELECT_SUBCATEGORY]: (data) => ({\r\n ...state,\r\n subCategory: data.subCategory,\r\n }),\r\n [GET_PR_FORM_DATA.REQUEST]: () => ({\r\n ...state,\r\n prDataLoading: true,\r\n }),\r\n [GET_PR_FORM_DATA.SUCCESS]: (data) => ({\r\n ...state,\r\n prFormData: data.data,\r\n prDataLoading: false,\r\n }),\r\n [VALIDATE_BUDGET.REQUEST]: () => ({\r\n ...state,\r\n budgets: [],\r\n validatingBudget: true,\r\n }),\r\n [VALIDATE_BUDGET.SUCCESS]: (data) => ({\r\n ...state,\r\n budgets: data.data,\r\n validatingBudget: false,\r\n }),\r\n [GET_RECOMMEND_ITEMS.REQUEST]: () => ({\r\n ...state,\r\n recommendItems: { data: [], loading: false },\r\n }),\r\n [GET_RECOMMEND_ITEMS.SUCCESS]: (data) => ({\r\n ...state,\r\n recommendItems: { data: data.data, loading: true },\r\n }),\r\n [PRDETAIL_CLEAR_DATA]: (data) => ({\r\n ...state,\r\n recommendItems: { data: data.data, loading: true },\r\n }),\r\n}))","import React from 'react'\r\nimport Moment from 'react-moment'\r\nimport NumberFormat from 'react-number-format'\r\nimport { Icon } from 'semantic-ui-react'\r\nimport { StatusTag, DivText } from './styled'\r\n\r\nexport const options = {\r\n listSize: [\r\n { text: '30', value: 30 },\r\n { text: '60', value: 60 },\r\n { text: '90', value: 90 },\r\n { text: '120', value: 120 }\r\n ],\r\n} \r\n\r\nconst prStatus = {0:'Draft',2:'In Progress',3:'Revise',4:'Completed',5:'Reject',6:'Cancelled'}\r\n\r\nexport const columns = { \r\n tEditItem:[\r\n {\r\n Header: 'Action',\r\n accessor: 'id',\r\n width: 120,\r\n Cell: row => (\r\n \r\n \r\n \r\n \r\n
\r\n )\r\n },{\r\n Header: 'No.',\r\n accessor: 'lineNo',\r\n width: 100,\r\n },{\r\n Header: 'Name',\r\n accessor: 'itemName',\r\n width: 100,\r\n },{\r\n Header: 'Description',\r\n accessor: 'itemDescription',\r\n width: 100,\r\n },{\r\n Header: 'Quantity',\r\n accessor: 'quantity',\r\n width: 100,\r\n },{\r\n Header: 'Unit',\r\n accessor: 'unit',\r\n width: 100,\r\n },{\r\n Header: 'Unit Price(Ex.VAT)',\r\n accessor: 'unitPrice',\r\n width: 100,\r\n },{\r\n Header: 'Currency',\r\n accessor: 'currency',\r\n width: 100,\r\n },{\r\n Header: 'Total Amount(Ex.VAT)',\r\n accessor: 'totalAmount',\r\n width: 100,\r\n },{\r\n Header: 'Budget Type',\r\n accessor: 'budgetType',\r\n width: 100,\r\n },{\r\n Header: 'Cost Center',\r\n accessor: 'costCenter',\r\n width: 100,\r\n },{\r\n Header: 'GL Account',\r\n accessor: 'GLAccountCode',\r\n width: 100,\r\n },{\r\n Header: 'Acc. Assa',\r\n accessor: 'AccountAssignmentCategoryCode',\r\n width: 100,\r\n },{\r\n Header: 'StartDate',\r\n accessor: 'startDate',\r\n width: 100,\r\n Cell: row => (\r\n \r\n {row.value?\r\n {row.value} \r\n :\r\n '-'\r\n }\r\n )\r\n },{\r\n Header: 'Delivery Date/Finish Date',\r\n accessor: 'deliveryDate',\r\n width: 100,\r\n Cell: row => (\r\n \r\n {row.value?\r\n {row.value} \r\n :\r\n '-'\r\n }\r\n )\r\n },{\r\n Header: 'Plant',\r\n accessor: 'plant',\r\n width: 100,\r\n },{\r\n Header: 'StorageLocation',\r\n accessor: 'storageLocation',\r\n width: 100,\r\n },{\r\n Header: 'Purchasing Group',\r\n accessor: 'purchasingGroup',\r\n width: 100,\r\n },{\r\n Header: 'Material Group',\r\n accessor: 'materialGroup',\r\n width: 100,\r\n }\r\n ],\r\n tPRs: (companies) =>{\r\n return ([\r\n {\r\n Header: 'Status',\r\n accessor: 'status',\r\n width: 100,\r\n Cell:row=>({prStatus[row.value]} )\r\n },{\r\n Header: 'Doc No.',\r\n accessor : row =>(row.status === 0 ? '-' : row.docNo),\r\n id:'docNo',\r\n width: 100,\r\n Cell:row=>({row.value} )\r\n }, {\r\n Header: ()=>(Title ),\r\n accessor : row =>(row.title.trim()),\r\n id:'title',\r\n width: 250\r\n }, {\r\n Header: ()=>(Project name ),\r\n accessor: 'projectName',\r\n width: 100\r\n }, {\r\n Header: ()=>(Company ),\r\n id:'company',\r\n accessor : row =>{\r\n let x = null \r\n if(companies.length>0){\r\n x = companies.find(x=>x.value==row.companyCode)\r\n }\r\n return (x?x.text:`${row.companyCode}`)\r\n },\r\n width: 100\r\n }, {\r\n Header: 'Priority',\r\n accessor: 'priority',\r\n width: 70,\r\n Cell: row => (\r\n row.value && \r\n {row.value.toUpperCase()}
)\r\n },{\r\n Header: 'Current Activity',\r\n accessor: 'statusActivity',\r\n width: 70,\r\n },{\r\n Header: ()=>(Requester ),\r\n accessor: 'requesterName',\r\n width: 100,\r\n Cell: row => (row.value&&{`${row.value||'-'}`} )\r\n },\r\n // {\r\n // Header: 'Overdue',\r\n // id:'overdue',\r\n // accessor : row =>(Math.floor(row.pendingDays-row.slaDays)),\r\n // width: 70,\r\n // Cell: row => ({`${ row.value>=1?`(${row.value} days)`:'-'}`} )\r\n // }, \r\n {\r\n Header: 'Submitted date',\r\n accessor: 'submittedDate',\r\n width: 120,\r\n Cell: row => (row.value&&\r\n \r\n {row.value?\r\n {row.value} \r\n :\r\n '-'\r\n }\r\n )\r\n }, {\r\n Header: 'Modified date',\r\n accessor: 'modifiedDate',\r\n width: 120,\r\n Cell: row => (row.value&&{row.value} )\r\n }\r\n ])\r\n },\r\n tSummary: [\r\n {\r\n Header: 'Code',\r\n accessor: 'code',\r\n width: 150\r\n }, {\r\n Header: 'Description',\r\n accessor: 'description',\r\n width: 150\r\n }, {\r\n Header: 'Code2',\r\n accessor: 'code2',\r\n width: 150\r\n }, {\r\n Header: 'Description',\r\n accessor: 'description2',\r\n width: 150\r\n }, {\r\n Header: 'Plan',\r\n accessor: 'plan',\r\n width: 150,\r\n Cell: row => ()\r\n }, {\r\n Header: 'Actual',\r\n accessor: 'actual',\r\n width: 150,\r\n Cell: row => ()\r\n }, {\r\n Header: 'Commitment',\r\n accessor: 'commitment',\r\n width: 150,\r\n Cell: row => ()\r\n }, {\r\n Header: 'Assigned',\r\n accessor: 'assigned',\r\n width: 150,\r\n Cell: row => ()\r\n }, {\r\n Header: 'Available',\r\n accessor: 'available',\r\n width: 150,\r\n Cell: row => ()\r\n }, {\r\n Header: 'Currency',\r\n accessor: 'currency',\r\n width: 150\r\n }, {\r\n Header: 'Modify Date',\r\n accessor: 'modifiedDate',\r\n width: 100,\r\n Cell: row => ({row.value} )\r\n }\r\n ],\r\n tBudget:[\r\n {\r\n Header: 'Code',\r\n accessor: 'code',\r\n width: 150\r\n },\r\n {\r\n Header: 'Description',\r\n accessor: 'description',\r\n width: 150\r\n },\r\n {\r\n Header: 'Code2/GL Account',\r\n accessor: 'code2',\r\n width: 150\r\n },\r\n {\r\n Header: 'Description',\r\n accessor: 'description2',\r\n width: 150\r\n },\r\n {\r\n Header: 'Plan/Budget',\r\n accessor: 'plan',\r\n width: 150,\r\n Cell: row => ()\r\n },\r\n {\r\n Header: 'Actual',\r\n accessor: 'actual',\r\n width: 150,\r\n Cell: row => ()\r\n },\r\n {\r\n Header: 'Commitment',\r\n accessor: 'commitment',\r\n width: 150,\r\n Cell: row => ()\r\n },\r\n {\r\n Header: 'Assigned',\r\n accessor: 'assigned',\r\n width: 150,\r\n Cell: row => ()\r\n },\r\n {\r\n Header: 'Available',\r\n accessor: 'available',\r\n width: 150,\r\n Cell: row => ()\r\n },\r\n {\r\n Header: 'Currency',\r\n accessor: 'currency',\r\n width: 150\r\n },\r\n ],\r\n tDetail:[\r\n {\r\n Header: 'No.',\r\n accessor: 'lineNo',\r\n width: 40\r\n },\r\n {\r\n Header: 'Item Name',\r\n accessor: 'itemName',\r\n width: 150\r\n },\r\n {\r\n Header: 'Item Description',\r\n accessor: 'itemDescription',\r\n width: 150\r\n },\r\n {\r\n Header: 'Unit',\r\n accessor: 'unit',\r\n width: 150\r\n },\r\n {\r\n Header: 'Quantity',\r\n accessor: 'quantity',\r\n width: 150\r\n },\r\n {\r\n Header: 'Currency',\r\n accessor: 'currency',\r\n width: 150\r\n },\r\n {\r\n Header: 'Unit Price Estimated (Ex.VAT)',\r\n accessor: 'unitPrice',\r\n width: 150,\r\n Cell: row => ()\r\n },\r\n {\r\n Header: 'Total Amount Estimated (Ex.VAT)',\r\n accessor: 'totalAmount',\r\n width: 150,\r\n Cell: row => ()\r\n },\r\n {\r\n Header: 'Budget Type',\r\n accessor: 'budgetType',\r\n width: 150\r\n },\r\n {\r\n Header: 'Cost Center',\r\n accessor: 'costCenter',\r\n width: 150\r\n },\r\n {\r\n Header: 'WBS',\r\n accessor: 'wbs',\r\n width: 150\r\n },\r\n {\r\n Header: 'GL Account',\r\n accessor: 'glAccountCode',\r\n width: 150\r\n },\r\n {\r\n Header: 'Acc Assc',\r\n accessor: 'accountAssc',\r\n width: 150\r\n },\r\n {\r\n Header: 'Start Date',\r\n accessor: 'startDate',\r\n width: 150,\r\n Cell: row => ({row.value} )\r\n },\r\n {\r\n Header: 'Delivery Date/Finish Date',\r\n accessor: 'deliveryDate',\r\n width: 150,\r\n Cell: row => ({row.value} )\r\n },\r\n {\r\n Header: 'Plant',\r\n accessor: 'plant',\r\n width: 150\r\n },\r\n {\r\n Header: 'Storage Location',\r\n accessor: 'storageLocation',\r\n width: 150\r\n },\r\n {\r\n Header: 'Purchasing Org',\r\n accessor: 'purchasingOrg',\r\n width: 150\r\n },\r\n {\r\n Header: 'Material Group',\r\n accessor: 'materialGroup',\r\n width: 150\r\n }\r\n ]\r\n}\r\n\r\nexport const AdditionalRemark = () => {\r\n return (\r\n \r\n
ขอบเขตงานเพิ่ม:
\r\n
\r\n งานที่ทำตามขอบเขตหรือเนื้องานเดิมของ PO หลัก/สัญญาหลัก \r\n งานที่มีขอบเขตงานต่อเนื่องจาก PO หลัก/สัญญาหลัก ไม่สามารถให้รายอื่นทำแทนได้ \r\n งานที่ไม่ใช่เนื้องานเดิมแต่ทำในพื้นที่เดิม ให้เลือก Special PR > เหตุผลอื่นๆ > การจัดซื้อสินค้าหรือการจัดจ้างบริการที่เป็นการจัดซื้อจัดจ้างงานต่อเนื่องพื้นที่โครงการเดิม โดยเป็นขอบเขตงานใหม่ \r\n \r\n
\r\n )\r\n}","import React from 'react'\r\nimport { connect } from 'react-redux'\r\nimport { reduxForm, getFormValues } from 'redux-form'\r\nimport { Icon } from 'semantic-ui-react'\r\nimport ReactTable from 'react-table'\r\n// import r from 'reactotron-react-js'\r\n\r\nimport {\r\n purchaseRequisitionCreatePath,\r\n purchaseRequisitionDetailPath,\r\n purchaseRequisitionEditPath\r\n} from '../../'\r\nimport { ProcurementContainer, ProcurementBody } from '../styled'\r\nimport { PRListCont } from './styled'\r\nimport {\r\n fetchPRList\r\n} from 'ducks/purchaseRequisition'\r\nimport {\r\n getCompanies\r\n} from 'ducks/options'\r\nimport {\r\n columns\r\n} from './AttributeData'\r\nimport {\r\n MainBodyContent,\r\n CustomButton,\r\n SearchList,\r\n TablePagination\r\n} from 'components'\r\n\r\nconst PurchaseRequisition = (props) => {\r\n const {\r\n prList,\r\n valueForm\r\n } = props\r\n\r\n const userPageSize = parseInt(localStorage.getItem('userPageSize') || '10')\r\n const [pageSize, setPageSize] = React.useState(userPageSize)\r\n\r\n React.useEffect(() => {\r\n props.getCompanies()\r\n window.scrollTo(0, 0)\r\n props.fetchPRList({ page: 1, size: pageSize })\r\n }, [])\r\n\r\n return (\r\n \r\n props.history.push(purchaseRequisitionCreatePath)}\r\n icon='plus'\r\n btnColor='gray'\r\n title='Create' />\r\n \r\n }\r\n >\r\n \r\n \r\n \r\n \r\n 0 ? prList.data : []}\r\n columns={columns.tPRs(props.companies)}\r\n defaultPageSize={userPageSize}\r\n noDataText='No Purchase Requisition found'\r\n previousText={ }\r\n nextText={ }\r\n className=\"-striped -highlight\"\r\n\r\n PaginationComponent={TablePagination}\r\n pages={Object.keys(prList).length > 0 ? prList.totalPage : 0}\r\n currentPage={Object.keys(prList).length > 0 ? prList.page : 0}\r\n onPageChange={(pageIndex) => {\r\n props.fetchPRList({ ...valueForm, page: pageIndex + 1, size: pageSize })\r\n }}\r\n onPageSizeChange={(pageSize, pageIndex) => {\r\n setPageSize(pageSize)\r\n localStorage.setItem('userPageSize', pageSize)\r\n props.fetchPRList({ ...valueForm, page: pageIndex + 1, size: pageSize })\r\n }}\r\n\r\n getTdProps={(state, rowInfo, column, instance) => {\r\n return {\r\n onClick: (e, handleOriginal) => {\r\n if (rowInfo && column && column.Header !== \"\") {\r\n if ([0, 3, 5].indexOf(Number(rowInfo.original.status)) >= 0) {\r\n window.open(purchaseRequisitionEditPath(rowInfo.original.id))\r\n } else {\r\n window.open(purchaseRequisitionDetailPath(rowInfo.original.id))\r\n }\r\n }\r\n if (handleOriginal) {\r\n handleOriginal()\r\n }\r\n },\r\n }\r\n }}\r\n />\r\n \r\n \r\n \r\n \r\n )\r\n}\r\n\r\nconst mapStateToProps = (state) => ({\r\n initialValues: {\r\n formStep: 1\r\n },\r\n valueForm: getFormValues('formSearchPR')(state),\r\n prList: state.pr.prList,\r\n companies: state.options.companies.data\r\n})\r\n\r\nconst mapDispatchToProps = {\r\n fetchPRList,\r\n getCompanies\r\n}\r\n\r\nconst contForm = reduxForm({\r\n form: 'formSearchPR',\r\n enableReinitialize: true,\r\n})(PurchaseRequisition)\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(contForm)","import styled from '@emotion/styled'\r\nimport * as v from 'variables/styles'\r\n\r\nexport const RICont = styled.div((props) => ({\r\n display: 'flex',\r\n flex: 1,\r\n flexDirection: 'column',\r\n}))\r\n\r\nexport const RIContDetail = styled.div((props) => ({\r\n display: 'flex',\r\n marginTop: `${props.sub ? '0' : '1rem'}`,\r\n flexDirection: 'column',\r\n\r\n '&>div:first-child': {\r\n marginLeft: '0px',\r\n flex: 1\r\n },\r\n\r\n '&>div': {\r\n marginLeft: '0px',\r\n flex: 1\r\n },\r\n\r\n '@media only screen and (min-width: 600px)': {\r\n flexDirection: 'row',\r\n\r\n '&>div:first-child': {\r\n marginLeft: '0px',\r\n flex: 1\r\n },\r\n \r\n '&>div': {\r\n marginLeft: '1rem',\r\n flex: 1\r\n },\r\n },\r\n\r\n '@media only screen and (min-width: 769px)': {\r\n flexDirection: 'row',\r\n\r\n '&>div:first-child': {\r\n marginLeft: 0,\r\n flex: 1\r\n },\r\n \r\n '&>div': {\r\n marginLeft: '1rem',\r\n flex: 1\r\n },\r\n },\r\n\r\n}))","import styled from '@emotion/styled'\r\nimport * as v from '../../../../../variables/styles'\r\n\r\nexport const CellCont = styled.div((props) => ({\r\n display: 'flex',\r\n flexDirection:'column',\r\n \r\n '.title':{\r\n color:'#888888',\r\n fontSize:'0.8rem'\r\n },\r\n '.value':{\r\n padding:'0.5rem 1rem',\r\n flex:1,\r\n border: '1px solid rgba(34,36,38,.15)',\r\n borderRadius:'0.3rem',\r\n minHeight:'2.5rem',\r\n wordBreak: 'break-all',\r\n },\r\n\r\n '.right':{\r\n display: 'flex',\r\n justifyContent: 'flex-end'\r\n },\r\n\r\n '.areaText':{\r\n minHeight:'6rem',\r\n maxHeight:'6rem',\r\n overflowY:'scroll',\r\n wordWrap:'anywhere',\r\n wordBreak:'break-all'\r\n },\r\n\r\n}))\r\n\r\n\r\n","import React from 'react'\r\nimport Moment from 'react-moment'\r\nimport NumberFormat from 'react-number-format'\r\n\r\nimport { \r\n CellCont } from './styled'\r\n\r\nexport const DataCell = (props) => {\r\n\r\n return (\r\n
\r\n {props.title||\"\"}
\r\n {/* */}\r\n \r\n {!props.isDate?\r\n props.isNumber?\r\n \r\n :\r\n props.value||\"-\"\r\n :\r\n props.value?\r\n \r\n {props.value}\r\n \r\n :'-'\r\n }\r\n
\r\n \r\n )\r\n}","import React from 'react'\r\nimport { connect } from 'react-redux'\r\nimport { RICont, RIContDetail } from './styled'\r\nimport { StdCard } from 'components'\r\nimport { DataCell } from '../DataCell'\r\nimport { getSpecialApproval } from 'ducks/goa'\r\n\r\nconst RequestInfo = (props) => {\r\n const { prDetail, specialApprovals } = props\r\n const prData = prDetail.data || {}\r\n const prLoading = prDetail.loading\r\n\r\n React.useEffect(() => {\r\n if (prData.specialApprovalId) {\r\n props.getSpecialApproval(prData.projectId)\r\n }\r\n }, [prDetail])\r\n\r\n return (\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n )\r\n\r\n function getSpecialApproval() {\r\n if (!prLoading && prData.specialApprovalId) {\r\n if (specialApprovals[prData.projectId]) {\r\n let val = specialApprovals[prData.projectId].find(x => x.id === prData.specialApprovalId)\r\n if (val) {\r\n return val.name\r\n }\r\n }\r\n }\r\n return null\r\n }\r\n}\r\n\r\nconst mapStateToProps = (state) => ({\r\n prDetail: state.pr.prDetail,\r\n specialApprovals: state.goa.specialApprovals\r\n})\r\n\r\nconst mapDispatchToProps = {\r\n getSpecialApproval\r\n}\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(RequestInfo)\r\n","import styled from '@emotion/styled'\r\nimport * as v from 'variables/styles'\r\n\r\nexport const Cont = styled.div((props) => ({\r\n display: 'flex',\r\n flex: 1,\r\n flexDirection: 'column',\r\n}))\r\n\r\nexport const SContDetail = styled.div((props) => ({\r\n display: 'flex',\r\n marginTop: `${props.sub ? '0' : '1rem'}`,\r\n flexDirection: 'column',\r\n\r\n '&>div:first-child': {\r\n marginLeft: 0,\r\n flex: 1\r\n },\r\n '>div:first-child .toleft': {\r\n marginLeft: 0,\r\n flex: 1,\r\n display: 'flex',\r\n flexDirection: 'column'\r\n },\r\n '&>div': {\r\n marginLeft: '1rem',\r\n flex: 1\r\n },\r\n\r\n '@media only screen and (min-width: 600px)': {\r\n flexDirection: 'unset',\r\n },\r\n\r\n '@media only screen and (min-width: 769px)': {\r\n flexDirection: 'unset',\r\n },\r\n\r\n}))\r\n\r\nexport const TableCont = styled.div((props) => ({\r\n marginTop: '1rem',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n}))","import styled from '@emotion/styled'\r\nimport * as v from 'variables/styles'\r\n\r\nexport const Cont = styled.div((props) => ({\r\n display: 'flex',\r\n flex: 1,\r\n flexDirection: 'column',\r\n}))\r\n\r\nexport const SContDetail = styled.div((props) => ({\r\n display: 'flex',\r\n marginTop: `${props.sub ? '0' : '1rem'}`,\r\n flexDirection: 'column',\r\n\r\n '&>div:first-child': {\r\n marginLeft: 0,\r\n flex: 1\r\n },\r\n\r\n '&>div': {\r\n marginLeft: '0px',\r\n flex: 1\r\n },\r\n\r\n '@media only screen and (min-width: 600px)': {\r\n flexDirection: 'unset',\r\n\r\n '&>div': {\r\n marginLeft: '1rem',\r\n flex: 1\r\n },\r\n },\r\n\r\n '@media only screen and (min-width: 769px)': {\r\n flexDirection: 'unset',\r\n\r\n '&>div': {\r\n marginLeft: '1rem',\r\n flex: 1\r\n },\r\n },\r\n\r\n}))\r\n\r\nexport const SContVDetail = styled.div((props) => ({\r\n display: 'flex',\r\n flexDirection: 'column',\r\n\r\n '&>div:first-child': {\r\n marginTop: 0,\r\n },\r\n '&>div': {\r\n marginTop: '1rem',\r\n }\r\n}))","import React, { useEffect, useState, Fragment } from 'react'\r\nimport { connect } from 'react-redux'\r\nimport { Collapse } from '@material-ui/core'\r\nimport { Checkbox, Icon } from 'semantic-ui-react'\r\nimport { Cont, SContDetail } from './styled'\r\nimport { StdCard } from 'components'\r\nimport { DataCell } from '../DataCell'\r\nimport { getPrSpecialOptions } from 'ducks/options'\r\nimport { purchaseOrderDetailPath } from 'routes'\r\nimport { AdditionalRemark } from '../../AttributeData'\r\nimport * as v from 'variables/styles'\r\n// import r from 'reactotron-react-js'\r\n\r\nconst PRGeneral = (props) => {\r\n const { prData, prLoading } = props\r\n\r\n const [showAdditional, setShowAdditional] = useState(prData.isAdditional)\r\n const [showSpecialPR, setShowSpecialPR] = useState(prData.special)\r\n const [showAffiliatedCompaniesPR, setShowAffiliatedCompaniesPR] = useState(prData.isAffiliatedCompanies)\r\n const [showPartnersPreQualifiedPR, setShowPartnersPreQualifiedPR] = useState(prData.isPartnersPreQualified)\r\n\r\n useEffect(()=>{\r\n if(prData.special){\r\n props.getPrSpecialOptions('Special')\r\n }else if(prData.isAffiliatedCompanies){\r\n props.getPrSpecialOptions('AffiliatedCompanies')\r\n }else if (prData.isPartnersPreQualified){\r\n props.getPrSpecialOptions('PartnersPreQualified')\r\n }\r\n },[prData.special, prData.isAffiliatedCompanies, prData.isPartnersPreQualified])\r\n\r\n const getSpecialReasonOption = (specialReason) => {\r\n return props.prSpecial.data.find(x => x.value === (specialReason || ''))\r\n }\r\n\r\n const getReasonTitle = (reasonCode) => {\r\n const reason = getSpecialReasonOption(reasonCode)\r\n return (reason || {}).text || ''\r\n }\r\n\r\n const getSubReasonTitle = (subReasonCode) => {\r\n const reason = getSpecialReasonOption(prData.specialReason)\r\n const subReasons = (reason || {}).subOptions || []\r\n const subReason = subReasons.find(x => x.value === (subReasonCode || prData.subSpecialReason || ''))\r\n return (subReason || {}).text || ''\r\n }\r\n\r\n return (\r\n
\r\n \r\n
\r\n \r\n \r\n
\r\n \r\n \r\n \r\n
\r\n \r\n \r\n \r\n
\r\n
\r\n
setShowSpecialPR(!showSpecialPR)} />\r\n \r\n
\r\n \r\n \r\n {\r\n ((prData.specialReason || '').startsWith('SP') && (prData.specialReason || '').length === 4) ?\r\n \r\n \r\n \r\n \r\n {\r\n prData.specialReason === 'SP04' ? \r\n \r\n \r\n : null\r\n }\r\n :\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
setShowAffiliatedCompaniesPR(!showAffiliatedCompaniesPR)} />\r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
setShowPartnersPreQualifiedPR(!showPartnersPreQualifiedPR)} />\r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
setShowAdditional(!showAdditional)} />\r\n \r\n
\r\n \r\n \r\n {AdditionalRemark()}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n prData.isAdditional && prData.referencePoId ?\r\n : null\r\n }\r\n \r\n {!prLoading && prData.rentDays &&\r\n \r\n \r\n
\r\n }\r\n \r\n
\r\n \r\n )\r\n}\r\n\r\nconst mapStateToProps = (state) => ({\r\n prData: state.pr.prDetail.data || {},\r\n prLoading: state.pr.prLoading,\r\n prSpecial: state.options.prSpecial,\r\n})\r\n\r\nconst mapDispatchToProps = {\r\n getPrSpecialOptions\r\n}\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(PRGeneral)\r\n","import styled from '@emotion/styled'\r\nimport * as v from '../../../../../variables/styles'\r\n\r\nexport const PHCont = styled.div((props)=>({\r\n display:'flex',\r\n flex:1,\r\n}))\r\n\r\nexport const Cont = styled.div((props)=>({\r\n display:'flex',\r\n flex:1,\r\n flexDirection:'column',\r\n}))\r\n\r\n\r\nexport const ContDetail = styled.div((props)=>({\r\n display:'flex',\r\n marginTop:'1rem',\r\n\r\n 'div:first-child':{\r\n flex:1,\r\n display:'flex',\r\n justifyContent:'end',\r\n paddingRight:'1rem',\r\n fontWeight:'bold'\r\n },\r\n 'div:last-child':{\r\n flex:2\r\n }\r\n\r\n}))\r\n\r\nexport const ChatCont = styled.div((props)=>({\r\n display:'flex',\r\n flex:1,\r\n justifyContent:`${props.right?'flex-end':props.center?'center':'flex-start'}`,\r\n alignItems:'baseline',\r\n marginTop:'0.5rem',\r\n\r\n '.time':{\r\n fontSize:'0.5rem',\r\n marginLeft:'3rem'\r\n },\r\n '.msg':{\r\n maxWidth:'15vw',\r\n overflowWrap:'break-word',\r\n },\r\n}))\r\n\r\nexport const ChatContY = styled.div((props)=>({\r\n display:'flex',\r\n flexDirection:'column',\r\n alignItems:'baseline',\r\n marginTop:'0.5rem',\r\n '.msgCont':{\r\n display:'flex',\r\n flex:1,\r\n alignItems:'baseline',\r\n },\r\n '.msg':{\r\n maxWidth:'15vw',\r\n overflowWrap:'break-word',\r\n },\r\n '.time':{\r\n fontSize:'0.5rem',\r\n marginLeft:'3rem'\r\n },\r\n}))\r\n\r\nexport const ChatContF = styled.div((props)=>({\r\n display:'flex',\r\n flexDirection:'column',\r\n alignItems:'baseline',\r\n marginTop:'0.5rem',\r\n\r\n '.name':{\r\n fontSize:'1.2rem',\r\n fontWeight:'bold'\r\n },\r\n 'time':{\r\n fontSize:'0.7rem'\r\n },\r\n '.msgCont':{\r\n display:'flex',\r\n flex:1,\r\n alignItems:'baseline',\r\n border: '1px solid rgba(34,36,38,.15)',\r\n borderRadius:'0.3rem',\r\n padding:'0.5rem 1rem',\r\n width:'100%'\r\n },\r\n '.msg':{\r\n overflowWrap:'break-word',\r\n },\r\n '.time':{\r\n fontSize:'0.5rem',\r\n marginLeft:'3rem'\r\n },\r\n}))","import React from 'react'\r\nimport Moment from 'react-moment'\r\nimport {\r\n Divider } from 'semantic-ui-react'\r\n\r\nimport { \r\n Cont, \r\n ContDetail } from './styled'\r\n\r\nexport const ProcessRow = ({ data }) => {\r\n\r\n return (\r\n
\r\n \r\n Commented by :
\r\n {data&&data.createdByName}
\r\n \r\n \r\n Commented date :
\r\n {data&&data.createdDate}
\r\n \r\n \r\n Activity :
\r\n {data&&data.activity}
\r\n \r\n \r\n Action :
\r\n {data&&data.action}
\r\n \r\n \r\n Comment :
\r\n {data&&data.comment||'-'}
\r\n \r\n \r\n \r\n )\r\n}","import React from 'react'\r\nimport NumberFormat from 'react-number-format'\r\nimport r from 'reactotron-react-js'\r\n\r\nexport const getCategory = (listCategories) => (catCode) => {\r\n return listCategories.find(c => c.code === catCode)\r\n}\r\n\r\nexport const getSubCategory = (listSubCategories) => (subCatCode) => {\r\n return listSubCategories.find(s => s.code === subCatCode)\r\n}\r\n\r\nexport const getOptionTitle = (options, value, displayWithValue = true) => {\r\n if (value !== undefined) {\r\n const opt = options && options.find(o => o.value === value)\r\n let result = opt ? opt.text : value\r\n if(result){\r\n result = result.replace(`:`, '|')\r\n return displayWithValue ? result : result.replace(`${value} | `, '')\r\n }else{\r\n return ''\r\n }\r\n } else {\r\n return ''\r\n }\r\n}\r\n\r\nexport const filterStorageLocation = (storageLocationOptions) => (plantCode) => {\r\n if (storageLocationOptions !== undefined && plantCode !== undefined && plantCode !== '') {\r\n var result = storageLocationOptions.filter(s => s.plantCode === plantCode)\r\n result = result.sort((a, b) => (a.value < b.value) ? -1 : 1)\r\n return result\r\n } else {\r\n return []\r\n }\r\n}\r\n\r\nexport const numberFormat = (value, allowNegative = false, decimalScale = 2) => {\r\n return (\r\n
\r\n )\r\n}\r\n\r\nexport const calculateTotalAmount = (items, change,isSumOnly=false) => {\r\n var total = 0\r\n items.map(i => total = total + (!i.deleted?(i.quantity * i.unitPrice):0))\r\n if (change) change('totalAmount', total)\r\n \r\n if(!isSumOnly) return numberFormat(total)\r\n}\r\n\r\nexport const calculateVat = (items, vat, change,isSumOnly=false) => {\r\n let vatAmount = 0\r\n items.map(i => vatAmount = vatAmount + (!i.deleted?((i.quantity * i.unitPrice) / 100):0) * vat)\r\n if (change) change('vatAmount', vatAmount)\r\n \r\n if(!isSumOnly) return numberFormat(vatAmount)\r\n}\r\n\r\nexport const calculateTotalIncludeVat = (items, vat, change,isSumOnly=false) => {\r\n let total = 0\r\n items.map(i => total = total + ((!i.deleted?(i.quantity * i.unitPrice):0) + ((!i.deleted?((i.quantity * i.unitPrice) / 100):0) * vat)))\r\n if (change) change('totalAmountIncludeVat', total)\r\n\r\n if(!isSumOnly) return numberFormat(total)\r\n}\r\n\r\nexport const getDocumentTypes = (attachmentType, isSpecial, isAdditional) => {\r\n let documentTypes = []\r\n if (attachmentType && attachmentType.documentTypes) {\r\n documentTypes = JSON.parse(JSON.stringify(attachmentType.documentTypes))\r\n }\r\n \r\n if (isAdditional && attachmentType && attachmentType.additionalDocumentTypes.length !== 0) {\r\n documentTypes = JSON.parse(JSON.stringify(attachmentType.additionalDocumentTypes))\r\n }\r\n \r\n if (isSpecial) {\r\n if (documentTypes.length > 0) {\r\n const index = documentTypes.findIndex(dt => dt.code === 'PR07')\r\n if (index !== -1) {\r\n documentTypes[index].isRequire = true\r\n } else {\r\n documentTypes.push({ name: 'Quotation/Invoice', code: 'PR07', isRequire: true })\r\n }\r\n } else {\r\n documentTypes.push({ name: 'Quotation/Invoice', code: 'PR07', isRequire: true })\r\n }\r\n }\r\n\r\n documentTypes = documentTypes.sort((a, b) => (a.isRequire === b.isRequire)? 0 : !a.isRequire? 1 : -1)\r\n\r\n return documentTypes\r\n}","import React from 'react'\r\nimport Moment from 'react-moment'\r\nimport styled from '@emotion/styled'\r\nimport { Button } from 'semantic-ui-react'\r\nimport { IconButton, Tooltip } from '@material-ui/core'\r\nimport { Delete, AddToPhotos, Edit, Refresh } from '@material-ui/icons'\r\nimport { getOptionTitle, numberFormat } from '../helper'\r\n\r\nconst budgetTypeOptions = [\r\n { value: 'BT01', text: 'งบประมาณหน่วยงาน(OPEX)' },\r\n { value: 'BT02', text: 'งบประมาณหน่วยงาน(OPEX) - ค่ารับรอง' },\r\n { value: 'BT03', text: 'งบประมาณด้านการตลาด' },\r\n { value: 'BT04', text: 'งบประมาณโครงการ Internal Order' },\r\n { value: 'BT05', text: 'งบประมาณโครงการ Real Estate' },\r\n { value: 'BT06', text: 'งบประมาณโครงการ WBS Type C' },\r\n { value: 'BT07', text: 'งบประมาณโครงการ WBS Type E,P' },\r\n { value: 'BT08', text: 'งบประมาณโครงการ WBS Type W' },\r\n { value: 'BT09', text: 'งบประมาณซื้อทรัพย์สิน' },\r\n { value: 'BT11', text: 'Asset Dummy' },\r\n { value: 'BT12', text: 'No Budget' },\r\n]\r\n\r\nexport const getBudgetTypeOptions = (listType) => {\r\n return budgetTypeOptions.filter(bt => listType.find(t => t === bt.value) !== undefined)\r\n}\r\n\r\n// PR ITEMS\r\nconst blankItem = {\r\n itemName: '', \r\n quantity: 0, \r\n unit: '', \r\n unitPrice: 0, \r\n totalAmount: 0,\r\n}\r\n\r\nconst checkVisibleColumn = (items, fieldName) => {\r\n if (fieldName === 'materialNo') {\r\n let itemWithMaterial = items.filter(i => i.materialNo !== '')\r\n return !(itemWithMaterial && itemWithMaterial.length === 0)\r\n }\r\n\r\n if (fieldName === 'costCenter') {\r\n let itemByAccountAssignment = items.filter(\r\n i => i.accountAssignment === 'K' || \r\n i.accountAssignment === 'Z')\r\n return !(itemByAccountAssignment && itemByAccountAssignment.length === 0)\r\n }\r\n\r\n if (fieldName === 'glAccountCode') {\r\n let itemByAccountAssignment = items.filter(\r\n i => i.accountAssignment !== 'A' && \r\n i.accountAssignment !== 'Y' && \r\n i.accountAssignment !== 'C' && \r\n i.accountAssignment !== '' && \r\n i.accountAssignment !== null) || []\r\n return (itemByAccountAssignment.length !== 0)\r\n }\r\n\r\n if (fieldName === 'wbsElement') {\r\n let itemByAccountAssignment = items.filter(\r\n i => i.accountAssignment === 'A' || \r\n i.accountAssignment === 'P' || \r\n i.accountAssignment === 'R' || \r\n i.accountAssignment === 'W')\r\n return !(itemByAccountAssignment && itemByAccountAssignment.length === 0)\r\n }\r\n\r\n if (fieldName === 'asset') {\r\n let itemByAccountAssignment = items.filter(\r\n i => i.accountAssignment === 'A' || \r\n i.accountAssignment === 'Y')\r\n return !(itemByAccountAssignment && itemByAccountAssignment.length === 0)\r\n }\r\n\r\n if (fieldName === 'orderNo') {\r\n let itemByAccountAssignment = items.filter(\r\n i => i.accountAssignment === 'F' || \r\n i.accountAssignment === 'Z' ||\r\n i.accountAssignment === 'A')\r\n return !(itemByAccountAssignment && itemByAccountAssignment.length === 0)\r\n }\r\n \r\n if (fieldName === 'salesOrder' || fieldName === 'salesOrderItemNo') {\r\n let itemByAccountAssignment = items.filter(i => i.accountAssignment === 'C')\r\n return !(itemByAccountAssignment && itemByAccountAssignment.length === 0)\r\n }\r\n\r\n if (fieldName === 'profitCenter') {\r\n let itemByAccountAssignment = items.filter(\r\n i => i.accountAssignment === 'X' || \r\n i.accountAssignment === 'S')\r\n return !(itemByAccountAssignment && itemByAccountAssignment.length === 0)\r\n }\r\n \r\n if (fieldName === 'productHierarchyLv2' || fieldName === 'customer') {\r\n let itemByAccountAssignment = items.filter(i => i.accountAssignment === 'S')\r\n return !(itemByAccountAssignment && itemByAccountAssignment.length === 0)\r\n }\r\n\r\n if (fieldName === 'accountAssignment') {\r\n let itemByAccountAssignment = items.filter(\r\n i => i.accountAssignment !== '' && \r\n i.accountAssignment !== null) || []\r\n return (itemByAccountAssignment.length !== 0)\r\n }\r\n\r\n if (fieldName === 'budgetType') {\r\n let itemByCondition = items.filter(\r\n i => i.budgetType === '' || \r\n i.budgetType === null ||\r\n i.budgetType === 'BT12') || []\r\n return itemByCondition.length !== items.length\r\n }\r\n\r\n return true\r\n}\r\n\r\nconst WrapTextDiv = styled.div({\r\n width: '100%',\r\n whiteSpace: 'normal',\r\n wordWrap: 'break-word'\r\n})\r\n\r\nconst columns = (props) => {\r\n const { \r\n withActions, fields, items, change, showPrItemModal, \r\n budgetTypeOptions, assetOptions, unitOptions, currencyOptions,\r\n materialGroupOptions, plantOptions, storageLocationOptions, \r\n costCenterOptions, glAccountOptions, onSubmitItem,\r\n purchasingGroupOptions, editPrItem, onDeletePRItem,\r\n orderOptions, purchasingOrgOptions, profitCenterOptions, wbsOptions } = props\r\n\r\n return [\r\n {\r\n Header: 'Actions',\r\n accessor: '',\r\n show: withActions,\r\n Cell: row => (\r\n
\r\n {!fields.get(row.index).deleted&&\r\n
\r\n \r\n showPrItemModal(true, false, {...row.original}, editPrItem(row.index, change))\r\n }>\r\n \r\n \r\n }\r\n {!fields.get(row.index).deleted&&\r\n
\r\n {\r\n showPrItemModal(true, true, {...row.original,id:0}, onSubmitItem(fields, change))}\r\n }> \r\n }\r\n
\r\n {\r\n if (props.isEditPR && row.original.id !== 0) {\r\n change(`items[${row.index}].deleted`,!fields.get(row.index).deleted)\r\n }else if (props.isEditPR){\r\n if(onDeletePRItem) {\r\n onDeletePRItem(fields, change,row.index)\r\n }\r\n } else {\r\n fields.remove(row.index)\r\n if (items.length === 1) {\r\n change('vatRate', 7)\r\n }\r\n }\r\n }}>\r\n {\r\n fields.get(row.index).deleted?\r\n \r\n :\r\n \r\n }\r\n \r\n \r\n
\r\n )\r\n }, {\r\n Header: 'No',\r\n accessor: 'lineNo',\r\n width: 40,\r\n Cell: row => (
{row.value} )\r\n }, {\r\n Header: 'Material No',\r\n accessor: 'materialNo',\r\n show: checkVisibleColumn(items, 'materialNo'),\r\n }, {\r\n Header: 'Item Name',\r\n width: 180,\r\n accessor: 'itemName',\r\n Cell: row => (
{row.value} )\r\n }, {\r\n Header: 'Item Description',\r\n accessor: 'itemDescription',\r\n Cell: row => (
{row.value}
)\r\n }, {\r\n Header: 'Quantity',\r\n accessor: 'quantity',\r\n width: 80,\r\n className:'right',\r\n Cell: row => (
{numberFormat(row.value, false, 3)}
)\r\n }, {\r\n Header: 'Unit',\r\n accessor: 'unit',\r\n width: 80,\r\n Cell: row => (getOptionTitle(unitOptions, row.value))\r\n }, {\r\n Header: 'Unit Price (Ex.VAT)',\r\n accessor: 'unitPrice',\r\n className:'right',\r\n width: 100,\r\n Cell: row => (
{numberFormat(row.value)}
)\r\n }, {\r\n Header: 'Currency',\r\n accessor: 'currency',\r\n width: 80,\r\n Cell: row => (getOptionTitle(currencyOptions, row.value))\r\n }, {\r\n Header: 'Total Amount (Ex.VAT)',\r\n accessor: 'totalAmount',\r\n className:'right',\r\n width: 100,\r\n Cell: row => (
{numberFormat(row.value)}
)\r\n }, {\r\n Header: 'Budget Type',\r\n accessor: 'budgetType',\r\n show: checkVisibleColumn(items, 'budgetType'),\r\n Cell: row => (getOptionTitle(budgetTypeOptions, row.value)),\r\n }, {\r\n Header: 'Cost Center',\r\n accessor: 'costCenter',\r\n show: checkVisibleColumn(items, 'costCenter'),\r\n Cell: row => (getOptionTitle(costCenterOptions, row.value)),\r\n }, {\r\n Header: 'WBS',\r\n accessor: 'wbsElement',\r\n show: checkVisibleColumn(items, 'wbsElement'),\r\n Cell: row => (getOptionTitle(wbsOptions, row.value)),\r\n }, {\r\n Header: 'Order No',\r\n accessor: 'orderNo',\r\n show: checkVisibleColumn(items, 'orderNo'),\r\n Cell: row => (getOptionTitle(orderOptions, row.value)),\r\n }, {\r\n Header: 'GL Account',\r\n accessor: 'glAccountCode',\r\n show: checkVisibleColumn(items, 'glAccountCode'),\r\n Cell: row => (getOptionTitle(glAccountOptions, row.value)),\r\n }, {\r\n Header: 'Asset',\r\n accessor: 'asset',\r\n show: checkVisibleColumn(items, 'asset'),\r\n Cell: row => (getOptionTitle(assetOptions, row.value)),\r\n }, {\r\n Header: 'Sales Order',\r\n accessor: 'salesOrder',\r\n show: checkVisibleColumn(items, 'salesOrder'),\r\n }, {\r\n Header: 'Sales Order Item No',\r\n accessor: 'salesOrderItemNo',\r\n show: checkVisibleColumn(items, 'salesOrderItemNo'),\r\n }, {\r\n Header: 'Profit Center',\r\n accessor: 'profitCenter',\r\n show: checkVisibleColumn(items, 'profitCenter'),\r\n Cell: row => (getOptionTitle(profitCenterOptions, row.value)),\r\n }, {\r\n Header: 'Product Hierarchy Level 2',\r\n accessor: 'productHierarchyLv2',\r\n show: checkVisibleColumn(items, 'productHierarchyLv2'),\r\n }, {\r\n Header: 'Customer',\r\n accessor: 'customer',\r\n show: checkVisibleColumn(items, 'customer'),\r\n }, { \r\n Header: 'Account Assignment',\r\n accessor: 'accountAssignment',\r\n width: 72,\r\n className: 'center',\r\n show: checkVisibleColumn(items, 'accountAssignment'),\r\n }, {\r\n Header: 'Start Date',\r\n accessor: 'startDate',\r\n Cell: row => (
{row.value} )\r\n }, {\r\n Header: 'Delivery Date / Finish Date',\r\n accessor: 'deliveryDate',\r\n Cell: row => (
{row.value} )\r\n }, {\r\n Header: 'Plant',\r\n accessor: 'plant',\r\n Cell: row => (getOptionTitle(plantOptions, row.value))\r\n }, {\r\n Header: 'Storage Location',\r\n accessor: 'storageLocation',\r\n Cell: row => (getOptionTitle(storageLocationOptions.filter(s => s.plantCode === row.original.plant), row.value))\r\n }, {\r\n Header: 'Purchasing Group',\r\n accessor: 'purchasingGroup',\r\n Cell: row => (getOptionTitle(purchasingGroupOptions, row.value))\r\n }, {\r\n Header: 'Purchasing Org',\r\n accessor: 'purchasingOrg',\r\n Cell: row => (getOptionTitle(purchasingOrgOptions, row.value))\r\n }, {\r\n Header: 'Material Group',\r\n accessor: 'materialGroup',\r\n Cell: row => (getOptionTitle(materialGroupOptions, row.value))\r\n },\r\n ]\r\n}\r\n\r\nexport const itemColumns = (props) => {\r\n const { \r\n withActions, fields, showPrItemModal, defaultCurrency,\r\n costCenterByRequester, onSubmitItem, menuSubCategory, } = props\r\n\r\n if (withActions) {\r\n return [\r\n {\r\n Header: \r\n withActions ?\r\n
\r\n \r\n showPrItemModal(true, true, { \r\n ...blankItem,\r\n currency: defaultCurrency || 'THB',\r\n menuSubCategory, \r\n costCenter: costCenterByRequester }, onSubmitItem(fields,props.change))}\r\n labelPosition='right'\r\n />\r\n
: null,\r\n columns: columns(props)\r\n }\r\n ]\r\n } else {\r\n return columns(props)\r\n }\r\n}\r\n\r\n// BUDGET \r\nexport const costCenterColumn = [\r\n {\r\n Header: 'Cost Center',\r\n accessor: 'code',\r\n },\r\n {\r\n Header: 'Cost Center Name',\r\n accessor: 'description',\r\n },\r\n {\r\n Header: 'GL Account',\r\n accessor: 'code2',\r\n },\r\n {\r\n Header: 'GL Description',\r\n accessor: 'description2',\r\n },\r\n {\r\n Header: 'Budget',\r\n accessor: 'plan',\r\n className: 'right',\r\n Cell: row => (\r\n row.value === null ? \r\n
Budget not found
: \r\n
{numberFormat(row.value, true)}
\r\n ),\r\n },\r\n {\r\n Header: 'Assigned',\r\n accessor: 'assigned',\r\n className: 'right',\r\n Cell: row => (
{numberFormat(row.value, true)}
),\r\n },\r\n {\r\n Header: 'Available',\r\n accessor: 'available',\r\n className: 'right',\r\n Cell: row => (
{numberFormat(row.value, true)}
),\r\n },\r\n {\r\n Header: 'Currency',\r\n accessor: 'currencyCode',\r\n width: 80,\r\n className: 'center',\r\n Cell: row => (
{row.value}
),\r\n },\r\n]\r\n\r\nexport const wbsColumn = [\r\n {\r\n Header: 'Work Breakdown Structure (WBS)',\r\n accessor: 'code',\r\n },\r\n {\r\n Header: 'Description',\r\n accessor: 'description',\r\n },\r\n {\r\n Header: 'Budget',\r\n accessor: 'plan',\r\n className: 'right',\r\n Cell: row => (\r\n
{numberFormat((row.value || 0), true)}
\r\n // row.value === null ? \r\n //
Budget not found
: \r\n //
{numberFormat(row.value, true)}
\r\n ),\r\n },\r\n {\r\n Header: 'Assigned',\r\n accessor: 'assigned',\r\n className: 'right',\r\n Cell: row => (
{numberFormat(row.value, true)}
),\r\n },\r\n {\r\n Header: 'Available',\r\n accessor: 'available',\r\n className: 'right',\r\n Cell: row => (
{numberFormat(row.value, true)}
),\r\n },\r\n {\r\n Header: 'Currency',\r\n accessor: 'currencyCode',\r\n width: 80,\r\n className: 'center',\r\n Cell: row => (
{row.value}
),\r\n },\r\n]\r\n\r\nexport const internalOrderColumn = [\r\n {\r\n Header: 'Internal Order',\r\n accessor: 'code',\r\n },\r\n {\r\n Header: 'Description',\r\n accessor: 'description',\r\n },\r\n {\r\n Header: 'GL Account',\r\n accessor: 'code2',\r\n },\r\n {\r\n Header: 'GL Description',\r\n accessor: 'description2',\r\n },\r\n {\r\n Header: 'Plan',\r\n accessor: 'plan',\r\n className: 'right',\r\n Cell: row => (\r\n row.value === null || row.value === 0 ? \r\n
Budget not found
: \r\n
{numberFormat(row.value, true)}
\r\n ),\r\n },\r\n {\r\n Header: 'Assigned',\r\n accessor: 'assigned',\r\n className: 'right',\r\n Cell: row => (
{numberFormat(row.value, true)}
),\r\n },\r\n {\r\n Header: 'Available',\r\n accessor: 'available',\r\n className: 'right',\r\n Cell: row => (
{numberFormat(row.value, true)}
),\r\n },\r\n {\r\n Header: 'Currency',\r\n accessor: 'currencyCode',\r\n width: 80,\r\n className: 'center',\r\n Cell: row => (
{row.value}
),\r\n },\r\n]\r\n\r\nexport const migrationColumn = [\r\n {\r\n Header: 'Code',\r\n accessor: 'code',\r\n },\r\n {\r\n Header: 'Description',\r\n accessor: 'description',\r\n },\r\n {\r\n Header: 'Code 2',\r\n accessor: 'code2',\r\n },\r\n {\r\n Header: 'Description 2',\r\n accessor: 'description2',\r\n },\r\n {\r\n Header: 'Plan',\r\n accessor: 'plan',\r\n className: 'right',\r\n Cell: row => (\r\n row.value === null || row.value === 0 ? \r\n
Budget not found
: \r\n
{numberFormat(row.value, true)}
\r\n ),\r\n },\r\n {\r\n Header: 'Assigned',\r\n accessor: 'assigned',\r\n className: 'right',\r\n Cell: row => (
{numberFormat(row.value, true)}
),\r\n },\r\n {\r\n Header: 'Available',\r\n accessor: 'available',\r\n className: 'right',\r\n Cell: row => (
{numberFormat(row.value, true)}
),\r\n },\r\n {\r\n Header: 'Currency',\r\n accessor: 'currencyCode',\r\n width: 80,\r\n className: 'center',\r\n Cell: row => (
{row.value}
),\r\n },\r\n]\r\n","import React from 'react'\r\nimport { connect } from 'react-redux'\r\nimport ReactTable from 'react-table'\r\nimport { Divider } from 'semantic-ui-react'\r\nimport { Cont, SContDetail, TableCont } from './styled'\r\nimport { StdCard } from 'components'\r\nimport { DataCell } from '../DataCell'\r\nimport PRGeneral from '../PRGeneral'\r\nimport { ProcessRow } from '../PRProcessHistory/ProcessRow'\r\nimport { costCenterColumn, wbsColumn, internalOrderColumn, migrationColumn } from '../../Create/data'\r\n\r\nconst PRSummary = (props) => {\r\n const { prDetail } = props\r\n const prData = prDetail.data || {}\r\n const prLoading = prDetail.loading\r\n\r\n const setLastComment = () => {\r\n if (!prDetail.loading && prData.comments.length > 0) {\r\n return (\r\n
\r\n
Last Comment
\r\n
\r\n
)\r\n }\r\n return null\r\n }\r\n\r\n return (\r\n
\r\n
\r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n \r\n \r\n \r\n
\r\n \r\n \r\n
\r\n \r\n {!prLoading && (prData.budgetsCostCenter.length > 0 || prData.budgetsWbs.length > 0 || prData.budgetsInternalOrder.length > 0 || prData.budgetsMigrate.length > 0) &&\r\n Budget Information
\r\n }\r\n \r\n {!prLoading && prData.budgetsCostCenter.length > 0 &&\r\n
\r\n Cost Center \r\n 10}\r\n />\r\n }\r\n {!prLoading && prData.budgetsWbs.length > 0 &&\r\n
\r\n Work Breakdown Structure (WBS) \r\n 10}\r\n />\r\n }\r\n {!prLoading && prData.budgetsInternalOrder.length > 0 &&\r\n
\r\n Internal Order \r\n 10}\r\n />\r\n }\r\n {!prLoading && prData.budgetsMigrate.length > 0 &&\r\n
\r\n Budgets \r\n 10}\r\n />\r\n }\r\n
\r\n {setLastComment()}\r\n \r\n
\r\n
\r\n )\r\n}\r\n\r\nconst mapStateToProps = (state) => ({\r\n prDetail: state.pr.prDetail\r\n})\r\n\r\nconst mapDispatchToProps = {}\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(PRSummary)\r\n","import styled from '@emotion/styled'\r\nimport * as v from 'variables/styled'\r\n\r\nexport const AttachmentContainer = styled.div({\r\n display: 'flex',\r\n flexDirection: 'column',\r\n\r\n '.MuiCardContent-root': {\r\n paddingTop: '0px',\r\n }, \r\n\r\n 'button.hiddenButton': {\r\n color: 'transparent',\r\n background: 'transparent',\r\n },\r\n\r\n 'button.hiddenButton:hover': {\r\n color: 'transparent',\r\n background: 'transparent',\r\n cursor: 'unset',\r\n },\r\n\r\n 'button.hiddenButton:focus': {\r\n color: 'transparent',\r\n background: 'transparent',\r\n cursor: 'unset',\r\n },\r\n\r\n 'button.hiddenButton:active': {\r\n color: 'transparent',\r\n background: 'transparent',\r\n cursor: 'unset',\r\n },\r\n})\r\n\r\nexport const AttachmentFormContainer = styled.div({\r\n display: 'flex',\r\n flexDirection: 'column',\r\n flexWrap: 'wrap',\r\n marginTop:'1rem',\r\n \r\n 'div.fileUploadContainer': {\r\n width:'95%',\r\n display:'flex',\r\n flexDirection:'column',\r\n marginBottom:'1rem'\r\n },\r\n\r\n '>div:last-child':{\r\n marginRight:'0 !important'\r\n },\r\n\r\n '.sectionLeft': {\r\n display: 'flex',\r\n flex: 1,\r\n flexDirection: 'column',\r\n marginRight: '15px',\r\n },\r\n\r\n '.sectionRight': {\r\n display: 'flex',\r\n flex: 1,\r\n flexDirection: 'column',\r\n },\r\n\r\n '.fileInput':{\r\n width:'100%'\r\n },\r\n\r\n '@media only screen and (min-width: 600px)': {\r\n flexDirection: 'row',\r\n\r\n 'div.fileUploadContainer': {\r\n width:'47%',\r\n marginRight:'1rem',\r\n },\r\n },\r\n\r\n '@media only screen and (min-width: 769px)': {\r\n flexDirection: 'row',\r\n\r\n 'div.fileUploadContainer': {\r\n width:'31%',\r\n marginRight:'1rem',\r\n },\r\n },\r\n})\r\n\r\nexport const FileCont = styled.div((props)=>({\r\n display:'flex',\r\n marginTop:'0.5rem',\r\n\r\n '>div:first-child':{\r\n flex:1\r\n },\r\n '>div:last-child':{\r\n flex:4\r\n },\r\n\r\n '.titleFile':{\r\n fontWeight:'normal',\r\n display:'flex',\r\n justifyContent:'flex-end'\r\n },\r\n\r\n '.fileItem':{\r\n fontWeight:'normal',\r\n display:'flex',\r\n flexDirection:'column',\r\n 'button':{\r\n marginTop:'0.1rem'\r\n }\r\n },\r\n\r\n '.fileName':{\r\n display:'flex',\r\n justifyContent:'flex-start',\r\n wordBreak: 'break-all',\r\n },\r\n\r\n '.noFile':{\r\n fontStyle:'italic',\r\n marginLeft: '1rem'\r\n },\r\n\r\n '.button':{\r\n marginLeft:'1rem'\r\n }\r\n}))\r\n\r\nexport const AttachmentInfoContainer = styled.div({\r\n display: 'flex',\r\n flexDirection: 'column',\r\n\r\n '.rowFields': {\r\n display: 'flex',\r\n flex: 1,\r\n flexDirection: 'row',\r\n },\r\n})\r\n\r\nexport const AttachmentContainer2 = styled.div({\r\n display: 'flex',\r\n})\r\n\r\nexport const Cont2 = styled.div(props => ({\r\n display:'flex',\r\n flex:1,\r\n flexDirection:'column',\r\n}))\r\n\r\nexport const SContDetail = styled.div(props => ({\r\n display: 'flex',\r\n marginTop: props.sub ? '0' : '1rem',\r\n\r\n '&>div:first-child': {\r\n marginLeft: 0,\r\n flex: 1\r\n },\r\n\r\n '>div:first-child .toleft': {\r\n marginLeft: 0,\r\n flex: 1,\r\n display: 'flex',\r\n flexDirection: 'column'\r\n },\r\n\r\n '&>div': {\r\n marginLeft: '1rem',\r\n flex: 1\r\n }\r\n}))\r\n\r\nexport const AttachmentGroup = styled.div({\r\n display: 'flex',\r\n flexDirection: 'row',\r\n width: '100%',\r\n marginTop: '15px',\r\n\r\n '&:first-child': {\r\n marginTop: '0px',\r\n },\r\n\r\n 'div.attachmentLabel': {\r\n display: 'flex',\r\n fontWeight: 'bold',\r\n minWidth: '100px',\r\n height: '40px',\r\n alignItems: 'center',\r\n },\r\n\r\n 'div.attachmentBy': {\r\n display: 'flex',\r\n minWidth: '150px',\r\n flexDirection: 'column',\r\n justifyContent: 'flex-start',\r\n marginRight: '5px',\r\n\r\n span: {\r\n fontWeight: 'bold',\r\n },\r\n },\r\n})\r\n\r\nexport const AttachmentContent = styled.div({\r\n display: 'flex',\r\n flexDirection: 'column',\r\n width: '100%',\r\n\r\n 'div:first-child>div': {\r\n marginTop: '0px',\r\n },\r\n\r\n 'div>div': {\r\n marginTop: '5px',\r\n }\r\n})","import React from 'react'\r\nimport { lower } from 'change-case'\r\nimport { connect } from 'react-redux'\r\nimport { getFormValues, Field, change } from 'redux-form'\r\nimport { CircularProgress } from '@material-ui/core'\r\n\r\nimport FieldInput, { InputType as type } from 'components/SemanticForm'\r\nimport { FileUploadCell } from 'components'\r\nimport { getCategory, getSubCategory } from '../../helper'\r\n\r\nimport { AttachmentFormContainer } from './styled'\r\nimport r from 'reactotron-react-js'\r\n\r\nconst FieldAttachment = props => {\r\n const { \r\n valueForm,\r\n attachmentType, \r\n loading, \r\n } = props\r\n\r\n const { special, isAdditional } = valueForm\r\n var documentTypes = attachmentType ? attachmentType.documentTypes ? [...attachmentType.documentTypes] : [] : []\r\n \r\n if (isAdditional && attachmentType && attachmentType.additionalDocumentTypes.length !== 0) {\r\n documentTypes = attachmentType.additionalDocumentTypes\r\n }\r\n\r\n if (special) {\r\n if (documentTypes.length > 0) {\r\n const index = documentTypes.findIndex(dt => dt.code === 'PR07')\r\n if (index !== -1) {\r\n documentTypes[index].isRequire = true\r\n } else {\r\n documentTypes.push({ name: 'Quotation/Invoice', code: 'PR07', isRequire: true })\r\n }\r\n } else {\r\n documentTypes.push({ name: 'Quotation/Invoice', code: 'PR07', isRequire: true })\r\n }\r\n }\r\n\r\n documentTypes = documentTypes.sort((a, b) => (a.isRequire === b.isRequire)? 0 : !a.isRequire? 1 : -1)\r\n documentTypes = [...documentTypes,{code:'pr15',name:'Others',isRequire:false,}]\r\n var countAttachLine = Array(Math.ceil(documentTypes.length/3)).fill(1)\r\n\r\n return (\r\n
\r\n { loading ? \r\n : \r\n \r\n {countAttachLine.map((v,i1)=>{\r\n return (\r\n {documentTypes.map((dt,i2) =>{ \r\n if((Math.floor(i2/3))===i1){\r\n return (\r\n \r\n
\r\n \r\n {valueForm.attachments.filter(x=>(x.documentTypeCode.toLowerCase() === dt.code.toLowerCase())&&(!x.deleted)).map((item,i3)=>(\r\n {\r\n let index = valueForm.attachments.findIndex(x=>x.id===item.id)\r\n props.dispatch(change('formEditPR',`attachments[${index}].deleted`,true))\r\n }}\r\n />\r\n ))}\r\n
\r\n \r\n )\r\n } else{\r\n return null\r\n }\r\n })}\r\n )\r\n })}\r\n \r\n }\r\n \r\n )\r\n}\r\n\r\nconst mapStateToProps = state => {\r\n const valueForm = getFormValues('formEditPR')(state)\r\n const menus = state.pr.menus || []\r\n var category = {}\r\n var subCategory = {}\r\n\r\n if (valueForm) {\r\n if (valueForm.menuCategory) {\r\n category = getCategory(menus)(valueForm.menuCategory)\r\n }\r\n if (valueForm.menuSubCategory && category&&category.subCategories) {\r\n subCategory = getSubCategory(category.subCategories)(valueForm.menuSubCategory)\r\n }\r\n }\r\n\r\n var attachType = ''\r\n if (valueForm.companyCode) {\r\n if (subCategory.attachmentType) {\r\n attachType = subCategory.attachmentType\r\n } else {\r\n if (subCategory.attachmentTypes) {\r\n if (subCategory.attachmentTypes[valueForm.companyCode]) {\r\n attachType = subCategory.attachmentTypes[valueForm.companyCode]\r\n } else if (subCategory.attachmentTypes['all']) {\r\n attachType = subCategory.attachmentTypes['all']\r\n }\r\n }\r\n }\r\n }\r\n\r\n const attachmentTypes = state.pr.attachmentTypes\r\n let attachmentTypeTemp = attachmentTypes.find(a => a.code === attachType)\r\n const attachmentType = JSON.parse(JSON.stringify(attachmentTypeTemp||null))\r\n\r\n return ({\r\n attachmentTypes,\r\n attachmentType,\r\n loading: state.pr.attachmentTypeLoading,\r\n initialValues: {\r\n ...valueForm,\r\n },\r\n valueForm,\r\n })\r\n}\r\n\r\nconst mapDispatchToProps = (dispatch) =>({\r\n dispatch\r\n})\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(FieldAttachment)\r\n","import React from 'react'\r\nimport { \r\n Button,\r\n Divider\r\n} from 'semantic-ui-react'\r\n\r\nimport { \r\n FileCont } from './styled'\r\n\r\nexport const FileRow = (props) => {\r\n\r\n return (\r\n
\r\n {`${props.attachmentTitle||''} : `}
\r\n \r\n {\r\n props.files.length!==0?\r\n props.files.map((item)=>{\r\n // return {item.originalFilename}
} icon='download' labelPosition='left' onClick={()=>(window.open(item.urlPath,\"_blank\"))}/>\r\n return {item.originalFilename} } icon='download' labelPosition='left' onClick={()=>(window.location.href = item.urlPath)}/>\r\n })\r\n :\r\n There is no attachment.
\r\n }\r\n