From bff4bfacacd191eafbad4d07c3b85f1d817d05a2 Mon Sep 17 00:00:00 2001 From: emile Date: Thu, 25 Apr 2024 22:03:25 +0300 Subject: [PATCH] new --- .../details_templates/order-details.html | 4 +- .../__pycache__/admin.cpython-310.pyc | Bin 392 -> 452 bytes .../custom_context.cpython-310.pyc | Bin 589 -> 1038 bytes .../__pycache__/models.cpython-310.pyc | Bin 2583 -> 3157 bytes .../__pycache__/urls.cpython-310.pyc | Bin 1774 -> 1887 bytes .../__pycache__/views.cpython-310.pyc | Bin 10822 -> 11760 bytes osinaweb/customercore/admin.py | 2 + osinaweb/customercore/custom_context.py | 15 +- .../migrations/0005_ticketstatusupdate.py | 26 +++ .../migrations/0006_ticketupdate_read.py | 18 ++ ...icketupdate_read_ticketupdatereadstatus.py | 29 +++ ...ename_ticketupdatereadstatus_ticketread.py | 19 ++ .../0005_ticketstatusupdate.cpython-310.pyc | Bin 0 -> 1204 bytes .../0006_ticketupdate_read.cpython-310.pyc | Bin 0 -> 658 bytes ...ead_ticketupdatereadstatus.cpython-310.pyc | Bin 0 -> 1153 bytes ...pdatereadstatus_ticketread.cpython-310.pyc | Bin 0 -> 755 bytes osinaweb/customercore/models.py | 18 ++ .../inner-customer-ticket.html | 152 +++++++------- .../listing_pages/customer-tickets.html | 6 +- osinaweb/customercore/urls.py | 5 +- osinaweb/customercore/views.py | 48 ++++- osinaweb/db.sqlite3 | Bin 1179648 -> 1200128 bytes .../__pycache__/urls.cpython-310.pyc | Bin 4107 -> 4119 bytes .../__pycache__/views.cpython-310.pyc | Bin 15709 -> 16063 bytes .../add/__pycache__/urls.cpython-310.pyc | Bin 1750 -> 1829 bytes .../add/__pycache__/views.cpython-310.pyc | Bin 11249 -> 12686 bytes osinaweb/osinacore/add/urls.py | 3 +- osinaweb/osinacore/add/views.py | 75 ++++++- .../templates/add_templates/add-ticket.html | 58 ++++-- .../osinacore/templates/customer_index.html | 86 ++------ .../details_templates/customer-details.html | 2 +- .../details_templates/ticket-details.html | 188 +++++++----------- .../templates/listing_pages/tickets.html | 14 +- osinaweb/osinacore/urls.py | 2 +- osinaweb/osinacore/views.py | 13 +- osinaweb/static/dist/output.css | 43 ++-- osinaweb/static/js/add-ticket.js | 6 + 37 files changed, 499 insertions(+), 333 deletions(-) create mode 100644 osinaweb/customercore/migrations/0005_ticketstatusupdate.py create mode 100644 osinaweb/customercore/migrations/0006_ticketupdate_read.py create mode 100644 osinaweb/customercore/migrations/0007_remove_ticketupdate_read_ticketupdatereadstatus.py create mode 100644 osinaweb/customercore/migrations/0008_rename_ticketupdatereadstatus_ticketread.py create mode 100644 osinaweb/customercore/migrations/__pycache__/0005_ticketstatusupdate.cpython-310.pyc create mode 100644 osinaweb/customercore/migrations/__pycache__/0006_ticketupdate_read.cpython-310.pyc create mode 100644 osinaweb/customercore/migrations/__pycache__/0007_remove_ticketupdate_read_ticketupdatereadstatus.cpython-310.pyc create mode 100644 osinaweb/customercore/migrations/__pycache__/0008_rename_ticketupdatereadstatus_ticketread.cpython-310.pyc diff --git a/osinaweb/billing/templates/details_templates/order-details.html b/osinaweb/billing/templates/details_templates/order-details.html index 9e38f3d6..eb6cdba6 100644 --- a/osinaweb/billing/templates/details_templates/order-details.html +++ b/osinaweb/billing/templates/details_templates/order-details.html @@ -19,9 +19,9 @@

Services

-
+
+ class="w-ful py-9 px-5 flex justify-center items-center text-center text-secondosiblue bg-white rounded-t-md">

Service Name

&s;s#pWs1#XLkb~nD@>5>^sl%K9kAY?G}Rd`}_9k2}S6aE$%J?#U5<+ z0s=z}C+N7!xXz@^BymzYqNzJ_F=7s*U(v{8?h)#Hw{Q~mvBBGYV%+__$h5)lB5dJ$ zH6Yu)4_p0&z|b7SCNmVH7|SC~Vkf4yVt4^{iMw-0dlqM8<}hbL=2$mk=Z0#ZQRYqv z^A=e9RWEBS@E%&?nDF&(-t4NBe7I~)3gB4kjgKkifsD8I1=m`~sh5p1d_yDxbboc8)-^%<{B-}Le zam*vFj0YtMo9>EnT6Z*u*5Yf;Q{x?%LrQo@$oQ4@@s;USveoE;;@UW2l9*Q2{T@sh zk6#J}DjP*+P1QD45ZTAlZ_nxKakvn^d}j7fWJZw zcnU6fl87rlIN<6`=hMMan22=iO*pm1PzfF7=^$4k3kMm$D1Wdx%qDpSUhwf?Wje|w zuM3zh)BIBJOs`C{&>|69aOHuxdJ2JJiXUPh_ppZ_Ve-!-~+QhM$9HVY0h|}M!j+fE4D)J-<_ZaO|KerhmC7QIzU)ne@R_l#htJPUyZ*DB1OVq Q*@vU-E&9kW2VE!s0V$9w>Hq)$ delta 312 zcmeC7(yU4BamiFVQyiFVoG5NX3%7P z3DTg+c#BahnGwW<0%jo10>sWhTx^kvsgg96vkd4A1uyV z%T&S!5>H{O0ou^ZRLhvc$x_3Z$q2G$vKOP8q)1|NNoHAUd~s<~adJ^+K}lwQUa=;7 z5%c7qjKOl6%(vK!QVUB{i%W{wfHvOZNG>fd$YuW6y?nf%m6cd6^%76YN~05YK_*f#HN8#sF(-}s0lHdAn&2mjx)`hVd08} zx@=N1CT?ofB}?Nk@CUebGb^|L1y|lXkhV4`gp>QueIMtZdwHM#aVF(xS|S3UpC1eT zRc(|yNA^d{JB6(XRjKwSLN!LVqp!tI0+OvqjcA3rN zaG5UrPCRk=j%hz%XxJPdfPAcMIWD6-=`RT9pQ=EP;gCJBEUv-g*EM8Bj)_3-y>QGP zb9ow8x){VA+n~&19t-z|H0+&&Y#4{^SeO!DKM0EgS@ge2Z^^vB75#o;5iivYqi1zp zx5q5YFu0C~Ls-J7;NOnb$vuCh%nezLN!v0N_JocCQJjiQq!Nwpff2BdvLv7iObi%} zNuN@mBb_vr!4M_LwawlR^IBfl8@P{lX%|E*@WPl(szt2{=U*2K7#Q delta 811 zcmaKqL5tHs6vs1Zw@uTgTWXO#c+ho`on2YfMFbVMHSMxhNWm6Y>O!cQsfNa6c}Wj? z>B$eUVnrjdI@;+;8*bEd((o8h=Kfg^M7w%{%U|=EFf0>67O#JZW5u$7ww6v-&NkMmspYy}Fp6VO27&9sCT&)@MiEbs3QqdH_-r<3s?Pu{ z(i;eeufi5Bwh7k>I$@Wvg2;+?t8cg3ove`f-b5yFgHksMcL}$t$QTJBh5O>=p0F&)35)mW9)S%tw~dTKP%v(j+Z#KZtDARS)$zeQ+a6+9$R z-^^MVb*INf#p%;5i_toow!6I0KUb@4A7ITLe3!QKthUl%K&r#d^lQ0kt1dL1QvWr3X54=r ZiD@7oFzQ7AWkoY^`g*RuQ7>LB{05rgrJ4W$ diff --git a/osinaweb/customercore/__pycache__/urls.cpython-310.pyc b/osinaweb/customercore/__pycache__/urls.cpython-310.pyc index 2554343705eff550966124baa6336f352728f051..fa8d64cfab03ac457bf71b0faca7d4d67403ad3b 100644 GIT binary patch delta 284 zcmaFId!J7`pO=@50SHbk(@I;w&cN^(#6bpIw1ie_g_Z;g6dIO&FOctW-%CmG zg>(iw*w)nIty(^`iQ@;1(`jv-VFvo4wgaLvGPZT_;V3AhR&57m@T29!^S^KN(T+CE z{`TDS&b{~CbM86&IN5yp;b>1zPRK)lSD&wIEm^TYnqb!c*>A;-xL%|e@Ad3q8_V<( zy>zcf#MqtdNL{1Plk9_Ar^{z!qIH_944n8; zcFSvHq>lJ>?oe%cfSfA~JCrE#|X*BSF~gsIhW% zzpb=K^#D?<2W_Q|4Qf^{B{pPhGO^)RyoQ|NRX~c6Qe`Zp%;!NnA6S4#3NkZ`%BRCN^X);}gyIlhw<^U^zdw_d^mB4+#XMtQ`BD=|y-%W2Y zo2@q8-FFSlkSx9$ctDIs^6xJjzhk(EE!i1vVmFYLiE9v1LXG>Uy*nhGu{eSLA{!UoXz)Cd9&EV|a3s zv`<9Rot-Vcvc@cP56!uv5>#(Q<(tII!2@w@>-bi4-Qe8yNNf(36;7@*gA8~J;Ck?U zC|3A14NbJPfKtFzl@6uytz&P7e5_ICY4T`rbISSB7|KIxA3vmyM+V^TQyIw{Iz&S= zLa0-c;}zlKt)%!!MW7n+krmNS!qkeely+~sYExAVGq)CS`>Br=52}_XpQ%(GeyR%v z^Bl!v|=_*kPuEMfViH!XJyx0j1X7iEG{!k-R?S-hDA5IoNW-j z(Hd4fi1!7UGIQ+K>qkgeI*3JgR8?pJ*aC|4a#>n(>-qyWs`9P-A7_Xb$ywcbJX6*t# z56B}|`+L&^T}HRXSoYWvCCXFJ0hMeO)8~K{GfC@J2O^Zc7?GgL|$S$J0^A|8rWfRB9UOv zh;xai@Lo*AOA3EnEGl2mUJ_p_-!g=I$zK4D5_W}G^kE`bzOFx2AJ#v zjsv)5{3QUd6YdX!Jc2yu#4m*t>Fwj0?P-(VHPRNB8AK;>)b4bb;i&DRd-}rq{m=yH zs<&Eg^rC^%b{+jSBnLn%<>!GUa6-H@ecs|%A^LzH5*#nBkji&^-y6^#1AYvk@VJcI zFCd*3%PK0_DY2zuMIn50a;QW1@RlyaG}GG*{&QIvXDag97ICqngIyIDsuH5D^5W22 znEp2K4)7~L)`j%#HyCyUzXi&GM}Qte^HJ4xK}O*c)b9ZofnNfsoqPBNh<_j)E$4rP z{3qbgz`H}>Ux2>?pB$+zFp=s&jl)pnZqL!KxMXhIpZ>oc&YWsA}l=#4zs4 zS>3d9`CV%oEAPIGg#Q^({x9r>_-*uOtv?<^{%@H4C+kUG_$0Lf{vmYN#JTET_K;Xv zlhCe1;kMA-HL?8b=oR>Njf}qp+#DON*}&?*0J|rECxNGc8vyzS|1uzeXMwK(Ulns} zmlS>t;&Z?O;1FN03*ORfx-zCLHZV+3a4c^w!9 zCdw@pcQ3+^@E;zx%4E^K39A{vK|qE_#&=>{ei9FU0-OeZ3j7SfiL%A#PnIbGMN}u( zX=v@Klo(1jv*Y6JWM%9zn8`EB(s);>sSU=1P_6~m1Dk-YKr7G%SU?}}D6kXg2X+Jd wfHS~V-~-?qa1($Nyinewv#BWCE`FD)D_#_0%5?gKvY$wZ1#*>qk*KTtFIp#W#sB~S delta 2822 zcmaKtdvH|M9mn_Fy}8-!E1P|U5H{nI=k6wfG+Fao6W*z6VJWj zkqM><3bnO1{;0MUd5l7heVeJJtz)Ov+NZXZsgFChm5wd-&5YA&|7f-6du~iprfo9! zv%m8@zjMy-_dCDey%)DWw=p;v2zXuMZ|$aZpSEH=7-#+Ct>?mewLa&dtGCt&>oxk^ zgRTRNLTvf9dZXSX)boY9S#N>5w_Z=`DWPl7(|W7;ZPeTJcJbRJY!>JrlQzvl?$8%X zxkXodT&c?^A7xi4!GJi~FP`<{F&pWEdnr3a_3C45MqN9?Cn9?2Bl5B)t5S&AQ*N)Kf@)k`Io}~hGwmh0# zBt*U#XaJglHlP*g02T`LQiG?9byL4*Sxty3@?ZPFt9qE?R+#pIU*qfOE8crMmSDw| z0Mfv(0_1UJybAIf;1j^Lz*-s)MrgM$9N8#_rbi&GsBZN`zsj$tqrUCFnFWq*tv?XW z2($N90o5(+ZWKa}5sOBs+rK}IBki*FTsJs(yrJ{{+StrK^MwKL0pyP9>6B##vB=yZ zrcBh2M~O03mA-5eLvhAg;q3OnJ6$WVdL~r3JuBXuF_b}Tmj=BVQ(FL>-8g5r5KR^Q^=IfJ7; zoW9CpE+9))24srfcV~-5ThooAVHviT<3`pp_$nBBq#@k80y}g9D=|@F6$T8k!php( z05!&!u={9hd~@h9ED#YN0rK=ryk5Hl;%Ry-zJfhKt#wJ|Jr~_v*Uz4se7f#^rlE>Q zK1u(WyPW=ZSra==^Aerx9@>_OvpZ;SqQ}RvJ_wlfQerbZMji9Fk9`S>hkyqKMtrOH zKWjV{_48v{$_&RV5NCODd3GPZroq&wcKQzp9{aMq{Gg-^I^yOmG zR!i9d!&Y}tW&PqsW6*d+pY$OgP7_N$7xr6$I`DsECaqNV7tW* zsfg2MPe6Mb_%;v)WCEXtbcSB5Pp~J6HLQ-I5bc0?PYv?SfMJ^1yup7Ud%V;TVN2-F zhMnwn+TR=}Z{ztf*#OUAk7t3O06zt!Z@+}J4R{`?1vUV;2yC2C9T#NjpM&~U;5WdJ zfU^Q?_^%=UR$!uz{|@qt0NR4Tj7;%Y02`36_y3tGS+4T(PQh5#o*R;^@lHs%BmR4! z36Pg3ost(SZ~Aded=;p4x!PS56;6Wx2+eE2c|hj&Nl1SJWQb=(7Nc})i@$8ZC=K6E z%bHiSH$*1u*q`ZmbLYn)$MzBGsY0!;oo z&`0OI&*!GtRr{vScW7PFTzDq5q@r;k%Qol3UoK zU9j5?>;d)y?*Mr3@J|8zfjfZ%z(IN;wJdfQ#Jhn*z^8$GC|es}z&``|v%u$o&jYb( zR71L7ph6J>QGfdKu_MrZ0eAp-5cnb>d-}_eWMdzN^sqoGI_m>@4BF$s2|)I@td8q2 zl=q4Lv4eTT%7_n+m9Yk`Y|&|d6a_tzj^*!zaT$OXOog4|_!bnh@nj!PVmKd=FE*Jd znd#|M_;)b-T|j<^z6a_1fDFy)$H!W0l|L|gwsn(sQB0+hlxW+?CTO@V5h}q}hV&w& zm+4g7mTl`GUJu*|Yyx_Lt-x(S4$uJu=mUztFz^)cI`9U7lHug^#x%TwG0n>4q00000 diff --git a/osinaweb/customercore/admin.py b/osinaweb/customercore/admin.py index c6029487..52db7685 100644 --- a/osinaweb/customercore/admin.py +++ b/osinaweb/customercore/admin.py @@ -3,6 +3,8 @@ from .models import * # Register your models here. admin.site.register(Ticket) +admin.site.register(TicketStatusUpdate) +admin.site.register(TicketRead) admin.site.register(TicketUpdate) admin.site.register(TicketAttachment) admin.site.register(TicketReaction) \ No newline at end of file diff --git a/osinaweb/customercore/custom_context.py b/osinaweb/customercore/custom_context.py index e1e7b971..e7db1aac 100644 --- a/osinaweb/customercore/custom_context.py +++ b/osinaweb/customercore/custom_context.py @@ -1,12 +1,23 @@ from billing.models import * from osinacore.models import * +from customercore.models import * +from django.db.models import Count, Q def utilities(request): active_subscriptions = None + customer_open_tickets = None if request.user.is_authenticated and CustomerProfile.objects.filter(user=request.user): customer = request.user.customerprofile active_subscriptions = OrderItem.objects.filter(active=True, order__customer=customer) + customer_open_tickets = Ticket.objects.filter( + Q(status__in=['Open', 'Working On']) & Q(customer=request.user.customerprofile) + ).order_by('-id') - + for ticket in customer_open_tickets: + unread_updates_count = 0 + for ticket_update in ticket.ticketupdate_set.all(): + if not TicketRead.objects.filter(ticket_update=ticket_update, user=request.user, read=True).exists(): + unread_updates_count += 1 + ticket.unread_updates_count = unread_updates_count - return {'active_subscriptions': active_subscriptions,} + return {'active_subscriptions': active_subscriptions, 'customer_open_tickets': customer_open_tickets} diff --git a/osinaweb/customercore/migrations/0005_ticketstatusupdate.py b/osinaweb/customercore/migrations/0005_ticketstatusupdate.py new file mode 100644 index 00000000..776214c6 --- /dev/null +++ b/osinaweb/customercore/migrations/0005_ticketstatusupdate.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.5 on 2024-04-25 15:32 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('customercore', '0004_ticket_ticket_number_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='TicketStatusUpdate', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('status', models.CharField(choices=[('Open', 'Open'), ('Working On', 'Working On'), ('Closed', 'Closed')], max_length=50, null=True)), + ('date_added', models.DateTimeField()), + ('added_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), + ('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='customercore.ticket')), + ], + ), + ] diff --git a/osinaweb/customercore/migrations/0006_ticketupdate_read.py b/osinaweb/customercore/migrations/0006_ticketupdate_read.py new file mode 100644 index 00000000..ee4ad54f --- /dev/null +++ b/osinaweb/customercore/migrations/0006_ticketupdate_read.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.5 on 2024-04-25 16:02 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('customercore', '0005_ticketstatusupdate'), + ] + + operations = [ + migrations.AddField( + model_name='ticketupdate', + name='read', + field=models.BooleanField(default=False, null=True), + ), + ] diff --git a/osinaweb/customercore/migrations/0007_remove_ticketupdate_read_ticketupdatereadstatus.py b/osinaweb/customercore/migrations/0007_remove_ticketupdate_read_ticketupdatereadstatus.py new file mode 100644 index 00000000..2daa680b --- /dev/null +++ b/osinaweb/customercore/migrations/0007_remove_ticketupdate_read_ticketupdatereadstatus.py @@ -0,0 +1,29 @@ +# Generated by Django 4.2.5 on 2024-04-25 18:16 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('customercore', '0006_ticketupdate_read'), + ] + + operations = [ + migrations.RemoveField( + model_name='ticketupdate', + name='read', + ), + migrations.CreateModel( + name='TicketUpdateReadStatus', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('read', models.BooleanField(default=False)), + ('ticket_update', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='customercore.ticketupdate')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/osinaweb/customercore/migrations/0008_rename_ticketupdatereadstatus_ticketread.py b/osinaweb/customercore/migrations/0008_rename_ticketupdatereadstatus_ticketread.py new file mode 100644 index 00000000..940759e5 --- /dev/null +++ b/osinaweb/customercore/migrations/0008_rename_ticketupdatereadstatus_ticketread.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.5 on 2024-04-25 18:25 + +from django.conf import settings +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('customercore', '0007_remove_ticketupdate_read_ticketupdatereadstatus'), + ] + + operations = [ + migrations.RenameModel( + old_name='TicketUpdateReadStatus', + new_name='TicketRead', + ), + ] diff --git a/osinaweb/customercore/migrations/__pycache__/0005_ticketstatusupdate.cpython-310.pyc b/osinaweb/customercore/migrations/__pycache__/0005_ticketstatusupdate.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bcb19d7d210b5ca3a7da08f3d608bd1d51c4b39f GIT binary patch literal 1204 zcmYjQOK;mo5auo^ilnIc*&qRO2yzO05RIZmfubnlN_HF651^7zfR_cu9nqBe>Mm7R zITdJ+^{qc3>8*chuRY~2BtY6((ssPSF6XtJ`M#O0hC|Q5_2<>6%P%d%_*X0U7ut*$ zxaC)PaD$WFC`d$zmT684GcpS+vRd8Ddy)N}!7bkV!{9wISN-43sL#!*5!i3>z7Y`R zNNAd@Ol3foS7fP(o2)9OvWtpCF3%DjcYh5~d4XI0g$EcB;YLKkd~HE*WxpYuq%`Vd zE{9WYg1hoCKUTnP-oLh%lsjk}qy~5YCS3al*Ctwha9{gx43viGA94#GthQF}YJ0V# z|H~h=QCr$~=h@}keCL`jY1-qv*EA*39^XT3`^r7N1%jyjWG$Pj0FhJzqGtyO2cNSh zOD>_g{gmrs0fNOPX9dQn-C66NHgU6-^P0yED4Oxvv7#?0fu;O--Bc_QfDWz(waAKC zY}h4ilq*4Gah|;b<^KX=QAuEBT!6A=`?tWvimdY*O0k9f1@xWwQzb630Z-3MvE7=K zJ_%F_k1m~$+~X+LbS2~6<`-c)W? zGHfJh2u-Ez4*9FS`=pFIV?f0tydoa!j96t?_cDW=%QIxvVJ#HKl*f=LzRm$&qq457$!fIQDO5Kcf|HdP%?vAf07 zlepH(xy+iRD#A);WgM1p)e2qu&Ugij@IKe!$2S(@D1LD>gWYtj+gTgc8_~mB9Nh9r zD|jX))(6X`WS>4H9(h6@5&GWx;QZG{296qZNk>UlE<38-8w+2wUFqn2d}kbW4}5gX hk9e-(>%1R{=%f&B%K5tM_%{SKsY~pvy=znm04vxAVO2=xD*nzJGqQ`N0|c6~Un;1dhr5V+z24TUPOc zSE3M{y1plb>m8sz+~i6Ty3LLg}j9c~k4W#>*jrovycT zEMDSyeyCD@`-gJU>)BqfQ5zMdSv6N}d<0W+f0shagiLOdiQs}~Jo%g64E@t(($7b# h6`T*-4m%Fb+hxY=KAqF2&qv)}(7R(ka@-LQFH7Ouxa+p3$lQ!uv*tC|g2Ngy~3j zsB)5Ulm|s9QmN{R;1J7$fj&1oT4=1}lwWWG!zbMEDVSd^s73W}gp(2V8yL&xl$+d| zqAzOl8n1&BwRi)6Hg9rgY7Nnkn2UC6O3-rAYQtPKA34!Nw8-0hZb}iKzmMxUm1kt} zg(<~&OMDS)T2jsZn*y*JcQBTPNFX1G9Q>8FwY3+l2nVN7j58h-z;XzKi*aJ{dUJvZZIwc8{iuSaMjB4FbVPrJB5jA zO31??4lh8tXOQ=Wgz|OlK!d|D7{`TbSE;Zny^Gb^{JXPhVuDSPGRzPPP_z)r8sqyN znrrc>`Y?o;%Y)7XWwSC0W6EI+J35X5_by`}$3d*?Vk|fHon?6*WLeNhKZgub4(VW$ zQ|+4HI5~dDPI@~>Z2xe3XHU7eCqj^_bp(kxgIyg{wYJLQ_ceRD)~a$h!_fxPQu*CY zAz}#9%5rwGGvO%xfCSZf6r>}eDDNw~tPEwS8e1E^t&Qy+<%kTfrTN{+pW(~p^83;| z!OEovNf-mfaX0~Q8{}yrGOvexCy)1nOdE$XECwR+gbdTbOX0lSR6#579QxiY<=)-b z;GuY4qF!{N|7++Tq6H*NX>_wmUc*FfobpMzaZF0AE2~aP`EOCOOy|f$@`%vC)|LII zJm0ZZtIDf85b3aLLh~Bo{jy&bx2v~cxB6PUH^k*nHA6c39aq(^gP5{kS6X;O(2_bq Lmo5;SteF1*dkbC* literal 0 HcmV?d00001 diff --git a/osinaweb/customercore/migrations/__pycache__/0008_rename_ticketupdatereadstatus_ticketread.cpython-310.pyc b/osinaweb/customercore/migrations/__pycache__/0008_rename_ticketupdatereadstatus_ticketread.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7e6f79d8c4664c1f473aef8562776e8a4f5dc2ff GIT binary patch literal 755 zcmY*XL2uJA6t6KZ-uf&)SzZGywPN$q;c#d71fC|weV*rnx-sH7Q74zNWanQQokWi%Odt?Xd(zwVIPC|zlzN@!BmfPFq5 zk6-WxO7#)A$HZp@HPL-E5sT=F_YYm2-8TRL literal 0 HcmV?d00001 diff --git a/osinaweb/customercore/models.py b/osinaweb/customercore/models.py index 52909365..96e13ad6 100644 --- a/osinaweb/customercore/models.py +++ b/osinaweb/customercore/models.py @@ -39,6 +39,19 @@ class Ticket(models.Model): super().save(*args, **kwargs) + +class TicketStatusUpdate(models.Model): + STATUS_CHOICES = ( + ('Open', 'Open'), + ('Working On', 'Working On'), + ('Closed', 'Closed'), + ) + ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE) + status = models.CharField(max_length=50, choices=STATUS_CHOICES, null=True) + added_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True) + date_added = models.DateTimeField() + + class TicketUpdate(models.Model): ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE) description = models.TextField(null=True, blank=True) @@ -46,6 +59,11 @@ class TicketUpdate(models.Model): date_added = models.DateTimeField() +class TicketRead(models.Model): + ticket_update = models.ForeignKey(TicketUpdate, on_delete=models.CASCADE) + user = models.ForeignKey(User, on_delete=models.CASCADE) + read = models.BooleanField(default=False) + class TicketAttachment(models.Model): ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE) ticket_update = models.ForeignKey(TicketUpdate, on_delete=models.CASCADE, null=True, blank=True) diff --git a/osinaweb/customercore/templates/details_templates/inner-customer-ticket.html b/osinaweb/customercore/templates/details_templates/inner-customer-ticket.html index d8287579..a64dd1aa 100644 --- a/osinaweb/customercore/templates/details_templates/inner-customer-ticket.html +++ b/osinaweb/customercore/templates/details_templates/inner-customer-ticket.html @@ -6,10 +6,10 @@
-

Ticket: #2226663535

+

Ticket {{ticket.ticket_number}}

-
+

Closed by Linode at 20-4-24 16:30

@@ -17,11 +17,32 @@
+ + {% for update in ticket_updates %}
- + {% if update.added_by.customerprofile %} + {% if update.added_by.customerprofile.image %} + + {% else %} +
+ {{ request.user.first_name.0 }}{{ request.user.last_name.0 }} +
+ {% endif %} + {% elif update.added_by.staffprofile %} + {% if update.added_by.staffprofile.image %} + + {% else %} +
+ {{ request.user.first_name.0 }}{{ request.user.last_name.0 }} +
+ {% endif %} + {% endif %}
@@ -29,9 +50,8 @@
-

Ositcom - Ltd - commented 2024-04-17 12:19

+

{{update.added_by.first_name}} + replied {{update.date_added}}

@@ -47,100 +67,72 @@

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus non purus consectetur - magna sodales fringilla. Suspendisse non imperdiet metus. Curabitur feugiat tristique - varius. Curabitur fermentum sapien nisi, sed suscipit odio luctus sed. Mauris pretium risus - a tincidunt facilisis. Aliquam quis odio in mi aliquet scelerisque et ut urna. Ut ultrices - turpis odio, id hendrerit lectus dignissim in. Donec at tortor quis dui auctor sodales porta - et purus. Aliquam at nunc sit amet tortor lacinia porttitor. Proin auctor, eros ac - sollicitudin iaculis, felis quam vulputate ante, eu varius dolor arcu non enim. Vestibulum - ornare dapibus risus, id eleifend ipsum. Aliquam metus urna, bibendum quis cursus vitae, - placerat sit amet felis. Aliquam tellus ex, pretium id gravida id, vulputate et velit. - Phasellus leo felis, lobortis ut dolor eget, viverra aliquet ligula. Aliquam molestie ac - eros et fermentum. + {{update.description}}

-
-
- - - -
-
-
- -
-
- -
-
-

Scott - Customer Support commented 2024-04-17 12:19

- - - - - - -
+ {% if update.added_by.staffprofile %} +
+ How + did I do? -
-

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus non purus consectetur - magna sodales fringilla. Suspendisse non imperdiet metus. Curabitur feugiat tristique - varius. Curabitur fermentum sapien nisi, sed suscipit odio luctus sed. Mauris pretium risus - a tincidunt facilisis. Aliquam quis odio in mi aliquet scelerisque et ut urna. Ut ultrices - turpis odio, id hendrerit lectus dignissim in. Donec at tortor quis dui auctor sodales porta - et purus. -

+
+
+ +
+ +
+ +
-
- How - did I do? - -
-
- -
- -
- -
- -
- -
+
+
+ {% endif %} + +
- + {% endfor %} -
+
+ {% csrf_token %}
- + {% if request.user.customerprofile %} + {% if request.user.customerprofile.image %} + + {% else %} +
+ {{ request.user.first_name.0 }}{{ request.user.last_name.0 }} +
+ {% endif %} + {% elif request.user.staffprofile %} + {% if request.user.staffprofile.image %} + + {% else %} +
+ {{ request.user.first_name.0 }}{{ request.user.last_name.0 }} +
+ {% endif %} + {% endif %}
- + rows="8" placeholder="Add Comment...">
@@ -160,7 +152,7 @@
-
+
diff --git a/osinaweb/customercore/templates/listing_pages/customer-tickets.html b/osinaweb/customercore/templates/listing_pages/customer-tickets.html index c62989e4..90df9d02 100644 --- a/osinaweb/customercore/templates/listing_pages/customer-tickets.html +++ b/osinaweb/customercore/templates/listing_pages/customer-tickets.html @@ -11,8 +11,8 @@
-

Open Ticktes

-

Closed Ticktes

+

Open Tickets

+

Closed Tickets

@@ -59,7 +59,7 @@ - +

My Account Balance

diff --git a/osinaweb/customercore/urls.py b/osinaweb/customercore/urls.py index 2013ef10..f8dbfe8a 100644 --- a/osinaweb/customercore/urls.py +++ b/osinaweb/customercore/urls.py @@ -7,7 +7,8 @@ urlpatterns = [ path('redirect-osicard/', views.redirect_osicard, name='redirectosicard'), # ADD - path('customer-add-ticket/', views.customer_add_ticket, name='customeraddticket'), + path('add/ticket/', views.customer_add_ticket, name='customeraddticket'), + path('customer/add/ticketupdate//', views.customer_add_ticket_update, name='customeraddticketupdate'), # LISTING @@ -18,7 +19,7 @@ urlpatterns = [ # DETAILS - path('inner-customer-ticket/', views.customer_ticket_details, name='customerticketdetails'), + path('my-tickets//', views.customer_ticket_details, name='customerticketdetails'), # PRODUCTS URL diff --git a/osinaweb/customercore/views.py b/osinaweb/customercore/views.py index 1e66c56b..eea676a6 100644 --- a/osinaweb/customercore/views.py +++ b/osinaweb/customercore/views.py @@ -62,13 +62,20 @@ def customer_add_ticket(request, *args, **kwargs): opened_date = datetime.now() ) ticket.save() + ticket_status_update = TicketStatusUpdate( + ticket = ticket, + status = 'Open', + added_by = request.user, + date_added = datetime.now() + ) + ticket_status_update.save() for file in request.FILES.getlist('files'): ticket_attachment = TicketAttachment( ticket=ticket, file=file ) ticket_attachment.save() - return redirect('customertickets') + return redirect('customerticketdetails', ticket_number=ticket.ticket_number) context = { 'customer_products': customer_products, @@ -79,6 +86,35 @@ def customer_add_ticket(request, *args, **kwargs): return render(request, 'add_templates/customer-add-ticket.html', context) +@customer_login_required +def customer_add_ticket_update(request, ticket_id): + ticket = get_object_or_404(Ticket, id=ticket_id) + + + if request.method == 'POST': + ticket_update = TicketUpdate( + ticket = ticket, + description = request.POST.get('description'), + added_by = request.user, + date_added = datetime.now(), + ) + ticket_update.save() + for file in request.FILES.getlist('files'): + ticket_attachment = TicketAttachment( + ticket_update=ticket_update, + file=file + ) + ticket_attachment.save() + return redirect('customerticketdetails', ticket_number=ticket.ticket_number) + + context = { + 'ticket': ticket, + + + } + + return render(request, 'add_templates/customer-add-ticket.html', context) + # LISTING @customer_login_required @@ -132,10 +168,16 @@ def customer_tickets(request, *args, **kwargs): # DETAILS -def customer_ticket_details(request, *args, **kwargs): +def customer_ticket_details(request, ticket_number): + ticket = get_object_or_404(Ticket, ticket_number=ticket_number) + ticket_updates = TicketUpdate.objects.filter(ticket=ticket).order_by('id') + for update in ticket_updates: + if not TicketRead.objects.filter(ticket_update=update, user=request.user).exists(): + TicketRead.objects.create(ticket_update=update, user=request.user, read=True) context = { - + 'ticket': ticket, + 'ticket_updates': ticket_updates, } return render(request, 'details_templates/inner-customer-ticket.html', context) diff --git a/osinaweb/db.sqlite3 b/osinaweb/db.sqlite3 index 139d35bbe5fd9f62d70d21eba2683c09d7bb18fc..e366fcb353838f031db43f5ab42462660a974762 100644 GIT binary patch delta 8324 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 delta 1399 zcmZ9JTTEPK5XbjBET@%S7Pb)10!yKV0?TsQ3%jrj3v5fFEw>h0Eug}dIp`+1ki$td zCI%CEXk&b6Cw(x{#utqbCbrpV`#|y0M-#D%D|l_K))cwJ(l2((4Zm=|17Otv0MppYHgFHlsv zu-cPv`$UlYDgRrg6jS|@ahbyv_IWcgJq@~Fcx^(gr7zcKi<0Y9l2H?Lb9xF4g&dF5*u!ns zajhZd{*h7U6nLt!S=>o4Hwuye2M0c2*o*~I(n@MvW82zuHl7UC2o=wVc8hJe66zF5EC>gMBi$Q*TZlaT zwdIs}AD?f1vs|I~%xq7jQuGq0p2-?WykJyuKR?S&3`S09J2)q2YBrV9r_AJR$~ecd zJbW(_6Zv=}QZAgB6OD^ku|L{}Jz*!l8_iW#EO;?mE4DU&JE}RC{@J{X8V-7nrAymB z7P!%VuJ;NzTxH3yTxGe&a);#}%YBwj77JAyRu%_~#=;$qTKUMo#T;S@H)B3wMSsV* Kcnn|b2>b;p_lH6N diff --git a/osinaweb/osinacore/add/__pycache__/urls.cpython-310.pyc b/osinaweb/osinacore/add/__pycache__/urls.cpython-310.pyc index 00960999534c6ebae77a38434bad4cffb706303e..f36e1851473d5bd5962e0b65ed8d9fd1a250da91 100644 GIT binary patch delta 180 zcmcb{yOd8mpO=@50SKIyX{GtGGcY^`agc!wkmCTv#RVI+V;Ln<8B>f?nX@EPOj6i- znbRerBvVX-88po{Ph$MS#3(trn?=RAO1303IXktav>+w1Bvs!gGq1!7A`+jOVy7R) spO}(@tin%IYV#(Rct+tUL7+@LR4GLFWI?uGMzhKD*-TmZ7&)E+0K5t@0RR91 delta 100 zcmZ3=ca2v&pO=@50SNXuXr+B)V_VOn$>=%Ea*;0Lxz%cK`qY diff --git a/osinaweb/osinacore/add/__pycache__/views.cpython-310.pyc b/osinaweb/osinacore/add/__pycache__/views.cpython-310.pyc index c33586590bc8361aad4eadd28f802a68bd69d6b8..725635fb682cf0fa96905e737641623d1a3afd3f 100644 GIT binary patch delta 2044 zcmZuxU5Fc16rMXXnIx0Re}dBiD53*3)516hFw5cfe&;6cQB=ofeh24HYgS{=r@$6y#nHVLjif}>Fw6N*v0 zorPU6E(T*rJPx~ILdbUEXcDFbGmf|bdj#H%cpCN!Jb`!yEP*Ex&%&I*Q;7G$et`>! z55T;@dk{Ya4+}hv_z`$C{K~yBbWE}i`frnjLQ?*Fs;Q7U-;X|{kd-Tm?-lZzf5-eq zAvgV7*$)Z%!>i@4ldLzLf1M2bSMt{sGUZo??h?}S7e-W>yx|`m3kdQ3iSeT{x#O=* z93kYM|Iy@bB1^J&d+KMB_HPuPAf({^w&yN6A%*?)28jED${S@A}jOb;%Lw6~j%kK_}rPA&1{&I%c@U>9^Pr;4;-==--l$Nsi)R#+(QYyra4)HsVMy z=%mgoSnDBAwq9=2!T68^o!7vP1#bYl{WxHO^nf z5X9GU0UL_P&jyJegc7qYHPBe4e9C6wf_1LdIa4eF*bqccRBCq1lIac3sC*P8!#BWY zrAn=JiEK|48yofGHpMkF-f^pt7TXIFJD=}uT9ahd`@kB{P%8fD$WCUwACtp)Vr*|$ zU1WAWh*vNc+1aKYXe;3^xrJ#z4+A`mVF})b`3vVHpZ|j)kVo0sxURozmYsiDdBx#}(6)yuX9&;o{wBA!Cvbc2A zgh)n>Mzr5!MmQFu`!OxuUn2JdQGJ=gSQMGF)|)0kx+BG zU0_LwI&#&781E{GJ934%8cSh6VN;8KN-WU>xEaw)q4`yjZhvfy%$NBwXH4dz?dJUbS@|V8iA%`I_R)h6j^E~{ID<3$Je#0gIGF_CLZVdafXAE=`-y8jo2W}bqt@o=nxSV<5ke;C~a-&S6 z!jN@QP;L|~{(s7?D(YW`Mt?x5B`+;mWXYQG4$WRQSNpcVxV%nn@26Qe!QCK~wBU8K feV#jK=GSm8C&h#XxefUh^WL3%UPIeGX_CJI?|2Pw delta 650 zcmYMw&ubGw6bJBqJIN+Zla2YYZPWbz(KVZ-HuVRAo&%EIF9iy(COn;B`_&F;^Y*j$;;44P;m@1n3Ziws&bf@Z7FgAC#2J4 z6Aw#g$VIfIv*Z$%rE}y8PDC8*J* z2J;ln)~v#}i-pQ__Y0-N+S(#pbU7+&kD%jnnBzjvGqvMxdmIJ5j(e5StA_YY>8fg} z{7Kp5pUN5V@~`FeWM5mFzjLqIvTZunRw*paP7Qov5a$Q6K8Otpe&92zzInuJ?OO}C zo9!#q-_mKruO>hTm8qcp@w@F!TC&u7-GaJh@;6iKe5JYsoBVgxj9jO^sNx0x|G{h1 I7gZhp0X5X8od5s; diff --git a/osinaweb/osinacore/add/urls.py b/osinaweb/osinacore/add/urls.py index ab4d9e11..bd222b07 100644 --- a/osinaweb/osinacore/add/urls.py +++ b/osinaweb/osinacore/add/urls.py @@ -27,7 +27,8 @@ urlpatterns = [ path('reference/', views.add_reference_modal, name='addreferencemodal'), path('tag/', views.add_tag_modal, name='addtagmodal'), path('reaction///', views.add_reaction, name='add_reaction'), - path('add-ticket//', views.add_ticket, name='addticket'), + path('ticket//', views.add_ticket, name='addticket'), + path('ticketupdate//', views.add_ticket_update, name='addticketupdate'), ] \ No newline at end of file diff --git a/osinaweb/osinacore/add/views.py b/osinaweb/osinacore/add/views.py index 8791b06f..80127020 100644 --- a/osinaweb/osinacore/add/views.py +++ b/osinaweb/osinacore/add/views.py @@ -8,6 +8,7 @@ from datetime import date from django.http import JsonResponse from osinacore.decorators import * from billing.models import * +from customercore.models import * @@ -601,18 +602,90 @@ def add_reaction(request, status_id, emoji): @staff_login_required def add_ticket(request, customer_id): customer= get_object_or_404(CustomerProfile, id=customer_id) - customer_products = OrderItem.objects.filter(order__status='Completed', active__in=[True, None], item__type='Product', order__customer=customer).values() + customer_products = OrderItem.objects.filter(order__status='Completed', active__in=[True, None], item__type='Product', order__customer=customer) customer_projects = Project.objects.filter(customer=customer) + departments = Department.objects.all().order_by('name') + if request.method == 'POST': + project = None + product = None + department_id = request.POST.get('department') + department = get_object_or_404(Department, id=department_id) + regarding = 'General/Account/Billing' + if request.POST.get('project'): + project = get_object_or_404(Project, id=request.POST.get('project')) + department = project.project_type.department + regarding = 'Project/Product' + elif request.POST.get('product'): + product = get_object_or_404(Item, id=request.POST.get('product')) + department = product.item_type.department + regarding = 'Project/Product' + ticket = Ticket( + status = 'Open', + customer = customer, + title = request.POST.get('title'), + description = request.POST.get('description'), + regarding = regarding, + project = project, + product = product, + department = department, + opened_by = request.user, + opened_date = datetime.now() + ) + ticket.save() + ticket_status_update = TicketStatusUpdate( + ticket = ticket, + status = 'Open', + added_by = request.user, + date_added = datetime.now() + ) + ticket_status_update.save() + for file in request.FILES.getlist('files'): + ticket_attachment = TicketAttachment( + ticket=ticket, + file=file + ) + ticket_attachment.save() + return redirect('ticketdetails', ticket_number=ticket.ticket_number) context = { 'customer_products' : customer_products, 'customer_projects' : customer_projects, + 'customer': customer, + 'departments' : departments } return render(request, 'add_templates/add-ticket.html', context) +@staff_login_required +def add_ticket_update(request, ticket_id): + ticket = get_object_or_404(Ticket, id=ticket_id) + + + if request.method == 'POST': + ticket_update = TicketUpdate( + ticket = ticket, + description = request.POST.get('description'), + added_by = request.user, + date_added = datetime.now(), + ) + ticket_update.save() + for file in request.FILES.getlist('files'): + ticket_attachment = TicketAttachment( + ticket_update=ticket_update, + file=file + ) + ticket_attachment.save() + return redirect('ticketdetails', ticket_number=ticket.ticket_number) + + context = { + 'ticket': ticket, + + + } + + return render(request, 'add_templates/customer-add-ticket.html', context) diff --git a/osinaweb/osinacore/templates/add_templates/add-ticket.html b/osinaweb/osinacore/templates/add_templates/add-ticket.html index 1c882ebc..04be705d 100644 --- a/osinaweb/osinacore/templates/add_templates/add-ticket.html +++ b/osinaweb/osinacore/templates/add_templates/add-ticket.html @@ -8,7 +8,7 @@ Add Ticket for {{customer.user.first_name}} {{customer.user.last_name}} -
+ {% csrf_token %}
@@ -19,7 +19,7 @@
- - - {% for customer_project in customer_projects %} - - {% endfor %} - + - + + + +
+ + +
+
- + @@ -57,7 +79,7 @@
- + Upload Document(s)
-
- - -
-

Invoices

-
- - - - - - - - - - - - - - - - - - - - - - - + + {% endfor %}
- Due Date - - Title - - Description - - Status - - Amount -
-

20-2-2024

-
-

Invoice 1

+
+ +

{{ticket.unread_updates_count}}

+
-

Invoice description section

-
-

Pending

-
-

200

-
@@ -185,7 +131,7 @@
-

Other Ways to Get Help

+

Ways to Get Help

diff --git a/osinaweb/osinacore/templates/details_templates/customer-details.html b/osinaweb/osinacore/templates/details_templates/customer-details.html index 4debe8c8..3d9ec8cb 100644 --- a/osinaweb/osinacore/templates/details_templates/customer-details.html +++ b/osinaweb/osinacore/templates/details_templates/customer-details.html @@ -28,7 +28,7 @@
diff --git a/osinaweb/osinacore/templates/details_templates/ticket-details.html b/osinaweb/osinacore/templates/details_templates/ticket-details.html index 624dcf24..6759e4b5 100644 --- a/osinaweb/osinacore/templates/details_templates/ticket-details.html +++ b/osinaweb/osinacore/templates/details_templates/ticket-details.html @@ -4,10 +4,10 @@
-

Ticket: #2226663535

+

Ticket: {{ticket.ticket_number}}

-
+

Closed by Linode at 20-4-24 16:30

@@ -15,11 +15,31 @@
+ {% for update in ticket_updates %}
- + {% if update.added_by.customerprofile %} + {% if update.added_by.customerprofile.image %} + + {% else %} +
+ {{ request.user.first_name.0 }}{{ request.user.last_name.0 }} +
+ {% endif %} + {% elif update.added_by.staffprofile %} + {% if update.added_by.staffprofile.image %} + + {% else %} +
+ {{ request.user.first_name.0 }}{{ request.user.last_name.0 }} +
+ {% endif %} + {% endif %}
@@ -27,9 +47,8 @@
-

Ositcom - Ltd - commented 2024-04-17 12:19

+

{{update.added_by.first_name}} + replied {{update.date_added}}

@@ -45,130 +64,77 @@

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus non purus consectetur - magna sodales fringilla. Suspendisse non imperdiet metus. Curabitur feugiat tristique - varius. Curabitur fermentum sapien nisi, sed suscipit odio luctus sed. Mauris pretium risus - a tincidunt facilisis. Aliquam quis odio in mi aliquet scelerisque et ut urna. Ut ultrices - turpis odio, id hendrerit lectus dignissim in. Donec at tortor quis dui auctor sodales porta - et purus. Aliquam at nunc sit amet tortor lacinia porttitor. Proin auctor, eros ac - sollicitudin iaculis, felis quam vulputate ante, eu varius dolor arcu non enim. Vestibulum - ornare dapibus risus, id eleifend ipsum. Aliquam metus urna, bibendum quis cursus vitae, - placerat sit amet felis. Aliquam tellus ex, pretium id gravida id, vulputate et velit. - Phasellus leo felis, lobortis ut dolor eget, viverra aliquet ligula. Aliquam molestie ac - eros et fermentum. + {{update.description}}

-
-
- -
-
-
- -
- -
-
-

Scott - Customer Support commented 2024-04-17 12:19

- - - - - - - -
- -
-

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus non purus consectetur - magna sodales fringilla. Suspendisse non imperdiet metus. Curabitur feugiat tristique - varius. Curabitur fermentum sapien nisi, sed suscipit odio luctus sed. Mauris pretium risus - a tincidunt facilisis. Aliquam quis odio in mi aliquet scelerisque et ut urna. Ut ultrices - turpis odio, id hendrerit lectus dignissim in. Donec at tortor quis dui auctor sodales porta - et purus. -

- -
- How - did I do? - -
-
- +
+ {% endfor %} + + + + {% csrf_token %} +
+
+ {% if request.user.customerprofile %} + {% if request.user.customerprofile.image %} + + {% else %} +
+ {{ request.user.first_name.0 }}{{ request.user.last_name.0 }}
- -
- + {% endif %} + {% elif request.user.staffprofile %} + {% if request.user.staffprofile.image %} + + {% else %} +
+ {{ request.user.first_name.0 }}{{ request.user.last_name.0 }}
- -
- -
-
+ {% endif %} + {% endif %}
-
-
- - -
-
-
- -
-
- - -
- +
+ -
-
- +
+
+ - - - -
+ + + +
- + + + +
-
-
-
+ +
+
diff --git a/osinaweb/osinacore/templates/listing_pages/tickets.html b/osinaweb/osinacore/templates/listing_pages/tickets.html index e9b9ff5d..2f9d41a9 100644 --- a/osinaweb/osinacore/templates/listing_pages/tickets.html +++ b/osinaweb/osinacore/templates/listing_pages/tickets.html @@ -26,8 +26,8 @@
-

Open Ticktes

-

Closed Ticktes

+

Open Tickets

+

Closed Tickets

@@ -49,10 +49,6 @@ class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap"> Regarding - - Date Created - Last Updated @@ -89,17 +85,13 @@

20-2-2024

- -

20-2-2024

- -

Ositcom Ltd

- +
diff --git a/osinaweb/osinacore/urls.py b/osinaweb/osinacore/urls.py index 33811162..8f76074e 100644 --- a/osinaweb/osinacore/urls.py +++ b/osinaweb/osinacore/urls.py @@ -54,7 +54,7 @@ urlpatterns = [ #Details Templates path('customers//', views.customerdetails, name='customerdetails'), - path('ticket-details/', views.ticket_details, name='ticketdetails'), + path('ticket//', views.ticket_details, name='ticketdetails'), path('businesses//', views.businessdetails, name='businessdetails'), path('staffs//', views.staffdetails, name='userdetails'), path('projectdetails//', views.projectdetails, name='detailed-project'), diff --git a/osinaweb/osinacore/views.py b/osinaweb/osinacore/views.py index 0bce1001..e776d1a8 100644 --- a/osinaweb/osinacore/views.py +++ b/osinaweb/osinacore/views.py @@ -20,7 +20,7 @@ from django.core.mail import send_mail from django.conf import settings from django.utils.encoding import force_bytes from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode - +from customercore .models import * def login_with_email(request, email, key): @@ -451,9 +451,16 @@ def customerdetails(request, customer_id): @staff_login_required -def ticket_details(request): +def ticket_details(request, ticket_number): + ticket = get_object_or_404(Ticket, ticket_number=ticket_number) + ticket_updates = TicketUpdate.objects.filter(ticket=ticket).order_by('id') + for update in ticket_updates: + if not TicketRead.objects.filter(ticket_update=update, user=request.user).exists(): + TicketRead.objects.create(ticket_update=update, user=request.user, read=True) - context = { + context = { + 'ticket' : ticket, + 'ticket_updates': ticket_updates, } diff --git a/osinaweb/static/dist/output.css b/osinaweb/static/dist/output.css index 217314b2..e1ba3132 100644 --- a/osinaweb/static/dist/output.css +++ b/osinaweb/static/dist/output.css @@ -1,5 +1,5 @@ /* -! tailwindcss v3.4.1 | MIT License | https://tailwindcss.com +! tailwindcss v3.3.3 | MIT License | https://tailwindcss.com */ /* @@ -32,11 +32,9 @@ 4. Use the user's configured `sans` font-family by default. 5. Use the user's configured `sans` font-feature-settings by default. 6. Use the user's configured `sans` font-variation-settings by default. -7. Disable tap highlights on iOS */ -html, -:host { +html { line-height: 1.5; /* 1 */ -webkit-text-size-adjust: 100%; @@ -46,14 +44,12 @@ html, -o-tab-size: 4; tab-size: 4; /* 3 */ - font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */ font-feature-settings: normal; /* 5 */ font-variation-settings: normal; /* 6 */ - -webkit-tap-highlight-color: transparent; - /* 7 */ } /* @@ -125,10 +121,8 @@ strong { } /* -1. Use the user's configured `mono` font-family by default. -2. Use the user's configured `mono` font-feature-settings by default. -3. Use the user's configured `mono` font-variation-settings by default. -4. Correct the odd `em` font sizing in all browsers. +1. Use the user's configured `mono` font family by default. +2. Correct the odd `em` font sizing in all browsers. */ code, @@ -137,12 +131,8 @@ samp, pre { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* 1 */ - font-feature-settings: normal; - /* 2 */ - font-variation-settings: normal; - /* 3 */ font-size: 1em; - /* 4 */ + /* 2 */ } /* @@ -1406,7 +1396,7 @@ video { } .max-w-0 { - max-width: 0px; + max-width: 0rem; } .max-w-2xl { @@ -3225,6 +3215,11 @@ video { transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } +.hover\:bg-gray-100:hover { + --tw-bg-opacity: 1; + background-color: rgb(243 244 246 / var(--tw-bg-opacity)); +} + .hover\:bg-gray-50:hover { --tw-bg-opacity: 1; background-color: rgb(249 250 251 / var(--tw-bg-opacity)); @@ -3322,6 +3317,13 @@ video { color: rgb(255 255 255 / var(--tw-text-opacity)); } +@media (prefers-color-scheme: dark) { + .dark\:text-gray-600 { + --tw-text-opacity: 1; + color: rgb(75 85 99 / var(--tw-text-opacity)); + } +} + @media (min-width: 650px) { .s\:mt-10 { margin-top: 2.5rem; @@ -3822,11 +3824,4 @@ video { .xll\:text-\[70px\] { font-size: 70px; } -} - -@media (prefers-color-scheme: dark) { - .dark\:text-gray-600 { - --tw-text-opacity: 1; - color: rgb(75 85 99 / var(--tw-text-opacity)); - } } \ No newline at end of file diff --git a/osinaweb/static/js/add-ticket.js b/osinaweb/static/js/add-ticket.js index 90a3f5b1..bcdb0297 100644 --- a/osinaweb/static/js/add-ticket.js +++ b/osinaweb/static/js/add-ticket.js @@ -17,6 +17,12 @@ selectRegarding.addEventListener('change', function() { projectsSelectTag.classList.remove('hidden'); projectsSelectTag.required = true; + productsSelectTag.required = false; + productsSelectTag.classList.add('hidden'); + } else if (selectedOption === 'General/Account/Billing') { + projectsSelectTag.classList.add('hidden'); + projectsSelectTag.required = true; + productsSelectTag.required = false; productsSelectTag.classList.add('hidden'); }