diff --git a/locales/en.json b/locales/en.json index 09099b0..93ed3c4 100644 --- a/locales/en.json +++ b/locales/en.json @@ -172,5 +172,6 @@ "Proceed to payment": "Proceed to payment", "Return to information": "Return to information", "Search shop": "Search shop", - "Dashboard": "Dashboard" + "Dashboard": "Dashboard", + "Create order": "Create order" } \ No newline at end of file diff --git a/public/javascripts/admin.js b/public/javascripts/admin.js index 7d689ad..2665625 100644 --- a/public/javascripts/admin.js +++ b/public/javascripts/admin.js @@ -329,6 +329,61 @@ $(document).ready(function (){ } }); + $(document).on('click', '#lookupCustomer', function(e){ + e.preventDefault(); + $.ajax({ + method: 'POST', + url: '/admin/customer/lookup', + data: { + customerEmail: $('#customerEmail').val() + } + }) + .done(function(result){ + showNotification(result.message, 'success'); + $('#orderFirstName').val(result.customer.firstName); + $('#orderLastName').val(result.customer.lastName); + $('#orderAddress1').val(result.customer.address1); + $('#orderAddress2').val(result.customer.address2); + $('#orderCountry').val(result.customer.country); + $('#orderState').val(result.customer.state); + $('#orderPostcode').val(result.customer.postcode); + $('#orderPhone').val(result.customer.phone); + }) + .fail(function(msg){ + showNotification(msg.responseJSON.message, 'danger'); + }); + }); + + $(document).on('click', '#orderCreate', function(e){ + e.preventDefault(); + if($('#createOrderForm').validator('validate').has('.has-error').length === 0){ + $.ajax({ + method: 'POST', + url: '/admin/order/create', + data: { + orderStatus: $('#orderStatus').val(), + email: $('#customerEmail').val(), + firstName: $('#orderFirstName').val(), + lastName: $('#orderLastName').val(), + address1: $('#orderAddress1').val(), + address2: $('#orderAddress2').val(), + country: $('#orderCountry').val(), + state: $('#orderState').val(), + postcode: $('#orderPostcode').val(), + phone: $('#orderPhone').val(), + orderComment: $('#orderComment').val() + } + }) + .done(function(result){ + showNotification(result.message, 'success'); + window.location = `/admin/order/view/${result.orderId}`; + }) + .fail(function(msg){ + showNotification(msg.responseJSON.message, 'danger'); + }); + } + }); + $('#sendTestEmail').on('click', function(e){ e.preventDefault(); $.ajax({ diff --git a/public/javascripts/admin.min.js b/public/javascripts/admin.min.js index 661bc6d..aa6cf3b 100644 --- a/public/javascripts/admin.min.js +++ b/public/javascripts/admin.min.js @@ -1 +1 @@ -$(document).ready(function(){if($(document).on("click","#btnGenerateAPIkey",function(e){e.preventDefault(),$.ajax({method:"POST",url:"/admin/createApiKey"}).done(function(e){$("#apiKey").val(e.apiKey),showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$(document).on("click",".product_opt_remove",function(e){e.preventDefault();var t=$(this).closest("li").find(".opt-name").html();$.ajax({method:"POST",url:"/admin/product/removeoption",data:{productId:$("#productId").val(),optName:t}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$(document).on("click","#product_opt_add",function(e){e.preventDefault();var t=$("#product_optName").val(),o=$("#product_optLabel").val(),a=$("#product_optType").val(),i=$("#product_optOptions").val(),n={};""!==$("#productOptions").val()&&'"{}"'!==$("#productOptions").val()&&(n=JSON.parse($("#productOptions").val()));var s='
  • ';s+='
    ',s+='
    '+t+"
    ",s+='
    '+o+"
    ",s+='
    '+a+"
    ",s+='
    '+i+"
    ",s+='
    ',s+='',s+="
  • ",$("#product_opt_wrapper").append(s),n[t]={optName:t,optLabel:o,optType:a,optOptions:$.grep(i.split(","),function(e){return 0===e||e})},$("#productOptions").val(JSON.stringify(n)),$("#product_optName").val(""),$("#product_optLabel").val(""),$("#product_optOptions").val("")}),$("#settingsForm").validator().on("submit",function(e){e.isDefaultPrevented()||(e.preventDefault(),$("#footerHtml_input").val($(".CodeMirror")[0].CodeMirror.getValue()),$("#googleAnalytics_input").val($(".CodeMirror")[1].CodeMirror.getValue()),$("#customCss_input").val($(".CodeMirror")[2].CodeMirror.getValue()),$.ajax({method:"POST",url:"/admin/settings/update",data:$("#settingsForm").serialize()}).done(function(e){showNotification(e.message,"success")}).fail(function(e){showNotification(e.responseJSON.message,"danger")}))}),$(document).on("click","#orderStatusUpdate",function(e){$.ajax({method:"POST",url:"/admin/order/statusupdate",data:{order_id:$("#order_id").val(),status:$("#orderStatus").val()}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$("#userNewForm").validator().on("submit",function(e){e.isDefaultPrevented()||(e.preventDefault(),$.ajax({method:"POST",url:"/admin/user/insert",data:{usersName:$("#usersName").val(),userEmail:$("#userEmail").val(),userPassword:$("#userPassword").val()}}).done(function(e){showNotification(e.message,"success",!1,"/admin/user/edit/"+e.userId)}).fail(function(e){showNotification(e.responseJSON.message,"danger")}))}),$(".userDelete").on("click",function(){confirm("Are you sure you want to delete?")&&$.ajax({method:"POST",url:"/admin/user/delete",data:{userId:$(this).attr("data-id")}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$("#userEditForm").validator().on("submit",function(e){e.isDefaultPrevented()||(e.preventDefault(),$.ajax({method:"POST",url:"/admin/user/update",data:{userId:$("#userId").val(),usersName:$("#usersName").val(),userEmail:$("#userEmail").val(),userPassword:$("#userPassword").val(),userAdmin:$("#userPassword").is(":checked")}}).done(function(e){showNotification(e.message,"success")}).fail(function(e){showNotification(e.responseJSON.message,"danger")}))}),$("#productNewForm").validator().on("submit",function(e){e.isDefaultPrevented()||(e.preventDefault(),""===$("#productPermalink").val()&&""!==$("#productTitle").val()&&$("#productPermalink").val(slugify($("#productTitle").val())),$.ajax({method:"POST",url:"/admin/product/insert",data:{productTitle:$("#productTitle").val(),productPrice:$("#productPrice").val(),productPublished:$("#productPublished").val(),productStock:$("#productStock").val(),productDescription:$("#productDescription").val(),productPermalink:$("#productPermalink").val(),productOptions:$("#productOptions").val(),productSubscription:$("#productSubscription").val(),productComment:$("#productComment").is(":checked"),productTags:$("#productTags").val()}}).done(function(e){showNotification(e.message,"success",!1,"/admin/product/edit/"+e.productId)}).fail(function(e){showNotification(e.responseJSON.message,"danger")}))}),$("#productEditForm").validator().on("submit",function(e){e.isDefaultPrevented()||(e.preventDefault(),""===$("#productPermalink").val()&&""!==$("#productTitle").val()&&$("#productPermalink").val(slugify($("#productTitle").val())),$.ajax({method:"POST",url:"/admin/product/update",data:{productId:$("#productId").val(),productTitle:$("#productTitle").val(),productPrice:$("#productPrice").val(),productPublished:$("#productPublished").val(),productStock:$("#productStock").val(),productDescription:$("#productDescription").val(),productPermalink:$("#productPermalink").val(),productOptions:$("#productOptions").val(),productSubscription:$("#productSubscription").val(),productComment:$("#productComment").is(":checked"),productTags:$("#productTags").val()}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")}))}),$(".set-as-main-image").on("click",function(){$.ajax({method:"POST",url:"/admin/product/setasmainimage",data:{product_id:$("#productId").val(),productImage:$(this).attr("data-id")}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$(".btn-delete-image").on("click",function(){confirm("Are you sure you want to delete this image?")&&$.ajax({method:"POST",url:"/admin/product/deleteimage",data:{product_id:$("#productId").val(),productImage:$(this).attr("data-id")}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$(".btn-delete-product").on("click",function(){confirm("Are you sure you want to delete this product?")&&$.ajax({method:"POST",url:"/admin/product/delete",data:{productId:$(this).attr("data-id")}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$(document).on("click","#validate_permalink",function(e){""!==$("#productPermalink").val()?$.ajax({method:"POST",url:"/admin/api/validate_permalink",data:{permalink:$("#productPermalink").val(),docId:$("#productId").val()}}).done(function(e){showNotification(e.message,"success")}).fail(function(e){showNotification(e.responseJSON.message,"danger")}):showNotification("Please enter a permalink to validate","danger")}),$(document).on("click","#btn_product_filter",function(e){""!==$("#product_filter").val()?window.location.href="/admin/products/filter/"+$("#product_filter").val():showNotification("Please enter a keyword to filter","danger")}),$(document).on("click","#btn_order_filter",function(e){""!==$("#order_filter").val()?window.location.href="/admin/orders/filter/"+$("#order_filter").val():showNotification("Please enter a keyword to filter","danger")}),$(document).on("click","#btn_customer_filter",function(e){""!==$("#customer_filter").val()?window.location.href="/admin/customers/filter/"+$("#customer_filter").val():showNotification("Please enter a keyword to filter","danger")}),$("#sendTestEmail").on("click",function(e){e.preventDefault(),$.ajax({method:"POST",url:"/admin/testEmail"}).done(function(e){showNotification(e,"success")}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$(document).on("click",".orderFilterByStatus",function(e){e.preventDefault(),window.location="/admin/orders/bystatus/"+$("#orderStatusFilter").val()}),$('input[class="published_state"]').change(function(){$.ajax({method:"POST",url:"/admin/product/published_state",data:{id:this.id,state:this.checked}}).done(function(e){showNotification(e.message,"success")}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$("#updateCustomer").validator().on("click",function(e){e.preventDefault(),0===$("#customer-form").validator("validate").has(".has-error").length&&$.ajax({method:"POST",url:"/admin/customer/update",data:{customerId:$("#customerId").val(),email:$("#email").val(),firstName:$("#firstName").val(),lastName:$("#lastName").val(),address1:$("#address1").val(),address2:$("#address2").val(),country:$("#country").val(),state:$("#state").val(),postcode:$("#postcode").val(),phone:$("#phone").val()}}).done(function(e){showNotification(e.message,"success")}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$("#deleteCustomer").on("click",function(e){e.preventDefault(),$.ajax({method:"DELETE",url:"/admin/customer",data:{customerId:$("#customerId").val()}}).done(function(e){showNotification(e.message,"success",!1,"/admin/customers")}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$("#footerHtml").length){var e=window.CodeMirror.fromTextArea(document.getElementById("footerHtml"),{mode:"xml",tabMode:"indent",theme:"flatly",lineNumbers:!0,htmlMode:!0,fixedGutter:!1});e.setValue(e.getValue())}if($("#googleAnalytics").length&&window.CodeMirror.fromTextArea(document.getElementById("googleAnalytics"),{mode:"xml",tabMode:"indent",theme:"flatly",lineNumbers:!0,htmlMode:!0,fixedGutter:!1}),$("#customCss").length){var t=window.CodeMirror.fromTextArea(document.getElementById("customCss"),{mode:"text/css",tabMode:"indent",theme:"flatly",lineNumbers:!0}),o=window.cssbeautify(t.getValue(),{indent:" ",autosemicolon:!0});t.setValue(o)}$(document).on("click","#btnPageUpdate",function(e){e.preventDefault(),$.ajax({method:"POST",url:"/admin/settings/page",data:{pageId:$("#pageId").val(),pageName:$("#pageName").val(),pageSlug:$("#pageSlug").val(),pageEnabled:$("#pageEnabled").is(":checked"),pageContent:$("#pageContent").val()}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$(document).on("click","#btnPageDelete",function(e){e.preventDefault(),confirm("Are you sure?")&&$.ajax({method:"POST",url:"/admin/settings/page/delete",data:{pageId:$(this).attr("data-id")}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.message,"danger",!0)})}),$(document).on("click","#settings-menu-new",function(e){e.preventDefault(),$.ajax({method:"POST",url:"/admin/settings/menu/new",data:{navMenu:$("#newNavMenu").val(),navLink:$("#newNavLink").val()}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.message,"danger",!0)})}),$(document).on("click","#settings-menu-update",function(e){e.preventDefault();var t=$(this).attr("data-id"),o=$("#menuId-"+t);$.ajax({method:"POST",url:"/admin/settings/menu/update",data:{navId:o.find(".navId").val(),navMenu:o.find(".navMenu").val(),navLink:o.find(".navLink").val()}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.message,"danger",!0)})}),$(document).on("click",".settings-menu-delete",function(e){e.preventDefault(),confirm("Are you sure?")&&$.ajax({method:"POST",url:"/admin/settings/menu/delete",data:{menuId:$(this).attr("data-id")}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.message,"danger",!0)})}),$("#draggable_list").length&&$("#draggable_list").sortable({update:function(){var e=[];$(".navId").each(function(t){e.push($($(".navId")[t]).val())}),$.ajax({data:{order:e},type:"POST",url:"/admin/settings/menu/save_order"}).done(function(){showNotification("Menu order saved","success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger",!0)})}}),$(document).on("click","#uploadButton",function(e){e.preventDefault();var t=new FormData($("#uploadForm")[0]);t.append("productId",$("#productId").val()),$.ajax({method:"POST",url:"/admin/file/upload",processData:!1,contentType:!1,cache:!1,data:t}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})})}); \ No newline at end of file +$(document).ready(function(){if($(document).on("click","#btnGenerateAPIkey",function(e){e.preventDefault(),$.ajax({method:"POST",url:"/admin/createApiKey"}).done(function(e){$("#apiKey").val(e.apiKey),showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$(document).on("click",".product_opt_remove",function(e){e.preventDefault();var t=$(this).closest("li").find(".opt-name").html();$.ajax({method:"POST",url:"/admin/product/removeoption",data:{productId:$("#productId").val(),optName:t}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$(document).on("click","#product_opt_add",function(e){e.preventDefault();var t=$("#product_optName").val(),o=$("#product_optLabel").val(),a=$("#product_optType").val(),n=$("#product_optOptions").val(),i={};""!==$("#productOptions").val()&&'"{}"'!==$("#productOptions").val()&&(i=JSON.parse($("#productOptions").val()));var s='
  • ';s+='
    ',s+='
    '+t+"
    ",s+='
    '+o+"
    ",s+='
    '+a+"
    ",s+='
    '+n+"
    ",s+='
    ',s+='',s+="
  • ",$("#product_opt_wrapper").append(s),i[t]={optName:t,optLabel:o,optType:a,optOptions:$.grep(n.split(","),function(e){return 0===e||e})},$("#productOptions").val(JSON.stringify(i)),$("#product_optName").val(""),$("#product_optLabel").val(""),$("#product_optOptions").val("")}),$("#settingsForm").validator().on("submit",function(e){e.isDefaultPrevented()||(e.preventDefault(),$("#footerHtml_input").val($(".CodeMirror")[0].CodeMirror.getValue()),$("#googleAnalytics_input").val($(".CodeMirror")[1].CodeMirror.getValue()),$("#customCss_input").val($(".CodeMirror")[2].CodeMirror.getValue()),$.ajax({method:"POST",url:"/admin/settings/update",data:$("#settingsForm").serialize()}).done(function(e){showNotification(e.message,"success")}).fail(function(e){showNotification(e.responseJSON.message,"danger")}))}),$(document).on("click","#orderStatusUpdate",function(e){$.ajax({method:"POST",url:"/admin/order/statusupdate",data:{order_id:$("#order_id").val(),status:$("#orderStatus").val()}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$("#userNewForm").validator().on("submit",function(e){e.isDefaultPrevented()||(e.preventDefault(),$.ajax({method:"POST",url:"/admin/user/insert",data:{usersName:$("#usersName").val(),userEmail:$("#userEmail").val(),userPassword:$("#userPassword").val()}}).done(function(e){showNotification(e.message,"success",!1,"/admin/user/edit/"+e.userId)}).fail(function(e){showNotification(e.responseJSON.message,"danger")}))}),$(".userDelete").on("click",function(){confirm("Are you sure you want to delete?")&&$.ajax({method:"POST",url:"/admin/user/delete",data:{userId:$(this).attr("data-id")}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$("#userEditForm").validator().on("submit",function(e){e.isDefaultPrevented()||(e.preventDefault(),$.ajax({method:"POST",url:"/admin/user/update",data:{userId:$("#userId").val(),usersName:$("#usersName").val(),userEmail:$("#userEmail").val(),userPassword:$("#userPassword").val(),userAdmin:$("#userPassword").is(":checked")}}).done(function(e){showNotification(e.message,"success")}).fail(function(e){showNotification(e.responseJSON.message,"danger")}))}),$("#productNewForm").validator().on("submit",function(e){e.isDefaultPrevented()||(e.preventDefault(),""===$("#productPermalink").val()&&""!==$("#productTitle").val()&&$("#productPermalink").val(slugify($("#productTitle").val())),$.ajax({method:"POST",url:"/admin/product/insert",data:{productTitle:$("#productTitle").val(),productPrice:$("#productPrice").val(),productPublished:$("#productPublished").val(),productStock:$("#productStock").val(),productDescription:$("#productDescription").val(),productPermalink:$("#productPermalink").val(),productOptions:$("#productOptions").val(),productSubscription:$("#productSubscription").val(),productComment:$("#productComment").is(":checked"),productTags:$("#productTags").val()}}).done(function(e){showNotification(e.message,"success",!1,"/admin/product/edit/"+e.productId)}).fail(function(e){showNotification(e.responseJSON.message,"danger")}))}),$("#productEditForm").validator().on("submit",function(e){e.isDefaultPrevented()||(e.preventDefault(),""===$("#productPermalink").val()&&""!==$("#productTitle").val()&&$("#productPermalink").val(slugify($("#productTitle").val())),$.ajax({method:"POST",url:"/admin/product/update",data:{productId:$("#productId").val(),productTitle:$("#productTitle").val(),productPrice:$("#productPrice").val(),productPublished:$("#productPublished").val(),productStock:$("#productStock").val(),productDescription:$("#productDescription").val(),productPermalink:$("#productPermalink").val(),productOptions:$("#productOptions").val(),productSubscription:$("#productSubscription").val(),productComment:$("#productComment").is(":checked"),productTags:$("#productTags").val()}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")}))}),$(".set-as-main-image").on("click",function(){$.ajax({method:"POST",url:"/admin/product/setasmainimage",data:{product_id:$("#productId").val(),productImage:$(this).attr("data-id")}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$(".btn-delete-image").on("click",function(){confirm("Are you sure you want to delete this image?")&&$.ajax({method:"POST",url:"/admin/product/deleteimage",data:{product_id:$("#productId").val(),productImage:$(this).attr("data-id")}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$(".btn-delete-product").on("click",function(){confirm("Are you sure you want to delete this product?")&&$.ajax({method:"POST",url:"/admin/product/delete",data:{productId:$(this).attr("data-id")}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$(document).on("click","#validate_permalink",function(e){""!==$("#productPermalink").val()?$.ajax({method:"POST",url:"/admin/api/validate_permalink",data:{permalink:$("#productPermalink").val(),docId:$("#productId").val()}}).done(function(e){showNotification(e.message,"success")}).fail(function(e){showNotification(e.responseJSON.message,"danger")}):showNotification("Please enter a permalink to validate","danger")}),$(document).on("click","#btn_product_filter",function(e){""!==$("#product_filter").val()?window.location.href="/admin/products/filter/"+$("#product_filter").val():showNotification("Please enter a keyword to filter","danger")}),$(document).on("click","#btn_order_filter",function(e){""!==$("#order_filter").val()?window.location.href="/admin/orders/filter/"+$("#order_filter").val():showNotification("Please enter a keyword to filter","danger")}),$(document).on("click","#btn_customer_filter",function(e){""!==$("#customer_filter").val()?window.location.href="/admin/customers/filter/"+$("#customer_filter").val():showNotification("Please enter a keyword to filter","danger")}),$(document).on("click","#lookupCustomer",function(e){e.preventDefault(),$.ajax({method:"POST",url:"/admin/customer/lookup",data:{customerEmail:$("#customerEmail").val()}}).done(function(e){showNotification(e.message,"success"),$("#orderFirstName").val(e.customer.firstName),$("#orderLastName").val(e.customer.lastName),$("#orderAddress1").val(e.customer.address1),$("#orderAddress2").val(e.customer.address2),$("#orderCountry").val(e.customer.country),$("#orderState").val(e.customer.state),$("#orderPostcode").val(e.customer.postcode),$("#orderPhone").val(e.customer.phone)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$(document).on("click","#orderCreate",function(e){e.preventDefault(),0===$("#createOrderForm").validator("validate").has(".has-error").length&&$.ajax({method:"POST",url:"/admin/order/create",data:{orderStatus:$("#orderStatus").val(),email:$("#customerEmail").val(),firstName:$("#orderFirstName").val(),lastName:$("#orderLastName").val(),address1:$("#orderAddress1").val(),address2:$("#orderAddress2").val(),country:$("#orderCountry").val(),state:$("#orderState").val(),postcode:$("#orderPostcode").val(),phone:$("#orderPhone").val(),orderComment:$("#orderComment").val()}}).done(function(e){showNotification(e.message,"success"),window.location=`/admin/order/view/${e.orderId}`}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$("#sendTestEmail").on("click",function(e){e.preventDefault(),$.ajax({method:"POST",url:"/admin/testEmail"}).done(function(e){showNotification(e,"success")}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$(document).on("click",".orderFilterByStatus",function(e){e.preventDefault(),window.location="/admin/orders/bystatus/"+$("#orderStatusFilter").val()}),$('input[class="published_state"]').change(function(){$.ajax({method:"POST",url:"/admin/product/published_state",data:{id:this.id,state:this.checked}}).done(function(e){showNotification(e.message,"success")}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$("#updateCustomer").validator().on("click",function(e){e.preventDefault(),0===$("#customer-form").validator("validate").has(".has-error").length&&$.ajax({method:"POST",url:"/admin/customer/update",data:{customerId:$("#customerId").val(),email:$("#email").val(),firstName:$("#firstName").val(),lastName:$("#lastName").val(),address1:$("#address1").val(),address2:$("#address2").val(),country:$("#country").val(),state:$("#state").val(),postcode:$("#postcode").val(),phone:$("#phone").val()}}).done(function(e){showNotification(e.message,"success")}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$("#deleteCustomer").on("click",function(e){e.preventDefault(),$.ajax({method:"DELETE",url:"/admin/customer",data:{customerId:$("#customerId").val()}}).done(function(e){showNotification(e.message,"success",!1,"/admin/customers")}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$("#footerHtml").length){var e=window.CodeMirror.fromTextArea(document.getElementById("footerHtml"),{mode:"xml",tabMode:"indent",theme:"flatly",lineNumbers:!0,htmlMode:!0,fixedGutter:!1});e.setValue(e.getValue())}if($("#googleAnalytics").length&&window.CodeMirror.fromTextArea(document.getElementById("googleAnalytics"),{mode:"xml",tabMode:"indent",theme:"flatly",lineNumbers:!0,htmlMode:!0,fixedGutter:!1}),$("#customCss").length){var t=window.CodeMirror.fromTextArea(document.getElementById("customCss"),{mode:"text/css",tabMode:"indent",theme:"flatly",lineNumbers:!0}),o=window.cssbeautify(t.getValue(),{indent:" ",autosemicolon:!0});t.setValue(o)}$(document).on("click","#btnPageUpdate",function(e){e.preventDefault(),$.ajax({method:"POST",url:"/admin/settings/page",data:{pageId:$("#pageId").val(),pageName:$("#pageName").val(),pageSlug:$("#pageSlug").val(),pageEnabled:$("#pageEnabled").is(":checked"),pageContent:$("#pageContent").val()}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})}),$(document).on("click","#btnPageDelete",function(e){e.preventDefault(),confirm("Are you sure?")&&$.ajax({method:"POST",url:"/admin/settings/page/delete",data:{pageId:$(this).attr("data-id")}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.message,"danger",!0)})}),$(document).on("click","#settings-menu-new",function(e){e.preventDefault(),$.ajax({method:"POST",url:"/admin/settings/menu/new",data:{navMenu:$("#newNavMenu").val(),navLink:$("#newNavLink").val()}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.message,"danger",!0)})}),$(document).on("click","#settings-menu-update",function(e){e.preventDefault();var t=$(this).attr("data-id"),o=$("#menuId-"+t);$.ajax({method:"POST",url:"/admin/settings/menu/update",data:{navId:o.find(".navId").val(),navMenu:o.find(".navMenu").val(),navLink:o.find(".navLink").val()}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.message,"danger",!0)})}),$(document).on("click",".settings-menu-delete",function(e){e.preventDefault(),confirm("Are you sure?")&&$.ajax({method:"POST",url:"/admin/settings/menu/delete",data:{menuId:$(this).attr("data-id")}}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.message,"danger",!0)})}),$("#draggable_list").length&&$("#draggable_list").sortable({update:function(){var e=[];$(".navId").each(function(t){e.push($($(".navId")[t]).val())}),$.ajax({data:{order:e},type:"POST",url:"/admin/settings/menu/save_order"}).done(function(){showNotification("Menu order saved","success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger",!0)})}}),$(document).on("click","#uploadButton",function(e){e.preventDefault();var t=new FormData($("#uploadForm")[0]);t.append("productId",$("#productId").val()),$.ajax({method:"POST",url:"/admin/file/upload",processData:!1,contentType:!1,cache:!1,data:t}).done(function(e){showNotification(e.message,"success",!0)}).fail(function(e){showNotification(e.responseJSON.message,"danger")})})}); \ No newline at end of file diff --git a/routes/customer.js b/routes/customer.js index 8e05c37..04efa6f 100644 --- a/routes/customer.js +++ b/routes/customer.js @@ -285,6 +285,35 @@ router.get('/admin/customers/filter/:search', restrict, async (req, res, next) = }); }); +router.post('/admin/customer/lookup', restrict, async (req, res, next) => { + const db = req.app.db; + const customerEmail = req.body.customerEmail; + + // Search for a customer + const customer = await db.customers.findOne({ email: customerEmail }); + + if(customer){ + req.session.customerPresent = true; + req.session.customerEmail = customer.email; + req.session.customerFirstname = customer.firstName; + req.session.customerLastname = customer.lastName; + req.session.customerAddress1 = customer.address1; + req.session.customerAddress2 = customer.address2; + req.session.customerCountry = customer.country; + req.session.customerState = customer.state; + req.session.customerPostcode = customer.postcode; + req.session.customerPhone = customer.phone; + + return res.status(200).json({ + message: 'Customer found', + customer + }); + } + return res.status(400).json({ + message: 'No customers found' + }); +}); + // login the customer and check the password router.post('/customer/login_action', async (req, res) => { const db = req.app.db; @@ -451,18 +480,7 @@ router.post('/customer/reset/:token', async (req, res) => { // logout the customer router.post('/customer/logout', (req, res) => { // Clear our session - req.session.customerPresent = null; - req.session.customerEmail = null; - req.session.customerFirstname = null; - req.session.customerLastname = null; - req.session.customerAddress1 = null; - req.session.customerAddress2 = null; - req.session.customerCountry = null; - req.session.customerState = null; - req.session.customerPostcode = null; - req.session.customerPhone = null; - req.session.orderComment = null; - + common.clearCustomer(req); res.status(200).json({}); }); diff --git a/routes/order.js b/routes/order.js index 50ec4fd..91db979 100644 --- a/routes/order.js +++ b/routes/order.js @@ -1,5 +1,13 @@ const express = require('express'); -const common = require('../lib/common'); +const { + clearSessionValue, + emptyCart, + getCountryList, + getId, + sendEmail, + getEmailTemplate, + clearCustomer +} = require('../lib/common'); const { restrict, checkAccess } = require('../lib/auth'); const { indexOrders } = require('../lib/indexing'); const router = express.Router(); @@ -25,8 +33,8 @@ router.get('/admin/orders', restrict, async (req, res, next) => { admin: true, config: req.app.config, session: req.session, - message: common.clearSessionValue(req.session, 'message'), - messageType: common.clearSessionValue(req.session, 'messageType'), + message: clearSessionValue(req.session, 'message'), + messageType: clearSessionValue(req.session, 'messageType'), helpers: req.handlebars.helpers }); }); @@ -60,8 +68,8 @@ router.get('/admin/orders/bystatus/:orderstatus', restrict, async (req, res, nex filteredStatus: req.params.orderstatus, config: req.app.config, session: req.session, - message: common.clearSessionValue(req.session, 'message'), - messageType: common.clearSessionValue(req.session, 'messageType'), + message: clearSessionValue(req.session, 'message'), + messageType: clearSessionValue(req.session, 'messageType'), helpers: req.handlebars.helpers }); }); @@ -69,21 +77,120 @@ router.get('/admin/orders/bystatus/:orderstatus', restrict, async (req, res, nex // render the editor router.get('/admin/order/view/:id', restrict, async (req, res) => { const db = req.app.db; - const order = await db.orders.findOne({ _id: common.getId(req.params.id) }); + const order = await db.orders.findOne({ _id: getId(req.params.id) }); res.render('order', { title: 'View order', result: order, config: req.app.config, session: req.session, - message: common.clearSessionValue(req.session, 'message'), - messageType: common.clearSessionValue(req.session, 'messageType'), + message: clearSessionValue(req.session, 'message'), + messageType: clearSessionValue(req.session, 'messageType'), editor: true, admin: true, helpers: req.handlebars.helpers }); }); +// render the editor +router.get('/admin/order/create', restrict, async (req, res) => { + res.render('order-create', { + title: 'Create order', + config: req.app.config, + session: req.session, + message: clearSessionValue(req.session, 'message'), + messageType: clearSessionValue(req.session, 'messageType'), + countryList: getCountryList(), + editor: true, + admin: true, + helpers: req.handlebars.helpers + }); +}); + +router.post('/admin/order/create', async (req, res, next) => { + const db = req.app.db; + const config = req.app.config; + + // Check if cart is empty + if(!req.session.cart){ + res.status(400).json({ + message: 'The cart is empty. You will need to add items to the cart first.' + }); + } + + const orderDoc = { + orderPaymentId: getId(), + orderPaymentGateway: 'Instore', + orderPaymentMessage: 'Your payment was successfully completed', + orderTotal: req.session.totalCartAmount, + orderItemCount: req.session.totalCartItems, + orderProductCount: req.session.totalCartProducts, + orderEmail: req.body.email || req.session.customerEmail, + orderFirstname: req.body.firstName || req.session.customerFirstname, + orderLastname: req.body.lastName || req.session.customerLastname, + orderAddr1: req.body.address1 || req.session.customerAddress1, + orderAddr2: req.body.address2 || req.session.customerAddress2, + orderCountry: req.body.country || req.session.customerCountry, + orderState: req.body.state || req.session.customerState, + orderPostcode: req.body.postcode || req.session.customerPostcode, + orderPhoneNumber: req.body.phone || req.session.customerPhone, + orderComment: req.body.orderComment || req.session.orderComment, + orderStatus: req.body.orderStatus, + orderDate: new Date(), + orderProducts: req.session.cart, + orderType: 'Single' + }; + + // insert order into DB + try{ + const newDoc = await db.orders.insertOne(orderDoc); + + // get the new ID + const orderId = newDoc.insertedId; + + // add to lunr index + indexOrders(req.app) + .then(() => { + // set the results + req.session.messageType = 'success'; + req.session.message = 'Your order was successfully placed. Payment for your order will be completed instore.'; + req.session.paymentEmailAddr = newDoc.ops[0].orderEmail; + req.session.paymentApproved = true; + req.session.paymentDetails = `

    Order ID: ${orderId}

    +

    Transaction ID: ${orderDoc.orderPaymentId}

    `; + + // set payment results for email + const paymentResults = { + message: req.session.message, + messageType: req.session.messageType, + paymentEmailAddr: req.session.paymentEmailAddr, + paymentApproved: true, + paymentDetails: req.session.paymentDetails + }; + + // clear the cart + if(req.session.cart){ + emptyCart(req, res, 'function'); + } + + // Clear customer session + clearCustomer(req); + + // send the email with the response + // TODO: Should fix this to properly handle result + sendEmail(req.session.paymentEmailAddr, `Your order with ${config.cartTitle}`, getEmailTemplate(paymentResults)); + + // redirect to outcome + res.status(200).json({ + message: 'Order created successfully', + orderId + }); + }); + }catch(ex){ + res.status(400).json({ err: 'Your order declined. Please try again' }); + } +}); + // Admin section router.get('/admin/orders/filter/:search', restrict, async (req, res, next) => { const db = req.app.db; @@ -92,7 +199,7 @@ router.get('/admin/orders/filter/:search', restrict, async (req, res, next) => { const lunrIdArray = []; ordersIndex.search(searchTerm).forEach((id) => { - lunrIdArray.push(common.getId(id.ref)); + lunrIdArray.push(getId(id.ref)); }); // we search on the lunr indexes @@ -113,8 +220,8 @@ router.get('/admin/orders/filter/:search', restrict, async (req, res, next) => { config: req.app.config, session: req.session, searchTerm: searchTerm, - message: common.clearSessionValue(req.session, 'message'), - messageType: common.clearSessionValue(req.session, 'messageType'), + message: clearSessionValue(req.session, 'message'), + messageType: clearSessionValue(req.session, 'messageType'), helpers: req.handlebars.helpers }); }); @@ -125,7 +232,7 @@ router.get('/admin/order/delete/:id', restrict, async(req, res) => { // remove the order try{ - await db.orders.deleteOne({ _id: common.getId(req.params.id) }); + await db.orders.deleteOne({ _id: getId(req.params.id) }); // remove the index indexOrders(req.app) @@ -163,7 +270,7 @@ router.post('/admin/order/statusupdate', restrict, checkAccess, async (req, res) const db = req.app.db; try{ await db.orders.updateOne({ - _id: common.getId(req.body.order_id) }, + _id: getId(req.body.order_id) }, { $set: { orderStatus: req.body.status } }, { multi: false }); return res.status(200).json({ message: 'Status successfully updated' }); diff --git a/views/order-create.hbs b/views/order-create.hbs new file mode 100644 index 0000000..fdaec35 --- /dev/null +++ b/views/order-create.hbs @@ -0,0 +1,116 @@ +{{> partials/menu}} +
    +
    +

    Create Order

    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + +
    + +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    +
    + {{#if session.cart}} + {{> (getTheme 'cart')}} + {{else}} + + {{/if}} +
    +
    +
    +
    \ No newline at end of file diff --git a/views/partials/menu.hbs b/views/partials/menu.hbs index 903dcba..ff77fb9 100644 --- a/views/partials/menu.hbs +++ b/views/partials/menu.hbs @@ -8,7 +8,8 @@ {{/ifCond}}
  •   {{ @root.__ "List" }}
  • Orders
  • -
  •   {{ @root.__ "List" }}
  • +
  •   {{ @root.__ "List" }}
  • +
  •   {{ @root.__ "Create" }}
  • Customers
  •   {{ @root.__ "List" }}
  • Users