diff --git a/backend/app/plugins/wiaas/assets/css/datatables.min.css b/backend/app/plugins/wiaas/assets/css/datatables.min.css new file mode 100644 index 0000000..6565b40 --- /dev/null +++ b/backend/app/plugins/wiaas/assets/css/datatables.min.css @@ -0,0 +1 @@ +table.dataTable{width:100%;margin:0 auto;clear:both;border-collapse:separate;border-spacing:0}table.dataTable thead th,table.dataTable tfoot th{font-weight:bold}table.dataTable thead th,table.dataTable thead td{padding:10px 18px;border-bottom:1px solid #111}table.dataTable thead th:active,table.dataTable thead td:active{outline:none}table.dataTable tfoot th,table.dataTable tfoot td{padding:10px 18px 6px 18px;border-top:1px solid #111}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{cursor:pointer;*cursor:hand;background-repeat:no-repeat;background-position:center right}table.dataTable thead .sorting{background-image:url("../images/sort_both.png")}table.dataTable thead .sorting_asc{background-image:url("../images/sort_asc.png")}table.dataTable thead .sorting_desc{background-image:url("../images/sort_desc.png")}table.dataTable thead .sorting_asc_disabled{background-image:url("../images/sort_asc_disabled.png")}table.dataTable thead .sorting_desc_disabled{background-image:url("../images/sort_desc_disabled.png")}table.dataTable tbody tr{background-color:#ffffff}table.dataTable tbody tr.selected{background-color:#B0BED9}table.dataTable tbody th,table.dataTable tbody td{padding:8px 10px}table.dataTable.row-border tbody th,table.dataTable.row-border tbody td,table.dataTable.display tbody th,table.dataTable.display tbody td{border-top:1px solid #ddd}table.dataTable.row-border tbody tr:first-child th,table.dataTable.row-border tbody tr:first-child td,table.dataTable.display tbody tr:first-child th,table.dataTable.display tbody tr:first-child td{border-top:none}table.dataTable.cell-border tbody th,table.dataTable.cell-border tbody td{border-top:1px solid #ddd;border-right:1px solid #ddd}table.dataTable.cell-border tbody tr th:first-child,table.dataTable.cell-border tbody tr td:first-child{border-left:1px solid #ddd}table.dataTable.cell-border tbody tr:first-child th,table.dataTable.cell-border tbody tr:first-child td{border-top:none}table.dataTable.stripe tbody tr.odd,table.dataTable.display tbody tr.odd{background-color:#f9f9f9}table.dataTable.stripe tbody tr.odd.selected,table.dataTable.display tbody tr.odd.selected{background-color:#acbad4}table.dataTable.hover tbody tr:hover,table.dataTable.display tbody tr:hover{background-color:#f6f6f6}table.dataTable.hover tbody tr:hover.selected,table.dataTable.display tbody tr:hover.selected{background-color:#aab7d1}table.dataTable.order-column tbody tr>.sorting_1,table.dataTable.order-column tbody tr>.sorting_2,table.dataTable.order-column tbody tr>.sorting_3,table.dataTable.display tbody tr>.sorting_1,table.dataTable.display tbody tr>.sorting_2,table.dataTable.display tbody tr>.sorting_3{background-color:#fafafa}table.dataTable.order-column tbody tr.selected>.sorting_1,table.dataTable.order-column tbody tr.selected>.sorting_2,table.dataTable.order-column tbody tr.selected>.sorting_3,table.dataTable.display tbody tr.selected>.sorting_1,table.dataTable.display tbody tr.selected>.sorting_2,table.dataTable.display tbody tr.selected>.sorting_3{background-color:#acbad5}table.dataTable.display tbody tr.odd>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd>.sorting_1{background-color:#f1f1f1}table.dataTable.display tbody tr.odd>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd>.sorting_2{background-color:#f3f3f3}table.dataTable.display tbody tr.odd>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd>.sorting_3{background-color:whitesmoke}table.dataTable.display tbody tr.odd.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_1{background-color:#a6b4cd}table.dataTable.display tbody tr.odd.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_2{background-color:#a8b5cf}table.dataTable.display tbody tr.odd.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_3{background-color:#a9b7d1}table.dataTable.display tbody tr.even>.sorting_1,table.dataTable.order-column.stripe tbody tr.even>.sorting_1{background-color:#fafafa}table.dataTable.display tbody tr.even>.sorting_2,table.dataTable.order-column.stripe tbody tr.even>.sorting_2{background-color:#fcfcfc}table.dataTable.display tbody tr.even>.sorting_3,table.dataTable.order-column.stripe tbody tr.even>.sorting_3{background-color:#fefefe}table.dataTable.display tbody tr.even.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_1{background-color:#acbad5}table.dataTable.display tbody tr.even.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_2{background-color:#aebcd6}table.dataTable.display tbody tr.even.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_3{background-color:#afbdd8}table.dataTable.display tbody tr:hover>.sorting_1,table.dataTable.order-column.hover tbody tr:hover>.sorting_1{background-color:#eaeaea}table.dataTable.display tbody tr:hover>.sorting_2,table.dataTable.order-column.hover tbody tr:hover>.sorting_2{background-color:#ececec}table.dataTable.display tbody tr:hover>.sorting_3,table.dataTable.order-column.hover tbody tr:hover>.sorting_3{background-color:#efefef}table.dataTable.display tbody tr:hover.selected>.sorting_1,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1{background-color:#a2aec7}table.dataTable.display tbody tr:hover.selected>.sorting_2,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2{background-color:#a3b0c9}table.dataTable.display tbody tr:hover.selected>.sorting_3,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3{background-color:#a5b2cb}table.dataTable.no-footer{border-bottom:1px solid #111}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}table.dataTable.compact thead th,table.dataTable.compact thead td{padding:4px 17px 4px 4px}table.dataTable.compact tfoot th,table.dataTable.compact tfoot td{padding:4px}table.dataTable.compact tbody th,table.dataTable.compact tbody td{padding:4px}table.dataTable th.dt-left,table.dataTable td.dt-left{text-align:left}table.dataTable th.dt-center,table.dataTable td.dt-center,table.dataTable td.dataTables_empty{text-align:center}table.dataTable th.dt-right,table.dataTable td.dt-right{text-align:right}table.dataTable th.dt-justify,table.dataTable td.dt-justify{text-align:justify}table.dataTable th.dt-nowrap,table.dataTable td.dt-nowrap{white-space:nowrap}table.dataTable thead th.dt-head-left,table.dataTable thead td.dt-head-left,table.dataTable tfoot th.dt-head-left,table.dataTable tfoot td.dt-head-left{text-align:left}table.dataTable thead th.dt-head-center,table.dataTable thead td.dt-head-center,table.dataTable tfoot th.dt-head-center,table.dataTable tfoot td.dt-head-center{text-align:center}table.dataTable thead th.dt-head-right,table.dataTable thead td.dt-head-right,table.dataTable tfoot th.dt-head-right,table.dataTable tfoot td.dt-head-right{text-align:right}table.dataTable thead th.dt-head-justify,table.dataTable thead td.dt-head-justify,table.dataTable tfoot th.dt-head-justify,table.dataTable tfoot td.dt-head-justify{text-align:justify}table.dataTable thead th.dt-head-nowrap,table.dataTable thead td.dt-head-nowrap,table.dataTable tfoot th.dt-head-nowrap,table.dataTable tfoot td.dt-head-nowrap{white-space:nowrap}table.dataTable tbody th.dt-body-left,table.dataTable tbody td.dt-body-left{text-align:left}table.dataTable tbody th.dt-body-center,table.dataTable tbody td.dt-body-center{text-align:center}table.dataTable tbody th.dt-body-right,table.dataTable tbody td.dt-body-right{text-align:right}table.dataTable tbody th.dt-body-justify,table.dataTable tbody td.dt-body-justify{text-align:justify}table.dataTable tbody th.dt-body-nowrap,table.dataTable tbody td.dt-body-nowrap{white-space:nowrap}table.dataTable,table.dataTable th,table.dataTable td{box-sizing:content-box}.dataTables_wrapper{position:relative;clear:both;*zoom:1;zoom:1}.dataTables_wrapper .dataTables_length{float:left}.dataTables_wrapper .dataTables_filter{float:right;text-align:right}.dataTables_wrapper .dataTables_filter input{margin-left:0.5em}.dataTables_wrapper .dataTables_info{clear:both;float:left;padding-top:0.755em}.dataTables_wrapper .dataTables_paginate{float:right;text-align:right;padding-top:0.25em}.dataTables_wrapper .dataTables_paginate .paginate_button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:0.5em 1em;margin-left:2px;text-align:center;text-decoration:none !important;cursor:pointer;*cursor:hand;color:#333 !important;border:1px solid transparent;border-radius:2px}.dataTables_wrapper .dataTables_paginate .paginate_button.current,.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{color:#333 !important;border:1px solid #979797;background-color:white;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff), color-stop(100%, #dcdcdc));background:-webkit-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-moz-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-ms-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-o-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:linear-gradient(to bottom, #fff 0%, #dcdcdc 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active{cursor:default;color:#666 !important;border:1px solid transparent;background:transparent;box-shadow:none}.dataTables_wrapper .dataTables_paginate .paginate_button:hover{color:white !important;border:1px solid #111;background-color:#585858;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));background:-webkit-linear-gradient(top, #585858 0%, #111 100%);background:-moz-linear-gradient(top, #585858 0%, #111 100%);background:-ms-linear-gradient(top, #585858 0%, #111 100%);background:-o-linear-gradient(top, #585858 0%, #111 100%);background:linear-gradient(to bottom, #585858 0%, #111 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button:active{outline:none;background-color:#2b2b2b;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));background:-webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);box-shadow:inset 0 0 3px #111}.dataTables_wrapper .dataTables_paginate .ellipsis{padding:0 1em}.dataTables_wrapper .dataTables_processing{position:absolute;top:50%;left:50%;width:100%;height:40px;margin-left:-50%;margin-top:-25px;padding-top:20px;text-align:center;font-size:1.2em;background-color:white;background:-webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(255,255,255,0.9)), color-stop(75%, rgba(255,255,255,0.9)), color-stop(100%, rgba(255,255,255,0)));background:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-ms-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-o-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%)}.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter,.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_processing,.dataTables_wrapper .dataTables_paginate{color:#333}.dataTables_wrapper .dataTables_scroll{clear:both}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody{*margin-top:-1px;-webkit-overflow-scrolling:touch}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>th,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>td,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>th,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>td{vertical-align:middle}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>td>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>td>div.dataTables_sizing{height:0;overflow:hidden;margin:0 !important;padding:0 !important}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:1px solid #111}.dataTables_wrapper.no-footer div.dataTables_scrollHead table.dataTable,.dataTables_wrapper.no-footer div.dataTables_scrollBody>table{border-bottom:none}.dataTables_wrapper:after{visibility:hidden;display:block;content:"";clear:both;height:0}@media screen and (max-width: 767px){.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_paginate{float:none;text-align:center}.dataTables_wrapper .dataTables_paginate{margin-top:0.5em}}@media screen and (max-width: 640px){.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter{float:none;text-align:center}.dataTables_wrapper .dataTables_filter{margin-top:0.5em}} diff --git a/backend/app/plugins/wiaas/assets/css/menu.css b/backend/app/plugins/wiaas/assets/css/menu.css index da83ba0..b0c4890 100644 --- a/backend/app/plugins/wiaas/assets/css/menu.css +++ b/backend/app/plugins/wiaas/assets/css/menu.css @@ -62,3 +62,122 @@ .gravityflow-dicussion-item-value { padding: 10px; } + +.woocommerce-help-tip{ + color:#666; + display:inline-block; + font-size:1.1em; + font-style:normal; + height:16px; + line-height:16px; + position:relative; + vertical-align:middle; + width:16px} + +.woocommerce-help-tip::after{ + font-family:Dashicons; + speak:none; + font-weight:400; + font-variant:normal; + text-transform:none; + line-height:1; + -webkit-font-smoothing:antialiased; + margin:0; + text-indent:0; + position:absolute; + top:0; + left:0; + width:100%; + height:100%; + text-align:center; + content:""; + cursor:help +} + +h2 .woocommerce-help-tip{ + margin-top:-5px; + margin-left:.25em +} + +/** + * Tooltips + */ +.tips { + cursor: help; + text-decoration: none; +} + +img.tips { + padding: 5px 0 0; +} + +#tiptip_holder { + display: none; + z-index: 8675309; + position: absolute; + top: 0; + /*rtl:ignore*/ + left: 0; +} +#tiptip_holder.tip_top { + padding-bottom: 5px; +} +#tiptip_holder.tip_top #tiptip_arrow_inner { + margin-top: -7px; + margin-left: -6px; + border-top-color: #333; +} +#tiptip_holder.tip_bottom { + padding-top: 5px; +} +#tiptip_holder.tip_bottom #tiptip_arrow_inner { + margin-top: -5px; + margin-left: -6px; + border-bottom-color: #333; +} +#tiptip_holder.tip_right { + padding-left: 5px; +} +#tiptip_holder.tip_right #tiptip_arrow_inner { + margin-top: -6px; + margin-left: -5px; + border-right-color: #333; +} +#tiptip_holder.tip_left { + padding-right: 5px; +} +#tiptip_holder.tip_left #tiptip_arrow_inner { + margin-top: -6px; + margin-left: -7px; + border-left-color: #333; +} + +#tiptip_content, +.chart-tooltip, +.wc_error_tip { + color: #fff; + font-size: 0.8em; + max-width: 150px; + background: #333; + text-align: center; + border-radius: 3px; + padding: 0.618em 1em; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); +} +#tiptip_content code, +.chart-tooltip code, +.wc_error_tip code { + padding: 1px; + background: #888; +} + +#tiptip_arrow, +#tiptip_arrow_inner { + position: absolute; + border-color: transparent; + border-style: solid; + border-width: 6px; + height: 0; + width: 0; +} + diff --git a/backend/app/plugins/wiaas/assets/css/wiaas-admin-dashboard.css b/backend/app/plugins/wiaas/assets/css/wiaas-admin-dashboard.css new file mode 100644 index 0000000..20d54dc --- /dev/null +++ b/backend/app/plugins/wiaas/assets/css/wiaas-admin-dashboard.css @@ -0,0 +1,25 @@ +.wiaas-dashboard-table { + width: 100%; +} + +.wiaas-dashboard-table thead td { + padding: .5em 1em +} + +.wiaas-dashboard-table tbody td { + border-top: 1px solid #f5f5f5; + vertical-align: middle; + padding: 1em +} + +.wiaas-dashboard-table-empty { + width: 100%; +} + +.wiaas-dashboard-table-empty p { + text-align: center; +} + +time.wiaas-order-date { + color: #999; +} \ No newline at end of file diff --git a/backend/app/plugins/wiaas/assets/css/wiaas-admin-delivery-process.css b/backend/app/plugins/wiaas/assets/css/wiaas-admin-delivery-process.css new file mode 100644 index 0000000..77d10ce --- /dev/null +++ b/backend/app/plugins/wiaas/assets/css/wiaas-admin-delivery-process.css @@ -0,0 +1,90 @@ +#wiaas_delivery_process_order_notes .note_content { + background: #a7cedc; + padding: 10px; + position: relative; +} + +#wiaas_delivery_process_order_notes .note_content:after { + content: ''; + display: block; + position: absolute; + bottom: -10px; + left: 20px; + width: 0; + height: 0; + border-width: 10px 10px 0 0; + border-style: solid; + border-color: #a7cedc transparent; +} + +#wiaas_delivery_process_order_notes .note_content p { + margin: 0; + padding: 0; + word-wrap: break-word; +} + +#wiaas_delivery_process_order_notes p.meta { + padding: 10px; + color: #999; + margin: 0; + font-size: 11px; +} + +#wiaas_delivery_process_order_notes .add-note { + border-top: 1px solid #ddd; + padding: 10px 10px 0; +} + +#wiaas_delivery_process_order_notes .add-note textarea { + width: 100%; + height: 50px; +} + +.wiaas-delivery-process-timeline-note { + margin: 20px 0 30px; + clear: both; + width: 100%; +} + +.wiaas-delivery-process-timeline-note > div.wiaas-delivery-process-timeline-note-body-wrap { + border: 1px solid #E0E0E0; + margin-left: 100px; + padding: 10px; + display: block; +} + +.wiaas-delivery-process-timeline-note > div .wiaas-delivery-process-timeline-note-body { + + overflow-y: hidden; + display: block; + line-height: 1.3em; + width: 100%; + word-wrap: break-word; +} + +.wiaas-delivery-process-timeline-note-title { + float: left; + margin-bottom: 0.5em; + font-size: 1.2em; + color: #939FA5; +} + +.wiaas-delivery-process-timeline-note-date { + color: #939FA5; + float: right; + font-size: 11px; + text-align: right; + display: block; +} + +.wiaas-delivery-process-timeline-note-avatar { + float: left; + width: 84px; + text-align: center; + padding-right: 10px; +} + +.wiaas-delivery-process-step-instructions { + padding: 10px 50px; + border-bottom: 1px solid #eee; +} \ No newline at end of file diff --git a/backend/app/plugins/wiaas/assets/css/wiaas-admin.css b/backend/app/plugins/wiaas/assets/css/wiaas-admin.css new file mode 100644 index 0000000..c384947 --- /dev/null +++ b/backend/app/plugins/wiaas/assets/css/wiaas-admin.css @@ -0,0 +1,37 @@ +mark.wiaas-order-status { + display: inline-flex; + padding: 0 1em; + line-height: 2.5em; + color: #777; + background: #e5e5e5; + border-radius: 4px; + border-bottom: 1px solid rgba(0, 0, 0, .05); + margin: -.5em 0; + cursor: inherit !important; + font-size: 13px; +} + +mark.wiaas-order-status-completed { + background: #c8d7e1; + color: #2e4453 +} + +mark.wiaas-order-status-on-hold { + background: #f8dda7; + color: #94660c +} + +mark.wiaas-order-status-failed { + background: #eba3a3; + color: #761919 +} + +mark.wiaas-order-status-processing { + background: #c6e1c6; + color: #5b841b +} + +mark.wiaas-order-status-trash { + background: #eba3a3; + color: #761919 +} \ No newline at end of file diff --git a/backend/app/plugins/wiaas/assets/images/sort_asc.png b/backend/app/plugins/wiaas/assets/images/sort_asc.png new file mode 100644 index 0000000..e1ba61a Binary files /dev/null and b/backend/app/plugins/wiaas/assets/images/sort_asc.png differ diff --git a/backend/app/plugins/wiaas/assets/images/sort_both.png b/backend/app/plugins/wiaas/assets/images/sort_both.png new file mode 100644 index 0000000..af5bc7c Binary files /dev/null and b/backend/app/plugins/wiaas/assets/images/sort_both.png differ diff --git a/backend/app/plugins/wiaas/assets/images/sort_desc.png b/backend/app/plugins/wiaas/assets/images/sort_desc.png new file mode 100644 index 0000000..0e156de Binary files /dev/null and b/backend/app/plugins/wiaas/assets/images/sort_desc.png differ diff --git a/backend/app/plugins/wiaas/assets/js/datatables.min.js b/backend/app/plugins/wiaas/assets/js/datatables.min.js new file mode 100644 index 0000000..7587a59 --- /dev/null +++ b/backend/app/plugins/wiaas/assets/js/datatables.min.js @@ -0,0 +1,180 @@ +/* + * This combined file was created by the DataTables downloader builder: + * https://datatables.net/download + * + * To rebuild or modify this file with the latest versions of the included + * software please visit: + * https://datatables.net/download/#dt/dt-1.10.18 + * + * Included libraries: + * DataTables 1.10.18 + */ + +/*! + DataTables 1.10.18 + ©2008-2018 SpryMedia Ltd - datatables.net/license +*/ +(function(h){"function"===typeof define&&define.amd?define(["jquery"],function(E){return h(E,window,document)}):"object"===typeof exports?module.exports=function(E,H){E||(E=window);H||(H="undefined"!==typeof window?require("jquery"):require("jquery")(E));return h(H,E,E.document)}:h(jQuery,window,document)})(function(h,E,H,k){function Z(a){var b,c,d={};h.each(a,function(e){if((b=e.match(/^([^A-Z]+?)([A-Z])/))&&-1!=="a aa ai ao as b fn i m o s ".indexOf(b[1]+" "))c=e.replace(b[0],b[2].toLowerCase()), +d[c]=e,"o"===b[1]&&Z(a[e])});a._hungarianMap=d}function J(a,b,c){a._hungarianMap||Z(a);var d;h.each(b,function(e){d=a._hungarianMap[e];if(d!==k&&(c||b[d]===k))"o"===d.charAt(0)?(b[d]||(b[d]={}),h.extend(!0,b[d],b[e]),J(a[d],b[d],c)):b[d]=b[e]})}function Ca(a){var b=n.defaults.oLanguage,c=b.sDecimal;c&&Da(c);if(a){var d=a.sZeroRecords;!a.sEmptyTable&&(d&&"No data available in table"===b.sEmptyTable)&&F(a,a,"sZeroRecords","sEmptyTable");!a.sLoadingRecords&&(d&&"Loading..."===b.sLoadingRecords)&&F(a, +a,"sZeroRecords","sLoadingRecords");a.sInfoThousands&&(a.sThousands=a.sInfoThousands);(a=a.sDecimal)&&c!==a&&Da(a)}}function eb(a){A(a,"ordering","bSort");A(a,"orderMulti","bSortMulti");A(a,"orderClasses","bSortClasses");A(a,"orderCellsTop","bSortCellsTop");A(a,"order","aaSorting");A(a,"orderFixed","aaSortingFixed");A(a,"paging","bPaginate");A(a,"pagingType","sPaginationType");A(a,"pageLength","iDisplayLength");A(a,"searching","bFilter");"boolean"===typeof a.sScrollX&&(a.sScrollX=a.sScrollX?"100%": +"");"boolean"===typeof a.scrollX&&(a.scrollX=a.scrollX?"100%":"");if(a=a.aoSearchCols)for(var b=0,c=a.length;b").css({position:"fixed",top:0,left:-1*h(E).scrollLeft(),height:1,width:1, +overflow:"hidden"}).append(h("
").css({position:"absolute",top:1,left:1,width:100,overflow:"scroll"}).append(h("
").css({width:"100%",height:10}))).appendTo("body"),d=c.children(),e=d.children();b.barWidth=d[0].offsetWidth-d[0].clientWidth;b.bScrollOversize=100===e[0].offsetWidth&&100!==d[0].clientWidth;b.bScrollbarLeft=1!==Math.round(e.offset().left);b.bBounding=c[0].getBoundingClientRect().width?!0:!1;c.remove()}h.extend(a.oBrowser,n.__browser);a.oScroll.iBarWidth=n.__browser.barWidth} +function hb(a,b,c,d,e,f){var g,j=!1;c!==k&&(g=c,j=!0);for(;d!==e;)a.hasOwnProperty(d)&&(g=j?b(g,a[d],d,a):a[d],j=!0,d+=f);return g}function Ea(a,b){var c=n.defaults.column,d=a.aoColumns.length,c=h.extend({},n.models.oColumn,c,{nTh:b?b:H.createElement("th"),sTitle:c.sTitle?c.sTitle:b?b.innerHTML:"",aDataSort:c.aDataSort?c.aDataSort:[d],mData:c.mData?c.mData:d,idx:d});a.aoColumns.push(c);c=a.aoPreSearchCols;c[d]=h.extend({},n.models.oSearch,c[d]);ka(a,d,h(b).data())}function ka(a,b,c){var b=a.aoColumns[b], +d=a.oClasses,e=h(b.nTh);if(!b.sWidthOrig){b.sWidthOrig=e.attr("width")||null;var f=(e.attr("style")||"").match(/width:\s*(\d+[pxem%]+)/);f&&(b.sWidthOrig=f[1])}c!==k&&null!==c&&(fb(c),J(n.defaults.column,c),c.mDataProp!==k&&!c.mData&&(c.mData=c.mDataProp),c.sType&&(b._sManualType=c.sType),c.className&&!c.sClass&&(c.sClass=c.className),c.sClass&&e.addClass(c.sClass),h.extend(b,c),F(b,c,"sWidth","sWidthOrig"),c.iDataSort!==k&&(b.aDataSort=[c.iDataSort]),F(b,c,"aDataSort"));var g=b.mData,j=S(g),i=b.mRender? +S(b.mRender):null,c=function(a){return"string"===typeof a&&-1!==a.indexOf("@")};b._bAttrSrc=h.isPlainObject(g)&&(c(g.sort)||c(g.type)||c(g.filter));b._setter=null;b.fnGetData=function(a,b,c){var d=j(a,b,k,c);return i&&b?i(d,b,a,c):d};b.fnSetData=function(a,b,c){return N(g)(a,b,c)};"number"!==typeof g&&(a._rowReadObject=!0);a.oFeatures.bSort||(b.bSortable=!1,e.addClass(d.sSortableNone));a=-1!==h.inArray("asc",b.asSorting);c=-1!==h.inArray("desc",b.asSorting);!b.bSortable||!a&&!c?(b.sSortingClass=d.sSortableNone, +b.sSortingClassJUI=""):a&&!c?(b.sSortingClass=d.sSortableAsc,b.sSortingClassJUI=d.sSortJUIAscAllowed):!a&&c?(b.sSortingClass=d.sSortableDesc,b.sSortingClassJUI=d.sSortJUIDescAllowed):(b.sSortingClass=d.sSortable,b.sSortingClassJUI=d.sSortJUI)}function $(a){if(!1!==a.oFeatures.bAutoWidth){var b=a.aoColumns;Fa(a);for(var c=0,d=b.length;cq[f])d(l.length+q[f],m);else if("string"=== +typeof q[f]){j=0;for(i=l.length;jb&&a[e]--; -1!=d&&c===k&&a.splice(d, +1)}function da(a,b,c,d){var e=a.aoData[b],f,g=function(c,d){for(;c.childNodes.length;)c.removeChild(c.firstChild);c.innerHTML=B(a,b,d,"display")};if("dom"===c||(!c||"auto"===c)&&"dom"===e.src)e._aData=Ia(a,e,d,d===k?k:e._aData).data;else{var j=e.anCells;if(j)if(d!==k)g(j[d],d);else{c=0;for(f=j.length;c").appendTo(g));b=0;for(c=l.length;btr").attr("role","row");h(g).find(">tr>th, >tr>td").addClass(m.sHeaderTH);h(j).find(">tr>th, >tr>td").addClass(m.sFooterTH);if(null!==j){a=a.aoFooter[0];b=0;for(c=a.length;b=a.fnRecordsDisplay()?0:g,a.iInitDisplayStart=-1);var g=a._iDisplayStart,m=a.fnDisplayEnd();if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++,C(a,!1);else if(j){if(!a.bDestroying&&!lb(a))return}else a.iDraw++;if(0!==i.length){f=j?a.aoData.length:m;for(j=j?0:g;j",{"class":e?d[0]:""}).append(h("",{valign:"top",colSpan:V(a),"class":a.oClasses.sRowEmpty}).html(c))[0];r(a,"aoHeaderCallback","header",[h(a.nTHead).children("tr")[0],Ka(a),g,m,i]);r(a,"aoFooterCallback","footer",[h(a.nTFoot).children("tr")[0],Ka(a),g,m,i]);d=h(a.nTBody);d.children().detach(); +d.append(h(b));r(a,"aoDrawCallback","draw",[a]);a.bSorted=!1;a.bFiltered=!1;a.bDrawing=!1}}function T(a,b){var c=a.oFeatures,d=c.bFilter;c.bSort&&mb(a);d?ga(a,a.oPreviousSearch):a.aiDisplay=a.aiDisplayMaster.slice();!0!==b&&(a._iDisplayStart=0);a._drawHold=b;P(a);a._drawHold=!1}function nb(a){var b=a.oClasses,c=h(a.nTable),c=h("
").insertBefore(c),d=a.oFeatures,e=h("
",{id:a.sTableId+"_wrapper","class":b.sWrapper+(a.nTFoot?"":" "+b.sNoFooter)});a.nHolding=c[0];a.nTableWrapper=e[0];a.nTableReinsertBefore= +a.nTable.nextSibling;for(var f=a.sDom.split(""),g,j,i,m,l,q,k=0;k")[0];m=f[k+1];if("'"==m||'"'==m){l="";for(q=2;f[k+q]!=m;)l+=f[k+q],q++;"H"==l?l=b.sJUIHeader:"F"==l&&(l=b.sJUIFooter);-1!=l.indexOf(".")?(m=l.split("."),i.id=m[0].substr(1,m[0].length-1),i.className=m[1]):"#"==l.charAt(0)?i.id=l.substr(1,l.length-1):i.className=l;k+=q}e.append(i);e=h(i)}else if(">"==j)e=e.parent();else if("l"==j&&d.bPaginate&&d.bLengthChange)g=ob(a);else if("f"==j&& +d.bFilter)g=pb(a);else if("r"==j&&d.bProcessing)g=qb(a);else if("t"==j)g=rb(a);else if("i"==j&&d.bInfo)g=sb(a);else if("p"==j&&d.bPaginate)g=tb(a);else if(0!==n.ext.feature.length){i=n.ext.feature;q=0;for(m=i.length;q',j=d.sSearch,j=j.match(/_INPUT_/)?j.replace("_INPUT_", +g):j+g,b=h("
",{id:!f.f?c+"_filter":null,"class":b.sFilter}).append(h("
").addClass(b.sLength);a.aanFeatures.l||(i[0].id=c+"_length");i.children().append(a.oLanguage.sLengthMenu.replace("_MENU_",e[0].outerHTML));h("select",i).val(a._iDisplayLength).on("change.DT",function(){Ra(a,h(this).val());P(a)});h(a.nTable).on("length.dt.DT",function(b,c,d){a=== +c&&h("select",i).val(d)});return i[0]}function tb(a){var b=a.sPaginationType,c=n.ext.pager[b],d="function"===typeof c,e=function(a){P(a)},b=h("
").addClass(a.oClasses.sPaging+b)[0],f=a.aanFeatures;d||c.fnInit(a,b,e);f.p||(b.id=a.sTableId+"_paginate",a.aoDrawCallback.push({fn:function(a){if(d){var b=a._iDisplayStart,i=a._iDisplayLength,h=a.fnRecordsDisplay(),l=-1===i,b=l?0:Math.ceil(b/i),i=l?1:Math.ceil(h/i),h=c(b,i),k,l=0;for(k=f.p.length;lf&&(d=0)):"first"==b?d=0:"previous"==b?(d=0<=e?d-e:0,0>d&&(d=0)):"next"==b?d+e",{id:!a.aanFeatures.r?a.sTableId+"_processing":null,"class":a.oClasses.sProcessing}).html(a.oLanguage.sProcessing).insertBefore(a.nTable)[0]} +function C(a,b){a.oFeatures.bProcessing&&h(a.aanFeatures.r).css("display",b?"block":"none");r(a,null,"processing",[a,b])}function rb(a){var b=h(a.nTable);b.attr("role","grid");var c=a.oScroll;if(""===c.sX&&""===c.sY)return a.nTable;var d=c.sX,e=c.sY,f=a.oClasses,g=b.children("caption"),j=g.length?g[0]._captionSide:null,i=h(b[0].cloneNode(!1)),m=h(b[0].cloneNode(!1)),l=b.children("tfoot");l.length||(l=null);i=h("
",{"class":f.sScrollWrapper}).append(h("
",{"class":f.sScrollHead}).css({overflow:"hidden", +position:"relative",border:0,width:d?!d?null:v(d):"100%"}).append(h("
",{"class":f.sScrollHeadInner}).css({"box-sizing":"content-box",width:c.sXInner||"100%"}).append(i.removeAttr("id").css("margin-left",0).append("top"===j?g:null).append(b.children("thead"))))).append(h("
",{"class":f.sScrollBody}).css({position:"relative",overflow:"auto",width:!d?null:v(d)}).append(b));l&&i.append(h("
",{"class":f.sScrollFoot}).css({overflow:"hidden",border:0,width:d?!d?null:v(d):"100%"}).append(h("
", +{"class":f.sScrollFootInner}).append(m.removeAttr("id").css("margin-left",0).append("bottom"===j?g:null).append(b.children("tfoot")))));var b=i.children(),k=b[0],f=b[1],t=l?b[2]:null;if(d)h(f).on("scroll.DT",function(){var a=this.scrollLeft;k.scrollLeft=a;l&&(t.scrollLeft=a)});h(f).css(e&&c.bCollapse?"max-height":"height",e);a.nScrollHead=k;a.nScrollBody=f;a.nScrollFoot=t;a.aoDrawCallback.push({fn:la,sName:"scrolling"});return i[0]}function la(a){var b=a.oScroll,c=b.sX,d=b.sXInner,e=b.sY,b=b.iBarWidth, +f=h(a.nScrollHead),g=f[0].style,j=f.children("div"),i=j[0].style,m=j.children("table"),j=a.nScrollBody,l=h(j),q=j.style,t=h(a.nScrollFoot).children("div"),n=t.children("table"),o=h(a.nTHead),p=h(a.nTable),s=p[0],r=s.style,u=a.nTFoot?h(a.nTFoot):null,x=a.oBrowser,U=x.bScrollOversize,Xb=D(a.aoColumns,"nTh"),Q,L,R,w,Ua=[],y=[],z=[],A=[],B,C=function(a){a=a.style;a.paddingTop="0";a.paddingBottom="0";a.borderTopWidth="0";a.borderBottomWidth="0";a.height=0};L=j.scrollHeight>j.clientHeight;if(a.scrollBarVis!== +L&&a.scrollBarVis!==k)a.scrollBarVis=L,$(a);else{a.scrollBarVis=L;p.children("thead, tfoot").remove();u&&(R=u.clone().prependTo(p),Q=u.find("tr"),R=R.find("tr"));w=o.clone().prependTo(p);o=o.find("tr");L=w.find("tr");w.find("th, td").removeAttr("tabindex");c||(q.width="100%",f[0].style.width="100%");h.each(ra(a,w),function(b,c){B=aa(a,b);c.style.width=a.aoColumns[B].sWidth});u&&I(function(a){a.style.width=""},R);f=p.outerWidth();if(""===c){r.width="100%";if(U&&(p.find("tbody").height()>j.offsetHeight|| +"scroll"==l.css("overflow-y")))r.width=v(p.outerWidth()-b);f=p.outerWidth()}else""!==d&&(r.width=v(d),f=p.outerWidth());I(C,L);I(function(a){z.push(a.innerHTML);Ua.push(v(h(a).css("width")))},L);I(function(a,b){if(h.inArray(a,Xb)!==-1)a.style.width=Ua[b]},o);h(L).height(0);u&&(I(C,R),I(function(a){A.push(a.innerHTML);y.push(v(h(a).css("width")))},R),I(function(a,b){a.style.width=y[b]},Q),h(R).height(0));I(function(a,b){a.innerHTML='
'+z[b]+"
";a.childNodes[0].style.height= +"0";a.childNodes[0].style.overflow="hidden";a.style.width=Ua[b]},L);u&&I(function(a,b){a.innerHTML='
'+A[b]+"
";a.childNodes[0].style.height="0";a.childNodes[0].style.overflow="hidden";a.style.width=y[b]},R);if(p.outerWidth()j.offsetHeight||"scroll"==l.css("overflow-y")?f+b:f;if(U&&(j.scrollHeight>j.offsetHeight||"scroll"==l.css("overflow-y")))r.width=v(Q-b);(""===c||""!==d)&&K(a,1,"Possible column misalignment",6)}else Q="100%";q.width=v(Q); +g.width=v(Q);u&&(a.nScrollFoot.style.width=v(Q));!e&&U&&(q.height=v(s.offsetHeight+b));c=p.outerWidth();m[0].style.width=v(c);i.width=v(c);d=p.height()>j.clientHeight||"scroll"==l.css("overflow-y");e="padding"+(x.bScrollbarLeft?"Left":"Right");i[e]=d?b+"px":"0px";u&&(n[0].style.width=v(c),t[0].style.width=v(c),t[0].style[e]=d?b+"px":"0px");p.children("colgroup").insertBefore(p.children("thead"));l.scroll();if((a.bSorted||a.bFiltered)&&!a._drawHold)j.scrollTop=0}}function I(a,b,c){for(var d=0,e=0, +f=b.length,g,j;e").appendTo(j.find("tbody"));j.find("thead, tfoot").remove();j.append(h(a.nTHead).clone()).append(h(a.nTFoot).clone());j.find("tfoot th, tfoot td").css("width","");m=ra(a,j.find("thead")[0]);for(n=0;n").css({width:o.sWidthOrig,margin:0,padding:0,border:0,height:1}));if(a.aoData.length)for(n=0;n").css(f||e?{position:"absolute",top:0,left:0,height:1,right:0,overflow:"hidden"}:{}).append(j).appendTo(k);f&&g?j.width(g):f?(j.css("width","auto"),j.removeAttr("width"),j.width()").css("width",v(a)).appendTo(b||H.body),d=c[0].offsetWidth;c.remove();return d}function Fb(a, +b){var c=Gb(a,b);if(0>c)return null;var d=a.aoData[c];return!d.nTr?h("").html(B(a,c,b,"display"))[0]:d.anCells[b]}function Gb(a,b){for(var c,d=-1,e=-1,f=0,g=a.aoData.length;fd&&(d=c.length,e=f);return e}function v(a){return null===a?"0px":"number"==typeof a?0>a?"0px":a+"px":a.match(/\d$/)?a+"px":a}function X(a){var b,c,d=[],e=a.aoColumns,f,g,j,i;b=a.aaSortingFixed;c=h.isPlainObject(b);var m=[];f=function(a){a.length&& +!h.isArray(a[0])?m.push(a):h.merge(m,a)};h.isArray(b)&&f(b);c&&b.pre&&f(b.pre);f(a.aaSorting);c&&b.post&&f(b.post);for(a=0;ae?1:0,0!==c)return"asc"===j.dir?c:-c;c=d[a];e=d[b];return ce?1:0}):i.sort(function(a,b){var c,g,j,i,k=h.length,n=f[a]._aSortData,o=f[b]._aSortData;for(j=0;jg?1:0})}a.bSorted=!0}function Ib(a){for(var b,c,d=a.aoColumns,e=X(a),a=a.oLanguage.oAria,f=0,g=d.length;f/g,"");var i=c.nTh;i.removeAttribute("aria-sort");c.bSortable&&(0e?e+1:3));e=0;for(f=d.length;ee?e+1:3))}a.aLastSort=d}function Hb(a,b){var c=a.aoColumns[b],d=n.ext.order[c.sSortDataType],e;d&&(e=d.call(a.oInstance,a,b,ba(a,b)));for(var f,g=n.ext.type.order[c.sType+"-pre"],j=0,i=a.aoData.length;j=f.length?[0,c[1]]:c)}));b.search!==k&&h.extend(a.oPreviousSearch,Bb(b.search));if(b.columns){d=0;for(e=b.columns.length;d=c&&(b=c-d);b-=b%d;if(-1===d||0>b)b=0;a._iDisplayStart=b}function Na(a,b){var c=a.renderer,d=n.ext.renderer[b];return h.isPlainObject(c)&&c[b]?d[c[b]]||d._:"string"=== +typeof c?d[c]||d._:d._}function y(a){return a.oFeatures.bServerSide?"ssp":a.ajax||a.sAjaxSource?"ajax":"dom"}function ia(a,b){var c=[],c=Kb.numbers_length,d=Math.floor(c/2);b<=c?c=Y(0,b):a<=d?(c=Y(0,c-2),c.push("ellipsis"),c.push(b-1)):(a>=b-1-d?c=Y(b-(c-2),b):(c=Y(a-d+2,a+d-1),c.push("ellipsis"),c.push(b-1)),c.splice(0,0,"ellipsis"),c.splice(0,0,0));c.DT_el="span";return c}function Da(a){h.each({num:function(b){return za(b,a)},"num-fmt":function(b){return za(b,a,Ya)},"html-num":function(b){return za(b, +a,Aa)},"html-num-fmt":function(b){return za(b,a,Aa,Ya)}},function(b,c){x.type.order[b+a+"-pre"]=c;b.match(/^html\-/)&&(x.type.search[b+a]=x.type.search.html)})}function Lb(a){return function(){var b=[ya(this[n.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return n.ext.internal[a].apply(this,b)}}var n=function(a){this.$=function(a,b){return this.api(!0).$(a,b)};this._=function(a,b){return this.api(!0).rows(a,b).data()};this.api=function(a){return a?new s(ya(this[x.iApiIndex])):new s(this)}; +this.fnAddData=function(a,b){var c=this.api(!0),d=h.isArray(a)&&(h.isArray(a[0])||h.isPlainObject(a[0]))?c.rows.add(a):c.row.add(a);(b===k||b)&&c.draw();return d.flatten().toArray()};this.fnAdjustColumnSizing=function(a){var b=this.api(!0).columns.adjust(),c=b.settings()[0],d=c.oScroll;a===k||a?b.draw(!1):(""!==d.sX||""!==d.sY)&&la(c)};this.fnClearTable=function(a){var b=this.api(!0).clear();(a===k||a)&&b.draw()};this.fnClose=function(a){this.api(!0).row(a).child.hide()};this.fnDeleteRow=function(a, +b,c){var d=this.api(!0),a=d.rows(a),e=a.settings()[0],h=e.aoData[a[0][0]];a.remove();b&&b.call(this,e,h);(c===k||c)&&d.draw();return h};this.fnDestroy=function(a){this.api(!0).destroy(a)};this.fnDraw=function(a){this.api(!0).draw(a)};this.fnFilter=function(a,b,c,d,e,h){e=this.api(!0);null===b||b===k?e.search(a,c,d,h):e.column(b).search(a,c,d,h);e.draw()};this.fnGetData=function(a,b){var c=this.api(!0);if(a!==k){var d=a.nodeName?a.nodeName.toLowerCase():"";return b!==k||"td"==d||"th"==d?c.cell(a,b).data(): +c.row(a).data()||null}return c.data().toArray()};this.fnGetNodes=function(a){var b=this.api(!0);return a!==k?b.row(a).node():b.rows().nodes().flatten().toArray()};this.fnGetPosition=function(a){var b=this.api(!0),c=a.nodeName.toUpperCase();return"TR"==c?b.row(a).index():"TD"==c||"TH"==c?(a=b.cell(a).index(),[a.row,a.columnVisible,a.column]):null};this.fnIsOpen=function(a){return this.api(!0).row(a).child.isShown()};this.fnOpen=function(a,b,c){return this.api(!0).row(a).child(b,c).show().child()[0]}; +this.fnPageChange=function(a,b){var c=this.api(!0).page(a);(b===k||b)&&c.draw(!1)};this.fnSetColumnVis=function(a,b,c){a=this.api(!0).column(a).visible(b);(c===k||c)&&a.columns.adjust().draw()};this.fnSettings=function(){return ya(this[x.iApiIndex])};this.fnSort=function(a){this.api(!0).order(a).draw()};this.fnSortListener=function(a,b,c){this.api(!0).order.listener(a,b,c)};this.fnUpdate=function(a,b,c,d,e){var h=this.api(!0);c===k||null===c?h.row(b).data(a):h.cell(b,c).data(a);(e===k||e)&&h.columns.adjust(); +(d===k||d)&&h.draw();return 0};this.fnVersionCheck=x.fnVersionCheck;var b=this,c=a===k,d=this.length;c&&(a={});this.oApi=this.internal=x.internal;for(var e in n.ext.internal)e&&(this[e]=Lb(e));this.each(function(){var e={},g=1").appendTo(q)); +p.nTHead=b[0];b=q.children("tbody");b.length===0&&(b=h("").appendTo(q));p.nTBody=b[0];b=q.children("tfoot");if(b.length===0&&a.length>0&&(p.oScroll.sX!==""||p.oScroll.sY!==""))b=h("").appendTo(q);if(b.length===0||b.children().length===0)q.addClass(u.sNoFooter);else if(b.length>0){p.nTFoot=b[0];ea(p.aoFooter,p.nTFoot)}if(g.aaData)for(j=0;j/g,Zb=/^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/,$b=RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^|\\-)","g"),Ya=/[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi,M=function(a){return!a||!0===a||"-"===a?!0:!1},Nb=function(a){var b=parseInt(a,10);return!isNaN(b)&& +isFinite(a)?b:null},Ob=function(a,b){Za[b]||(Za[b]=RegExp(Qa(b),"g"));return"string"===typeof a&&"."!==b?a.replace(/\./g,"").replace(Za[b],"."):a},$a=function(a,b,c){var d="string"===typeof a;if(M(a))return!0;b&&d&&(a=Ob(a,b));c&&d&&(a=a.replace(Ya,""));return!isNaN(parseFloat(a))&&isFinite(a)},Pb=function(a,b,c){return M(a)?!0:!(M(a)||"string"===typeof a)?null:$a(a.replace(Aa,""),b,c)?!0:null},D=function(a,b,c){var d=[],e=0,f=a.length;if(c!==k)for(;ea.length)){b=a.slice().sort();for(var c=b[0],d=1,e=b.length;d")[0],Wb=va.textContent!==k,Yb= +/<.*?>/g,Oa=n.util.throttle,Rb=[],w=Array.prototype,ac=function(a){var b,c,d=n.settings,e=h.map(d,function(a){return a.nTable});if(a){if(a.nTable&&a.oApi)return[a];if(a.nodeName&&"table"===a.nodeName.toLowerCase())return b=h.inArray(a,e),-1!==b?[d[b]]:null;if(a&&"function"===typeof a.settings)return a.settings().toArray();"string"===typeof a?c=h(a):a instanceof h&&(c=a)}else return[];if(c)return c.map(function(){b=h.inArray(this,e);return-1!==b?d[b]:null}).toArray()};s=function(a,b){if(!(this instanceof +s))return new s(a,b);var c=[],d=function(a){(a=ac(a))&&(c=c.concat(a))};if(h.isArray(a))for(var e=0,f=a.length;ea?new s(b[a],this[a]):null},filter:function(a){var b=[];if(w.filter)b=w.filter.call(this,a,this);else for(var c=0,d=this.length;c").addClass(b),h("td",c).addClass(b).html(a)[0].colSpan=V(d),e.push(c[0]))};f(a,b);c._details&&c._details.detach();c._details=h(e); +c._detailsShow&&c._details.insertAfter(c.nTr)}return this});o(["row().child.show()","row().child().show()"],function(){Tb(this,!0);return this});o(["row().child.hide()","row().child().hide()"],function(){Tb(this,!1);return this});o(["row().child.remove()","row().child().remove()"],function(){db(this);return this});o("row().child.isShown()",function(){var a=this.context;return a.length&&this.length?a[0].aoData[this[0]]._detailsShow||!1:!1});var bc=/^([^:]+):(name|visIdx|visible)$/,Ub=function(a,b, +c,d,e){for(var c=[],d=0,f=e.length;d=0?b:g.length+b];if(typeof a==="function"){var e=Ba(c,f);return h.map(g,function(b,f){return a(f,Ub(c,f,0,0,e),i[f])?f:null})}var k=typeof a==="string"?a.match(bc): +"";if(k)switch(k[2]){case "visIdx":case "visible":b=parseInt(k[1],10);if(b<0){var n=h.map(g,function(a,b){return a.bVisible?b:null});return[n[n.length+b]]}return[aa(c,b)];case "name":return h.map(j,function(a,b){return a===k[1]?b:null});default:return[]}if(a.nodeName&&a._DT_CellIndex)return[a._DT_CellIndex.column];b=h(i).filter(a).map(function(){return h.inArray(this,i)}).toArray();if(b.length||!a.nodeName)return b;b=h(a).closest("*[data-dt-column]");return b.length?[b.data("dt-column")]:[]},c,f)}, +1);c.selector.cols=a;c.selector.opts=b;return c});u("columns().header()","column().header()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].nTh},1)});u("columns().footer()","column().footer()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].nTf},1)});u("columns().data()","column().data()",function(){return this.iterator("column-rows",Ub,1)});u("columns().dataSrc()","column().dataSrc()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].mData}, +1)});u("columns().cache()","column().cache()",function(a){return this.iterator("column-rows",function(b,c,d,e,f){return ja(b.aoData,f,"search"===a?"_aFilterData":"_aSortData",c)},1)});u("columns().nodes()","column().nodes()",function(){return this.iterator("column-rows",function(a,b,c,d,e){return ja(a.aoData,e,"anCells",b)},1)});u("columns().visible()","column().visible()",function(a,b){var c=this.iterator("column",function(b,c){if(a===k)return b.aoColumns[c].bVisible;var f=b.aoColumns,g=f[c],j=b.aoData, +i,m,l;if(a!==k&&g.bVisible!==a){if(a){var n=h.inArray(!0,D(f,"bVisible"),c+1);i=0;for(m=j.length;id;return!0};n.isDataTable= +n.fnIsDataTable=function(a){var b=h(a).get(0),c=!1;if(a instanceof n.Api)return!0;h.each(n.settings,function(a,e){var f=e.nScrollHead?h("table",e.nScrollHead)[0]:null,g=e.nScrollFoot?h("table",e.nScrollFoot)[0]:null;if(e.nTable===b||f===b||g===b)c=!0});return c};n.tables=n.fnTables=function(a){var b=!1;h.isPlainObject(a)&&(b=a.api,a=a.visible);var c=h.map(n.settings,function(b){if(!a||a&&h(b.nTable).is(":visible"))return b.nTable});return b?new s(c):c};n.camelToHungarian=J;o("$()",function(a,b){var c= +this.rows(b).nodes(),c=h(c);return h([].concat(c.filter(a).toArray(),c.find(a).toArray()))});h.each(["on","one","off"],function(a,b){o(b+"()",function(){var a=Array.prototype.slice.call(arguments);a[0]=h.map(a[0].split(/\s/),function(a){return!a.match(/\.dt\b/)?a+".dt":a}).join(" ");var d=h(this.tables().nodes());d[b].apply(d,a);return this})});o("clear()",function(){return this.iterator("table",function(a){oa(a)})});o("settings()",function(){return new s(this.context,this.context)});o("init()",function(){var a= +this.context;return a.length?a[0].oInit:null});o("data()",function(){return this.iterator("table",function(a){return D(a.aoData,"_aData")}).flatten()});o("destroy()",function(a){a=a||!1;return this.iterator("table",function(b){var c=b.nTableWrapper.parentNode,d=b.oClasses,e=b.nTable,f=b.nTBody,g=b.nTHead,j=b.nTFoot,i=h(e),f=h(f),k=h(b.nTableWrapper),l=h.map(b.aoData,function(a){return a.nTr}),o;b.bDestroying=!0;r(b,"aoDestroyCallback","destroy",[b]);a||(new s(b)).columns().visible(!0);k.off(".DT").find(":not(tbody *)").off(".DT"); +h(E).off(".DT-"+b.sInstance);e!=g.parentNode&&(i.children("thead").detach(),i.append(g));j&&e!=j.parentNode&&(i.children("tfoot").detach(),i.append(j));b.aaSorting=[];b.aaSortingFixed=[];wa(b);h(l).removeClass(b.asStripeClasses.join(" "));h("th, td",g).removeClass(d.sSortable+" "+d.sSortableAsc+" "+d.sSortableDesc+" "+d.sSortableNone);f.children().detach();f.append(l);g=a?"remove":"detach";i[g]();k[g]();!a&&c&&(c.insertBefore(e,b.nTableReinsertBefore),i.css("width",b.sDestroyWidth).removeClass(d.sTable), +(o=b.asDestroyStripes.length)&&f.children().each(function(a){h(this).addClass(b.asDestroyStripes[a%o])}));c=h.inArray(b,n.settings);-1!==c&&n.settings.splice(c,1)})});h.each(["column","row","cell"],function(a,b){o(b+"s().every()",function(a){var d=this.selector.opts,e=this;return this.iterator(b,function(f,g,h,i,m){a.call(e[b](g,"cell"===b?h:d,"cell"===b?d:k),g,h,i,m)})})});o("i18n()",function(a,b,c){var d=this.context[0],a=S(a)(d.oLanguage);a===k&&(a=b);c!==k&&h.isPlainObject(a)&&(a=a[c]!==k?a[c]: +a._);return a.replace("%d",c)});n.version="1.10.18";n.settings=[];n.models={};n.models.oSearch={bCaseInsensitive:!0,sSearch:"",bRegex:!1,bSmart:!0};n.models.oRow={nTr:null,anCells:null,_aData:[],_aSortData:null,_aFilterData:null,_sFilterRow:null,_sRowStripe:"",src:null,idx:-1};n.models.oColumn={idx:null,aDataSort:null,asSorting:null,bSearchable:null,bSortable:null,bVisible:null,_sManualType:null,_bAttrSrc:!1,fnCreatedCell:null,fnGetData:null,fnSetData:null,mData:null,mRender:null,nTh:null,nTf:null, +sClass:null,sContentPadding:null,sDefaultContent:null,sName:null,sSortDataType:"std",sSortingClass:null,sSortingClassJUI:null,sTitle:null,sType:null,sWidth:null,sWidthOrig:null};n.defaults={aaData:null,aaSorting:[[0,"asc"]],aaSortingFixed:[],ajax:null,aLengthMenu:[10,25,50,100],aoColumns:null,aoColumnDefs:null,aoSearchCols:[],asStripeClasses:null,bAutoWidth:!0,bDeferRender:!1,bDestroy:!1,bFilter:!0,bInfo:!0,bLengthChange:!0,bPaginate:!0,bProcessing:!1,bRetrieve:!1,bScrollCollapse:!1,bServerSide:!1, +bSort:!0,bSortMulti:!0,bSortCellsTop:!1,bSortClasses:!0,bStateSave:!1,fnCreatedRow:null,fnDrawCallback:null,fnFooterCallback:null,fnFormatNumber:function(a){return a.toString().replace(/\B(?=(\d{3})+(?!\d))/g,this.oLanguage.sThousands)},fnHeaderCallback:null,fnInfoCallback:null,fnInitComplete:null,fnPreDrawCallback:null,fnRowCallback:null,fnServerData:null,fnServerParams:null,fnStateLoadCallback:function(a){try{return JSON.parse((-1===a.iStateDuration?sessionStorage:localStorage).getItem("DataTables_"+ +a.sInstance+"_"+location.pathname))}catch(b){}},fnStateLoadParams:null,fnStateLoaded:null,fnStateSaveCallback:function(a,b){try{(-1===a.iStateDuration?sessionStorage:localStorage).setItem("DataTables_"+a.sInstance+"_"+location.pathname,JSON.stringify(b))}catch(c){}},fnStateSaveParams:null,iStateDuration:7200,iDeferLoading:null,iDisplayLength:10,iDisplayStart:0,iTabIndex:0,oClasses:{},oLanguage:{oAria:{sSortAscending:": activate to sort column ascending",sSortDescending:": activate to sort column descending"}, +oPaginate:{sFirst:"First",sLast:"Last",sNext:"Next",sPrevious:"Previous"},sEmptyTable:"No data available in table",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sDecimal:"",sThousands:",",sLengthMenu:"Show _MENU_ entries",sLoadingRecords:"Loading...",sProcessing:"Processing...",sSearch:"Search:",sSearchPlaceholder:"",sUrl:"",sZeroRecords:"No matching records found"},oSearch:h.extend({}, +n.models.oSearch),sAjaxDataProp:"data",sAjaxSource:null,sDom:"lfrtip",searchDelay:null,sPaginationType:"simple_numbers",sScrollX:"",sScrollXInner:"",sScrollY:"",sServerMethod:"GET",renderer:null,rowId:"DT_RowId"};Z(n.defaults);n.defaults.column={aDataSort:null,iDataSort:-1,asSorting:["asc","desc"],bSearchable:!0,bSortable:!0,bVisible:!0,fnCreatedCell:null,mData:null,mRender:null,sCellType:"td",sClass:"",sContentPadding:"",sDefaultContent:null,sName:"",sSortDataType:"std",sTitle:null,sType:null,sWidth:null}; +Z(n.defaults.column);n.models.oSettings={oFeatures:{bAutoWidth:null,bDeferRender:null,bFilter:null,bInfo:null,bLengthChange:null,bPaginate:null,bProcessing:null,bServerSide:null,bSort:null,bSortMulti:null,bSortClasses:null,bStateSave:null},oScroll:{bCollapse:null,iBarWidth:0,sX:null,sXInner:null,sY:null},oLanguage:{fnInfoCallback:null},oBrowser:{bScrollOversize:!1,bScrollbarLeft:!1,bBounding:!1,barWidth:0},ajax:null,aanFeatures:[],aoData:[],aiDisplay:[],aiDisplayMaster:[],aIds:{},aoColumns:[],aoHeader:[], +aoFooter:[],oPreviousSearch:{},aoPreSearchCols:[],aaSorting:null,aaSortingFixed:[],asStripeClasses:null,asDestroyStripes:[],sDestroyWidth:0,aoRowCallback:[],aoHeaderCallback:[],aoFooterCallback:[],aoDrawCallback:[],aoRowCreatedCallback:[],aoPreDrawCallback:[],aoInitComplete:[],aoStateSaveParams:[],aoStateLoadParams:[],aoStateLoaded:[],sTableId:"",nTable:null,nTHead:null,nTFoot:null,nTBody:null,nTableWrapper:null,bDeferLoading:!1,bInitialised:!1,aoOpenRows:[],sDom:null,searchDelay:null,sPaginationType:"two_button", +iStateDuration:0,aoStateSave:[],aoStateLoad:[],oSavedState:null,oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,bAjaxDataGet:!0,jqXHR:null,json:k,oAjaxData:k,fnServerData:null,aoServerParams:[],sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,iDraw:0,bDrawing:!1,iDrawError:-1,_iDisplayLength:10,_iDisplayStart:0,_iRecordsTotal:0,_iRecordsDisplay:0,oClasses:{},bFiltered:!1,bSorted:!1,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],fnRecordsTotal:function(){return"ssp"==y(this)?1*this._iRecordsTotal: +this.aiDisplayMaster.length},fnRecordsDisplay:function(){return"ssp"==y(this)?1*this._iRecordsDisplay:this.aiDisplay.length},fnDisplayEnd:function(){var a=this._iDisplayLength,b=this._iDisplayStart,c=b+a,d=this.aiDisplay.length,e=this.oFeatures,f=e.bPaginate;return e.bServerSide?!1===f||-1===a?b+d:Math.min(b+a,this._iRecordsDisplay):!f||c>d||-1===a?d:c},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null,aLastSort:[],oPlugins:{},rowIdFn:null,rowId:null};n.ext=x={buttons:{}, +classes:{},build:"dt/dt-1.10.18",errMode:"alert",feature:[],search:[],selector:{cell:[],column:[],row:[]},internal:{},legacy:{ajax:null},pager:{},renderer:{pageButton:{},header:{}},order:{},type:{detect:[],search:{},order:{}},_unique:0,fnVersionCheck:n.fnVersionCheck,iApiIndex:0,oJUIClasses:{},sVersion:n.version};h.extend(x,{afnFiltering:x.search,aTypes:x.type.detect,ofnSearch:x.type.search,oSort:x.type.order,afnSortData:x.order,aoFeatures:x.feature,oApi:x.internal,oStdClasses:x.classes,oPagination:x.pager}); +h.extend(n.ext.classes,{sTable:"dataTable",sNoFooter:"no-footer",sPageButton:"paginate_button",sPageButtonActive:"current",sPageButtonDisabled:"disabled",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled", +sSortableDesc:"sorting_desc_disabled",sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sFilterInput:"",sLengthSelect:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sHeaderTH:"",sFooterTH:"",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"", +sJUIHeader:"",sJUIFooter:""});var Kb=n.ext.pager;h.extend(Kb,{simple:function(){return["previous","next"]},full:function(){return["first","previous","next","last"]},numbers:function(a,b){return[ia(a,b)]},simple_numbers:function(a,b){return["previous",ia(a,b),"next"]},full_numbers:function(a,b){return["first","previous",ia(a,b),"next","last"]},first_last_numbers:function(a,b){return["first",ia(a,b),"last"]},_numbers:ia,numbers_length:7});h.extend(!0,n.ext.renderer,{pageButton:{_:function(a,b,c,d,e, +f){var g=a.oClasses,j=a.oLanguage.oPaginate,i=a.oLanguage.oAria.paginate||{},m,l,n=0,o=function(b,d){var k,s,u,r,v=function(b){Ta(a,b.data.action,true)};k=0;for(s=d.length;k").appendTo(b);o(u,r)}else{m=null;l="";switch(r){case "ellipsis":b.append('');break;case "first":m=j.sFirst;l=r+(e>0?"":" "+g.sPageButtonDisabled);break;case "previous":m=j.sPrevious;l=r+(e>0?"":" "+g.sPageButtonDisabled);break;case "next":m= +j.sNext;l=r+(e",{"class":g.sPageButton+" "+l,"aria-controls":a.sTableId,"aria-label":i[r],"data-dt-idx":n,tabindex:a.iTabIndex,id:c===0&&typeof r==="string"?a.sTableId+"_"+r:null}).html(m).appendTo(b);Wa(u,{action:r},v);n++}}}},s;try{s=h(b).find(H.activeElement).data("dt-idx")}catch(u){}o(h(b).empty(),d);s!==k&&h(b).find("[data-dt-idx="+ +s+"]").focus()}}});h.extend(n.ext.type.detect,[function(a,b){var c=b.oLanguage.sDecimal;return $a(a,c)?"num"+c:null},function(a){if(a&&!(a instanceof Date)&&!Zb.test(a))return null;var b=Date.parse(a);return null!==b&&!isNaN(b)||M(a)?"date":null},function(a,b){var c=b.oLanguage.sDecimal;return $a(a,c,!0)?"num-fmt"+c:null},function(a,b){var c=b.oLanguage.sDecimal;return Pb(a,c)?"html-num"+c:null},function(a,b){var c=b.oLanguage.sDecimal;return Pb(a,c,!0)?"html-num-fmt"+c:null},function(a){return M(a)|| +"string"===typeof a&&-1!==a.indexOf("<")?"html":null}]);h.extend(n.ext.type.search,{html:function(a){return M(a)?a:"string"===typeof a?a.replace(Mb," ").replace(Aa,""):""},string:function(a){return M(a)?a:"string"===typeof a?a.replace(Mb," "):a}});var za=function(a,b,c,d){if(0!==a&&(!a||"-"===a))return-Infinity;b&&(a=Ob(a,b));a.replace&&(c&&(a=a.replace(c,"")),d&&(a=a.replace(d,"")));return 1*a};h.extend(x.type.order,{"date-pre":function(a){a=Date.parse(a);return isNaN(a)?-Infinity:a},"html-pre":function(a){return M(a)? +"":a.replace?a.replace(/<.*?>/g,"").toLowerCase():a+""},"string-pre":function(a){return M(a)?"":"string"===typeof a?a.toLowerCase():!a.toString?"":a.toString()},"string-asc":function(a,b){return ab?1:0},"string-desc":function(a,b){return ab?-1:0}});Da("");h.extend(!0,n.ext.renderer,{header:{_:function(a,b,c,d){h(a.nTable).on("order.dt.DT",function(e,f,g,h){if(a===f){e=c.idx;b.removeClass(c.sSortingClass+" "+d.sSortAsc+" "+d.sSortDesc).addClass(h[e]=="asc"?d.sSortAsc:h[e]=="desc"?d.sSortDesc: +c.sSortingClass)}})},jqueryui:function(a,b,c,d){h("
").addClass(d.sSortJUIWrapper).append(b.contents()).append(h("").addClass(d.sSortIcon+" "+c.sSortingClassJUI)).appendTo(b);h(a.nTable).on("order.dt.DT",function(e,f,g,h){if(a===f){e=c.idx;b.removeClass(d.sSortAsc+" "+d.sSortDesc).addClass(h[e]=="asc"?d.sSortAsc:h[e]=="desc"?d.sSortDesc:c.sSortingClass);b.find("span."+d.sSortIcon).removeClass(d.sSortJUIAsc+" "+d.sSortJUIDesc+" "+d.sSortJUI+" "+d.sSortJUIAscAllowed+" "+d.sSortJUIDescAllowed).addClass(h[e]== +"asc"?d.sSortJUIAsc:h[e]=="desc"?d.sSortJUIDesc:c.sSortingClassJUI)}})}}});var Vb=function(a){return"string"===typeof a?a.replace(//g,">").replace(/"/g,"""):a};n.render={number:function(a,b,c,d,e){return{display:function(f){if("number"!==typeof f&&"string"!==typeof f)return f;var g=0>f?"-":"",h=parseFloat(f);if(isNaN(h))return Vb(f);h=h.toFixed(c);f=Math.abs(h);h=parseInt(f,10);f=c?b+(f-h).toFixed(c).substring(2):"";return g+(d||"")+h.toString().replace(/\B(?=(\d{3})+(?!\d))/g, +a)+f+(e||"")}}},text:function(){return{display:Vb}}};h.extend(n.ext.internal,{_fnExternApiFunc:Lb,_fnBuildAjax:sa,_fnAjaxUpdate:lb,_fnAjaxParameters:ub,_fnAjaxUpdateDraw:vb,_fnAjaxDataSrc:ta,_fnAddColumn:Ea,_fnColumnOptions:ka,_fnAdjustColumnSizing:$,_fnVisibleToColumnIndex:aa,_fnColumnIndexToVisible:ba,_fnVisbleColumns:V,_fnGetColumns:ma,_fnColumnTypes:Ga,_fnApplyColumnDefs:ib,_fnHungarianMap:Z,_fnCamelToHungarian:J,_fnLanguageCompat:Ca,_fnBrowserDetect:gb,_fnAddData:O,_fnAddTr:na,_fnNodeToDataIndex:function(a, +b){return b._DT_RowIndex!==k?b._DT_RowIndex:null},_fnNodeToColumnIndex:function(a,b,c){return h.inArray(c,a.aoData[b].anCells)},_fnGetCellData:B,_fnSetCellData:jb,_fnSplitObjNotation:Ja,_fnGetObjectDataFn:S,_fnSetObjectDataFn:N,_fnGetDataMaster:Ka,_fnClearTable:oa,_fnDeleteIndex:pa,_fnInvalidate:da,_fnGetRowElements:Ia,_fnCreateTr:Ha,_fnBuildHead:kb,_fnDrawHead:fa,_fnDraw:P,_fnReDraw:T,_fnAddOptionsHtml:nb,_fnDetectHeader:ea,_fnGetUniqueThs:ra,_fnFeatureHtmlFilter:pb,_fnFilterComplete:ga,_fnFilterCustom:yb, +_fnFilterColumn:xb,_fnFilter:wb,_fnFilterCreateSearch:Pa,_fnEscapeRegex:Qa,_fnFilterData:zb,_fnFeatureHtmlInfo:sb,_fnUpdateInfo:Cb,_fnInfoMacros:Db,_fnInitialise:ha,_fnInitComplete:ua,_fnLengthChange:Ra,_fnFeatureHtmlLength:ob,_fnFeatureHtmlPaginate:tb,_fnPageChange:Ta,_fnFeatureHtmlProcessing:qb,_fnProcessingDisplay:C,_fnFeatureHtmlTable:rb,_fnScrollDraw:la,_fnApplyToChildren:I,_fnCalculateColumnWidths:Fa,_fnThrottle:Oa,_fnConvertToWidth:Eb,_fnGetWidestNode:Fb,_fnGetMaxLenString:Gb,_fnStringToCss:v, +_fnSortFlatten:X,_fnSort:mb,_fnSortAria:Ib,_fnSortListener:Va,_fnSortAttachListener:Ma,_fnSortingClasses:wa,_fnSortData:Hb,_fnSaveState:xa,_fnLoadState:Jb,_fnSettingsFromNode:ya,_fnLog:K,_fnMap:F,_fnBindAction:Wa,_fnCallbackReg:z,_fnCallbackFire:r,_fnLengthOverflow:Sa,_fnRenderer:Na,_fnDataSource:y,_fnRowAttributes:La,_fnExtend:Xa,_fnCalculateEnd:function(){}});h.fn.dataTable=n;n.$=h;h.fn.dataTableSettings=n.settings;h.fn.dataTableExt=n.ext;h.fn.DataTable=function(a){return h(this).dataTable(a).api()}; +h.each(n,function(a,b){h.fn.DataTable[a]=b});return h.fn.dataTable}); + + diff --git a/backend/app/plugins/wiaas/assets/js/wiaas-admin-cl-packages.js b/backend/app/plugins/wiaas/assets/js/wiaas-admin-cl-packages.js index 55332cb..5743a71 100644 --- a/backend/app/plugins/wiaas/assets/js/wiaas-admin-cl-packages.js +++ b/backend/app/plugins/wiaas/assets/js/wiaas-admin-cl-packages.js @@ -1,5 +1,15 @@ jQuery(document).ready(function ($) { + $( document.body ).on( 'init_tooltips', function() { + $( '.woocommerce-help-tip' ).tipTip( { + 'attribute': 'data-tip', + 'fadeIn': 50, + 'fadeOut': 50, + 'delay': 200, + 'defaultPosition': 'top' + } ); + } ).trigger( 'init_tooltips' ); + $('#tabs').each(function() { var disabled = $( this ).data('disabled') || ''; diff --git a/backend/app/plugins/wiaas/assets/js/wiaas-admin-dashboard.js b/backend/app/plugins/wiaas/assets/js/wiaas-admin-dashboard.js new file mode 100644 index 0000000..9d08e2b --- /dev/null +++ b/backend/app/plugins/wiaas/assets/js/wiaas-admin-dashboard.js @@ -0,0 +1,14 @@ +jQuery(document).ready(function($) { + $('#wiaas_order_central_table').DataTable({ + "paging": false, + "info": false, + "filter": false, + "order": [[ 0, "desc" ]] + }); + + $('#wiaas_next_actions_table').DataTable({ + "info": false, + "filter": false, + "order": [[ 0, "desc" ]] + }); +} ); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/assets/js/wiaas-admin-delivery-process.js b/backend/app/plugins/wiaas/assets/js/wiaas-admin-delivery-process.js index 10341bb..9af6a14 100644 --- a/backend/app/plugins/wiaas/assets/js/wiaas-admin-delivery-process.js +++ b/backend/app/plugins/wiaas/assets/js/wiaas-admin-delivery-process.js @@ -5,4 +5,34 @@ jQuery(document).ready(function ($) { $('#wiaas_delivery_process_navigation_action').val(action); }); + + $('#wiaas_delivery_process_add_note').click(function(e) { + if ( ! $( 'textarea#wiaas_add_order_note' ).val() ) { + return; + } + + $( '#wiaas_delivery_process_order_notes' ).block({ + message: null, + overlayCSS: { + background: '#fff', + opacity: 0.6 + } + }); + + var data = { + action: 'wiaas_add_order_note', + post_id: $( 'textarea#wiaas_add_order_note' ).data('order-id'), + note: $( 'textarea#wiaas_add_order_note' ).val(), + security: $( 'textarea#wiaas_add_order_note' ).data('nonce'), + }; + + + $.post( ajaxurl, data, function( response ) { + $( '#delivery_process_order_notes_list' ).prepend( response ); + $( '#wiaas_delivery_process_order_notes' ).unblock(); + $( '#wiaas_add_order_note' ).val( '' ); + }); + + return false; + }); }); diff --git a/backend/app/plugins/wiaas/assets/js/wiaas-admin-product-quick-edit.js b/backend/app/plugins/wiaas/assets/js/wiaas-admin-product-quick-edit.js new file mode 100644 index 0000000..971122b --- /dev/null +++ b/backend/app/plugins/wiaas/assets/js/wiaas-admin-product-quick-edit.js @@ -0,0 +1,32 @@ +/*global inlineEditPost, woocommerce_admin, woocommerce_quick_edit */ +jQuery(function( $ ) { + $('#the-list').on('click', '.editinline', function(){ + + /** + * Extract metadata and put it as the value for the custom field form + */ + inlineEditPost.revert(); + + var post_id = jQuery(this).closest('tr').attr('id'); + + post_id = post_id.replace("post-", ""); + + var $cfd_inline_data = jQuery('#package_additional_fields_inline_' + post_id), + $wc_inline_data = jQuery('#woocommerce_inline_' + post_id ); + + jQuery('textarea[name="_package_pricing"]', '.inline-edit-row').val($cfd_inline_data.find("#_package_prices").text()); + + + /** + * Only show custom field for appropriate types of products (simple) + */ + var product_type = $wc_inline_data.find('.product_type').text(); + + if (product_type==='bundle') { + jQuery('#wiaas_pricing_quick_edit', '.inline-edit-row').show(); + } else { + jQuery('#wiaas_pricing_quick_edit', '.inline-edit-row').hide(); + } + + }); +}); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/admin/admin-cl/class-wiaas-admin-cl-orders.php b/backend/app/plugins/wiaas/includes/admin/admin-cl/class-wiaas-admin-cl-orders.php index 2486d65..c562cc9 100644 --- a/backend/app/plugins/wiaas/includes/admin/admin-cl/class-wiaas-admin-cl-orders.php +++ b/backend/app/plugins/wiaas/includes/admin/admin-cl/class-wiaas-admin-cl-orders.php @@ -78,12 +78,16 @@ class Wiaas_Admin_CL_Orders { * @return array */ public static function columns_for_list_table_orders($columns) { - $show_columns = array(); - $show_columns['cb'] = $columns['cb']; - $show_columns['_wiaas_order_number'] = __( 'Order', 'woocommerce' ); - $show_columns['order_date'] = __( 'Date', 'woocommerce' ); - $show_columns['order_status'] = __( 'Status', 'woocommerce' ); - $show_columns['order_total'] = __( 'Total', 'woocommerce' ); + $show_columns = array(); + $show_columns['cb'] = $columns['cb']; + $show_columns['_wiaas_order_number'] = __( 'Order', 'wiaas' ); + $show_columns['order_date'] = $columns['order_date']; + $show_columns['wiaas_reference'] = __( 'Location', 'wiaas' ); + $show_columns['wiaas_customer'] = __( 'Customer', 'wiaas' ); + $show_columns['order_status'] = $columns['order_status']; + $show_columns['billing_address'] = $columns['billing_address']; + $show_columns['shipping_address'] = $columns['shipping_address']; + $show_columns['order_total'] = $columns['order_total']; return $show_columns; } @@ -114,10 +118,13 @@ class Wiaas_Admin_CL_Orders { $order = wc_get_order($order_id); - echo '#' . esc_attr( $order->get_order_number() ) . ''; + $order_url = $entry_url = admin_url('admin.php?page=wiaas-order-delivery&id=' . $order->get_id()); if ( $order->get_status() !== 'trash' ) { + echo '#' . esc_attr( $order->get_order_number() ) . ''; echo '' . esc_html( __( 'Preview', 'wiaas' ) ) . ''; + } else { + echo '#' . esc_attr( $order->get_order_number() ) . ''; } } } diff --git a/backend/app/plugins/wiaas/includes/admin/admin-cl/class-wiaas-admin-cl-packages.php b/backend/app/plugins/wiaas/includes/admin/admin-cl/class-wiaas-admin-cl-packages.php index ec50c23..c1e7b79 100644 --- a/backend/app/plugins/wiaas/includes/admin/admin-cl/class-wiaas-admin-cl-packages.php +++ b/backend/app/plugins/wiaas/includes/admin/admin-cl/class-wiaas-admin-cl-packages.php @@ -40,6 +40,7 @@ class Wiaas_Admin_CL_Packages { $plugin_url = untrailingslashit( plugins_url( '/', WIAAS_FILE ) ); wp_enqueue_style( 'wiaas_admin_menu', $plugin_url . '/assets/css/menu.css' ); + } public static function add_cl_packages_menu() { diff --git a/backend/app/plugins/wiaas/includes/admin/admin-cl/views/html-cl-package-details.php b/backend/app/plugins/wiaas/includes/admin/admin-cl/views/html-cl-package-details.php index d2b95b5..507f117 100644 --- a/backend/app/plugins/wiaas/includes/admin/admin-cl/views/html-cl-package-details.php +++ b/backend/app/plugins/wiaas/includes/admin/admin-cl/views/html-cl-package-details.php @@ -149,25 +149,6 @@ if ( ! defined( 'ABSPATH' ) ) {
- -
-
- - - -
-
- - - -
-
- - - -
-
-
  • |
  • diff --git a/backend/app/plugins/wiaas/includes/admin/admin-cl/views/html-cl-package-prices.php b/backend/app/plugins/wiaas/includes/admin/admin-cl/views/html-cl-package-prices.php index cb3220f..522d48a 100644 --- a/backend/app/plugins/wiaas/includes/admin/admin-cl/views/html-cl-package-prices.php +++ b/backend/app/plugins/wiaas/includes/admin/admin-cl/views/html-cl-package-prices.php @@ -20,7 +20,13 @@ $id = isset($customer_id) ? 'extras_customer_'.$customer_id : 'extras_default'; ?> - + + + + + + + - -
    - - -
    - 0) { - ?> -
    - - +
    + + - -
    - -
    - - - -
    + data-target="wiaas_cl_fixed_extra_" + data-type="fixed" + name="cl_extras[][fixed]" + value="" + type="text" + > +
    +
    + + +
    + + + +
    + + +
    +
    + + +
    + + + + + 0) { + ?> +
    + + +
    +
    + + +
    + +
    = diff --git a/backend/app/plugins/wiaas/includes/admin/admin-supplier/class-wiaas-admin-supplier-orders.php b/backend/app/plugins/wiaas/includes/admin/admin-supplier/class-wiaas-admin-supplier-orders.php index 700272b..cbd7479 100644 --- a/backend/app/plugins/wiaas/includes/admin/admin-supplier/class-wiaas-admin-supplier-orders.php +++ b/backend/app/plugins/wiaas/includes/admin/admin-supplier/class-wiaas-admin-supplier-orders.php @@ -21,11 +21,15 @@ class Wiaas_Admin_Supplier_Orders { add_filter('woocommerce_admin_order_preview_actions', array(__CLASS__, 'remove_actions_from_order_preview')); - add_filter('woocommerce_admin_order_preview_line_items', array(__CLASS__, 'filter_order_items_for_order_preview'), 10, 2); + add_filter('woocommerce_admin_order_preview_line_items', array(__CLASS__, 'filter_order_items_for_order_preview'), 999, 2); + + add_filter( 'woocommerce_admin_order_preview_line_item_columns', array(__CLASS__, 'customize_order_preview_columns'), 999); + + add_filter( 'woocommerce_admin_order_preview_line_item_column_wiaas_simple_product_bundle', array(__CLASS__, 'render_bundled_item_bundle'), 10, 4); add_filter('manage_shop_order_posts_columns', array(__CLASS__, 'columns_for_list_table_orders'), 999); - add_filter('manage_edit-shop_order_sortable_columns', array(__CLASS__, 'define_sortable_columns_for_list_table_orders')); + add_filter('manage_edit-shop_order_sortable_columns', array(__CLASS__, 'define_sortable_columns_for_list_table_orders'), 999); add_action('manage_shop_order_posts_custom_column', array(__CLASS__, 'render_columns_for_list_table_orders'), 999, 2); } @@ -53,7 +57,7 @@ class Wiaas_Admin_Supplier_Orders { * Show only simple products from this supplier on order preview * * @param $order_items - * @param $order + * @param WC_Order $order * * @return array */ @@ -61,26 +65,51 @@ class Wiaas_Admin_Supplier_Orders { $user_organisation_id = Wiaas_User_Organization::get_user_organization_id(wp_get_current_user()->ID); + $order_items = $order->get_items(); $items = array(); foreach ($order_items as $key => $order_item) { - $product = wc_get_product($order_item->get_product_id()); + if (wc_pb_is_bundled_order_item($order_item)) { - if ($product->get_type() == 'simple') { + $item_supplier_organization_id = absint($order_item['wiaas_supplier_organization_id']); - $supplier_organisation_id = Wiaas_Product_Supplier - ::get_supplier_organisation_id_from_product($order_item->get_product_id()); + if ($item_supplier_organization_id === $user_organisation_id) { - if ($supplier_organisation_id === $user_organisation_id) { - $items[$key] = $order_item; - } + $items[] = $order_item; + } } } return $items; } + public static function customize_order_preview_columns() { + + return array( + 'product' => __('Product', 'wiaas'), + 'quantity' => __( 'Quantity', 'wiaas' ), + 'wiaas_simple_product_bundle' => __( '', 'wiaas' ) + ); + } + + public static function render_bundled_item_bundle($empty, $item, $item_id, $order) { + + $html = ''; + + if (wc_pb_is_bundled_order_item($item) ) { + + $container_order_item = wc_pb_get_bundled_order_item_container($item, $order); + + if ( ! empty($container_order_item) ) { + + return $container_order_item->get_name(); + } + } + + return $html; + } + /** * Override default table columns so only supplier specific columns are visible * @@ -89,11 +118,14 @@ class Wiaas_Admin_Supplier_Orders { * @return array */ public static function columns_for_list_table_orders($columns) { - $show_columns = array(); - $show_columns['cb'] = $columns['cb']; - $show_columns['_wiaas_order_number'] = __( 'Order', 'woocommerce' ); - $show_columns['order_date'] = __( 'Date', 'woocommerce' ); - $show_columns['order_status'] = __( 'Status', 'woocommerce' ); + $show_columns = array(); + $show_columns['cb'] = $columns['cb']; + $show_columns['_wiaas_order_number'] = __( 'Order', 'wiaas' ); + $show_columns['order_date'] = $columns['order_date']; + $show_columns['wiaas_reference'] = __( 'Location', 'wiaas' ); + $show_columns['wiaas_customer'] = __( 'Customer', 'wiaas' ); + $show_columns['order_status'] = $columns['order_status']; + $show_columns['shipping_address'] = $columns['shipping_address']; return $show_columns; } @@ -124,11 +156,14 @@ class Wiaas_Admin_Supplier_Orders { $order = wc_get_order($order_id); - echo '#' . esc_attr($order->get_order_number()) . ''; + $order_url = $entry_url = admin_url('admin.php?page=wiaas-order-delivery&id=' . $order->get_id()); - if ($order->get_status() !== 'trash') { - echo '' . esc_html(__('Preview', 'wiaas')) . ''; - } + if ( $order->get_status() !== 'trash' ) { + echo '#' . esc_attr( $order->get_order_number() ) . ''; + echo '' . esc_html( __( 'Preview', 'wiaas' ) ) . ''; + } else { + echo '#' . esc_attr( $order->get_order_number() ) . ''; + } } } } diff --git a/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-cl.php b/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-cl.php index 94f723f..70c7ef8 100644 --- a/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-cl.php +++ b/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-cl.php @@ -37,6 +37,7 @@ class Wiaas_Admin_CL { $plugin_url = untrailingslashit( plugins_url( '/', WIAAS_FILE ) ); wp_enqueue_script( 'wiaas_admin_cl_packages', $plugin_url . '/assets/js/wiaas-admin-cl-packages.js' ); + wp_enqueue_script('jquery-tiptip'); wp_enqueue_style( 'wiaas_admin_cl', $plugin_url . '/assets/css/wiaas-admin-cl.css' ); } diff --git a/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-countries.php b/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-countries.php new file mode 100644 index 0000000..342f59f --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-countries.php @@ -0,0 +1,71 @@ +'. $code . ''; + } + + if ($column === 'wiaas_vat') { + + $vat = get_term_meta($id, '_wiaas_country_vat', true); + $columns .= ''. $vat . ''; + } + + if ($column === 'wiaas_currency') { + + $currency = get_term_meta($id, '_wiaas_country_currency', true); + $columns .= ''. $currency . ''; + } + + return $columns; + } + + public static function populate_country_codes($field) { + $countries_list = Wiaas_Countries::get_country_choices(); + + $countries_choices = array(); + foreach ($countries_list as $code => $name) { + + $countries_choices[$code] = $code . ' - ' . $name; + } + + $field['choices'] = $countries_choices; + + return $field; + } + + public static function populate_country_currencies($field) { + + $field['choices'] = Wiaas_Countries::get_currency_choices(); + + return $field; + } +} + +Wiaas_Admin_Countries::init(); diff --git a/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-dashboard.php b/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-dashboard.php new file mode 100644 index 0000000..82e809c --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-dashboard.php @@ -0,0 +1,172 @@ + 5, + 'status' => array('open', 'processing') + )); + + if (empty($orders)) { + + ?> +
    +

    + +

    +
    + + + + + + + + + + + + + get_date_created() ? $order->get_date_created()->getTimestamp() : ''; + $show_date = '–'; + + if ( $order_timestamp ) { + + if ( $order_timestamp > strtotime( '-1 day', current_time( 'timestamp', true ) ) && $order_timestamp <= current_time( 'timestamp', true ) ) { + $show_date = sprintf( + /* translators: %s: human-readable time difference */ + _x( '%s ago', '%s = human-readable time difference', 'wiaas' ), + human_time_diff( $order->get_date_created()->getTimestamp(), current_time( 'timestamp', true ) ) + ); + } else { + $show_date = $order->get_date_created()->date_i18n( __( 'M j, Y', 'wiaas' ) ); + } + } + + ?> + + + + + + + +
    + + get_id() ) . '&action=edit' ); + } else { + $order_edit_url = admin_url('admin.php?page=wiaas-order-delivery&id=' . absint( $order->get_id() ) ); + } + + echo '#' . + esc_html($order->get_order_number()) . + ''; + ?> + +
    + +
    + + + get_status() ) ) ?> + + + get_formatted_order_total() ?>
    + + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + +
    + + # + + + + + +
    + ID); + break; + + case 'wiaas_commercial_lead': + $column_content = Wiaas_Order::get_order_commercial_lead_name($post->ID); + break; + + case 'wiaas_customer': + $column_content = Wiaas_Order::get_order_customer_full_name($post->ID); + + $customer_organization_info = Wiaas_Order::get_customer_organization_info($post->ID); + + if ( ! empty($customer_organization_info) ) { + + $column_content .= '
    '; + $column_content .= '' . $customer_organization_info['name'] . ''; + } + break; + } + + echo $column_content; + } + + /** + * Filter default hidden columns for orders list + * + * @param array $hidden + * @param object $screen + * + * @return array + */ + public static function filter_orders_list_default_hidden_columns($hidden, $screen) { + + if (isset($screen->id) && $screen->id === 'edit-shop_order') { + + $hidden = array( 'wc_actions' ); + } + + return $hidden; + } + + /** + * Add custom information to order preview data + * + * @param array $order + * + * @return array + */ + public static function add_custom_data_to_order_preview ($order) { + + $order['wiaas_commercial_lead_name'] = Wiaas_Order::get_order_commercial_lead_name( $order['data']['id'] ); + $order['needs_shipping'] = true; + + return $order; + } + + /** + * Display custom information in order preview + * + */ + public static function show_custom_data_before_order_preview () { + + echo '
    +
    +

    Commercial lead

    + {{data.wiaas_commercial_lead_name}} +
    +
    '; + } + + /** + * Display only bundles (not simple products) + * + * This will also not display options and addons + * + * @param array $order_items + * + * @return array + */ + public static function remove_simple_items_from_preview( $order_items){ + + $items = array(); + + foreach ($order_items as $order_item) { + + if ( Wiaas_Order_Item::is_standard_bundle($order_item) ) { + $items[] = $order_item; + } + } + + return $items; + } + + /** + * Columns for order preview order items table + * + * @return array + */ + public static function order_preview_order_item_columns( ) { + + return array( + 'product' => __('Product', 'wiaas'), + 'quantity' => __( 'Quantity', 'wiaas' ), + 'wiaas_order_item_price' => __( 'Price', 'wiaas' ) + ); + + } + + /** + * @param $empty + * @param WC_Order_Item $item + * @param int $item_id + * @param WC_Order $order + * + * @return string + */ + public static function render_order_item_preview_price_column($empty, $item, $item_id, $order) { + + if (Wiaas_Order_Item::is_standard_bundle($item)) { + + $total_price = wc_price( $item->get_total(), array( 'currency' => $order->get_currency() ) ); + + $monthly_price = wc_price( + Wiaas_Order_Item::get_monthly_recurring_total($item), + array( 'currency' => $order->get_currency() ) + ); + + return sprintf('On Delivery: %s
    Monthly: %s', + $total_price, + $monthly_price); + } + + return ''; + } + + /** + * Render order item payment info with order item metadata on order details page + * + * @param $item_id + * @param WC_Order_Item $item + * @param $product + */ + public static function render_order_details_order_item_custom_info($item_id, $item, $product) { + + if (Wiaas_Order_Item::is_standard_bundle($item)) { + + $order = $item->get_order(); + + $total_price = wc_price( $item->get_total(), array( 'currency' => $order->get_currency() ) ); + + $monthly_price = wc_price( + Wiaas_Order_Item::get_monthly_recurring_total($item), + array( 'currency' => $order->get_currency() ) + ); + + ?> +

    + On Delivery: +
    + Monthly: + key) { + case '_wiaas_payment_type': + return 'Payment type'; + + case '_wiaas_services_extra': + return 'Services and support price'; + + case '_wiaas_recurrent_extra': + return 'Recurrent price'; + + default: + return $display_key; + } + } + + /** + * @param string $display_value + * @param object $meta + * @param WC_Order_Item $item + * + * @return string + */ + public static function order_item_display_meta_value($display_value, $meta, $item) { + + switch ($meta->key) { + + case '_wiaas_services_extra': + $order = $item->get_order(); + + return wc_price( + Wiaas_Order_Item::get_services_total($item), + array( 'currency' => $order->get_currency()) + ); + + case '_wiaas_recurrent_extra': + $order = $item->get_order(); + + return wc_price( + Wiaas_Order_Item::get_recurrent_total($item), + array( 'currency' => $order->get_currency()) + ); + + default: + return $display_value; + } + } + +} + +Wiaas_Admin_Orders::init(); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-user-profile.php b/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-user-profile.php new file mode 100644 index 0000000..44d92a0 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-user-profile.php @@ -0,0 +1,31 @@ +add('phone_error', __( 'ERROR: Enter valid phone number.', 'crf' )); + }; + + } + + public static function modify_user_contact_methods($user_contact){ + $user_contact['phone'] = __( 'Phone number' ); + + return $user_contact; + } + + +} + +Wiaas_Admin_Profile::init(); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/admin/delivery-process/class-wiaas-admin-delivery-process-flow.php b/backend/app/plugins/wiaas/includes/admin/delivery-process/class-wiaas-admin-delivery-process-flow.php index 98f1dec..6c1a7b0 100644 --- a/backend/app/plugins/wiaas/includes/admin/delivery-process/class-wiaas-admin-delivery-process-flow.php +++ b/backend/app/plugins/wiaas/includes/admin/delivery-process/class-wiaas-admin-delivery-process-flow.php @@ -4,135 +4,62 @@ class Wiaas_Admin_Order_Process_Flow { public static function init() { + add_action( 'admin_menu', array(__CLASS__, 'add_delivery_process_page') ); + add_action( 'gravityflow_entry_detail', array( __CLASS__, 'display_process_steps_details' ), 10, 3 ); - - //add_action( 'gravityflow_title_entry_detail', array( __CLASS__, 'process_title' ), 10, 3 ); - - add_action('gravityflow_entry_detail', array(__CLASS__, 'add_delivery_dates_box'), 9, 3); - - add_action('gravityflow_entry_detail', array(__CLASS__, 'maybe_display_delivery_process_navigation'), 9, 3); - - add_action('gravityflow_workflow_detail_sidebar', array(__CLASS__, 'render_procurement_order_download_link'), 10, 3); - - add_filter('gravityflow_admin_action_feedback', array(__CLASS__, 'maybe_process_admin_step_change_action'), 10, 4); - - add_filter('gravityflow_admin_actions_workflow_detail', array(__CLASS__, 'filter_workflow_admin_actions'), 10, 5); } - /** - * Filter workflow admin actions - * - * @param $admin_actions - * @param $current_step - * @param $steps - * @param $form - * @param $entry - * - * @return array - */ - public static function filter_workflow_admin_actions($admin_actions, $current_step, $steps, $form, $entry) { - - $allowed_actions = array(); - - // allow basic admin actions for step action workflow - if (Wiaas_Delivery_Process_Action::is_action_form($form)) { - - $allowed_actions = array( 'cancel_workflow', 'restart_workflow', 'restart_step'); - } - - $filtered_admin_actions = array(); - - foreach ( $admin_actions as $admin_action ) { - - if (in_array($admin_action['value'], $allowed_actions)) { - $filtered_admin_actions[] = $admin_action; - } - } - - return $filtered_admin_actions; + public static function add_delivery_process_page() { + add_submenu_page( + 'edit.php?post_type=shop_order', + __( 'Order Delivery', 'wiaas' ), + null, + 'read', + 'wiaas-order-delivery', + array(__CLASS__, 'output_delivery_process') + ); } - public static function render_procurement_order_download_link($form, $entry, $current_step) { + public static function output_delivery_process() { + $order_id = absint( $_GET['id'] ); - if(! GFAPI::current_user_can_any( 'gravityflow_workflow_detail_admin_actions' ) || - empty( $current_step ) || - Wiaas_Delivery_Process_Action::is_action_form($form) ) { - return; - } + $has_access = Wiaas_Access_Management::can_current_user_read_order($order_id); - $order_id = $entry['wiaas_delivery_order_id']; + if (! $has_access) { - ?> + echo "

    You don't have permission to view this order.

    "; -
    -

    - -

    -
    - - - -
    -
    - get_id()); - $workflow_api = new Gravity_Flow_API($form['id']); - $steps = $workflow_api->get_steps(); + if ($delivery_process && + wp_verify_nonce($_POST['wiaas_delivery_process_navigation_nonce'], 'wiaas_delivery_process_navigation') && + GFAPI::current_user_can_any( 'manage_wiaas_order_delivery_process' )) { - /** - * Disable if: - * - actions for customer config validation is not done - * - action for customer acceptance is active or completed - */ - $is_disabled = false; - foreach ($steps as $step) { + self::_maybe_process_admin_step_change_action($delivery_process); - if (Wiaas_Delivery_Process_Action::process_step_has_customer_validate_questionnaires_action($step) && - $step->get_status() !== 'complete') { + // refresh order + $order = wc_get_order($order_id); + } - $is_disabled = true; - break; - } + require 'views/html-admin-delivery-process-page.php'; + } - if (Wiaas_Delivery_Process_Action::process_step_has_customer_acceptance_action($step) && - ($step->get_id() === $current_step->get_id() || $step->get_status() === 'complete')) { - - $is_disabled = true; - break; - } - } - - $order_id = $entry['wiaas_delivery_order_id']; - - $suppliers = Wiaas_Order::get_suppliers($order_id); - $final_estimated_date = Wiaas_Order::get_final_estimated_date($order_id); - $final_confirmed_date = Wiaas_Order::get_final_confirmed_date($order_id); - $earliest_installation_date = Wiaas_Order::get_earliest_installation_date($order_id); - - require 'views/html-order-suppliers-delivery-dates.php'; - } - - public static function maybe_process_admin_step_change_action($feedback, $admin_action, $form, $entry) { + private static function _maybe_process_admin_step_change_action($entry) { $admin_action = rgpost( 'wiaas_delivery_process_navigation_action' ); if ($admin_action === 'complete') { - $api = new Gravity_Flow_API( $form['id'] ); + $api = new Gravity_Flow_API( $entry['form_id'] ); $current_step = $api->get_current_step($entry); @@ -142,294 +69,15 @@ class Wiaas_Admin_Order_Process_Flow { } $api->process_workflow($entry['id']); - - $feedback = esc_html__( 'Workflow Complete', 'wiaas' ); - - return $feedback; } list( $base_admin_action, $action_id ) = rgexplode( '|', $admin_action, 2 ); if ( $base_admin_action == 'send_to_step' ) { $step_id = $action_id; - $api = new Gravity_Flow_API( $form['id'] ); + $api = new Gravity_Flow_API( $entry['form_id'] ); $api->send_to_step( $entry, $step_id ); - $entry = GFAPI::get_entry( $entry['id'] ); - $new_step = $api->get_current_step( $entry ); - $feedback = $new_step ? - sprintf( esc_html__( 'Sent to step: %s', 'wiaas' ), $new_step->get_name() ) : - esc_html__( 'Workflow Complete', 'wiaas' ); } - - return $feedback; - } - - public static function maybe_display_delivery_process_navigation($form, $entry, $current_step) { - - if(! GFAPI::current_user_can_any( 'gravityflow_workflow_detail_admin_actions' ) || - empty( $current_step ) || - Wiaas_Delivery_Process_Action::is_action_form($form) ) { - return; - } - - $steps = gravity_flow()->get_steps($form['id'], $entry); - - // get next step id - $next_step = gravity_flow()->get_next_step($current_step, $entry, $form); - $next_step_id = empty($next_step) ? null : $next_step->get_id(); - - // get previous step id - foreach ($steps as $step) { - - $next = gravity_flow()->get_next_step($step, $entry, $form); - if ($next && $next->get_id() === $current_step->get_id()) { - $previous_step = $step; - } - } - $previous_step_id = empty($previous_step) ? null : $previous_step->get_id(); - - // bail out if none exist - if ( empty($next_step_id) && empty($previous_step_id) ) { - - return; - } - - /** - * @reference Gravity_Flow::maybe_process_admin_action for used field names - * which are being checked there - * - */ - - ?> - -
    - - - - - - - - class="button button-primary wiaas_delivery_step_nav" - style="float:right;" value="PREV STEP"> -
    - id]; - } - } - - // display process steps - - $workflow_api = new Gravity_Flow_API($form['id']); - - $steps = $workflow_api->get_steps(); - - ?> - -
    -

    - - Order placed -

    -
    - -
    -

    - - Assign process -

    -
    - - $step) { - - if (! $step->is_active()) { - continue; - } - - $is_step_completed = $step->get_status() === 'complete' || $step->get_status() === 'approved'; - $is_current_step = $current_step && $step->get_id() === $current_step->get_id(); - - if ($is_current_step) { - $style = 'color: #FD8049;'; - } else if ($is_step_completed) { - $style = 'color: #34C388;'; - } else { - $style = 'opacity: 0.5; color: #CCC;'; - } - - ?> - -
    - -

    - - get_name(), 'wiaas') ?> -

    - - target_form_id ); - - if (empty($action_form)) { - - echo '
    '; - - continue; - } - - $page_size = 20; - $search_criteria = array( - 'status' => 'active', - 'field_filters' => array( - array( 'key' => 'wiaas_delivery_process_id', - 'value' => $entry['id'] - ), - ), - ); - $sorting = array( 'key' => 'date_created', 'direction' => 'DESC' ); - $paging = array( 'offset' => 0, 'page_size' => $page_size ); - - $entries = GFAPI::get_entries( $action_form['id'], $search_criteria, $sorting, $paging ); - - if (empty($entries)) { - - echo '
    '; - - continue; - } - - ?> - -
    - - - -

    '; - - - foreach ($entries as $action_entry) { - self::_display_step_action_entry($action_form, $action_entry); - } - - ?> - -
    - - - -
    - - - -
- get_current_step($action_entry); - - $entry_url = add_query_arg( array( - 'page' => 'gravityflow-inbox', - 'view' => 'entry', - 'id' => $action_entry['form_id'], - 'lid' => $action_entry['id'] - ), admin_url() ); - - - ?> - - - type === 'wiaas_order') { - continue; - } - - if ($field->type === 'workflow_discussion') { - - echo ''; - - continue; - } - - $value = $field->get_value_entry_detail($action_entry[$field->id]); - $label = $field->get_field_label(false, $action_entry[$field->id]); - - echo '' . - '' . - '' . - ''; - } - - ?> - - - - - - - - -
' . $field->format_discussion_value($action_entry[$field->id]) . '
' . $label . ' : ' . $value . '
- - - get_status($action_entry) : - $current_action_step->get_status_label($current_action_step->get_status()) . ': ' . $current_action_step->get_name();; - - echo '' . - ' ' . - ''; - - ?> - - -
- -
- id ); + + $title = strtolower($form_details['title']); + + $delivery_settings = rgar($form_details, 'wiaas_delivery_process'); + $country_code = ! empty($delivery_settings) ? $delivery_settings['delivery_country'] : ''; + $country_name = Wiaas_Countries::get_available_country_name_by_code($country_code); + $country_name = strtolower($country_name); + + if (strpos($title, $search_query) !== false || strpos($country_code, $search_query) !== false || + strpos($country_name, $search_query) !== false) { + $filtered_forms[] = $form; + } + } + + return $filtered_forms; + } + + return $forms; + } + + /** + * Remove unused actions and add workflow action for delivery forms list + * + * @param array $actions + * @param int $form_id + * + * @return mixed + */ + public static function filter_gform_form_actions($actions, $form_id) { + unset($actions['entries']); + unset($actions['preview']); + unset($actions['edit']); + + $actions['wiaas_workflow'] = array( + 'label' => __( 'Workflow', 'wiaas' ), + 'short_label' => esc_html__( 'Workflow', 'wiaas' ), + 'title' => __( 'Edit workflow', 'wiaas' ), + 'url' => '?page=gf_edit_forms&view=settings&id=' . $form_id . '&subview=gravityflow', + 'priority' => 1000, + ); + + return $actions; + } + + /** + * Render country column for delivery process forms list + * + * @param mixed $form + */ + public static function render_gform_form_list_wiaas_country_column($form) { + + $form_details = GFAPI::get_form($form->id); + $delivery_settings = rgar($form_details, 'wiaas_delivery_process'); + + $country_code = ! empty($delivery_settings) ? $delivery_settings['delivery_country'] : ''; + + $country_name = Wiaas_Countries::get_available_country_name_by_code($country_code); + + echo '' . esc_html_e($country_name) . ''; + } + + /** + * Render actions column for delivery process forms list + * @param mixed $form + */ + public static function render_gform_form_list_wiaas_actions_column($form) { + + $form_details = GFAPI::get_form($form->id); + $delivery_settings = rgar($form_details, 'wiaas_delivery_process'); + + $form_type = ! empty($delivery_settings) ? $delivery_settings['delivery_form_type'] : ''; + + ?> + Workflow + + | + Change Country + get_currency()) - ); + $list_of_delivery_processes = Wiaas_Delivery_Process::get_available_process_list_for_country($country_code); ?>
@@ -79,12 +77,7 @@ class Wiaas_Admin_Delivery_Process_Order { 'gravityflow-inbox', - 'view' => 'entry', - 'id' => $process_entry['form_id'], - 'lid' => $process_entry['id'] - ), admin_url() ); + $entry_url = admin_url('admin.php?page=wiaas-order-delivery&id=' . $order_id); ?> Delivery Process diff --git a/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-admin-delivery-process-page.php b/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-admin-delivery-process-page.php new file mode 100644 index 0000000..0a51b6e --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-admin-delivery-process-page.php @@ -0,0 +1,208 @@ +get_id()); + +if ( ! empty($delivery_process)) { + + $form_id = $delivery_process['form_id']; + $workflow_api = new Gravity_Flow_API($form_id); + + $current_step = $workflow_api->get_current_step($delivery_process); + + $steps = $workflow_api->get_steps(); +} + +?> + +
+
+ + +
+
+ +
+
+
+ + + +
+
+
+ +
+ +
+
+
+
+

+ Delivery Order + get_id() ) ) . '&action=edit' ) . '">#' . esc_attr( $order->get_order_number() ) . ''; + } else { + echo '#' . esc_attr($order->get_order_number()); + } + ?> +     + + + get_status() ) ) ?> + + +

+ + +

+ + + +

+ + + Delivery process has not been assigned.'; + } + + if (! empty($delivery_process)) { + + $is_disabled = ! Wiaas_Delivery_Process::can_delivery_dates_be_set($order->get_id(), $delivery_process, $steps); + + require 'html-order-suppliers-delivery-dates.php'; + } + + ?> +
+
+
+
+ + + +
+

+ + Order placed +

+
+ +
+

+ + Assign process +

+
+ + get_step($step->get_id(), $delivery_process); + + require 'html-delivery-process-step.php'; + } + + ?> + +
+
+

+ +

+ +
+ user_id; + $step = Gravity_Flow_Common::get_timeline_note_step( $note ); + $display_name = Gravity_Flow_Common::get_timeline_note_display_name( $note, $step ); + $step_type = $step ? $step->get_type() : $display_name; + + if ( $user_id ) { + $avatar = get_avatar( $user_id, 65 ); + } else { + $step_icon = $step ? $step->get_icon_url() : gravity_flow()->get_base_url() . '/images/gravityflow-icon-blue.svg'; + + if ( strpos( $step_icon, 'http' ) !== false ) { + $avatar = sprintf( '', $step_icon ); + } else { + $avatar = sprintf( '%s', $step_icon ); + } + } + + ?> +
+
+ +
+
+
+
+
+ +
+
+ date_created ), 'wiaas' ) ?> +
+
+
+ value ) ) ?> +
+
+
+
+ +
+ +
+
+ + + +
+ +
+
+
+
diff --git a/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-delivery-process-navigation.php b/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-delivery-process-navigation.php new file mode 100644 index 0000000..2614de1 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-delivery-process-navigation.php @@ -0,0 +1,50 @@ +get_status() === 'complete' || $current_step->get_status() === 'approved'; + +// get next step id +$next_step = gravity_flow()->get_next_step($current_step, $current_step->get_entry(), $current_step->get_form()); +$next_step_id = empty($next_step) ? null : $next_step->get_id(); + +// get previous step id +foreach ($steps as $step) { + + $next = gravity_flow()->get_next_step($step, $current_step->get_entry(), $current_step->get_form()); + if ($next && $next->get_id() === $current_step->get_id()) { + $previous_step = $step; + } +} +$previous_step_id = empty($previous_step) ? null : $previous_step->get_id(); + +// bail out if none exist +if ( empty($next_step_id) && empty($previous_step_id) && $is_step_completed) { + + return; +} + +?> + +
+ + + + + + + + class="button button-primary wiaas_delivery_step_nav" + style="float:right;" value="PREV STEP"> +
diff --git a/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-delivery-process-step-action.php b/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-delivery-process-step-action.php new file mode 100644 index 0000000..b52c8fd --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-delivery-process-step-action.php @@ -0,0 +1,77 @@ +get_current_step($action_entry); + +$entry_url = add_query_arg( array( + 'page' => 'gravityflow-inbox', + 'view' => 'entry', + 'id' => $action_entry['form_id'], + 'lid' => $action_entry['id'] +), admin_url() ); + +?> + + + + type === 'wiaas_order') { + continue; + } + + if ($field->type === 'workflow_discussion') { + + echo ''; + + continue; + } + + $value = $field->get_value_entry_detail($action_entry[$field->id]); + $label = $field->get_field_label(false, $action_entry[$field->id]); + + echo '' . + '' . + '' . + ''; + } + + ?> + + + + + + + + +
' . $field->format_discussion_value($action_entry[$field->id]) . '
' . $label . ' : ' . $value . '
+ + + get_status($action_entry) : + $current_action_step->get_status_label($current_action_step->get_status()) . ': ' . $current_action_step->get_name();; + + echo '' . + ' ' . + ''; + + ?> + + +
+ +
+ + diff --git a/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-delivery-process-step.php b/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-delivery-process-step.php new file mode 100644 index 0000000..cfecd09 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-delivery-process-step.php @@ -0,0 +1,75 @@ +get_status() === 'complete' || $step->get_status() === 'approved'; +$is_current_step = $current_step && $step->get_id() === $current_step->get_id(); + +if ($is_current_step) { + $style = 'color: #FD8049;'; +} else if ($is_step_completed) { + $style = 'color: #34C388;'; +} else { + $style = 'opacity: 0.5; color: #CCC;'; +} + +?> + +
+ +

+ + get_name(), 'wiaas') ?> +

+ + instructionsEnable) { + + $instructions = $step->instructionsValue; + $instructions = GFCommon::replace_variables( $instructions, $step->get_form(), $step->get_entry(), false, false, true ); + $instructions = do_shortcode( $instructions ); + + echo '
' . $instructions . '
'; + } + + $action_form = GFAPI::get_form( $step->target_form_id ); + + if (! empty($action_form)) { + + $page_size = 20; + $search_criteria = array( + 'status' => 'active', + 'field_filters' => array( + array( 'key' => 'wiaas_delivery_process_id', + 'value' => $delivery_process['id'] + ), + ), + ); + $sorting = array( 'key' => 'date_created', 'direction' => 'DESC' ); + $paging = array( 'offset' => 0, 'page_size' => $page_size ); + + $entries = GFAPI::get_entries( $action_form['id'], $search_criteria, $sorting, $paging ); + + $action_workflow = new Gravity_Flow_API($action_form['id']); + $current_assignee_key = $step->get_current_assignee_key(); + + foreach ($entries as $action_entry) { + + $action_entry_step = $action_workflow->get_current_step($action_entry); + + $show_entry = GFAPI::current_user_can_any( 'manage_wiaas_order_delivery_process' ) || + ($action_entry_step && + $action_entry_step->is_assignee($current_assignee_key)); + + if ($show_entry) { + require 'html-delivery-process-step-action.php'; + } + } + } + + ?> + +
diff --git a/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-order-notes.php b/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-order-notes.php new file mode 100644 index 0000000..d13922b --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-order-notes.php @@ -0,0 +1,53 @@ + $order->get_id(), 'type' => 'customer' ) ); + +?> + +
+ +
+ +
+ content ) ) ); ?> +
+

+ date_created->date_i18n( wc_date_format() ), $note->date_created->date_i18n( wc_time_format() ) ); ?> + added_by ) : + /* translators: %s: note author */ + printf( ' ' . __( 'by %s', 'woocommerce' ), $note->added_by ); + endif; + ?> +

+ +
+ +
+

+ + +

+

+ + +

+
+ +
diff --git a/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-order-suppliers-delivery-dates.php b/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-order-suppliers-delivery-dates.php index 93ae9e4..774023d 100644 --- a/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-order-suppliers-delivery-dates.php +++ b/backend/app/plugins/wiaas/includes/admin/delivery-process/views/html-order-suppliers-delivery-dates.php @@ -2,9 +2,16 @@ if ( ! defined( 'ABSPATH' ) ) { exit; } + +$suppliers = Wiaas_Order::get_suppliers($order_id); +$final_estimated_date = Wiaas_Order::get_final_estimated_date($order_id); +$final_confirmed_date = Wiaas_Order::get_final_confirmed_date($order_id); +$earliest_installation_date = Wiaas_Order::get_earliest_installation_date($order_id); + ?> -
+
+
@@ -54,35 +61,50 @@ if ( ! defined( 'ABSPATH' ) ) { placeholder="Tracking URL" value="" /> - - class="button" - onClick="saveTrackingInfo(event, )" - value="SAVE"> - - class="button" - onClick="deleteTrackingInfo(event, )" value="REMOVE" - > + + + + class="button" + onClick="saveTrackingInfo(event, )" + value="SAVE"> + + class="button" + onClick="deleteTrackingInfo(event, )" value="REMOVE" + > + + + + + - - - 0 ) { + $order = wc_get_order( $post_id ); + $comment_id = $order->add_order_note( $note, true, true ); + $note = wc_get_order_note( $comment_id ); + ?> +
+ content ) ) ); ?> +
+

+ date_created->date_i18n( wc_date_format() ), $note->date_created->date_i18n( wc_time_format() ) ); ?> + added_by ); + ?> +

+ get_id(), 'wiaas') ?>">
- + get_meta('_wiaas_commercial_lead_id', true)); if ($commercial_lead_id) { Wiaas_User_Organization::assign_post_to_organization($order_id, $commercial_lead_id); @@ -79,24 +99,46 @@ class Wiaas_Access_Management { } /** - * Assignees order to supplier organizations extracted from ordered items when order payment is complete. + * Assignees order to supplier organizations extracted from ordered items except installation + * + * Order will be assigned to corresponding installation company during delivery process * * @param int $order_id */ - public static function assign_order_to_suppliers($order_id){ + public static function assign_order_to_supplier_organizations($order_id) { - $order = wc_get_order($order_id); - $product_from_order = $order->get_items('line_item'); + $order = wc_get_order($order_id); - foreach ($product_from_order as $product_item) { + $order_items = $order->get_items('line_item'); - $supplier_organisation_id = Wiaas_Product_Supplier - ::get_supplier_organisation_id_from_product($product_item->get_product_id()); + foreach ($order_items as $key => $order_item) { - Wiaas_User_Organization::assign_post_to_organization($order_id, $supplier_organisation_id); + $supplier_organisation_id = $order_item->get_meta('_wiaas_supplier_organization_id'); + + if (! empty($supplier_organisation_id) && $order_item->get_meta('_wiaas_category') !== 'installation') { + + Wiaas_User_Organization::assign_post_to_organization($order_id, $supplier_organisation_id); + } } } + + /** + * Assign order to installation organization that handles installation of corresponding ordered bundle item + * + * @param WC_Order $order + * @param WC_Order_Item $bundle_item + * @param WC_Order_Item $installation_item + */ + public static function assign_order_to_installation_organization($order, $bundle_item, $installation_item) { + + $supplier_organisation_id = $installation_item->get_meta('_wiaas_supplier_organization_id'); + + if (! empty($supplier_organisation_id) ) { + + Wiaas_User_Organization::assign_post_to_organization($order->get_id(), $supplier_organisation_id); + } + } } Wiaas_Access_Management::init(); diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-admin.php b/backend/app/plugins/wiaas/includes/class-wiaas-admin.php index 6d5021e..ebe04a7 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-admin.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-admin.php @@ -28,13 +28,27 @@ class Wiaas_Admin { require_once dirname(__FILE__) . '/admin/class-wiaas-admin-supplier.php'; + require_once dirname(__FILE__) . '/admin/class-wiaas-admin-user-profile.php'; + + require_once dirname(__FILE__) . '/admin/class-wiaas-admin-countries.php'; + + require_once dirname(__FILE__) . '/admin/class-wiaas-admin-orders.php'; + + require_once dirname(__FILE__) . '/admin/class-wiaas-admin-dashboard.php'; + add_action( 'admin_enqueue_scripts', array(__CLASS__, 'enqueue_scripts'), 100 ); } public static function enqueue_scripts() { + $plugin_url = untrailingslashit( plugins_url( '/', WIAAS_FILE ) ); + wp_enqueue_script( 'wiaas_data_tables', $plugin_url . '/assets/js/datatables.min.js' ); + wp_enqueue_style( 'wiaas_data_tables', $plugin_url . '/assets/css/datatables.min.css' ); + + wp_enqueue_style( 'wiaas_admin', $plugin_url . '/assets/css/wiaas-admin.css' ); + wp_enqueue_style( 'wiaas_admin_menu', $plugin_url . '/assets/css/menu.css' ); wp_enqueue_style( 'wiaas_admin_packages', $plugin_url . '/assets/css/wiaas-admin-package.css' ); diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-cart.php b/backend/app/plugins/wiaas/includes/class-wiaas-cart.php index 4549663..8f64b9e 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-cart.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-cart.php @@ -21,8 +21,6 @@ class Wiaas_Cart { public static function init() { add_action( 'woocommerce_checkout_create_order_line_item', array( __CLASS__, 'add_order_item_meta' ), 10, 3 ); - add_filter( 'woocommerce_hidden_order_itemmeta', array( __CLASS__, 'hidden_order_item_meta' ) ); - add_action( 'woocommerce_before_calculate_totals', array( __CLASS__, 'on_calculate_totals' ), 99, 1); add_action( 'woocommerce_cart_loaded_from_session', array( __CLASS__, 'on_calculate_totals' ), 99, 1); @@ -444,40 +442,6 @@ class Wiaas_Cart { return $order_item; } - /** - * Mark extended properties for order as hidden - * @param $hidden - * - * @return array - */ - public static function hidden_order_item_meta( $hidden ) { - - return array_merge( $hidden, array( - '_wiaas_payment_type', - '_wiaas_services_extra', - '_wiaas_service_contract_period', - '_wiaas_max_contract_period', - '_wiaas_period_unit', - '_wiaas_recurrent_extra', - '_wiaas_pay_period', - '_wiaas_addon_items', - '_wiaas_addon_for', - '_wiaas_option_items', - '_wiaas_option_for', - '_wiaas_option_group_name', - '_wiaas_standard_package', - '_wiaas_documents', - '_wiaas_category', - '_wiaas_manufacturer_product_no', - '_wiaas_supplier_product_no', - '_wiaas_supplier_organization_id', - '_wiaas_product_price', - '_wiaas_earliest_installation_additional_days', - '_wiaas_installation', - '_wiaas_installation_date' - ) ); - } - /** * Sets additional order data form cart after order is successfully created * @@ -492,6 +456,8 @@ class Wiaas_Cart { $country = get_user_meta(get_current_user_id(), '_wiaas_cart_items_country', true); $currency = empty($country) ? get_woocommerce_currency() : $country['currency']; + $order->add_meta_data('_wiaas_country_code', $country['code']); + $order->set_currency($currency); // get order commercial lead diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-countries.php b/backend/app/plugins/wiaas/includes/class-wiaas-countries.php index a88c14f..7d14ff3 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-countries.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-countries.php @@ -12,28 +12,19 @@ if ( ! defined( 'ABSPATH' ) ) { class Wiaas_Countries { /** - * Available countries for wiaas + * Default available countries for wiaas * @var array */ - private static $available_countries = array( - 'Sweden' => array( - 'id' => 1, - 'name' => 'Sweden', - 'code' => 'se', + private static $default_countries = array( + 'se' => array( 'vat' => 9 , 'currency' => 'SEK' ), - 'Denmark' => array( - 'id' => 2, - 'name' => 'Denmark', - 'code' => 'dk', + 'dk' => array( 'vat' => 9 , 'currency' => 'DKK' ), - 'Finland' => array( - 'id' => 3, - 'name' => 'Finland', - 'code' => 'fi', + 'fi' => array( 'vat' => 9 , 'currency' => 'EUR' ), @@ -44,31 +35,97 @@ class Wiaas_Countries { add_action('woocommerce_after_register_taxonomy', array(__CLASS__, 'register_product_countries_taxonomy')); } - public static function get_list_of_countries(){ - $result = []; - foreach(self::$available_countries as $country){ - array_push($result, array( - 'country_id' => $country['id'], - 'country_name' => $country['name'] - )); + /** + * Retrieve all possible country choices + * + * @return array + */ + public static function get_country_choices() { + $countries = new WC_Countries(); + $choices = array(); + + foreach ($countries->get_countries() as $code => $name) { + $choices[strtolower($code)] = $name; } - return $result; + + return $choices; } - public static function get_country_name_by_id($id){ - foreach(self::$available_countries as $country){ - if ($country['id'] == $id) return $country['name']; - } - return ''; + /** + * Retrieve all possible currency choices + * + * @return array + */ + public static function get_currency_choices() { + return get_woocommerce_currencies(); } - public static function get_country_code_by_currency($currency) { + /** + * Retrieve list of available countries setup by administrator + * + * @return array + */ + public static function get_available_countries() { + $available_countries = []; - foreach (self::$available_countries as $country) { + $available_country_terms = get_terms(array( + 'taxonomy' => 'product_country', + 'hide_empty' => false, + )); - if ($country['currency'] === $currency) { + foreach($available_country_terms as $country_term) { + $code = get_term_meta($country_term->term_id, '_wiaas_country_code', true); + $currency = get_term_meta($country_term->term_id, '_wiaas_country_currency', true); + $vat = get_term_meta($country_term->term_id, '_wiaas_country_vat', true); - return $country['code']; + $available_countries[] = array( + 'id' => $country_term->term_id, + 'name' => $country_term->name, + 'code' => $code, + 'currency' => $currency, + 'vat' => $vat + ); + } + + return $available_countries; + } + + /** + * Retrieve country name by code for available country + * + * @param string $code + * + * @return string|null + */ + public static function get_available_country_name_by_code($code) { + $available_countries = self::get_available_countries(); + + foreach ($available_countries as $available_country) { + + if ($available_country['code'] === $code) { + + return $available_country['name']; + } + } + + return null; + } + + /** + * Retrieve country code by currency for available country + * + * @param string $currency + * + * @return string|null + */ + public static function get_available_country_code_by_currency($currency) { + $available_countries = self::get_available_countries(); + + foreach ($available_countries as $available_country) { + + if ($available_country['currency'] === $currency) { + + return $available_country['code']; } } @@ -106,8 +163,27 @@ class Wiaas_Countries { register_taxonomy( 'product_country', array( 'product' ), $args ); - foreach (self::$available_countries as $available_country) { - wp_insert_term($available_country['name'], 'product_country'); + $choices = self::get_country_choices(); + + foreach (self::$default_countries as $code => $info) { + + $name = $choices[$code]; + + if (has_term($name)) { + // bail out + return; + } + + $name = $choices[$code]; + $result = wp_insert_term($name, 'product_country'); + + if (is_wp_error($result)) { + continue; + } + + update_term_meta($result['term_id'], '_wiaas_country_code', $code); + update_term_meta($result['term_id'], '_wiaas_country_currency', $info['currency']); + update_term_meta($result['term_id'], '_wiaas_country_vat', $info['vat']); } } @@ -128,10 +204,25 @@ class Wiaas_Countries { * @return array|null */ public static function get_product_country($product) { - $product_country = get_the_terms($product->get_id(), 'product_country'); - return is_array($product_country) && isset($product_country[0]) ? - self::$available_countries[$product_country[0]->name] : - null; + $country_terms = get_the_terms($product->get_id(), 'product_country'); + + if (is_wp_error($country_terms) || empty($country_terms) || empty($country_terms[0])) { + return null; + } + + $country_term = $country_terms[0]; + + $code = get_term_meta($country_term->term_id, '_wiaas_country_code', true); + $currency = get_term_meta($country_term->term_id, '_wiaas_country_currency', true); + $vat = get_term_meta($country_term->term_id, '_wiaas_country_vat', true); + + return array( + 'id' => $country_term->term_id, + 'name' => $country_term->name, + 'code' => $code, + 'currency' => $currency, + 'vat' => $vat + ); } /** diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-db-update.php b/backend/app/plugins/wiaas/includes/class-wiaas-db-update.php index 73c78cd..9c753d1 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-db-update.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-db-update.php @@ -18,15 +18,19 @@ class Wiaas_DB_Update { '20181018044450' => 'wiaas_db_setup_create_customer_commercial_lead_table', '20181018054450' => 'wiaas_db_update_update_commercial_lead_capabilities', '20181018064450' => 'wiaas_db_update_add_organization_info_ui_fields', - '20191019014550' => 'wiaas_db_update_add_general_ui_fields', - '20191019014650' => 'wiaas_db_update_add_product_properties_ui_fields', - '20191020014650' => 'wiaas_create_organization_roles_capabilities', - '20191030162450' => 'wiaas_db_update_update_supplier_order_capabilities', - '20191102112451' => 'wiaas_disable_processing_order_email_delivery', - '20191131172850' => 'wiaas_db_update_update_delivery_forms', - '20191131182856' => 'wiaas_db_update_enable_workflow_inbox_for_roles', - '20191201133550' => 'wiaas_db_update_add_bundle_properties_ui_field', - '20191202133553' => 'wiaas_db_update_add_installation_date_delivery_action_form' + '20181019014550' => 'wiaas_db_update_add_general_ui_fields', + '20181019014650' => 'wiaas_db_update_add_product_properties_ui_fields', + '20181020014650' => 'wiaas_create_organization_roles_capabilities', + '20181021162450' => 'wiaas_db_update_update_supplier_order_capabilities', + '20181102112451' => 'wiaas_disable_processing_order_email_delivery', + '20181103172850' => 'wiaas_db_update_update_delivery_forms', + '20181104182856' => 'wiaas_db_update_enable_workflow_inbox_for_roles', + '20181105133550' => 'wiaas_db_update_add_bundle_properties_ui_field', + '20181106133553' => 'wiaas_db_update_add_installation_date_delivery_action_form', + '20181125133553' => 'wiaas_db_update_add_country_settings_ui_fields', + '20181125143553' => 'wiaas_db_migration_fix_user_profile_addresses', // remove after migration + '20181125153553' => 'wiaas_db_migration_fix_countries', // remove after migration, + '20181203115826' => 'wiaas_db_update_add_administrator_delivery_process_capabilities' ); public static function execute() { diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-delivery-process.php b/backend/app/plugins/wiaas/includes/class-wiaas-delivery-process.php index b459820..947fb54 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-delivery-process.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-delivery-process.php @@ -88,6 +88,123 @@ class Wiaas_Delivery_Process { return false; } + /** + * Delivery dates cannot be set if: + * - user cannot edit delivery dates + * - actions for customer config validation is not done + * - action for customer acceptance is active or completed + * + * @param int $order_id + * @param mixed $delivery_process_entry + * @param array $steps + * + * @return bool + */ + public static function can_delivery_dates_be_set($order_id, $delivery_process_entry = null, $steps = null) { + + if ( empty($delivery_process_entry) ) { + + $delivery_process_entry = self::get_order_delivery_process_entry($order_id); + } + + if (empty($delivery_process_entry) || ! GFAPI::current_user_can_any( 'manage_wiaas_order_delivery_process' )) { + + return false; + } + + $workflow_api = new Gravity_Flow_API($delivery_process_entry['form_id']); + $current_step = $workflow_api->get_current_step($delivery_process_entry); + + if ( empty($steps) ) { + $steps = $workflow_api->get_steps(); + } + + foreach ($steps as $step) { + $step = $workflow_api->get_step($step->get_id(), $delivery_process_entry); + + // customer validation not done + if ($step && Wiaas_Delivery_Process_Action::process_step_has_customer_validate_questionnaires_action($step) && + $step->get_status() !== 'complete') { + + return false; + } + + // customer acceptance is active or completed + if ($step && Wiaas_Delivery_Process_Action::process_step_has_customer_acceptance_action($step) && + ($current_step && $step->get_id() === $current_step->get_id() || $step->get_status() === 'complete')) { + + return false; + } + } + + return true; + } + + public static function get_next_actions_for_current_user() { + + $current_user = wp_get_current_user(); + + $field_filters = array(); + $field_filters[] = array( + 'key' => 'workflow_user_id_' . $current_user->ID, + 'value' => 'pending', + ); + + $user_roles = gravity_flow()->get_user_roles(); + foreach ( $user_roles as $user_role ) { + $field_filters[] = array( + 'key' => 'workflow_role_' . $user_role, + 'value' => 'pending', + ); + } + + $field_filters['mode'] = 'any'; + + $search_criteria = array(); + $search_criteria['field_filters'] = $field_filters; + $search_criteria['status'] = 'active'; + + $form_ids = gravity_flow()->get_workflow_form_ids(); + + $entries = GFAPI::get_entries( + $form_ids, + $search_criteria, + null, + null); + + $actions = array(); + + foreach ($entries as $entry) { + + $order_id = $entry['wiaas_delivery_order_id']; + $order = wc_get_order($order_id); + + if (! $order) { + continue; + } + + $step = gravity_flow()->get_step( $entry['workflow_step'] ); + + if (!$step) { + continue; + } + + $action = array( + 'order_id' => $order_id, + 'order_number' => $order->get_order_number(), + 'action_title' => $step->get_name() + ); + + if (is_admin()) { + $action['url'] = '?page=gravityflow-inbox&view=entry&id=' . $entry['form_id'] . '&lid=' . $entry['id']; + } + + $actions[] = $action; + } + + return $actions; + } + /** * Maybe complete parent order for completed delivery process * @param $entry_id diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-order.php b/backend/app/plugins/wiaas/includes/class-wiaas-order.php index ec34773..bcd5859 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-order.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-order.php @@ -19,6 +19,7 @@ class Wiaas_Order { require_once dirname( __FILE__ ) . '/order/class-wiaas-order-project.php'; require_once dirname( __FILE__ ) . '/order/wiaas-order-functions.php'; + require_once dirname( __FILE__ ) . '/order/class-wiaas-order-item.php'; add_filter('woocommerce_register_post_type_shop_order', array(__CLASS__, 'manage_order_settings')); @@ -370,6 +371,25 @@ class Wiaas_Order { return $response; } + public static function get_order_customer_full_name($order_id){ + $order = wc_get_order($order_id); + + $customer_user_id = $order->get_customer_id(); + + $customer = get_userdata($customer_user_id); + + return $customer->last_name . ' ' . $customer->first_name; + } + + public static function get_order_commercial_lead_name($order_id){ + $order = wc_get_order($order_id); + + $commercial_lead_org_id = $order->get_meta('_wiaas_commercial_lead_id', true); + $commercial_lead_organization_info = wiaas_get_organization_info($commercial_lead_org_id); + + return $commercial_lead_organization_info['name']; + } + public static function set_order_vat($order_id, $vat_code) { add_post_meta($order_id, '_wiaas_vat_code', $vat_code); } @@ -400,7 +420,69 @@ class Wiaas_Order { public static function get_order_tender($order_id) { return get_post_meta($order_id, '_wiaas_tender', true); - } + } + + public static function get_order_country_code($order_id) { + + $order = wc_get_order($order_id); + + $code = $order->get_meta('_wiaas_country_code'); + + if (empty($code)) { + $code = Wiaas_Countries::get_available_country_code_by_currency($order->get_currency()); + $order->add_meta_data('_wiaas_country_code', $code); + $order->save_meta_data(); + } + + return $code; + } + + /** + * Retrieve customer organization id for order + * + * @param int $order_id + * + * @return int|null + */ + public static function get_order_customer_organization_id($order_id) { + $order = wc_get_order($order_id); + + $customer_organization_id = $order->get_meta('_wiaas_customer_id', true); + + if (empty($customer_organization_id)) { + + $customer_organization_id = wiaas_get_user_organization_id($order->get_customer_id()); + } + + return $customer_organization_id; + } + + /** + * Retrieve customer organization info from order + * + * @param int $order_id + * + * @return array|null + */ + public static function get_customer_organization_info($order_id) { + $order = wc_get_order($order_id); + + $customer_organization_info = $order->get_meta('_wiaas_customer_info', true); + + $customer_organization_id = self::get_order_customer_organization_id($order_id); + + if ( empty($customer_organization_info) && ! empty( $customer_organization_id) ) { + + $customer_organization_info = wiaas_get_organization_info($customer_organization_id); + } + + if ( ! empty($customer_organization_info) ) { + + $customer_organization_info['id'] = $customer_organization_id; + } + + return ! empty($customer_organization_info) ? $customer_organization_info : null; + } /** * PRIVATE diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-pricing.php b/backend/app/plugins/wiaas/includes/class-wiaas-pricing.php index 2555030..d50e3a0 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-pricing.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-pricing.php @@ -48,7 +48,7 @@ class Wiaas_Pricing { $bundled_items = $package->get_bundled_items(); foreach ($bundled_items as $bundled_item) { - $product = $bundled_item->product; + $product = wc_get_product($bundled_item->get_product_id()); $product_cat = Wiaas_Product_Category::get_category($product); if (!isset($total_cost_per_category[$product_cat])) { diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-product.php b/backend/app/plugins/wiaas/includes/class-wiaas-product.php index 73f5a82..3ce3d0d 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-product.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-product.php @@ -5,6 +5,8 @@ class Wiaas_Product { public static function init() { require_once dirname( __FILE__ ) . '/product/class-wiaas-product-category.php'; require_once dirname( __FILE__ ) . '/product/class-wiaas-product-supplier.php'; + require_once dirname( __FILE__ ) . '/product/class-wiaas-product-quick-edit.php'; + add_filter('woocommerce_register_post_type_product', array(__CLASS__, 'manage_product_settings')); diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-validation.php b/backend/app/plugins/wiaas/includes/class-wiaas-validation.php new file mode 100644 index 0000000..e9771c2 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/class-wiaas-validation.php @@ -0,0 +1,13 @@ +ID); + + if (! empty($billing_addresses)) { + + foreach ($billing_addresses as $index => $billing_address) { + + switch ($billing_address['id_country_selected']) { + + case 1: + $billing_address['country_code'] = 'se'; + break; + case 2: + $billing_address['country_code'] = 'dk'; + break; + case 3: + $billing_address['country_code'] = 'fi'; + break; + } + unset($billing_address['id_country_selected']); + $billing_addresses[$index] = $billing_address; + } + + update_user_meta( $user->ID, 'billing_addresses', $billing_addresses); + } + + $profile_addresses = Wiaas_Customer::get_customer_profile_addresses($user->ID); + + if (! empty($profile_addresses)) { + + foreach ($profile_addresses as $index => $profile_address) { + + switch ($profile_address['id_country_selected']) { + + case 1: + $profile_address['country_code'] = 'se'; + break; + case 2: + $profile_address['country_code'] = 'dk'; + break; + case 3: + $profile_address['country_code'] = 'fi'; + break; + } + unset($profile_address['id_country_selected']); + $profile_addresses[$index] = $profile_address; + } + + update_user_meta( $user->ID, 'profile_addresses', $profile_addresses); + } + + } +} + +// TODO: Remove after migration has been completed +function wiaas_db_migration_fix_countries() { + + $available_country_terms = get_terms(array( + 'taxonomy' => 'product_country', + 'hide_empty' => false, + )); + + foreach($available_country_terms as $country_term) { + + $code = ''; $currency = ''; $vat = ''; + + switch ($country_term->name) { + + case 'Sweden': + $code = 'se'; + $currency = 'SEK'; + $vat = 9; + break; + case 'Denmark': + $code = 'dk'; + $currency = 'DKK'; + $vat = 9; + break; + case 'Finland': + $code = 'fi'; + $currency = 'EUR'; + $vat = 9; + break; + } + + update_term_meta($country_term->term_id, '_wiaas_country_code', $code); + update_term_meta($country_term->term_id, '_wiaas_country_currency', $currency); + update_term_meta($country_term->term_id, '_wiaas_country_vat', $vat); + } + } \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-roles.php b/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-roles.php index b39cb5e..bea6ecf 100644 --- a/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-roles.php +++ b/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-roles.php @@ -323,4 +323,9 @@ function wiaas_db_update_enable_workflow_inbox_for_roles() { // add workflow inbox for commercial lead wp_roles()->add_cap( 'commercial_lead', 'gravityflow_inbox' ); +} + +function wiaas_db_update_add_administrator_delivery_process_capabilities() { + + wp_roles()->add_cap('administrator', 'manage_wiaas_order_delivery_process'); } \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-ui-fields.php b/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-ui-fields.php index cdc5177..f958784 100644 --- a/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-ui-fields.php +++ b/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-ui-fields.php @@ -45,6 +45,15 @@ function wiaas_db_update_add_product_properties_ui_fields() { _wiaas_import_field_group($ui_json); } +function wiaas_db_update_add_country_settings_ui_fields() { + + $ui_json = file_get_contents( dirname( __FILE__ ) . '/data/wiaas-ui-field-country-settings.json' ); + + $ui_json = json_decode( $ui_json, true ); + + _wiaas_import_field_group($ui_json); +} + // private helper function diff --git a/backend/app/plugins/wiaas/includes/delivery-process/class-wiaas-delivery-process-addon.php b/backend/app/plugins/wiaas/includes/delivery-process/class-wiaas-delivery-process-addon.php index ecf4024..690385e 100644 --- a/backend/app/plugins/wiaas/includes/delivery-process/class-wiaas-delivery-process-addon.php +++ b/backend/app/plugins/wiaas/includes/delivery-process/class-wiaas-delivery-process-addon.php @@ -11,9 +11,9 @@ class Wiaas_Delivery_Process_Addon extends Gravity_Flow_Extension { protected $_slug = 'wiaas_delivery_process'; - protected $_title = 'Delivery Process'; + protected $_title = 'Delivery Settings'; - protected $_short_title = 'Delivery Process'; + protected $_short_title = 'Delivery Settings'; public static function get_instance() { @@ -125,7 +125,7 @@ class Wiaas_Delivery_Process_Addon extends Gravity_Flow_Extension { $tabs[] = array( 'name' => $this->_slug, - 'label' => esc_html__( 'Delivery Process', 'wiaas' ), + 'label' => esc_html__( 'Delivery Settings', 'wiaas' ), 'query' => array( 'fid' => null ) ); @@ -218,14 +218,16 @@ class Wiaas_Delivery_Process_Addon extends Gravity_Flow_Extension { return; } + $countries = Wiaas_Countries::get_available_countries(); + + $countries_choices = array(); + foreach ($countries as $country) { + $countries_choices[] = array( 'value' => $country['code'] , 'label' => $country['name'] ); + } $this->settings_select(array( 'name' => 'delivery_country', - 'choices' => array( - array( 'value' => 'se', 'label' => 'Sweden' ), - array( 'value' => 'dk', 'label' => 'Denmark' ), - array( 'value' => 'fi', 'label' => 'Finland' ) - ), + 'choices' => $countries_choices, 'after_select' => '

Choose country for which this process is defined.

' )); } diff --git a/backend/app/plugins/wiaas/includes/delivery-process/class-wiaas-order-fields.php b/backend/app/plugins/wiaas/includes/delivery-process/class-wiaas-order-fields.php index fea6b52..710e99e 100644 --- a/backend/app/plugins/wiaas/includes/delivery-process/class-wiaas-order-fields.php +++ b/backend/app/plugins/wiaas/includes/delivery-process/class-wiaas-order-fields.php @@ -228,6 +228,12 @@ class Wiaas_Order_Fields { $bundle_item->update_meta_data('_wiaas_installation', $selected_installation->get_id()); $bundle_item->save_meta_data(); + + /** + * Apply actions related to order item installation + * (ex. make order visible to corresponding installation company) + */ + do_action('wiaas_order_item_installation_assigned', $order, $bundle_item, $selected_installation); } } } @@ -448,6 +454,12 @@ class Wiaas_Order_Fields { $entry[(string) $field->id] = 'wiaas_installation_' . $order->get_id() . '|' . $installation_item->get_id(); + /** + * Apply actions related to order item installation + * (ex. make order visible to corresponding installation company) + */ + do_action('wiaas_order_item_installation_assigned', $order, $bundle_item, $installation_item); + } else if (count($installation_items) > 1) { // force admin to select installation diff --git a/backend/app/plugins/wiaas/includes/order/class-wiaas-order-item.php b/backend/app/plugins/wiaas/includes/order/class-wiaas-order-item.php new file mode 100644 index 0000000..57da78f --- /dev/null +++ b/backend/app/plugins/wiaas/includes/order/class-wiaas-order-item.php @@ -0,0 +1,90 @@ +get_meta('_wiaas_standard_package'); + return ! empty($is_standard); + } + + /** + * @param WC_Order_Item $order_item + * + * @return float + */ + public static function get_services_total($order_item) { + $quantity = $order_item->get_quantity(); + + return $quantity * floatval($order_item->get_meta('_wiaas_services_extra')); + } + + /** + * @param WC_Order_Item $order_item + * + * @return float + */ + public static function get_recurrent_total($order_item) { + $quantity = $order_item->get_quantity(); + + return $quantity * floatval($order_item->get_meta('_wiaas_recurrent_extra')); + } + + /** + * @param WC_Order_Item $order_item + * + * @return float + */ + public static function get_monthly_recurring_total($order_item) { + + return self::get_services_total($order_item) + self::get_recurrent_total($order_item); + } + +} + +Wiaas_Order_Item::init(); diff --git a/backend/app/plugins/wiaas/includes/product/class-wiaas-product-quick-edit.php b/backend/app/plugins/wiaas/includes/product/class-wiaas-product-quick-edit.php new file mode 100644 index 0000000..797c195 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/product/class-wiaas-product-quick-edit.php @@ -0,0 +1,73 @@ + +
+

+ + +
+ + + id){ $updated = array( 'id' => $new_address->id, - 'country_name' => Wiaas_Countries::get_country_name_by_id($new_address->id_country_selected), + 'country_name' => Wiaas_Countries::get_available_country_name_by_code($new_address->country_code), 'delivery_mail' => $new_address->delivery_mail, - 'id_country_selected' => $new_address->id_country_selected, + 'country_code' => $new_address->country_code, 'city' => $new_address->city, 'detailed_address' => $new_address->detailed_address, 'zip_code' => $new_address->zip_code, @@ -152,9 +152,9 @@ class Wiaas_Customer { }else{ $new_billing_address = array( 'id' => time(), - 'country_name' => Wiaas_Countries::get_country_name_by_id($new_address->id_country_selected), + 'country_name' => Wiaas_Countries::get_available_country_name_by_code($new_address->country_code), 'delivery_mail' => $new_address->delivery_mail, - 'id_country_selected' => $new_address->id_country_selected, + 'country_code' => $new_address->country_code, 'city' => $new_address->city, 'detailed_address' => $new_address->detailed_address, 'zip_code' => $new_address->zip_code, @@ -178,9 +178,9 @@ class Wiaas_Customer { if ($new_address->id){ $updated = array( 'id' => $new_address->id, - 'country_name' => Wiaas_Countries::get_country_name_by_id($new_address->id_country_selected), + 'country_name' => Wiaas_Countries::get_available_country_name_by_code($new_address->country_code), 'delivery_mail' => $new_address->delivery_mail, - 'id_country_selected' => $new_address->id_country_selected, + 'country_code' => $new_address->country_code, 'city' => $new_address->city, 'detailed_address' => $new_address->detailed_address, 'zip_code' => $new_address->zip_code, @@ -197,9 +197,9 @@ class Wiaas_Customer { }else{ $new_delivery_address = array( 'id' => time(), - 'country_name' => Wiaas_Countries::get_country_name_by_id($new_address->id_country_selected), + 'country_name' => Wiaas_Countries::get_available_country_name_by_code($new_address->country_code), 'delivery_mail' => $new_address->delivery_mail, - 'id_country_selected' => $new_address->id_country_selected, + 'country_code' => $new_address->country_code, 'city' => $new_address->city, 'detailed_address' => $new_address->detailed_address, 'zip_code' => $new_address->zip_code, diff --git a/backend/app/plugins/wiaas/tests/bootstrap.php b/backend/app/plugins/wiaas/tests/bootstrap.php index c6cc935..a33225e 100644 --- a/backend/app/plugins/wiaas/tests/bootstrap.php +++ b/backend/app/plugins/wiaas/tests/bootstrap.php @@ -25,6 +25,12 @@ tests_add_filter( 'pre_option_active_plugins', 'load_active_plugins_list'); # Start up the WP testing environment. require $_tests_dir . '/includes/bootstrap.php'; +// Require Wiaas test case factories +require_once '/tmp/wiaas-backend-test/app/plugins/wiaas/tests/factories/class-wiaas-unit-test-organization-factory.php'; +require_once '/tmp/wiaas-backend-test/app/plugins/wiaas/tests/factories/class-wiaas-unit-test-product-factory.php'; +require_once '/tmp/wiaas-backend-test/app/plugins/wiaas/tests/factories/class-wiaas-unit-test-order-factory.php'; +require_once '/tmp/wiaas-backend-test/app/plugins/wiaas/tests/class-wiaas-unit-test-factory.php'; + # Require Wiaas Unit Test case class require_once '/tmp/wiaas-backend-test/app/plugins/wiaas/tests/wiaas-unit-test-case.php'; require_once '/tmp/wiaas-backend-test/app/plugins/wiaas/tests/wiaas-api-unit-test-case.php'; diff --git a/backend/app/plugins/wiaas/tests/class-wiaas-unit-test-factory.php b/backend/app/plugins/wiaas/tests/class-wiaas-unit-test-factory.php new file mode 100644 index 0000000..11a2ee6 --- /dev/null +++ b/backend/app/plugins/wiaas/tests/class-wiaas-unit-test-factory.php @@ -0,0 +1,28 @@ +product = new Wiaas_Unit_Test_Product_Factory(); + + $this->organization = new Wiaas_Unit_Test_Organization_Factory(); + + $this->order = new Wiaas_Unit_Test_Order_Factory(); + } +} \ No newline at end of file diff --git a/backend/app/plugins/wiaas/tests/factories/class-wiaas-unit-test-order-factory.php b/backend/app/plugins/wiaas/tests/factories/class-wiaas-unit-test-order-factory.php new file mode 100644 index 0000000..53f28cf --- /dev/null +++ b/backend/app/plugins/wiaas/tests/factories/class-wiaas-unit-test-order-factory.php @@ -0,0 +1,139 @@ + $customer_id + )); + + return $order; + } + + /** + * @param WC_Order|int $order + * @param int $customer_organization_id + */ + public function add_customer_organization_info($order, $customer_organization_id) { + + if (is_numeric($order)) { + + $order = wc_get_order($order); + } + + $order->add_meta_data('_wiaas_customer', $customer_organization_id); + + $order->add_meta_data('_wiaas_customer_info', wiaas_get_organization_info($customer_organization_id)); + + $order->save_meta_data(); + } + + + /** + * @param array $args + * @param WC_Order_Item_Product|null $bundle_item + * @param WC_Order|null $order + * + * @return WC_Order_Item_Product + */ + public function create_new_simple_product_order_item($args = array(), $bundle_item = null, $order = null) { + + $defaults = array( + 'quantity' => 1, + 'total' => 0 + ); + + $args = wp_parse_args($args, $defaults); + + $item = new WC_Order_Item_Product(); + + $item->set_props( + array( + 'quantity' => $args['quantity'], + 'total' => $args['total'], + ) + ); + + if (! empty($args['category']) ) { + + $item->add_meta_data('_wiaas_category', $args['category']); + } + + if (! empty($args['supplier_organization_id']) ) { + + $item->add_meta_data('_wiaas_supplier_organization_id', $args['supplier_organization_id']); + } + + $item->set_backorder_meta(); + + if (! empty($order) ) { + + $order->add_item($item); + + $order->save(); + } + + return $item; + } + + /** + * @param array $args + * @param WC_Order|null $order + * + * @return WC_Order_Item_Product + */ + public function create_new_bundle_order_item($args = array(), $order = null) { + + $defaults = array( + 'quantity' => 1, + 'total' => 0 + ); + + $args = wp_parse_args($args, $defaults); + + $item = new WC_Order_Item_Product(); + + $item->set_props( + array( + 'quantity' => $args['quantity'], + 'total' => $args['total'], + ) + ); + + $item->set_backorder_meta(); + + if (! empty($order) ) { + + $order->add_item($item); + + $order->save(); + } + + return $item; + } + + /** + * @param WC_Order $order + * @param array $items + */ + public function add_order_items($order, $items) { + + foreach ( $items as $item ) { + + $order->add_item($item); + } + + $order->save(); + } +} \ No newline at end of file diff --git a/backend/app/plugins/wiaas/tests/factories/class-wiaas-unit-test-organization-factory.php b/backend/app/plugins/wiaas/tests/factories/class-wiaas-unit-test-organization-factory.php new file mode 100644 index 0000000..a483b15 --- /dev/null +++ b/backend/app/plugins/wiaas/tests/factories/class-wiaas-unit-test-organization-factory.php @@ -0,0 +1,70 @@ + 'organization' + ); + + $args = wp_parse_args($args, $defaults); + + $term_args = array(); + + if (! empty($args['parent_id'])) { + + $term_args['parent'] = $args['parent_id']; + } + + $result = wp_insert_term( + $args['name'], + Wiaas_User_Organization::TAXONOMY_NAME, + $term_args + ); + + if (! is_wp_error($result) ) { + + return $result['term_id']; + } + + return 0; + } + + public function assign_user_to_organization($user_id, $organization_id) { + wp_set_object_terms( + $user_id, + $organization_id, + Wiaas_User_Organization::TAXONOMY_NAME); + + update_user_meta($user_id, '_wiaas_organization_id', $organization_id); + } + + public function delete_organization($organization_id) { + wp_delete_term( + $organization_id, + Wiaas_User_Organization::TAXONOMY_NAME); + } + + public function delete_organizations() { + + $terms = get_terms(array( + 'taxonomy' => Wiaas_User_Organization::TAXONOMY_NAME, + 'hide_empty' => false + )); + + foreach ($terms as $term) { + + wp_delete_term($term->term_id, Wiaas_User_Organization::TAXONOMY_NAME); + } + } +} \ No newline at end of file diff --git a/backend/app/plugins/wiaas/tests/factories/class-wiaas-unit-test-product-factory.php b/backend/app/plugins/wiaas/tests/factories/class-wiaas-unit-test-product-factory.php new file mode 100644 index 0000000..d7a14b7 --- /dev/null +++ b/backend/app/plugins/wiaas/tests/factories/class-wiaas-unit-test-product-factory.php @@ -0,0 +1,218 @@ + 10, + 'is_recurring' => false, + 'pay_period' => 0 + ); + + $args = wp_parse_args($args, $defaults); + + $post_id = wp_insert_post(array( + 'post_type' => 'product', + 'post_status' => 'publish', + 'post_name' => 'product', + 'post_title' => 'Product', + 'post_content' => 'Product', + 'post_excerpt' => 'Product' + ), true); + + $product = new WC_Product_Simple($post_id); + + $this->set_product_price($product, $args['price'], $args['is_recurring'], $args['pay_period']); + + $product->save(); + + if (! empty($args['category']) ) { + + $this->assign_product_to_category($product->get_id(), $args['category']); + } + + if (! empty($args['country']) ) { + + $this->assign_product_to_country($product->get_id(), $args['country']); + } + + if (! empty($args['supplier']) ) { + + $this->assign_product_to_supplier($product->get_id(), $args['supplier']); + } + + return $product; + } + + /** + * @param WC_Product_Simple|int $product Product or Product ID + * @param int $price + * @param bool $is_recurring + * @param int $pay_period + */ + public function set_product_price($product, $price = 10, $is_recurring = false, $pay_period = 0) { + + if (is_numeric($product)) { + + $product = wc_get_product($product); + } + + Wiaas_Product_Pricing::set_product_price($product, $price, $is_recurring, $pay_period); + + $product->save(); + + delete_transient('wc_bundled_product_data'); + + + } + + /** + * @param WC_Product_Simple|int $product Product or Product ID + * @param string|int $category + */ + public function assign_product_to_category($product, $category) { + + if (is_numeric($product)) { + $product_id = $product; + } else { + $product_id = $product->get_id(); + } + + wp_add_object_terms($product_id, $category, 'product_cat'); + } + + /** + * @param WC_Product_Simple|int $product Product or Product ID + * @param string|int $country + */ + public function assign_product_to_country($product, $country) { + + if (is_numeric($product)) { + $product_id = $product; + } else { + $product_id = $product->get_id(); + } + + wp_add_object_terms($product_id, $country, 'product_country'); + } + + /** + * @param WC_Product_Simple|int $product Product or Product ID + * @param string|int $supplier + */ + public function assign_product_to_supplier($product, $supplier) { + + if (is_numeric($product)) { + $product_id = $product; + } else { + $product_id = $product->get_id(); + } + + wp_add_object_terms($product_id, $supplier, 'supplier'); + } + + /** + * @param array $args { + * @type array $products Simple products + * @type array $product_quantities Quantities for corresponding products from $products ( ex: [10, 5, 7] ) + * } + * + * @return WC_Product_Bundle + */ + public function create_product_bundle($args = array()) { + + $post_id = wp_insert_post(array( + 'post_type' => 'product', + 'post_status' => 'publish', + 'post_name' => 'Bundle', + 'post_title' => 'Product Bundle', + 'post_content' => 'Product Bundle', + 'post_excerpt' => 'Product Bundle' + ), true); + + $bundle = new WC_Product_Bundle($post_id); + + if (! empty($args['products']) ) { + + if ( empty($args['product_quantities']) ) { + + $args['product_quantities'] = array_fill(0, count($args['products']), 1); + } + + if ( count($args['product_quantities']) < count($args['products'])) { + + $args['product_quantities'] = array_pad($args['product_quantities'], count($args['products']), 1); + } + + $args['product_quantities'] = array_map('absint', $args['product_quantities']); + + $bundled_data = array(); + + foreach ($args['products'] as $index => $product) { + + $bundled_data[] = array( + 'product_id' => $product->get_id(), + 'quantity_min' => $args['product_quantities'][$index], + 'quantity_max' => $args['product_quantities'][$index], + 'priced_individually' => true + ); + } + + $bundle->set_bundled_data_items($bundled_data); + + $bundle->sync(true); + } + + $bundle->save(); + + if (! empty($args['country']) ) { + + $this->assign_product_to_country($bundle->get_id(), $args['country']); + } + + return $bundle; + } + + /** + * @param WC_Product_Bundle $bundle + * @param array $pricing_rules + * @param int $commission + * @param int $cost_margin + */ + public function set_product_bundle_prices($bundle, $pricing_rules = null, $commission = 50, $cost_margin = 0) { + + if ( empty($pricing_rules) ) { + + $pricing_rules = array( + 'purchase' => array( + 'minimal_fixed_price' => 500, + 'principal_amount' => 0, + 'minimal_services_price' => 0 + ) + ); + } + + Wiaas_Package_Pricing::set_package_prices($bundle, $pricing_rules, $commission, $cost_margin); + } +} \ No newline at end of file diff --git a/backend/app/plugins/wiaas/tests/unit-tests/api/test-wiaas-rest-user-api.php b/backend/app/plugins/wiaas/tests/unit-tests/api/test-wiaas-rest-user-api.php index 6f8176a..57704a3 100644 --- a/backend/app/plugins/wiaas/tests/unit-tests/api/test-wiaas-rest-user-api.php +++ b/backend/app/plugins/wiaas/tests/unit-tests/api/test-wiaas-rest-user-api.php @@ -102,7 +102,7 @@ class Wiass_REST_User_Api_Test extends Wiaas_Unit_Test_Case { $country = $data[0]; $this->assertNotNull($country); $this->assertTrue(is_array($country)); - $this->assertArrayHasKey('country_id', $country); - $this->assertArrayHasKey('country_name', $country); + $this->assertArrayHasKey('code', $country); + $this->assertArrayHasKey('name', $country); } } diff --git a/backend/app/plugins/wiaas/tests/unit-tests/package/test-wiaas-package-addon.php b/backend/app/plugins/wiaas/tests/unit-tests/package/test-wiaas-package-addon.php index 5a289a2..6f26ef0 100644 --- a/backend/app/plugins/wiaas/tests/unit-tests/package/test-wiaas-package-addon.php +++ b/backend/app/plugins/wiaas/tests/unit-tests/package/test-wiaas-package-addon.php @@ -16,10 +16,10 @@ class Wiaas_Package_Addon_Test extends Wiaas_Unit_Test_Case { * @covers Wiaas_Package_Addon::get_package_addons() */ function test_adding_package_addons() { - $package = $this->create_new_package(); + $package = $this->factory->product->create_product_bundle(); - $addon1 = $this->create_new_package(); - $addon2 = $this->create_new_package(); + $addon1 = $this->factory->product->create_product_bundle(); + $addon2 = $this->factory->product->create_product_bundle(); $addons_ids = array( $addon1->get_id(), $addon2->get_id() diff --git a/backend/app/plugins/wiaas/tests/unit-tests/package/test-wiaas-package-option-groups.php b/backend/app/plugins/wiaas/tests/unit-tests/package/test-wiaas-package-option-groups.php index 448c5ad..4423b3e 100644 --- a/backend/app/plugins/wiaas/tests/unit-tests/package/test-wiaas-package-option-groups.php +++ b/backend/app/plugins/wiaas/tests/unit-tests/package/test-wiaas-package-option-groups.php @@ -16,12 +16,12 @@ class Wiaas_Package_Option_Groups_Test extends Wiaas_Unit_Test_Case { * @covers Wiaas_Package_Option_Groups::get_package_option_groups() */ function test_adding_package_option_group() { - $package = $this->create_new_package(); + $package = $this->factory->product->create_product_bundle(); - $option_package1 = $this->create_new_package(); + $option_package1 = $this->factory->product->create_product_bundle(); Wiaas_Package_Type::set_package_type($option_package1->get_id(), 'option'); - $option_package2 = $this->create_new_package(); + $option_package2 = $this->factory->product->create_product_bundle(); Wiaas_Package_Type::set_package_type($option_package2->get_id(), 'option'); $option_group1 = array( @@ -79,9 +79,9 @@ class Wiaas_Package_Option_Groups_Test extends Wiaas_Unit_Test_Case { * @covers Wiaas_Package_Option_Groups::get_group_name_for_package_option() */ function test_get_group_name_for_package_option() { - $package = $this->create_new_package(); + $package = $this->factory->product->create_product_bundle(); - $option_package = $this->create_new_package(); + $option_package = $this->factory->product->create_product_bundle(); Wiaas_Package_Type::set_package_type($option_package->get_id(), 'option'); $option_group = array( diff --git a/backend/app/plugins/wiaas/tests/unit-tests/package/class-wiaas-package-status.php b/backend/app/plugins/wiaas/tests/unit-tests/package/test-wiaas-package-status.php similarity index 71% rename from backend/app/plugins/wiaas/tests/unit-tests/package/class-wiaas-package-status.php rename to backend/app/plugins/wiaas/tests/unit-tests/package/test-wiaas-package-status.php index f722379..3ed02b0 100644 --- a/backend/app/plugins/wiaas/tests/unit-tests/package/class-wiaas-package-status.php +++ b/backend/app/plugins/wiaas/tests/unit-tests/package/test-wiaas-package-status.php @@ -16,6 +16,7 @@ class Wiaas__Package_Status_Test extends Wiaas_Unit_Test_Case { $this->assertNotEmpty($package_statuses); $this->assertContains(Wiaas_Package_Status::AVAILABLE, $package_statuses); + $this->assertContains(Wiaas_Package_Status::INVALID_MARGIN, $package_statuses); } /** @@ -23,7 +24,7 @@ class Wiaas__Package_Status_Test extends Wiaas_Unit_Test_Case { * @covers Wiaas_Package_Type::get_package_status() */ function test_adding_package_status() { - $package = $this->create_new_package(); + $package = $this->factory->product->create_product_bundle(); Wiaas_Package_Status::set_package_status($package->get_id(), Wiaas_Package_Status::AVAILABLE); @@ -37,15 +38,15 @@ class Wiaas__Package_Status_Test extends Wiaas_Unit_Test_Case { * Test package status update on simple product price update */ function test_package_status_update_on_simple_product_price_update() { - $product1 = $this->create_new_product(20); - $this->add_product_category($product1, 'hardware'); - $product2 = $this->create_new_product(20); - $this->add_product_category($product2, 'software'); + $product1 = $this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'hardware' )); - $package = $this->create_new_package(); - - $this->add_products_to_package($package, array( $product1, $product2)); + $package = $this->factory->product->create_product_bundle(array( + 'products' => array( + $product1, + $this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'software' )) + ) + )); $pricing_rules = array( 'purchase' => array( @@ -68,10 +69,13 @@ class Wiaas__Package_Status_Test extends Wiaas_Unit_Test_Case { $cost_margin = 100; Wiaas_Package_Pricing::set_package_prices($package, $pricing_rules, $commision, $cost_margin); - $this->assertEquals(Wiaas_Package_Status::get_package_status($package)->get_id(), Wiaas_Package_Status::AVAILABLE); + $this->assertEquals(Wiaas_Package_Status::get_package_status($package->get_id()), Wiaas_Package_Status::AVAILABLE); - $product1->set_price(1000); - $this->assertEquals(Wiaas_Package_Status::get_package_status($package)->get_id(), Wiaas_Package_Status::MARGIN_EXCEEDED); + $this->factory->product->set_product_price($product1, 1000); + + Wiaas_Package_Pricing::on_product_update($product1->get_id()); + + $this->assertEquals(Wiaas_Package_Status::get_package_status($package->get_id()), Wiaas_Package_Status::INVALID_MARGIN); } @@ -79,15 +83,12 @@ class Wiaas__Package_Status_Test extends Wiaas_Unit_Test_Case { * Test package status update on cost margin update */ function test_package_status_update_on_margin_cost_update() { - $product1 = $this->create_new_product(20); - $this->add_product_category($product1, 'hardware'); - - $product2 = $this->create_new_product(20); - $this->add_product_category($product2, 'software'); - - $package = $this->create_new_package(); - - $this->add_products_to_package($package, array( $product1, $product2)); + $package = $this->factory->product->create_product_bundle(array( + 'products' => array( + $this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'hardware' )), + $this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'software' )) + ) + )); $pricing_rules = array( 'purchase' => array( @@ -108,13 +109,14 @@ class Wiaas__Package_Status_Test extends Wiaas_Unit_Test_Case { ); $commision = 50; $cost_margin = 0; - + Wiaas_Package_Pricing::set_package_prices($package, $pricing_rules, $commision, $cost_margin); - $this->assertEquals(Wiaas_Package_Status::get_package_status($package)->get_id(), Wiaas_Package_Status::AVAILABLE); + $this->assertEquals(Wiaas_Package_Status::get_package_status($package->get_id()), Wiaas_Package_Status::AVAILABLE); $cost_margin = 1; Wiaas_Package_Pricing::set_package_prices($package, $pricing_rules, $commision, $cost_margin); - $this->assertEquals(Wiaas_Package_Status::get_package_status($package)->get_id(), Wiaas_Package_Status::MARGIN_EXCEEDED); + + $this->assertEquals(Wiaas_Package_Status::get_package_status($package->get_id()), Wiaas_Package_Status::INVALID_MARGIN); } } \ No newline at end of file diff --git a/backend/app/plugins/wiaas/tests/unit-tests/package/test-wiaas-package-type.php b/backend/app/plugins/wiaas/tests/unit-tests/package/test-wiaas-package-type.php index a2e5fd0..3c66c06 100644 --- a/backend/app/plugins/wiaas/tests/unit-tests/package/test-wiaas-package-type.php +++ b/backend/app/plugins/wiaas/tests/unit-tests/package/test-wiaas-package-type.php @@ -23,7 +23,7 @@ class Wiaas__Package_Type_Test extends Wiaas_Unit_Test_Case { * @covers Wiaas_Package_Type::get_package_type() */ function test_adding_package_type() { - $package = $this->create_new_package(); + $package = $this->factory->product->create_product_bundle(); Wiaas_Package_Type::set_package_type($package->get_id(), 'standard'); diff --git a/backend/app/plugins/wiaas/tests/unit-tests/pricing/test-wiaas-package-cl-pricing.php b/backend/app/plugins/wiaas/tests/unit-tests/pricing/test-wiaas-package-cl-pricing.php index 6dcfcf5..59849b0 100644 --- a/backend/app/plugins/wiaas/tests/unit-tests/pricing/test-wiaas-package-cl-pricing.php +++ b/backend/app/plugins/wiaas/tests/unit-tests/pricing/test-wiaas-package-cl-pricing.php @@ -6,17 +6,17 @@ class Wiaas_Package_CL_Pricing_Test extends Wiaas_Unit_Test_Case { function setUp() { parent::setUp(); - $this->shop_owner_id = wp_insert_term( - 'Shop owner organization', - Wiaas_User_Organization::TAXONOMY_NAME)['term_id']; + $this->shop_owner_id = $this->factory->organization->create_new_organization( + array( 'name' => 'Shop owner organization' ) + ); - $this->customer_id = wp_insert_term( - 'Customer Organization', - Wiaas_User_Organization::TAXONOMY_NAME)['term_id']; + $this->customer_id = $this->factory->organization->create_new_organization( + array( 'name' => 'Customer Organization' ) + ); - $package = $this->create_new_package(); - - $this->add_products_to_package($package, array( $this->create_new_product())); + $package = $this->factory->product->create_product_bundle(array( + 'products' => array( $this->factory->product->create_simple_product() ) + )); $this->package_id = $package->get_id(); diff --git a/backend/app/plugins/wiaas/tests/unit-tests/pricing/test-wiaas-package-pricing.php b/backend/app/plugins/wiaas/tests/unit-tests/pricing/test-wiaas-package-pricing.php index 3c73c3f..292daed 100644 --- a/backend/app/plugins/wiaas/tests/unit-tests/pricing/test-wiaas-package-pricing.php +++ b/backend/app/plugins/wiaas/tests/unit-tests/pricing/test-wiaas-package-pricing.php @@ -8,7 +8,7 @@ class Wiaas_Package_Pricing_Test extends Wiaas_Unit_Test_Case { */ function test_set_and_get_package_prices() { - $package = $this->create_new_package(); + $package = $this->factory->product->create_product_bundle(); $pricing_rules = array( 'purchase' => array( diff --git a/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-access-management.php b/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-access-management.php new file mode 100644 index 0000000..0cc93de --- /dev/null +++ b/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-access-management.php @@ -0,0 +1,196 @@ +customer_user_id = wp_insert_user(array( + 'user_login' => 'test_customer', + 'user_pass' => 'test', + 'user_email' => 'test_customer@mail.com', + 'role' => 'customer', + )); + + $this->organization_id = $this->factory->organization->create_new_organization(); + + $this->factory->organization->assign_user_to_organization($this->customer_user_id, $this->organization_id); + + $this->order = $this->factory->order->create_new_order(); + } + + function tearDown() { + parent::tearDown(); + + wp_set_current_user(1); + + wp_delete_user($this->customer_user_id); + + $this->factory->organization->delete_organizations(); + } + + /** + * @covers Wiaas_Access_Management::maybe_handle_product_access() + */ + function test_simple_product_has_admin_access() { + + $simple_product = $this->factory->product->create_simple_product(); + + Wiaas_Access_Management::maybe_handle_product_access($simple_product->get_id(), get_post($simple_product->get_id())); + + $access_group_ids = Groups_Post_Access::get_read_group_ids( $simple_product->get_id() ); + $this->assertEquals(1, count($access_group_ids)); + $admin_access_group = Groups_Group::read_by_name('admin'); + $this->assertEquals($admin_access_group->group_id, $access_group_ids[0]); + } + + /** + * @covers Wiaas_Access_Management::maybe_handle_product_access() + */ + function test_bundle_with_no_price_has_admin_access() { + + $bundle_product = $this->factory->product->create_product_bundle(); + + Wiaas_Access_Management::maybe_handle_product_access($bundle_product->get_id(), get_post($bundle_product->get_id())); + + $access_group_ids = Groups_Post_Access::get_read_group_ids( $bundle_product->get_id() ); + $this->assertEquals(1, count($access_group_ids)); + $admin_access_group = Groups_Group::read_by_name('admin'); + $this->assertEquals($admin_access_group->group_id, $access_group_ids[0]); + } + + /** + * @covers Wiaas_Access_Management::maybe_handle_product_access() + */ + function test_bundle_with_prices_has_registered_access() { + + $bundle_product = $this->factory->product->create_product_bundle(); + $this->factory->product->set_product_bundle_prices($bundle_product); + + Wiaas_Access_Management::maybe_handle_product_access($bundle_product->get_id(), get_post($bundle_product->get_id())); + + $access_group_ids = Groups_Post_Access::get_read_group_ids( $bundle_product->get_id() ); + $this->assertEquals(1, count($access_group_ids)); + $registered_access_group = Groups_Group::read_by_name('Registered'); + $this->assertEquals($registered_access_group->group_id, $access_group_ids[0]); + } + + /** + * @covers Wiaas_Access_Management::assign_order_to_customer_organization() + */ + function test_order_assigned_to_customer_organization() { + + wp_set_current_user($this->customer_user_id); + + Wiaas_Access_Management::assign_order_to_customer_organization($this->order->get_id()); + + $organization_access_group = Groups_Group::read_by_name('organization'); + $access_group_ids = Groups_Post_Access::get_read_group_ids( $this->order->get_id() ); + + $this->assertEquals(1, count($access_group_ids)); + $this->assertNotNull($access_group_ids[0]); + $this->assertEquals($organization_access_group->group_id, $access_group_ids[0]); + + } + + /** + * @covers Wiaas_Access_Management::assign_order_to_commercial_lead_organization() + */ + function test_order_assigned_to_commercial_lead_organization() { + + $this->order->update_meta_data('_wiaas_commercial_lead_id', $this->organization_id); + $this->order->save_meta_data(); + + Wiaas_Access_Management::assign_order_to_commercial_lead_organization($this->order->get_id()); + + $organization_access_group = Groups_Group::read_by_name('organization'); + $access_group_ids = Groups_Post_Access::get_read_group_ids( $this->order->get_id() ); + + $this->assertEquals(1, count($access_group_ids)); + $this->assertNotNull($access_group_ids[0]); + $this->assertEquals($organization_access_group->group_id, $access_group_ids[0]); + } + + /** + * @covers Wiaas_Access_Management::assign_order_to_supplier_organizations() + */ + function test_order_assigned_to_supplier_organizations() { + + $items = array(); + $items[] = $this->factory->order->create_new_simple_product_order_item(array( + 'category' => 'hardware', + 'supplier_organization_id' => $this->factory->organization->create_new_organization( array( 'name' => 'hardware supplier')) + )); + $items[] = $this->factory->order->create_new_simple_product_order_item(array( + 'category' => 'software', + 'supplier_organization_id' => $this->factory->organization->create_new_organization( array( 'name' => 'software supplier')) + )); + $items[] = $this->factory->order->create_new_simple_product_order_item(array( + 'category' => 'service', + 'supplier_organization_id' => $this->factory->organization->create_new_organization( array( 'name' => 'service supplier')) + )); + $items[] = $this->factory->order->create_new_simple_product_order_item(array( + 'category' => 'installation', + 'supplier_organization_id' => $this->factory->organization->create_new_organization( array( 'name' => 'installation supplier')) + )); + + $this->factory->order->add_order_items($this->order, $items); + + Wiaas_Access_Management::assign_order_to_supplier_organizations($this->order->get_id()); + + $access_group_ids = Groups_Post_Access::get_read_group_ids( $this->order->get_id() ); + $this->assertEquals(3, count($access_group_ids)); + + $organization_access_group = Groups_Group::read_by_name('hardware supplier'); + $this->assertContains($organization_access_group->group_id, $access_group_ids); + + $organization_access_group = Groups_Group::read_by_name('software supplier'); + $this->assertContains($organization_access_group->group_id, $access_group_ids); + + $organization_access_group = Groups_Group::read_by_name('service supplier'); + $this->assertContains($organization_access_group->group_id, $access_group_ids); + + } + + /** + * @covers Wiaas_Access_Management::assign_order_to_installation_organization() + */ + function test_order_assigned_to_installation_organization() { + + $bundle_item = $this->factory->order->create_new_bundle_order_item(); + + $installation_item = $this->factory->order->create_new_simple_product_order_item(array( + 'category' => 'installation', + 'supplier_organization_id' => $this->organization_id + )); + + $this->order->add_item($bundle_item); + $this->order->add_item($installation_item); + + Wiaas_Access_Management::assign_order_to_installation_organization($this->order, $bundle_item, $installation_item); + + $organization_access_group = Groups_Group::read_by_name('organization'); + $access_group_ids = Groups_Post_Access::get_read_group_ids( $this->order->get_id() ); + + $this->assertEquals(1, count($access_group_ids)); + $this->assertNotNull($access_group_ids[0]); + $this->assertEquals($organization_access_group->group_id, $access_group_ids[0]); + } +} \ No newline at end of file diff --git a/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-countries.php b/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-countries.php index be4b538..a352811 100644 --- a/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-countries.php +++ b/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-countries.php @@ -5,7 +5,7 @@ */ class Wiaas_Countries_Test extends Wiaas_Unit_Test_Case { - var $product, $package, $current_country = 'Sweden'; + var $product, $package; public function setUp() { parent::setUp(); @@ -13,14 +13,10 @@ class Wiaas_Countries_Test extends Wiaas_Unit_Test_Case { # set admin as current user wp_set_current_user(1); - $this->product = $this->create_new_product(); - wp_set_object_terms($this->product->get_id(), $this->current_country, 'product_country', false); - clean_object_term_cache( $this->product->get_id(), 'product_country' ); + $this->product = $this->factory->product->create_simple_product(array( 'country' => 'sweden' )); - $this->package = $this->create_new_package(); - wp_set_object_terms($this->package->get_id(), $this->current_country, 'product_country', false); - clean_object_term_cache( $this->package->get_id(), 'product_country' ); + $this->package = $this->factory->product->create_product_bundle(array( 'country' => 'sweden' )); } @@ -29,19 +25,13 @@ class Wiaas_Countries_Test extends Wiaas_Unit_Test_Case { */ function test_available_countries_created() { // test taxonomy is available - $taxonomy = get_taxonomy('product_country'); + $countries = Wiaas_Countries::get_available_countries(); - $this->assertInstanceOf(WP_Taxonomy::class, $taxonomy); + $country_codes = wp_list_pluck($countries, 'code'); - $country_names = array_map(function($term) { - return $term->name; - }, get_terms(array( 'taxonomy' => 'product_country', 'hide_empty' => false ))); - - $this->assertNotEmpty($country_names); - - $this->assertContains('Sweden', $country_names); - $this->assertContains('Denmark', $country_names); - $this->assertContains('Finland', $country_names); + $this->assertContains('se', $country_codes); + $this->assertContains('fi', $country_codes); + $this->assertContains('dk', $country_codes); } /** @@ -53,7 +43,7 @@ class Wiaas_Countries_Test extends Wiaas_Unit_Test_Case { $this->assertNotNull($retrieved_country, 'Product has not country!'); - $this->assertEquals($retrieved_country['name'], $this->current_country, 'Retrieved product country is incorrect!'); + $this->assertEquals($retrieved_country['name'], 'Sweden', 'Retrieved product country is incorrect!'); } @@ -65,7 +55,7 @@ class Wiaas_Countries_Test extends Wiaas_Unit_Test_Case { $this->assertNotNull($retrieved_country, 'Package has not country!'); - $this->assertEquals($retrieved_country['name'], $this->current_country, 'Retrieved package country is incorrect!'); + $this->assertEquals($retrieved_country['name'], 'Sweden', 'Retrieved package country is incorrect!'); } } \ No newline at end of file diff --git a/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-order.php b/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-order.php index a789e8c..1bcb655 100644 --- a/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-order.php +++ b/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-order.php @@ -6,7 +6,7 @@ class Wiaas_Order_Test extends Wiaas_Unit_Test_Case { - var $customer_id, $customer_organization_id, $customer_organization_name, $order_id; + var $customer_id, $customer_organization_id, $customer_organization_name, $order; public function setUp() { parent::setUp(); @@ -23,26 +23,15 @@ class Wiaas_Order_Test extends Wiaas_Unit_Test_Case { $this->customer_organization_name = 'test-customer-organization'; # create customer organization - $this->customer_organization_id = wp_insert_term( - $this->customer_organization_name, - Wiaas_User_Organization::TAXONOMY_NAME - )['term_id']; + $this->customer_organization_id = $this->factory->organization->create_new_organization( + array( 'name' => $this->customer_organization_name ) + ); - update_user_meta($this->customer_id, '_wiaas_organization_id', $this->customer_organization_id); - - # add customer to organization - wp_set_terms_for_user( - $this->customer_id, - Wiaas_User_Organization::TAXONOMY_NAME, - [$this->customer_organization_name]); + $this->factory->organization->assign_user_to_organization($this->customer_id, $this->customer_organization_id); wp_set_current_user($this->customer_id); - $order = wc_create_order(array( - 'customer_id' => $this->customer_id - )); - - $this->order_id = $order->get_id(); + $this->order = $this->factory->order->create_new_order(); } function tearDown() { @@ -57,46 +46,6 @@ class Wiaas_Order_Test extends Wiaas_Unit_Test_Case { Wiaas_User_Organization::TAXONOMY_NAME); } - /** - * @covers Wiaas_Order::assign_order_to_organization() - */ - function test_order_assigned_to_customer_organization() { - - $organization_access_group = Groups_Group::read_by_name($this->customer_organization_name); - $access_group_ids = Groups_Post_Access::get_read_group_ids( $this->order_id ); - - $this->assertEquals(1, count($access_group_ids)); - $this->assertNotNull($access_group_ids[0]); - $this->assertEquals($organization_access_group->group_id, $access_group_ids[0]); - } - - /** - * @covers Wiaas_Order::check_order_access() - */ - function test_order_customer_can_access_order() { - - $has_access = Wiaas_Order::check_order_access(true, 'view', $this->order_id, 'shop_order'); - - $this->assertTrue($has_access); - } - - /** - * @covers Wiaas_Order::check_order_access() - */ - function test_customer_cannot_access_order_when_not_in_organization() { - $customer_id = wc_create_new_customer( - 'test_customer1@mail.com', - 'test_customer1', - 'test1'); - wp_set_current_user($customer_id); - - $this->assertTrue(Groups_Post_Access::handles_post_type('shop_order')); - - $has_access = Wiaas_Order::check_order_access(true, 'view', $this->order_id, 'shop_order'); - - $this->assertFalse($has_access); - } - /** * @covers Wiaas_Order::wiaas_prepare_rest_orders_query() */ @@ -139,10 +88,12 @@ class Wiaas_Order_Test extends Wiaas_Unit_Test_Case { 'line_items' => array() ); + $this->factory->order->add_customer_organization_info($this->order, $this->customer_organization_id); + $order_rest_response = Wiaas_Order::transform_rest_order( new WP_REST_Response($order_response), - wc_get_order($this->order_id), - array( 'id' => $this->order_id)); + $this->order, + array( 'id' => $this->order->get_id() )); $transformed_order_response = $order_rest_response->get_data(); diff --git a/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-pricing.php b/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-pricing.php index a8d766c..6f81118 100644 --- a/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-pricing.php +++ b/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-pricing.php @@ -3,15 +3,16 @@ class Wiaas_Pricing_Test extends Wiaas_Unit_Test_Case { private function _create_package_to_sell() { - $product1 = $this->create_new_product(20); - $this->add_product_category($product1, 'hardware'); - - $product2 = $this->create_new_product(20, true, 2); - $this->add_product_category($product2, 'installation'); - - $package = $this->create_new_package(); - - $this->add_products_to_package($package, array( $product1, $product2)); + $package = $this->factory->product->create_product_bundle(array( + 'products' => array( + $this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'hardware' )), + $this->factory->product->create_simple_product(array( + 'price' => 20, + 'is_recurring' => true, + 'pay_period' => 2, + 'category' => 'installation' )) + ) + )); $pricing_rules = array( 'purchase' => array( @@ -32,17 +33,16 @@ class Wiaas_Pricing_Test extends Wiaas_Unit_Test_Case { ); $commision = 50; $cost_margin = 0; - Wiaas_Package_Pricing::set_package_prices($package, $pricing_rules, $commision, $cost_margin); - $customer_id = wp_create_term( - 'Customer', - Wiaas_User_Organization::TAXONOMY_NAME - )['term_id']; + $this->factory->product->set_product_bundle_prices($package, $pricing_rules, $commision, $cost_margin); - $commercial_lead_id = wp_create_term( - 'Commercial Lead', - Wiaas_User_Organization::TAXONOMY_NAME - )['term_id']; + $customer_id = $this->factory->organization->create_new_organization( + array( 'name' => 'Customer' ) + ); + + $commercial_lead_id = $this->factory->organization->create_new_organization( + array( 'name' => 'Commercial Lead' ) + ); self::_set_package_default_extras($commercial_lead_id, $package->get_id()); @@ -97,7 +97,7 @@ class Wiaas_Pricing_Test extends Wiaas_Unit_Test_Case { * @covers Wiaas_Pricing::get_product_total_cost() */ function test_get_fixed_product_total_cost() { - $product = $this->create_new_product(); + $product = $this->factory->product->create_simple_product(); $total_cost = Wiaas_Pricing::get_product_total_cost($product); @@ -108,7 +108,11 @@ class Wiaas_Pricing_Test extends Wiaas_Unit_Test_Case { * @covers Wiaas_Pricing::get_product_total_cost() */ function test_get_recurring_product_total_cost() { - $product = $this->create_new_product(10, true, 2); + $product = $this->factory->product->create_simple_product(array( + 'price' => 10, + 'is_recurring' => true, + 'pay_period' => 2 + )); $total_cost = Wiaas_Pricing::get_product_total_cost($product); @@ -119,15 +123,12 @@ class Wiaas_Pricing_Test extends Wiaas_Unit_Test_Case { * @covers Wiaas_Pricing::get_package_total_cost() */ function test_get_package_with_fixed_products_total_cost() { - $product1 = $this->create_new_product(20); - $this->add_product_category($product1, 'hardware'); - - $product2 = $this->create_new_product(20); - $this->add_product_category($product2, 'software'); - - $package = $this->create_new_package(); - - $this->add_products_to_package($package, array( $product1, $product2)); + $package = $this->factory->product->create_product_bundle(array( + 'products' => array( + $this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'hardware' )), + $this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'software' )) + ) + )); $expected_total_price = 40; @@ -140,15 +141,12 @@ class Wiaas_Pricing_Test extends Wiaas_Unit_Test_Case { * @covers Wiaas_Pricing::get_package_total_cost() */ function test_get_package_with_recurring_products_total_cost() { - $product1 = $this->create_new_product(20); - $this->add_product_category($product1, 'hardware'); - - $product2 = $this->create_new_product(20, true, 2); - $this->add_product_category($product2, 'software'); - - $package = $this->create_new_package(); - - $this->add_products_to_package($package, array( $product1, $product2)); + $package = $this->factory->product->create_product_bundle(array( + 'products' => array( + $this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'hardware' )), + $this->factory->product->create_simple_product(array( 'price' => 20, 'is_recurring' => true, 'pay_period' => 2, 'category' => 'software' )) + ) + )); $expected_total_price = 60; @@ -161,15 +159,12 @@ class Wiaas_Pricing_Test extends Wiaas_Unit_Test_Case { * @covers Wiaas_Pricing::get_package_total_cost() */ function test_package_with_single_installation_product_total_cost() { - $product1 = $this->create_new_product(20); - $this->add_product_category($product1, 'hardware'); - - $product2 = $this->create_new_product(20, true, 2); - $this->add_product_category($product2, 'installation'); - - $package = $this->create_new_package(); - - $this->add_products_to_package($package, array( $product1, $product2)); + $package = $this->factory->product->create_product_bundle(array( + 'products' => array( + $this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'hardware' )), + $this->factory->product->create_simple_product(array( 'price' => 20, 'is_recurring' => true, 'pay_period' => 2, 'category' => 'installation' )) + ) + )); $expected_total_price = 60; @@ -182,20 +177,13 @@ class Wiaas_Pricing_Test extends Wiaas_Unit_Test_Case { * @covers Wiaas_Pricing::get_package_total_cost() */ function test_package_with_multiple_installation_products_total_cost() { - $product1 = $this->create_new_product(20); - $this->add_product_category($product1, 'hardware'); - - $product2 = $this->create_new_product(10, true, 2); - $this->add_product_category($product2, 'installation'); - - $this->assertTrue(Wiaas_Product_Category::is_installation($product2)); - - $product3 = $this->create_new_product(20, true, 2); - $this->add_product_category($product3, 'installation'); - - $package = $this->create_new_package(); - - $this->add_products_to_package($package, array( $product1, $product2, $product3)); + $package = $this->factory->product->create_product_bundle(array( + 'products' => array( + $this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'hardware' )), + $this->factory->product->create_simple_product(array( 'price' => 20, 'is_recurring' => true, 'pay_period' => 2, 'category' => 'installation' )), + $this->factory->product->create_simple_product(array( 'price' => 20, 'is_recurring' => true, 'pay_period' => 2, 'category' => 'installation' )) + ) + )); // price will be 20 + 20*2 , more expensive installation will be applied $expected_total_price = 60; @@ -246,12 +234,11 @@ class Wiaas_Pricing_Test extends Wiaas_Unit_Test_Case { function test_get_addon_package_customer_price() { list( $package, $expected_prices, $customer_id, $commercial_lead_id ) = $this->_create_package_to_sell(); - $addon_product = $this->create_new_product(20); - $this->add_product_category($addon_product, 'hardware'); - - $addon_package = $this->create_new_package(); - - $this->add_products_to_package($addon_package, array($addon_product)); + $addon_package = $this->factory->product->create_product_bundle(array( + 'products' => array( + $this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'hardware' )), + ) + )); $pricing_rules = array( 'purchase' => array( @@ -330,12 +317,11 @@ class Wiaas_Pricing_Test extends Wiaas_Unit_Test_Case { function test_get_option_package_customer_price() { list( $package, $customer_id, $commercial_lead_id ) = $this->_create_package_to_sell(); - $option_product = $this->create_new_product(20); - $this->add_product_category($option_product, 'hardware'); - - $option_package = $this->create_new_package(); - - $this->add_products_to_package($option_package, array($option_product)); + $option_package = $this->factory->product->create_product_bundle(array( + 'products' => array( + $this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'hardware' )), + ) + )); $pricing_rules = array( 'purchase' => array( diff --git a/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-templates.php b/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-templates.php index e3f008d..3ff3d18 100644 --- a/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-templates.php +++ b/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-templates.php @@ -19,11 +19,10 @@ class Wiaas_Templates_Test extends Wiaas_Unit_Test_Case { ); $this->template = $this->create_new_wiaas_template(); - $this->product = $this->create_new_product(); - $this->package = $this->create_new_package(); - $this->add_products_to_package($this->package, $this->product); - - + $this->product = $this->factory->product->create_simple_product(); + $this->package = $this->factory->product->create_product_bundle(array( + 'products' => $this->product + )); } public function test_template_category_taxonomy_created() { diff --git a/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-user-organization.php b/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-user-organization.php index 8bb9718..fada82a 100644 --- a/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-user-organization.php +++ b/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-user-organization.php @@ -22,28 +22,18 @@ class Wiaas_User_Organization_Test extends Wiaas_Unit_Test_Case { $this->user_department_name = 'test_department'; - # create organization - $this->user_organization_id = wp_insert_term( - $this->user_organization_name, - Wiaas_User_Organization::TAXONOMY_NAME - )['term_id']; + // create organization + $this->user_organization_id = $this->factory->organization->create_new_organization( + array( 'name' => $this->user_organization_name ) + ); - update_user_meta($this->user_id, '_wiaas_organization_id', $this->user_organization_id); + // create department + $this->user_department_id = $this->factory->organization->create_new_organization( + array( 'name' => $this->user_department_name, 'parent_id' => $this->user_organization_id ) + ); - # create department - $this->user_department_id = wp_insert_term( - $this->user_department_name, - Wiaas_User_Organization::TAXONOMY_NAME, - array( - 'parent' => $this->user_organization_id - ) - )['term_id']; - - # assign user to organization - wp_set_terms_for_user( - $this->user_id, - Wiaas_User_Organization::TAXONOMY_NAME, - [$this->user_organization_name]); + // assign user to organization + $this->factory->organization->assign_user_to_organization($this->user_id, $this->user_organization_id); } function tearDown() { @@ -53,12 +43,7 @@ class Wiaas_User_Organization_Test extends Wiaas_Unit_Test_Case { wp_delete_user($this->user_id); - wp_delete_term( - $this->user_organization_id, - Wiaas_User_Organization::TAXONOMY_NAME); - wp_delete_term( - $this->user_department_id, - Wiaas_User_Organization::TAXONOMY_NAME); + $this->factory->organization->delete_organizations(); } /** diff --git a/backend/app/plugins/wiaas/tests/wiaas-unit-test-case.php b/backend/app/plugins/wiaas/tests/wiaas-unit-test-case.php index f83ff95..a9ba184 100644 --- a/backend/app/plugins/wiaas/tests/wiaas-unit-test-case.php +++ b/backend/app/plugins/wiaas/tests/wiaas-unit-test-case.php @@ -2,13 +2,18 @@ class Wiaas_Unit_Test_Case extends WP_UnitTestCase { + public $factory; + /** * Executes any db migrations that are done to * `wp_options` table since it is deleted on every execution */ function setUp() { parent::setUp(); - wp_set_current_user(1); + + $this->factory = new Wiaas_Unit_Test_Factory(); + + wp_set_current_user(1); # Setup Gravity info since options table is deleted after each test gf_upgrade()->install(); @@ -28,6 +33,8 @@ class Wiaas_Unit_Test_Case extends WP_UnitTestCase { Wiaas_Order_Project::register_order_project_taxonomy(); Wiaas_Product_Supplier::register_supplier_taxonomy(); + + Wiaas_Package_Status::register_package_status_taxonomy(); define('WP_TEST_IN_PROGRESS',true); } diff --git a/backend/app/plugins/wiaas/tests/wiaas-unit-test-factory.php b/backend/app/plugins/wiaas/tests/wiaas-unit-test-factory.php deleted file mode 100644 index 4933eae..0000000 --- a/backend/app/plugins/wiaas/tests/wiaas-unit-test-factory.php +++ /dev/null @@ -1,17 +0,0 @@ - { id: address.id, countryName: address.country_name, deliveryMail: address.delivery_mail, - idCountrySelected: address.id_country_selected, + idCountrySelected: address.country_code, city: address.city, detailedAddress: address.detailed_address, zipCode: address.zip_code, @@ -18,7 +18,7 @@ export const toWiaasAddress = (address) => { id: address.id, country_name: address.countryName, delivery_mail: address.deliveryMail, - id_country_selected: address.idCountrySelected, + country_code: address.idCountrySelected, city: address.city, detailed_address: address.detailedAddress, zip_code: address.zipCode, diff --git a/frontend/src/helpers/CountryHelper.js b/frontend/src/helpers/CountryHelper.js index e1c2ca6..7d708c2 100644 --- a/frontend/src/helpers/CountryHelper.js +++ b/frontend/src/helpers/CountryHelper.js @@ -1,6 +1,6 @@ export const fromWiaasCountryList = (countryList) => { return { - idCountry: countryList.country_id, - countryName: countryList.country_name + idCountry: countryList.code, + countryName: countryList.name } } \ No newline at end of file
Suppliers
+ + class="button" + id= onClick="addAdditionalTrackingInfo(event)" + value="Add new tracking info"> +
- - class="button" - id= onClick="addAdditionalTrackingInfo(event)" - value="Add new tracking info"> -