From cc0f042c00fc68b00c736ba55441d41f9ddacc06 Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Fri, 15 Nov 2013 18:17:12 -0500 Subject: [PATCH 1/4] Add ability to view and change the credit card associated with an account --- endpoints/api.py | 74 ++++++++++++ static/css/quay.css | 30 +++++ static/directives/billing-options.html | 25 +++- static/img/creditcards/amex.png | Bin 0 -> 6415 bytes static/img/creditcards/credit.png | Bin 0 -> 1776 bytes static/img/creditcards/dankort.png | Bin 0 -> 2667 bytes static/img/creditcards/diners.png | Bin 0 -> 2813 bytes static/img/creditcards/discover.png | Bin 0 -> 3516 bytes static/img/creditcards/forbru.png | Bin 0 -> 2363 bytes static/img/creditcards/google.png | Bin 0 -> 3230 bytes static/img/creditcards/jcb.png | Bin 0 -> 2812 bytes static/img/creditcards/laser.png | Bin 0 -> 2366 bytes static/img/creditcards/maestro.png | Bin 0 -> 4429 bytes static/img/creditcards/mastercard.png | Bin 0 -> 4154 bytes static/img/creditcards/money.png | Bin 0 -> 5370 bytes static/img/creditcards/paypa.png | Bin 0 -> 2985 bytes static/img/creditcards/shopify.png | Bin 0 -> 3146 bytes static/img/creditcards/solo.png | Bin 0 -> 3964 bytes static/img/creditcards/visa.png | Bin 0 -> 3182 bytes static/js/app.js | 161 ++++++++++++++++++++++--- static/js/controllers.js | 8 ++ static/partials/org-admin.html | 14 ++- static/partials/user-admin.html | 4 +- 23 files changed, 290 insertions(+), 26 deletions(-) create mode 100644 static/img/creditcards/amex.png create mode 100644 static/img/creditcards/credit.png create mode 100644 static/img/creditcards/dankort.png create mode 100644 static/img/creditcards/diners.png create mode 100644 static/img/creditcards/discover.png create mode 100644 static/img/creditcards/forbru.png create mode 100644 static/img/creditcards/google.png create mode 100644 static/img/creditcards/jcb.png create mode 100644 static/img/creditcards/laser.png create mode 100644 static/img/creditcards/maestro.png create mode 100644 static/img/creditcards/mastercard.png create mode 100644 static/img/creditcards/money.png create mode 100644 static/img/creditcards/paypa.png create mode 100644 static/img/creditcards/shopify.png create mode 100644 static/img/creditcards/solo.png create mode 100644 static/img/creditcards/visa.png diff --git a/endpoints/api.py b/endpoints/api.py index 1f1222a92..062ad69e1 100644 --- a/endpoints/api.py +++ b/endpoints/api.py @@ -1218,6 +1218,80 @@ def subscription_view(stripe_subscription, used_repos): } +@app.route('/api/user/card', methods=['GET']) +@api_login_required +def get_user_card_api(): + user = current_user.db_user() + return jsonify(get_card(user)) + + +@app.route('/api/organization//card', methods=['GET']) +@api_login_required +def get_org_card_api(orgname): + permission = AdministerOrganizationPermission(orgname) + if permission.can(): + organization = model.get_organization(orgname) + return jsonify(get_card(organization)) + + abort(403) + + +@app.route('/api/user/card', methods=['POST']) +@api_login_required +def set_user_card_api(): + user = current_user.db_user() + token = request.get_json()['token'] + return jsonify(set_card(user, token)) + + +@app.route('/api/organization//card', methods=['POST']) +@api_login_required +def set_org_card_api(orgname): + permission = AdministerOrganizationPermission(orgname) + if permission.can(): + organization = model.get_organization(orgname) + token = request.get_json()['token'] + return jsonify(set_card(organization, token)) + + abort(403) + + +def set_card(user, token): + print token + + if user.stripe_id: + cus = stripe.Customer.retrieve(user.stripe_id) + if cus: + cus.card = token + cus.save() + + return get_card(user) + + +def get_card(user): + card_info = { + 'is_valid': False + } + + if user.stripe_id: + cus = stripe.Customer.retrieve(user.stripe_id) + if cus and cus.default_card: + # Find the default card. + default_card = None + for card in cus.cards.data: + if card.id == cus.default_card: + default_card = card + break + + if default_card: + card_info = { + 'owner': card.name, + 'type': card.type, + 'last4': card.last4 + } + + return {'card': card_info} + @app.route('/api/user/plan', methods=['PUT']) @api_login_required def subscribe_api(): diff --git a/static/css/quay.css b/static/css/quay.css index e466e43d6..dcf702505 100644 --- a/static/css/quay.css +++ b/static/css/quay.css @@ -6,9 +6,39 @@ visibility: hidden; } +.billing-options-element .current-card { + font-size: 16px; + margin-bottom: 20px; +} + + +.billing-options-element .current-card .no-card-outline { + display: inline-block; + width: 73px; + height: 44px; + vertical-align: middle; + margin-right: 10px; + border: 1px dashed #aaa; + border-radius: 4px; +} + +.billing-options-element .current-card .last4 { + color: #aaa; +} + +.billing-options-element .current-card .last4 b { + color: black; +} + +.billing-options-element .current-card img { + margin-right: 10px; + vertical-align: middle; +} + .settings-option { padding: 4px; font-size: 18px; + margin-bottom: 10px; } .settings-option label { diff --git a/static/directives/billing-options.html b/static/directives/billing-options.html index 777a56519..93eaf12ca 100644 --- a/static/directives/billing-options.html +++ b/static/directives/billing-options.html @@ -1,4 +1,27 @@ -
+
+ +
+
+ Credit Card +
+
+ +
+ + + + ****-****-****-{{ currentCard.last4 }} + No credit card found +
+ + +
+
+ +
Billing Options diff --git a/static/img/creditcards/amex.png b/static/img/creditcards/amex.png new file mode 100644 index 0000000000000000000000000000000000000000..492d40aff6aa9e4f0af35b38f6548c0ac1e79d9f GIT binary patch literal 6415 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 literal 0 HcmV?d00001 diff --git a/static/img/creditcards/dankort.png b/static/img/creditcards/dankort.png new file mode 100644 index 0000000000000000000000000000000000000000..400f57c9508db53a3ce2180d86b86e4f5a3242cf GIT binary patch literal 2667 zcmaJ@c|25WA0J9t8e1Y%jv-4i3uACHWf{#(X0i;|c3Z~G!C=menPG-DWiO$;;^mUW z&CQm|wMK=DikrBW(k3t2ulG`2O7G}a_x!g3veVJC$MO)|0W zcY=aBlxP9Oh~DqXiVkJjvQc|>19lQnO2CCgOhCd7gN2}ki2B3}O82W~3<~(|6RG1gL!9-;XeiK&*R8B{_IX9#8v) zhG}?dtOSaKCL)(_`d>2#9z9yIms7WQD!?lyQTpQ6p7Xw>a4vCajmCBqM^RSc1Xjo1 zKJ=2gNuj!%DNpBB#@gx-l%M<3-J1`Krz4-_J=Om8Rzq=G9=Bl^!;kGMXqb60JyZ9b zm^Syru2Y330IqlN(coaVvAm-!@?GU~ue<$S2?JBr#zsa>u37y(d?D75`glLWRE?vR zu)Zb!r2!V9tD`ebrBcI_D8_Y>GkzIefiBpGb4HhYHp@_)-`8f-7Fur8CgBtZVzS=G zH8%|PWyx>nhgI(s1SQAxDdDRBJZNYncb2N=GFiQSLf^}~qM)&Hi&oP|8Mr3ba$sdJ z>c&vY{6=G7*Dl?b1eF0}L2nZ3(da%3MgGY7W6sVt5hI5A$KY*yp+NO2?Ba{2=rtw3 z+YU8J?6$oRpHSaz$5-tQq_vL>4_^zaeli1`=e`8gUMcGq#TFNrl$Et6yninixwx-RMwD6O^TIm6{Y|EvkM-@jH_RNM8er@mREoSf?JYvSIzvG3?9ZcRQu;kOMj zqc1Oxj8c>Qs<$|%Wb%ebN2FDZGWfBLv#!-oD}UcWP|EUDk^^hfVUvEB#Sa=mwD zxfAUR8^mWH-^jgv#(t%A{K`dU$34UJfKz+A5wEis*_hF*IvoSLQQD^2&hk_$7D-25 zb96orcn{czgLONV-YTCoHFy5aZ&S_yW8TI8+|{9I`eSSeuiLl3BH>@ZSrH?uWzn79 zS6|fe)hhBD^z(L-MYFOb9@_0gbg!jQKhIXB^>hGhtF#-nRb5?x-1Y55cmGqR?GR-2J)(qdyrHDP~DC) zzDa3`Hju|dpt8^Uw*LWSZ*A4dw;k$vn9A699i+_(NaXh&EgKJ;4%o@GLez*>EY`wtIwwGL4s)!E;2Pc+J?$<;hcNw#Mb4Y?Kyuu zk24T!W2{r&%3VUN__Ua{*6qHS;T9pZF!(uGCB=Zewl;O_I%%pW@_xmwVV%v->%2Pd zDPoLIDfYw*sj*2DC7$r;jx2vd zSdRQh=K5QCjCrjN@P_J-TD@r#6N}L;sno{y1K!@_*N4KUH~o-q96u?^4*Onj-mIy(FlF6%r!syLMtR92kw^-aI=^*oUw?o7`JVy<$PSmplnqDk z>R}F!lJ{9pzgd~yZf|skN~=%QGd;W2I+fS>pbR82$&AIt#WHKS=XTbeg4StA|)gzcTLftGu{Q*Qlf(la^vJ2^{@O8hHpG^&bJ zWvw?2=I1VG>qe1H0i&wpXYQI&BW<>j9igI+Vy0wp=1t26z1icwzP^`t?AWodqp-0R zGdr0zJhY^(97o2r#3vdbziTRAHqe=4S?0t`8C1*muTu4NdPn)FfJMyC#*Uk6tGcXS O|ESLUNfnNVPyGk*>tu=m literal 0 HcmV?d00001 diff --git a/static/img/creditcards/diners.png b/static/img/creditcards/diners.png new file mode 100644 index 0000000000000000000000000000000000000000..72e1808fb1f9dcfa16e0d3a5df2ea777efa288c5 GIT binary patch literal 2813 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 literal 0 HcmV?d00001 diff --git a/static/img/creditcards/forbru.png b/static/img/creditcards/forbru.png new file mode 100644 index 0000000000000000000000000000000000000000..2668cdb3def639fdf3d3f0b6e3151a9fb0f1bb59 GIT binary patch literal 2363 zcmaJ@eK?bQAKy5n6_ZNHm6^y(?1gPMb|jm#&4$ovUTbYP7JISX+Nhq2JVnKf&e5w7 z491sF@I6MhUKzw?T z+GrA9EGdNI|0$OCL`KGgpqPY0$z(D&nY)`v5{JSNi9{U-7VE0@aFwPAL5|#2D79N+ zpa4>?gf9m9A|XP@$k{DQ2FXZmrhk?o5Pzl>N{ z_LhPnz+d_PBe66rMGT-q0I4Wh!qpBg)=n2nO!AWe98e?)6NwU+x)>ZU0!7kzkr?3@ zibpuII9$F^XK?z6V6jMap%ml@xd5F)Mrt|S_MXXK?0QKYxp)%s zo*sCj?-%(#VR>K9#qWz)lr|ZZZnS?J^^!@eAKmt|aJ7fe(g%cEy-T#h-ZPWC3<5Ez zq*HvuBI%Exom6otZw|iplJ^D1N?T zHe(rXHj`rO&|KiL%>`p?*yLScYOucLkkvLs1f!yq8b7$VUOTGT?2*&A?hOix;4jMY zQf1!Y@P*TFCI}-3%9ut_EAwtyys%{O#IB9;3#$F;u@~sHbMrFeJ95`uYMYjE^4J`y zq^B$C+>tUq3u^vB94%uEXkwSQgVDKgMHkuQWcZmOL&vJS?TQJ*V~}6prPFE9;)Ip( zkS%`@`hmD8RU%>}K6+&<5wz1DWC@k)2%P@iSnYFSlFw@dM{BTP}H z8urX8l2Uj{&J(QL2R9y@w`mjeo%N3jm39`tm3uy#?>KNnz_Rn0SXT4l*@&m~Usfpc z{mfQU0%pIGw4DJEW1bA>6deyQ_&4;9$Hj*KWEEuRq~c8>dD!S}_Ia*9FBIPSd1vdZ z_X}_7omOk!ZY+vz{EFLlv<>Ycv`Y*J=GzCYMLx21R(1~7AugD({2l0!d9D1EJ)+chy0^E1WH^(R@*0TX*remnwLGbPd8xiy&wo$J zYT(p^LgSMLg&4tS1kt2(s|ecrQY}X<0jN=0q6>3 z{+7suTa)R|RhFq z@jU%Z$?s=h1tg_{FfX6?#>t$%p>%>&Ni#^rp z#U8ez@9m!}eL1E9&rB zQTNLnnvTbfM=xmLoYy>vbSc#wJ~B}O7{84o7c;c49x+rL$^i> z?c@eG^J<3^6{=0)SfgW)I;*c1_FL2{N{6aRL8@F@Yz0r@1f88nMmiB1ck`KFw{HpP z3X|lVidQz(X#}gP#XzHtvMbLqZIP#l;yrPMUQcPX8%n-+pbrb5P~O{^@~*a$g=QBu zqNtvc3$&>0nQVEjLs8hsbz%YQSu3&&18^ z4jXLy=8n$K=98<<=?D9FVZf_dy_1hRtFCS@&hz({Pe~qr<@fE|`XN(4QI9`ZPuO?6 zJI3YN)Tod9{9YvR-TSe;^9CR4@+0g`hG$)K>hj<Zll?4 z4%)Bk4h9oN#_IHGxM|{mR~d}Kcw8TTR{f^U>z*ktY4P=OvCB|Ze_iuS!`_2?RQn(Z zUolKmB{nr)|8RlrRVR#?93E^cR$hu44UD-9gq;trBlFhd6TA#AyTFLO6z8KsaJc$t z-*U>-%Ajj(cH1=Jf%=K2a?OnT%8wo*pP4ID?WhVk)ti>dPgXEwt^4$gkOZY=?F&-s z`!j31s|y0!P3*sSC|jJ}A@y^tam>k|_(3}UYryK7hAV6r^XZ0*b2U#>Wy|yZU@?Y^ zHhk4VtB^x{TY!$PDyOGOH`qne<+JaW+O0v??d)SZCy1#cLbr3C!TKXjW)*Pw}#XE#rhTezuv-+nrED$kUO- U@yNiJ8r^kj$%!6 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 T7BeXS`oRI$GtsToc8>TTD?`Gw literal 0 HcmV?d00001 diff --git a/static/img/creditcards/mastercard.png b/static/img/creditcards/mastercard.png new file mode 100644 index 0000000000000000000000000000000000000000..af9b1d701c9651437c6110fd29d2299ab6851185 GIT binary patch literal 4154 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 literal 0 HcmV?d00001 diff --git a/static/img/creditcards/money.png b/static/img/creditcards/money.png new file mode 100644 index 0000000000000000000000000000000000000000..a99814aa1a9fe228728061011169861466b17286 GIT binary patch literal 5370 zcmaJ_XE}*a6i^Ri?~F1>*(3ctI#DVlB$ouyH>~m2Mutj` zSd66oZ;Yfb26w?GAyHBD#o0T$qVPZmlr!2L#=lkH%nw8(Vf+gxO z@Hf8U=QxjNb*1$0 z<>ly!#^KReci?YDdk3sH9>#wW>3>qd;Qo2IKs(f<#{ zVE#dS;muM1jrac)_PXJRLrIyVys+M$ju(w{68P;3rv&#z+2gUEH?UZ@zpH5Kg2iLK zT(CGG+yVjw8QD9c-G3WI|6~{$De1X;;qBcWQF>Z1{tFFBG#aS{halwSAW$tWu!4e& z3_=DftthXd0asAel$X=b5hO1Bu z!M|o0rg!3>pN(P9t}CS^X4{{<$OdQQU1aIGVt6zsL*dfVVMfR}y>&=0hRNgd%#@PE!gC2Zu)YqL9p`iVg!fnBO2R> z%cu9QWMpRreGkh@VUW*U-!y(UK%6mcaGq{lW{5LU$!r?Y)g5&=ZVW=7WK$j`TzQmT z=r}_#P#eEeq?~mAJn)nl!5JFhv-Y!K#0rX#?o~V|;NMr$O@~V_x}yx`{&{40M3s zPkGuNT?}7@%69a@PZDm&e;-ufk})`fxi(BDj!1sVl?yvnUQIc8ZMfY2PPQ_gs(byz z%%^9+GMeb==sx;~<&~J{a~X&oxiK?J+SNjI>NV^-I^i1w-a_kz(VFH44T&ko`*b4h z>!my?@pJMCQD+ZNV)qvC--;oPSz{pLu*!_L7U+Du{zVPu81VIRB^;~Z~0 zO9E=+cvdo(6JcJedsWV})4%o*Yop(pA2?_5ic_n5lP!)IWl;&|se|!oyD7O`ZtB=F zuX^EZF>2cHyc`RwLt--(D)HZD5d)&^nvaFDtEz~6zT7(GRz1tb4C}hA8V+hF31pt8 zbqrwR_C7-e>knvbT^gsQFuBsJCp1q-UR**mC1lS^iNKYtI2{(Ma{%j$evzf!h4M5a4GP6OMf&GmJ7JuDdr~r{<4VhFse1>0Ta0%S*m4!2%;_*YL(8G!H?BE zVneiz3HN!XM0MAg6m#ehBw-dV+J5s(j4;F2BG51eXRxU}4HBD;7LCLQD2LsL&Egw96R2B~ zHSNc@T*lcoX?7Vc=|svtYn#QcDD6Ji3nsX+HfCFR+55cgD@ad#DW1bR_k@MD4t$_$ zX!}D#&gP4eEj@YF#I2CwDz;<0lR!>h&hUW5Al}UkMSV?YBNhglap8}pqvi|^{js$x zT3I2lHBQq+V@1Zs1qIz7KTlPLddSdT%ZMsJdB&b9s=X~rLFxn}AAW6mVrz3R>Rv-& z0$}_6EDsnQxML;lbtXpmxv^}AM7D{`fg*4bt4!%S$R$#3{`&>jmhK3}U;P=0Y#NV;G8&u?I zGHJRZj(3y$+hurkoBUTJ=DGb1l_-7j%AG?x=lG}40w81u*>4+`KDAbQwVtyq5bu7M5I-DvyseRvRIF-#h#C;qV&UQJ zwMPYptN@rs&@=? z+uN)9l|(+;zpUuLpqOEfH)O%tS1LHqE?WJfoyv8vmz122%q9Gw7Jnn&skrdL{!J~Q zV-tG0@N2b2y>=z(9xZLLDWZaO!Ov^3h<}5mThfJ!#i0BOUyD<*Xjay&k#Ig~mbvx= z9>Jv-tYS2Ah|e|fID|S#L&lbWv?eg1U%38!r6g~{+VHvfg525q`>)%*5k6GT)rp(o zEV)Vu%-2=bOwqoM<4~vCw3Fbuu}hGp@1GDv5Oc>cV`p^dcJf@B8i;4X+>G!vgL9Ks zmc*T9J^}GW+>LA4@)jgT7fK!tq+wp|snW!z0=i!rROj!&PC>scEYzRdzA57ts_~f% zI!=kY#&?^jF9&qW*SZtoa&nW~xjDYJq2hChbcS)n(#DMcmsS~QJ6@g9lR*0=zcf^? zmrKV%S2XIE5TED_n}&;;fm~o8OEK>W{|v?%h$O9XMeF=@mk(`nC;a0tOMjLf@f1!^ zOM2{iyf$0#e2Q0Duw&XQwZ{o!3jUDe<~Wj)YmY=f|H!?C^lb;h)_Pfdd1@u zxh%nNCa`|6;2mLCsX(aq zwZ*P&!f14@_nw*i)>q=Z$~TwURgkYG#$uZSf4%JyOl}0p- zPAjy`@cP~5CM9ySUA+NXYAl##Y_oRoez0LfOD(?Ksvfz+6MB1_px?qW~Vd%s^j zGen*%9qvRooBN@tFKWelZ%<66NxR2RE1gwHq$U-~`&>{=!L-9}ZTvTGeqs;zFv zNh~JBz2b!zwy;yMU-idd8ov7r9MEs1yzKd1d3MeNiYHL%Al(tua?Dk$AV7_58uwO* z=h(*riejm@i7Opx_x*&6dYH|o+|=6bNXm!_aqOw#P)H>ZvIRCO=ZFZc?`Q{AIGfyv z$jERVGUkHy;*fK?F^f52t*42m%5opJ1S`8KhN`?CMrML#WiM6v4?DCp1{|_>s(~tA zuBnHzGw}u>v0U_w5^E_cKH|w(A-{*EPhxgy!>)1$ZzD9rTL|AoipA7jtwYpreXO3k z6+)@zHz3>~=f^ZM@)F?$i?6h8pz~qHg^asekl?&KP9AIKbMHJ>OS&n-6t zt{>QF>oDS&_JjR?VTc?`?GH919Yx#F!c(8vQ!#dJ2i`YpSVx)I}#IuKl8~crTE}+GqxeA;1~KZ-E*${ zfIPj)n`vpZEO~ccmX%nwt}t^xrQ-a;mUr32Bru}gatgl69uiWvT}*|Vx+yqH2iC1W zd0k!V-5$Sma~xFU{^8RiFfOlA@N7@D5}W4#Lf=4$Pxx6+5sXy!FkhNKemVaVyj5U( z$kC*=TP+~kQ*$Lo%C-(LIA~>m-V|6KaOBQ;m0O=|#iTEbSUNg;Gp5^piV)^sXzM@k z$l0{JqL2cG42&6xq6L<4mXxDfIW%mVF9ahrBdb4858(Gzdu6L~D4pm+k z6M2_aK2aJiVSs1LP`}P;F7)Y{xzyE{Z-h9nOpy1f{CKuKKWZELwR@x8jASbq7ZIeo zRv9pA>${uu7JhvsZ{p5V@6;(!%a@q$qke-m#dW{neBzsenmS9T3ODyGIZ=J1m;oWt zAc4`V>2oYT$u*zB$!Tz>!+77w+hc5oT`$r*)$h4VYH+Unq0qE%$lN8^;5|!kjU7@o zSNs~OJ=0cV@^L3z!+^S8I>%AO-2WViPN1l{v)^Oz;%I# zS(QXm%3}XpL^+XrdkcXZ32)LnQH6|9g)68e-a?s`Icwvx(Y07~$~ta)CIqlD9Wh?( zDjj%6BQE|0UR9lDSZb8tv-0_Fx$~%^A+HJz<=m#qIz>IA$2N~E>Q0|(W)7(IkrpN{C+cUfG?ykCkIK_TV4G$ zF1s5VTQ%O+Kxw}`)+-p^;WA}t`;JeQWlX+sr01=%kez#`NIXqNOAd{^70Y>PXL$a* zIJn(}&O9v!V>}b9R7i?l;J}AoHCdqXIU;jZOLR1M;C982@p0$|a z5G}uw1bby0&!-A} z<_%ee1Q-|&=!fnCtYq>%w3+wx2$CMf$ue_k?XEp<>xgM>>>@+T5u)1crq83xN*THJ z-I^8kx-mjuR`i9&a=88+K5H44_BvZ3+I(C3X5ed2Nq~Z$m;FonU@Xhysw@XdL!PYn%dTV z8pr!`BwwdkyeLvBNg?6Ku~89map_@9vbj~)Y%gxy(5%NZ_a zM|lycpU-^@+t|FiU_y_}KmK@y_Bar^@8I(z|>34RC8!VFyiD&bFU4vv+>(sxg{tnSs%Pd8zzxLsc2 z1wlp9P3zkW`;!6JI*w}g#Lrs;CaGhW*q!YirbU8ccQyFD&kwEz@9$Sm2d_o#b&qah zs@Hseo>N_X9VM{L9~u1`RBJfKq$aZThPC_H`TF`gpX5w;lIbS_eoZHvz8&3Jj2IV8 d?A-!zlJsp|JKk1JsrmgkQV(IQRiBpQxB&uzY{EKV zT!brD`04(>UijDAmx2^73ZU&#(3R;8a*1pT#G1_XqCl~9q7TJ|LL>(Vv{1|;5HWQs z{wR3V$q`Lr()EdJKKeX5ONfR*%q@8=B8f%;p7PAnUW zFV!K0O>qsu;YlGhk|`Nxxd&>_LkkJ$6p#qz(ft`5G|vL|jTbH4ubJU6=rX8rt07aqn0V5;|1?WNz5P$(3A$(DKfDsyrLK_%EzdtZxG&b2A z?SirU9!q$#fcb(T3k`>JxmpCIh<0Nc3U`f)+4grhk_}XZ@sQaK5)m*f2Pc$btjj5fA0wzES3doc#a#sFXom?BJ&*48%0 zCVP=a7()Q@1B+pj0_hY6_ybG+2W#_7?3x(pEMa5}g-s2jknPw^I`mu7XzH(XG5saq zcP#nWxmf=a3l}B>UmNXzjrxa4sGqg%PvHs=Kc!D$2=&eu3R?%U#}fkiT?vb^#`FGs z;}OcjKUerF2%orB(@$kHb^qP!b|rx-nhm4i4pK{82Ui0`=v}n$?b~%uGSq@u2-6 zSnD}~o2~jZ$mv+UJoIU~E))lgX&@#}Pw{$3-}`SB->KwDaxKJ5+Xf605Xw2PlEKgG z*1I6K4^A#DW;M69#dswJ-#;<+acL5%*v^RhBf4i?(Ky}FZG+J*6ab7E_)sXcsbhJE z3vWvwwo0cdZ+m3lIOrUucFPgakRUo(#x=T&%UTl;%3M1yeezLWrDL2Z)>;eLw;?%+ zkd%wX(qt%t^PRGdx#@EC7-Eu)U;?NH4r{%X?-b;^Liqb7s;*WJOpY*WJk8^7XK$Wc zFDkMn8ZvcPQCGWcxam{zlXAZ80;-vQ$~~ZEc49IDc$^o1BF`?cP9n6oH&(kwya&6}qcGhfs$Ng*Me)s|C zkbf;Pa?gU}DE@(%^hu!4jeD{L3rd;=%-holPj^S~AyJ{PNJ^?DXuTab({vvX`)Ej> zbGj-oNK{X*Ua}{vq>fJx^LKnAprtXRH0G7O&RA(=cfWD;`*p4+;A`b-{e-z?dDr!? zb&7cYt2>-;9^#cuAD2w1A~^JsI&HWMG=I^E;5p{p7PBK4wt2ZZ?fN&a)%pg!<4Mm< zYCZC8lWP+^w{xUXGwQ|U+}wzA6(X{vOXBr@3@&!_kZw!8l#+I$T~UoMr)8m^fV8oF zRx#oBIY7WYx2lU}6prnEmuP-@<}jWVYzx3kZs<)yf!i0mZ;kRTNyD#sjy?ruAzcxL zs--I*h?sNyC@L7R__qO$)S*dg~)ryjR)J zwx*wFI-VkRCoD^4J=wauDzCl8&2TIusi|}O;#cwOSNWOkgNq6p=T}#(3?uG6P{^WY zJGR~*FoxNb+Sqo9URnmF;i}B~3vesAW;>`=rFoMEv@=W)+_1vM@ItE`^NJafn7zb1 zC+ZZ{Y8^dt6>f8FES`z)rCZDYxzxl8dRi}_8$d-oQj=Rw{*kUjsx9id?(9myX{kyU zRBs?CWj}m4RkX3Hz`MSxFjqW*UMt4!JwohL&3HQ4t0j>23Jb;vGgqBJ^?HJI0KXx2x(rX%X+$m|Mw50jeNe!3yNLZD-CN(mKmej(E zaT>woTIgn%9;-gx$wR1HGz%glD#D+^57Z}>i++eVDf^1a9Hbo&27c2>a1qzDRgv%V zezQ%gDC$H3-{BK{GkR=>c5?%v<=Oig|FGoqb?!@V**j8=KfbvCVyIW=z=!r;CoN42OriVqah3S|+yU2lpSlGug|yu9a-P*wWfmGQ!w(2Cd}douQIq zTQ#Ma=n`jsTV$Yb=$ux!?2|hUlcD2P$1Y_zE@#k&^gA0YHNO(?s#u21W-Pn2i__ez z$1jwWAdp@1CMxe!nGIi+o?reTQZ311g zL9V~My}~e(n8U5wr3h z@WoM&ct*{s+2OW2!SiP z+qbFjl(99^rl!YDM@grrKmsmPCAi1;?NSMw$Qje_HD6inOPFt#6U1h`ZRs)mLRhJ_ zyHRkhE~Ya4R=|yE6%yY0!V+#B?60DMx7Gm+T(yRKqb%}O9xlvls`}x9p8XPAqT>5r z8d3kacfYh{e3I*bCP0vmiX<<|km?dAGBjfsjfZN(hC4nFhv{kW@*8hY-JE4SzTL2F zcEaz1D{kun&O~0R5@6lo37ZY#54QUoy_9~9^(n=SN_MMF>=MbC#)`gatsHI|Yn%>h zK+iCU!MB$e?m?*h%yL$+*sIp+i*o!^%7U1(Ieu|1zfP3a*u`txP?1xFJCW>YhfC4R z#~&8Cia8*nt}(h<$FaJk5Jt7agD2-t9pe~LH5v~!>TlANmy&vNm4$$o^9jkhSPmy8 zF>R#bq8z*GQj@5s)xFh22C=6EBfOJq#xPdvwE|Cz`B*>fp~mnJAB$yUN;Abe7_jnE z2p~7ljpz;^8(FR}G6?(pFY(`_bMi$8RK05A{P^~S8I=DF@ARC+%8^JB$arKM0y!es!CBn zibw~MaYRHVp;#zNQBXkhC!v&hoWt~4CkmllDi5V=f!$lgSNRWRO#PQ5f^ReNQe$382JDX8v_uLa1KE*k%k9E1_zO-@JJ-^8!w!*-!X%MfNw6eKqT;= zq+Buf0CO^h2+#xRXcHh%C_rBy1l85k*N18WU=Sz_4B@=`+E87%o<1CA0Qmj@IngLS zzHltc;(IL42?_M4(L&&0a707|C_)EBruc!OMn*H#v-k1adO{r-a~;pR^?E_cn1F29CssfT1ABPDwu;F_{1F8XWx7 zn@YnH|IPP*5>p+cLWp22kxCAu5IBSLRo)2|0yn1+@ia2UkxUNy(M5ZIGL202Cx-yc zaryua44x1`+A(N;Ltrp)D-xB4ClQENC?t@>0SXB4ft%}Dpmof2bx<&UQz#S-HG&xG znVOm#7@FznqI95;A6OKb5Ee`%(SBfk{>AG461yXY;1Et^6p<1TPV}*$kb?o=iiQXL zIv40K`MzU)ew_>Kmsl_-8Su_%|7+AgOdS2}Y<~)ubNDHJB8j7S3P;!t?3VppTmo%Y zC{xGCXN$QuLC0NW`?u#Nqc)M@eO6n}qmAbdI8qpCVw$g%#GSRO>b=g;i>v9GPEIBO zl`;@h%)P>E_aavCfVj!vu1XOp-WR%z+$UGUpZ7=lA_~`EjGR{Npf0zs-Dse<5X?_o z6wQYE%@(fZZLb%sY%W7ajQr0HOb*PgO?h1u&bWJeOIfeycEYhsPBOBxpQPH~!*f7* znZ$QGyLygV1Pbhq^TMUP)fcUYU7z^UZ_CU7n{u2zf>?z$h)iWmZdE4GT2=mO^S*h>6*ZTxSzer3x3lw}BBnysR&akZcQ`z}pOk8UU4bE`!Y@xehx}P7qce${z^zwTi z%>6Rf{hnFh*RC2?3m2{0>)dLs&%je`z*@!E!HN8$`eJ+d-gf!TX{x0Fj3xR<=Z+E% zQTgR#4BpL79JX*e`0-SsrCf%yi$2r3{Kk#9ZGT?2)I_Y+9g}H`ufK#UsXuG`g3p@~ zEcqsHqx-~EmuT!(*dw`D$``FNqu1-5ZOSPRYrX344>>0Q6&7DotUwti*W;u{AKqxlFjH=(_uee( zoaO5Zl~Qxj#N*yg)=E`q?a_-Ax)f}NcRU1z;*0G^Ol9rGK{*3sw;;xE9al0RrJeW; zITOo3;{$y~wZ!@Ocni-D3Gq#FFgkUMxPBfq73QuWp9eT?em>3p|G1 z58U08<)v-iEpOHH8c$}_^K|&J#`^Yct*TN~Es{sYu?1ZoS3kyuj8Rq@_g{JIE5fI??QsNuA0nqw$dT+g4Ptwdy|-wTDmd6gPf0Y*? zKk&98wr!rx_%1Xva?`Szwt_><1Bm9CNN07IkJlTC_xCqE<@GWy7&@!W{Wm?K{myCO zoQHB_e)+>!U@D2=g1FsP5=!Hv8mUf-_AF*RQYy@(w0~i>>aV2c?OKTvVD-Yu@X=Sg z4M|Na9=*}w;#US$wWOf7!rK z#_l7LQI&OP^W?89)rbK0AuT~JXwS_Dce`BqRUGat+#aJ7C`L!YYN6N)i&u;=F;Gx(M9TM=#AQgyHTY7<;Lu@aZLNZ}Vemw2Q`)_8#f|q_ zI6q$~%uvnmO>f!#F3MW|WK=7DF?5`rU(NQQ7_7%&7s}e0AegU{s&=K2WJ1dNw~Bf^(|}-)TH=>Kh+8gGmK2M-3S*zEU%Z4I@oSCPVk(9kJXVcZ^C|l4RcO@5 zt51ec#j{xls+=WM38HsrfRDJ8mA!cEx^Ql9QBB2)`Cse~#(x#86L&1&Q~cXOGSx!( z$xzK_?9IBfXXHuK%NBL>35gr?0-(Ob33E%yFr^@WxuGnf@LL&;H#RlKVVQFXv%4&l z8+R_4^rUyHAh?GU)St&rHSan*h7ZgA8um{o;9i4K7=&6n!iK`&IjChs5pZ z&pFhi?Dp;TsoYDZ=w`Hh>Q>rTMyu!-O$*W8Vp5W-u{JW9%hjVo)Mv%Pz!`a6+~$*^`QL zEJX=LNS3I0$N8Pk@BQQLeLm0g-1q(ce6Q=fUH{xvI~%jptir4S0N}KRIoyG^TF}0; z%uKYuyk(XqZ4n}yxRD(R{^W2Z2?H=f6Z|kh3mh^4Z2vr2p7!!y!k0N0l zqimc|Q9&qOG|1o_P(K1fBfw$ENMHmm7#{+OfP((!h0ylLW)%?dZx?b96!f2@+z@s^ zV*&{S)KpeiLaBnmKrJn0u!g3V7WgbsO%<%BqDp(Ul)xGgO)ZF;Ht?SZM2kj3`$HVy zrvJpEouHsVGMNZbQ3($ZR}NQKCXfPDz`DA+#~f;EN;D6pkVrfk8KHy^k^IE~$Aq9r zSRxrqzypsNk$!|wG89D1^gkuwi2u^!L;h(Ktzjw=NTLc@S@pQ2UycaG|L=;!{p%e< zcEJ2M-~W?1#3_=9QE|Y85JE{P+Ti>pk3$h5#v}}qOdvTC2*JO)XctHz6G8$BM4+*w z7Elg>L}BsA2Km1c2n56eA3{drQ5Xw26hz}t#$wSBBVD)}+(=s!uBNRG2AhC&RdqCt zjEuE)V450mb+GC$ES!J}#bNN|Us&{iv0A^y9*Y4-q(z2fNZ2q8+LT1V0sk%c8dt2aEoFE*ihZs?d^AIUeo*8uc#|O+Uxme}zjs{40G7o~CyaP1tfg;=%mo0|E~AO!ps*g(v-|toW;9&!)XUY!#srwd9yO0p;HCt*gd5x2TzG) zh0=#~S!D`Ur>m!n%VT3zVkHW1^V0q@Z1cQJ^8x_ONDZs+r)0*v<&FH?y>fRy{-N><04IsVgSzD2#_@pBK z4FT%=p|AbH0r6b7#sz_8GnRYaq3Y*E@%P$eka-dWOj|gLO*8u&(sj9M~&|=e2&kf!!?F>Lg<4XD0aX1O= zl%>wD9r=>2NL-F0X#JiB?Iayju=>AIK;n1%EW&f9-10 zc)w!G1@H@i^AJo)uw*7Mmb%?-IDFf1 zNjf*DU$pav0*13>S0b>SQrBNC*L6W=t=rCU6R{h4|b~aW(#TMvHx`H zVf4aLOMWcMlq=qHYyNPW%}bLs$C+-jRX0djzd$m=>4hiNeIKYs8DInbhm^0$)QutCZ4V{sg+u$C?QIM zX+_n2!>yJ~w)B>3mJlqcrEhDU$5&*+ZVIMLSlB1^rd(%oRh=rP3*9au)lxIs%!iOPVJUcZlAZ>1otVrATYwi}%Le zAJhY-^W)=dv@FHZ#J>U2Y|kVnGwXLJMbbPdc=3i0nQ7HQ0| zveXHLt`Z&-9c81u^_XAxSYm~F!l|S@?pq?wV*AjC>|!?;oH6qKKeH57XFNq@dHgh-f=SAB*zDmLWlD2MR=Ia-O~qHjMKTr z`dPlHh`8k%3|cdrB0K7H`dUvs?TRw1^R4FU7I!DS*<5?v^*wyJGjbOj5jrMWr6EwJ zxF*5LcUG~5;q{XC{I&SB(pj(A4S~z_cS>ReQ`T018%}LuLTe$zPN1ZU~=}W;;;MA#lg8-E^4|V2ne5Bu1I3D z!HMM_)&#wd7f3~aIp+hk1Iy-kJ3;j^-TQMqOps;a$E9g}xRO`cJ5K%_{4Z7jYWB32{kj3DdH2TXEhpjcQg{jh{#72Bn`bN1={;1M2@cA7V zD%5^>bH6TasENwwGRby|BHFx=<4yH7MA6et)b8`IX`09#+KAOU&h?EF`FYAfmdk2Z z(vBf^Q!i^W8h$`pJxed+0!NVBpP#=l$biYKY1+oS9 zHjJT(9vQwj?+j+QkcujLEb2N90@4~My!_C_9C_CuO2sVW$i$_O`RETBL6(Q z3+zi&^OSJ8tzu>lSLGDBW>m$Cm*DmG%x`g-SLaBz34x@*z&VO@_2Wx(lXsU1%fjY& zVS4%m@hrxs(hs4e>Lo8_>l&^g>!*1Ys(rlMS6)z2aXicyka7~I-`v&8tjkGk$X^;- zWy1wg_Tt$Ezv8g#=iskOb6#-Q>F#ueGWfH$g|JIykttS9@t!wIw(3mf`%4~5wD7x@ z9PZ56Meg}cK$~H8zH$5A^D5O9&%uGpa}MO6vCNF1q=anST zg8qryvUSf7zVUA#t@2pvS@MkNCDt50X32cp$+_z;twUT*Q7iaDaix)F1wqs8 z%o@RMo{-JYnnBXNIy>oD4ide?STDj>T_-VQFq|=LECzN??NRLq30@ypGxr!(_uev2 zb#5IkZc^kqfe(W!jAfi%UPynHd5R-%WoXHX=j2 zTz#I5nnGs-civSh6abf>Drdb#^4}AB(spEf6TT(wjD3~les-e$&S(y)O5s|gffwKM zOyo_OQ&Qc8+`>dq3jR|I^ZrAWEqe3%*PE%hgpt)$j*;T21-P3jNZSUNyvC3})C S8>`syeb~ap23`mAz4|}TzUI^b literal 0 HcmV?d00001 diff --git a/static/img/creditcards/visa.png b/static/img/creditcards/visa.png new file mode 100644 index 0000000000000000000000000000000000000000..ffd17c5a280af87c03886a2e3fcbda7ab79aa859 GIT binary patch literal 3182 zcmaJ^c|6nqAD<)PXX(yW%}CqVvBL~=F56g4Ii|x=vwg7G=9o6htsLoM5}}-lTG2($ zP&$xBNk~PJzDOl=_M5)d@At>A-{+yO%U)S@WchXKrTd<;!A=P!vea?h=Qa9+5mn` zyYOJZCEU@K9_~*!Wk9VgA?AFXgn$KbX%IdufE|M4TR?yC;w1YeGXe_v;llN|fc}%z zZpu!G4JR0Y7#SGq(~&3?1dBC5VT`a?lpX|)M4=H#$&1xTVQ@xR9NHN2^MOjD1v7kb z&IHoWSdxkRxS-~UM*;u;nRAe?~^PG~S)GB_WtrBH!5n_z&(m26aU?(LEl}%i;ODxrMrciFsjud=u^39zIK5Rdwb}K1{Xp__>FSZLqa!6}@9- zGgDz+gUKMcic;Os^qg^T09J*<@w&Rft!xUQQvKIP?mF5(u9?vE26G{awdrI_&N$bn zWd3p%#b;}y9L(ih^AWN9DThD(xr#H|K+F0`E=ie1rXxn&Mn3a1@v!8;AQ zrFNZY$j+8~k-SRrgiPi%)b$pb@dY(_^49cVo3i_bmwGCjCI_GSZfYn&BxZH5XbN!3 zJAw%a`?^W6&O?`^F`?4%s$hdtRIz$aT*0*x9oJUJCN2A8lg-J_uyXs?Q+L+i;DNPT zSBRz>2dRNC^pZq{nSt=^TG`?*kCGD_u(saly!u9sibmceWuq%9cl)TQ!OgSJEXCCc zG1l@YQUhw(a^G@l;%|SuEe&5^Rj`?JIjgV5@G2(%o3+_Wr4Pe_<@B`J>#SPwwIbym zLcOHS@BK}~_vUu2g+>=J&H@n_sbw@!O?pJoZ%X zPF0<1vv_f1R@khaHhG~ff}Tx^X zk!Pwl#{2^Syv1LoZq&B7NOPw7Ugc-=i}UWO!yPf|V7uv_ijVTo7i%0Vh=UWcU-c(> z-eZqtyfo&;+1XJC&wy_#$zO82F3acg9lo{r?vp-?32JMzkIOk1KepP-vQ9Auf7|0V z?~n&>WiHB`>KW6;pjKG3y^ti#XnVHC=qlFj^6#&2g)#X3y<46An3iJ7)T7u|@Ur zfY;S(wfJed@`c*8*?HONo&?TnFit@R1zbUnJKs8}e|_oP!WV_iJU|;B@2kuw zkeVL(4v1RZTStnX!x-ZTE3xa2HI>EZ#;JG0j3*UWsS6>g&h4U(mkFrNE^G2!3McUzaKAncUGeWO6M!&+=Fj&8#JKDx4cPGo#zJ@nU~+3r}MuM`_u+Q|YH;uU^Tt zo&Q?m`)0w)$kTeCwh4w;<>X{idwY8I$xH9twJ*f$dc2oP7IrD1G7@nqqyaA~$;~fK z`EF=W!M`dJ!&{>ieS6-$w2hCHH)D#UUS1s`t9UvtP93K)pKat1&+Tgld?upi=9oU8 zQi|iW#DgbGojj>Xrht#V9%ddk`HYl_7z-F_D0rM)oPkWZDBw&brC0h(dAAdbdib+R zb6+R8MZrE#ds^dcI}#d^~!lWq|P5~vS=+q zUm{Fk@i*UOrihep?45^)lBJxLNRM23_7`9ao7Y!8 zQ=qvD+&g1?kCL7ECEe+1DcFZl7wt!- 0) { + update(); + } + }); + + $scope.$on('$destroy', function() { + PlanService.unregisterListener(this); + }); + + $scope.changeCard = function() { + $scope.changingCard = true; + var callbacks = { + 'opened': function() { $scope.changingCard = true; }, + 'closed': function() { $scope.changingCard = false; }, + 'started': function() { $scope.currentCard = null; }, + 'success': function(resp) { + $scope.currentCard = resp.card; + $scope.changingCard = false; + }, + 'failure': function() { + $('#couldnotchangecardModal').modal({}); + $scope.changingCard = false; + } + }; + + PlanService.changeCreditCard($scope, $scope.organization ? $scope.organization.name : null, callbacks); + }; + + $scope.getCreditImage = function(creditInfo) { + if (!creditInfo) { return 'credit.png'; } + + var kind = creditInfo.type.toLowerCase() || 'credit'; + var supported = { + 'american express': 'amex', + 'credit': 'credit', + 'diners club': 'diners', + 'discover': 'discover', + 'jcb': 'jcb', + 'mastercard': 'mastercard', + 'visa': 'visa' + }; + + kind = supported[kind] || 'credit'; + return kind + '.png'; + }; var update = function() { if (!$scope.user && !$scope.organization) { return; } $scope.obj = $scope.user ? $scope.user : $scope.organization; $scope.invoice_email = $scope.obj.invoice_email; + + // Load the credit card information. + var url = $scope.organization ? + getRestUrl('organization', $scope.organization.name, 'card') : 'user/card'; + + var getCard = Restangular.one(url); + getCard.customGET().then(function(resp) { + $scope.currentCard = resp.card; + }); }; var save = function() { @@ -677,7 +797,8 @@ quayApp.directive('planManager', function () { scope: { 'user': '=user', 'organization': '=organization', - 'readyForPlan': '&readyForPlan' + 'readyForPlan': '&readyForPlan', + 'planChanged': '&planChanged' }, controller: function($scope, $element, PlanService, Restangular) { var hasSubscription = false; @@ -715,6 +836,10 @@ quayApp.directive('planManager', function () { PlanService.getPlan(sub.plan, function(subscribedPlan) { $scope.subscribedPlan = subscribedPlan; $scope.planUsagePercent = sub.usedPrivateRepos * 100 / $scope.subscribedPlan.privateRepos; + + if ($scope.planChanged) { + $scope.planChanged({ 'plan': subscribedPlan }); + } if (sub.usedPrivateRepos > $scope.subscribedPlan.privateRepos) { $scope.limit = 'over'; diff --git a/static/js/controllers.js b/static/js/controllers.js index e4e3d5d4f..2d475f5f7 100644 --- a/static/js/controllers.js +++ b/static/js/controllers.js @@ -728,6 +728,10 @@ function UserAdminCtrl($scope, $timeout, $location, Restangular, PlanService, Us $('.form-change-pw').popover(); + $scope.planChanged = function(plan) { + $scope.hasPaidPlan = plan && plan.price > 0; + }; + $scope.showConvertForm = function() { PlanService.getMatchingBusinessPlan(function(plan) { $scope.org.plan = plan; @@ -1206,6 +1210,10 @@ function OrgAdminCtrl($rootScope, $scope, Restangular, $routeParams, UserService $scope.membersFound = null; $scope.invoiceLoading = true; + $scope.planChanged = function(plan) { + $scope.hasPaidPlan = plan && plan.price > 0; + }; + $scope.loadInvoices = function() { if ($scope.invoices) { return; } $scope.invoiceLoading = true; diff --git a/static/partials/org-admin.html b/static/partials/org-admin.html index 7df7b3fd9..46e3af4ea 100644 --- a/static/partials/org-admin.html +++ b/static/partials/org-admin.html @@ -15,7 +15,8 @@
@@ -24,15 +25,18 @@
-
+
- -
+ +
+
+ +
- Loading billing history: +
diff --git a/static/partials/user-admin.html b/static/partials/user-admin.html index db81cb629..e6c7123e6 100644 --- a/static/partials/user-admin.html +++ b/static/partials/user-admin.html @@ -27,8 +27,8 @@ @@ -38,7 +38,7 @@
-
+
From 58cb6881c4626711fc5539682562bd6a91b7723b Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Fri, 15 Nov 2013 18:30:15 -0500 Subject: [PATCH 2/4] Fix wording --- static/directives/billing-options.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/directives/billing-options.html b/static/directives/billing-options.html index 93eaf12ca..ba5ac47e3 100644 --- a/static/directives/billing-options.html +++ b/static/directives/billing-options.html @@ -32,7 +32,7 @@
- If checked, a receipt email will be sent to {{ obj.email }} on every successful billing + If checked, a receipt email will be sent to {{ obj.email }} on every successful charge
From 4efc5968c637030aa8cecd8ab64f4d1a8cc7a2dd Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Fri, 15 Nov 2013 18:34:54 -0500 Subject: [PATCH 3/4] Fix missing check --- static/js/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/js/app.js b/static/js/app.js index e7f1554d1..02248862a 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -729,7 +729,7 @@ quayApp.directive('billingOptions', function () { }; $scope.getCreditImage = function(creditInfo) { - if (!creditInfo) { return 'credit.png'; } + if (!creditInfo || !creditInfo.type) { return 'credit.png'; } var kind = creditInfo.type.toLowerCase() || 'credit'; var supported = { From b6be962bf3418e7331f9ee203e0a1bb66ab7030e Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Fri, 15 Nov 2013 18:58:47 -0500 Subject: [PATCH 4/4] Change the rules about when to show the subscribe dialog --- static/directives/billing-options.html | 3 +- static/js/app.js | 41 ++++++++++++++++---------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/static/directives/billing-options.html b/static/directives/billing-options.html index ba5ac47e3..1543e5239 100644 --- a/static/directives/billing-options.html +++ b/static/directives/billing-options.html @@ -14,8 +14,7 @@ No credit card found
-
diff --git a/static/js/app.js b/static/js/app.js index 02248862a..26d7aa5da 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -237,16 +237,31 @@ quayApp = angular.module('quay', ['restangular', 'angularMoment', 'angulartics', }, failure); }; - planService.changePlan = function($scope, orgname, planId, hasExistingSubscription, callbacks) { - if (!hasExistingSubscription) { - planService.showSubscribeDialog($scope, orgname, planId, callbacks); - return; - } - + planService.getCardInfo = function(orgname, callback) { + var url = orgname ? getRestUrl('organization', orgname, 'card') : 'user/card'; + var getCard = Restangular.one(url); + getCard.customGET().then(function(resp) { + callback(resp.card); + }, function() { + callback({'is_valid': false}); + }); + }; + + planService.changePlan = function($scope, orgname, planId, callbacks) { if (callbacks['started']) { - callbacks['started'](); + callbacks['started'](); } - planService.setSubscription(orgname, planId, callbacks['success'], callbacks['failure']); + + planService.getPlan(planId, function(plan) { + planService.getCardInfo(orgname, function(cardInfo) { + if (plan.price > 0 && !cardInfo.last4) { + planService.showSubscribeDialog($scope, orgname, planId, callbacks); + return; + } + + planService.setSubscription(orgname, planId, callbacks['success'], callbacks['failure']); + }); + }); }; planService.changeCreditCard = function($scope, orgname, callbacks) { @@ -752,12 +767,8 @@ quayApp.directive('billingOptions', function () { $scope.invoice_email = $scope.obj.invoice_email; // Load the credit card information. - var url = $scope.organization ? - getRestUrl('organization', $scope.organization.name, 'card') : 'user/card'; - - var getCard = Restangular.one(url); - getCard.customGET().then(function(resp) { - $scope.currentCard = resp.card; + PlanService.getCardInfo($scope.organization ? $scope.organization.name : null, function(card) { + $scope.currentCard = card; }); }; @@ -819,7 +830,7 @@ quayApp.directive('planManager', function () { 'failure': function() { $scope.planChanging = false; } }; - PlanService.changePlan($scope, $scope.organization, planId, hasSubscription, callbacks); + PlanService.changePlan($scope, $scope.organization, planId, callbacks); }; $scope.cancelSubscription = function() {