Merged master into whydcl
This commit is contained in:
		
				commit
				
					
						36976d923e
					
				
			
		
					 21 changed files with 554 additions and 324 deletions
				
			
		
							
								
								
									
										10
									
								
								Changelog
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								Changelog
									
										
									
									
									
								
							|  | @ -1,3 +1,11 @@ | ||||||
|  | 1.0.18: 2017-07-02 | ||||||
|  |     * [datacenterlight] Introduced the new flow. Landing page -> Payment -> Order confirmation -> Success | ||||||
|  |     * [datacenterlight] Fixed issue showing local time to the user in order confirmation page, vm pages (like ssh keys) | ||||||
|  |     * [hosting] Fixed responsive issue while user signup | ||||||
|  |     * [hosting] Fixed 500 error when user requests for a vm whose id does not belong to him | ||||||
|  |     * [datacenterlight] Refactored partially dcl text and dcl support email to be obtained from env parameters | ||||||
|  |     * [datacenterlight] Updated DE translations | ||||||
|  |     * [hosting] Updated email text for user activation | ||||||
| 1.0.17: 2017-06-16 | 1.0.17: 2017-06-16 | ||||||
|     * [datacenterlight] Cleanup OrderView useless code |     * [datacenterlight] Cleanup OrderView useless code | ||||||
|     * [datacenterlight] Replaced GiB to GB |     * [datacenterlight] Replaced GiB to GB | ||||||
|  | @ -5,7 +13,7 @@ | ||||||
|     * [datacenterlight] Fixed translations |     * [datacenterlight] Fixed translations | ||||||
|     * [datacenterlight] Added email confirmation feature |     * [datacenterlight] Added email confirmation feature | ||||||
|     * [datacenterlight] Changed logo on datacerlight dashboard |     * [datacenterlight] Changed logo on datacerlight dashboard | ||||||
|     * [datacenterlight] Credit card input disappearance fix  |     * [datacenterlight] Credit card input disappearance fix | ||||||
| 1.0.16: 2017-06-15 | 1.0.16: 2017-06-15 | ||||||
|     * [datacenterlight] .po file issue with multiple definition fixed |     * [datacenterlight] .po file issue with multiple definition fixed | ||||||
|     * [datacenterlight] Navbar items in dcl user area rearranged |     * [datacenterlight] Navbar items in dcl user area rearranged | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ msgid "" | ||||||
| msgstr "" | msgstr "" | ||||||
| "Project-Id-Version: PACKAGE VERSION\n" | "Project-Id-Version: PACKAGE VERSION\n" | ||||||
| "Report-Msgid-Bugs-To: \n" | "Report-Msgid-Bugs-To: \n" | ||||||
| "POT-Creation-Date: 2017-06-19 12:22+0530\n" | "POT-Creation-Date: 2017-07-02 23:08+0530\n" | ||||||
| "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | ||||||
| "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | ||||||
| "Language-Team: LANGUAGE <LL@li.org>\n" | "Language-Team: LANGUAGE <LL@li.org>\n" | ||||||
|  | @ -18,14 +18,6 @@ msgstr "" | ||||||
| "Content-Transfer-Encoding: 8bit\n" | "Content-Transfer-Encoding: 8bit\n" | ||||||
| "Plural-Forms: nplurals=2; plural=(n != 1);\n" | "Plural-Forms: nplurals=2; plural=(n != 1);\n" | ||||||
| 
 | 
 | ||||||
| #: templates/datacenterlight/base.html:72 |  | ||||||
| msgid "Please enter your name" |  | ||||||
| msgstr "Bitte gib Deinen Namen ein" |  | ||||||
| 
 |  | ||||||
| #: templates/datacenterlight/base.html:73 |  | ||||||
| msgid "Please enter a valid email address" |  | ||||||
| msgstr "Bitte gib eine gültige E-Mail-Adresse ein" |  | ||||||
| 
 |  | ||||||
| #: templates/datacenterlight/beta_access.html:13 | #: templates/datacenterlight/beta_access.html:13 | ||||||
| msgid "Enter name" | msgid "Enter name" | ||||||
| msgstr "Name" | msgstr "Name" | ||||||
|  | @ -99,15 +91,18 @@ msgid "" | ||||||
| "datacenterlight account.<br/>\n" | "datacenterlight account.<br/>\n" | ||||||
| "                %(base_url)s%(activation_link)s\n" | "                %(base_url)s%(activation_link)s\n" | ||||||
| "                " | "                " | ||||||
| msgstr "\n" | msgstr "" | ||||||
| "                <a href=\"%(base_url)s%(activation_link)s\">Klicke hier</a> um deinen %(dcl_text)s zu aktivieren.<br/><br/>\n" | "\n" | ||||||
| "                Oder kopiere den folgenden Link in die Adressleiste deines Browsers und folge dann dem Link um deinen %(dcl_text)s Account zu aktivieren.<br/>\n" | "                <a href=\"%(base_url)s%(activation_link)s\">Klicke hier</a> " | ||||||
|  | "um deinen %(dcl_text)s zu aktivieren.<br/><br/>\n" | ||||||
|  | "                Oder kopiere den folgenden Link in die Adressleiste deines " | ||||||
|  | "Browsers und folge dann dem Link um deinen %(dcl_text)s Account zu " | ||||||
|  | "aktivieren.<br/>\n" | ||||||
| "                %(base_url)s%(activation_link)s\n" | "                %(base_url)s%(activation_link)s\n" | ||||||
| "                " | "                " | ||||||
| 
 | 
 | ||||||
| #: templates/datacenterlight/emails/user_activation.html:123 | #: templates/datacenterlight/emails/user_activation.html:123 | ||||||
| #: templates/datacenterlight/emails/user_activation.txt:11 | #: templates/datacenterlight/emails/user_activation.txt:11 | ||||||
| #| msgid "Your Name" |  | ||||||
| msgid "Your" | msgid "Your" | ||||||
| msgstr "Dein" | msgstr "Dein" | ||||||
| 
 | 
 | ||||||
|  | @ -128,8 +123,9 @@ msgstr "" | ||||||
| "\n" | "\n" | ||||||
| "Hallo,\n" | "Hallo,\n" | ||||||
| "\n" | "\n" | ||||||
| "Du kannst deinen %(dcl_text)s Account aktivieren, indem du hier klickst %(base_url)s" | "Du kannst deinen %(dcl_text)s Account aktivieren, indem du hier klickst " | ||||||
| "%(activation_link)s\n" | "%(base_url)s%(activation_link)s\n" | ||||||
|  | 
 | ||||||
| #: templates/datacenterlight/includes/_footer.html:11 | #: templates/datacenterlight/includes/_footer.html:11 | ||||||
| #: templates/datacenterlight/includes/_footer.html:31 | #: templates/datacenterlight/includes/_footer.html:31 | ||||||
| #: templates/datacenterlight/includes/_navbar.html:27 | #: templates/datacenterlight/includes/_navbar.html:27 | ||||||
|  | @ -260,44 +256,112 @@ msgstr "MwSt. inklusive" | ||||||
| msgid "Hosted in Switzerland" | msgid "Hosted in Switzerland" | ||||||
| msgstr "Standort: Schweiz" | msgstr "Standort: Schweiz" | ||||||
| 
 | 
 | ||||||
| #: templates/datacenterlight/index.html:173 | #: templates/datacenterlight/index.html:161 | ||||||
|  | msgid "Please enter a value greater than or equal to 1." | ||||||
|  | msgstr "Bitte gib einen Wert größer oder gleich 1 ein." | ||||||
|  | 
 | ||||||
|  | #: templates/datacenterlight/index.html:170 | ||||||
|  | msgid "Please enter a value greater than or equal to 2." | ||||||
|  | msgstr "Bitte gib einen Wert größer oder gleich 2 ein." | ||||||
|  | 
 | ||||||
|  | #: templates/datacenterlight/index.html:179 | ||||||
|  | msgid "Please enter a value greater than or equal to 10." | ||||||
|  | msgstr "Bitte gib einen Wert größer oder gleich 10 ein" | ||||||
|  | 
 | ||||||
|  | #: templates/datacenterlight/index.html:180 | ||||||
| #: templates/datacenterlight/pricing.html:50 | #: templates/datacenterlight/pricing.html:50 | ||||||
| msgid "GB Storage (SSD)" | msgid "GB Storage (SSD)" | ||||||
| msgstr "GB Storage (SSD)" | msgstr "GB Storage (SSD)" | ||||||
| 
 | 
 | ||||||
| #: templates/datacenterlight/index.html:189 | #: templates/datacenterlight/index.html:199 | ||||||
| msgid "Name" | msgid "Name" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
| #: templates/datacenterlight/index.html:190 | #: templates/datacenterlight/index.html:200 | ||||||
| msgid "Your Name" | msgid "Your Name" | ||||||
| msgstr "Dein Name" | msgstr "Dein Name" | ||||||
| 
 | 
 | ||||||
| #: templates/datacenterlight/index.html:193 | #: templates/datacenterlight/index.html:200 | ||||||
|  | msgid "Please enter your name" | ||||||
|  | msgstr "Bitte gib Deinen Namen ein" | ||||||
|  | 
 | ||||||
|  | #: templates/datacenterlight/index.html:214 | ||||||
| msgid "Email" | msgid "Email" | ||||||
| msgstr "E-Mail-Adresse" | msgstr "E-Mail-Adresse" | ||||||
| 
 | 
 | ||||||
| #: templates/datacenterlight/index.html:194 | #: templates/datacenterlight/index.html:215 | ||||||
| msgid "Your Email" | msgid "Your Email" | ||||||
| msgstr "Deine E-Mail" | msgstr "Deine E-Mail" | ||||||
| 
 | 
 | ||||||
| #: templates/datacenterlight/index.html:197 | #: templates/datacenterlight/index.html:215 | ||||||
|  | msgid "Please enter a valid email address" | ||||||
|  | msgstr "Bitte gib eine gültige E-Mailadresse ein" | ||||||
|  | 
 | ||||||
|  | #: templates/datacenterlight/index.html:228 | ||||||
| #: templates/datacenterlight/pricing.html:79 | #: templates/datacenterlight/pricing.html:79 | ||||||
| msgid "Order Now!" | msgid "Order Now!" | ||||||
| msgstr "Bestelle jetzt!" | msgstr "Bestelle jetzt!" | ||||||
| 
 | 
 | ||||||
| #: templates/datacenterlight/index.html:226 | #: templates/datacenterlight/index.html:254 | ||||||
| msgid "Switzerland " | msgid "Switzerland " | ||||||
| msgstr "Schweiz" | msgstr "Schweiz" | ||||||
| 
 | 
 | ||||||
| #: templates/datacenterlight/index.html:243 | #: templates/datacenterlight/index.html:271 | ||||||
| msgid "Questions?" | msgid "Questions?" | ||||||
| msgstr "Fragen?" | msgstr "Fragen?" | ||||||
| 
 | 
 | ||||||
| #: templates/datacenterlight/index.html:243 | #: templates/datacenterlight/index.html:271 | ||||||
| msgid "Contact us!" | msgid "Contact us!" | ||||||
| msgstr "Kontaktiere uns!" | msgstr "Kontaktiere uns!" | ||||||
| 
 | 
 | ||||||
|  | #: templates/datacenterlight/order_detail.html:24 | ||||||
|  | msgid "Confirm Order" | ||||||
|  | msgstr "Bestellung Bestätigen" | ||||||
|  | 
 | ||||||
|  | #: templates/datacenterlight/order_detail.html:30 | ||||||
|  | msgid "Billed To:" | ||||||
|  | msgstr "Rechnungsadresse" | ||||||
|  | 
 | ||||||
|  | #: templates/datacenterlight/order_detail.html:39 | ||||||
|  | msgid "Date" | ||||||
|  | msgstr "Datum" | ||||||
|  | 
 | ||||||
|  | #: templates/datacenterlight/order_detail.html:48 | ||||||
|  | msgid "Payment Method:" | ||||||
|  | msgstr "Bezahlmethode" | ||||||
|  | 
 | ||||||
|  | #: templates/datacenterlight/order_detail.html:49 | ||||||
|  | msgid "ending" | ||||||
|  | msgstr "endend in" | ||||||
|  | 
 | ||||||
|  | #: templates/datacenterlight/order_detail.html:59 | ||||||
|  | msgid "Order summary" | ||||||
|  | msgstr "Bestellungsübersicht" | ||||||
|  | 
 | ||||||
|  | #: templates/datacenterlight/order_detail.html:63 | ||||||
|  | msgid "Cores" | ||||||
|  | msgstr "Prozessorkerne" | ||||||
|  | 
 | ||||||
|  | #: templates/datacenterlight/order_detail.html:65 | ||||||
|  | msgid "Memory" | ||||||
|  | msgstr "Arbeitsspeicher" | ||||||
|  | 
 | ||||||
|  | #: templates/datacenterlight/order_detail.html:67 | ||||||
|  | msgid "Disk space" | ||||||
|  | msgstr "Festplattenkapazität" | ||||||
|  | 
 | ||||||
|  | #: templates/datacenterlight/order_detail.html:69 | ||||||
|  | msgid "Configuration" | ||||||
|  | msgstr "Konfiguration" | ||||||
|  | 
 | ||||||
|  | #: templates/datacenterlight/order_detail.html:71 | ||||||
|  | msgid "Total" | ||||||
|  | msgstr "" | ||||||
|  | 
 | ||||||
|  | #: templates/datacenterlight/order_detail.html:78 | ||||||
|  | msgid "Place order" | ||||||
|  | msgstr "Bestellen" | ||||||
|  | 
 | ||||||
| #: templates/datacenterlight/pricing.html:9 | #: templates/datacenterlight/pricing.html:9 | ||||||
| msgid "We are cutting down the costs significantly!" | msgid "We are cutting down the costs significantly!" | ||||||
| msgstr "Wir sorgen dafür, dass die Kosten für Dich signifikant abnehmen" | msgstr "Wir sorgen dafür, dass die Kosten für Dich signifikant abnehmen" | ||||||
|  | @ -328,6 +392,14 @@ msgstr "" | ||||||
| msgid "as soon as possible!" | msgid "as soon as possible!" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | #: views.py:234 | ||||||
|  | msgid "is not a proper name" | ||||||
|  | msgstr "ist kein gültiger Name" | ||||||
|  | 
 | ||||||
|  | #: views.py:241 | ||||||
|  | msgid "is not a proper email" | ||||||
|  | msgstr "ist keine gültige E-Mailadresse" | ||||||
|  | 
 | ||||||
| #~ msgid "Buy VM" | #~ msgid "Buy VM" | ||||||
| #~ msgstr "VM Kaufen" | #~ msgstr "VM Kaufen" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -7,7 +7,6 @@ | ||||||
|     font-family: 'Lato-Regular'; |     font-family: 'Lato-Regular'; | ||||||
|     src: url('../fonts/Lato/Lato-Regular.ttf'); |     src: url('../fonts/Lato/Lato-Regular.ttf'); | ||||||
| } | } | ||||||
| 
 |  | ||||||
| body, | body, | ||||||
| html { | html { | ||||||
|     width: 100%; |     width: 100%; | ||||||
|  | @ -189,7 +188,6 @@ h6 { | ||||||
| .nav-language:hover .drop-language{ | .nav-language:hover .drop-language{ | ||||||
|     display: block; |     display: block; | ||||||
| } | } | ||||||
| 
 |  | ||||||
| .intro-header { | .intro-header { | ||||||
|     height: 100vh; |     height: 100vh; | ||||||
|     text-align: center; |     text-align: center; | ||||||
|  | @ -438,7 +436,6 @@ h6 { | ||||||
| } | } | ||||||
| .pricing-section .card .description{ | .pricing-section .card .description{ | ||||||
|     padding: 12px; |     padding: 12px; | ||||||
|     border-bottom: 1px solid rgba(128, 128, 128, 0.3); |  | ||||||
| } | } | ||||||
| .pricing-section .card .descriptions{ | .pricing-section .card .descriptions{ | ||||||
|     padding: 10px 30px; |     padding: 10px 30px; | ||||||
|  | @ -789,11 +786,10 @@ tech-sub-sec h2 { | ||||||
| } | } | ||||||
| .price-calc-section .card .description{ | .price-calc-section .card .description{ | ||||||
|     padding: 12px; |     padding: 12px; | ||||||
|     border-bottom: 1px solid rgba(128, 128, 128, 0.3); |  | ||||||
|     position: relative; |     position: relative; | ||||||
|     display: flex; |     display: flex; | ||||||
|     justify-content: space-around; |     justify-content: space-around !important; | ||||||
|     align-items: center; |     align-items: center !important; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .price-calc-section .card .description span { | .price-calc-section .card .description span { | ||||||
|  | @ -804,10 +800,10 @@ tech-sub-sec h2 { | ||||||
|     width: 30%; |     width: 30%; | ||||||
|     text-align: left; |     text-align: left; | ||||||
| } | } | ||||||
| .price-calc-section .card .description input{ | .price-calc-section .card .description .select-number{ | ||||||
|    font-size: 20px; | 	font-size: 20px; | ||||||
|     text-align: center; | 	text-align: center; | ||||||
|     width: 60px; | 	width: 60px; | ||||||
| } | } | ||||||
| .price-calc-section .card .description i{ | .price-calc-section .card .description i{ | ||||||
|     color: #29427A; |     color: #29427A; | ||||||
|  | @ -844,8 +840,8 @@ tech-sub-sec h2 { | ||||||
| .price-calc-section .card .check-ip{ | .price-calc-section .card .check-ip{ | ||||||
|     font-size: 18px; |     font-size: 18px; | ||||||
| } | } | ||||||
| .price-calc-section .card .description.input{ | .price-calc-section .card .justify-center{ | ||||||
|     justify-content: center; |     justify-content: center !important; | ||||||
| } | } | ||||||
| .price-calc-section .card .description.input label{ | .price-calc-section .card .description.input label{ | ||||||
|     font-size: 15px; |     font-size: 15px; | ||||||
|  | @ -854,10 +850,11 @@ tech-sub-sec h2 { | ||||||
|     margin-bottom: 0; |     margin-bottom: 0; | ||||||
|     width: 40px; |     width: 40px; | ||||||
| } | } | ||||||
| .price-calc-section .card .description.input input{ | /*Changed class****.price-calc-section .card .description.input input*/ | ||||||
|      width: 200px; | .price-calc-section .card .description input{ | ||||||
|     font-size: 14px; | 	width: 200px; | ||||||
|     text-align: left; | 	font-size: 14px; | ||||||
|  | 	text-align: left; | ||||||
|     padding: 5px 10px; |     padding: 5px 10px; | ||||||
|     border-radius: 4px; |     border-radius: 4px; | ||||||
|     border: 1px solid #d0d0d0; |     border: 1px solid #d0d0d0; | ||||||
|  | @ -869,6 +866,18 @@ tech-sub-sec h2 { | ||||||
|     font-size: 17px; |     font-size: 17px; | ||||||
|     margin: 0 8px; |     margin: 0 8px; | ||||||
| } | } | ||||||
|  | .help-block.with-errors { | ||||||
|  |     text-align: center; | ||||||
|  |     margin: 0; | ||||||
|  |     padding: 0; | ||||||
|  | } | ||||||
|  | .has-error .checkbox, .has-error .checkbox-inline, .has-error .control-label, .has-error .help-block, .has-error .radio, .has-error .radio-inline, .has-error.checkbox label, .has-error.checkbox-inline label, .has-error.radio label, .has-error.radio-inline label{ | ||||||
|  | color: #eb4d5c; | ||||||
|  | } | ||||||
|  | .form-group { | ||||||
|  |     margin: 0; | ||||||
|  |     border-bottom: 1px solid rgba(128, 128, 128, 0.3); | ||||||
|  | } | ||||||
| @media(max-width:767px) { | @media(max-width:767px) { | ||||||
| 	.percent-text { | 	.percent-text { | ||||||
| 		font-size: 50px; | 		font-size: 50px; | ||||||
|  | @ -1125,7 +1134,7 @@ line-height: 40px; | ||||||
|         text-align: center; |         text-align: center; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     .price-calc-section .card .description input { |     .price-calc-section .card .description .select-number{ | ||||||
|         font-size: 17px; |         font-size: 17px; | ||||||
|         text-align: center; |         text-align: center; | ||||||
|         width: 60px; |         width: 60px; | ||||||
|  |  | ||||||
|  | @ -33,6 +33,9 @@ | ||||||
|         <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> |         <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> | ||||||
|         <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> |         <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> | ||||||
|     <![endif]--> |     <![endif]--> | ||||||
|  |     <!-- Google analytics --> | ||||||
|  |     {% include "google_analytics.html" %} | ||||||
|  |     <!-- End Google Analytics --> | ||||||
| </head> | </head> | ||||||
| 
 | 
 | ||||||
| <body> | <body> | ||||||
|  | @ -60,53 +63,5 @@ | ||||||
|     <script src="{% static 'datacenterlight/js/form.js' %}"></script> |     <script src="{% static 'datacenterlight/js/form.js' %}"></script> | ||||||
|     <script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.5.4/bootstrap-select.js"></script> |     <script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.5.4/bootstrap-select.js"></script> | ||||||
|     <script src="//cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.16.0/jquery.validate.min.js"></script> |     <script src="//cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.16.0/jquery.validate.min.js"></script> | ||||||
|      |     <script src="//cdnjs.cloudflare.com/ajax/libs/1000hz-bootstrap-validator/0.11.9/validator.min.js"></script> | ||||||
|     <script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.5.4/bootstrap-select.js"></script> |  | ||||||
|      |  | ||||||
|     <script type="text/javascript"> |  | ||||||
|            $(document).ready(function(){ |  | ||||||
|                $.validator.setDefaults({ |  | ||||||
|                    ignore: [] |  | ||||||
|                }); |  | ||||||
| 
 |  | ||||||
|                var name_message = "{% trans 'Please enter your name' %}"; |  | ||||||
|                var email_message = "{% trans 'Please enter a valid email address' %}"; |  | ||||||
|                $('#order_form').validate({ |  | ||||||
|                    wrapper: 'div', |  | ||||||
|                    errorLabelContainer: "#error_message_box", |  | ||||||
|                    rules: { |  | ||||||
|                        name: { |  | ||||||
|                            required: true, |  | ||||||
|                            minlength: 3 |  | ||||||
|                        }, |  | ||||||
|                        email: { |  | ||||||
|                            required: true, |  | ||||||
|                            email: true |  | ||||||
|                        } |  | ||||||
|                    }, |  | ||||||
|                    messages: { |  | ||||||
|                        name: name_message, |  | ||||||
|                        email: email_message |  | ||||||
|                    }, |  | ||||||
|                    submitHandler: function (form) { |  | ||||||
|                        return true; |  | ||||||
|                    } |  | ||||||
|                }); |  | ||||||
|            }); |  | ||||||
| 
 |  | ||||||
|           // window.onload=function(){ |  | ||||||
|           //   $('.selectpicker').selectpicker({ |  | ||||||
|           //        style: 'btn-link', |  | ||||||
|           //        windowPadding: 10, |  | ||||||
|           //   }); |  | ||||||
| 
 |  | ||||||
|           //   var hash = window.location.hash.substr(1); |  | ||||||
|           //   console.log(hash); |  | ||||||
|           //   if (hash == 'requestform'){ |  | ||||||
|           //       $('#reques-success-message').modal('show'); |  | ||||||
|           //   } |  | ||||||
| 
 |  | ||||||
|           //  }; |  | ||||||
|     </script> |  | ||||||
| 
 |  | ||||||
| </html> | </html> | ||||||
|  |  | ||||||
|  | @ -139,7 +139,7 @@ | ||||||
|                         <div class="landing card"> |                         <div class="landing card"> | ||||||
|                             <img class="img-beta" src="{% static 'datacenterlight/img/beta-img.png' %}" alt=""> |                             <img class="img-beta" src="{% static 'datacenterlight/img/beta-img.png' %}" alt=""> | ||||||
|                             <div class="caption"> |                             <div class="caption"> | ||||||
|                                 <form id="order_form" method="POST" action=""> |                                 <form id="order_form" method="POST" action="" data-toggle="validator" role="form"> | ||||||
|                                     {% csrf_token %} |                                     {% csrf_token %} | ||||||
|                                     <div class="title"> |                                     <div class="title"> | ||||||
|                                        <h3>{% trans "VM hosting" %} </h3> |                                        <h3>{% trans "VM hosting" %} </h3> | ||||||
|  | @ -152,28 +152,37 @@ | ||||||
|                                         </div> |                                         </div> | ||||||
|                                     </div> |                                     </div> | ||||||
|                                     <div class="descriptions"> |                                     <div class="descriptions"> | ||||||
|                                         <div class="description"> |                                         <div class="description form-group"> | ||||||
|                                             <p>{% trans "Hosted in Switzerland" %}</p> |                                             <p>{% trans "Hosted in Switzerland" %}</p> | ||||||
|                                         </div> |                                         </div> | ||||||
|                                         <div class="description"> |                                         <div class="form-group"> | ||||||
|  |                                             <div class="description input"> | ||||||
|                                             <i class="fa fa-minus-circle left" data-minus="cpu" aria-hidden="true"></i> |                                             <i class="fa fa-minus-circle left" data-minus="cpu" aria-hidden="true"></i> | ||||||
|                                             <input class="input-price" type="number"  min="1" max="42" id="coreValue" name="cpu"> |                                             <input class="input-price select-number" type="number"  min="1" max="42" id="coreValue" name="cpu" data-error="{% trans 'Please enter a value greater than or equal to 1.' %}" required> | ||||||
|                                             <span> Core</span> |                                             <span> Core</span> | ||||||
|                                             <i class="fa fa-plus-circle right" data-plus="cpu"  aria-hidden="true"></i> |                                             <i class="fa fa-plus-circle right" data-plus="cpu"  aria-hidden="true"></i> | ||||||
|  |                                             </div> | ||||||
|  |                                             <div class="help-block with-errors"></div> | ||||||
|                                         </div> |                                         </div> | ||||||
|                                         <div class="description"> |                                         <div class="form-group"> | ||||||
|  |                                             <div class="description input"> | ||||||
|                                             <i class="fa fa-minus-circle left" data-minus="ram" aria-hidden="true"></i> |                                             <i class="fa fa-minus-circle left" data-minus="ram" aria-hidden="true"></i> | ||||||
|                                             <input id="ramValue" class="input-price" type="number"  min="2" max="200"  name="ram"> |                                             <input id="ramValue" class="input-price select-number" type="number"  min="2" max="200"  name="ram" data-error="{% trans 'Please enter a value greater than or equal to 2.' %}" required> | ||||||
|                                             <span> GB RAM</span> |                                             <span> GB RAM</span> | ||||||
|                                             <i class="fa fa-plus-circle right" data-plus="ram"  aria-hidden="true"></i> |                                             <i class="fa fa-plus-circle right" data-plus="ram"  aria-hidden="true"></i> | ||||||
|  |                                             </div> | ||||||
|  |                                             <div class="help-block with-errors"></div> | ||||||
|                                         </div> |                                         </div> | ||||||
|                                         <div class="description"> |                                         <div class="form-group"> | ||||||
|  |                                             <div class="description input"> | ||||||
|                                             <i class="fa fa-minus-circle left" data-minus="storage" aria-hidden="true"></i> |                                             <i class="fa fa-minus-circle left" data-minus="storage" aria-hidden="true"></i> | ||||||
|                                             <input id="storageValue" class="input-price" type="number"  min="10" max="500" step="10" name="storage"> |                                             <input id="storageValue" class="input-price select-number" type="number"  min="10" max="500" step="10" name="storage" data-error="{% trans 'Please enter a value greater than or equal to 10.' %}" required> | ||||||
|                                             <span>{% trans "GB Storage (SSD)" %}</span> |                                             <span>{% trans "GB Storage (SSD)" %}</span> | ||||||
|                                             <i class="fa fa-plus-circle right" data-plus="storage"  aria-hidden="true"></i> |                                             <i class="fa fa-plus-circle right" data-plus="storage"  aria-hidden="true"></i> | ||||||
|  |                                             </div> | ||||||
|  |                                             <div class="help-block with-errors"></div> | ||||||
|                                         </div> |                                         </div> | ||||||
|                                         <div class="description select-configuration input"> |                                         <div class="description select-configuration input form-group justify-center"> | ||||||
|                                             <label for="config">OS</label> |                                             <label for="config">OS</label> | ||||||
|                                             <select name="config" id=""> |                                             <select name="config" id=""> | ||||||
|                                                 {% for template in templates %} |                                                 {% for template in templates %} | ||||||
|  | @ -185,21 +194,40 @@ | ||||||
|                                         <!--<div class="description check-ip"> |                                         <!--<div class="description check-ip"> | ||||||
|                                             <input type="checkbox" name="ipv6"> Ipv6 Only<br> |                                             <input type="checkbox" name="ipv6"> Ipv6 Only<br> | ||||||
|                                         </div>--> |                                         </div>--> | ||||||
|                                         <div class="description input"> |                                             <div class="form-group"> | ||||||
|                                             <label for="name">{% trans "Name"%}</label> |                                                 <div class="description input justify-center"> | ||||||
|                                             <input type="text" name="name" placeholder="{% trans "Your Name" %}"> |                                                 <label for="name" class="control-label">{% trans "Name"%}</label> | ||||||
|                                         </div> |                                                 <input type="text" name="name" class="form-control" placeholder="{% trans 'Your Name'%}" data-minlength="3" data-error="{% trans 'Please enter your name' %}" required> | ||||||
|                                         <div class="description input"> |                                                 </div> | ||||||
|                                             <label for="email">{% trans "Email" %}</label> |                                                 <div class="help-block with-errors"> | ||||||
|                                             <input type="email" name="email" placeholder="{% trans "Your Email" %}"> |                                                     {% for message in messages %} | ||||||
|                                         </div> |                                                         {% if 'name' in message.tags %} | ||||||
|  |                                                         <ul class="list-unstyled"><li> | ||||||
|  |                                                             {{ message|safe }} | ||||||
|  |                                                         </li></ul> | ||||||
|  |                                                         {% endif %} | ||||||
|  |                                                     {% endfor %} | ||||||
|  |                                                 </div> | ||||||
|  |                                             </div> | ||||||
|  |                                             <div class="form-group"> | ||||||
|  |                                                 <div class="description input justify-center"> | ||||||
|  |                                                 <label for="email" class="control-label">{% trans "Email"%}</label> | ||||||
|  |                                                 <input name="email" type="email" pattern="^[^@\s]+@([^@\s]+\.)+[^@\s]+$" class="form-control" placeholder="{% trans 'Your Email' %}" data-error="{% trans 'Please enter a valid email address' %}" required> | ||||||
|  |                                                 </div> | ||||||
|  |                                                 <div class="help-block with-errors"> | ||||||
|  |                                                     {% for message in messages %} | ||||||
|  |                                                         {% if 'email' in message.tags %} | ||||||
|  |                                                          <ul class="list-unstyled"><li> | ||||||
|  |                                                             {{ message|safe }} | ||||||
|  |                                                         </li></ul> | ||||||
|  |                                                         {% endif %} | ||||||
|  |                                                     {% endfor %} | ||||||
|  |                                                 </div> | ||||||
|  |                                             </div> | ||||||
|                                     </div> |                                     </div> | ||||||
|                                     <input type="submit" class="btn btn-primary" value="{% trans 'Order Now!' %}"></input> |                                     <input type="submit" class="btn btn-primary" value="{% trans 'Order Now!' %}"></input> | ||||||
|                                 </form> |                                 </form> | ||||||
|                             </div> |                             </div> | ||||||
|                             <div> |  | ||||||
|                                 <div id="error_message_box" class="error-message-box"></div> |  | ||||||
|                             </div> |  | ||||||
|                         </div> |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
| 
 | 
 | ||||||
|  | @ -250,4 +278,4 @@ | ||||||
|          |          | ||||||
|     </div> |     </div> | ||||||
|     <!-- /.banner --> |     <!-- /.banner --> | ||||||
|     {% endblock %} |     {% endblock %} | ||||||
|  |  | ||||||
|  | @ -1,7 +1,8 @@ | ||||||
| {% extends "hosting/base_short.html" %} | {% extends "hosting/base_short.html" %} | ||||||
| {% load staticfiles bootstrap3 %} | {% load staticfiles bootstrap3 %} | ||||||
| {% load i18n %} | {% load i18n %} | ||||||
| {% block content %}  | {% load custom_tags %} | ||||||
|  | {% block content %} | ||||||
| 
 | 
 | ||||||
| <div class="order-detail-container"> | <div class="order-detail-container"> | ||||||
|    {% if messages %} |    {% if messages %} | ||||||
|  | @ -19,37 +20,38 @@ | ||||||
|     {% if not error %} |     {% if not error %} | ||||||
|     <div class="row">   |     <div class="row">   | ||||||
|         <div class="col-xs-12 col-md-8 col-md-offset-2"> |         <div class="col-xs-12 col-md-8 col-md-offset-2"> | ||||||
|     		<div class="invoice-title"> |             <div class="invoice-title"> | ||||||
|     			<h2>{% trans "Confirm Order"%}</h2><h3 class="pull-right">{% trans "Order #"%} {{order.id}}</h3> |                 <h2>{% trans "Confirm Order"%}</h2> | ||||||
|     		</div> |             </div> | ||||||
|     		<hr> |             <hr> | ||||||
|     		<div class="row"> |             <div class="row"> | ||||||
|     			<div class="col-xs-6"> |                 <div class="col-xs-6"> | ||||||
|     				<address> |                     <address> | ||||||
|                     <h3><b>{% trans "Billed To:"%}</b></h3> |                     <h3><b>{% trans "Billed To:"%}</b></h3> | ||||||
|     					{{user.name}}<br> |                     {% with request.session.billing_address_data as billing_address %} | ||||||
|                         {{order.billing_address.street_address}},{{order.billing_address.postal_code}}<br> |                         {{request.session.user.name}}<br> {{billing_address|get_value_from_dict:'street_address'}}, {{billing_address|get_value_from_dict:'postal_code'}}<br> | ||||||
|                         {{order.billing_address.city}}, {{order.billing_address.country}}. |                         {{billing_address|get_value_from_dict:'city'}}, {{billing_address|get_value_from_dict:'country'}}. | ||||||
|     				</address> |                     {% endwith %} | ||||||
|     			</div> |                     </address> | ||||||
|  |                 </div> | ||||||
|                 <div class="col-xs-6 text-right"> |                 <div class="col-xs-6 text-right"> | ||||||
|                     <address> |                     <address> | ||||||
|                         <strong>{% trans "Date"%}:</strong><br> |                         <strong>{% trans "Date"%}:</strong><br> | ||||||
|                         {{order.created_at}}<br><br> |                         <span id="order-created_at">{% now "Y-m-d H:i" %}</span><br><br> | ||||||
|                     </address> |                     </address> | ||||||
| 
 | 
 | ||||||
|                 </div> |                 </div> | ||||||
|     		</div> |             </div> | ||||||
|     		<div class="row"> |             <div class="row"> | ||||||
|     			<div class="col-xs-6"> |                 <div class="col-xs-6"> | ||||||
|     				<address> |                     <address> | ||||||
|     					<strong>{% trans "Payment Method:"%}</strong><br> |                         <strong>{% trans "Payment Method:"%}</strong><br> | ||||||
|     					{{order.cc_brand}} ending **** {{order.last4}}<br> |                             {{cc_brand}} {% trans "ending" %} **** {{cc_last4}}<br> | ||||||
|     					{{user.email}} |                             {{request.session.user.email}} | ||||||
|     				</address> |                     </address> | ||||||
|     			</div> |                 </div> | ||||||
|     		</div> |             </div> | ||||||
|     	</div> |         </div> | ||||||
|     </div> |     </div> | ||||||
|      |      | ||||||
|     <div class="row"> |     <div class="row"> | ||||||
|  | @ -57,23 +59,39 @@ | ||||||
|             <h3><b>{% trans "Order summary"%}</b></h3> |             <h3><b>{% trans "Order summary"%}</b></h3> | ||||||
|             <hr> |             <hr> | ||||||
|             <div class="content"> |             <div class="content"> | ||||||
|                 <p><b>{% trans "Cores"%}</b> <span class="pull-right">{{vm.cores}}</span></p> |                 {% with request.session.specs as vm %} | ||||||
|                 <hr> |                     <p><b>{% trans "Cores"%}</b> <span class="pull-right">{{vm.cpu}}</span></p> | ||||||
|                 <p><b>{% trans "Memory"%}</b> <span class="pull-right">{{vm.memory}} GB</span></p> |                     <hr> | ||||||
|                 <hr> |                     <p><b>{% trans "Memory"%}</b> <span class="pull-right">{{vm.memory}} GB</span></p> | ||||||
|                 <p><b>{% trans "Disk space"%}</b> <span class="pull-right">{{vm.disk_size}} GB</span></p> |                     <hr> | ||||||
|                 <hr> |                     <p><b>{% trans "Disk space"%}</b> <span class="pull-right">{{vm.disk_size}} GB</span></p> | ||||||
|                 <h4>{% trans "Total"%}<p class="pull-right"><b>{{vm.price}} CHF</b></p></h4> |                     <hr> | ||||||
|  |                     <p><b>{% trans "Configuration"%}</b> <span class="pull-right">{{request.session.template.name}}</span></p> | ||||||
|  |                     <hr> | ||||||
|  |                     <h4>{% trans "Total"%}<p class="pull-right"><b>{{vm.price}} CHF</b></p></h4> | ||||||
|  |                 {% endwith %} | ||||||
|             </div> |             </div> | ||||||
|             <br/> |             <br/> | ||||||
|             {% url 'datacenterlight:payment' as payment_url %} |             <form method="post"> | ||||||
|             {% if payment_url in request.META.HTTP_REFERER  %} |             {% csrf_token %} | ||||||
|             <div class=" content pull-right"> |             <div class=" content pull-right"> | ||||||
|                 <a href="{{next_url}}" ><button class="btn btn-info">{% trans "Finish Configuration"%}</button></a> |                 <a href="{{next_url}}" ><button class="btn btn-info">{% trans "Place order"%}</button></a> | ||||||
|             </div> |             </div> | ||||||
|             {% endif %} |             </form> | ||||||
|         </div> |         </div> | ||||||
|     </div> |     </div> | ||||||
|     {% endif %} |     {% endif %} | ||||||
| </div> | </div> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | <script type="text/javascript"> | ||||||
|  | 
 | ||||||
|  |     window.onload = function () { | ||||||
|  |             var locale_date = moment.utc(document.getElementById("order-created_at").textContent,'YYYY-MM-DD HH:mm').toDate(); | ||||||
|  |             locale_date =  moment(locale_date).format("YYYY-MM-DD h:mm:ss a"); | ||||||
|  |             document.getElementById('order-created_at').innerHTML = locale_date; | ||||||
|  | 
 | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
| {%endblock%} | {%endblock%} | ||||||
|  |  | ||||||
|  | @ -21,4 +21,14 @@ def change_lang(context, lang=None, *args, **kwargs): | ||||||
|         activate(cur_language) |         activate(cur_language) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     return "%s" % url |     return "%s" % url | ||||||
|  | 
 | ||||||
|  | @register.filter('get_value_from_dict') | ||||||
|  | def get_value_from_dict(dict_data, key): | ||||||
|  |     """ | ||||||
|  |     usage example {{ your_dict|get_value_from_dict:your_key }} | ||||||
|  |     """ | ||||||
|  |     if key: | ||||||
|  |         return dict_data.get(key) | ||||||
|  |     else : | ||||||
|  |         return "" | ||||||
|  |  | ||||||
|  | @ -10,7 +10,7 @@ urlpatterns = [ | ||||||
|     url(r'^/landing/?$', LandingProgramView.as_view(), name='landing'), |     url(r'^/landing/?$', LandingProgramView.as_view(), name='landing'), | ||||||
|     url(r'^/pricing/?$', PricingView.as_view(), name='pricing'), |     url(r'^/pricing/?$', PricingView.as_view(), name='pricing'), | ||||||
|     url(r'^/payment/?$', PaymentOrderView.as_view(), name='payment'), |     url(r'^/payment/?$', PaymentOrderView.as_view(), name='payment'), | ||||||
|     url(r'^/order-confirmation/(?P<pk>\d+)/?$', OrderConfirmationView.as_view(), name='order_confirmation'), |     url(r'^/order-confirmation/?$', OrderConfirmationView.as_view(), name='order_confirmation'), | ||||||
|     url(r'^/order-success/?$', SuccessView.as_view(), name='order_success'), |     url(r'^/order-success/?$', SuccessView.as_view(), name='order_success'), | ||||||
|     url(r'^/beta_access?$', BetaAccessView.as_view(), name='beta_access'), |     url(r'^/beta_access?$', BetaAccessView.as_view(), name='beta_access'), | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | @ -12,7 +12,9 @@ from django import forms | ||||||
| from django.core.exceptions import ValidationError | from django.core.exceptions import ValidationError | ||||||
| from django.views.decorators.cache import cache_control | from django.views.decorators.cache import cache_control | ||||||
| from django.conf import settings | from django.conf import settings | ||||||
|  | from django.utils.translation import ugettext_lazy as _ | ||||||
| from utils.forms import BillingAddressForm, UserBillingAddressForm | from utils.forms import BillingAddressForm, UserBillingAddressForm | ||||||
|  | from utils.models import BillingAddress | ||||||
| from membership.models import StripeCustomer | from membership.models import StripeCustomer | ||||||
| from hosting.models import HostingOrder, HostingBill | from hosting.models import HostingOrder, HostingBill | ||||||
| from utils.stripe_utils import StripeUtils | from utils.stripe_utils import StripeUtils | ||||||
|  | @ -31,9 +33,14 @@ class SuccessView(TemplateView): | ||||||
|     def get(self, request, *args, **kwargs): |     def get(self, request, *args, **kwargs): | ||||||
|         if 'specs' not in request.session or 'user' not in request.session: |         if 'specs' not in request.session or 'user' not in request.session: | ||||||
|             return HttpResponseRedirect(reverse('datacenterlight:index')) |             return HttpResponseRedirect(reverse('datacenterlight:index')) | ||||||
|         else : |         elif 'token' not in request.session: | ||||||
|             del request.session['specs'] |             return HttpResponseRedirect(reverse('datacenterlight:payment'))             | ||||||
|             del request.session['user'] |         elif 'order_confirmation' not in request.session: | ||||||
|  |             return HttpResponseRedirect(reverse('datacenterlight:order_confirmation'))             | ||||||
|  |         else: | ||||||
|  |             for session_var in ['specs', 'user', 'template', 'billing_address', 'billing_address_data', 'token', 'customer']: | ||||||
|  |                 if session_var in request.session: | ||||||
|  |                     del request.session[session_var] | ||||||
|         return render(request, self.template_name) |         return render(request, self.template_name) | ||||||
| 
 | 
 | ||||||
| class PricingView(TemplateView): | class PricingView(TemplateView): | ||||||
|  | @ -187,15 +194,14 @@ class IndexView(CreateView): | ||||||
|      |      | ||||||
|     @cache_control(no_cache=True, must_revalidate=True, no_store=True) |     @cache_control(no_cache=True, must_revalidate=True, no_store=True) | ||||||
|     def get(self, request, *args, **kwargs): |     def get(self, request, *args, **kwargs): | ||||||
|         if 'specs' in request.session : |         for session_var in ['specs', 'user', 'billing_address_data']: | ||||||
|             del request.session['specs'] |             if session_var in request.session: | ||||||
|         if 'user' in request.session : |                 del request.session[session_var] | ||||||
|             del request.session['user'] |  | ||||||
|         try: |         try: | ||||||
|             manager = OpenNebulaManager() |             manager = OpenNebulaManager() | ||||||
|             templates = manager.get_templates() |             templates = manager.get_templates() | ||||||
|             context = { |             context = { | ||||||
|                 'templates': VirtualMachineTemplateSerializer(templates, many=True).data, |                 'templates': VirtualMachineTemplateSerializer(templates, many=True).data | ||||||
|             } |             } | ||||||
|         except: |         except: | ||||||
|             messages.error( request, |             messages.error( request, | ||||||
|  | @ -224,14 +230,16 @@ class IndexView(CreateView): | ||||||
|         try: |         try: | ||||||
|             name = name_field.clean(name) |             name = name_field.clean(name) | ||||||
|         except ValidationError as err: |         except ValidationError as err: | ||||||
|             messages.add_message(self.request, messages.ERROR, '%(value) is not a proper name.'.format(name)) |             msg='{} {}.'.format(name, _('is not a proper name')) | ||||||
|             return HttpResponseRedirect(reverse('datacenterlight:index')) |             messages.add_message(self.request, messages.ERROR, msg, extra_tags='name') | ||||||
|  |             return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form") | ||||||
| 
 | 
 | ||||||
|         try:     |         try:     | ||||||
|             email = email_field.clean(email) |             email = email_field.clean(email) | ||||||
|         except ValidationError as err: |         except ValidationError as err: | ||||||
|             messages.add_message(self.request, messages.ERROR, '%(value) is not a proper email.'.format(email)) |             msg='{} {}.'.format(email, _('is not a proper email')) | ||||||
|             return HttpResponseRedirect(reverse('datacenterlight:index')) |             messages.add_message(self.request, messages.ERROR, msg, extra_tags='email') | ||||||
|  |             return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form") | ||||||
| 
 | 
 | ||||||
|         specs = { |         specs = { | ||||||
|             'cpu': cores, |             'cpu': cores, | ||||||
|  | @ -323,11 +331,27 @@ class WhyDataCenterLightView(IndexView): | ||||||
| class PaymentOrderView(FormView): | class PaymentOrderView(FormView): | ||||||
|     template_name = 'hosting/payment.html' |     template_name = 'hosting/payment.html' | ||||||
|     form_class = BillingAddressForm |     form_class = BillingAddressForm | ||||||
|  |      | ||||||
|  |     def get_form_kwargs(self): | ||||||
|  |         form_kwargs = super(PaymentOrderView, self).get_form_kwargs() | ||||||
|  |         billing_address_data = self.request.session.get('billing_address_data') | ||||||
|  |         if billing_address_data: | ||||||
|  |             form_kwargs.update({ | ||||||
|  |                 'initial': { | ||||||
|  |                     'street_address': billing_address_data['street_address'], | ||||||
|  |                     'city': billing_address_data['city'], | ||||||
|  |                     'postal_code': billing_address_data['postal_code'], | ||||||
|  |                     'country': billing_address_data['country'], | ||||||
|  |                 } | ||||||
|  |             }) | ||||||
|  |         return form_kwargs | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|     def get_context_data(self, **kwargs): |     def get_context_data(self, **kwargs): | ||||||
|         context = super(PaymentOrderView, self).get_context_data(**kwargs) |         context = super(PaymentOrderView, self).get_context_data(**kwargs) | ||||||
|         context.update({ |         context.update({ | ||||||
|             'stripe_key': settings.STRIPE_API_PUBLIC_KEY |             'stripe_key': settings.STRIPE_API_PUBLIC_KEY, | ||||||
|  |             'site_url': reverse('datacenterlight:index') | ||||||
|         }) |         }) | ||||||
|         return context |         return context | ||||||
| 
 | 
 | ||||||
|  | @ -342,13 +366,9 @@ class PaymentOrderView(FormView): | ||||||
|         if form.is_valid(): |         if form.is_valid(): | ||||||
|             # Get billing address data |             # Get billing address data | ||||||
|             billing_address_data = form.cleaned_data |             billing_address_data = form.cleaned_data | ||||||
|             context = self.get_context_data() |  | ||||||
|             template = request.session.get('template') |  | ||||||
|             specs = request.session.get('specs') |  | ||||||
|             user = request.session.get('user') |  | ||||||
|             vm_template_id = template.get('id', 1) |  | ||||||
|             final_price = specs.get('price') |  | ||||||
|             token = form.cleaned_data.get('token') |             token = form.cleaned_data.get('token') | ||||||
|  |             user = request.session.get('user') | ||||||
|  |              | ||||||
|             try: |             try: | ||||||
|                 custom_user = CustomUser.objects.get(email=user.get('email')) |                 custom_user = CustomUser.objects.get(email=user.get('email')) | ||||||
|             except CustomUser.DoesNotExist: |             except CustomUser.DoesNotExist: | ||||||
|  | @ -360,7 +380,6 @@ class PaymentOrderView(FormView): | ||||||
|                                     app='dcl',  |                                     app='dcl',  | ||||||
|                                     base_url=None, send_email=False) |                                     base_url=None, send_email=False) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|             # Get or create stripe customer |             # Get or create stripe customer | ||||||
|             customer = StripeCustomer.get_or_create(email=user.get('email'), |             customer = StripeCustomer.get_or_create(email=user.get('email'), | ||||||
|                                                     token=token) |                                                     token=token) | ||||||
|  | @ -370,115 +389,131 @@ class PaymentOrderView(FormView): | ||||||
| 
 | 
 | ||||||
|             # Create Billing Address |             # Create Billing Address | ||||||
|             billing_address = form.save() |             billing_address = form.save() | ||||||
| 
 |             request.session['billing_address_data'] = billing_address_data | ||||||
|             # Make stripe charge to a customer |             request.session['billing_address'] = billing_address.id | ||||||
|             stripe_utils = StripeUtils() |             request.session['token'] = token | ||||||
|             charge_response = stripe_utils.make_charge(amount=final_price, |             request.session['customer'] = customer.id | ||||||
|                                                        customer=customer.stripe_id) |             return HttpResponseRedirect(reverse('datacenterlight:order_confirmation')) | ||||||
|             charge = charge_response.get('response_object') |  | ||||||
| 
 |  | ||||||
|             # Check if the payment was approved |  | ||||||
|             if not charge: |  | ||||||
|                 context.update({ |  | ||||||
|                     'paymentError': charge_response.get('error'), |  | ||||||
|                     'form': form |  | ||||||
|                 }) |  | ||||||
|                 return render(request, self.template_name, context) |  | ||||||
| 
 |  | ||||||
|             charge = charge_response.get('response_object') |  | ||||||
|          |  | ||||||
|             # Create OpenNebulaManager |  | ||||||
|             manager = OpenNebulaManager(email=settings.OPENNEBULA_USERNAME, |  | ||||||
|                                         password=settings.OPENNEBULA_PASSWORD) |  | ||||||
|              |  | ||||||
|             # Create a vm using logged user |  | ||||||
|             vm_id = manager.create_vm( |  | ||||||
|                 template_id=vm_template_id, |  | ||||||
|                 specs=specs, |  | ||||||
|                 vm_name="{email}-{template_name}-{date}".format( |  | ||||||
|                        email=user.get('email'),  |  | ||||||
|                        template_name=template.get('name'), |  | ||||||
|                        date=int(datetime.now().strftime("%s"))) |  | ||||||
|             ) |  | ||||||
|              |  | ||||||
|             # Create a Hosting Order |  | ||||||
|             order = HostingOrder.create( |  | ||||||
|                 price=final_price, |  | ||||||
|                 vm_id=vm_id, |  | ||||||
|                 customer=customer, |  | ||||||
|                 billing_address=billing_address |  | ||||||
|             ) |  | ||||||
|              |  | ||||||
|             # Create a Hosting Bill |  | ||||||
|             bill = HostingBill.create( |  | ||||||
|                 customer=customer, billing_address=billing_address) |  | ||||||
| 
 |  | ||||||
|             # Create Billing Address for User if he does not have one |  | ||||||
|             if not customer.user.billing_addresses.count(): |  | ||||||
|                 billing_address_data.update({ |  | ||||||
|                     'user': customer.user.id |  | ||||||
|                 }) |  | ||||||
|                 billing_address_user_form = UserBillingAddressForm( |  | ||||||
|                     billing_address_data) |  | ||||||
|                 billing_address_user_form.is_valid() |  | ||||||
|                 billing_address_user_form.save() |  | ||||||
| 
 |  | ||||||
|             # Associate an order with a stripe payment |  | ||||||
|             order.set_stripe_charge(charge) |  | ||||||
| 
 |  | ||||||
|             # If the Stripe payment was successed, set order status approved |  | ||||||
|             order.set_approved() |  | ||||||
|              |  | ||||||
|             vm = VirtualMachineSerializer(manager.get_vm(vm_id)).data |  | ||||||
|              |  | ||||||
|             context = { |  | ||||||
|                 'name': user.get('name'), |  | ||||||
|                 'email': user.get('email'), |  | ||||||
|                 'cores': specs.get('cpu'), |  | ||||||
|                 'memory': specs.get('memory'), |  | ||||||
|                 'storage': specs.get('disk_size'), |  | ||||||
|                 'price': specs.get('price'), |  | ||||||
|                 'template': template.get('name'), |  | ||||||
|                 'vm.name': vm['name'], |  | ||||||
|                 'vm.id': vm['vm_id'], |  | ||||||
|                 'order.id': order.id |  | ||||||
|             } |  | ||||||
|             email_data = { |  | ||||||
|                 'subject': "Data Center Light Order from %s" % context['email'], |  | ||||||
|                 'from_email': '(Data Center Light) Data Center Light Support <support@datacenterlight.ch>', |  | ||||||
|                 'to': ['info@ungleich.ch'], |  | ||||||
|                 'body': "\n".join(["%s=%s" % (k, v) for (k, v) in context.items()]), |  | ||||||
|                 'reply_to': [context['email']], |  | ||||||
|             } |  | ||||||
|             email = EmailMessage(**email_data) |  | ||||||
|             email.send() |  | ||||||
|             return HttpResponseRedirect(reverse('datacenterlight:order_confirmation', kwargs={'pk': order.id})) |  | ||||||
|         else: |         else: | ||||||
|             return self.form_invalid(form) |             return self.form_invalid(form) | ||||||
| 
 | 
 | ||||||
| class OrderConfirmationView(DetailView): | class OrderConfirmationView(DetailView): | ||||||
|     template_name = "datacenterlight/order_detail.html" |     template_name = "datacenterlight/order_detail.html" | ||||||
|  |     payment_template_name = 'hosting/payment.html' | ||||||
|     context_object_name = "order" |     context_object_name = "order" | ||||||
|     model = HostingOrder |     model = HostingOrder | ||||||
|     def get_context_data(self, **kwargs): |      | ||||||
|         # Get context |     @cache_control(no_cache=True, must_revalidate=True, no_store=True) | ||||||
|         context = super(DetailView, self).get_context_data(**kwargs) |     def get(self, request, *args, **kwargs): | ||||||
|         obj = self.get_object() |         if 'specs' not in request.session or 'user' not in request.session: | ||||||
|  |             return HttpResponseRedirect(reverse('datacenterlight:index')) | ||||||
|  |         if 'token' not in request.session: | ||||||
|  |             return HttpResponseRedirect(reverse('datacenterlight:payment')) | ||||||
|  |         stripe_customer_id = request.session.get('customer') | ||||||
|  |         customer = StripeCustomer.objects.filter(id=stripe_customer_id).first() | ||||||
|  |         stripe_utils = StripeUtils() | ||||||
|  |         card_details = stripe_utils.get_card_details(customer.stripe_id, request.session.get('token')) | ||||||
|  |         context = { | ||||||
|  |             'site_url': reverse('datacenterlight:index'), | ||||||
|  |             'cc_last4' : card_details.get('response_object').get('last4'), | ||||||
|  |             'cc_brand' : card_details.get('response_object').get('brand') | ||||||
|  |         } | ||||||
|  |         return render(request, self.template_name, context) | ||||||
|  |     | ||||||
|  |     def post(self, request, *args, **kwargs): | ||||||
|  |         template = request.session.get('template') | ||||||
|  |         specs = request.session.get('specs') | ||||||
|  |         user = request.session.get('user') | ||||||
|  |         stripe_customer_id = request.session.get('customer') | ||||||
|  |         customer = StripeCustomer.objects.filter(id=stripe_customer_id).first() | ||||||
|  |         billing_address_data = request.session.get('billing_address_data') | ||||||
|  |         billing_address_id = request.session.get('billing_address') | ||||||
|  |         billing_address = BillingAddress.objects.filter(id=billing_address_id).first() | ||||||
|  |         token = request.session.get('token') | ||||||
|  |         vm_template_id = template.get('id', 1) | ||||||
|  |         final_price = specs.get('price') | ||||||
|  | 
 | ||||||
|  |         # Make stripe charge to a customer | ||||||
|  |         stripe_utils = StripeUtils() | ||||||
|  |         charge_response = stripe_utils.make_charge(amount=final_price, | ||||||
|  |                                                    customer=customer.stripe_id) | ||||||
|  |         charge = charge_response.get('response_object') | ||||||
|  | 
 | ||||||
|  |         # Check if the payment was approved | ||||||
|  |         if not charge: | ||||||
|  |             context.update({ | ||||||
|  |                 'paymentError': charge_response.get('error') | ||||||
|  |                 # TODO add logic in payment form to autofill data  | ||||||
|  |                 #'form': form | ||||||
|  |             }) | ||||||
|  |             return render(request, self.payment_template_name, context) | ||||||
|  | 
 | ||||||
|  |         charge = charge_response.get('response_object') | ||||||
|  |          | ||||||
|  |         # Create OpenNebulaManager | ||||||
|         manager = OpenNebulaManager(email=settings.OPENNEBULA_USERNAME, |         manager = OpenNebulaManager(email=settings.OPENNEBULA_USERNAME, | ||||||
|                                     password=settings.OPENNEBULA_PASSWORD) |                                     password=settings.OPENNEBULA_PASSWORD) | ||||||
|         try: |          | ||||||
|             vm = manager.get_vm(obj.vm_id) |         # Create a vm using oneadmin, also specify the name | ||||||
|             context['vm'] = VirtualMachineSerializer(vm).data |         vm_id = manager.create_vm( | ||||||
|             context['next_url'] = reverse('datacenterlight:order_success') |             template_id=vm_template_id, | ||||||
|         except WrongIdError: |             specs=specs, | ||||||
|             messages.error(self.request, |             vm_name="{email}-{template_name}-{date}".format( | ||||||
|                            'The VM you are looking for is unavailable at the moment. \ |                    email=user.get('email'),  | ||||||
|                             Please contact Data Center Light support.' |                    template_name=template.get('name'), | ||||||
|                            ) |                    date=int(datetime.now().strftime("%s"))) | ||||||
|             self.kwargs['error'] = 'WrongIdError' |         ) | ||||||
|             context['error'] = 'WrongIdError' |          | ||||||
|         except ConnectionRefusedError: |         # Create a Hosting Order | ||||||
|             messages.error(self.request, |         order = HostingOrder.create( | ||||||
|                            'In order to create a VM, you need to create/upload your SSH KEY first.' |             price=final_price, | ||||||
|                            ) |             vm_id=vm_id, | ||||||
|         return context |             customer=customer, | ||||||
|  |             billing_address=billing_address | ||||||
|  |         ) | ||||||
|  |          | ||||||
|  |         # Create a Hosting Bill | ||||||
|  |         bill = HostingBill.create( | ||||||
|  |             customer=customer, billing_address=billing_address) | ||||||
|  | 
 | ||||||
|  |         # Create Billing Address for User if he does not have one | ||||||
|  |         if not customer.user.billing_addresses.count(): | ||||||
|  |             billing_address_data.update({ | ||||||
|  |                 'user': customer.user.id | ||||||
|  |             }) | ||||||
|  |             billing_address_user_form = UserBillingAddressForm( | ||||||
|  |                 billing_address_data) | ||||||
|  |             billing_address_user_form.is_valid() | ||||||
|  |             billing_address_user_form.save() | ||||||
|  | 
 | ||||||
|  |         # Associate an order with a stripe payment | ||||||
|  |         order.set_stripe_charge(charge) | ||||||
|  | 
 | ||||||
|  |         # If the Stripe payment was successed, set order status approved | ||||||
|  |         order.set_approved() | ||||||
|  |          | ||||||
|  |         vm = VirtualMachineSerializer(manager.get_vm(vm_id)).data | ||||||
|  |          | ||||||
|  |         context = { | ||||||
|  |             'name': user.get('name'), | ||||||
|  |             'email': user.get('email'), | ||||||
|  |             'cores': specs.get('cpu'), | ||||||
|  |             'memory': specs.get('memory'), | ||||||
|  |             'storage': specs.get('disk_size'), | ||||||
|  |             'price': specs.get('price'), | ||||||
|  |             'template': template.get('name'), | ||||||
|  |             'vm.name': vm['name'], | ||||||
|  |             'vm.id': vm['vm_id'], | ||||||
|  |             'order.id': order.id | ||||||
|  |         } | ||||||
|  |         email_data = { | ||||||
|  |             'subject': settings.DCL_TEXT + " Order from %s" % context['email'], | ||||||
|  |             'from_email': settings.DCL_SUPPORT_FROM_ADDRESS, | ||||||
|  |             'to': ['info@ungleich.ch'], | ||||||
|  |             'body': "\n".join(["%s=%s" % (k, v) for (k, v) in context.items()]), | ||||||
|  |             'reply_to': [context['email']], | ||||||
|  |         } | ||||||
|  |         email = EmailMessage(**email_data) | ||||||
|  |         email.send() | ||||||
|  |         request.session['order_confirmation'] = True | ||||||
|  |         return HttpResponseRedirect(reverse('datacenterlight:order_success')) | ||||||
|  |  | ||||||
|  | @ -39,27 +39,13 @@ | ||||||
|     <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> |     <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> | ||||||
|     <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> |     <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> | ||||||
|     <!--[if lt IE 9]> |     <!--[if lt IE 9]> | ||||||
|     <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> |         <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> | ||||||
|     <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> |         <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> | ||||||
|     <![endif]--> |     <![endif]--> | ||||||
| 
 | 
 | ||||||
|     <script> |     <!-- Google analytics --> | ||||||
|         (function (i, s, o, g, r, a, m) { |     {% include 'google_analytics.html' %} | ||||||
|             i['GoogleAnalyticsObject'] = r; |     <!-- End Google Analytics --> | ||||||
|             i[r] = i[r] || function () { |  | ||||||
|                         (i[r].q = i[r].q || []).push(arguments) |  | ||||||
|                     }, i[r].l = 1 * new Date(); |  | ||||||
|             a = s.createElement(o), |  | ||||||
|                     m = s.getElementsByTagName(o)[0]; |  | ||||||
|             a.async = 1; |  | ||||||
|             a.src = g; |  | ||||||
|             m.parentNode.insertBefore(a, m) |  | ||||||
|         })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga'); |  | ||||||
| 
 |  | ||||||
|         ga('create', 'UA-62285904-2', 'auto'); |  | ||||||
|         ga('send', 'pageview'); |  | ||||||
| 
 |  | ||||||
|     </script> |  | ||||||
| </head> | </head> | ||||||
| 
 | 
 | ||||||
| <body> | <body> | ||||||
|  |  | ||||||
|  | @ -118,6 +118,7 @@ INSTALLED_APPS = ( | ||||||
| 
 | 
 | ||||||
| MIDDLEWARE_CLASSES = ( | MIDDLEWARE_CLASSES = ( | ||||||
|     'django.contrib.sessions.middleware.SessionMiddleware', |     'django.contrib.sessions.middleware.SessionMiddleware', | ||||||
|  |     'utils.middleware.MultipleProxyMiddleware', | ||||||
|     'django.middleware.common.CommonMiddleware', |     'django.middleware.common.CommonMiddleware', | ||||||
|     'django.middleware.csrf.CsrfViewMiddleware', |     'django.middleware.csrf.CsrfViewMiddleware', | ||||||
|     'django.contrib.auth.middleware.AuthenticationMiddleware', |     'django.contrib.auth.middleware.AuthenticationMiddleware', | ||||||
|  | @ -138,6 +139,7 @@ TEMPLATES = [ | ||||||
|     { |     { | ||||||
|         'BACKEND': 'django.template.backends.django.DjangoTemplates', |         'BACKEND': 'django.template.backends.django.DjangoTemplates', | ||||||
|         'DIRS': [os.path.join(PROJECT_DIR, 'cms_templates/'), |         'DIRS': [os.path.join(PROJECT_DIR, 'cms_templates/'), | ||||||
|  |                  os.path.join(PROJECT_DIR, 'templates'), | ||||||
|                  os.path.join(PROJECT_DIR, 'cms_templates/djangocms_blog/'), |                  os.path.join(PROJECT_DIR, 'cms_templates/djangocms_blog/'), | ||||||
|                  os.path.join(PROJECT_DIR, 'membership'), |                  os.path.join(PROJECT_DIR, 'membership'), | ||||||
|                  os.path.join(PROJECT_DIR, 'hosting/templates/'), |                  os.path.join(PROJECT_DIR, 'hosting/templates/'), | ||||||
|  | @ -161,6 +163,7 @@ TEMPLATES = [ | ||||||
|                 "django.contrib.messages.context_processors.messages", |                 "django.contrib.messages.context_processors.messages", | ||||||
|                 'sekizai.context_processors.sekizai', |                 'sekizai.context_processors.sekizai', | ||||||
|                 'cms.context_processors.cms_settings', |                 'cms.context_processors.cms_settings', | ||||||
|  |                 'utils.context_processor.google_analytics', | ||||||
|             ], |             ], | ||||||
|         }, |         }, | ||||||
|     }, |     }, | ||||||
|  | @ -509,3 +512,12 @@ OPENNEBULA_ENDPOINT = env('OPENNEBULA_ENDPOINT') | ||||||
| # dcl email configurations | # dcl email configurations | ||||||
| DCL_TEXT = env('DCL_TEXT') | DCL_TEXT = env('DCL_TEXT') | ||||||
| DCL_SUPPORT_FROM_ADDRESS = env('DCL_SUPPORT_FROM_ADDRESS') | DCL_SUPPORT_FROM_ADDRESS = env('DCL_SUPPORT_FROM_ADDRESS') | ||||||
|  | 
 | ||||||
|  | # Settings for Google analytics | ||||||
|  | GOOGLE_ANALYTICS_PROPERTY_IDS = { | ||||||
|  |     'datacenterlight.ch': 'UA-62285904-9', | ||||||
|  |     'digitalglarus.ch': 'UA-62285904-2', | ||||||
|  |     '127.0.0.1:8000': 'localhost', | ||||||
|  |     'dynamicweb-development.ungleich.ch': 'development', | ||||||
|  |     'dynamicweb-staging.ungleich.ch': 'staging' | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ msgid "" | ||||||
| msgstr "" | msgstr "" | ||||||
| "Project-Id-Version: PACKAGE VERSION\n" | "Project-Id-Version: PACKAGE VERSION\n" | ||||||
| "Report-Msgid-Bugs-To: \n" | "Report-Msgid-Bugs-To: \n" | ||||||
| "POT-Creation-Date: 2017-06-23 02:28+0530\n" | "POT-Creation-Date: 2017-07-01 02:09+0530\n" | ||||||
| "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | ||||||
| "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | ||||||
| "Language-Team: LANGUAGE <LL@li.org>\n" | "Language-Team: LANGUAGE <LL@li.org>\n" | ||||||
|  | @ -26,47 +26,47 @@ msgstr "Dein Account wurde noch nicht aktiviert." | ||||||
| msgid "Paste here your public key" | msgid "Paste here your public key" | ||||||
| msgstr "Fügen Sie Ihren public key ein" | msgstr "Fügen Sie Ihren public key ein" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/base_short.html:67 | #: templates/hosting/base_short.html:68 | ||||||
| msgid "My Virtual Machines" | msgid "My Virtual Machines" | ||||||
| msgstr "Meine virtuellen Maschinen" | msgstr "Meine virtuellen Maschinen" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/base_short.html:72 templates/hosting/orders.html.py:12 | #: templates/hosting/base_short.html:73 templates/hosting/orders.html.py:12 | ||||||
| msgid "My Orders" | msgid "My Orders" | ||||||
| msgstr "Meine Bestellungen" | msgstr "Meine Bestellungen" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/base_short.html:81 | #: templates/hosting/base_short.html:82 | ||||||
| msgid "Keys" | msgid "Keys" | ||||||
| msgstr "Schlüssel" | msgstr "Schlüssel" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/base_short.html:86 | #: templates/hosting/base_short.html:87 | ||||||
| msgid "Notifications " | msgid "Notifications " | ||||||
| msgstr "Benachrichtigungen" | msgstr "Benachrichtigungen" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/base_short.html:89 | #: templates/hosting/base_short.html:90 | ||||||
| msgid "Logout" | msgid "Logout" | ||||||
| msgstr "Abmelden" | msgstr "Abmelden" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/base_short.html:94 | #: templates/hosting/base_short.html:95 | ||||||
| msgid "How it works" | msgid "How it works" | ||||||
| msgstr "So funktioniert es" | msgstr "So funktioniert es" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/base_short.html:97 | #: templates/hosting/base_short.html:98 | ||||||
| msgid "Your infrastructure" | msgid "Your infrastructure" | ||||||
| msgstr "deine Infrastruktur" | msgstr "deine Infrastruktur" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/base_short.html:100 | #: templates/hosting/base_short.html:101 | ||||||
| msgid "Our inftrastructure" | msgid "Our inftrastructure" | ||||||
| msgstr "Unsere Infrastruktur" | msgstr "Unsere Infrastruktur" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/base_short.html:103 | #: templates/hosting/base_short.html:104 | ||||||
| msgid "Pricing" | msgid "Pricing" | ||||||
| msgstr "Preise" | msgstr "Preise" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/base_short.html:106 | #: templates/hosting/base_short.html:107 | ||||||
| msgid "Contact" | msgid "Contact" | ||||||
| msgstr "Kontakt" | msgstr "Kontakt" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/base_short.html:109 | #: templates/hosting/base_short.html:110 | ||||||
| #: templates/hosting/confirm_reset_password.html:38 | #: templates/hosting/confirm_reset_password.html:38 | ||||||
| #: templates/hosting/login.html:17 templates/hosting/login.html.py:26 | #: templates/hosting/login.html:17 templates/hosting/login.html.py:26 | ||||||
| #: templates/hosting/reset_password.html:32 templates/hosting/signup.html:30 | #: templates/hosting/reset_password.html:32 templates/hosting/signup.html:30 | ||||||
|  | @ -347,11 +347,11 @@ msgstr "Bestellung stornieren" | ||||||
| msgid "Do You want to delete your order?" | msgid "Do You want to delete your order?" | ||||||
| msgstr "Willst du deine Bestellung löschen?" | msgstr "Willst du deine Bestellung löschen?" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/orders.html:63 templates/hosting/user_keys.html.py:62 | #: templates/hosting/orders.html:63 templates/hosting/user_keys.html.py:63 | ||||||
| msgid "Close" | msgid "Close" | ||||||
| msgstr "Schliessen" | msgstr "Schliessen" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/orders.html:65 templates/hosting/user_keys.html.py:64 | #: templates/hosting/orders.html:65 templates/hosting/user_keys.html.py:65 | ||||||
| msgid "Delete" | msgid "Delete" | ||||||
| msgstr "Löschen" | msgstr "Löschen" | ||||||
| 
 | 
 | ||||||
|  | @ -359,31 +359,36 @@ msgstr "Löschen" | ||||||
| msgid "Billing Amount" | msgid "Billing Amount" | ||||||
| msgstr "Rechnungsbetrag" | msgstr "Rechnungsbetrag" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/payment.html:35 | #: templates/hosting/payment.html:26 | ||||||
|  | #: templates/hosting/virtual_machine_detail.html:98 | ||||||
|  | msgid "Configuration" | ||||||
|  | msgstr "Konfiguration" | ||||||
|  | 
 | ||||||
|  | #: templates/hosting/payment.html:38 | ||||||
| msgid "Billing Address" | msgid "Billing Address" | ||||||
| msgstr "Rechnungsadresse" | msgstr "Rechnungsadresse" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/payment.html:49 | #: templates/hosting/payment.html:52 | ||||||
| msgid "Payment Details" | msgid "Payment Details" | ||||||
| msgstr "Rechnungsdetails" | msgstr "Rechnungsdetails" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/payment.html:62 | #: templates/hosting/payment.html:65 | ||||||
| msgid "Submit Payment" | msgid "Submit Payment" | ||||||
| msgstr "Betrag überweisen" | msgstr "Betrag überweisen" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/payment.html:81 | #: templates/hosting/payment.html:84 | ||||||
| msgid "CARD NUMBER" | msgid "CARD NUMBER" | ||||||
| msgstr "Kreditkartennummer" | msgstr "Kreditkartennummer" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/payment.html:86 | #: templates/hosting/payment.html:89 | ||||||
| msgid "Valid Card Number" | msgid "Valid Card Number" | ||||||
| msgstr "Gültige Kreditkartennummer" | msgstr "Gültige Kreditkartennummer" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/payment.html:95 | #: templates/hosting/payment.html:98 | ||||||
| msgid "EXPIRATION DATE" | msgid "EXPIRATION DATE" | ||||||
| msgstr "Ablaufdatum" | msgstr "Ablaufdatum" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/payment.html:106 | #: templates/hosting/payment.html:109 | ||||||
| msgid "CV CODE" | msgid "CV CODE" | ||||||
| msgstr "CV Code" | msgstr "CV Code" | ||||||
| 
 | 
 | ||||||
|  | @ -425,13 +430,13 @@ msgstr "Schlüssel hinzufügen" | ||||||
| msgid "Created at" | msgid "Created at" | ||||||
| msgstr "Erstellt am" | msgstr "Erstellt am" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/user_keys.html:42 | #: templates/hosting/user_keys.html:43 | ||||||
| #, fuzzy | #, fuzzy | ||||||
| #| msgid "Delete" | #| msgid "Delete" | ||||||
| msgid "Delete Key" | msgid "Delete Key" | ||||||
| msgstr "Löschen" | msgstr "Löschen" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/user_keys.html:55 | #: templates/hosting/user_keys.html:56 | ||||||
| #, fuzzy | #, fuzzy | ||||||
| #| msgid "Do You want do delete your order?" | #| msgid "Do You want do delete your order?" | ||||||
| msgid "Do You want to delete this key?" | msgid "Do You want to delete this key?" | ||||||
|  | @ -453,10 +458,6 @@ msgstr "Ip nicht zugewiesen" | ||||||
| msgid "Disk" | msgid "Disk" | ||||||
| msgstr "Festplatte" | msgstr "Festplatte" | ||||||
| 
 | 
 | ||||||
| #: templates/hosting/virtual_machine_detail.html:98 |  | ||||||
| msgid "Configuration" |  | ||||||
| msgstr "Konfiguration" |  | ||||||
| 
 |  | ||||||
| #: templates/hosting/virtual_machine_detail.html:108 | #: templates/hosting/virtual_machine_detail.html:108 | ||||||
| msgid "Current pricing" | msgid "Current pricing" | ||||||
| msgstr "Aktueller Preis" | msgstr "Aktueller Preis" | ||||||
|  |  | ||||||
|  | @ -57,7 +57,7 @@ | ||||||
|                     <span class="icon-bar"></span> |                     <span class="icon-bar"></span> | ||||||
|                     <span class="icon-bar"></span> |                     <span class="icon-bar"></span> | ||||||
|                 </button> |                 </button> | ||||||
|                 <a class="navbar-brand topnav" href="{{ request.session.hosting_url}}"><img src="{% static 'datacenterlight/img/logo_black.svg' %}"></a> |                 <a class="navbar-brand topnav" href="{% if site_url %}{{site_url}}{% else %}{{ request.session.hosting_url}}{% endif %}"><img src="{% static 'datacenterlight/img/logo_black.svg' %}"></a> | ||||||
|             </div> |             </div> | ||||||
|             {% if request.user.is_authenticated %} |             {% if request.user.is_authenticated %} | ||||||
|             <!-- Collect the nav links, forms, and other content for toggling --> |             <!-- Collect the nav links, forms, and other content for toggling --> | ||||||
|  | @ -131,6 +131,8 @@ | ||||||
|             <p class="copyright text-muted small">Copyright © ungleich GmbH {% now "Y" %}. All Rights Reserved</p> |             <p class="copyright text-muted small">Copyright © ungleich GmbH {% now "Y" %}. All Rights Reserved</p> | ||||||
|         </div> |         </div> | ||||||
|     </footer> |     </footer> | ||||||
|  |     {% else %} | ||||||
|  |         {% include "datacenterlight/includes/_footer.html" %} | ||||||
|     {% endif %} |     {% endif %} | ||||||
|     <!-- jQuery --> |     <!-- jQuery --> | ||||||
|     <script src="{% static 'hosting/js/jquery.js' %}"></script> |     <script src="{% static 'hosting/js/jquery.js' %}"></script> | ||||||
|  | @ -162,6 +164,12 @@ | ||||||
|     <!-- Gen SSH Key lib --> |     <!-- Gen SSH Key lib --> | ||||||
|     <script type="text/javascript" src="{% static 'hosting/js/gen-ssh-key.js' %}"></script> |     <script type="text/javascript" src="{% static 'hosting/js/gen-ssh-key.js' %}"></script> | ||||||
| 
 | 
 | ||||||
|  |     <!-- Moment --> | ||||||
|  |     <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script> | ||||||
|  |     <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment-with-locales.js"></script> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| </body> | </body> | ||||||
| 
 | 
 | ||||||
| </html> | </html> | ||||||
|  |  | ||||||
|  | @ -35,7 +35,7 @@ | ||||||
|                 <div class="col-xs-6 text-right"> |                 <div class="col-xs-6 text-right"> | ||||||
|                     <address> |                     <address> | ||||||
|                         <strong>{% trans "Date"%}:</strong><br> |                         <strong>{% trans "Date"%}:</strong><br> | ||||||
|                         {{order.created_at}}<br><br> |                         <span id="order-created_at">{{order.created_at|date:'Y-m-d H:i'}}</span><br><br> | ||||||
|                         <strong>{% trans "Status:"%}</strong><br> |                         <strong>{% trans "Status:"%}</strong><br> | ||||||
|                         <strong class="{% if order.status == 'Approved' %}text-success |                         <strong class="{% if order.status == 'Approved' %}text-success | ||||||
|                                        {%else%} text-danger |                                        {%else%} text-danger | ||||||
|  | @ -68,7 +68,7 @@ | ||||||
|                 <hr> |                 <hr> | ||||||
|                 <p><b>{% trans "Disk space"%}</b> <span class="pull-right">{{vm.disk_size}} GB</span></p> |                 <p><b>{% trans "Disk space"%}</b> <span class="pull-right">{{vm.disk_size}} GB</span></p> | ||||||
|                 <hr> |                 <hr> | ||||||
|                 <h4>{% trans "Total"%}<p class="pull-right"><b>{{vm.price}} CHF</b></p></h4> |                                 <h4>{% trans "Total"%}<p class="pull-right"><b>{{vm.price}} CHF</b></p></h4> | ||||||
|             </div> |             </div> | ||||||
|             <br/> |             <br/> | ||||||
|             {% url 'hosting:payment' as payment_url %} |             {% url 'hosting:payment' as payment_url %} | ||||||
|  | @ -81,4 +81,17 @@ | ||||||
|     </div> |     </div> | ||||||
|     {% endif %} |     {% endif %} | ||||||
| </div> | </div> | ||||||
|  | 
 | ||||||
|  |   | ||||||
|  | <script type="text/javascript">  | ||||||
|  | 
 | ||||||
|  |     window.onload = function () { | ||||||
|  |             var locale_date = moment.utc(document.getElementById("order-created_at").textContent,'YYYY-MM-DD HH:mm').toDate(); | ||||||
|  |             locale_date =  moment(locale_date).format("YYYY-MM-DD h:mm:ss a"); | ||||||
|  |             document.getElementById('order-created_at').innerHTML = locale_date; | ||||||
|  | 
 | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
| {%endblock%} | {%endblock%} | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | @ -24,7 +24,7 @@ | ||||||
|                         {% for order in orders %} |                         {% for order in orders %} | ||||||
|                             <tr> |                             <tr> | ||||||
|                                 <td scope="row">{{ order.id }}</td> |                                 <td scope="row">{{ order.id }}</td> | ||||||
|                                 <td>{{ order.created_at }}</td> |                                 <td>{{ order.created_at | date:"M d, Y" }}</td> | ||||||
|                                 <td>{{ order.price }} CHF</td> |                                 <td>{{ order.price }} CHF</td> | ||||||
|                                 <td>{% if order.approved %} |                                 <td>{% if order.approved %} | ||||||
|                                     <span class="text-success strong">{% trans "Approved"%}</span> |                                     <span class="text-success strong">{% trans "Approved"%}</span> | ||||||
|  |  | ||||||
|  | @ -22,6 +22,9 @@ | ||||||
| 								<hr> | 								<hr> | ||||||
| 								<p><b>{%trans "Disk space"%}</b> <span | 								<p><b>{%trans "Disk space"%}</b> <span | ||||||
|                                     class="pull-right">{{request.session.specs.disk_size|floatformat}} GB</span></p> |                                     class="pull-right">{{request.session.specs.disk_size|floatformat}} GB</span></p> | ||||||
|  | 								<hr> | ||||||
|  | 								<p><b>{%trans "Configuration"%}</b> <span | ||||||
|  |                                     class="pull-right">{{request.session.template.name}}</span></p> | ||||||
| 								<hr> | 								<hr> | ||||||
| 								<h4>Total<p | 								<h4>Total<p | ||||||
|                                     class="pull-right"><b>{{request.session.specs.price }} CHF</b></p></h4> |                                     class="pull-right"><b>{{request.session.specs.price }} CHF</b></p></h4> | ||||||
|  |  | ||||||
|  | @ -32,7 +32,8 @@ | ||||||
|                             {% for user_key in keys %} |                             {% for user_key in keys %} | ||||||
|                             <tr>  |                             <tr>  | ||||||
|                                 <td scope="row">{{user_key.name}}</td>  |                                 <td scope="row">{{user_key.name}}</td>  | ||||||
|                                 <td>{{user_key.created_at}}</td>  | 
 | ||||||
|  |                                 <td><span id="ssh-created_at-{{user_key.id}}">{{user_key.created_at|date:'Y-m-d H:i' }}</span></td>  | ||||||
|                                 <td> |                                 <td> | ||||||
|                                     <span class="h3 label label-success"><strong>Active</strong></span> |                                     <span class="h3 label label-success"><strong>Active</strong></span> | ||||||
|                                 </td>  |                                 </td>  | ||||||
|  | @ -92,5 +93,21 @@ | ||||||
|     </script> |     </script> | ||||||
| {% endif %} | {% endif %} | ||||||
| 
 | 
 | ||||||
|  |   | ||||||
|  | <script type="text/javascript">  | ||||||
|  | 
 | ||||||
|  |     window.onload = function () { | ||||||
|  |         {% for user_key in keys %} | ||||||
|  |             // var locale_date = new Date(document.getElementById("ssh-created_at-{{user_key.id}}").textContent).toISOString(); | ||||||
|  |             var locale_date = moment.utc(document.getElementById("ssh-created_at-{{user_key.id}}").textContent,'YYYY-MM-DD HH:mm').toDate(); | ||||||
|  |             locale_date =  moment(locale_date).format("YYYY-MM-DD h:mm:ss a"); | ||||||
|  |             document.getElementById('ssh-created_at-{{user_key.id}}').innerHTML = locale_date; | ||||||
|  | 
 | ||||||
|  |         {% endfor %} | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| {%endblock%} | {%endblock%} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										13
									
								
								templates/google_analytics.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								templates/google_analytics.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | ||||||
|  | {% if GOOGLE_ANALYTICS_PROPERTY_ID %} | ||||||
|  |     <script> | ||||||
|  |         (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ | ||||||
|  |         (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), | ||||||
|  |         m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) | ||||||
|  |         })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); | ||||||
|  | 
 | ||||||
|  |         ga('create', '{{ GOOGLE_ANALYTICS_PROPERTY_ID }}', 'auto'); | ||||||
|  |         ga('send', 'pageview'); | ||||||
|  |     </script> | ||||||
|  | {% else %} | ||||||
|  |     <!-- Empty analytics --> | ||||||
|  | {% endif %} | ||||||
							
								
								
									
										15
									
								
								utils/context_processor.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								utils/context_processor.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | ||||||
|  | from django.conf import settings | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def google_analytics(request): | ||||||
|  |     """ | ||||||
|  |     Use the variables returned in this function to | ||||||
|  |     render your Google Analytics tracking code template. | ||||||
|  |     """ | ||||||
|  |     host = request.get_host() | ||||||
|  |     ga_prop_id = getattr(settings, 'GOOGLE_ANALYTICS_PROPERTY_IDS', False).get(host) | ||||||
|  |     if not settings.DEBUG and ga_prop_id: | ||||||
|  |         return { | ||||||
|  |             'GOOGLE_ANALYTICS_PROPERTY_ID': ga_prop_id | ||||||
|  |         } | ||||||
|  |     return {} | ||||||
							
								
								
									
										17
									
								
								utils/middleware.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								utils/middleware.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | ||||||
|  | class MultipleProxyMiddleware(object): | ||||||
|  |     FORWARDED_FOR_FIELDS = [ | ||||||
|  |         'HTTP_X_FORWARDED_FOR', | ||||||
|  |         'HTTP_X_FORWARDED_HOST', | ||||||
|  |         'HTTP_X_FORWARDED_SERVER', | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     def process_request(self, request): | ||||||
|  |         """ | ||||||
|  |         Rewrites the proxy headers so that only the most | ||||||
|  |         recent proxy is used. | ||||||
|  |         """ | ||||||
|  |         for field in self.FORWARDED_FOR_FIELDS: | ||||||
|  |             if field in request.META: | ||||||
|  |                 if ',' in request.META[field]: | ||||||
|  |                     parts = request.META[field].split(',') | ||||||
|  |                     request.META[field] = parts[-1].strip() | ||||||
|  | @ -77,6 +77,16 @@ class StripeUtils(object): | ||||||
|         } |         } | ||||||
|         return new_card_data |         return new_card_data | ||||||
| 
 | 
 | ||||||
|  |     @handleStripeError | ||||||
|  |     def get_card_details(self, customer_id, token): | ||||||
|  |         customer = stripe.Customer.retrieve(customer_id) | ||||||
|  |         credit_card_raw_data = customer.sources.data.pop() | ||||||
|  |         card_details = { | ||||||
|  |             'last4': credit_card_raw_data.last4, | ||||||
|  |             'brand': credit_card_raw_data.brand | ||||||
|  |         } | ||||||
|  |         return card_details | ||||||
|  | 
 | ||||||
|     def check_customer(self, id, user, token): |     def check_customer(self, id, user, token): | ||||||
|         customers = self.stripe.Customer.all() |         customers = self.stripe.Customer.all() | ||||||
|         if not customers.get('data'): |         if not customers.get('data'): | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue