Author: jcouteau Date: 2013-08-30 16:05:35 +0200 (Fri, 30 Aug 2013) New Revision: 389 Url: http://chorem.org/projects/chorem/repository/revisions/389 Log: Use angular to power up sales funnel Added: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-cancel.html trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-draftToSent.html trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-leadToDraft.html trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-sentToAccepted.html trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-sentToRejected.html trunk/chorem-webmotion/src/main/webapp/js/salesFunnel.js Modified: trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/sales/SalesAction.java trunk/chorem-webmotion/src/main/resources/mapping trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/salesFunnel.jsp trunk/chorem-webmotion/src/main/webapp/js/chorem.js Modified: trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/sales/SalesAction.java =================================================================== --- trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/sales/SalesAction.java 2013-08-16 09:51:45 UTC (rev 388) +++ trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/sales/SalesAction.java 2013-08-30 14:05:35 UTC (rev 389) @@ -32,10 +32,12 @@ import org.chorem.entities.Sent; import org.chorem.entities.Started; import org.chorem.entities.Cancelled; +import org.chorem.webmotion.render.RenderWikitty; import org.chorem.webmotion.render.RenderWikittyJson; import org.debux.webmotion.server.WebMotionController; import org.debux.webmotion.server.render.Render; import org.nuiton.wikitty.WikittyUtil; +import org.nuiton.wikitty.entities.Wikitty; import java.text.ParseException; import java.util.Date; @@ -85,14 +87,14 @@ getContext().addInfoMessage("message", "Warning: Could not parse date " + rejectedDate); } client.store(rejected); - return new RenderWikittyJson(rejected); + return new RenderWikitty().setModelWikitty((Wikitty) rejected); } public Render start(ChoremClient client, String id) { Started started = client.restore(Started.class, id); started.setStartedDate(new Date()); client.store(started); - return new RenderWikittyJson(started); + return new RenderWikitty().setModelWikitty((Wikitty)started); } public Render answer(ChoremClient client, String id, String sendingDate, @@ -106,7 +108,8 @@ } draft.setReference(reference); draft = client.store(draft); - return new RenderWikittyJson(draft); + Wikitty w = client.castTo(Wikitty.class, draft); + return new RenderWikitty().setModelWikitty(w); } public Render cancel(ChoremClient client, String id, String cancelledDate, Modified: trunk/chorem-webmotion/src/main/resources/mapping =================================================================== --- trunk/chorem-webmotion/src/main/resources/mapping 2013-08-16 09:51:45 UTC (rev 388) +++ trunk/chorem-webmotion/src/main/resources/mapping 2013-08-30 14:05:35 UTC (rev 389) @@ -10,6 +10,7 @@ * /wikitty-json/* DecoratorFilter.decorate wmDecoratorNo=true * /fragment/* DecoratorFilter.decorate wmDecoratorNo=true * /sales/funnel/json/* DecoratorFilter.decorate wmDecoratorNo=true +* /sales/funnel/partial/* DecoratorFilter.decorate wmDecoratorNo=true * /project/json/* DecoratorFilter.decorate wmDecoratorNo=true * /hr/employeeEdit/json/* DecoratorFilter.decorate wmDecoratorNo=true * /ascii/* DecoratorFilter.decorate wmDecoratorNo=true @@ -74,6 +75,11 @@ * /sales/report/salesPerAccount action:sales.SalesPerAccountReportAction.sales * /sales/report/salesPerAccount/{account} action:sales.AccountSalesReportAction.sales * /sales/funnel action:sales.FunnelAction.funnel +* /sales/funnel/partial/dialog-leadToDraft.html view:salesReports/dialog-leadToDraft.html +* /sales/funnel/partial/dialog-draftToSent.html view:salesReports/dialog-draftToSent.html +* /sales/funnel/partial/dialog-sentToAccepted.html view:salesReports/dialog-sentToAccepted.html +* /sales/funnel/partial/dialog-sentToRejected.html view:salesReports/dialog-sentToRejected.html +* /sales/funnel/partial/dialog-cancel.html view:salesReports/dialog-cancel.html * /sales/funnel/json/{method} action:sales.SalesAction.{method} * /sales/funnel/json/{method}/{id} action:sales.SalesAction.{method} * /project action:project.DashboardProjectAction.requestProject Added: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-cancel.html =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-cancel.html (rev 0) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-cancel.html 2013-08-30 14:05:35 UTC (rev 389) @@ -0,0 +1,17 @@ +<div class="modal-header" title="Proposition commerciale annulée"> + <h3>Proposition commerciale annulée</h3> +</div> +<div class="modal-body"> + <form class="form-horizontal"> + <fieldset> + <label for="cancelledDate">Date d'annulation</label> + <input type="text" ui-date ui-date-format="dd/mm/yy" ng-model="lead.cancelledDate" id="cancelledDate" class="datepicker" /> + <label for="cancelledReason">Raison</label> + <input type="text" ng-model="lead.cancelledReason" name="cancelledReason" id="cancelledReason" value="" class="text ui-widget-content ui-corner-all" /> + </fieldset> + </form> +</div> +<div class="modal-footer"> + <button ng-click="cancel()">Annuler</button> + <button ng-click="validate()">Valider</button> +</div> \ No newline at end of file Added: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-draftToSent.html =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-draftToSent.html (rev 0) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-draftToSent.html 2013-08-30 14:05:35 UTC (rev 389) @@ -0,0 +1,15 @@ +<div class="modal-header" title="Proposition commerciale envoyée"> + <h3>Proposition commerciale envoyée</h3> +</div> +<div class="modal-body"> + <form class="form-horizontal"> + <fieldset> + <label for="sendDate">Date d'envoirrrrrrrrrrrr</label> + <input type="text" ui-date ng-model="draft.sendingDate" id="sendDate" class="datepicker" /> + </fieldset> + </form> +</div> +<div class="modal-footer"> + <button ng-click="cancel()">Annuler</button> + <button ng-click="validate()">Envoyer</button> +</div> \ No newline at end of file Added: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-leadToDraft.html =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-leadToDraft.html (rev 0) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-leadToDraft.html 2013-08-30 14:05:35 UTC (rev 389) @@ -0,0 +1,17 @@ +<div class="modal-header" title="Proposition commerciale à envoyer"> + <h3>Proposition commerciale à envoyer</h3> +</div> +<div class="modal-body"> + <form class="form-horizontal"> + <fieldset> + <label for="sendingDate">Date d'envoi</label> + <input type="text" ui-date ui-date-format="dd/mm/yy" ng-model="lead.sendingDate" id="sendingDate" class="datepicker" /> + <label for="reference">Référence</label> + <input type="text" ng-model="lead.reference" id="reference" class="text ui-widget-content ui-corner-all" /> + </fieldset> + </form> +</div> +<div class="modal-footer"> + <button ng-click="cancel()">Annuler</button> + <button ng-click="validate()">Envoyer</button> +</div> \ No newline at end of file Added: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-sentToAccepted.html =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-sentToAccepted.html (rev 0) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-sentToAccepted.html 2013-08-30 14:05:35 UTC (rev 389) @@ -0,0 +1,15 @@ +<div class="modal-header" title="Proposition commerciale acceptée"> + <h3>Proposition commerciale acceptée</h3> +</div> +<div class="modal-body"> + <form class="form-horizontal"> + <fieldset> + <label for="acceptedDate">Date d'acceptation</label> + <input type="text" ui-date ui-date-format="dd/mm/yy" ng-model="sent.acceptedDate" id="acceptedDate" class="datepicker" /> + </fieldset> + </form> +</div> +<div class="modal-footer"> + <button ng-click="cancel()">Annuler</button> + <button ng-click="validate()">Accepter</button> +</div> \ No newline at end of file Added: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-sentToRejected.html =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-sentToRejected.html (rev 0) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/dialog-sentToRejected.html 2013-08-30 14:05:35 UTC (rev 389) @@ -0,0 +1,15 @@ +<div class="modal-header" title="Proposition commerciale rejetée"> + <h3>Proposition commerciale rejetée</h3> +</div> +<div class="modal-body"> + <form class="form-horizontal"> + <fieldset> + <label for="rejectedDate">Date de rejet</label> + <input type="text" ui-date ui-date-format="dd/mm/yy" ng-model="sent.rejectedDate" id="rejectedDate" class="datepicker" /> + </fieldset> + </form> +</div> +<div class="modal-footer"> + <button ng-click="cancel()">Annuler</button> + <button ng-click="validate()">Rejeter</button> +</div> \ No newline at end of file Modified: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/salesFunnel.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/salesFunnel.jsp 2013-08-16 09:51:45 UTC (rev 388) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/salesFunnel.jsp 2013-08-30 14:05:35 UTC (rev 389) @@ -27,11 +27,17 @@ <head> <link rel="stylesheet/less" href="<c:url value='/css/chorem-sales.css'/>"> + <script type="text/javascript" src="<c:url value='/js/salesFunnel.js'/>"></script> + <script type="text/javascript" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.5.0.js"></script> + <script type="text/javascript" src="https://raw.github.com/angular-ui/ui-date/master/src/date.js"></script> </head> <body> -<div class="row-fluid"> +<div ng-app="salesFunnel"> + +<div class="row-fluid" ng-controller="salesFunnelController"> + <ul id="funnelTabs" class="nav nav-tabs" data-tabs="funnelTabs"> <li class="active" > <a href="#lead" data-toggle="tab">Leads</a> @@ -48,150 +54,87 @@ <!-- LEADS TAB --> <div class="tab-pane active" id="lead"> - <h4> Total : ${leadAmount}€ - Total espéré : ${leadAmountHope}€</h4> + <h4> Total : {{leadsAmount}}€ - Total espéré : {{leadsAmountHope}}€</h4> <ul class="unstyled leads"> - <c:forEach var="q" items="${leads}"> - <li class="salesFunnelItem"> - <div class="pull-left"> - <a href="<c:url value="/wikitty/edit/${q.wikittyId}"/>"> - <i class="icon-edit"></i> - </a> - <small> - <a href="<c:url value="/wikitty/Employee/view/${q.customer}"/>"> - <w:display wikitty="${q.wikitty}" fqfield="Quotation.customer" label=""/> - </a> - </small> - <p> - <span class="salesFunnelItemTitle"> - <a class="name-link" href="<c:url value="/wikitty/Project/view/${q.project}"/>"> - <w:display wikitty="${q.wikitty}" fqfield="Quotation.project" label=""/> - </a> - </span> - <small> - <w:display wikitty="${q.wikitty}" fqfield="Quotation.description" label=""/> - </small> - </p> - </div> - <a class="btn btn-success pull-right salesFunnelItemButton lead" wikittyId="${q.wikittyId}">Répondre</a> - <a class="btn btn-warning pull-right salesFunnelItemButton toCancelled" wikittyId="${q.wikittyId}">Annuler</a> - <div class="pull-right salesFunnelItemPrice"> - <p class="salesFunnelItemTitle"> - <w:display wikitty="${q.wikitty}" fqfield="Quotation.amount" label=""/> - </p> - <small> - <w:display wikitty="${q.wikitty}" fqfield="Quotation.category" label=""/> - - <w:display wikitty="${q.wikitty}" fqfield="Quotation.estimatedDays" label=""/>j - </small> - </div> - <div style="clear:both;"/> - </li> - </c:forEach> + <li ng-repeat="lead in leads" class="salesFunnelItem"> + <div class="pull-left"> + <a href="../wikitty/edit/{{lead.meta.id}}"/> + <i class="icon-edit"></i> + </a> + <small> + <a href="/wikitty/Employee/view/{{lead.getField('Quotation', 'customer')}}">{{lead.getField('Quotation','customer')}}</a> + </small> + <p> + <span class="salesFunnelItemTitle"> + <a class="name-link" href="/wikitty/Project/view/{{lead.getField('Quotation','project')}}"/>{{lead.getField('Quotation','projet')}}</a> + </span> - <small>{{lead.getField('Quotation','description')}}</small> + </p> + </div> + <a class="btn btn-success pull-right" ng-click="leadToDraft(lead)">Envoyer</a> + <a class="btn btn-warning pull-right" ng-click="cancel(lead)">Annuler</a> + <div class="pull-right"> + <p class="salesFunnelItemTitle">{{lead.getField('Quotation','amount')}} €</p> + <small>{{lead.getField('Quotation','category')}} - {{lead.getField('Quotation','estimatedDays')}}j - {{lead.getField('Quotation','conversionHope')}} %</small> + </div> + <div style="clear:both;"/> + </li> </ul> </div> <!-- DRAFT TAB --> <div class="tab-pane" id="draft"> - <h4>Total : <span id="draftAmount">${draftAmount}</span>€ - Total espéré : <span id="draftAmountHope">${draftAmountHope}</span>€</h4> + <h4>Total : {{draftsAmount}}€ - Total espéré : {{draftsAmountHope}}€</h4> <ul class="unstyled drafts"> - <c:forEach var="q" items="${drafts}"> - <li class="salesFunnelItem draft"> - <div class="pull-left"> - <a href="<c:url value="/wikitty/edit/${q.wikittyId}"/>"><i class="icon-edit"></i></a> - <small><a href="<c:url value="/wikitty/Employee/view/${q.customer}"/>"><w:display wikitty="${q.wikitty}" fqfield="Quotation.customer" label=""/></a></small> - <p><span class="salesFunnelItemTitle"><a class="name-link" href="<c:url value="/wikitty/Project/view/${q.project}"/>"><w:display wikitty="${q.wikitty}" fqfield="Quotation.project" label=""/></a></span> - <small><w:display wikitty="${q.wikitty}" fqfield="Quotation.description" label=""/></small></p> - </div> - <a class="btn btn-success pull-right salesFunnelItemButton draft" wikittyId="${q.wikittyId}">Envoyer</a> - <a class="btn btn-warning pull-right salesFunnelItemButton toCancelled" wikittyId="${q.wikittyId}">Annuler</a> - <div class="pull-right salesFunnelItemPrice"> - <p class="salesFunnelItemTitle"><w:display wikitty="${q.wikitty}" fqfield="Quotation.amount" label=""/></p> - <small><w:display wikitty="${q.wikitty}" fqfield="Quotation.category" label=""/> - <w:display wikitty="${q.wikitty}" fqfield="Quotation.estimatedDays" label=""/>j - <w:display wikitty="${q.wikitty}" fqfield="Quotation.conversionHope" label=""/></small> - </div> - <div style="clear:both;"/> - </li> - </c:forEach> + <li ng-repeat="draft in drafts" class="salesFunnelItem"> + <div class="pull-left"> + <a href="../wikitty/edit/{{draft.meta.id}}"/><i class="icon-edit"></i></a> + <small><a href="/wikitty/Employee/view/{{draft.getField('Quotation', 'customer')}}">{{draft.getField('Quotation','customer')}}</a></small> + <p> + <span class="salesFunnelItemTitle"> + <a class="name-link" href="/wikitty/Project/view/{{draft.getField('Quotation','project')}}"/>{{draft.getField('Quotation','projet')}}</a> + </span> - <small>{{draft.getField('Quotation','description')}}</small> + </p> + </div> + <a class="btn btn-success pull-right" ng-click="draftToSent(draft)">Envoyer</a> + <a class="btn btn-warning pull-right" ng-click="cancel(draft)">Annuler</a> + <div class="pull-right"> + <p class="salesFunnelItemTitle">{{draft.getField('Quotation','amount')}} €</p> + <small>{{draft.getField('Quotation','category')}} - {{draft.getField('Quotation','estimatedDays')}}j - {{draft.getField('Quotation','conversionHope')}} %</small> + </div> + <div style="clear:both;"/> + </li> </ul> </div> <!-- SENT TAB --> <div class="tab-pane" id="sent"> - <h4> Total : <span id="sentAmount">${sentAmount}</span>€ - Total espéré : <span id="sentAmountHope">${sentAmountHope}</span>€</h4> + <h4> Total : {{sentsAmount}}€ - Total espéré : {{sentsAmountHope}}€</h4> <ul class="unstyled sents"> - <c:forEach var="q" items="${sents}"> - <li class="salesFunnelItem sent"> - <div class="pull-left"> - <a href="<c:url value="/wikitty/edit/${q.wikittyId}"/>"><i class="icon-edit"></i></a> - <small><a href="<c:url value="/wikitty/Employee/view/${q.customer}"/>"><w:display wikitty="${q.wikitty}" fqfield="Quotation.customer" label=""/></a></small> - <p><span class="salesFunnelItemTitle"><a class="name-link" href="<c:url value="/wikitty/Project/view/${q.project}"/>"><w:display wikitty="${q.wikitty}" fqfield="Quotation.project" label=""/></a></span> - <small><w:display wikitty="${q.wikitty}" fqfield="Quotation.description" label=""/></small></p> - </div> - <a class="btn btn-success pull-right salesFunnelItemButton sent toAccepted" wikittyId="${q.wikittyId}">Accepté</a> - <a class="btn btn-danger pull-right salesFunnelItemButton sent toRejected" wikittyId="${q.wikittyId}">Rejeté</a> - <a class="btn btn-warning pull-right salesFunnelItemButton toCancelled" wikittyId="${q.wikittyId}">Annuler</a> - <div class="pull-right salesFunnelItemPrice"> - <p class="salesFunnelItemTitle"><w:display wikitty="${q.wikitty}" fqfield="Quotation.amount" label=""/></p> - <small><w:display wikitty="${q.wikitty}" fqfield="Quotation.category" label=""/> - <w:display wikitty="${q.wikitty}" fqfield="Quotation.estimatedDays" label=""/>j - <w:display wikitty="${q.wikitty}" fqfield="Quotation.conversionHope" label=""/></small> - </div> - <div style="clear:both;"/> - </li> - </c:forEach> + <li ng-repeat="sent in sents" class="salesFunnelItem"> + <div class="pull-left"> + <a href="wikitty/edit/{{sent.meta.id}}"/><i class="icon-edit"></i></a> + <small><a href="/wikitty/Employee/view/{{sent.getField('Quotation', 'customer')}}">{{sent.getField('Quotation','customer')}}</a></small> + <p> + <span> + <a class="name-link" href="/wikitty/Project/view/{{sent.getField('Quotation','project')}}"/>{{sent.getField('Quotation','projet')}}</a> + </span> - <small>{{sent.getField('Quotation','description')}}</small> + </p> + </div> + <a class="btn btn-success pull-right" ng-click="sentToAccepted(sent)">Accepté</a> + <a class="btn btn-danger pull-right" ng-click="sentToRejected(sent)">Rejeté</a> + <a class="btn btn-warning pull-right" ng-click="cancel(sent)">Annuler</a> + <div class="pull-right"> + <p class="salesFunnelItemTitle">{{sent.getField('Quotation','amount')}} €</p> + <small>{{sent.getField('Quotation','category')}} - {{sent.getField('Quotation','estimatedDays')}}j - {{sent.getField('Quotation','conversionHope')}} %</small> + </div> + <div style="clear:both;"/> + </li> </ul> </div> - - <div id="dialog-form-leadToDraft" title="Proposition commerciale à envoyer"> - <form> - <fieldset> - <label for="sendingDate">Date d'envoi</label> - <input type="text" name="sendingDate" id="sendingDate" class="datepicker" /> - <label for="reference">Référence</label> - <input type="text" name="reference" id="reference" value="" class="text ui-widget-content ui-corner-all" /> - <input type="hidden" name="id" id="lead-wikittyId"/> - </fieldset> - </form> - </div> - - <div id="dialog-form-draftToSent" title="Proposition commerciale envoyée"> - <form> - <fieldset> - <label for="sendDate">Date d'envoi</label> - <input type="text" name="sendDate" id="sendDate" class="datepicker" /> - <input type="hidden" name="id" id="draft-wikittyId"/> - </fieldset> - </form> - </div> - - <div id="dialog-form-sentToAccepted" title="Proposition commerciale acceptée"> - <form> - <fieldset> - <label for="acceptedDate">Date d'acceptation</label> - <input type="text" name="acceptedDate" id="acceptedDate" class="datepicker" /> - <input type="hidden" name="id" id="sent-wikittyId"/> - </fieldset> - </form> - </div> - - <div id="dialog-form-sentToRejected" title="Proposition commerciale refusée"> - <form> - <fieldset> - <label for="rejectedDate">Date de refus</label> - <input type="text" name="rejectedDate" id="rejectedDate" class="datepicker" /> - <input type="hidden" name="id" id="rejected-wikittyId"/> - </fieldset> - </form> - </div> - - <div id="dialog-form-toCancelled" title="Proposition commerciale annulée"> - <form> - <fieldset> - <label for="cancelledDate">Date d'annulation</label> - <input type="text" name="cancelledDate" id="cancelledDate" class="datepicker" /> - <label for="cancelledReason">Raison</label> - <input type="text" name="cancelledReason" id="cancelledReason" value="" class="text ui-widget-content ui-corner-all" /> - <input type="hidden" name="id" id="cancelled-wikittyId"/> - </fieldset> - </form> - </div> - </div> </div> +</div> <div style="clear:both;"/> </body> \ No newline at end of file Modified: trunk/chorem-webmotion/src/main/webapp/js/chorem.js =================================================================== --- trunk/chorem-webmotion/src/main/webapp/js/chorem.js 2013-08-16 09:51:45 UTC (rev 388) +++ trunk/chorem-webmotion/src/main/webapp/js/chorem.js 2013-08-30 14:05:35 UTC (rev 389) @@ -96,41 +96,6 @@ /*********** SALES FUNNEL FUNCTIONS**********************/ -function leadToDraft(){ - var id = $(this).attr('wikittyId'); - var oldQuotation = $(this).parent(); - $("#lead-wikittyId").val(id); - $("#dialog-form-leadToDraft" ).data("oldQuotation", oldQuotation).dialog( "open" ); -}; - -function draftToSent(){ - var id = $(this).attr('wikittyId'); - var oldQuotation = $(this).parent(); - $("#draft-wikittyId").val(id); - $("#dialog-form-draftToSent" ).data("oldQuotation", oldQuotation).dialog( "open" ); -}; - -function sentToAccepted(){ - var id = $(this).attr('wikittyId'); - var oldQuotation = $(this).parent(); - $("#sent-wikittyId").val(id); - $("#dialog-form-sentToAccepted" ).data("oldQuotation", oldQuotation).dialog( "open" ); -}; - -function sentToRejected(){ - var id = $(this).attr('wikittyId'); - var oldQuotation = $(this).parent(); - $("#rejected-wikittyId").val(id); - $("#dialog-form-sentToRejected" ).data("oldQuotation", oldQuotation).dialog( "open" ); -}; - -function toCancelled(){ - var id = $(this).attr('wikittyId'); - var oldQuotation = $(this).parent(); - $("#cancelled-wikittyId").val(id); - $("#dialog-form-toCancelled" ).data("oldQuotation", oldQuotation).dialog( "open" ); -}; - //ajout ble //clic sur les cases à cocher half-day d'une vacation (VacationRequest) @@ -266,451 +231,7 @@ return false; }); - // ******************************************************************** - // * SALES FUNNEL * - // ******************************************************************** - - //Passage d'un lead -> draft - $("a.lead").click(leadToDraft); - - $( "#dialog-form-leadToDraft" ).dialog({ - autoOpen: false, - height: 300, - width: 350, - modal: true, - buttons: { - Ok: function() { - - var reference = $("#reference").val(); - var sendingDate = $("#sendingDate").val(); - var id = $("#lead-wikittyId").val(); - var oldQuotation = $(this).data('oldQuotation'); - var allFields = $([]).add($("#reference")).add($("#sendingDate")).add($("#lead-wikittyId")) - - var dialog = $( this ); - - $.post(createUrl("/sales/funnel/json/answer/", id,"?sendingDate=", sendingDate, "&reference=",reference), - function(data){ - //success - var wikittyId = data.meta.id; - var wikitty = data.data; - - var li = $("<li></li>").addClass("salesFunnelItem draft"); - - //leftDiv - var leftDiv = $("<div></div>").addClass("pull-left"); - var aIconEdit = $("<a></a>") - .attr("href", createUrl("/wikitty/edit/", wikittyId)); - var iconEdit = $("<i></i>").addClass("icon-edit"); - aIconEdit.append(iconEdit); - leftDiv.append(aIconEdit); - var smallAccount = $("<small></small>"); - if (wikitty["Quotation.customer"]!=null){ - var customer = data.preloaded[wikitty["Quotation.customer"]]; - var firstName = customer.preloaded[customer.data["Employee.person"]].data["Person.firstName"]; - var lastName = customer.preloaded[customer.data["Employee.person"]].data["Person.lastName"]; - var company = customer.preloaded[customer.data["Employee.company"]].data["Company.name"]; - } - var aAccount = $("<a></a>") - .text(firstName + " " + lastName + " (" + company + ")") - .attr("href",createUrl("/wikitty/Employee/view/", wikitty["Quotation.customer"])); - smallAccount.append(aAccount); - leftDiv.append(smallAccount); - var leftP = $("<p> - </p>"); - var itemTitleSpan = $('<span></span>').addClass('salesFunnelItemTitle'); - - if (wikitty["Quotation.project"]!=null) { - var aProject = $("<a/>") - .addClass("nameLink") - .attr("href" , createUrl("/wikitty/Project/view/", wikitty["Quotation.project"])) - .text(data.preloaded[wikitty["Quotation.project"]].data["Project.name"]); - } - itemTitleSpan.append(aProject); - var descriptionSmall = $('<small/>').text(wikitty["Quotation.description"]); - leftP.append(descriptionSmall); - leftP.prepend(itemTitleSpan); - leftDiv.append(leftP); - - //button - var aSend = $('<a/>') - .attr('wikittyId', wikittyId) - .addClass("btn btn-success pull-right salesFunnelItemButton draft") - .text("Envoyer") - .click(draftToSent); - - var aCancelled = $('<a/>') - .attr('wikittyId', wikittyId) - .addClass("btn btn-warning pull-right salesFunnelItemButton toCancelled") - .text("Annuler") - .click(toCancelled); - - //rightDiv - var rightDiv = $("<div>").addClass("pull-right"); - var rightP = $("<p>").addClass("salesFunnelItemTitle").text(wikitty["Quotation.amount"] +" €"); - if (wikitty["Quotation.category"] != null) { - var smallInfo = $("<small>") - .text(data.preloaded[wikitty["Quotation.category"]].data["WikittyTreeNode.name"] - + ' - ' + wikitty["Quotation.estimatedDays"] + 'j - ' + - wikitty["Quotation.conversionHope"] + "%"); - } - rightDiv.append(rightP); - rightDiv.append(smallInfo); - - //clear:both - var clearBoth=$("<div style='clear:both;'/>") - - li.append(leftDiv); - li.append(aSend); - li.append(aCancelled); - li.append(rightDiv); - li.append(clearBoth); - - var drafts = $(".drafts"); - drafts.append(li); - oldQuotation.slideUp(); - - //update draftAmount and draftAmountHope - var draftAmount = parseInt($("#draftAmount").text()) + wikitty["Quotation.amount"]; - var amountHope = wikitty["Quotation.amount"]*wikitty["Quotation.conversionHope"]/100; - var draftAmountHope = parseInt($("#draftAmountHope").text()) + amountHope; - $("#draftAmount").text(draftAmount); - $("#draftAmountHope").text(draftAmountHope); - - //update leadAmount and leadAmountHope - var leadAmount = parseInt($("#leadAmount").text()) - wikitty["Quotation.amount"]; - var leadAmountHope = parseInt($("#leadAmountHope").text()) - amountHope; - $("#leadAmount").text(leadAmount); - $("#leadAmountHope").text(leadAmountHope); - - allFields.val(""); - - dialog.dialog( "close" ); - - }).fail(function(){ - //fail - //TODO JC20130212 retour utilisateur - dialog.dialog( "close" ); - }); - }, - Cancel: function() { - $( this ).dialog( "close" ); - } - }, - close: function() { - }, - open: function(event, ui) { - var date = new Date(); - $("#sendingDate").val(date.getDate() + "/" + (date.getMonth()+1)+"/"+date.getFullYear()); - } - }); - - //Passage d'un draft -> sent - $("a.draft").click(draftToSent); - - $( "#dialog-form-draftToSent" ).dialog({ - autoOpen: false, - height: 300, - width: 350, - modal: true, - buttons: { - Ok: function() { - - var sendingDate = $("#sendDate").val(); - var id = $("#draft-wikittyId").val(); - var oldQuotation = $(this).data('oldQuotation'); - var allFields = $([]).add($("#sendDate")).add($("#draft-wikittyId")) - - var dialog = $( this ); - - $.post(createUrl("/sales/funnel/json/send/", id,"?sendingDate=", sendingDate), - function(data){ - //success - - var wikittyId = data.meta.id; - var wikitty = data.data; - - var li = $("<li></li>").addClass("salesFunnelItem draft"); - - //leftDiv - var leftDiv = $("<div></div>").addClass("pull-left"); - var aIconEdit = $("<a></a>") - .attr("href",createUrl("/wikitty/edit/", wikittyId)); - var iconEdit = $("<i></i>").addClass("icon-edit"); - aIconEdit.append(iconEdit); - leftDiv.append(aIconEdit); - var smallAccount = $("<small></small>"); - if (wikitty["Quotation.customer"]!=null){ - var customer = data.preloaded[wikitty["Quotation.customer"]]; - var firstName = customer.preloaded[customer.data["Employee.person"]].data["Person.firstName"]; - var lastName = customer.preloaded[customer.data["Employee.person"]].data["Person.lastName"]; - var company = customer.preloaded[customer.data["Employee.company"]].data["Company.name"]; - } - var aAccount = $("<a></a>") - .text(firstName + " " + lastName + " (" + company + ")") - .attr("href", createUrl("/wikitty/Employee/view/", wikitty["Quotation.customer"])); - smallAccount.append(aAccount); - leftDiv.append(smallAccount); - var leftP = $("<p> - </p>"); - var itemTitleSpan = $('<span></span>').addClass('salesFunnelItemTitle'); - - if (wikitty["Quotation.project"]!=null) { - var aProject = $("<a/>") - .addClass("nameLink") - .attr("href" , createUrl("/wikitty/Project/view/", wikitty["Quotation.project"])) - .text(data.preloaded[wikitty["Quotation.project"]].data["Project.name"]); - } - itemTitleSpan.append(aProject); - var descriptionSmall = $('<small/>').text(wikitty["Quotation.description"]); - leftP.append(descriptionSmall); - leftP.prepend(itemTitleSpan); - leftDiv.append(leftP); - - //button - var aAccepted = $('<a/>') - .attr('wikittyId', wikittyId) - .addClass("btn btn-success pull-right salesFunnelItemButton sent toAccepted") - .text("Accepté") - .click(sentToAccepted); - var aRejected = $('<a/>') - .attr('wikittyId', wikittyId) - .addClass("btn btn-danger pull-right salesFunnelItemButton sent toRejected") - .text("Rejeté") - .click(sentToRejected); - var aCancelled = $('<a/>') - .attr('wikittyId', wikittyId) - .addClass("btn btn-warning pull-right salesFunnelItemButton sent toCancelled") - .text("Annuler") - .click(toCancelled); - - //rightDiv - var rightDiv = $("<div>").addClass("pull-right"); - var rightP = $("<p>").addClass("salesFunnelItemTitle").text(wikitty["Quotation.amount"] +" €"); - if (wikitty["Quotation.category"] != null) { - var smallInfo = $("<small>") - .text(data.preloaded[wikitty["Quotation.category"]].data["WikittyTreeNode.name"] - + ' - ' + wikitty["Quotation.estimatedDays"] + 'j - ' + - wikitty["Quotation.conversionHope"] + "%"); - } - rightDiv.append(rightP); - rightDiv.append(smallInfo); - - //clear:both - var clearBoth=$("<div style='clear:both;'/>") - - li.append(leftDiv); - li.append(aAccepted); - li.append(aRejected); - li.append(aCancelled); - li.append(rightDiv); - li.append(clearBoth); - - var sents = $(".sents"); - sents.append(li); - oldQuotation.slideUp(); - - //update draftAmount and draftAmountHope - var draftAmount = parseInt($("#draftAmount").text()) - wikitty["Quotation.amount"]; - var amountHope = wikitty["Quotation.amount"]*wikitty["Quotation.conversionHope"]/100; - var draftAmountHope = parseInt($("#draftAmountHope").text()) - amountHope; - $("#draftAmount").text(draftAmount); - $("#draftAmountHope").text(draftAmountHope); - - //update sentAmount and sentAmountHope - var sentAmount = parseInt($("#sentAmount").text()) + wikitty["Quotation.amount"]; - var sentAmountHope = parseInt($("#sentAmountHope").text()) + amountHope; - $("#sentAmount").text(sentAmount); - $("#sentAmountHope").text(sentAmountHope); - - allFields.val(""); - - dialog.dialog( "close" ); - - }).fail(function(){ - //fail - //TODO JC20130212 retour utilisateur - dialog.dialog( "close" ); - }); - - }, - Cancel: function() { - $( this ).dialog( "close" ); - } - }, - close: function() { - }, - open: function(event, ui) { - var date = new Date(); - $("#sendDate").val(date.getDate() + "/" + (date.getMonth()+1)+"/"+date.getFullYear()); - } - }); - - //Passage d'un sent vers accepted - $("a.toAccepted").click(sentToAccepted); - - $( "#dialog-form-sentToAccepted" ).dialog({ - autoOpen: false, - height: 300, - width: 350, - modal: true, - buttons: { - Ok: function() { - - var acceptedDate = $("#acceptedDate").val(); - var id = $("#sent-wikittyId").val(); - var oldQuotation = $(this).data('oldQuotation'); - var allFields = $([]).add($("#acceptedDate")).add($("#sent-wikittyId")) - - var dialog = $( this ); - - $.post(createUrl("/sales/funnel/json/accept/", id,"?acceptedDate=", acceptedDate), - function(data){ - //success - oldQuotation.slideUp(); - - var wikitty = data.data; - - //update sentAmount and sentAmountHope - var sentAmount = parseInt($("#sentAmount").text()) - wikitty["Quotation.amount"]; - var amountHope = wikitty["Quotation.amount"]*wikitty["Quotation.conversionHope"]/100; - var sentAmountHope = parseInt($("#sentAmountHope").text()) - amountHope; - $("#sentAmount").text(sentAmount); - $("#sentAmountHope").text(sentAmountHope); - - allFields.val(""); - - dialog.dialog( "close" ); - - }).fail(function(){ - //fail - //TODO JC20130212 retour utilisateur - dialog.dialog( "close" ); - }); - - }, - Cancel: function() { - $( this ).dialog( "close" ); - } - }, - close: function() { - }, - open: function(event, ui) { - var date = new Date(); - $("#acceptedDate").val(date.getDate() + "/" + (date.getMonth()+1)+"/"+date.getFullYear()); - } - }); - - //Passage d'un sent vers rejected - $("a.toRejected").click(sentToRejected); - - $( "#dialog-form-sentToRejected" ).dialog({ - autoOpen: false, - height: 300, - width: 350, - modal: true, - buttons: { - Ok: function() { - - var rejectedDate = $("#rejectedDate").val(); - var id = $("#rejected-wikittyId").val(); - var oldQuotation = $(this).data('oldQuotation'); - var allFields = $([]).add($("#rejectedDate")).add($("#rejected-wikittyId")) - - var dialog = $( this ); - - $.post(createUrl("/sales/funnel/json/reject/", id,"?rejectedDate=", rejectedDate), - function(data){ - //success - oldQuotation.slideUp(); - - var wikitty = data.data; - - //update sentAmount and sentAmountHope - var sentAmount = parseInt($("#sentAmount").text()) - wikitty["Quotation.amount"]; - var amountHope = wikitty["Quotation.amount"]*wikitty["Quotation.conversionHope"]/100; - var sentAmountHope = parseInt($("#sentAmountHope").text()) - amountHope; - $("#sentAmount").text(sentAmount); - $("#sentAmountHope").text(sentAmountHope); - - allFields.val(""); - - dialog.dialog( "close" ); - - }).fail(function(){ - //fail - //TODO JC20130212 retour utilisateur - dialog.dialog( "close" ); - }); - - }, - Cancel: function() { - $( this ).dialog( "close" ); - } - }, - close: function() { - }, - open: function(event, ui) { - var date = new Date(); - $("#rejectedDate").val(date.getDate() + "/" + (date.getMonth()+1)+"/"+date.getFullYear()); - } - }); - - //Passage vers cancelled - $("a.toCancelled").click(toCancelled); - - $( "#dialog-form-toCancelled" ).dialog({ - autoOpen: false, - height: 300, - width: 350, - modal: true, - buttons: { - Ok: function() { - - var cancelledDate = $("#cancelledDate").val(); - var reason = $("#cancelledReason").val(); - var id = $("#cancelled-wikittyId").val(); - var oldQuotation = $(this).data('oldQuotation'); - var allFields = $([]).add($("#cancelledDate")).add($("#cancelled-wikittyId")).add($("#cancelledReason")); - - var dialog = $( this ); - - $.post(createUrl("/sales/funnel/json/cancel/", id,"?cancelledDate=", cancelledDate,"&reason=",reason), - function(data){ - //success - oldQuotation.slideUp(); - - var wikitty = data.data; - - //TODO JC20130527 update amounts - //update sentAmount and sentAmountHope - //var sentAmount = parseInt($("#sentAmount").text()) - wikitty["Quotation.amount"]; - //var amountHope = wikitty["Quotation.amount"]*wikitty["Quotation.conversionHope"]/100; - //var sentAmountHope = parseInt($("#sentAmountHope").text()) - amountHope; - //$("#sentAmount").text(sentAmount); - //$("#sentAmountHope").text(sentAmountHope); - - allFields.val(""); - dialog.dialog( "close" ); - - }).fail(function(){ - //fail - //TODO JC20130212 retour utilisateur - dialog.dialog( "close" ); - }); - - }, - Cancel: function() { - $( this ).dialog( "close" ); - } - }, - close: function() { - }, - open: function(event, ui) { - var date = new Date(); - $("#cancelledDate").val(date.getDate() + "/" + (date.getMonth()+1)+"/"+date.getFullYear()); - } - }); - // ******************************************************************** // * PROJECT DASHBOARD * // ******************************************************************** Added: trunk/chorem-webmotion/src/main/webapp/js/salesFunnel.js =================================================================== --- trunk/chorem-webmotion/src/main/webapp/js/salesFunnel.js (rev 0) +++ trunk/chorem-webmotion/src/main/webapp/js/salesFunnel.js 2013-08-30 14:05:35 UTC (rev 389) @@ -0,0 +1,242 @@ +var salesFunnel = angular.module('salesFunnel', ['wikitty', 'ui.bootstrap', 'ui.date']); + +salesFunnel.directive('datepicker', function() { + return { + restrict: 'A', + require : 'ngModel', + link : function (scope, element, attrs, ngModelCtrl) { + $(function(){ + element.datepicker({ + dateFormat:'dd/mm/yy', + onSelect:function (date) { + ngModelCtrl.$setViewValue(date); + scope.$apply(); + } + }); + }); + } + } +}); + + +var salesFunnelController = ['$scope', '$dialog', 'Wikitty', function ($scope, $dialog, Wikitty) { + $scope.wikittyId = ''; + $scope.wikitty = {}; + + $scope.leads = {}; + $scope.leadsAmount=0; + $scope.leadsAmountHope=0; + $scope.drafts={}; + $scope.draftsAmount=0; + $scope.draftsAmountHope=0; + $scope.sents={}; + $scope.sentsAmount=0; + $scope.sentsAmountHope=0; + + Wikitty.query("extension = Quotation AND extension != Draft AND extension != Cancelled", function(w) { + $scope.leads= w; + }); + + Wikitty.query("extension = Draft AND extension != Sent AND extension != Cancelled", function(w) { + $scope.drafts= w; + }); + + Wikitty.query("extension = Sent AND extension != Accepted AND extension != Rejected AND extension != Cancelled", function(w) { + $scope.sents= w; + }); + + $scope.leadToDraft = function(lead){ + var d = $dialog.dialog({ + templateUrl: './funnel/partial/dialog-leadToDraft.html', + controller: 'LeadToDraftDialogController', + resolve: { + dialogModel: function() { + return {lead:lead, leads:$scope.leads, drafts:$scope.drafts}; + } + } + }); + d.open(); + //initFields(); + }; + + $scope.draftToSent = function(draft){ + var d = $dialog.dialog({ + templateUrl: './funnel/partial/dialog-draftToSent.html', + controller: 'DraftToSentDialogController', + resolve: { + dialogModel: function() { + return {draft:draft, drafts:$scope.drafts, sents:$scope.sents}; + } + } + }); + d.open(); + }; + + $scope.sentToAccepted = function(sent){ + var d = $dialog.dialog({ + templateUrl: './funnel/partial/dialog-sentToAccepted.html', + controller: 'SentToAcceptedDialogController', + resolve: { + dialogModel: function() { + return {sent:sent, sents:$scope.sents}; + } + } + }); + d.open(); + }; + + $scope.sentToRejected = function(sent){ + var d = $dialog.dialog({ + templateUrl: './funnel/partial/dialog-sentToRejected.html', + controller: 'SentToRejectedDialogController', + resolve: { + dialogModel: function() { + return {sent:sent, sents:$scope.sents}; + } + } + }); + d.open(); + }; + + $scope.cancel = function(toCancel){ + var d = $dialog.dialog({ + templateUrl: './funnel/partial/dialog-cancel.html', + controller: 'CancelDialogController', + resolve: { + dialogModel: function() { + return {toCancel:toCancel, leads:$scope.leads, drafts:$scope.drafts, sents:$scope.sents}; + } + } + }); + d.open(); + }; +}]; + + + +// Controller for the Lead To Draft Dialog +var LeadToDraftDialogController = ['$scope', '$http', 'dialog', 'dialogModel', 'Wikitty', function ($scope, $http, dialog, dialogModel, Wikitty) { + $scope.lead = dialogModel.lead; + $scope.drafts = dialogModel.drafts; + $scope.leads = dialogModel.leads; + $scope.lead.sendingDate = new Date().toString("dd/mm/yy"); + + $scope.cancel = function(){ + dialog.close(); + }; + + $scope.validate = function(){ + //pass scope to the success function + var scope = $scope; + $http.get(createUrl('sales/funnel/json/answer/'+$scope.lead.meta.id), + {params: {sendingDate:$scope.lead.sendingDate,reference:$scope.lead.reference}}).success( + function(data,status){ + scope.drafts.push(new Wikitty(data)); + scope.leads.splice(scope.leads.indexOf(scope.lead),1); + dialog.close(); + } + ); + } +}]; + + + +// Controller for the Draft To Sent Dialog +var DraftToSentDialogController = ['$scope', '$http', 'dialog', 'dialogModel', 'Wikitty', function ($scope, $http, dialog, dialogModel, Wikitty) { + $scope.draft = dialogModel.draft; + $scope.drafts = dialogModel.drafts; + $scope.sents = dialogModel.sents; + //$scope.draft.sendingDate = new Date().toString("dd/mm/yy"); + + $scope.cancel = function(){ + dialog.close(); + }; + + $scope.validate = function(){ + //pass scope to the success function + var scope = $scope; + $http.get(createUrl('sales/funnel/json/send/'+$scope.draft.meta.id), + {params: {sendingDate:$scope.draft.sendingDate}}).success( + function(data,status){ + scope.sents.push(new Wikitty(data)); + scope.drafts.splice(scope.drafts.indexOf(scope.draft),1); + dialog.close(); + } + ); + } +}]; + + + +// Controller for the Sent to Accepted Dialog +var SentToAcceptedDialogController = ['$scope', '$http', 'dialog', 'dialogModel', function ($scope, $http, dialog, dialogModel) { + $scope.sent = dialogModel.sent; + $scope.sents = dialogModel.sents; + $scope.sent.acceptedDate = new Date(); + + $scope.cancel = function(){ + dialog.close(); + }; + + $scope.validate = function(){ + //pass scope to the success function + var scope = $scope; + $http.get(createUrl('sales/funnel/json/accept/'+$scope.sent.meta.id), + {params: {acceptedDate:$scope.sent.acceptedDate}}).success( + function(data,status){ + $scope.sents.splice($scope.sents.indexOf(sent),1); + dialog.close(); + } + ); + } +}]; + + + +// Controller for the Sent to Rejected Dialog +var SentToRejectedDialogController = ['$scope', '$http', 'dialog', 'dialogModel', function ($scope, $http, dialog, dialogModel) { + $scope.sent = dialogModel.sent; + $scope.sents = dialogModel.sents; + $scope.sent.rejectedDate = new Date(); + + $scope.cancel = function(){ + dialog.close(); + }; + + $scope.validate = function(){ + //pass scope to the success function + var scope = $scope; + $http.get(createUrl('sales/funnel/json/reject/'+$scope.sent.meta.id),{params: {rejectedDate:$scope.sent.rejectedDate}}).success( + function(data,status){ + $scope.sents.splice($scope.sents.indexOf(sent),1); + dialog.close(); + } + ); + } +}]; + + + +// Controller for the Cancel Dialog +var CancelDialogController = ['$scope', '$http', 'dialog', 'dialogModel', function ($scope, $http, dialog, dialogModel) { + $scope.toCancel = dialogModel.toCancel; + $scope.sents = dialogModel.sents; + $scope.leads = dialogModel.leads; + $scope.drafts = dialogModel.drafts; + $scope.toCancel.cancelledDate = new Date(); + $scope.toCancel.cancelledReason = ""; + + $scope.cancel = function(){ + dialog.close(); + }; + + $scope.validate = function(){ + //pass scope to the success function + var scope = $scope; + $http.get(createUrl('sales/funnel/json/cancel/'+$scope.sent.meta.id),{params: {rejectedDate:$scope.sent.rejectedDate}}).success( + function(data,status){ + dialog.close(); + } + ); + } +}]; \ No newline at end of file