From 43e8203fc1b21d6904bd5676cf486abd477fd046 Mon Sep 17 00:00:00 2001 From: emile Date: Fri, 26 Apr 2024 16:37:06 +0300 Subject: [PATCH] new --- .../__pycache__/models.cpython-310.pyc | Bin 6238 -> 6238 bytes .../billing/__pycache__/urls.cpython-310.pyc | Bin 620 -> 650 bytes .../billing/__pycache__/views.cpython-310.pyc | Bin 1623 -> 1876 bytes .../add/__pycache__/urls.cpython-310.pyc | Bin 531 -> 630 bytes .../add/__pycache__/views.cpython-310.pyc | Bin 4149 -> 4367 bytes osinaweb/billing/add/urls.py | 1 + osinaweb/billing/add/views.py | 56 ++++++----- .../delete/__pycache__/urls.cpython-310.pyc | Bin 0 -> 385 bytes .../delete/__pycache__/views.cpython-310.pyc | Bin 0 -> 667 bytes osinaweb/billing/delete/urls.py | 7 ++ osinaweb/billing/delete/views.py | 11 +++ .../details_templates/order-details.html | 91 ++++++++---------- osinaweb/billing/urls.py | 5 +- osinaweb/billing/views.py | 15 +-- .../custom_context.cpython-310.pyc | Bin 1060 -> 1232 bytes .../__pycache__/models.cpython-310.pyc | Bin 3157 -> 3156 bytes .../__pycache__/views.cpython-310.pyc | Bin 11798 -> 12535 bytes osinaweb/customercore/custom_context.py | 9 ++ .../0009_alter_ticketattachment_ticket.py | 19 ++++ ...er_ticketattachment_ticket.cpython-310.pyc | Bin 0 -> 816 bytes osinaweb/customercore/models.py | 2 +- .../inner-customer-ticket.html | 41 +++++--- .../listing_pages/customer-tickets.html | 12 +-- .../templates/products/osimenu-plans.html | 22 ++++- osinaweb/customercore/views.py | 47 ++++++++- osinaweb/db.sqlite3 | Bin 1200128 -> 1204224 bytes .../osinacore/templates/customer_index.html | 12 +-- .../osinacore/templates/customer_main.html | 62 +++++++++++- .../templates/listing_pages/tickets.html | 2 +- osinaweb/static/dist/output.css | 9 ++ osinaweb/static/images/download_15 | 17 ++++ osinaweb/static/images/download_15_kNZ8LKm | 17 ++++ osinaweb/static/images/download_15_laVlbQ6 | 17 ++++ .../invoice_24-1425_FTErGsJ.pdf | Bin 0 -> 38666 bytes .../invoice_24-1425_y5h8xt2.pdf | Bin 0 -> 38661 bytes osinaweb/static/images/invoice_56.pdf | Bin 0 -> 38661 bytes 36 files changed, 355 insertions(+), 119 deletions(-) create mode 100644 osinaweb/billing/delete/__pycache__/urls.cpython-310.pyc create mode 100644 osinaweb/billing/delete/__pycache__/views.cpython-310.pyc create mode 100644 osinaweb/customercore/migrations/0009_alter_ticketattachment_ticket.py create mode 100644 osinaweb/customercore/migrations/__pycache__/0009_alter_ticketattachment_ticket.cpython-310.pyc create mode 100644 osinaweb/static/images/download_15 create mode 100644 osinaweb/static/images/download_15_kNZ8LKm create mode 100644 osinaweb/static/images/download_15_laVlbQ6 create mode 100644 osinaweb/static/images/generated_invoices/invoice_24-1425_FTErGsJ.pdf create mode 100644 osinaweb/static/images/generated_invoices/invoice_24-1425_y5h8xt2.pdf create mode 100644 osinaweb/static/images/invoice_56.pdf diff --git a/osinaweb/billing/__pycache__/models.cpython-310.pyc b/osinaweb/billing/__pycache__/models.cpython-310.pyc index 35e332fb82d26ea9586b03d1f666633a622f54bf..07fab5b8163b54f9672acad35014e18665a73d73 100644 GIT binary patch delta 20 acmca-aL<4{pO=@50SFXUYH#EYmH+@cAOzL` delta 20 acmca-aL<4{pO=@50SLT)&Yo%%O+|Yc(Y`&rm&^3_cEt4rf{UP zWU-}iLU~+39(xKml*a?)ais7M%$&)-j7svd`9&$IMNpAqeVfd@5-YG!d}fNBe$?c4#u7GOpreX-Co?h? YiU|Rk0*pM2JS=?7e2hQ{BssnT0IdWuT>t<8 diff --git a/osinaweb/billing/__pycache__/views.cpython-310.pyc b/osinaweb/billing/__pycache__/views.cpython-310.pyc index 41c19eafe5ff4946acc1bba3a37810bddc823f71..074f9e2cefb7467c838a1343db116cbcde743690 100644 GIT binary patch literal 1876 zcmb7F&2Jk;6yN#SkJxL+g#axDQJ|`7pm7gXPpCq`r4mYtQZ7Dp<#;CUx@)hQ87Gak zKEXAA0X-zgUiow8%Bg2=mH2pX#+$|>AhFWCnR)YO{C>ap;j-0g1n~WG_W8l>I0$~j z&Bc$x<|`Qb5eN|oQUnvyCllJIBoI`vf;~n(FZd+vhoB2Z^mEXUL@W}RW3eF`FejoZ zQkXYHOSEBbh|RsA+j#}A23=|+C8t6vdu1d|R_>4G5GIw~yL;~yK?`EZXDGfO;@idBTKf@@e4X$v5JfE1zm=QSAmGC@FxcD#5*>Aq)IU# znwP|Kb3Bu;*_~Y2cu%Usd?>-wWabUDO|)0)#nmF$CZCS7*W}l558G3PToky>&i41p8;(ZkFpg^j;c&|P{GmW@9gj4=k%AEPX!co`2v|GEH5i=IQ56zsMG@#AWE1jd=z5pxQ%U?G+nG z0%}`CfSj9n%ucyUuo;~YlT>uPAvSOY7L60~HT1SKGHyUOXr8|jp5IFU$E~P>46j1b zdcl^lX#&&jDt1h7?x>Hz^DgnsxQvgnxUyV4hNi|3fNs?U6NPX=lMLtDloP4Cq~EF6 zS(fYRyeQy2$_4DE3YqCL_pEKYFlMf3UBg)1{AWa+&3Zi3H}SL^uEelm`K;}rPnfl~ zc{nJbJ7t*js*P&wy$T~}WBGho%%L`2Crf-SeuBp?6K=z*-+tpApw`Yo-`g%rl$N(% z`F|H4&{)o5jw)N9enc>`M=Z*tsqe&@bq0eo^ z{HBS?p=K^O$tJB4&Qul-kbN$oA%;!5kIuN! zJ=jM}8j@)vW+98s&}3wr+KTPao^ne&aV4xEx22=2FUVifJg$Yc*bUujOjXxo5enp7 z*4`VTCtX>`y&;A4aBs?nY~t=qUoPOjAY0Fk;LPFp?Zu}7D|tSQ)tfX?$ZN!<(s^{q z@Nsy;`hi)BCs~?2Q`sm@GF6I4c|Mw37$UY+KFC!((owF)pLSSKEVB=tCMEzMp{#DD zNv`(ui2+N+XSTaY|BwlUHfuA}G+E`haA2jlYd&UP@y@*YvPJi-NNZ>#0}~-|;4JYD z!6Lyb!8wAZ6Ih-*C^q8=KC?~xkFa1B^LJh7;#pvCfLGkG?o5T?0$uu#P>=kl36X$cA3=#p<%7;)k_4m{?%Z?ehdw#>AeMQSua|g27P28o5r%UN(ox>vXuK22$nG zP-oXL@Q6wh%sy5MNT~^z@Qg~jOqte-Uruljt`NUU@bBl8-m&m3=Piop6I@5w2wKIr z%IblTyHT>8uJ7e23pRR6F0s2b9^jB!iBp`DtgO!>cW@?v-Uc;tcV@@)u~^q>gyjNt v9##mZ&Fc{h2uS_prMG94npyJuD7B~61DeQ;y6@u$2*#ODX!APfye{0onYy>< diff --git a/osinaweb/billing/add/__pycache__/urls.cpython-310.pyc b/osinaweb/billing/add/__pycache__/urls.cpython-310.pyc index 67a26cc4d02f7c2da5d0e7dcff70fb91f8321170..46a91e1bd4652203fe9fb262abb6598d4c431a43 100644 GIT binary patch delta 222 zcmbQt@{L71pO=@50SJ!OXs4ZIWMFs<;vfS~AjbiSi_<1*2TP#aVelU0h$IWAZ1G=goFbBfQ|-QOVA)n3Mv{vyyH6pW6v|s%=k_NyhbW?iC#95xacRe$)7fvnI$g&^JH; zqLw&k_$33)#?R;_+i+{UNuz&ej~~1aw(2~9PeSYwAN$zCA-0G^K{a@sze1Y;cmDQm z@jN*0nUDBybAUWj^d?L|GOTbT8Exbv4YwrCt=tCLs06u}h!YUcR_E;pY>6=26^`i0gXBi@H{@$Vx(_?#{RIaK~3UWBl=ny;xqg?iWf z5Rdgw-WZP`uDAchws;Bh>5U*6Hn*jf6g4w9yIU5ixUN4A*0-*Ki#P*N+tW-`vZh%f z#cRz%b$gb{;{th6{}5bUGx>xI5Ot3$#N1qr^{Mdg>9KqN@K?!x8?3E(D#8Vg&SqlAS z=js#n0BV0aoy^L2vtlCB_x3Z9auGqSc+!BWGhzNxaZCT++1%a)IzS9F+=T-5VPt?^ ROsI#+W6;k+KjUG4zkC1|QjoNKmqetkGCV`)AYbK~G~WnSqQpj;iHQjelVw|4%i=26xj}GGi!nDh zFDOg>ahBN-GIaeEq4?p$LzVr`*C1xjedex}AY%X5V|+}_e) zVD}0w!eAvt%b=(yg+#)LSe>m!0^eMVg3ym5IxKk_M5lpsLJ|RhM`XH`_*Cct^E<*> zU89YadgPPkIuk}3ijr-!f(prdb9&Rf<+FAWF_F0{v*@@iGzLOsQ^&k4f=QkEEa><` z3%hrzE;;g1&Y%?SH%qsswFJF9t--}V~}I+2}4v;s6wn9`7(88DNJ z`0(5UfaoL$2YJX+9Rx>(15yW%4%kptB#-d}8y*@)7^yl~Kb;J%CLglj#@GONwovSn zK5n+0rwZwRuEieU!PXG>xSM>n9-&Hd-=0O4y?y&TGK3!0*Zt&;TfaUFcMC0IRA4#u zMmO~7S?Sa7`E@GH`Eb1(G<-S&K6+Y;Q5nrN0}6}Of{@WmsUuo#2kiGs&m`14dhoI& zn;=U0baMiy4{ZfSZgfNDhfLsR(DuW6$4?e=Wp@qYk-XAT2esru z?nocDJXD0$U|0-YlBI`|x4B+&BR^B1C9vsnDXLN|CGYZ+hYkSjS1>FsFINlN0fcot IipQPuFXi~{TL1t6 diff --git a/osinaweb/billing/add/urls.py b/osinaweb/billing/add/urls.py index 96894a68..b5c7f44b 100644 --- a/osinaweb/billing/add/urls.py +++ b/osinaweb/billing/add/urls.py @@ -8,4 +8,5 @@ urlpatterns = [ path('order//', views.add_order, name='addorder'), path('invoice//', views.add_invoice_pdf, name='addinvoice'), + path('service///', views.add_service_in_order, name='addserviceinorder'), ] diff --git a/osinaweb/billing/add/views.py b/osinaweb/billing/add/views.py index 44159426..b6a8a700 100644 --- a/osinaweb/billing/add/views.py +++ b/osinaweb/billing/add/views.py @@ -5,11 +5,12 @@ from django.http import JsonResponse, HttpResponse from django.template.loader import get_template from django.conf import settings import os +from osinacore.decorators import * from django.core.files.base import ContentFile from weasyprint import HTML, CSS - +@staff_login_required def add_product(request, *args, **kwargs): item_types = ProjectType.objects.all().order_by('name') if request.method == 'POST': @@ -38,7 +39,7 @@ def add_product(request, *args, **kwargs): return render(request, 'add_templates/add-product.html', context) - +@staff_login_required def add_service (request, *args, **kwargs): item_types = ProjectType.objects.all().order_by('name') customers = CustomerProfile.objects.all().order_by('user__first_name') @@ -72,38 +73,26 @@ def add_service (request, *args, **kwargs): return render(request, 'add_templates/add-service.html', context) -def add_order (request, customer_id): +@staff_login_required +def add_order(request, customer_id): customer= get_object_or_404(CustomerProfile, id=customer_id) businesses = Business.objects.filter(customer=customer) if request.method == 'POST': - customer_id = request.POST.get('customer') - customer = get_object_or_404(CustomerProfile, id=customer_id) - status = request.POST.get('status') - - customer_id = request.POST.get('customer') - customer = get_object_or_404(CustomerProfile, id=customer_id) - business_id = request.POST.get('business') if business_id: business = get_object_or_404(Business, id=business_id) else: business = None - selected_items = request.POST.getlist('items') order = Order.objects.create( customer=customer, status=status, business=business, ) - - for item_id in selected_items: - item = Item.objects.get(id=item_id) - OrderItem.objects.create(order=order, item=item, purchased_at=datetime.now()) - return redirect('orders') - + return redirect('orderdetails', order_id=order.id) context = { 'customer' : customer, @@ -114,12 +103,27 @@ def add_order (request, customer_id): +@staff_login_required +def add_service_in_order(request, service_id, order_id): + service =get_object_or_404(Item, id=service_id) + order= get_object_or_404(Order, id=order_id) + + order_item = OrderItem.objects.create( + order = order, + item = service, + purchased_at = datetime.now() + ) + order_item.save() + return redirect('orderdetails', order_id=order.id) + + -def add_invoice_pdf(request, order_id): + + +def add_invoice_pdf(request, order_id): order = get_object_or_404(Order, id=order_id) - current_year = str(timezone.now().year)[-2:] last_invoice = Invoice.objects.filter(invoice_number__startswith=current_year).order_by('-invoice_number').first() if last_invoice: @@ -163,21 +167,15 @@ def add_invoice_pdf(request, order_id): presentational_hints=True ) + filename = f'invoice_{invoice.invoice_number}.pdf' + pdf_content = ContentFile(pdf) + invoice.pdf.save(filename, pdf_content, save=True) - # Save PDF to a file - pdf_file_path = os.path.join(settings.MEDIA_ROOT, f'invoice_{invoice.id}.pdf') - with open(pdf_file_path, 'wb') as pdf_file: - pdf_file.write(pdf) - - # Associate PDF file path with the Invoice object - invoice.pdf = pdf_file_path - invoice.save() # Return PDF response = HttpResponse(pdf, content_type='application/pdf') response['Content-Disposition'] = 'attachment; filename="my_pdf.pdf"' - - return response
 + return response diff --git a/osinaweb/billing/delete/__pycache__/urls.cpython-310.pyc b/osinaweb/billing/delete/__pycache__/urls.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ce36e5e15651e3e2aa4f7b90316d4ed759fdec2a GIT binary patch literal 385 zcmYjLJ5B>J5ViM{tjGrrKta1gTK6c5C@2vWQJQTc2M>#bKP%fI3U}ZP)JU9zLu^aM z6=+~Ki&l)}nR!q1o}ZmejtJJr>-qgV&d(P7uN1*0K3`xHL{LREEh%mHNJTm>V@iOE z7~)ML5|O^d6)jUSSde`9g&LC6CaHONz?nWt*!kyE>jXF%K+mKJ7d=`@F=yqm00jYh zw$&T1;U*t6BeCJ8vc=XZ?;oZ`nm!!{;kI!&^lUjvPCn*aa+ literal 0 HcmV?d00001 diff --git a/osinaweb/billing/delete/__pycache__/views.cpython-310.pyc b/osinaweb/billing/delete/__pycache__/views.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a09ee1bc8f56af971c28199995fef5e1c00e6539 GIT binary patch literal 667 zcmYjPv2NQi5G5&DQBucs0DnNoss+pr8H1ugyA&vrA<3dekj1l0ml9o)juF6_+BIYM zbnGv2&D3A$lp`geIpFT}PN(;dN9p6^BZBtg;qCGlCFC)H=awM&fNsw)2qLH=EiGxw zO4cT2LPL$I^s3LJA!kF{}oo{aav@hT$@d#n2FuDzcj9E@|I;Lid z;Ji4**2p=xU$t?~)>#u49aj*~SWcsIqYcbkjl9-R2H63Zv;Q3eu(5X9SU/', views.delete_orderitem, name='deleteorderitem'), +] diff --git a/osinaweb/billing/delete/views.py b/osinaweb/billing/delete/views.py index e69de29b..4e927fbe 100644 --- a/osinaweb/billing/delete/views.py +++ b/osinaweb/billing/delete/views.py @@ -0,0 +1,11 @@ +from django.shortcuts import render, get_object_or_404, redirect +from osinacore.models import * +from billing.models import * +from osinacore.decorators import * + +@staff_login_required +def delete_orderitem(request, orderitem_id): + order_item = get_object_or_404(OrderItem, id=orderitem_id) + order_id = order_item.order.id + order_item.delete() + return redirect('orderdetails', order_id=order_id) diff --git a/osinaweb/billing/templates/details_templates/order-details.html b/osinaweb/billing/templates/details_templates/order-details.html index eb6cdba6..347cde05 100644 --- a/osinaweb/billing/templates/details_templates/order-details.html +++ b/osinaweb/billing/templates/details_templates/order-details.html @@ -9,78 +9,71 @@
-

Order 234443

-

Salim Elliye

+

Order {{order.order_id}}

+

{{order.customer.user.first_name}} {{order.customer.user.last_name}}

-

Completed

+

{{order.status}}

-
-

Services

+ {% if order_items %} +
+

Order Items

-
-
-

Service Name

+ + {% for item in order_items %} +
+
+

{{item.item.title}} +

-
- - - -

Add

+
+

${{item.item.amount}}

+
+ > + + + +

Remove

+
+ {% endfor %}
+ {% endif %} -
-

Products

-
-
-
-

Basic -

- -
-

$0

-

monthly/restaurant

-
-
-
- - - -

Add

-
-
+ {% if services %} +
+

Add Services

+
-
-
-

Standard + {% for service in services %} +

+
+

{{service.title}}

- -
-

$20

-

monthly/restaurant

-
-
+
+

${{service.amount}}

+
+

Add

-
+
+ {% endfor %}
+ {% endif %} +
diff --git a/osinaweb/billing/urls.py b/osinaweb/billing/urls.py index 98fcf974..d21abcda 100644 --- a/osinaweb/billing/urls.py +++ b/osinaweb/billing/urls.py @@ -5,6 +5,7 @@ from billing import views urlpatterns = [ path('add/', include('billing.add.urls')), + path('delete/', include('billing.delete.urls')), # LISTING path('items/', views.items, name='items'), @@ -12,6 +13,6 @@ urlpatterns = [ path('invoices/', views.invoices, name='invoices'), # DETAILS - path('invoice-details//', views.invoice_details, name='invoicedetails'), - path('order-details//', views.order_details, name='orderdetails'), + path('invoices//', views.invoice_details, name='invoicedetails'), + path('orders//', views.order_details, name='orderdetails'), ] diff --git a/osinaweb/billing/views.py b/osinaweb/billing/views.py index 2cac222a..de212bef 100644 --- a/osinaweb/billing/views.py +++ b/osinaweb/billing/views.py @@ -1,9 +1,7 @@ from django.shortcuts import render, get_object_or_404 -from django.utils import timezone -from datetime import timedelta from .models import * -from django.http import JsonResponse, HttpResponse -from django.template.loader import get_template +from django.db.models import Q + # LISTING @@ -49,13 +47,18 @@ def invoice_details(request, order_id): def order_details(request, order_id): order = get_object_or_404(Order, id=order_id) + order_items = OrderItem.objects.filter(order=order).order_by('-id') + order_item_ids = order_items.values_list('item_id', flat=True) + + services = Item.objects.filter(Q(type='Service') & (Q(customer=order.customer) | Q(customer__isnull=True))).exclude(id__in=order_item_ids).order_by('-id') + products = Item.objects.filter(Q(type='Product') & (Q(customer=order.customer) | Q(customer__isnull=True))).exclude(id__in=order_item_ids).order_by('-id') context = { 'order' : order, + 'order_items' : order_items, + 'services': services, } return render(request, 'details_templates/order-details.html', context) - - diff --git a/osinaweb/customercore/__pycache__/custom_context.cpython-310.pyc b/osinaweb/customercore/__pycache__/custom_context.cpython-310.pyc index ffca7fb2f3fbbc6d99c96395119810cf52a904c9..466c37ad163af259c84b3008e65bde59d53f53f9 100644 GIT binary patch delta 341 zcmZ3&ae#u6g$%XqHS9&1HSAdeS%Nhz@j^hB zFpw50G)`dv@xdgJSHoDtl)^WMDVRZ%e{uk02X7U(Zc1WFYJ6f!N@~jF8;k~wqLVq9 zHiq0{P0K7QE-B&$y6F}dm>r*&n420Ul9O0m5?@+?&=sFld5a6djS@pvfe_c^n7oHc zOE8KXNqQwik@DnMOpS~NlXIArh1eJcm{=IOfRK%egOQ85NOkg5<|t8Bpc{&mQ3;jF HEG!BDo~>N` delta 168 zcmcb>xrBo+pO=@50R(nxr4_PFk6I`I`6*D%&FrSQ&S3TDvco7}?KFzD u%vvlf8HyApcQH3Is!Zl#QD);{p@C5khX4Qo delta 84 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 delta 4408 zcmaKv3vgUj8OQhBeJ1?A$>lt%ia>glC{H>#Hgl4E>}8qk=(*tmArtr@r5*C6Y1J{T!$~)=VMmAl1nX*|(ayP$B$?e?L?}#sdouVPX$u`P>cAQ1!No}euOsX?J zf=_d?2=g&fDWCM0%X-aMEQ&}UclC*4IpJKi!cT7^0HBkI=21bC6&5;A3q55fGDbR; z6ub)U3e_{OIG1a&1yHmDadapW`c5)SkL?uAP`1fso^IA5xu=0EGXmNHr6CJ zdh6I?IqDtGmB8={KqJIMqLdz%D=BswmS@)gB8qgf{jQMPeN{BIJwBb?B%cV^ z%d@_Fb1i6Z0^niXrM{+Q(FN@?pc_q^6`cK0!NSx)+RivB3h#k&(o>$nb2+H0~n%GcJP5Nn_k5 zuMcbq*3jz_O{lc&kdFnrbNPu|?i&Tyg~1}ANwJo9~0qa-k^i_N7Z@0c3K zxQ`4CWRp)TXD*j=Y|zo*aHJS1=l(n-;2*1C3_IkV!IsEj4|hMp_Bu_+9qh1XI=M$4 z4OYjXb4@#^UEF&}+v_&H(+=*NcHiZsZC}(U7Rtv%4W%&}XUe%G%`H#QNXF2)43(_U z`Rv@vyDAXwf;CLyRW0QIIL*6TSp2X znEUg{w|sT-tAQc|_jlcMpcXcPuU6()=? zhS9?_yS3-XMvg}6u0Bc@MmZtC%2^YuAZj1gG&?3@j2hmT3SLqmeN`&-$mmy=~}THGnWUDhqHDsRZS z#kDlt1t%@{P+AzK?T=j-3ij8BVJiRwnC}tktRR(rDwo;B_(*chc$!p3m=Mt-bgW>p z$+dR_9+4$wipg*JD>ZS8tcdR0T>B(aD52`p|0c2fzcL+}03MbV4) zmOqYG`+t+~uxGAAuwv;YI&7?{^S_qwFfrHR{!4cFEp>P^-(gaouedebLho^AxzeUS zO361R)0N9|h_e;iq^Gh%&|%jznHteA#JweG;5&h7;9~LijwdH^JUOUh zs7MF25OZk-k3(BnP4kI&WxkoZdZdk6t44)KhG5m$x+>2rS_H@Pt9SLFw4AePeqAjQ@ zstTN;o0gNRzUATih)$bx1g1C#=gK!Zw8BBRn%QGgMjNlIdK5-(7!~zSr1Wt!of(T) zh*D`bu8J-|BkGnwT*Rkp_zV`=vM%(JmG z%ySPJO>LED>sHHmnp)X$S>L?2;UV<&2;Inz&^@DnOHWU4f4`_9E!DFF^3LXd|HtV? zgn&=T7n@htsxu1HvI0hS&`622nlbJ1W3sztNA5A0J`Q}1Fy+ttv?3Pou!FY}t!sgO zzzN`cz%f9ruev;}z^jUMFQoMZD=?lFso^9Y9*LxB=V=f0uCe5(Zn^G|rLD_zpN7Uq z)nv$|nqZ$L$^{GKyaZegybQDh-z8X{WXeqM)U8^-gvEaFMKWcOZ58{@M}O-o);l04_|?l0bT{L zylOLvagsJ4aoH2Ze8eAtw}9UPF95$MtQW6A`~%@gz4#O4KLf7=Z(yejRgC@uNu|go z4%yfdY?VR5E8YTgK1P;Oe3qn7inncg(C_w2fW)N%Thb5c`39f%gEE zW+8#k0QUnA0G}mHb;+OA*2^~+m)H2A`yB9j;6dOJ@Q|!tQorO25FZ8}0lo;lf3o6B zr0XUZ#g}DjNq6omF!?Hg%BSj#I0{MCp07iC9C!kFk`OO1xKAE~_8Y(quoh7Hrvj-m z2K(0v?WA95bo`qMGh-%4>@tP4+ivHbssgHPJ&Pe81@c899(gNTh zpu(t@DF0dUBNu57P6%+rU}i9B>}M zlnNG3En$TtLXq^X8l_)BBl>ExpdS+Qp00YjC&;5+wf;ac^Ob0kVy1=UFS^?P3q!%; AyZ`_I diff --git a/osinaweb/customercore/custom_context.py b/osinaweb/customercore/custom_context.py index 8e76a44a..ed6b7514 100644 --- a/osinaweb/customercore/custom_context.py +++ b/osinaweb/customercore/custom_context.py @@ -20,4 +20,13 @@ def utilities(request): unread_updates_count += 1 ticket.unread_updates_count = unread_updates_count + last_update = ticket.ticketupdate_set.order_by('-date_added').first() + if last_update: + ticket.last_update_added_by = last_update.added_by.first_name + ticket.last_update_date_added = last_update.date_added + else: + ticket.last_update_added_by = None + ticket.last_update_date_added = None + + return {'active_subscriptions': active_subscriptions, 'customer_open_tickets': customer_open_tickets} diff --git a/osinaweb/customercore/migrations/0009_alter_ticketattachment_ticket.py b/osinaweb/customercore/migrations/0009_alter_ticketattachment_ticket.py new file mode 100644 index 00000000..2aac446e --- /dev/null +++ b/osinaweb/customercore/migrations/0009_alter_ticketattachment_ticket.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.5 on 2024-04-26 08:49 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('customercore', '0008_rename_ticketupdatereadstatus_ticketread'), + ] + + operations = [ + migrations.AlterField( + model_name='ticketattachment', + name='ticket', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='customercore.ticket'), + ), + ] diff --git a/osinaweb/customercore/migrations/__pycache__/0009_alter_ticketattachment_ticket.cpython-310.pyc b/osinaweb/customercore/migrations/__pycache__/0009_alter_ticketattachment_ticket.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..78c75ce8906e47815784a74d65ffb47c6d3ec024 GIT binary patch literal 816 zcmYjPO^?$s5Vf6;rlFNqAkYFAt`Q>X5fDOK?Xnzz}XZ4a6|h) z;4k^giNAn^mT}Uhwd9fC^LReqxS38vg6l{5`23I&^2>t#8 z=V*YWRFISjx}vEAZix|v1AaLYE@lbJap{*~c}sZ0zjDRs%0a)02r%o|jNjd)!`zd+ zQ@W|3&6^g|C$rh?Y1Tr`E68+_Ux4n`f@^4j3#Ga4)Rwk{IT&2H);#}IL9LBHFdx3$ z*^e6!Y~&hmDS3Ti+`5y}jGH>cWVrhcD z5}bh<9nTlX^OIL5Y}T-y%TLliz}LO`^F8^fpj8P}g#?hY*g$du>Owc`WWi-oJ$lR6 z7Q9!5&YLP}R8jM!hRgmiBpt|0SSI^QCA+VX;4GeH+?K!9e5do4h}WCe{=gA#bsJ4U znB!i%9;1vNQul9g-QP#P84p=wvFvpjw7CDDjE8R*--yuOwcXm-yS|6hL*z{GVwk{7 Oib(lr4p>0%IsX9qoAKEI literal 0 HcmV?d00001 diff --git a/osinaweb/customercore/models.py b/osinaweb/customercore/models.py index 96e13ad6..b8a2ba3e 100644 --- a/osinaweb/customercore/models.py +++ b/osinaweb/customercore/models.py @@ -65,7 +65,7 @@ class TicketRead(models.Model): read = models.BooleanField(default=False) class TicketAttachment(models.Model): - ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE) + ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE, null=True, blank=True) ticket_update = models.ForeignKey(TicketUpdate, on_delete=models.CASCADE, null=True, blank=True) file = models.FileField() diff --git a/osinaweb/customercore/templates/details_templates/inner-customer-ticket.html b/osinaweb/customercore/templates/details_templates/inner-customer-ticket.html index 6ebe7751..07e58ee4 100644 --- a/osinaweb/customercore/templates/details_templates/inner-customer-ticket.html +++ b/osinaweb/customercore/templates/details_templates/inner-customer-ticket.html @@ -6,33 +6,47 @@
-

Ticket {{ticket.ticket_number}}

+

Ticket #{{ticket.ticket_number}}

+ + {% if last_ticket_status.status == 'Open' %} +
+
+

Opened by {{last_ticket_status.added_by.first_name}} at {{last_ticket_status.date_added}}

+
+ {% elif last_ticket_status.status == 'Working On' %} +
+
+

Updated to 'Working On' by {{last_ticket_status.added_by.first_name}} at {{last_ticket_status.date_added}}

+
+ {% elif last_ticket_status.status == 'Closed' %}
-

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

+

Closed by {{last_ticket_status.added_by.first_name}} at {{last_ticket_status.date_added}}

+ {% endif %}
-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus sagittis, risus id sollicitudin - maximus, diam velit tempus est, pulvinar cursus arcu nisi nec ligula. Nunc eleifend, est eget - lacinia semper, ligula purus scelerisque nunc, a molestie elit magna quis sem. Curabitur eget auctor - mi, vel sodales purus. Nullam odio erat, convallis sit amet feugiat molestie, fermentum sit amet - purus. Proin eget nunc eget risus tristique tempus. Donec egestas bibendum ligula sit amet porta. +

{{ticket.description}}

+ {% if ticket.ticketattachment_set.all %} + {% endif %} +
@@ -92,16 +106,21 @@ {{update.description}}

+ + {% if update.ticketattachment_set.all %} + {% endif %}
@@ -175,7 +194,7 @@
- +
-

My Tickets

+

My Tickets

@@ -85,17 +85,17 @@ -

{{ ticket.last_updated }}

+

{{ticket.last_update_date_added}}

-

{{ ticket.updated_by }}

+

{{ ticket.last_update_added_by }}

-

2

+

{{ticket.unread_updates_count}}

@@ -164,11 +164,11 @@ -

{{ ticket.last_updated }}

+

{{ ticket.last_update_date_added }}

-

{{ ticket.updated_by }}

+

{{ ticket.last_update_added_by }}

{% endfor %} diff --git a/osinaweb/customercore/templates/products/osimenu-plans.html b/osinaweb/customercore/templates/products/osimenu-plans.html index 9964f9e9..1923782e 100644 --- a/osinaweb/customercore/templates/products/osimenu-plans.html +++ b/osinaweb/customercore/templates/products/osimenu-plans.html @@ -13,7 +13,7 @@