From 082d3bc08675f47e819756665621a71fd8cef94c Mon Sep 17 00:00:00 2001 From: jcquadros Date: Fri, 8 Mar 2024 19:31:43 -0300 Subject: [PATCH 1/8] first commit --- venhapararecomb/db.sqlite3 | Bin 0 -> 131072 bytes venhapararecomb/manage.py | 22 ++++ venhapararecomb/notafiscal/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 168 bytes .../__pycache__/admin.cpython-310.pyc | Bin 0 -> 209 bytes .../__pycache__/apps.cpython-310.pyc | Bin 0 -> 455 bytes .../__pycache__/forms.cpython-310.pyc | Bin 0 -> 404 bytes .../__pycache__/models.cpython-310.pyc | Bin 0 -> 206 bytes .../__pycache__/urls.cpython-310.pyc | Bin 0 -> 299 bytes .../__pycache__/views.cpython-310.pyc | Bin 0 -> 593 bytes venhapararecomb/notafiscal/admin.py | 3 + venhapararecomb/notafiscal/apps.py | 6 + venhapararecomb/notafiscal/forms.py | 4 + .../notafiscal/migrations/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 179 bytes venhapararecomb/notafiscal/models.py | 3 + .../notafiscal/templates/index.html | 16 +++ venhapararecomb/notafiscal/tests.py | 3 + venhapararecomb/notafiscal/urls.py | 5 + venhapararecomb/notafiscal/views.py | 16 +++ venhapararecomb/venhapararecomb/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 173 bytes .../__pycache__/settings.cpython-310.pyc | Bin 0 -> 2335 bytes .../__pycache__/urls.cpython-310.pyc | Bin 0 -> 1023 bytes .../__pycache__/wsgi.cpython-310.pyc | Bin 0 -> 592 bytes venhapararecomb/venhapararecomb/asgi.py | 16 +++ venhapararecomb/venhapararecomb/settings.py | 124 ++++++++++++++++++ venhapararecomb/venhapararecomb/urls.py | 23 ++++ venhapararecomb/venhapararecomb/wsgi.py | 16 +++ 29 files changed, 257 insertions(+) create mode 100644 venhapararecomb/db.sqlite3 create mode 100755 venhapararecomb/manage.py create mode 100644 venhapararecomb/notafiscal/__init__.py create mode 100644 venhapararecomb/notafiscal/__pycache__/__init__.cpython-310.pyc create mode 100644 venhapararecomb/notafiscal/__pycache__/admin.cpython-310.pyc create mode 100644 venhapararecomb/notafiscal/__pycache__/apps.cpython-310.pyc create mode 100644 venhapararecomb/notafiscal/__pycache__/forms.cpython-310.pyc create mode 100644 venhapararecomb/notafiscal/__pycache__/models.cpython-310.pyc create mode 100644 venhapararecomb/notafiscal/__pycache__/urls.cpython-310.pyc create mode 100644 venhapararecomb/notafiscal/__pycache__/views.cpython-310.pyc create mode 100644 venhapararecomb/notafiscal/admin.py create mode 100644 venhapararecomb/notafiscal/apps.py create mode 100644 venhapararecomb/notafiscal/forms.py create mode 100644 venhapararecomb/notafiscal/migrations/__init__.py create mode 100644 venhapararecomb/notafiscal/migrations/__pycache__/__init__.cpython-310.pyc create mode 100644 venhapararecomb/notafiscal/models.py create mode 100644 venhapararecomb/notafiscal/templates/index.html create mode 100644 venhapararecomb/notafiscal/tests.py create mode 100644 venhapararecomb/notafiscal/urls.py create mode 100644 venhapararecomb/notafiscal/views.py create mode 100644 venhapararecomb/venhapararecomb/__init__.py create mode 100644 venhapararecomb/venhapararecomb/__pycache__/__init__.cpython-310.pyc create mode 100644 venhapararecomb/venhapararecomb/__pycache__/settings.cpython-310.pyc create mode 100644 venhapararecomb/venhapararecomb/__pycache__/urls.cpython-310.pyc create mode 100644 venhapararecomb/venhapararecomb/__pycache__/wsgi.cpython-310.pyc create mode 100644 venhapararecomb/venhapararecomb/asgi.py create mode 100644 venhapararecomb/venhapararecomb/settings.py create mode 100644 venhapararecomb/venhapararecomb/urls.py create mode 100644 venhapararecomb/venhapararecomb/wsgi.py diff --git a/venhapararecomb/db.sqlite3 b/venhapararecomb/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..882843ded834be3d39ec72cca82710a0b58e469e GIT binary patch literal 131072 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 Ef5C(HVE_OC literal 0 HcmV?d00001 diff --git a/venhapararecomb/manage.py b/venhapararecomb/manage.py new file mode 100755 index 0000000..3018984 --- /dev/null +++ b/venhapararecomb/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'venhapararecomb.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/venhapararecomb/notafiscal/__init__.py b/venhapararecomb/notafiscal/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venhapararecomb/notafiscal/__pycache__/__init__.cpython-310.pyc b/venhapararecomb/notafiscal/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..821dccbee4f43056e06e5a90844efaf3e199ba62 GIT binary patch literal 168 zcmd1j<>g`k0*S`gsUZ3>h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vTKO;XkRX?jV zCnqyizbrK`Be5W{D6uFtIX^c^Hz_eWJ2fu_U0gpeza%j&vp6|1M?XG3GcU6wK3=b& X@)n0pZhlH>PO2Tql42$x!NLFlNmwcF literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/__pycache__/admin.cpython-310.pyc b/venhapararecomb/notafiscal/__pycache__/admin.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3e54a1b3db10174ef6125d713758bfb807f3d627 GIT binary patch literal 209 zcmd1j<>g`k0*S`gsrEqnF^Gc(44TX@fuanW zjJH@5Q*tx&{4|+v@ug%X=B4NBCFkdr6lEqAfecv5P{abHz{D>P{fzwFRQ;^doSe*5 z{j$`&jKqS(qQs)q{F219%;Mz49DT4=dIgoYIBatBQ%ZAE O?HGZE7lSMkU;qGCa5csN literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/__pycache__/apps.cpython-310.pyc b/venhapararecomb/notafiscal/__pycache__/apps.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5ff2c474422caa6fb1ed478281c3e71cb9d8f003 GIT binary patch literal 455 zcmZ8dy-ve05VqqKg|w9r>cE1;nt|j65Nbi9TNk!0mYZ|h6ekXGf&?3ahu{_ZN?w@| zZ@|R4t!Twb_xXN5-<=)~LxOVl`Yk{3{dCTu_~?vL%>@Dwpo)|VbbxqTUx)k%-#kNnPLSDlZn9iyR6?XN+n_2$G}}2zJwyftUKgkj1wrGu?{3Fqu$W zmX~u_iE5!^n8&3CsZ4xREGAv6?+U5FhSgugEb7^S^GcMGa~pDw^__C|fb+*rs9ok1 zWG*_@a)B&7-_ZCjwer_02x?`Fngn;-opqtn%Vz$3q&eb-a``cCTr`TG3jM?C7yUw*cqj7`-GGf0! C<8%-J literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/__pycache__/forms.cpython-310.pyc b/venhapararecomb/notafiscal/__pycache__/forms.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..33daadb4f7bb26b30110b4c83917b599b8520b7c GIT binary patch literal 404 zcmZ8du};G<5Ix69X-m2xK7cI)f((uS|$P zVB(wzQE}3p@7+5;-JO|C#(?(t@+If^et58JA%ZD-bA&;FAPO|e34wDEfuPSIs3cYJ zL~|;_Ye=F`?1O~3Xlbl&3XgUzKrlsb4lqc_iGVzi^fi2gJQ4&I0=GB6y3FwREE%{V zV>Q>3F*jyR8__DC$Bb=Su6o9LO*hI)C9_g0;r6-RwB^>Yd#&EVj*#xc_eHugTBcR2 zR4LP~tXF)^Ew{2TdU3qq#jUKx|9V=RJH9NNf~&OK>16$2DQbFe{C$QHlddvLLN^c< euWw90ROr{}sJ|)t%wOFNPy3C|$gflkhrti6zhDdi literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/__pycache__/models.cpython-310.pyc b/venhapararecomb/notafiscal/__pycache__/models.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7f974977eb247bddc41f97da8c0dc6e8f7f450f7 GIT binary patch literal 206 zcmd1j<>g`k0*S`gsg^+cF^Gc(44TX@fuanW zjJMcw^HWlDiv2X1ZgHk$CFZ5)>!l zMq)u?QDRYQa(-@-Zc<`$c4}S IkWB&%0Ez81hyVZp literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/__pycache__/urls.cpython-310.pyc b/venhapararecomb/notafiscal/__pycache__/urls.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f690233d8575a8fc7f1c58eb68cbe0ed8f70114c GIT binary patch literal 299 zcmZ9GJ5Iwu5QcaB!XgRxaDjaR6s4o1p>wzK46)5VtX(@mPs>5L(za9)H=u!8Xi!F) zZ}iXGZZ?;K4PHM8>im3P))UwqBg_F5z|;&$}$5V1yM{ zc-KtM_;=yr>%aKAZF;Mz85gAnYK~-jIY}oSbyn}M_p*B=gXj6i*jYXdzLTnnC+q1Y VlsDSqqG%hx^(A91)^L@S-#>X!Oz{8! literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/__pycache__/views.cpython-310.pyc b/venhapararecomb/notafiscal/__pycache__/views.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b3ec8957668f897e541329b86850a146243f06cf GIT binary patch literal 593 zcmZ8ey>8S%5Z)iJeVB^`K`AIGDU5{u0tg{NB9KssbXT2(kmH@4ecAP1cGpQjzA7|y zJVH|Danf!}g?Ixh#zsOX#+pwv-;TcdvDw*43EJKFU+|3*@?%K0jbZW%-91B)L{ddG zT~Ip2Ofk(Fp+rXufee??SF(sDn~_ZX#Cnp^5L;*^*ux6d|CzvuqrXOXbA+C(Q2UhG zr=Ci7h5E=a$sdyq_53>O=?&emo?VL@vf-Zge5~Pb$j4+8VIHmGfjN8Plb*=vYMkLP zL`NTH^AJPpt?9z#QmaoVje;*}gF{{Bwbv?}gjj>GjSOOKo7M+$@b3NoEHJ=uU0Mer zSpo_eAGj}%TfC7y@Z;5?~Z@=Fbwb4+lI;9#Y&Y`VK z)GaMkMjt;vE~`_#(f@qW8eg6?t}0b=-oS;+*PnwJ=N=lmU4)cQSV|GcZ%R{UA0eG3 z;elM0?b76~Hr7|2cjMGy4=<48E&%!d-x=q_*kYu@{VmSkL!nV^++hob#$ob88`&v% OIs8@^BTUIIo$^0`HJNY# literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/admin.py b/venhapararecomb/notafiscal/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/venhapararecomb/notafiscal/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/venhapararecomb/notafiscal/apps.py b/venhapararecomb/notafiscal/apps.py new file mode 100644 index 0000000..66eaea5 --- /dev/null +++ b/venhapararecomb/notafiscal/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class NotafiscalConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'notafiscal' diff --git a/venhapararecomb/notafiscal/forms.py b/venhapararecomb/notafiscal/forms.py new file mode 100644 index 0000000..bb139b0 --- /dev/null +++ b/venhapararecomb/notafiscal/forms.py @@ -0,0 +1,4 @@ +from django import forms + +class XMLForm(forms.Form): + arquivo_xml = forms.FileField() \ No newline at end of file diff --git a/venhapararecomb/notafiscal/migrations/__init__.py b/venhapararecomb/notafiscal/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venhapararecomb/notafiscal/migrations/__pycache__/__init__.cpython-310.pyc b/venhapararecomb/notafiscal/migrations/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b54e270db5ffda517eebcdcb37843bb9d45b421e GIT binary patch literal 179 zcmd1j<>g`k0*S`gsUZ3>h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o10OKO;XkRX?jV zCnqyizbrK`Be5W{D6uFtIX^c^Hz_eWJ2fu_U0gpeza%j&vp6|1M?W_+y(qCHGe56b iKR!M)FS8^*Uaz3?7Kcr4eoARhsvXF_VkRKL!T + + + + + Document + + +
+ {% csrf_token %} + + + +
+ + \ No newline at end of file diff --git a/venhapararecomb/notafiscal/tests.py b/venhapararecomb/notafiscal/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/venhapararecomb/notafiscal/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/venhapararecomb/notafiscal/urls.py b/venhapararecomb/notafiscal/urls.py new file mode 100644 index 0000000..ee51af7 --- /dev/null +++ b/venhapararecomb/notafiscal/urls.py @@ -0,0 +1,5 @@ +from django.urls import path +from . import views +urlpatterns = [ + path('', views.index, name='index'), +] diff --git a/venhapararecomb/notafiscal/views.py b/venhapararecomb/notafiscal/views.py new file mode 100644 index 0000000..cfcfdc6 --- /dev/null +++ b/venhapararecomb/notafiscal/views.py @@ -0,0 +1,16 @@ +from django.shortcuts import render +import xml.etree.ElementTree as et + + +def index(request): + if request.method == 'POST': + + print('entrou') + xml_file = request.FILES['xml_file'] + tree = et.parse(xml_file) + root = tree.getroot() + print(root) + for element in root: + print(element.tag) + + return render(request, 'index.html') \ No newline at end of file diff --git a/venhapararecomb/venhapararecomb/__init__.py b/venhapararecomb/venhapararecomb/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venhapararecomb/venhapararecomb/__pycache__/__init__.cpython-310.pyc b/venhapararecomb/venhapararecomb/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37936d4d86976cbc77cb6641b4c94984e2ce1537 GIT binary patch literal 173 zcmd1j<>g`k0`=P0sUZ3>h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o10CKO;XkRX?jV zCnqyizbrK`Be5W{D6uFtIX^c^Hz_eWJ2fu_T^xfSAD@|*SrQ+wS5SG2!zMRBr8Fni N4rEg?6OdqG002Q>EC>Jq literal 0 HcmV?d00001 diff --git a/venhapararecomb/venhapararecomb/__pycache__/settings.cpython-310.pyc b/venhapararecomb/venhapararecomb/__pycache__/settings.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f17795a5fb75964e5562c5dc254a54af66400583 GIT binary patch literal 2335 zcmb7FTaVjB6t=z2rRk>K?rtx%Lb6n7NnxE{wiF>$>P@`c(A>0ky5JYf@l29QeMvo& zZsRw^-{=GIfW+V6XUr>4hq8vNf-N;*s#fit`bNSAhGv^zJ<#I`Y>(6h0$G@x! z!mr88@|A~|CvelBU_gQ;AQ4HP=u4I)3RuD`--+MLKM3R8IA`V2id8_eRU8V|xuJk^ zKZ;ffo_TnlM+IvYfdk%yvHMyu8ZR7MwY9$ma4ptUy=5v_~p5?TkF zOK2kR#l=^Nt$R~k9nG>;vCN?3JD;L?=TVu3jEoKKw#qGPaqFm8ZkDZpI56Wbg4Rzag+h1 zQ^i3Q0IMvV5SLbu60gqT*$69xsplykp-c$}Ckt}|1c5Mtil;zUe=iMR)F_(WCpXZjA=p_wRm)#zPvg?T3$MuaWx_ ze{k#GXzYgW&DqE^D}{J-4x_qZz#`ID)1t;3S?Lra-pB|O7aTA)n_wDW%_u3R6v}*B z;e)~%g2(l&2ZN1qlkK3q6okwf5b8P}7z_84is`Z4-MX-hQv*qa>+5f zh@-MCJGbVgT=M$#9gFaY`(o_4FMt^8*SnG93PFtx6_ou`7&KWEt{1RBi;*S@$ z$Bmm*_8rJc#p4GVs)SYEj>C9tdE~& z7LfMQ#G&*sjF1f{3qff(wMTKJv4qM~h7IBq&q?Ujwb+5&I-_;`Zyx)X@ndOwx*P?^vqgZfb$>dQ;pwWz(OVc5Mht1J7fs- z3U>+iP`h%K7i=4jcH8EK2^^pv=|>WjmKSY1Idl?vglXu#!aNTjAz&ph?r4Ud>^LtO zdTn1f?PvNoJXhCudV9RAHJhCSy>3747^cB5G}?vVBtV z+P(c|t<&D+=S;oTZEB`&@U;VDuaVd{8#OKID1NT4nOYLo;McUC`PA-ehH=o@uiMYH zW&@NRXvA_;Ywz{6J>9N#>N)^6TDom@pk<0ZNVswDvo_BsGt+|1O+c@z1z^6^`C|4CR8CE{_0jop^vL$_>d7?&728a3-)K_r{0e~jp}5^i(kNIOg;P< zzWD7%|d_1&>WP88>!Ym)MSMXJBSqiGSgj zvSo$%0~UzuG?l6%B(RjozB)PgoO2z0a*`lek2gQ~qaH%v{9%8^aCi=n^)H5Ihy^Sx z0~yZ3!0&ryPe!vy#@>a-{FBY_8Bj@WI2H<6<(9uHIkg;H&Zh~6wQ{bqQ$m<7Y{u49E%mM)^d?-9huJ;i zbR`N)JeWXxOOjWgsRS-NP0ngnw9?zQE$RIXzhDegg@vrNaZ`*JMoTQOb6QnhaVxXM zKj`q@fj6+{5IzO7tMO3prUE}7zojh-DcXGj{Gh%Mwexv4i&x3*A3Yo~4BP$$lBJZp@-kbJU zWQHE(Uq3I1A1_(gWhpp0_$gr8#Ye8#Vf~M@?~zs4&ESdDtS! HgTb%gU|d0B literal 0 HcmV?d00001 diff --git a/venhapararecomb/venhapararecomb/__pycache__/wsgi.cpython-310.pyc b/venhapararecomb/venhapararecomb/__pycache__/wsgi.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0009f9a92c7d58e9a5bb6aa0b2c69dcf215bd583 GIT binary patch literal 592 zcmZWn!EO^V5cN7~Qx=LipsGjTP$atUg$qKcNNuB3B|W4FDVL42o@^Yv_R4lrTB)ag z1XnonOTKX6g!lta%qBvL!bl$L&1mL5&)Dworv&ZA{cre^5c0DDo7P5fg2x}DlVn6> zBB@SB3EnMDtJbKM5J=|juRF3WcfL_Xtp_sNm2^nDyLUg*kHcP{71m5u$)?t^C77A0 zg%b`6TTNK)>>P@arD;Df_*`2Lo`o5(b)nE&Of)dznP8Qb3k^pamY~^EIJHU{QGsOR zv8ZdU3K5hw<1zL-N4Cm3V9FqIwMsB+u(|SVsx-W09w42CQ2W=MOI!F%&V?!MKTRl* zgW<2TV?MJt!Ey<;wzn0Sz;Ar1c=`*+LI&L=J})8UO)TG#5f4r;-VJ(J`S9%exS$A1=@C4!5R|c?dz7(sw(tljkTU&m*-yK3faQ3VcV_w09H zp+kJU!Tg=LX0a>x=MvRdz~>9C74R+UqlqX!fsxzs|8T>e)wgl)&3X-Q@xKt?u(ZkE KqbKw!P3d1Ol)OCv literal 0 HcmV?d00001 diff --git a/venhapararecomb/venhapararecomb/asgi.py b/venhapararecomb/venhapararecomb/asgi.py new file mode 100644 index 0000000..1117c7b --- /dev/null +++ b/venhapararecomb/venhapararecomb/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for venhapararecomb project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'venhapararecomb.settings') + +application = get_asgi_application() diff --git a/venhapararecomb/venhapararecomb/settings.py b/venhapararecomb/venhapararecomb/settings.py new file mode 100644 index 0000000..c78bdb7 --- /dev/null +++ b/venhapararecomb/venhapararecomb/settings.py @@ -0,0 +1,124 @@ +""" +Django settings for venhapararecomb project. + +Generated by 'django-admin startproject' using Django 5.0.3. + +For more information on this file, see +https://docs.djangoproject.com/en/5.0/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/5.0/ref/settings/ +""" + +from pathlib import Path + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure--okz#m@yr*2dh72v&hf420%djgsnt457yxdcqe$&1hjcoc#yhl' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'notafiscal', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'venhapararecomb.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'venhapararecomb.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/5.0/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} + + +# Password validation +# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/5.0/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/5.0/howto/static-files/ + +STATIC_URL = 'static/' + +# Default primary key field type +# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/venhapararecomb/venhapararecomb/urls.py b/venhapararecomb/venhapararecomb/urls.py new file mode 100644 index 0000000..15e4a89 --- /dev/null +++ b/venhapararecomb/venhapararecomb/urls.py @@ -0,0 +1,23 @@ +""" +URL configuration for venhapararecomb project. + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/5.0/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path, include + +urlpatterns = [ + path('admin/', admin.site.urls), + path('', include('notafiscal.urls')), +] diff --git a/venhapararecomb/venhapararecomb/wsgi.py b/venhapararecomb/venhapararecomb/wsgi.py new file mode 100644 index 0000000..6c218a6 --- /dev/null +++ b/venhapararecomb/venhapararecomb/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for venhapararecomb project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'venhapararecomb.settings') + +application = get_wsgi_application() From 579a83a4462ee56dc188a1d0fbf5303eaf0b6e60 Mon Sep 17 00:00:00 2001 From: jcquadros Date: Sat, 9 Mar 2024 13:52:37 -0300 Subject: [PATCH 2/8] prototipo leitura processamento e envio de dados --- teste.py | 23 ++++++ venhapararecomb/db.sqlite3 | Bin 131072 -> 196608 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 182 bytes .../__pycache__/admin.cpython-312.pyc | Bin 0 -> 636 bytes .../__pycache__/apps.cpython-312.pyc | Bin 0 -> 496 bytes .../__pycache__/models.cpython-312.pyc | Bin 0 -> 2001 bytes .../__pycache__/urls.cpython-312.pyc | Bin 0 -> 364 bytes .../__pycache__/views.cpython-312.pyc | Bin 0 -> 3586 bytes venhapararecomb/notafiscal/admin.py | 6 +- .../notafiscal/migrations/0001_initial.py | 50 ++++++++++++ .../__pycache__/0001_initial.cpython-312.pyc | Bin 0 -> 2622 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 193 bytes venhapararecomb/notafiscal/models.py | 19 ++++- .../notafiscal/templates/index.html | 20 ++++- venhapararecomb/notafiscal/urls.py | 2 + venhapararecomb/notafiscal/views.py | 71 +++++++++++++++--- .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 187 bytes .../__pycache__/settings.cpython-312.pyc | Bin 0 -> 2600 bytes .../__pycache__/urls.cpython-312.pyc | Bin 0 -> 1143 bytes .../__pycache__/wsgi.cpython-312.pyc | Bin 0 -> 691 bytes 20 files changed, 177 insertions(+), 14 deletions(-) create mode 100644 teste.py create mode 100644 venhapararecomb/notafiscal/__pycache__/__init__.cpython-312.pyc create mode 100644 venhapararecomb/notafiscal/__pycache__/admin.cpython-312.pyc create mode 100644 venhapararecomb/notafiscal/__pycache__/apps.cpython-312.pyc create mode 100644 venhapararecomb/notafiscal/__pycache__/models.cpython-312.pyc create mode 100644 venhapararecomb/notafiscal/__pycache__/urls.cpython-312.pyc create mode 100644 venhapararecomb/notafiscal/__pycache__/views.cpython-312.pyc create mode 100644 venhapararecomb/notafiscal/migrations/0001_initial.py create mode 100644 venhapararecomb/notafiscal/migrations/__pycache__/0001_initial.cpython-312.pyc create mode 100644 venhapararecomb/notafiscal/migrations/__pycache__/__init__.cpython-312.pyc create mode 100644 venhapararecomb/venhapararecomb/__pycache__/__init__.cpython-312.pyc create mode 100644 venhapararecomb/venhapararecomb/__pycache__/settings.cpython-312.pyc create mode 100644 venhapararecomb/venhapararecomb/__pycache__/urls.cpython-312.pyc create mode 100644 venhapararecomb/venhapararecomb/__pycache__/wsgi.cpython-312.pyc diff --git a/teste.py b/teste.py new file mode 100644 index 0000000..1836788 --- /dev/null +++ b/teste.py @@ -0,0 +1,23 @@ +import xml.etree.ElementTree as ET + +#xml = ET.parse('32211207872718000117550010000217781877120005-nfe.xml') +xml = ET.parse('NFe-002-3103.xml') +root = xml.getroot() +nsNFe = {'ns': 'http://www.portalfiscal.inf.br/nfe'} +# recuperando o valor do campo NFe infNFe dest xNome e cnpj +#1) Listar os valores e data de Vencimento dos boletos presentes em um nota fiscal conforme o CPF ou CNPJ de um fornecedor. Verificar qual deles está presente +#2) Apresentar o nome, identificador (CPF ou CNPJ), endereço dos clientes de um fornecedor. +# fornecedor +xNome = root.find('ns:NFe/ns:infNFe/ns:emit/ns:xNome', nsNFe).text +cnpj = root.find('ns:NFe/ns:infNFe/ns:emit/ns:CNPJ', nsNFe).text +print(f'Fornecedor: {xNome} - CNPJ: {cnpj}') +# clientes +for dest in root.findall('ns:NFe/ns:infNFe/ns:dest', nsNFe): + xNome = dest.find('ns:xNome', nsNFe).text + cpf = dest.find('ns:CPF', nsNFe) + cnpj = dest.find('ns:CNPJ', nsNFe) + if cpf is not None: + ident = cpf.text + else: + ident = cnpj.text + print(f'Cliente: {xNome} - Identificador: {ident}') diff --git a/venhapararecomb/db.sqlite3 b/venhapararecomb/db.sqlite3 index 882843ded834be3d39ec72cca82710a0b58e469e..4de6e213829ddcc2a43e2482ea95d774dc3e6d2b 100644 GIT binary patch delta 7654 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 Be8>O* delta 530 zcmZo@;Av>!m>?}E$H2g#0K_n0HBrY{SdKw2+=~?`#K`{}Bq7fKd$V9c4?m}6nc3$r$3VrfZ6 zd_ihaZf0?DW`3RoFDJ7i2Usw@D8ICThl^Pr!YwUMEn;Apyh>k_jZK(|S(jt-O?@>{ zAugbmZ2a8}{O|Zr^WWm%%fEoXdt+lc|Kx7_N@fY3gvsmEXC zFv@M;>%wTo%*6O$W8)ph?N>b+Ll_w^PHa58{ku0KmxwO2JA*L8X9oT(z5?E@JTJJO zbJ=jNH$-8_*ogh`0Gk3k3& z4+t>5JDJgx1;{s=*r>PtKr-V?*6jy#810#-pKxY8H{I5oarbsN55|5*My}0_5B~d4 ln!qB!#^1%j|CawI|0(`G{PX#{Ha3>=PwzUJmtkIamWj77{q763w+F}nZ& literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/__pycache__/admin.cpython-312.pyc b/venhapararecomb/notafiscal/__pycache__/admin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a3090d4dd41600ca932f1dc8df0a94556d4d2ec8 GIT binary patch literal 636 zcmbVKJxc>Y5S`6^BpxIvDHURSh4}$SEQ~}*kwVboxaM*@#=Gp@hP{grtgLM9{0-ty zu@WQ7fgfOFz(Pou%H3cHu`^T5ym`x;eY5Ocv1oye&+{*QmGwh4v(SFQ7zn^MP@sfC zL>xkZ=BUPUk>+TT?&y)>7?J6i1dxQKnS5TuwK<+4)NbWe75`G{OR0>dROVbY&~0O+ z%-SR~JQ@Y@NV&K5%xZ8EqmPt}EMI2<#wljz9%q>H%xdw}YXph!v6j7(m1yY29bWZ$ zoQj|=)B|T`#3`~w7_t$jN_mwE>P$}pIjtbD6C^2$8yHI#CWrNH_b5S;xM82Mz}?5B zoARD}hViM_^MohR=TUpB?fG4d>0jQBrK^*vD|fm}wKtd)cBGF!!(Fi|uTaY+$1;6u vgpe25e1qBp)ZW3kv@WbCDBnZ*syT$p^8#})gpEa}F@*I+ruhgJp+3nE^GJl# literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/__pycache__/apps.cpython-312.pyc b/venhapararecomb/notafiscal/__pycache__/apps.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..314b4d0dfa95cf211ddb39125568d48f7474b82c GIT binary patch literal 496 zcmZ8dJ4?hs5Z+C4a^6D@5g&zxjgZ3BDsph%q1}Ong(0x)WjAN;HV?Cj5If<1fZcWW z;!m-$JOWl$f`xF}T;*;O6`W$``)1}FX6C8ctN~#M7w`05#8*jvtWtvct^iX&0D%m6 z(1Z{u;1m#L0*FfCqgwQtN~-CVH%WAuEqB7O8~Bbpw2N}#VM*p|0!#q~CM3XA2sBlq zm|CjpTGr|ZF?L*TV^&PK*(M|G4+Db?3@;#*apTw>c9J+aaVaBN&Hokj^-5Mn$j2T< zD61hP`V%H`1EH$~v$C>EsDl$0BP^yMCm*B9+5?!&6&GjSL+hN=h+CtCG1ux*K8}OX zx~Bdm4snDdY6sq6Z-DJF^~wLd^|z9R!;l+c8p(g=P7{DPg`0rc*8a1$KC5rs_9B_d z>wR6#>gCB&9LWzC@`gltQQlDJ8B6kpUdTAKU4_e3)uNwQsCxY`UOPDRo|JM Bg)#sD literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/__pycache__/models.cpython-312.pyc b/venhapararecomb/notafiscal/__pycache__/models.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..18e249acd2433c8faeffde73345e1720d4bef030 GIT binary patch literal 2001 zcmcIly>Ht_6hBhmq&}iT71~;e0Yf&bB=*n(9fBfgYDG!Y+8xpcg&=@9lP8%9MXE>H zs5TkMpiEIe0Iwb!*h5Em>L1WaumA}JI&~7zp@7{bQ{OvUvLh&Qm%icY?(uhzPru)L z$KMkPg@EOL{EKA*g#3w{iG|J=r^m3^Ck8Pji!`LNBoUe1Cx-l#7y%~LgOdXnzlV?u ztsD@@ARt3mAcF!K24v(4WJn;RfQ(&%47ZhnI>tf@k{50`2D4lpw-Y-rlbn77k$u8Q zSu#jjmI({gqZ81@uOS`DhmyZ9Lm96@1umh&?O-9~DJ6&7OlO9}#|E5#A$dxJey3T? zuC=zuNeFEgB3@L}Y}#O&<|uDKhs-%V}12nY~S$lvB=hr?IuVMfE4lHfG}$+iB6N z>FU&~_?)dZ+Z?+=I4r3(jlCjIPY%Aq{G@44 ze}c#V5A#AFq;|$w6m)xQCJ5W3;GyhC%St;`2z!xr%Vc(o@i2sW1YHaqh!=Bg4VsCy z*k(cHI6_=S7e|K#@dP@2xtA~vNMcq^or3(L6_{DGKW9Ft@Rqxe*6$YYc}jKKB>Wm4 z7tCRyJTq}vgnI|vT=FydUTK)g_cQrl!&T+l;XoNP^|e*d<9+AxZdC2UvH; zNckAmD#-pM8D`CFxn9y>y4j$X*0iY3T>dsdHVg525_$2WkM-v$v`a0JCsw2_=0{Qn zZBY$|1~P(z4u1!d`E&3tuHHj8BUBD!=#YkqQ1QiXX&7JZ#}|M8;Fu2LpLFhxvMasn zFuT&vuAF4w?|k`Yp)lcmp?dJ-YN1#N=$#|Xku(+W4bn_+Jmt0WsZ&h6Ef)fwvI$p6 zNn9c45+vqHFpp6$wL$InR}OligJ^y)s{6C(3UeQ||YsQv;4Tm=H zlj6687*Qd=sNvPVcp3fJzs~RQTaXJsA?_F8{tifz^ashE1!d`GFT0=nK6gf7c@_;w ipGn>7bL*LPMsR(mh{)sTm1mWU$f|$lAAqciQvU@!D~I&} literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/__pycache__/urls.cpython-312.pyc b/venhapararecomb/notafiscal/__pycache__/urls.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dd2f5c2049518ad126adc7c25472bcf57e65a66c GIT binary patch literal 364 zcmZ8bzfZzI6n@uhOSPhju8t;#LH+<^Ty$_UabSTi2ls@+_1fIEAfrw&IqJV)^gnTR zYQp41;(%de@-9eBe8cy?@BRGVtJQ5V;Xiy~Ve+RHoA7?g^2(4W;J}H1gfs~O?r#`4~rtc5p>aimKqy;yR*vu()| zysr6W$oouo(|VzVR`!9-#&O-ll@8Ku{CWyk3QVv1*Ln=eW-TK;14YmUK;=a literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/__pycache__/views.cpython-312.pyc b/venhapararecomb/notafiscal/__pycache__/views.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8ddf4e1bbd788f0594f7bc97f0e4866d38f15bf3 GIT binary patch literal 3586 zcmb7HTTB~Q8b0I8jPV5<4A@{2h!Y5=DP$213%QU2=9UDq3)__tEi#^Qu;W{221wX( z(n>3>BUOsM`(TieV4s#MdEl{+d92iznK+TH(^N&>yj0o;Hrb~>?SIBh%m$NmkK}Xy z^IyLIKmWP>3k(Swwpqk%TC#wZgr&6#3Vb5$|(oH=Hhvm97i=d3LKXEbNKtMf5G6Bj-T(>xbv zIerRA6VI_>o(qaUQ$%LK=FtQn=YkxY;4w2C4Rdjk!}L%h%83bVo=S*;(XbEOezV^C68Dl%e=l(WtQ^1pBQ9mZrB@ zFlF_P&_6neE2Wck5zA4nM+dBwp5!e|r3{ijVmqqG(vsoPL41+wqw;OIL&3vW8$oAXDQpI%*S9`59!d7`AeH* zuIR%Ow@P$niDZg6kFF1LU}0^WI&HTo^p#*hkPquI`KT^O0{I9+K5UY$Vm|C;&599K zA7kfukDXnzR$NK7WM^v*uS8-blVoLUH}!A}$UUe#x_;Jq37B7T1~~2UdA9Byci~25 zgovvWY8Yu}HbseUO(W8zQROjmqD*U)M6vbc4zUfSe=~ED*<+K2JP)@b#iSe{cM}Qh zM<;M<#FH>lTSb4TG--L1Y7RWru#Kum=5f;_@{T}*6LHQ!V(=XDQ7d{&QiOiBk6N}_ z#ja&f9QZi-zdpn>|2HP{xJ5g;DW~L&v}*|EG2$!J8ugwGeW2-;N9m9!%_D`tBX1m_g!iG_Hi$Q>;^>!jzWV8RYX$VZ+VonORa~0_?(_SQML} zTL^`t9M;8!HSdxrCI`B^S65fNk_lc6L_=zA=?cd~U5k8oJjAV?iVFi%qg*!(z&)V2 zSXd;SJ5z}mx7PYDmEozIlRh0b#6c4qg7IWz&0R^KWXUsJGDeFe-cs^wQGrH@!)MhL8M3-J(79v3w<-a)8((vgDV)0en}E-5t- zs+M%*K?eC7T9x}Kb->0jd>hN;i;ixK$v5U>qc z3kiN92uDTac!mh+g9)kid==@)>abqmL`=gW0zF<`l!3^|yWy+D49|VO4139w_Yv#K zp);tV8RG(+9&A+4OetAv?o>1mj6cDWBU~4d4+8H>_ zA%UQ^R%pNcet2O14+6&v^O5CfG(11T3Ae>WavpYmDFAs4!1q@ow)o*`{16Iz4%wVy(Wovw6JnP?UZrz&Ln8^5x4tLI;weQqFsaIOZ zo;$|(YlxTq2IOi?j}Z_lE6Hd4PnPqp8?O*;>jP-FXUnu>pIyx^ctblH*|`%B|W*$?0HUa zPb!}7SBSDnREBv00Yg9qN4w%^-x=E-{d)S_K6z$QxfYa@YqF#Lx#Lg!dZN46_rm>w!xs~=u_aP8srgXzt&t?7;FLUWJO-1ALDZtlr9Pdu|u5{=0R zlMkmJOl@A+y0USl;5n~&&VMs0d(P)QW6!MPFP)zCvApw)Y(4YRQjT9IFI{cg01{)$mBCcMtuMz)SV$uiQFQ!XivmE8F@K<3<{%#1Z k&_RYM>IZcCN92`}_XpJWBf6MJ7r#fA*K{xSF{L8>7b-LrJOBUy literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/admin.py b/venhapararecomb/notafiscal/admin.py index 8c38f3f..9157264 100644 --- a/venhapararecomb/notafiscal/admin.py +++ b/venhapararecomb/notafiscal/admin.py @@ -1,3 +1,7 @@ from django.contrib import admin +from .models import Fornecedor, Cliente, Boleto, NotaFiscal -# Register your models here. +admin.site.register(Fornecedor) +admin.site.register(Cliente) +admin.site.register(Boleto) +admin.site.register(NotaFiscal) diff --git a/venhapararecomb/notafiscal/migrations/0001_initial.py b/venhapararecomb/notafiscal/migrations/0001_initial.py new file mode 100644 index 0000000..7c35c74 --- /dev/null +++ b/venhapararecomb/notafiscal/migrations/0001_initial.py @@ -0,0 +1,50 @@ +# Generated by Django 5.0.3 on 2024-03-09 14:39 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Fornecedor', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('nome', models.CharField(max_length=100)), + ('cnpj', models.CharField(max_length=14)), + ], + ), + migrations.CreateModel( + name='Cliente', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('nome', models.CharField(max_length=100)), + ('identificador', models.CharField(max_length=14)), + ('fornecedor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='notafiscal.fornecedor')), + ], + ), + migrations.CreateModel( + name='Boleto', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('valor', models.DecimalField(decimal_places=2, max_digits=10)), + ('data_vencimento', models.DateField()), + ('fornecedor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='notafiscal.fornecedor')), + ], + ), + migrations.CreateModel( + name='NotaFiscal', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('boletos', models.ManyToManyField(to='notafiscal.boleto')), + ('clientes', models.ManyToManyField(to='notafiscal.cliente')), + ('fornecedor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='notafiscal.fornecedor')), + ], + ), + ] diff --git a/venhapararecomb/notafiscal/migrations/__pycache__/0001_initial.cpython-312.pyc b/venhapararecomb/notafiscal/migrations/__pycache__/0001_initial.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b47e0ef281958d5f044660eea10fab0a5a0523ef GIT binary patch literal 2622 zcmd5;J#5=X6ecN(`mt+SR4#0&vTN5?QNTY{kT`bH#_b>oASm8Rrc9A4 zNgI);6v)sqTRmoMVGSMKscV2PBr1T$Ee+7gKnDR%mrOa5QY^D-~!!oq^F#Y(ROs` zL@rT)EO}}~iKYnXt%n9baAiON51#YY+1JdGfCMz~wwXih(|)QH@Hyy+s}GLA-wqs- zt_9-|~`Ox5E9N>8jO zF4_Rw4)^(}QZ@Q5*onL&J6D|5Oui=e7#MF~J&O*a4)Xd%-=GJGx3hx#GDnU zFRmEG+t&tmcj8i9@*M7iV5dfxBCW}63I#U$J!A_7i;5~k0Rlxuln9E5y1kaAQHbBw z6;4nguS0-_nyT2~)fTq{TPUDGRpcdcAEMA6R4a-GIhk)jM9WG8o&Zc*mc)IEzt2ff zuIbx|7UX9A#6AtUfzb|@sfthn8uG15B9wKAhDCtiVpSA)JC$JdWm@~=vZC`e_L|N1^t0)9u6UvwiL4=xW-vMZ7)hWY<-RxDn1EbK2 zSX;&gD%vEX!0I-yx}sf8DAwe4Tqg$9dAX(_3RIBap$T6anDFI$tIKO&qR^U4Nzca` zF0?C-Zt!wzOR>kEQ>6)eSI#fQDUMG(2dhivZ}C3R%Jp4I63c5)+tHO~8MC;}H+hv; zp`bJ>(-mIW!K-=IUOpqLe0HCebGh6nT#tyEW=myoC};3tL7T$`eMmeVi9EQ~rO7eo z!QHN(2&8@tTK-AXKY1KZJ`Il>(Wys!R&>gYP94!tGDe9rWVI933|2o5M~zta;HnkN znz8J!_d2mfgI#*X`b{VHnZYi0ee~GKGp{cY?6T)##NRK*bt9dBeA7zj&2;{#(n&8H z>Eo36h4|ml0{x-@o zDCQoD8Bm#Vf1YOgCqtdaFcf$>@0>m7xViiAQ`?Knnmcm2V gLz3hvLy$NAB0hS?d`vQrf)<-G+04HLRvZT}0K#u?*8l(j literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/migrations/__pycache__/__init__.cpython-312.pyc b/venhapararecomb/notafiscal/migrations/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..06ecd2d2da85d5d75cc5975264ef4828b086df20 GIT binary patch literal 193 zcmX@j%ge<81eTF+QbF`%5P=Rpvj9b=GgLBYGWxA#C}INgK7-W!N^rJ{2`x@7Dvrr2 z&B@7(aY-%CF3B&5DND`ENGwP!N-RoE&d*KKO-fA8PR&a}7mvxyFG)qi$RQ!%#4hTMa)1J0N~m- AUjP6A literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/models.py b/venhapararecomb/notafiscal/models.py index 71a8362..3b039aa 100644 --- a/venhapararecomb/notafiscal/models.py +++ b/venhapararecomb/notafiscal/models.py @@ -1,3 +1,20 @@ from django.db import models -# Create your models here. +class Fornecedor(models.Model): + nome = models.CharField(max_length=100) + cnpj = models.CharField(max_length=14) + +class Cliente(models.Model): + nome = models.CharField(max_length=100) + identificador = models.CharField(max_length=14) # cpf ou cnpj + fornecedor = models.ForeignKey(Fornecedor, on_delete=models.CASCADE) + +class Boleto(models.Model): + valor = models.DecimalField(max_digits=10, decimal_places=2) + data_vencimento = models.DateField() + fornecedor = models.ForeignKey(Fornecedor, on_delete=models.CASCADE) + +class NotaFiscal(models.Model): + fornecedor = models.ForeignKey(Fornecedor, on_delete=models.CASCADE) + clientes = models.ManyToManyField(Cliente) + boletos = models.ManyToManyField(Boleto) diff --git a/venhapararecomb/notafiscal/templates/index.html b/venhapararecomb/notafiscal/templates/index.html index 2201387..540695c 100644 --- a/venhapararecomb/notafiscal/templates/index.html +++ b/venhapararecomb/notafiscal/templates/index.html @@ -10,7 +10,25 @@ {% csrf_token %} - + + + {% if xml_data %} +

Nota Fiscal

+

Fornecedor: Nome - {{ xml_data.fornecedor.nome }} | CNPJ - {{ xml_data.fornecedor.cnpj }}

+

Clientes:

+ {% for cliente in xml_data.clientes %} +

Nome: {{ cliente.nome }} Identificação: {{ cliente.identificador }}

+ {% endfor %} +

Boletos:

+ {% for boleto in xml_data.boletos %} +

Valor: {{ boleto.valor }}

+

Vencimento: {{ boleto.vencimento }}

+ {% endfor %} +
+ {% csrf_token %} + +
+ {% endif %} \ No newline at end of file diff --git a/venhapararecomb/notafiscal/urls.py b/venhapararecomb/notafiscal/urls.py index ee51af7..feb22e3 100644 --- a/venhapararecomb/notafiscal/urls.py +++ b/venhapararecomb/notafiscal/urls.py @@ -1,5 +1,7 @@ from django.urls import path from . import views + urlpatterns = [ path('', views.index, name='index'), + ] diff --git a/venhapararecomb/notafiscal/views.py b/venhapararecomb/notafiscal/views.py index cfcfdc6..adb6ce4 100644 --- a/venhapararecomb/notafiscal/views.py +++ b/venhapararecomb/notafiscal/views.py @@ -1,16 +1,65 @@ from django.shortcuts import render -import xml.etree.ElementTree as et +import xml.etree.ElementTree as ET +from django.shortcuts import redirect +from .models import Fornecedor, Cliente, Boleto, NotaFiscal +import json def index(request): - if request.method == 'POST': - - print('entrou') - xml_file = request.FILES['xml_file'] - tree = et.parse(xml_file) - root = tree.getroot() - print(root) - for element in root: - print(element.tag) + xml_data = {} - return render(request, 'index.html') \ No newline at end of file + if request.method == 'POST': + if 'read_xml' in request.POST: + xml = ET.parse(request.FILES['xml_file']) + root = xml.getroot() + nsNFe = {'ns': 'http://www.portalfiscal.inf.br/nfe'} + # recuperando o nome e o cnpj do fornecedor + xNome = root.find('ns:NFe/ns:infNFe/ns:emit/ns:xNome', nsNFe).text + cnpj = root.find('ns:NFe/ns:infNFe/ns:emit/ns:CNPJ', nsNFe).text + #fornecedor, created = Fornecedor.objects.get_or_create(nome=xNome, cnpj=cnpj) + fornecedor = {'nome': xNome, 'cnpj': cnpj} + + # recuperando o nome e o cpf ou cnpj dos clientes + clientes = [] + for dest in root.findall('ns:NFe/ns:infNFe/ns:dest', nsNFe): + xNome = dest.find('ns:xNome', nsNFe).text + cpf = dest.find('ns:CPF', nsNFe) + cnpj = dest.find('ns:CNPJ', nsNFe) + if cpf is not None: + ident = cpf.text + else: + ident = cnpj.text + clientes.append({'nome': xNome, 'identificador': ident}) + + #cliente, created = Cliente.objects.get_or_create(nome=xNome, identificador=ident, fornecedor=fornecedor) + boletos = [] + for det in root.findall('ns:NFe/ns:infNFe/ns:cobr/ns:dup', nsNFe): + valor = det.find('ns:vDup', nsNFe).text + data_vencimento = det.find('ns:dVenc', nsNFe).text + boletos.append({'valor': valor, 'data_vencimento': data_vencimento}) + #boleto = Boleto.objects.create(valor=valor, data_vencimento=data_vencimento, fornecedor=fornecedor) + xml_data = {'fornecedor': fornecedor, 'clientes': clientes, 'boletos': boletos} + request.session['xml_data'] = xml_data + + elif 'save_nf' in request.POST: + xml_data = request.session.get('xml_data', {}) + + fornecedor, created = Fornecedor.objects.get_or_create(nome=xml_data['fornecedor']['nome'], cnpj=xml_data['fornecedor']['cnpj']) + + for cliente in xml_data['clientes']: + Cliente.objects.create(nome=cliente['nome'], identificador=cliente['identificador'], fornecedor=fornecedor) + for boleto in xml_data['boletos']: + Boleto.objects.create(valor=boleto['valor'], data_vencimento=boleto['data_vencimento'], fornecedor=fornecedor) + + nf=NotaFiscal.objects.create(fornecedor=fornecedor) + nf.clientes.set(Cliente.objects.filter(fornecedor=fornecedor)) + nf.boletos.set(Boleto.objects.filter(fornecedor=fornecedor)) + + return redirect('index') + + return render(request, 'index.html', {'xml_data': xml_data}) + + + + + diff --git a/venhapararecomb/venhapararecomb/__pycache__/__init__.cpython-312.pyc b/venhapararecomb/venhapararecomb/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e62f09caec220bb5b3a6c00d25a6af1d0b20bfdb GIT binary patch literal 187 zcmX@j%ge<81eTF+QbF`%5P=Rpvj9b=GgLBYGWxA#C}INgK7-W!igLD!2`x@7Dvrr2 z&B@7(aY-%CF3B&5DND`ENGwP!N-RoE&d*KKO-fA8PR&a}7sueo$7kkcmc+;F6;%G> fu*uC&Da}c>D`Ev&#R$a3AjU^#Mn=XWW*`dyYL7F@ literal 0 HcmV?d00001 diff --git a/venhapararecomb/venhapararecomb/__pycache__/settings.cpython-312.pyc b/venhapararecomb/venhapararecomb/__pycache__/settings.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..52bef5a114ebd4cc2563e35a06f8fecfc28d9e34 GIT binary patch literal 2600 zcmb7GOK;mo5GM70TUM0VNm_tG8oP39Do&iF4FWf`L_0!cN!2562m=JIT}hNFQsGi@ z#FOs5^wu77%B{#x=_N)FF?cf2Q-K`h1ij?cp&qs%8>mZ2+}(M6Gdnvo%Rj>500qzY z&p+U`Fh%`kFUF5&H2L%aCcjdM5-3C?heEd;f`g_U6n0?eTY4zf^pDj}$G4+tb713? zZqLr62_EDWyvQZ^>XhKGQ^@^>76LGOU<@L!5JJE~E@blpZ)llD!Pl-jErd}>h@dcv zU=NxxgA|3LuN^Wi%%E8m1F2bbY4DB@-j`*%?h>NtiZF}jgc#Vn1phdi7cQf#!jCAF?G1RI8|)(KP7bmk>i8&X@+B^_6_)-Kc5wI;3_Y#^|SRjf+}M$B%P zSwsWfWeK%pl_7?t8zad@rb7UY8G+wpZ?ktndjqgrnvNM+1v4$lkTsQopV5%Pu&m&3 z!4Dj07)F~sOeT?5CG60~*aL7UiPa#<#9*}A>Bb}# zfgvoz_9Uf)$^WsXPvS}UjLzL(>HU+O| zGTxsMeK6&V1c99NgM&51P_7P=azb%>6XUQ=DsK%#IiYp`oJ}Zlb+0K^_nu&tmsUU1p_r8=^iqQp<~QP3kDdNxq}q(>RhB zifrJ!W&ntzdBS0N_}peD$6Kx(x5eursCx6s)CLB5)RqX@*K{O8XOYps99tn+=M1}) zI|eSvEm@K5@_06s&~$U{qDWh^Dz`eVELQ7A<5d5Li|P-{rZDpH6yWhi0dk!d*5&G1 z1UFWfJH&EU$|=(e{U6FFX?{6^g-EtEgcZWB%XKI(Z9~Qi$|dG3uP8!m7e&k4h6bw0 zySfuXYxzXcZaOwy$3#V0(f2q zd-~2u*wOR%87hAN9Tf#scjPd}9!BSXdvp+8Ja#*yAmbj$T%-Im@1jEA=>R?7U{RP{ z{5ZKN4i}fhUpU@T^Zf;CcD@%r3eEQXN5Pq%?+Bds^g~o+4jc_oSMD89G5r?A;$ItM BXRZJM literal 0 HcmV?d00001 diff --git a/venhapararecomb/venhapararecomb/__pycache__/urls.cpython-312.pyc b/venhapararecomb/venhapararecomb/__pycache__/urls.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..88c7170ded45bb1590e8ca8b8eee73a892b0451b GIT binary patch literal 1143 zcmb7EL2J}N6rN<0?l!en1i|Bo=x(4UD)eBm7O55s>OrjHvap>^W_PnqX2MKTZSmqo z>dl_|8>BzQi_nv~c<>~6XenNL@=Z3OOGVH*WM5w1eDC|dH?yB-XDtNl&a0pFNe!Xz z>ZMxsGB|zYlHs?!S zLmtz4%t%ZZn<{SF)^bFoywL+;!365xSnza6g(BheN(;0=H?~)(>?;Z7nxR5Qogxb3-|v*URedsUq*@XnPK{kbWqA5*53j+S7Tx+l8~! z?dIo8x}Y)@VNby2L;1{v24O%(m?~|^Fr~Snl;txM)Bc2x;WIjUvFvr$Bo(qV%AzRj zJfLy|&S2-v&47{n8t0@=Zaahwd?MR=~j9(aO zSH7WZM^nh0-nsm7Vb9z3_Lg>+4vec`jmFN!4==x5x_&U*JTO{^W^GP?HzU+P!Ec6} BS-1cI literal 0 HcmV?d00001 diff --git a/venhapararecomb/venhapararecomb/__pycache__/wsgi.cpython-312.pyc b/venhapararecomb/venhapararecomb/__pycache__/wsgi.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c211c64d8bf92901c15cf04b0a47f5ec7c076c00 GIT binary patch literal 691 zcmZWn&ubGw6rS0QP1)EWVvEN?yaeoSJ$SH)Af|>?O%G`mLtr!6c}XUnomqA!sp+jJ z{{;U8k^U)ODhk40RK$beLCLKrXPbtW_zv@a@xAYRGxK3(#Y5KazxoaDFhW1_WNwA? zVA{38Tf|TcG0Yr+TiAM6II-JuF#Q-S*w#s$sX^Mo=V9W_73LsPy zN@B%E0@ekLL69*``B_WS7#QhvXp#sXQNxw&bnLt*mMvB(5H2loeAXaJ+TmQ29v5(j zXaH|uOrke~fT>9PY)EBa%{5tp0m$HfW=h!C>~ zUf^Hv(r6zfTde<==Mwy6a=QFr_7)G*vZb;A4CxJf{BbeHf1M&OOs^yC{X}=aA?J;E f Date: Sat, 9 Mar 2024 18:44:56 -0300 Subject: [PATCH 3/8] gerenciamento de nf e estilizacao index.html concluidos --- teste.py | 23 ---- venhapararecomb/db.sqlite3 | Bin 196608 -> 200704 bytes .../__pycache__/models.cpython-312.pyc | Bin 2001 -> 2828 bytes .../__pycache__/views.cpython-312.pyc | Bin 3586 -> 3483 bytes ...edor_remove_cliente_fornecedor_and_more.py | 48 ++++++++ ..._rename_identificador_cliente_documento.py | 18 +++ ...liente_fornecedor_and_more.cpython-312.pyc | Bin 0 -> 1833 bytes ...ificador_cliente_documento.cpython-312.pyc | Bin 0 -> 768 bytes venhapararecomb/notafiscal/models.py | 38 +++++-- .../notafiscal/templates/index.html | 34 ------ venhapararecomb/notafiscal/views.py | 97 ++++++++-------- venhapararecomb/static/css/style.css | 14 +++ venhapararecomb/templates/index.html | 107 ++++++++++++++++++ .../__pycache__/settings.cpython-312.pyc | Bin 2600 -> 2823 bytes venhapararecomb/venhapararecomb/settings.py | 9 +- 15 files changed, 269 insertions(+), 119 deletions(-) delete mode 100644 teste.py create mode 100644 venhapararecomb/notafiscal/migrations/0002_remove_boleto_fornecedor_remove_cliente_fornecedor_and_more.py create mode 100644 venhapararecomb/notafiscal/migrations/0003_rename_identificador_cliente_documento.py create mode 100644 venhapararecomb/notafiscal/migrations/__pycache__/0002_remove_boleto_fornecedor_remove_cliente_fornecedor_and_more.cpython-312.pyc create mode 100644 venhapararecomb/notafiscal/migrations/__pycache__/0003_rename_identificador_cliente_documento.cpython-312.pyc delete mode 100644 venhapararecomb/notafiscal/templates/index.html create mode 100644 venhapararecomb/static/css/style.css create mode 100644 venhapararecomb/templates/index.html diff --git a/teste.py b/teste.py deleted file mode 100644 index 1836788..0000000 --- a/teste.py +++ /dev/null @@ -1,23 +0,0 @@ -import xml.etree.ElementTree as ET - -#xml = ET.parse('32211207872718000117550010000217781877120005-nfe.xml') -xml = ET.parse('NFe-002-3103.xml') -root = xml.getroot() -nsNFe = {'ns': 'http://www.portalfiscal.inf.br/nfe'} -# recuperando o valor do campo NFe infNFe dest xNome e cnpj -#1) Listar os valores e data de Vencimento dos boletos presentes em um nota fiscal conforme o CPF ou CNPJ de um fornecedor. Verificar qual deles está presente -#2) Apresentar o nome, identificador (CPF ou CNPJ), endereço dos clientes de um fornecedor. -# fornecedor -xNome = root.find('ns:NFe/ns:infNFe/ns:emit/ns:xNome', nsNFe).text -cnpj = root.find('ns:NFe/ns:infNFe/ns:emit/ns:CNPJ', nsNFe).text -print(f'Fornecedor: {xNome} - CNPJ: {cnpj}') -# clientes -for dest in root.findall('ns:NFe/ns:infNFe/ns:dest', nsNFe): - xNome = dest.find('ns:xNome', nsNFe).text - cpf = dest.find('ns:CPF', nsNFe) - cnpj = dest.find('ns:CNPJ', nsNFe) - if cpf is not None: - ident = cpf.text - else: - ident = cnpj.text - print(f'Cliente: {xNome} - Identificador: {ident}') diff --git a/venhapararecomb/db.sqlite3 b/venhapararecomb/db.sqlite3 index 4de6e213829ddcc2a43e2482ea95d774dc3e6d2b..d4007d79c6e67a3b723cf16b8f328f95ff050bc0 100644 GIT binary patch delta 3210 zcmcImeQXow8Nc`Z?Zkd5!8im^oiIM4V(0FBw(k-q;g3sfC;m$8IAKy9f1Di$Cr%tE zc0x(wP<5-2wz6y-sx%GO7P@IrLH=M9|9~bYZ7^7?sauh@QdLu7+E#U9VrnaG?>UJ> zQd()!X8U>c`kv>0&-30r&+~g17U~zy*1xjznF|<(kw{vRsE|B=>Yy21xIFYal<3sa zCB>HgQuRf3^m1jddOoa^Va-YVSiTrfXD5^K96=D~Sb-mlkMgl>iXSUx)7fM^l`q7S zxh(q2$5Q#^)F@izDT1PngxN^229jwv)9sYS#4-e7vyN<&W6c%KMpz2Lj^?NNSR$X} zi}_eOUl?=pNnXTWwXB5@O{YPJ0D1!wRbSJ_KXBR z)P4f5!D)CBzN%f;p3&Ze&qF6PXk0-ap7 zqfT7EG6Zx`1=UzRK+j}HgM`&JED>$nK;6ZmQ`o%HpO(YC^%bv7M# zjN49C7=Dg;ZfY=AirIR4Qqm?DXa{ zgY#WkPm-F+juK#}b<(N2*j z)`t4VdgUy*F7_>y1~BQT(f}OQp3}Trf2r;db)@S5(I<+l`f72lPACY=MfB=2CS zB`uPsQMLVa^FCIdwqXWDM7b&zNNwg})6FH%I4sQ@z=J2gxpOBx&cL@GDd_g7_ zWK7s~3{TXxF79(G^lfe6#4+K+7x4X{WyNnU2Q-4d3z&r1alGS+J0Kb@(rSpsj#>z= zTH^99Iobk-Rg9eqeVhc9NOmm6m%mW{e6=HDD?R`x8W^#bNQL^A4B2e zw}5P~S|$NNrK)OWRV%7mUe&UymWr-AgmxE$pTo!SAMkJR0mAzed=LH(-bHB3aJN*V z0%}pIM5Pp!LR4~5E&cWV#tYKxU`wM~6T#pw;7ib>{kQg-c0y~^JkOGi|dXz9$)qRtdKu z{&m@HcpLrQ;fcr%a&D1u~-gvCgb%Emh3P8+V@FP2Pidwo=mxTwgNvf1!s4P`TuLC@SkKo@C z#C^E6diP2n)FFJiN_{?vZ>g^V{Sv;69FIe;LoUZctw87Q3HKQ|e;4O>+j~8B17~ms z{C(lxh%>U5a)%m-~i6fD(oie1gRl^=s?1|c$sPuI0pLWdRl2@j}D3BdyXHR0?8eqO3LC;gG&E#U9fDb7i5>MME=SnL+< zlrS`jzl-en6`{R||4OYm2mY*|>H?MH!r>ymMPXNx3LF}nZ%T+p&{aJPu3U+H2P z?LuV2z8X!fFya0h6CP334zz+H4z?=~q8GEqjr?=P?0A0t$lGF=ju(={@xlSR)!+|= z4gN?^&;NjRHW68kqy$45-`TWzXa6l-3m;A6*Mtv_;r|jW^Y|@VY*F-4B56ZnLSjU6 y5Xo~$#4`wiWFL|}t3s~y@}uwI+i|h6QPROip)L#M}a>9Ta;bNC+>6@`fa delta 1844 zcmdUv|8Emz9LMi@+O2E1_9Wy_Pb`b<&l&-%I=J<9q*fl-yK9a4f)K4n3+or{zRWtf^ zcjX&VD^aC6AwxfE?xTw+i;khUH8bc%v_o?OsWjK8#k{6WuaVIJi=(i56Vz8q;}j>b z(fHUPn+!%dJ{1{^ggG8=(#jkFpA_IzKt6eYN3~KWb<`mlv!vZ%hSh3W!=u^|my8IU z9Gxcg%10~*lkrGOh@jIoRg(h^)c{Ur8(syg&Kt`H%G7rV^_^+)JGJ7-I#A|5+B$jr z-7Vv`M4OEtD%yMVA%n}>G2(N2e60pUfNjoE0_SjN{l;NKhGmNdUvsE=tUsF-;=Zv6 z8A~wHL@MPm*bIS)*X`M7p)J-HHk}phUHp){B_6OCi;Zl^-QgZ;aZ|y*HXG~CMnZ;A zXIqxa*!z8>e1^`9hiuK^c+npTcK5a0nY~`pl5_Mh?tNjecdXT!_7`)$Uc28P@8TkZ z!^0jfKAcQMVi~i0Fkk3SL%wqiZPYbqKWI*xfCp4bfPV_POZxbiCNj zrrpVmFG?pvHcz&@r!$`FG52`_k>EHV^CT1fqb|3rvE7>MH*&FfJkBsoFVox8N^?Ss zYuGW?LKy;COTt5?d_Hp~+rse)!C5S{babW!*H|}SNQN7IX{y&nk$z`5kaI9xI<_}H zGMMT2x2FSMhlLJzaalT+B9o-R_>+wumyHT0n~USVM2O>Zoq>qY?X?tq1*f^IC)k@B ziss$^jG6AS*;Ac13&}T;e7rc)-ozX8Bi4k|(`|2ywui|8mE&!F!H_8#+)KB3hMOB* zeaVo;PErZRWHea}Mzg_Wt|h4^i>b+E+d^t<4T+IGa_6`65->bsiNFmzC;POj>D_? zK@?#8^$_?Jzc~bU<5yz9jNcgsZ{gT5u$C^yz*$ft6JVEIP7ty+c$5RxXhNVBI)(v9 z1_d^hj4WcZVd)08Vs0Gj@#_bn3ctrgCDx8XIbQ7mq^v;5(h-4D0w>cy;8 zp`&SVxN^z$A$NF$1Cyooc5nus>IB;J_vE!I8JZ)|FX#c9n^}>*jquzjpjs-<6X*}L zfaay*52!SM39QsgRfa&Hqn8mgE$&1m=6i6uR{z9$sTY5=mLSkqlJYVtw?H}Jt;g&w zP>1Ic)Pbu~{R&c;VHx472lzS%4Qlw0>KeMXq{G)5;4|v|QZ7seQaY_rT>`W4H>8k5 z837jGrr;dXmP?BSfbk!}xWYvJG8F+##5v4lw1rvufR?o-l&|=K3Aa=bqttrEzX

~iE;@HBaFYPPREfS_3SGtl!~=Mb05@Y}2A+{mD0fzrW;5^#kc(Sw3j9G19>C;F zP_O@Y9}ULCb@k%2jS5|m1fmz8ExcIHCXm diff --git a/venhapararecomb/notafiscal/__pycache__/models.cpython-312.pyc b/venhapararecomb/notafiscal/__pycache__/models.cpython-312.pyc index 18e249acd2433c8faeffde73345e1720d4bef030..96a2f8d2f88d0db5a5ba8200fb7b74673b6cd7b2 100644 GIT binary patch literal 2828 zcma);O-vg{6o6-c{J+@P32q1kENE!lHnbv14^c{**r5$5CK5>wmZjCkJAj?_t~+a@ z8uj1<2XYEMK@_#&m}3HOpy-`lkzxTbU@zkM_N=FRN9 zZ{G87U0r?x?Zw7l^kEQnR|J;~d{ zN5u@dOMypGHwqM=Ce>z5oEm#Klen6>Z&GGv@(Y@l%Ot7!sALo~kEuSd6cwg0nl%a! zFFsVVkEpJ;k7snFq|D~btfFO{qZ}=kEsrdlB__*@k;Bg#ZH^%y`x1x>*$JI`T7FXA z_MX|t4X5Hh%PY&eQlPSI`DGa#E@-Grvi$9WqB(Dv2)33lF|V+R9Mx17!oHZ*i+M|c zW!Wj{zap#$9xQ^w-4Zy{90RdLb^?9NU(^GA)j;36SqpqpNxnbAYJra{$vu&C^{$<2 z5O_H5(9;oC&?C0}dmv6`g}Q(a{P?!E$!+k?P}-yN)C+6~z=p3Z#$A>_1!p{ApD_f_ zXXr8@OG}gmV9F61(1%UKWl-S0a-Dg|H`j7jbmVjLBR@mpd}>j`K0>T|0 zT8Y-fL)Gxm`qi!In}OE@weUBUNeuB7C&X7A7dWwVh<}1NCx=+&RDM%92&a<}I)r=! zykSd20s|=UP}>^y!T9O6LFjIZ2i^m!i%I~C8(`@wd*WWpebWFoj9pCXyBKGTAZ8LZ zH>uLlFSPI^!e)PC{zY<7_ClD8w!z zPOis_W-u$HDkVjRECaitddcWaRnVE-A_^%nV<3>IGi#?`oPBn7Oj(TDgtfLTs<(%kXfA!!Un z7=Gp?2;fc{T%M>)gH>tp<=B=|lfJ6l+KG;=%+{kL)#%6{(F>L7oyhRYNIf!KjSR0( zZjHPdeLY%>+^$R^o7WvSuRCm_^UiGk4sQ>{yop84Qmd9w3H4&lbnKZfxCSvXl2y1-1<8PHI3 zlPy9K7lwDXNnogrKr49f_T6bYIi0wF=T_?8w4Lc#FHW$_Sg@2U8nS9+7wlVM`3}@J zCfVmW=hz&GMUJ6B*XA6EC9=m0QFkS^=O3#OW<4biauwIst=v~?z)5jy`1W7 z-!=OJ**ia)(cgKmIe!Jl**G}D(3w*p_5_aO-je8B(%%qWT<=PBwf~3y1_8AZ6uB#{ jKBx`J&0Sx9@HF!z(;%QWx+Si6dG@LHMEje7YKQ9|q>?8v literal 2001 zcmcIly>Ht_6hBhmq&}iT71~;e0Yf&bB=*n(9fBfgYDG!Y+8xpcg&=@9lP8%9MXE>H zs5TkMpiEIe0Iwb!*h5Em>L1WaumA}JI&~7zp@7{bQ{OvUvLh&Qm%icY?(uhzPru)L z$KMkPg@EOL{EKA*g#3w{iG|J=r^m3^Ck8Pji!`LNBoUe1Cx-l#7y%~LgOdXnzlV?u ztsD@@ARt3mAcF!K24v(4WJn;RfQ(&%47ZhnI>tf@k{50`2D4lpw-Y-rlbn77k$u8Q zSu#jjmI({gqZ81@uOS`DhmyZ9Lm96@1umh&?O-9~DJ6&7OlO9}#|E5#A$dxJey3T? zuC=zuNeFEgB3@L}Y}#O&<|uDKhs-%V}12nY~S$lvB=hr?IuVMfE4lHfG}$+iB6N z>FU&~_?)dZ+Z?+=I4r3(jlCjIPY%Aq{G@44 ze}c#V5A#AFq;|$w6m)xQCJ5W3;GyhC%St;`2z!xr%Vc(o@i2sW1YHaqh!=Bg4VsCy z*k(cHI6_=S7e|K#@dP@2xtA~vNMcq^or3(L6_{DGKW9Ft@Rqxe*6$YYc}jKKB>Wm4 z7tCRyJTq}vgnI|vT=FydUTK)g_cQrl!&T+l;XoNP^|e*d<9+AxZdC2UvH; zNckAmD#-pM8D`CFxn9y>y4j$X*0iY3T>dsdHVg525_$2WkM-v$v`a0JCsw2_=0{Qn zZBY$|1~P(z4u1!d`E&3tuHHj8BUBD!=#YkqQ1QiXX&7JZ#}|M8;Fu2LpLFhxvMasn zFuT&vuAF4w?|k`Yp)lcmp?dJ-YN1#N=$#|Xku(+W4bn_+Jmt0WsZ&h6Ef)fwvI$p6 zNn9c45+vqHFpp6$wL$InR}OligJ^y)s{6C(3UeQ||YsQv;4Tm=H zlj6687*Qd=sNvPVcp3fJzs~RQTaXJsA?_F8{tifz^ashE1!d`GFT0=nK6gf7c@_;w ipGn>7bL*LPMsR(mh{)sTm1mWU$f|$lAAqciQvU@!D~I&} diff --git a/venhapararecomb/notafiscal/__pycache__/views.cpython-312.pyc b/venhapararecomb/notafiscal/__pycache__/views.cpython-312.pyc index 8ddf4e1bbd788f0594f7bc97f0e4866d38f15bf3..65d286e3e86b011b718b9fca33444f9bdd0af227 100644 GIT binary patch literal 3483 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 diff --git a/venhapararecomb/notafiscal/migrations/0002_remove_boleto_fornecedor_remove_cliente_fornecedor_and_more.py b/venhapararecomb/notafiscal/migrations/0002_remove_boleto_fornecedor_remove_cliente_fornecedor_and_more.py new file mode 100644 index 0000000..b44f5c0 --- /dev/null +++ b/venhapararecomb/notafiscal/migrations/0002_remove_boleto_fornecedor_remove_cliente_fornecedor_and_more.py @@ -0,0 +1,48 @@ +# Generated by Django 5.0.3 on 2024-03-09 18:27 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('notafiscal', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='boleto', + name='fornecedor', + ), + migrations.RemoveField( + model_name='cliente', + name='fornecedor', + ), + migrations.RemoveField( + model_name='notafiscal', + name='boletos', + ), + migrations.RemoveField( + model_name='notafiscal', + name='clientes', + ), + migrations.AddField( + model_name='boleto', + name='nota_fiscal', + field=models.ForeignKey(default=-2015, on_delete=django.db.models.deletion.CASCADE, to='notafiscal.notafiscal'), + preserve_default=False, + ), + migrations.AddField( + model_name='cliente', + name='nota_fiscal', + field=models.ForeignKey(default=-1995, on_delete=django.db.models.deletion.CASCADE, to='notafiscal.notafiscal'), + preserve_default=False, + ), + migrations.AddField( + model_name='cliente', + name='tipo_documento', + field=models.CharField(choices=[('CPF', 'CPF'), ('CNPJ', 'CNPJ')], default=-1995, max_length=4), + preserve_default=False, + ), + ] diff --git a/venhapararecomb/notafiscal/migrations/0003_rename_identificador_cliente_documento.py b/venhapararecomb/notafiscal/migrations/0003_rename_identificador_cliente_documento.py new file mode 100644 index 0000000..9751b9a --- /dev/null +++ b/venhapararecomb/notafiscal/migrations/0003_rename_identificador_cliente_documento.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.3 on 2024-03-09 18:34 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('notafiscal', '0002_remove_boleto_fornecedor_remove_cliente_fornecedor_and_more'), + ] + + operations = [ + migrations.RenameField( + model_name='cliente', + old_name='identificador', + new_name='documento', + ), + ] diff --git a/venhapararecomb/notafiscal/migrations/__pycache__/0002_remove_boleto_fornecedor_remove_cliente_fornecedor_and_more.cpython-312.pyc b/venhapararecomb/notafiscal/migrations/__pycache__/0002_remove_boleto_fornecedor_remove_cliente_fornecedor_and_more.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..14fa7974a556bc63cf77b0866b99be4b3a6590f3 GIT binary patch literal 1833 zcmd5-&u<$=6rTOz_3p+=oF#3cp$Um2V5zVI5)y(MDY!LKX`-r#pjuW}>z#?S&hCzx zT}Px`KJ zRircp+Hl`+IZ#rgn%S4^%tP*M+A=jmzd_u@$5BkR5JMEi-f)LlW{1wvr!udOMCGas zrG`{hWPsF3wV(`@L-l~|;Nyi^nU~7aVD=@jG^jt5l}oFio*6HLvB@^`r=zJ2O=L9Z zpN}_ZCdAH8h`suJ3{D;9Mtz6VhcgFinj<KVzSz#>Pl-Tz(Nw+-*Ph+<@lR*4Ey0{K!vy=4o{tpafHM8h&E?OL$wnDQIZM*Ft zp$3i|RtF`B$_cL6Dw$&FgkKrWZ2KsHG~Xg9Mr04MM6t>LfML^_#BX5-Vy_)CR+v#% z%GWF89NWokwY+)#D&b0b$fdwbdOO(nP)z1Hwi&wLI01?p$n)dm0!1hzxmtEUTLFS z+US+Gx}~jN=~lONtK;3iZ++XpuySl<7@Hh0PN6V1{|(A=-&)~ZR=U>8z0J<0Yn_W5 zov&&gzj@!w|l zjBNcIP&@KpFm-BlD-#k!q_#^Zo}IWU-0=Lpdq2MSzVpv|-3L0yM}P1K1NfCY<*6*d z**1YgkRVwM3F|Nh7Q6sy9e}iv4V^Wgv_rOhzdRmP%sGQ<0#lsaP&hiXRKKOC#2J0Xa85r_OR5BjFX!Ka5437v`SCA*MtVMwsbb zPjll9=E3I?#?ts|hzl{l!&$D)<(H@1!P^XV77WI590kuX+Z(B2u#f3`F%(*83{}#7 z&=uhxwf_G;SZWn4Un(Hg9+5c3SpTfeOR285-yBYK{+NYv31nMj4q)bj_m0hMYt8-i zYUYD?@2h`WTR*9-Pj7Eb8_j8B*l7x}RU_M%iPR^z`IFq0rk3Uj~tr>o7A)#e3|Q&j&2r8C$1 literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/models.py b/venhapararecomb/notafiscal/models.py index 3b039aa..3c32bef 100644 --- a/venhapararecomb/notafiscal/models.py +++ b/venhapararecomb/notafiscal/models.py @@ -1,20 +1,42 @@ +from typing import Any from django.db import models class Fornecedor(models.Model): nome = models.CharField(max_length=100) cnpj = models.CharField(max_length=14) -class Cliente(models.Model): - nome = models.CharField(max_length=100) - identificador = models.CharField(max_length=14) # cpf ou cnpj + def __str__(self) -> str: + return self.nome + +class NotaFiscal(models.Model): fornecedor = models.ForeignKey(Fornecedor, on_delete=models.CASCADE) + def __str__(self) -> str: + return f'Nota Fiscal {self.fornecedor.nome}' + class Boleto(models.Model): valor = models.DecimalField(max_digits=10, decimal_places=2) data_vencimento = models.DateField() - fornecedor = models.ForeignKey(Fornecedor, on_delete=models.CASCADE) + nota_fiscal = models.ForeignKey(NotaFiscal, on_delete=models.CASCADE) -class NotaFiscal(models.Model): - fornecedor = models.ForeignKey(Fornecedor, on_delete=models.CASCADE) - clientes = models.ManyToManyField(Cliente) - boletos = models.ManyToManyField(Boleto) + def __str__(self) -> str: + return f'Boleto {self.valor} - {self.data_vencimento}' + +class Cliente(models.Model): + TIPO_DOCUMENTO = ( + ('CPF', 'CPF'), + ('CNPJ', 'CNPJ'), + ) + + nome = models.CharField(max_length=100) + tipo_documento = models.CharField(max_length=4, choices=TIPO_DOCUMENTO) + documento = models.CharField(max_length=14) # cpf ou cnpj + nota_fiscal = models.ForeignKey(NotaFiscal, on_delete=models.CASCADE) + + def __str__(self) -> str: + return self.nome + + + + + diff --git a/venhapararecomb/notafiscal/templates/index.html b/venhapararecomb/notafiscal/templates/index.html deleted file mode 100644 index 540695c..0000000 --- a/venhapararecomb/notafiscal/templates/index.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - Document - - -

- {% csrf_token %} - - - - -
- {% if xml_data %} -

Nota Fiscal

-

Fornecedor: Nome - {{ xml_data.fornecedor.nome }} | CNPJ - {{ xml_data.fornecedor.cnpj }}

-

Clientes:

- {% for cliente in xml_data.clientes %} -

Nome: {{ cliente.nome }} Identificação: {{ cliente.identificador }}

- {% endfor %} -

Boletos:

- {% for boleto in xml_data.boletos %} -

Valor: {{ boleto.valor }}

-

Vencimento: {{ boleto.vencimento }}

- {% endfor %} -
- {% csrf_token %} - -
- {% endif %} - - \ No newline at end of file diff --git a/venhapararecomb/notafiscal/views.py b/venhapararecomb/notafiscal/views.py index adb6ce4..2eab0cc 100644 --- a/venhapararecomb/notafiscal/views.py +++ b/venhapararecomb/notafiscal/views.py @@ -1,65 +1,58 @@ -from django.shortcuts import render +from django.shortcuts import render, redirect import xml.etree.ElementTree as ET -from django.shortcuts import redirect from .models import Fornecedor, Cliente, Boleto, NotaFiscal -import json + + +def parse_xml(xml_file): + xml = ET.parse(xml_file) + root = xml.getroot() + nsNFe = {'ns': 'http://www.portalfiscal.inf.br/nfe'} + + xNome = root.find('ns:NFe/ns:infNFe/ns:emit/ns:xNome', nsNFe).text + cnpj = root.find('ns:NFe/ns:infNFe/ns:emit/ns:CNPJ', nsNFe).text + fornecedor = {'nome': xNome, 'cnpj': cnpj} + + clientes = [] + for dest in root.findall('ns:NFe/ns:infNFe/ns:dest', nsNFe): + xNome = dest.find('ns:xNome', nsNFe).text + cpf = dest.find('ns:CPF', nsNFe) + cnpj = dest.find('ns:CNPJ', nsNFe) + + documento = cpf.text if cpf is not None else cnpj.text + tipo_documento = 'CPF' if cpf is not None else 'CNPJ' + + clientes.append({'nome': xNome, 'documento': documento, 'tipo_documento': tipo_documento}) + + boletos = [] + for det in root.findall('ns:NFe/ns:infNFe/ns:cobr/ns:dup', nsNFe): + valor = det.find('ns:vDup', nsNFe).text + data_vencimento = det.find('ns:dVenc', nsNFe).text + boletos.append({'valor': valor, 'data_vencimento': data_vencimento}) + + return {'fornecedor': fornecedor, 'clientes': clientes, 'boletos': boletos} def index(request): - xml_data = {} - + context = {} + if request.method == 'POST': if 'read_xml' in request.POST: - xml = ET.parse(request.FILES['xml_file']) - root = xml.getroot() - nsNFe = {'ns': 'http://www.portalfiscal.inf.br/nfe'} - # recuperando o nome e o cnpj do fornecedor - xNome = root.find('ns:NFe/ns:infNFe/ns:emit/ns:xNome', nsNFe).text - cnpj = root.find('ns:NFe/ns:infNFe/ns:emit/ns:CNPJ', nsNFe).text - #fornecedor, created = Fornecedor.objects.get_or_create(nome=xNome, cnpj=cnpj) - fornecedor = {'nome': xNome, 'cnpj': cnpj} - - # recuperando o nome e o cpf ou cnpj dos clientes - clientes = [] - for dest in root.findall('ns:NFe/ns:infNFe/ns:dest', nsNFe): - xNome = dest.find('ns:xNome', nsNFe).text - cpf = dest.find('ns:CPF', nsNFe) - cnpj = dest.find('ns:CNPJ', nsNFe) - if cpf is not None: - ident = cpf.text - else: - ident = cnpj.text - clientes.append({'nome': xNome, 'identificador': ident}) - - #cliente, created = Cliente.objects.get_or_create(nome=xNome, identificador=ident, fornecedor=fornecedor) - boletos = [] - for det in root.findall('ns:NFe/ns:infNFe/ns:cobr/ns:dup', nsNFe): - valor = det.find('ns:vDup', nsNFe).text - data_vencimento = det.find('ns:dVenc', nsNFe).text - boletos.append({'valor': valor, 'data_vencimento': data_vencimento}) - #boleto = Boleto.objects.create(valor=valor, data_vencimento=data_vencimento, fornecedor=fornecedor) - xml_data = {'fornecedor': fornecedor, 'clientes': clientes, 'boletos': boletos} - request.session['xml_data'] = xml_data + xml_data = parse_xml(request.FILES['xml_file']) + request.session['xml_data'] = xml_data + context['xml_data'] = xml_data elif 'save_nf' in request.POST: - xml_data = request.session.get('xml_data', {}) - - fornecedor, created = Fornecedor.objects.get_or_create(nome=xml_data['fornecedor']['nome'], cnpj=xml_data['fornecedor']['cnpj']) - - for cliente in xml_data['clientes']: - Cliente.objects.create(nome=cliente['nome'], identificador=cliente['identificador'], fornecedor=fornecedor) - for boleto in xml_data['boletos']: - Boleto.objects.create(valor=boleto['valor'], data_vencimento=boleto['data_vencimento'], fornecedor=fornecedor) - - nf=NotaFiscal.objects.create(fornecedor=fornecedor) - nf.clientes.set(Cliente.objects.filter(fornecedor=fornecedor)) - nf.boletos.set(Boleto.objects.filter(fornecedor=fornecedor)) - - return redirect('index') - - return render(request, 'index.html', {'xml_data': xml_data}) - + xml_data = request.session.pop('xml_data', {}) + fornecedor, _ = Fornecedor.objects.get_or_create(nome=xml_data['fornecedor']['nome'], cnpj=xml_data['fornecedor']['cnpj']) + nf = NotaFiscal.objects.create(fornecedor=fornecedor) + for cliente in xml_data['clientes']: + Cliente.objects.create(nome=cliente['nome'], documento=cliente['documento'], tipo_documento=cliente['tipo_documento'], nota_fiscal=nf) + for boleto in xml_data['boletos']: + Boleto.objects.create(valor=boleto['valor'], data_vencimento=boleto['data_vencimento'], nota_fiscal=nf) + + return redirect('index') + return render(request, 'index.html', context) diff --git a/venhapararecomb/static/css/style.css b/venhapararecomb/static/css/style.css new file mode 100644 index 0000000..ed9650e --- /dev/null +++ b/venhapararecomb/static/css/style.css @@ -0,0 +1,14 @@ +:root{ + --primary-color: #0b9ad7; + --secondary-color: #1d7a9f; + --tertiary-color: #f5b111; + --white-color: #deecef; + --dark-grey-color: #283238; + --light-grey-color: #3C4B56; + --black-color: #13181B; + + +} + + + diff --git a/venhapararecomb/templates/index.html b/venhapararecomb/templates/index.html new file mode 100644 index 0000000..c288c05 --- /dev/null +++ b/venhapararecomb/templates/index.html @@ -0,0 +1,107 @@ + + + + + + Gerenciamento de Notas Fiscais + + + + + + + + +
+ +
+

Olá, seja bem vindo!

+
+

Este é um sistema de gerenciamento de notas fiscais. Envie um arquivo XML para começar:

+
+
+ {% csrf_token %} + + +
+
+
+
+ + +
+
+

Nota Fiscal

+
+
+ {% csrf_token %} + +
+
+
+
+
+
    +
  • + Fornecedor:
    + Nome - {{ xml_data.fornecedor.nome }} | + CNPJ - {{ xml_data.fornecedor.cnpj }} +
  • +
  • + Clientes: +
      + {% for cliente in xml_data.clientes %} +
    • + Nome: {{ cliente.nome }} | + {{ cliente.tipo_documento }}: {{ cliente.documento }} +
    • + {% endfor %} +
    +
  • +
  • + Boletos: +
      + {% for boleto in xml_data.boletos %} +
    • + Valor: {{ boleto.valor }} | + Vencimento: {{ boleto.data_vencimento }} +
    • + {% endfor %} +
    +
  • +
+
+
+
+
+ +
+
+

Entre em contato:

+

Email: contato@empresa.com

+

Telefone: (XX) XXXX-XXXX

+
+
+ + diff --git a/venhapararecomb/venhapararecomb/__pycache__/settings.cpython-312.pyc b/venhapararecomb/venhapararecomb/__pycache__/settings.cpython-312.pyc index 52bef5a114ebd4cc2563e35a06f8fecfc28d9e34..ff7fd7a5c08bf0cb9f75411f6f4cebfb5f4b7254 100644 GIT binary patch delta 583 zcmah`&ubGw6n<}ZvOlwRH`ykeCX$0*iq;BR@G5F+Ac&Zr=1?uZWxGplr3r%dP}@tc zjf19#o_euR@Dl$EFO}Zve;^*#gLrkexdaq^FyH&;B{tC?8ck!UV}ZW#kh71UkzaQmTrRtV&r5y)41=9}}~-fAy-K7X!{iQF)n zY_=}Z^v h-KBnex4j=8+&SY{GmQo86ufK-Dhpqsv~^7__yaC&a=!oo delta 389 zcmZutJxjx25Wahp=HqSCrfHhCT5%HT{6z?lJ(jC#O^O0sNHjupi^ zPe?hy7&+V5BP54&lxK(Yp}~c27J%Kph>;3hWKXGzT$-Xk#d3_1PA&&j;$EbenFGXJ`f4noWwtxbPJFbIe4C5fUZaxK zt!lDvohQ#$H`%st>dWfl$#>f7SuoZR@l#0Dzp8+>P@0JW9X- diff --git a/venhapararecomb/venhapararecomb/settings.py b/venhapararecomb/venhapararecomb/settings.py index c78bdb7..14a481d 100644 --- a/venhapararecomb/venhapararecomb/settings.py +++ b/venhapararecomb/venhapararecomb/settings.py @@ -11,6 +11,7 @@ """ from pathlib import Path +import os # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -55,7 +56,7 @@ TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], + 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ @@ -116,7 +117,11 @@ # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/5.0/howto/static-files/ -STATIC_URL = 'static/' +STATIC_URL = '/static/' + +STATICFILES_DIRS = [ + os.path.join(BASE_DIR, 'static') +] # Default primary key field type # https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field From 1be1f5c3b58387a254729522ec52a60867834eef Mon Sep 17 00:00:00 2001 From: jcquadros Date: Sun, 10 Mar 2024 15:01:33 -0300 Subject: [PATCH 4/8] upload bd and nfs page --- venhapararecomb/db.sqlite3 | Bin 200704 -> 192512 bytes .../__pycache__/admin.cpython-312.pyc | Bin 636 -> 727 bytes .../__pycache__/models.cpython-312.pyc | Bin 2828 -> 3889 bytes .../__pycache__/urls.cpython-312.pyc | Bin 364 -> 549 bytes .../__pycache__/views.cpython-312.pyc | Bin 3483 -> 5729 bytes venhapararecomb/notafiscal/admin.py | 3 +- ...ota_fiscal_notafiscal_clientes_and_more.py | 32 ++++ .../0005_endereco_cliente_endereco.py | 34 ++++ ...tafiscal_clientes_and_more.cpython-312.pyc | Bin 0 -> 1305 bytes ..._endereco_cliente_endereco.cpython-312.pyc | Bin 0 -> 1938 bytes venhapararecomb/notafiscal/models.py | 27 ++- venhapararecomb/notafiscal/urls.py | 2 + venhapararecomb/notafiscal/views.py | 39 +++- venhapararecomb/templates/base.html | 45 +++++ venhapararecomb/templates/detail_nf.html | 67 +++++++ venhapararecomb/templates/index.html | 176 ++++++++---------- venhapararecomb/templates/list_nfs.html | 21 +++ 17 files changed, 331 insertions(+), 115 deletions(-) create mode 100644 venhapararecomb/notafiscal/migrations/0004_remove_cliente_nota_fiscal_notafiscal_clientes_and_more.py create mode 100644 venhapararecomb/notafiscal/migrations/0005_endereco_cliente_endereco.py create mode 100644 venhapararecomb/notafiscal/migrations/__pycache__/0004_remove_cliente_nota_fiscal_notafiscal_clientes_and_more.cpython-312.pyc create mode 100644 venhapararecomb/notafiscal/migrations/__pycache__/0005_endereco_cliente_endereco.cpython-312.pyc create mode 100644 venhapararecomb/templates/base.html create mode 100644 venhapararecomb/templates/detail_nf.html create mode 100644 venhapararecomb/templates/list_nfs.html diff --git a/venhapararecomb/db.sqlite3 b/venhapararecomb/db.sqlite3 index d4007d79c6e67a3b723cf16b8f328f95ff050bc0..3e00abfc20d8e3ada306ebe340b2418af1d06b7a 100644 GIT binary patch delta 5750 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 b$3$!gJ=h|%f%|4#astCL|0^|{i{bwOmAF(a delta 5303 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 ZD~mM-#9A!KMwe$-jTPe`21GYO{{cyUq%r^i delta 1012 zcmZ`%OHUI~6rS78OlLaN0jX4~6^Sh+gYpPSq6xuAD+bX*47wmBlcqD6>a>HmWl>!~ zq6>&7NbW*+u1RsBu3f1sd~8_F4=~Xf3 zBE+9Z8ysxDzsSA_aWVxAI@x+Kb;=A_5>yRBRk_CNf*Z~`)%<9&QpnqD#Fd@0VOq9T zwWz|z`Fp*{g*IauB;MiIM?&{ob^?1119%#S#=i5(DDuqdVH$&-9zkeh9YV6_B$~$% zFrFq5c6w^ZBZ2~7CCwfS$D`QJkl)Ub@7fOS{1i{1ufpDm4?Fjzrd@KN1!tR9jNJ|C z3qCFFe_EIZC3MxSRVbG7_Gr^3Of!mqhSLrtn%RgKWmEr`y3zr7;NM z5XYj@4bf{i?LEmy_DQMn>%lr<*VJ>vp?Uz^U`?y0WJTbKWOyR27SUj2lcRJH9Kq%@xyh^a4123~h3J+jBz$%u0@qYS*jJvWt$f@1U_=)kK2>v!ROQ{L-zJndO-V2WF#LCGn-%6?@tK&4KBO^B1#a+=>7I diff --git a/venhapararecomb/notafiscal/__pycache__/urls.cpython-312.pyc b/venhapararecomb/notafiscal/__pycache__/urls.cpython-312.pyc index dd2f5c2049518ad126adc7c25472bcf57e65a66c..c25b7fade855b0e4079942c50741d26acdfc9989 100644 GIT binary patch delta 282 zcmaFEw3J2tG%qg~0}!0}@;3D&kbVr}zyLdx@p;BXb=L?chE&EB_EhF9um+eK2%W;Q zhHW)7gbh~52~@{}ss_YM;X^j+jQ9<`63rC081kveo6Xh1@X*gHeI!12Z!}QzLf~4^RjIqTv!W diff --git a/venhapararecomb/notafiscal/__pycache__/views.cpython-312.pyc b/venhapararecomb/notafiscal/__pycache__/views.cpython-312.pyc index 65d286e3e86b011b718b9fca33444f9bdd0af227..267b623e7b73996163d6134d09e4beece72131ab 100644 GIT binary patch delta 2945 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 diff --git a/venhapararecomb/notafiscal/admin.py b/venhapararecomb/notafiscal/admin.py index 9157264..84259e1 100644 --- a/venhapararecomb/notafiscal/admin.py +++ b/venhapararecomb/notafiscal/admin.py @@ -1,7 +1,8 @@ from django.contrib import admin -from .models import Fornecedor, Cliente, Boleto, NotaFiscal +from .models import Fornecedor, Cliente, Boleto, NotaFiscal, Endereco admin.site.register(Fornecedor) admin.site.register(Cliente) admin.site.register(Boleto) admin.site.register(NotaFiscal) +admin.site.register(Endereco) diff --git a/venhapararecomb/notafiscal/migrations/0004_remove_cliente_nota_fiscal_notafiscal_clientes_and_more.py b/venhapararecomb/notafiscal/migrations/0004_remove_cliente_nota_fiscal_notafiscal_clientes_and_more.py new file mode 100644 index 0000000..464cecc --- /dev/null +++ b/venhapararecomb/notafiscal/migrations/0004_remove_cliente_nota_fiscal_notafiscal_clientes_and_more.py @@ -0,0 +1,32 @@ +# Generated by Django 5.0.3 on 2024-03-10 16:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('notafiscal', '0003_rename_identificador_cliente_documento'), + ] + + operations = [ + migrations.RemoveField( + model_name='cliente', + name='nota_fiscal', + ), + migrations.AddField( + model_name='notafiscal', + name='clientes', + field=models.ManyToManyField(related_name='notas_fiscais', to='notafiscal.cliente'), + ), + migrations.AlterField( + model_name='cliente', + name='documento', + field=models.CharField(max_length=14, unique=True), + ), + migrations.AlterField( + model_name='fornecedor', + name='cnpj', + field=models.CharField(max_length=14, unique=True), + ), + ] diff --git a/venhapararecomb/notafiscal/migrations/0005_endereco_cliente_endereco.py b/venhapararecomb/notafiscal/migrations/0005_endereco_cliente_endereco.py new file mode 100644 index 0000000..edf48cc --- /dev/null +++ b/venhapararecomb/notafiscal/migrations/0005_endereco_cliente_endereco.py @@ -0,0 +1,34 @@ +# Generated by Django 5.0.3 on 2024-03-10 17:15 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('notafiscal', '0004_remove_cliente_nota_fiscal_notafiscal_clientes_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='Endereco', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('logradouro', models.CharField(max_length=100)), + ('numero', models.CharField(max_length=10)), + ('bairro', models.CharField(max_length=50)), + ('cidade', models.CharField(max_length=50)), + ('estado', models.CharField(max_length=2)), + ('cep', models.CharField(max_length=8)), + ('pais', models.CharField(max_length=50)), + ('telefone', models.CharField(max_length=15)), + ], + ), + migrations.AddField( + model_name='cliente', + name='endereco', + field=models.ForeignKey(default=-1991, on_delete=django.db.models.deletion.CASCADE, to='notafiscal.endereco'), + preserve_default=False, + ), + ] diff --git a/venhapararecomb/notafiscal/migrations/__pycache__/0004_remove_cliente_nota_fiscal_notafiscal_clientes_and_more.cpython-312.pyc b/venhapararecomb/notafiscal/migrations/__pycache__/0004_remove_cliente_nota_fiscal_notafiscal_clientes_and_more.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d6541381a93da83972a59417e89f890a03d3acb GIT binary patch literal 1305 zcmb7E&r2IY6rTN&&F&`AxCDf%QKE>URD||aiXavXQau!V38BNfGl?7bN1WYA(^Cr` zdh}4}ztGkcdhGwuO9O&oZlxy=g@BfVr_StVOYh=jUOkwk#yMwD70o7{M1&CekX5h-Fc(Gj;>5ag@KQR$Z=S z+7o4iYFkM?d2u~IG;4NXnGU_Zva)g)66~2ShBm@pXxD7ZL_UF*V>1^+((Jrc9nb@s9u!! zZsWMV=7gBUSXy*4$FZvqaj+ly&FUfc_ROY9 zOoA=n-MzDGTKg=cf9I>i8disorOMiQkF}F0eBHo5ngxfel5hY`53zC(yxeRP{z4h9opX9$?mf2-#m|opqM!Qibqn5=dEOA=IU0~=+eGp%VRkFxj_Dcc5G&6lk b5QJX}5XzUzEkQZf&+-f1{K8MboM`oLCh}B2 literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/migrations/__pycache__/0005_endereco_cliente_endereco.cpython-312.pyc b/venhapararecomb/notafiscal/migrations/__pycache__/0005_endereco_cliente_endereco.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..026bd52e9b3dfeedb114c234325d65138db920ce GIT binary patch literal 1938 zcmbtV%WLCC7?)&QkrXG9ormpp9JfsE-mzwg@Pd|l)Y?cBs-68426!t^F4m^ee=CW zzYYut6kb0){}WDyDC!TwbQk8mb+(DO?^?)hL(g-L z0d$GZ1sDnjZ}J5gKy++*@Tw`F20{D_0rsfxFz8Em7{GaG@dh-1BplKgxc;8F@HN~( zPu$=&+|Yl-i9KE{LH+I!ti9d=R;`)$benm*cO>%i$Yjw{DP)zbXUCqw#LffzVN^TkR5)8){5s(um*cb{=U%O}FG7 z#VpDyT3K9Nd`B{1MXy7ts47siphWbN5Af&?*-@L4tO2Q_8xV0D8h{2Y>WERm7n_K= zx1I^2uw1irsc1mif&leb4W%L*4QUTH5N|?5kyYg>MBzF#3c88C$rXqMRmY+k(02x5ULes+MPf2A^pa`p{9HD|$ zSuqi3K^5-k8ayQF{Nu=DV6q0QCX5BiB?5 z@wz7AA%+%2jHTnq1#hUmh>SFGAM!jPv1&jZIZkos=!1-iILQM_5)vewPEb=Jro)o- zxF)OQeuM+CN<3>t1)2tVRZ#z$m)I@xd>CY^QTQXJw2D){Nuojg+OBN)B)1BHPYIj2 zTuMp%1lNECWmzlXl7Rx^yzAo!3H7b5e!jN4zJUb23OkR~57Zg9PrazGE$6?)_c!z9 znyM=Kb!hHcdNp5%+OAxc4Vkn+r7%~Ji+lLC|CZ-3)0n?}0rR-?-j%v(z39EJV7}Tg zSnS;U>%)Y(j-RGyRGX#vujqDw8DYQvv@KA4`dh)}CLC^}6-oXc8MR|G`*k-q4k&3n_h6z3nyT*6nk zQ*#H~Zfed+&7DM>sTEtywugn0!Sm1nFSN%gew@Uabhux18*jo85M@+iv!elYL|tpERS5R_cv&K7_5LN2BaF_l>*Vv}Rb8@S9;C z6z2U8(tNig3~#*n3%%EUUc>oyxkIdYrj{`Ef?M%h_ str: return self.nome class NotaFiscal(models.Model): fornecedor = models.ForeignKey(Fornecedor, on_delete=models.CASCADE) + clientes = models.ManyToManyField('Cliente', related_name='notas_fiscais') def __str__(self) -> str: return f'Nota Fiscal {self.fornecedor.nome}' @@ -22,6 +23,19 @@ class Boleto(models.Model): def __str__(self) -> str: return f'Boleto {self.valor} - {self.data_vencimento}' +class Endereco(models.Model): + logradouro = models.CharField(max_length=100) + numero = models.CharField(max_length=10) + bairro = models.CharField(max_length=50) + cidade = models.CharField(max_length=50) + estado = models.CharField(max_length=2) + cep = models.CharField(max_length=8) + pais = models.CharField(max_length=50) + telefone = models.CharField(max_length=15) + + def __str__(self) -> str: + return self.logradouro + class Cliente(models.Model): TIPO_DOCUMENTO = ( ('CPF', 'CPF'), @@ -30,13 +44,8 @@ class Cliente(models.Model): nome = models.CharField(max_length=100) tipo_documento = models.CharField(max_length=4, choices=TIPO_DOCUMENTO) - documento = models.CharField(max_length=14) # cpf ou cnpj - nota_fiscal = models.ForeignKey(NotaFiscal, on_delete=models.CASCADE) + documento = models.CharField(max_length=14, unique=True) # cpf ou cnpj + endereco = models.ForeignKey(Endereco, on_delete=models.CASCADE) def __str__(self) -> str: - return self.nome - - - - - + return self.nome diff --git a/venhapararecomb/notafiscal/urls.py b/venhapararecomb/notafiscal/urls.py index feb22e3..62763b6 100644 --- a/venhapararecomb/notafiscal/urls.py +++ b/venhapararecomb/notafiscal/urls.py @@ -3,5 +3,7 @@ urlpatterns = [ path('', views.index, name='index'), + path('nfs/', views.list_nfs, name='notas_fiscais'), + path('nf//', views.detail_nf, name='nota_fiscal'), ] diff --git a/venhapararecomb/notafiscal/views.py b/venhapararecomb/notafiscal/views.py index 2eab0cc..23396ec 100644 --- a/venhapararecomb/notafiscal/views.py +++ b/venhapararecomb/notafiscal/views.py @@ -1,6 +1,6 @@ from django.shortcuts import render, redirect import xml.etree.ElementTree as ET -from .models import Fornecedor, Cliente, Boleto, NotaFiscal +from .models import Fornecedor, Cliente, Boleto, NotaFiscal, Endereco def parse_xml(xml_file): @@ -18,10 +18,25 @@ def parse_xml(xml_file): cpf = dest.find('ns:CPF', nsNFe) cnpj = dest.find('ns:CNPJ', nsNFe) + endereco = dest.find('ns:enderDest', nsNFe) + logradouro = endereco.find('ns:xLgr', nsNFe).text + numero = endereco.find('ns:nro', nsNFe).text + bairro = endereco.find('ns:xBairro', nsNFe).text + cidade = endereco.find('ns:xMun', nsNFe).text + estado = endereco.find('ns:UF', nsNFe).text + cep = endereco.find('ns:CEP', nsNFe).text + pais = endereco.find('ns:xPais', nsNFe).text + telefone = endereco.find('ns:fone', nsNFe).text + documento = cpf.text if cpf is not None else cnpj.text tipo_documento = 'CPF' if cpf is not None else 'CNPJ' - clientes.append({'nome': xNome, 'documento': documento, 'tipo_documento': tipo_documento}) + endereco_json = { + 'logradouro': logradouro, 'numero': numero, 'bairro': bairro, + 'cidade': cidade, 'estado': estado, 'cep': cep, 'pais': pais, 'telefone': telefone + } + + clientes.append({'nome': xNome, 'documento': documento, 'tipo_documento': tipo_documento, 'endereco': endereco_json}) boletos = [] for det in root.findall('ns:NFe/ns:infNFe/ns:cobr/ns:dup', nsNFe): @@ -31,7 +46,6 @@ def parse_xml(xml_file): return {'fornecedor': fornecedor, 'clientes': clientes, 'boletos': boletos} - def index(request): context = {} @@ -48,7 +62,10 @@ def index(request): nf = NotaFiscal.objects.create(fornecedor=fornecedor) for cliente in xml_data['clientes']: - Cliente.objects.create(nome=cliente['nome'], documento=cliente['documento'], tipo_documento=cliente['tipo_documento'], nota_fiscal=nf) + + endereco_obj = Endereco.objects.create(logradouro=cliente['endereco']['logradouro'], numero=cliente['endereco']['numero'], bairro=cliente['endereco']['bairro'], cidade=cliente['endereco']['cidade'], estado=cliente['endereco']['estado'], cep=cliente['endereco']['cep'], pais=cliente['endereco']['pais'], telefone=cliente['endereco']['telefone']) + cliente_obj, created = Cliente.objects.get_or_create(documento=cliente['documento'], defaults={'nome': cliente['nome'], 'tipo_documento': cliente['tipo_documento']}, endereco=endereco_obj) + nf.clientes.add(cliente_obj) for boleto in xml_data['boletos']: Boleto.objects.create(valor=boleto['valor'], data_vencimento=boleto['data_vencimento'], nota_fiscal=nf) @@ -56,3 +73,17 @@ def index(request): return redirect('index') return render(request, 'index.html', context) + + +def list_nfs(request): + context = { + 'nfs': NotaFiscal.objects.all() + } + return render(request, 'list_nfs.html', context) + +def detail_nf(request, nf_id): + context = { + 'nf': NotaFiscal.objects.get(id=nf_id) + } + return render(request, 'detail_nf.html', context) + diff --git a/venhapararecomb/templates/base.html b/venhapararecomb/templates/base.html new file mode 100644 index 0000000..83607e0 --- /dev/null +++ b/venhapararecomb/templates/base.html @@ -0,0 +1,45 @@ + + + + + + {% block title %}{% endblock %} + + + + + + + + +
+ {% block content %} + {% endblock %} +
+ + +
+
+

Entre em contato:

+

Email: contato@empresa.com

+

Telefone: (XX) XXXX-XXXX

+
+
+ + diff --git a/venhapararecomb/templates/detail_nf.html b/venhapararecomb/templates/detail_nf.html new file mode 100644 index 0000000..f09d234 --- /dev/null +++ b/venhapararecomb/templates/detail_nf.html @@ -0,0 +1,67 @@ +{% extends 'base.html' %} + +{% block title %} +Informações da nota fiscal {{ nf.id }} +{% endblock %} + + +{% block content %} +
+

Nota Fiscal

+
+

Nota Fiscal

+
+
+ {% csrf_token %} + +
+
+
+
+
+
    +
  • + Fornecedor:
    + Nome - {{ nf.fornecedor.nome }} | + CNPJ - {{ nf.fornecedor.cnpj }} +
  • +
  • + Clientes: +
      + {% for cliente in nf.clientes %} +
    • + Nome: {{ cliente.nome }} | + {{ cliente.tipo_documento }}: {{ cliente.documento }} +
        +
      • Endereço: {{ cliente.endereco.logradouro }} {{ cliente.endereco.numero }}
      • +
      • CEP: {{ cliente.endereco.cep }}
      • +
      • Cidade: {{ cliente.endereco.cidade }}
      • +
      • Estado: {{ cliente.endereco.estado }}
      • +
      • País: {{ cliente.endereco.pais }}
      • +
      • Telefone: {{ cliente.endereco.telefone }}
      • +
      +
    • + {% endfor %} +
    +
  • +
  • + Boletos: +
      + {% for boleto in nf.boletos %} +
    • + Valor: {{ boleto.valor }} | + Vencimento: {{ boleto.data_vencimento }} +
    • + {% endfor %} +
    + +
  • +
+
+
+
+
+ Voltar +
+ +{% endblock %} \ No newline at end of file diff --git a/venhapararecomb/templates/index.html b/venhapararecomb/templates/index.html index c288c05..3c30b8c 100644 --- a/venhapararecomb/templates/index.html +++ b/venhapararecomb/templates/index.html @@ -1,107 +1,81 @@ - - - - - - Gerenciamento de Notas Fiscais - - - - - - - - -
- -
-

Olá, seja bem vindo!

-
-

Este é um sistema de gerenciamento de notas fiscais. Envie um arquivo XML para começar:

-
-
- {% csrf_token %} - - -
-
-
-
+{% extends 'base.html' %} - -
-
-

Nota Fiscal

-
-
- {% csrf_token %} - -
-
-
-
-
-
    -
  • - Fornecedor:
    - Nome - {{ xml_data.fornecedor.nome }} | - CNPJ - {{ xml_data.fornecedor.cnpj }} -
  • -
  • - Clientes: -
      - {% for cliente in xml_data.clientes %} -
    • - Nome: {{ cliente.nome }} | - {{ cliente.tipo_documento }}: {{ cliente.documento }} -
    • - {% endfor %} -
    -
  • -
  • - Boletos: -
      - {% for boleto in xml_data.boletos %} -
    • - Valor: {{ boleto.valor }} | - Vencimento: {{ boleto.data_vencimento }} -
    • - {% endfor %} -
    -
  • -
-
-
+{% block title %} +Gerenciamento de Notas Fiscais +{% endblock %} + +{% block content %} + +
+

Olá, seja bem vindo!

+
+

Este é um sistema de gerenciamento de notas fiscais. Envie um arquivo XML para começar:

+
+
+ {% csrf_token %} + + +
+
-
-
-

Entre em contato:

-

Email: contato@empresa.com

-

Telefone: (XX) XXXX-XXXX

+ +{% if xml_data %} +
+
+

Nota Fiscal

+
+
+ {% csrf_token %} + +
-
- - +
+
+
+
    +
  • + Fornecedor:
    + Nome - {{ xml_data.fornecedor.nome }} | + CNPJ - {{ xml_data.fornecedor.cnpj }} +
  • +
  • + Clientes: +
      + {% for cliente in xml_data.clientes %} +
    • + Nome: {{ cliente.nome }} | + {{ cliente.tipo_documento }}: {{ cliente.documento }} + +
        +
      • Endereço: {{ cliente.endereco.logradouro }} {{ cliente.endereco.numero }}
      • +
      • CEP: {{ cliente.endereco.cep }}
      • +
      • Cidade: {{ cliente.endereco.cidade }}
      • +
      • Estado: {{ cliente.endereco.estado }}
      • +
      • País: {{ cliente.endereco.pais }}
      • +
      • Telefone: {{ cliente.endereco.telefone }}
      • +
      +
    • + {% endfor %} +
    +
  • +
  • + Boletos: +
      + {% for boleto in xml_data.boletos %} +
    • + Valor: {{ boleto.valor }} | + Vencimento: {{ boleto.data_vencimento }} +
    • + {% endfor %} +
    +
  • +
+
+
+
+{% endif %} + +{% endblock %} diff --git a/venhapararecomb/templates/list_nfs.html b/venhapararecomb/templates/list_nfs.html new file mode 100644 index 0000000..f9c54dc --- /dev/null +++ b/venhapararecomb/templates/list_nfs.html @@ -0,0 +1,21 @@ +{% extends 'base.html' %} + +{% block title %} +Lista de Notas Fiscais +{% endblock %} + +{% block content %} +
+

Notas Fiscais

+ {% if nfs %} +
    + {% for nf in nfs %} +
  • {{ nf }}
  • + {% endfor %} +
+ {% endif %} +
+
+ Voltar +
+{% endblock %} From 2bd9094c6ac910afe74ab595093f60ff23b58617 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 10 Mar 2024 19:26:38 -0300 Subject: [PATCH 5/8] update readme --- README.md | 105 +++++----- venhapararecomb/db.sqlite3 | Bin 192512 -> 196608 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 194 bytes .../__pycache__/admin.cpython-311.pyc | Bin 0 -> 796 bytes .../__pycache__/apps.cpython-311.pyc | Bin 0 -> 573 bytes .../__pycache__/models.cpython-311.pyc | Bin 0 -> 4979 bytes .../__pycache__/tests.cpython-311.pyc | Bin 0 -> 8590 bytes .../__pycache__/urls.cpython-311.pyc | Bin 0 -> 1076 bytes .../__pycache__/views.cpython-311.pyc | Bin 0 -> 11302 bytes venhapararecomb/notafiscal/forms.py | 4 - .../notafiscal/migrations/0001_initial.py | 37 ++-- ...edor_remove_cliente_fornecedor_and_more.py | 48 ----- ..._rename_identificador_cliente_documento.py | 18 -- ...ota_fiscal_notafiscal_clientes_and_more.py | 32 ---- .../0005_endereco_cliente_endereco.py | 34 ---- .../__pycache__/0001_initial.cpython-311.pyc | Bin 0 -> 3510 bytes ...icador_alter_notafiscal_id.cpython-311.pyc | Bin 0 -> 1157 bytes ...liente_fornecedor_and_more.cpython-311.pyc | Bin 0 -> 1828 bytes ...ificador_cliente_documento.cpython-311.pyc | Bin 0 -> 835 bytes ...tafiscal_clientes_and_more.cpython-311.pyc | Bin 0 -> 1384 bytes ..._endereco_cliente_endereco.cpython-311.pyc | Bin 0 -> 1962 bytes .../0006_alter_notafiscal_id.cpython-311.pyc | Bin 0 -> 885 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 205 bytes venhapararecomb/notafiscal/models.py | 18 +- venhapararecomb/notafiscal/tests.py | 83 +++++++- venhapararecomb/notafiscal/urls.py | 10 +- venhapararecomb/notafiscal/views.py | 181 ++++++++++++++++-- venhapararecomb/static/css/style.css | 14 -- venhapararecomb/templates/base.html | 24 +-- venhapararecomb/templates/detail_nf.html | 31 ++- venhapararecomb/templates/index.html | 21 +- venhapararecomb/templates/list_clientes.html | 31 +++ .../templates/list_fornecedores.html | 35 ++++ venhapararecomb/templates/list_nfs.html | 35 ++-- .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 199 bytes .../__pycache__/settings.cpython-311.pyc | Bin 0 -> 2795 bytes .../__pycache__/urls.cpython-311.pyc | Bin 0 -> 1199 bytes .../__pycache__/wsgi.cpython-311.pyc | Bin 0 -> 737 bytes venhapararecomb/venhapararecomb/settings.py | 21 +- 39 files changed, 485 insertions(+), 297 deletions(-) create mode 100644 venhapararecomb/notafiscal/__pycache__/__init__.cpython-311.pyc create mode 100644 venhapararecomb/notafiscal/__pycache__/admin.cpython-311.pyc create mode 100644 venhapararecomb/notafiscal/__pycache__/apps.cpython-311.pyc create mode 100644 venhapararecomb/notafiscal/__pycache__/models.cpython-311.pyc create mode 100644 venhapararecomb/notafiscal/__pycache__/tests.cpython-311.pyc create mode 100644 venhapararecomb/notafiscal/__pycache__/urls.cpython-311.pyc create mode 100644 venhapararecomb/notafiscal/__pycache__/views.cpython-311.pyc delete mode 100644 venhapararecomb/notafiscal/forms.py delete mode 100644 venhapararecomb/notafiscal/migrations/0002_remove_boleto_fornecedor_remove_cliente_fornecedor_and_more.py delete mode 100644 venhapararecomb/notafiscal/migrations/0003_rename_identificador_cliente_documento.py delete mode 100644 venhapararecomb/notafiscal/migrations/0004_remove_cliente_nota_fiscal_notafiscal_clientes_and_more.py delete mode 100644 venhapararecomb/notafiscal/migrations/0005_endereco_cliente_endereco.py create mode 100644 venhapararecomb/notafiscal/migrations/__pycache__/0001_initial.cpython-311.pyc create mode 100644 venhapararecomb/notafiscal/migrations/__pycache__/0002_notafiscal_identificador_alter_notafiscal_id.cpython-311.pyc create mode 100644 venhapararecomb/notafiscal/migrations/__pycache__/0002_remove_boleto_fornecedor_remove_cliente_fornecedor_and_more.cpython-311.pyc create mode 100644 venhapararecomb/notafiscal/migrations/__pycache__/0003_rename_identificador_cliente_documento.cpython-311.pyc create mode 100644 venhapararecomb/notafiscal/migrations/__pycache__/0004_remove_cliente_nota_fiscal_notafiscal_clientes_and_more.cpython-311.pyc create mode 100644 venhapararecomb/notafiscal/migrations/__pycache__/0005_endereco_cliente_endereco.cpython-311.pyc create mode 100644 venhapararecomb/notafiscal/migrations/__pycache__/0006_alter_notafiscal_id.cpython-311.pyc create mode 100644 venhapararecomb/notafiscal/migrations/__pycache__/__init__.cpython-311.pyc delete mode 100644 venhapararecomb/static/css/style.css create mode 100644 venhapararecomb/templates/list_clientes.html create mode 100644 venhapararecomb/templates/list_fornecedores.html create mode 100644 venhapararecomb/venhapararecomb/__pycache__/__init__.cpython-311.pyc create mode 100644 venhapararecomb/venhapararecomb/__pycache__/settings.cpython-311.pyc create mode 100644 venhapararecomb/venhapararecomb/__pycache__/urls.cpython-311.pyc create mode 100644 venhapararecomb/venhapararecomb/__pycache__/wsgi.cpython-311.pyc diff --git a/README.md b/README.md index 817b8c7..8c9a32e 100644 --- a/README.md +++ b/README.md @@ -1,62 +1,43 @@ -# Venha para Recomb - -O desafio é desenvolver um programa que permita realizar as seguintes buscas: - -1) Listar os valores e data de Vencimento dos boletos presentes em um nota fiscal conforme o CPF ou CNPJ de um fornecedor. -2) Apresentar o nome, identificador (CPF ou CNPJ), endereço dos clientes de um fornecedor. - -**Escolha as tecnologias que você vai usar e tente montar uma solução completa para rodar a aplicação.** - -Para enviar o resultado, basta realiazar um Fork deste repositório e abra um Pull Request, com seu nome. - -É importante comentar que deve ser enviado apenas o código fonte. Não aceitaremos códigos compilados. - -Por fim, o candidato deve atualizar o Readme.md com as seguintes informações: - - 1) Documentação da solução; - 2) Lista dos diferenciais implementados - -## Avaliação - -O programa será avaliado levando em conta os seguintes critérios: -|Critério| Valor| -|-------|--------| -|Legibilidade do Código |10| -|Organização do Código|10| -|Documentação do código |10| -|Documentação da solução |10| -|Tratamento de Erros |10| -|Total| 50| - -A pontuação do candidato será a soma dos valores obtidos nos critérios acima. - -## Diferenciais - -O candidato pode aumentar a sua pontuação na seleção implementando um ou mais dos itens abaixo: -|Item | Pontos Ganhos| -|-----|--------------| -|Criar um serviço com o problema |30| -|Utilizar banco de dados |30| -|Implementar Clean Code |20| -|Implementar o padrão de programação da tecnologia escolhida |20| -|Qualidade de Código com SonarQube| 15| -|Implementar testes unitários |15| -|Implementar testes comportamentais | 15| -|Implementar integração com Travis |10| -|Implementar integração com Travis + SonarQube |10| -|Implementar usando Docker |5| -|Total | 170| - -A nota final do candidato será acrescido dos pontos referente ao item implementado corretamente. - -## Penalizações - -O candidato será desclassifiado nas seguintes situações: - -1) Submeter um solução que não funcione; -2) Não cumprir os critérios presentes no seção Avaliação; -3) Plágio; - - - - +## Documentação da Solução + +### Tecnologias Utilizadas +- Django: Framework web em Python. +- Sqlite3: Serviço de banco de dados local do Django. +- HTML, CSS e Bootstrap: para a interface do usuário. + +### Funcionalidades Implementadas +1. **Parse de XML**: A função parse_xml recebe um arquivo XML de uma nota fiscal e extrai as informações relevantes, como fornecedor, clientes, endereços e boletos. +2. **Página Inicial**: A view index renderiza a página inicial do sistema, permitindo aos usuários enviar arquivos XML para processamento. +3. **Cadastro de Notas Fiscais**: Ao submeter um arquivo XML válido, as informações da nota fiscal são salvas no banco de dados, incluindo fornecedor, clientes e boletos associados. +4. **Listagem de Notas Fiscais**: A view list_nfs apresenta uma lista de todas as notas fiscais cadastradas no sistema. +5. **Detalhes da Nota Fiscal**: A view detail_nf permite visualizar os detalhes de uma nota fiscal específica, incluindo clientes e boletos associados. +6. **Exclusão de Notas Fiscais**: A view delete_nf permite excluir uma nota fiscal do banco de dados, mas não exclui dados de fornecedor e clientes. +7. **Listagem de Fornecedores**: A view list_fornecedores lista todos os fornecedores cadastrados no sistema. +8. **Exclusão de Fornecedores**: A view delete_fornecedor permite excluir um fornecedor do banco de dados. Ao excluir um fornecedor do banco de dados as notas fiscais associadas também são apagadas. +9. **Listagem de Clientes**: A view list_clientes lista todos os clientes cadastrados no sistema. +10. **Exclusão de Clientes**: A view delete_cliente permite excluir um cliente do banco de dados. Ao apagar um cliente, as notas fiscais relacionadas não são apagadas. + +### Como Executar a Aplicação +1. Clone o repositório do projeto: + ``` + git clone https://github.com/jcquadros/venhapararecomb-backend.git + ``` +2. Instale o Django: + ``` + pip install django + ``` +3. Navegue até o diretório do projeto que contenha o arquivo manage.py. + +4. Inicie o servidor: + ``` + python manage.py runserver + ``` + +5. Acesse a aplicação em seu navegador, através do endereço 'http://127.0.0.1:8000/'. + +## Diferenciais Implementados +- Interface de Usuário Responsiva: A interface do usuário foi desenvolvida de forma simples com Bootstrap, mas responsiva. +- Tratamento de Erros: O sistema trata erros comuns, como tentativa de envio de nota fiscal fornecedores e clientes duplicados. +- Padrão de programação Django MTV (Model, Template, View) +- Uso de banco de dados: A aplicação utiliza o Sqlite3 como serviço de banco de dados local. +- Implementação de Testes Unitários: Os testes cobrem as principais funções da aplicação, incluindo o parse de XML, as views e os modelos do Django. \ No newline at end of file diff --git a/venhapararecomb/db.sqlite3 b/venhapararecomb/db.sqlite3 index 3e00abfc20d8e3ada306ebe340b2418af1d06b7a..8a4d913abaf2f8fc6c8f325230fee31a32463e97 100644 GIT binary patch delta 3934 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 delta 4500 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 diff --git a/venhapararecomb/notafiscal/__pycache__/__init__.cpython-311.pyc b/venhapararecomb/notafiscal/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6811ac70da945fb4d2fee122d68fafff655bbefb GIT binary patch literal 194 zcmZ3^%ge<81Y3T+O$E`9K?DpiLK&agfQ;!3DGb33nv8xc8H$*I{LdiCU!l%cF`>n& zMa3~$r8zm7F)pda*(Lb}F=eTF8HojnMTteJ$@#fSx=D%2*{OLc=;ASX`6Y>InZ?P8 yIWh6^nR%Hd@$q^EmA^P_a`RJ4b5iY!Sb?^H+)>OABt9@RGBSQ(fDuK^KrsL;GBo4> literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/__pycache__/admin.cpython-311.pyc b/venhapararecomb/notafiscal/__pycache__/admin.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..435071659a09d46bf3b81dba6d716d995f93b551 GIT binary patch literal 796 zcmbVJJ!>055S{gXDF;djDkY(`Dy+h#2`=nd2`N-Kq&coR-A2!`F!pu*3j+f1(;g~w?vmA> zxw!-ilrZ2VA_V9Tb=VGfB8R(?%e~0se&q8YG9pMOjY{I`QI*wqbUqu!FJ}F<2XWjj zINlZ0Sq;D}`?3e^6gWLQWYj%1Mx zvph|hZX64W3R5}ihx##{B;r&KQYi|Rjg|cz?Q=vFW|U*nEwFpV|WX#@6h`6dIr5Y q^h)S0YUs-ubmq`0p;JePGicADT|&E#{$JtM47zjZmX)g~rt?3?w6Jaf literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/__pycache__/apps.cpython-311.pyc b/venhapararecomb/notafiscal/__pycache__/apps.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9a12de3c991c0a07f28715843b329439b6661aaa GIT binary patch literal 573 zcmZutJ5R$f5I!doJq*@`D@Prk3N=v?LSxt&{oIok T1#L~>ue$4h$lK3TqRGtc&pouwQMNEq#);&4T ziZ|^Q1&{DsLGykkXg=ay_EiTz_X@&G`0|qWGc7-81v+R2m{t(9qz+m^rWFFMa0e}k zX+=OQ+CeL%#pZG$#BUWjgZMg2o2M~tPy!~HJknt$P;;2we-C>lE4+zn7tC{iPP z^o(#3>-feGyFok^z7&?>mzO!1GzIhe@TT}{k=&w%1C)1j6Q3-6ZV_rNEEjV*ePNPV zUlh#z!ee4QRP!oTDao2E53W2=vtJNHYwTYz%!0b8TUj-?z+YQ3zv>1v8LL1unYEsp z36qt+2;BA%-M%F3$sasfwWSk>xXct-T*_n&b%kUyZa9;H>54h5M>Cm6MKxEs0&{C- zHj|;~5^iYXp-QK9lGA7$+rF%kUv|B4ciIQ-7Xtkm{Lo$$fvUif))I))(cgi`@qxghL#B}dGD(5B!3nPC#_-NohAl?7hDA3@ zNlq;gjky?&!N@v(&?y){gHVC}Ry2nHP?D@Bp+C1BY}FSK_DB~pK0GN+46PxY+c;`Ij`B$b>>Z} zVVRx)MfxF%lPFH1z^9-%gBz=}G26_DzGTdjRR#hW>c-r}jmarGg4*&O)mWW3Q8Job zscLU}7N^7&(|!~+p3Y$t1@2MSpFyEB`BM&tZ<2@Z}{9q3$?(Bn+)1(3(JuLI_64f($YVoG9c5Zkph`=Gvoy2u015UPf-*I zs`W<@Z6Jv$>(frOf9s=N)sBvrqvK9=yfn3!7~EKN5`*Q$kdqiH-QDZCurcWLT-dz5 zJNQG=?wKj~%s4$WrCFroQ%=XHNJmS->A=<0(Sh3@mcyj@K04l?Ts3Jx!dRDn`I|I2 zLA4aFStHaiN1$mA9^h(o1e-J>4RbW#CEB1NHO&!&5ZP4;k#Z$ON>heLFiR?Kf(<(( z3>g%tzW&~|@`)jLoLl2yW3nx1=}*;%m6J@YdvZ zR}EEV_bLpuYN_C#Z0T$T)b7r~joyTjZonv_W!wNaiyPo3aRb~Qt~X2at}n0ZmMc|_ z&>qw=n3AHnh^zVuL>o|hSlBwZHD|}Kmg85Q_*Dp5u`}!Uo!FVJ9y@lq9J}nqE|;eN zi_W+m8!5*|oY)8q51(8gbiyY$RXaRX4i7ouq0&Sx4Yebe%8^S>^qz{J0d=`1TOHw6!QiC)4= z8j(M);U~VP6Bj~%TqmeW+o6Vx6tVX&qld6UBG8IfTif9V?U)u}a7H1t%KT(W2SB^{ z6hvn(E6GlU%1Y}PlX!4qTov@ZiP`I&onGn02GKEE@Sn!j61NBQZj3(beeH*PyObX4WRl`+VItHkY;HQNJ= zua>=E+`X*7f@lq_HxVeM4#KTZbgclri);=3ukZ?@bw>-5c*QhVLXM!@M-wr=he z?C#NW_o&l7TAJCD7356WJh5~C@4vU@$+A4@$djD4|L_!utHz^lpsV*UP;g*Vubx)qH? mmk3)_vsi!p2l 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 M4#MK0asJc)06PdCwg3PC literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/__pycache__/views.cpython-311.pyc b/venhapararecomb/notafiscal/__pycache__/views.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cffbeb42bb06508f1e9164a2d771e1318fff8151 GIT binary patch literal 11302 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 literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/forms.py b/venhapararecomb/notafiscal/forms.py deleted file mode 100644 index bb139b0..0000000 --- a/venhapararecomb/notafiscal/forms.py +++ /dev/null @@ -1,4 +0,0 @@ -from django import forms - -class XMLForm(forms.Form): - arquivo_xml = forms.FileField() \ No newline at end of file diff --git a/venhapararecomb/notafiscal/migrations/0001_initial.py b/venhapararecomb/notafiscal/migrations/0001_initial.py index 7c35c74..0127622 100644 --- a/venhapararecomb/notafiscal/migrations/0001_initial.py +++ b/venhapararecomb/notafiscal/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.0.3 on 2024-03-09 14:39 +# Generated by Django 5.0.3 on 2024-03-10 21:02 import django.db.models.deletion from django.db import migrations, models @@ -12,12 +12,26 @@ class Migration(migrations.Migration): ] operations = [ + migrations.CreateModel( + name='Endereco', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('logradouro', models.CharField(max_length=100)), + ('numero', models.CharField(max_length=10)), + ('bairro', models.CharField(max_length=50)), + ('cidade', models.CharField(max_length=50)), + ('estado', models.CharField(max_length=2)), + ('cep', models.CharField(max_length=8)), + ('pais', models.CharField(max_length=50)), + ('telefone', models.CharField(max_length=15)), + ], + ), migrations.CreateModel( name='Fornecedor', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('nome', models.CharField(max_length=100)), - ('cnpj', models.CharField(max_length=14)), + ('cnpj', models.CharField(max_length=14, unique=True)), ], ), migrations.CreateModel( @@ -25,26 +39,27 @@ class Migration(migrations.Migration): fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('nome', models.CharField(max_length=100)), - ('identificador', models.CharField(max_length=14)), - ('fornecedor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='notafiscal.fornecedor')), + ('tipo_documento', models.CharField(choices=[('CPF', 'CPF'), ('CNPJ', 'CNPJ')], max_length=4)), + ('documento', models.CharField(max_length=14, unique=True)), + ('endereco', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='notafiscal.endereco')), ], ), migrations.CreateModel( - name='Boleto', + name='NotaFiscal', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('valor', models.DecimalField(decimal_places=2, max_digits=10)), - ('data_vencimento', models.DateField()), + ('identificador', models.CharField(max_length=50, unique=True)), + ('clientes', models.ManyToManyField(related_name='notas_fiscais', to='notafiscal.cliente')), ('fornecedor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='notafiscal.fornecedor')), ], ), migrations.CreateModel( - name='NotaFiscal', + name='Boleto', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('boletos', models.ManyToManyField(to='notafiscal.boleto')), - ('clientes', models.ManyToManyField(to='notafiscal.cliente')), - ('fornecedor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='notafiscal.fornecedor')), + ('valor', models.DecimalField(decimal_places=2, max_digits=10)), + ('data_vencimento', models.DateField()), + ('nota_fiscal', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='notafiscal.notafiscal')), ], ), ] diff --git a/venhapararecomb/notafiscal/migrations/0002_remove_boleto_fornecedor_remove_cliente_fornecedor_and_more.py b/venhapararecomb/notafiscal/migrations/0002_remove_boleto_fornecedor_remove_cliente_fornecedor_and_more.py deleted file mode 100644 index b44f5c0..0000000 --- a/venhapararecomb/notafiscal/migrations/0002_remove_boleto_fornecedor_remove_cliente_fornecedor_and_more.py +++ /dev/null @@ -1,48 +0,0 @@ -# Generated by Django 5.0.3 on 2024-03-09 18:27 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('notafiscal', '0001_initial'), - ] - - operations = [ - migrations.RemoveField( - model_name='boleto', - name='fornecedor', - ), - migrations.RemoveField( - model_name='cliente', - name='fornecedor', - ), - migrations.RemoveField( - model_name='notafiscal', - name='boletos', - ), - migrations.RemoveField( - model_name='notafiscal', - name='clientes', - ), - migrations.AddField( - model_name='boleto', - name='nota_fiscal', - field=models.ForeignKey(default=-2015, on_delete=django.db.models.deletion.CASCADE, to='notafiscal.notafiscal'), - preserve_default=False, - ), - migrations.AddField( - model_name='cliente', - name='nota_fiscal', - field=models.ForeignKey(default=-1995, on_delete=django.db.models.deletion.CASCADE, to='notafiscal.notafiscal'), - preserve_default=False, - ), - migrations.AddField( - model_name='cliente', - name='tipo_documento', - field=models.CharField(choices=[('CPF', 'CPF'), ('CNPJ', 'CNPJ')], default=-1995, max_length=4), - preserve_default=False, - ), - ] diff --git a/venhapararecomb/notafiscal/migrations/0003_rename_identificador_cliente_documento.py b/venhapararecomb/notafiscal/migrations/0003_rename_identificador_cliente_documento.py deleted file mode 100644 index 9751b9a..0000000 --- a/venhapararecomb/notafiscal/migrations/0003_rename_identificador_cliente_documento.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 5.0.3 on 2024-03-09 18:34 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('notafiscal', '0002_remove_boleto_fornecedor_remove_cliente_fornecedor_and_more'), - ] - - operations = [ - migrations.RenameField( - model_name='cliente', - old_name='identificador', - new_name='documento', - ), - ] diff --git a/venhapararecomb/notafiscal/migrations/0004_remove_cliente_nota_fiscal_notafiscal_clientes_and_more.py b/venhapararecomb/notafiscal/migrations/0004_remove_cliente_nota_fiscal_notafiscal_clientes_and_more.py deleted file mode 100644 index 464cecc..0000000 --- a/venhapararecomb/notafiscal/migrations/0004_remove_cliente_nota_fiscal_notafiscal_clientes_and_more.py +++ /dev/null @@ -1,32 +0,0 @@ -# Generated by Django 5.0.3 on 2024-03-10 16:34 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('notafiscal', '0003_rename_identificador_cliente_documento'), - ] - - operations = [ - migrations.RemoveField( - model_name='cliente', - name='nota_fiscal', - ), - migrations.AddField( - model_name='notafiscal', - name='clientes', - field=models.ManyToManyField(related_name='notas_fiscais', to='notafiscal.cliente'), - ), - migrations.AlterField( - model_name='cliente', - name='documento', - field=models.CharField(max_length=14, unique=True), - ), - migrations.AlterField( - model_name='fornecedor', - name='cnpj', - field=models.CharField(max_length=14, unique=True), - ), - ] diff --git a/venhapararecomb/notafiscal/migrations/0005_endereco_cliente_endereco.py b/venhapararecomb/notafiscal/migrations/0005_endereco_cliente_endereco.py deleted file mode 100644 index edf48cc..0000000 --- a/venhapararecomb/notafiscal/migrations/0005_endereco_cliente_endereco.py +++ /dev/null @@ -1,34 +0,0 @@ -# Generated by Django 5.0.3 on 2024-03-10 17:15 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('notafiscal', '0004_remove_cliente_nota_fiscal_notafiscal_clientes_and_more'), - ] - - operations = [ - migrations.CreateModel( - name='Endereco', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('logradouro', models.CharField(max_length=100)), - ('numero', models.CharField(max_length=10)), - ('bairro', models.CharField(max_length=50)), - ('cidade', models.CharField(max_length=50)), - ('estado', models.CharField(max_length=2)), - ('cep', models.CharField(max_length=8)), - ('pais', models.CharField(max_length=50)), - ('telefone', models.CharField(max_length=15)), - ], - ), - migrations.AddField( - model_name='cliente', - name='endereco', - field=models.ForeignKey(default=-1991, on_delete=django.db.models.deletion.CASCADE, to='notafiscal.endereco'), - preserve_default=False, - ), - ] diff --git a/venhapararecomb/notafiscal/migrations/__pycache__/0001_initial.cpython-311.pyc b/venhapararecomb/notafiscal/migrations/__pycache__/0001_initial.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..00c821a10a0c4f69769a299332db4d056ca8d69e GIT binary patch literal 3510 zcmb_fO>omj6qfv>*p3tA5J(*3I3y{>(3p_W6o<4F^1~2_OZn-+lU5^pH%5*u8A;BN z^unQs9=SEWaZ0B{4jg^pz>(u>W)GP?G1F5n9W&&_^w3?&Kh$`J&{nqAyV`Hx``))t zPx5a)Jt2-Be2Jdvd*4nWxO;rZ zL-nAid(buSYCZ4~S`W7Q>!fwG4KoDz-Pk`Fta%FF53oA%KeLLru^I-6f(MN3o@{3Z zM%$1b`GYYB<=ksbRoGn&*X8AkUCmxkv)9|`f$`l>+I<%MA5i1eN2u{>8~>h8`h(LB zs&Q9xAPLUwo^9s^KKs{EPIQRU_kk!=9}(p_hnd(^RRrC;lkf3A@1P=~CW+vIPO@ zE*nZoHa4YoxJiO0G!$7?wjc>_KqIG{P}1ZQBq3F&MHlE5L*EB9t|U+Eu>4R`p;oZ& z6G5w#Ae~}aN`#!O7<4e@4Dt$)0VD!6ExLZ6)du3t!}30>xWreM6_W%ksKPZ}gZnH^ zXpQ$dPK7lEs=y?nCEd_q9s=Es-s6f&+uPRWpAnCP~ zvMvEVPnl_!PK|o!Z!H<8>JH{Jx0a1h>0qB#cskpazppEKXu9Tt&4nZY>l$ty)pSc< zQ_Q@qrWzON%Al@E^eF_XQ;(&SP==zG92DtM0CldcDR~;ZK>~S~oJo3^DN}NcDdtw+ zJC^GhYB+2_mF5CK3j)%=Ds8sJ`sUPP*rv^jl$%Z-eas313wTS7>4`u{|fj`TMfrcG>Pj zrJ&uQ`6+;+tQBZBgB%Gsn$y<+y60E!%wJhpBu7?cZS$_qT6b-D!417`bb+c_H>#Im z{Uzde?hWwavTkw-WKrS>1S8a;EX*u zg9m4j_{Cmi07aAA$8j|I>^6#Cw4)bs^db_|G$a(C*!~X3C#roYK4-`0aC{DlU)GL> z`g?2so?z%TN1FrI)K0XNh#x|Umd`sVnzo~99CcZ?CT_p*q3EI=UBuBvBresue9UVX z^Gcfo*3`t7*P;L7^&}dbelml{rmH`omG9Bq4`^LQVFYRs8>h2KvQWHY$16BqLE=WOTVV8qj6Q7+ zSX1k7(Lao6BWQH$$tgTKRn5KZN23{gG=oPoNc_g(FwHnjzeu2a3W^u)coD~oNL+Wa zZjxo)WOe3w8eh7BFWtqLR+0P=B{uEECQfW3ajO>eGkyWak2VLasr9w^MGqnGAR3z3 zK81%Ss^7kxLPHsQD1(Pwexqpo!jmODe!(7}!Q*b;4Wp6sPXs)2zPj}MI-a|U=kDRT z?@?|OjcnN?TXyo>K3yvMm4l11( zI-h$s$fDkY_2-df2ucVR08&pW1%5*^$ zW|P%94w&cqLT`G6I({`~%Kyy3IX?p908vy@2r8*WsVgN-MKsZfMZv3yjOdNjfP+Ya zB#GWh4ND;Dj&Ya(QE*?Ks7^ZeppF^UF|H#z(Mg(QI@w`fCpTQVu9i%43)&kI#_PB* z*`(_QxW@b{c0_h=Zf@RYE(;iTxRfe#j8HdVHCDyMqmFj-^NA!4+}sZaS1wc`pZBSI~%04a;xfoE4a z#Q`NE)8ed&`L4Z1cZC5Q5XRn9k=>!Z;`uZxUeNdmNaCXs#sJm|8IiW5oNWu!wn0eS zp}hSRgHU9N+k2&CbE2H3m4LLC_oLruM{@4X65WQ>0_d+B@q zyOaH~2YoBQKhv}FNAo|e3K&UB-0?jFfE_(FuFVrnX57ED{Z}vu~&Sc`^KiTNL Fe*h;OJAwcJ literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/migrations/__pycache__/0002_remove_boleto_fornecedor_remove_cliente_fornecedor_and_more.cpython-311.pyc b/venhapararecomb/notafiscal/migrations/__pycache__/0002_remove_boleto_fornecedor_remove_cliente_fornecedor_and_more.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf22680511833d673b3f81ebb1c275a8c7b087b2 GIT binary patch literal 1828 zcmcIk&2Jk;6rbI-*Sj0%YiTJ^`jHp`roswHT%bXUoCc{hQAI^7EQ{58XJW6t-Z8W5 zh&GoTIB@I@{(?|MjvP4fCvb2jAFR1@>H%r1q!P-dyqWdJw6&TG%; zo$W#U8bZH7Pg^aIm0PHse^J7FaHAG{Qr!%AkR0O`GXg+-Bj^Be&yiI zX}&iLwK;qiYT#9FZf3a`g%Hx%-S#8T4R~>7W#t3M5B=B&NpH}A#FSgxl!e42m@-*7 zqF9{J?Gm1owBQ9k31h-Ue0d?=6>(!c9q}0f;iMS;(%(;?-a9)1txVXm#tWEiyZs>M zCJi0HAu-`e6*8;(4w<8aGy;F|OU z0({YNzUjMxIK7ZC>5&kV(DT8HxN>~v3(}=KWJCICtYIuUCJ?!`K^gIz;pgNo*Kyko zo0O}#!3}v_xRAV1UAt9XTffH5YRhG*5sUW7_`d#(4#5sO{;~RT{YwZyRB!i#z^|{9 zs1ws(eTRfCx92jK5s!8o?>Ahp1O7cfU!MfNK6wo4Py!!1OuFx+sdOg!&lKa-{#)aQ z7y`sdrFWN!Dc6^?$T)SLXy`^>oEdy zBuHXR)R$kbE{zu7c*$;1pP!Hgb8yY%4NZ?}K{YPh;NT)jP9{d(Zt z8`!%K?cJfhJG!u(n0etLkRw5oA~G{0;NgE_WNBnC3s06GYz?m77+l#L+^G-z_Q38u zv^zt)GsTNfO18dtU3~1lEc9iazn)fC1ve_`3t!1fjFn&+H&67kYGrw*xho4R($p2; zj*Y8n>3_;9AVNA()BuubilRV1m8Ai?oc<&9?qJ%V=w(Gu(2L~0HC%Y>u}~aM(Mliw E0Y3@bEC2ui literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/migrations/__pycache__/0003_rename_identificador_cliente_documento.cpython-311.pyc b/venhapararecomb/notafiscal/migrations/__pycache__/0003_rename_identificador_cliente_documento.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5fe1f5c88dbb28795100e7a36cf5ba01866cc2e2 GIT binary patch literal 835 zcmZuvF>ljA6nBNL?~eMX(@LAtWl05L5`n5-goAzL((C_Jwmt# zMz;O~5Q4EkgrP&^m5Bk#RXb(kofD@maA!Y%@7{a&-TTg88VwI<9L#^?0R#AHoN`o` z;P?)KeUKno1TpI}1{OR5X?*}`BO6*}!Dk!b8@-FswPfW5w5z|2+h&;;hXXCfp-R$V znNoaKG+X5E145Tcpkg*)UE2bz49g6nl(wvVubwBOJV!c2RmAVLuE6m1eF~ z!6c>?)wZceB{AZOh%u|HNG?%=Zws_TN38P#a-Mmdc9xR}39oVfW+Ea}XgrA{Oo%23 zG1W%V?80+2!G|G6GV|03mr{O(W255y{e!#y%M^9$4<}I+`rDZ9j@8KD!{oIX2`w}R zD(>CviC~wu{(Id&)yhA;C!bWiP2v>CI@dNYrCN2rIeMqfMHR*&kZzNiu4e9l`-m31^6Jv7Qx#UbAo2i@SwmT%TD~BQ(s7=`` zgjsN|n~WmuGNE~WYa#4CeU)7LuOWR#Cbt=5bPjgo2ei&UxwFQc9R4+*yu*tdM<#Ic IpJ>7O2jyJqlK=n! literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/migrations/__pycache__/0004_remove_cliente_nota_fiscal_notafiscal_clientes_and_more.cpython-311.pyc b/venhapararecomb/notafiscal/migrations/__pycache__/0004_remove_cliente_nota_fiscal_notafiscal_clientes_and_more.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd9908704723f63a5498cd70a4a1255474052f72 GIT binary patch literal 1384 zcmb7E%}*0S6rcU*w!3WwHY6m1V1N)BBO%d~Ax#Jd6CxZGJv5Dz?as7p+3uFvmWU?~ z9z1d|@jt+?9z1yP&nQU`%^tjX;$X4_PMmx*+ZGXHWVZYIK7a4cd#`<;%^C>K*YltB zlY-C>F7!{L$DA$!^9~V2Bp21Bf>e_WvV>&x2od=;A_|qN5F4LE;64wef_q z#+)1)HK)R?hU0rdsMUNz-N5bzim!A}IMpPclA?k{P(dbAMJgyVqH48Y6r?6fOFfh! z9lY@o9$H@_38H}}SxpTzNs?;mmt$JS<&p)4K8TP>T40DaaV^P^Z0p9gFowwR^)V`H zAx%c0d1k1u_q)bh==lw+>;$&uhIbYh7w=(4J*!5sL#Wqq%8qRjpJCf|K%|)XcC!YY zA0~UMFwGHg3?XL1=YTmzsB+4ZaLq8)a}UBS_YdL#CwOIE6tK|q0hA1*uGOF<#*rI- zPGNkSEW^PPWrw;X)CbiZ-vITd$ZoyFF7+yntx#)v&Q6ntM%iZ`wJF>qRBf+b-NXu$XuhUq7?=I_!~kw3Leh~SvYZA0sp zx3}qY8rzL!w?SFV>nmGUk2U-{?QQKxbPAE^{O!tv;_!FM40gD29EzA8nEJgV(Kjtrzvy)ine$?n+g?#N`6P;}!20XgF&N+ErMo5#Cj zGu@H#t~q}&*D>e6`0ce9Z4)1vxMSidsq!EoXPj`%Ngi}dU`}++X&yBFq4aIEZRU^6 ze8)4Wi!olKyxXoe>E~wv0pv80bn2(OpuN-fco=jwgWe1j&!ki8;W_O+ zo#8&6&;Xs0KAq74I%EGqC)}qK8DJ;cr!zi4XQEGM(0(TSbf(_4QxeZ&r##IE?VU!~ z_{*Zl!8lB~R$SDuS@;$jE{8mMS?EzCJ!;gWVDfDGbzH!}S?cu~mH6BkyhE{)CgP5V z5e69Du$4X4Dk>UTSy)*3KsHgus3W_X zAiN5{*(Utwn;Aa|DK*=WizZTR1j%sKR4amU9|GawjZ2UG+^PVK* zBSR4FDK*U|qM^(5xFH)6-Zp6Dl6(Bzh|Dx|A81q(#M%F3CgabEE7ql z>4Y^6Q92~chc!iG`(qqLRpwbQs>m|g9YBUR+{Es%gKo0(NJ5{grFEL}Z59m?H}(~? zLk8C&>`>A+Etgu-zoaz~U|G>iv}CYAg6{U|)j@_f)}L&wZ*CFEsG{z5@*B9K_Q6ek zV>$mV-M^JD*ECJdZzAi!HmdnL()X3BVk!&*mBL&>DIU<>_Rr^U)0n@#tMU|iAIe@@ zd)V_P=Bo{pod9=W*O7HdFP5X;(-wgE9oP2p6T;C~Z3&3!pCl)Erxi)Qh)m+x{o}e5 zyMN*Ta|Y*RteZGyHDi_&vvAmMMN&BZ@TBgfA6~qV(`(K2nv-6`;ZItT1WrCUS#**Q z&P|+LZYGzVzLZoAE^_zKFw*T9Ft| zWKO1>MCSZ!oLFimmYl>A4rggdI5l^&>!ju`qBynEOszPn6&zk|k4qDy?ZAjAy##c) zWJAT)R-urdyV)u{loz)#@b=O(_0T-X*XrmczIMGHc^-fz1 zFe7xhWk`tbJ$pqH}r0yR6 E1vyh4D*ylh literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/migrations/__pycache__/0006_alter_notafiscal_id.cpython-311.pyc b/venhapararecomb/notafiscal/migrations/__pycache__/0006_alter_notafiscal_id.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..89de3f5c6190af728d6766a6820c9cbfdbe9752b GIT binary patch literal 885 zcmZuwO>5LZ7@kS8*-dOggW?C;LlrRx%OWT!MUYAb(Oz5?LU5SfneJwH^5G;auBSbC z@Yq}bfgji(;MJQKp~4=Pxq9kFQnsg_oXKvs)H)O1Jnz@M&paWY78h+G*H7&a{SE>6 zt(afUa8w1t^is@Lnc5se7tv=yTk3uu(ld4Q{tLJP>= zEeRUyt}ZWz-y%k%cGeN65*~z@4^WQ|gq2brU>3ZiMU}cTif~AUQP|36KpEL^Em1>7 z93f#NB&F#yD)9nBulty(TICU%C{|G`pea`>3;O}fC|_5na6<*GwGN*8!j2Oer8L9&&P`z5&2{apIee1az*_oXk7`%O=dX^>oEtmKTh~X< z^5^C^@`LU=jbBb<n& zMa3~$r8zm7F)pda*(Lb}F=eTF8HojnMTteJ$@#fSx=D%2*{OLc=;ASX`6Y>InZ?P8 zIWf7J=|zbpnfZCeG4b)4d6^~g@p=W7zc_4i^HWN5QtgUZffjIfwuN literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/models.py b/venhapararecomb/notafiscal/models.py index deb8929..48d758d 100644 --- a/venhapararecomb/notafiscal/models.py +++ b/venhapararecomb/notafiscal/models.py @@ -2,6 +2,9 @@ from django.db import models class Fornecedor(models.Model): + """ + Modelo que representa um fornecedor de produtos. Cada fornecedor possui um nome e um CNPJ. + """ nome = models.CharField(max_length=100) cnpj = models.CharField(max_length=14, unique=True) @@ -9,13 +12,20 @@ def __str__(self) -> str: return self.nome class NotaFiscal(models.Model): + """ + Modelo que representa uma nota fiscal. Cada nota fiscal possui um identificador único, um fornecedor e uma lista de clientes. + """ + identificador = models.CharField(max_length=50, unique=True) fornecedor = models.ForeignKey(Fornecedor, on_delete=models.CASCADE) clientes = models.ManyToManyField('Cliente', related_name='notas_fiscais') def __str__(self) -> str: - return f'Nota Fiscal {self.fornecedor.nome}' + return f'Nota Fiscal {self.id} - {self.fornecedor}' class Boleto(models.Model): + """ + Modelo que representa um boleto. Cada boleto possui um valor, uma data de vencimento e uma nota fiscal. + """ valor = models.DecimalField(max_digits=10, decimal_places=2) data_vencimento = models.DateField() nota_fiscal = models.ForeignKey(NotaFiscal, on_delete=models.CASCADE) @@ -24,6 +34,9 @@ def __str__(self) -> str: return f'Boleto {self.valor} - {self.data_vencimento}' class Endereco(models.Model): + """ + Modelo que representa um endereço. Cada endereço possui um logradouro, um número, um bairro, uma cidade, um estado, um CEP, um país e um telefone. + """ logradouro = models.CharField(max_length=100) numero = models.CharField(max_length=10) bairro = models.CharField(max_length=50) @@ -37,6 +50,9 @@ def __str__(self) -> str: return self.logradouro class Cliente(models.Model): + """ + Modelo que representa um cliente. Cada cliente possui um nome, um tipo de documento (CPF ou CNPJ), um documento (CPF ou CNPJ) e um endereço. + """ TIPO_DOCUMENTO = ( ('CPF', 'CPF'), ('CNPJ', 'CNPJ'), diff --git a/venhapararecomb/notafiscal/tests.py b/venhapararecomb/notafiscal/tests.py index 7ce503c..b4abefe 100644 --- a/venhapararecomb/notafiscal/tests.py +++ b/venhapararecomb/notafiscal/tests.py @@ -1,3 +1,84 @@ from django.test import TestCase +from django.urls import reverse +from .models import Fornecedor, NotaFiscal, Cliente, Boleto, Endereco + +class ModelTestCase(TestCase): + def setUp(self): + self.fornecedor = Fornecedor.objects.create(nome='Fornecedor Test', cnpj='12345678901234') + self.endereco = Endereco.objects.create(logradouro='Rua Test', numero='123', bairro='Bairro Test', + cidade='Cidade Test', estado='TS', cep='12345678', + pais='País Test', telefone='123456789') + self.cliente = Cliente.objects.create(nome='Cliente Test', tipo_documento='CPF', documento='12345678901', + endereco=self.endereco) + self.nf = NotaFiscal.objects.create(identificador='NF001', fornecedor=self.fornecedor) + self.boleto = Boleto.objects.create(valor=100.00, data_vencimento='2024-12-31', nota_fiscal=self.nf) + + def test_fornecedor_creation(self): + self.assertEqual(self.fornecedor.nome, 'Fornecedor Test') + self.assertEqual(self.fornecedor.cnpj, '12345678901234') + + def test_nota_fiscal_creation(self): + self.assertEqual(self.nf.identificador, 'NF001') + self.assertEqual(self.nf.fornecedor, self.fornecedor) + + def test_cliente_creation(self): + self.assertEqual(self.cliente.nome, 'Cliente Test') + self.assertEqual(self.cliente.tipo_documento, 'CPF') + self.assertEqual(self.cliente.documento, '12345678901') + self.assertEqual(self.cliente.endereco, self.endereco) + + def test_boleto_creation(self): + self.assertEqual(self.boleto.valor, 100.00) + self.assertEqual(str(self.boleto.data_vencimento), '2024-12-31') + self.assertEqual(self.boleto.nota_fiscal, self.nf) + + +class ViewTestCase(TestCase): + def setUp(self) : + self.fornecedor = Fornecedor.objects.create(nome='Fornecedor Test', cnpj='12345678901234') + + def test_index_view(self): + response = self.client.get(reverse('index')) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'index.html') + + def test_list_nfs_view(self): + response = self.client.get(reverse('list_nfs')) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'list_nfs.html') + + def test_detail_nf_view(self): + nf = NotaFiscal.objects.create(identificador='NF002', fornecedor=self.fornecedor) + response = self.client.get(reverse('detail_nf', args=(nf.id,))) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'detail_nf.html') + + def test_delete_nf_view(self): + nf = NotaFiscal.objects.create(identificador='NF003', fornecedor=self.fornecedor) + response = self.client.post(reverse('delete_nf', args=(nf.id,))) + self.assertEqual(response.status_code, 302) + + def test_list_clientes_view(self): + response = self.client.get(reverse('list_clientes')) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'list_clientes.html') + + def test_list_forncedores_view(self): + response = self.client.get(reverse('list_fornecedores')) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'list_fornecedores.html') + + def test_delete_fornecedor_view(self): + response = self.client.post(reverse('delete_fornecedor', args=(self.fornecedor.id,))) + self.assertEqual(response.status_code, 302) + + def test_delete_cliente_view(self): + cliente = Cliente.objects.create(nome='Cliente Test', tipo_documento='CPF', documento='12345678901', + endereco=Endereco.objects.create(logradouro='Rua Test', numero='123', bairro='Bairro Test', + cidade='Cidade Test', estado='TS', cep='12345678', + pais='País Test', telefone='123456789')) + response = self.client.post(reverse('delete_cliente', args=(cliente.id,))) + self.assertEqual(response.status_code, 302) + + -# Create your tests here. diff --git a/venhapararecomb/notafiscal/urls.py b/venhapararecomb/notafiscal/urls.py index 62763b6..a6a00ea 100644 --- a/venhapararecomb/notafiscal/urls.py +++ b/venhapararecomb/notafiscal/urls.py @@ -3,7 +3,11 @@ urlpatterns = [ path('', views.index, name='index'), - path('nfs/', views.list_nfs, name='notas_fiscais'), - path('nf//', views.detail_nf, name='nota_fiscal'), - + path('nfs/', views.list_nfs, name='list_nfs'), + path('nf//', views.detail_nf, name='detail_nf'), + path('nf//delete/', views.delete_nf, name='delete_nf'), + path('fornecedores/', views.list_fornecedores, name='list_fornecedores'), + path('fornecedor//delete/', views.delete_fornecedor, name='delete_fornecedor'), + path('clientes/', views.list_clientes, name='list_clientes'), + path('cliente//delete/', views.delete_cliente, name='delete_cliente'), ] diff --git a/venhapararecomb/notafiscal/views.py b/venhapararecomb/notafiscal/views.py index 23396ec..c9096c2 100644 --- a/venhapararecomb/notafiscal/views.py +++ b/venhapararecomb/notafiscal/views.py @@ -1,23 +1,40 @@ from django.shortcuts import render, redirect import xml.etree.ElementTree as ET from .models import Fornecedor, Cliente, Boleto, NotaFiscal, Endereco +from django.urls import reverse +from django.views.decorators.http import require_POST def parse_xml(xml_file): + """ + Esta função recebe um arquivo XML e extrai informações relevantes para o sistema de notas fiscais. + + Args: + xml_file: O arquivo XML enviado pelo usuário. + + Returns: + dict: Um dicionário contendo informações extraídas do XML, incluindo ID da nota fiscal, fornecedor, + clientes e boletos. + """ + xml = ET.parse(xml_file) root = xml.getroot() nsNFe = {'ns': 'http://www.portalfiscal.inf.br/nfe'} + nf_id = root.find('.//ns:infNFe', nsNFe).attrib['Id'] + # Extraindo informações do fornecedor da nota fiscal (emitente) xNome = root.find('ns:NFe/ns:infNFe/ns:emit/ns:xNome', nsNFe).text cnpj = root.find('ns:NFe/ns:infNFe/ns:emit/ns:CNPJ', nsNFe).text fornecedor = {'nome': xNome, 'cnpj': cnpj} - + + # Extraindo informações dos clientes da nota fiscal clientes = [] for dest in root.findall('ns:NFe/ns:infNFe/ns:dest', nsNFe): xNome = dest.find('ns:xNome', nsNFe).text cpf = dest.find('ns:CPF', nsNFe) cnpj = dest.find('ns:CNPJ', nsNFe) + # Extraindo informações do endereço do cliente endereco = dest.find('ns:enderDest', nsNFe) logradouro = endereco.find('ns:xLgr', nsNFe).text numero = endereco.find('ns:nro', nsNFe).text @@ -35,55 +52,183 @@ def parse_xml(xml_file): 'logradouro': logradouro, 'numero': numero, 'bairro': bairro, 'cidade': cidade, 'estado': estado, 'cep': cep, 'pais': pais, 'telefone': telefone } - + clientes.append({'nome': xNome, 'documento': documento, 'tipo_documento': tipo_documento, 'endereco': endereco_json}) + # Extraindo informações dos boletos da nota fiscal boletos = [] for det in root.findall('ns:NFe/ns:infNFe/ns:cobr/ns:dup', nsNFe): valor = det.find('ns:vDup', nsNFe).text data_vencimento = det.find('ns:dVenc', nsNFe).text - boletos.append({'valor': valor, 'data_vencimento': data_vencimento}) + boletos.append({'valor': valor, 'data_vencimento': data_vencimento}) # Adicionando informações do boleto à lista de boletos + + return {'nf_id': nf_id, 'fornecedor': fornecedor, 'clientes': clientes, 'boletos': boletos} + - return {'fornecedor': fornecedor, 'clientes': clientes, 'boletos': boletos} def index(request): - context = {} + """ + Esta função é responsável por renderizar a página inicial do sistema de notas fiscais. + Permite aos usuários enviar arquivos XML para processamento e salvar as informações da nota fiscal no banco de dados. + Returns: + HttpResponse: Uma resposta HTTP renderizada com base na solicitação do usuário. + """ + context = {} if request.method == 'POST': + # Verificando se o usuário deseja ler um arquivo XML if 'read_xml' in request.POST: xml_data = parse_xml(request.FILES['xml_file']) request.session['xml_data'] = xml_data context['xml_data'] = xml_data + # Verificando se o usuário deseja salvar a nota fiscal lida elif 'save_nf' in request.POST: xml_data = request.session.pop('xml_data', {}) - fornecedor, _ = Fornecedor.objects.get_or_create(nome=xml_data['fornecedor']['nome'], cnpj=xml_data['fornecedor']['cnpj']) - nf = NotaFiscal.objects.create(fornecedor=fornecedor) - - for cliente in xml_data['clientes']: - - endereco_obj = Endereco.objects.create(logradouro=cliente['endereco']['logradouro'], numero=cliente['endereco']['numero'], bairro=cliente['endereco']['bairro'], cidade=cliente['endereco']['cidade'], estado=cliente['endereco']['estado'], cep=cliente['endereco']['cep'], pais=cliente['endereco']['pais'], telefone=cliente['endereco']['telefone']) - cliente_obj, created = Cliente.objects.get_or_create(documento=cliente['documento'], defaults={'nome': cliente['nome'], 'tipo_documento': cliente['tipo_documento']}, endereco=endereco_obj) + nf, created = NotaFiscal.objects.get_or_create(identificador=xml_data['nf_id'], fornecedor=fornecedor) + + # Verificando se a nota fiscal já foi cadastrada + if not created: + context['error'] = 'Nota Fiscal já cadastrada' + context['xml_data'] = xml_data + return render(request, 'index.html', context) + + # Adicionando clientes à nota fiscal + for cliente_data in xml_data['clientes']: + documento = cliente_data['documento'] + try: + cliente_obj = Cliente.objects.get(documento=documento) + except Cliente.DoesNotExist: + endereco_obj = Endereco.objects.create(**cliente_data['endereco']) + cliente_obj = Cliente.objects.create(documento=documento, nome=cliente_data['nome'], tipo_documento=cliente_data['tipo_documento'], endereco=endereco_obj) + nf.clientes.add(cliente_obj) - for boleto in xml_data['boletos']: - Boleto.objects.create(valor=boleto['valor'], data_vencimento=boleto['data_vencimento'], nota_fiscal=nf) - - return redirect('index') + # Adicionando boletos à nota fiscal + for boleto_data in xml_data['boletos']: + Boleto.objects.create(valor=boleto_data['valor'], data_vencimento=boleto_data['data_vencimento'], nota_fiscal=nf) + + context['success'] = 'Nota Fiscal cadastrada com sucesso' return render(request, 'index.html', context) +@require_POST +def delete_nf(request, id): + """ + Esta função é responsável por deletar uma nota fiscal do banco de dados. + + Args: + id: O ID da nota fiscal a ser deletada. + + Returns: + HttpResponseRedirect: Redireciona o usuário para a página de listagem de notas fiscais após a exclusão. + """ + try: + nf = NotaFiscal.objects.get(id=id) + nf.delete() + except NotaFiscal.DoesNotExist: + pass + return redirect(reverse('list_nfs')) + def list_nfs(request): + """ + Esta função é responsável por listar todas as notas fiscais cadastradas no sistema. + + Returns: + HttpResponse: Uma resposta HTTP renderizada com base na solicitação do usuário, listando todas as notas fiscais. + """ context = { 'nfs': NotaFiscal.objects.all() } return render(request, 'list_nfs.html', context) -def detail_nf(request, nf_id): + +def detail_nf(request, id): + """ + Esta função é responsável por renderizar a página de detalhes de uma nota fiscal. + + Args: + id: O ID da nota fiscal a ser visualizada. + + Returns: + HttpResponse: Uma resposta HTTP renderizada com base na solicitação do usuário, exibindo os detalhes da nota fiscal. + """ + + nf = NotaFiscal.objects.get(id=id) + clientes = nf.clientes.all() + fornecedor = nf.fornecedor + boletos = Boleto.objects.filter(nota_fiscal=nf) + context = { - 'nf': NotaFiscal.objects.get(id=nf_id) + 'nf': nf, + 'clientes': clientes, + 'boletos': boletos, + 'fornecedor': fornecedor } + return render(request, 'detail_nf.html', context) +@require_POST +def delete_fornecedor(request, id): + """ + Esta função é responsável por deletar um fornecedor do banco de dados. + + Args: + id: O ID do fornecedor a ser deletado. + + Returns: + HttpResponseRedirect: Redireciona o usuário para a página de listagem de fornecedores após a exclusão. + """ + try: + fornecedor = Fornecedor.objects.get(id=id) + fornecedor.delete() + except Fornecedor.DoesNotExist: + pass + return redirect(reverse('list_fornecedores')) + +def list_fornecedores(request): + """ + Esta função é responsável por listar todos os fornecedores cadastrados no sistema. + + Returns: + HttpResponse: Uma resposta HTTP renderizada com base na solicitação do usuário, listando todos os fornecedores. + """ + context = { + 'fornecedores': Fornecedor.objects.all() + } + return render(request, 'list_fornecedores.html', context) + +@require_POST +def delete_cliente(request, id): + """ + Esta função é responsável por deletar um cliente do banco de dados. + + Args: + id: O ID do cliente a ser deletado. + + Returns: + HttpResponseRedirect: Redireciona o usuário para a página de listagem de clientes após a exclusão. + """ + try: + cliente = Cliente.objects.get(id=id) + cliente.delete() + except Cliente.DoesNotExist: + pass + return redirect(reverse('list_clientes')) + +def list_clientes(request): + """ + Esta função é responsável por listar todos os clientes cadastrados no sistema. + + Returns: + HttpResponse: Uma resposta HTTP renderizada com base na solicitação do usuário, listando todos os clientes. + """ + context = { + 'clientes': Cliente.objects.all() + } + + return render(request, 'list_clientes.html', context) + + diff --git a/venhapararecomb/static/css/style.css b/venhapararecomb/static/css/style.css deleted file mode 100644 index ed9650e..0000000 --- a/venhapararecomb/static/css/style.css +++ /dev/null @@ -1,14 +0,0 @@ -:root{ - --primary-color: #0b9ad7; - --secondary-color: #1d7a9f; - --tertiary-color: #f5b111; - --white-color: #deecef; - --dark-grey-color: #283238; - --light-grey-color: #3C4B56; - --black-color: #13181B; - - -} - - - diff --git a/venhapararecomb/templates/base.html b/venhapararecomb/templates/base.html index 83607e0..6be0930 100644 --- a/venhapararecomb/templates/base.html +++ b/venhapararecomb/templates/base.html @@ -5,12 +5,13 @@ {% block title %}{% endblock %} + + @@ -21,7 +22,13 @@ Home + + @@ -32,14 +39,7 @@ {% block content %} {% endblock %} - - -
-
-

Entre em contato:

-

Email: contato@empresa.com

-

Telefone: (XX) XXXX-XXXX

-
-
+ + diff --git a/venhapararecomb/templates/detail_nf.html b/venhapararecomb/templates/detail_nf.html index f09d234..16c4e15 100644 --- a/venhapararecomb/templates/detail_nf.html +++ b/venhapararecomb/templates/detail_nf.html @@ -1,37 +1,32 @@ {% extends 'base.html' %} {% block title %} -Informações da nota fiscal {{ nf.id }} +Informações da nota fiscal {{ nf.identificador }} {% endblock %} {% block content %} -
-

Nota Fiscal

-
-

Nota Fiscal

-
-
- {% csrf_token %} - -
-
-
+ +
+

Nota Fiscal

    +
  • Fornecedor:
    - Nome - {{ nf.fornecedor.nome }} | - CNPJ - {{ nf.fornecedor.cnpj }} + Nome - {{ fornecedor.nome }} | + CNPJ - {{ fornecedor.cnpj }}
  • +
  • Clientes:
      - {% for cliente in nf.clientes %} + {% for cliente in clientes %}
    • Nome: {{ cliente.nome }} | {{ cliente.tipo_documento }}: {{ cliente.documento }} +
      • Endereço: {{ cliente.endereco.logradouro }} {{ cliente.endereco.numero }}
      • CEP: {{ cliente.endereco.cep }}
      • @@ -44,10 +39,11 @@

        Nota Fiscal

        {% endfor %}
    • +
    • Boletos:
        - {% for boleto in nf.boletos %} + {% for boleto in boletos %}
      • Valor: {{ boleto.valor }} | Vencimento: {{ boleto.data_vencimento }} @@ -60,8 +56,9 @@

        Nota Fiscal

+ {% endblock %} \ No newline at end of file diff --git a/venhapararecomb/templates/index.html b/venhapararecomb/templates/index.html index 3c30b8c..9151e04 100644 --- a/venhapararecomb/templates/index.html +++ b/venhapararecomb/templates/index.html @@ -21,9 +21,21 @@

Olá, seja bem vindo!

+ +{% if error %} + +{% elif success %} + +{% endif %} + -{% if xml_data %} +{% if xml_data and not error %}
+

Nota Fiscal

@@ -33,14 +45,18 @@

Nota Fiscal

+ +
    +
  • Fornecedor:
    Nome - {{ xml_data.fornecedor.nome }} | CNPJ - {{ xml_data.fornecedor.cnpj }}
  • +
  • Clientes:
      @@ -48,7 +64,7 @@

      Nota Fiscal

    • Nome: {{ cliente.nome }} | {{ cliente.tipo_documento }}: {{ cliente.documento }} - +
      • Endereço: {{ cliente.endereco.logradouro }} {{ cliente.endereco.numero }}
      • CEP: {{ cliente.endereco.cep }}
      • @@ -61,6 +77,7 @@

        Nota Fiscal

        {% endfor %}
    • +
    • Boletos:
        diff --git a/venhapararecomb/templates/list_clientes.html b/venhapararecomb/templates/list_clientes.html new file mode 100644 index 0000000..f206de8 --- /dev/null +++ b/venhapararecomb/templates/list_clientes.html @@ -0,0 +1,31 @@ +{% extends 'base.html' %} + +{% block title %} +Lista de Clientes +{% endblock %} + +{% block content %} + +
        +

        Clientes

        + + {% if clientes %} +
          + {% for cliente in clientes %} +
        • + + {{ cliente }} + +
          + {% csrf_token %} + +
          +
        • + {% endfor %} +
        + {% endif %} +
        +
        + Voltar +
        +{% endblock %} diff --git a/venhapararecomb/templates/list_fornecedores.html b/venhapararecomb/templates/list_fornecedores.html new file mode 100644 index 0000000..4e0b5f7 --- /dev/null +++ b/venhapararecomb/templates/list_fornecedores.html @@ -0,0 +1,35 @@ +{% extends 'base.html' %} + +{% block title %} +Lista de Fornecedores +{% endblock %} + +{% block content %} + +
        +

        Fornecedores

        + + + + {% if fornecedores %} +
          + {% for fornecedor in fornecedores %} +
        • + + {{ fornecedor }} + +
          + {% csrf_token %} + +
          +
        • + {% endfor %} +
        + {% endif %} +
        +
        + Voltar +
        +{% endblock %} diff --git a/venhapararecomb/templates/list_nfs.html b/venhapararecomb/templates/list_nfs.html index f9c54dc..16651f7 100644 --- a/venhapararecomb/templates/list_nfs.html +++ b/venhapararecomb/templates/list_nfs.html @@ -5,17 +5,26 @@ {% endblock %} {% block content %} -
        -

        Notas Fiscais

        - {% if nfs %} -
          - {% for nf in nfs %} -
        • {{ nf }}
        • - {% endfor %} -
        - {% endif %} -
        -
        - Voltar -
        + +
        +

        Notas Fiscais

        + {% if nfs %} +
          + {% for nf in nfs %} +
        • + + {{ nf }} + +
          + {% csrf_token %} + +
          +
        • + {% endfor %} +
        + {% endif %} +
        +
        + Voltar +
        {% endblock %} diff --git a/venhapararecomb/venhapararecomb/__pycache__/__init__.cpython-311.pyc b/venhapararecomb/venhapararecomb/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d55a950e8d611ee3ebb543055cda0aae616f1748 GIT binary patch literal 199 zcmZ3^%ge<81Y3T+O$E`9K?DpiLK&agfQ;!3DGb33nv8xc8H$*I{LdiCUs29hF`>n& zMa3~$r8zm7F)pda*(Lb}F=eTF8HojnMTteJ$@#fSx=D%2*{OLc=;9ds`1s7c%#!$c oy@JYL95%W6DWy57c15f}t3Zw^<_8iVm>C%vKQO?EB4(f%0B+$n^8f$< literal 0 HcmV?d00001 diff --git a/venhapararecomb/venhapararecomb/__pycache__/settings.cpython-311.pyc b/venhapararecomb/venhapararecomb/__pycache__/settings.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b3a4ddf816c385567359193de8b17865bdf1654b GIT binary patch literal 2795 zcmb7G-EZ4e6u-_#^U)+r+ic6m5J4N;I;gXcZbJx_xry6Fq)DjL4XjC)>wBBr%&{|H zXQO_~BS<_TgtR^E0r4CEoVLv6Hk>I*H-f=YE~@J0JI)d-GE| zokZ}g6#piFW)S+rAB>-wQRkm?972x~Ml!-24(VJsB!@V^AJ)TiID|-uM4kc9uka0@ zAEM*lWcv&TzaC6<#`x&4C&zF^j^n7DXdyY-LU`s!PM(D}25kz*mA;eVo*f9OZEOX{5!;S)7sQ@G+bP{yAqBAw2&yL^*jLFW?+- zE#Tt;JrU58lxs!g1)P_2_>_DcY&-$qNqkz)=4c7lgV{r5KFZQE^O}>F5p0RNyS}i6qv1A_K5RB zq0a!VFap2MU*@lY^crAyO^Xz$0cyIcO--W!uid7gnCj#Mu!AJqw%ubN6^q!^7(di8 zwgAj25~B!!MceFAjTOg+7l-h6n-q5Xx?a#JvkT_Vp<}9nK@p+go~ri=`#-uYvNNIR zFMppFIXBW!?RL#s9fg4!jA(s}EG?P$owMCryVj+vxP9~L!}IN(<*S$9!<`m0?B(k> zcfZ8i19I;Cm3BunwX?fzy}1~3azhwiGY#9K+k6mJXJLA_Z?~PdrY3z6V%YX>k1*%t z)FLB{L7a~+bYVelfyC))2^)4s^Y??fNyD_&9m+IS2OF10oL!2sP98yi@PW_N-sL6V zdFX5$tU1fmz#~)m33+KaHzBonR0(W**EIN2(EJB0vv&9rkUNw-nqa*-Ws3@doU}uL zF~pE+K~_!(PCGFU+obTuFq9KgH(uj}PPO|TRl5(B!GFGHsa;a<`6a+6onl&N zL+*@NTd&kaH&PQeL@Ny^fOC7wfgq)NDr1jK3oCHSP#mb^w-~Vm+pp@rO(fc-y6RWT zogs&5IV*39v_TEp?RTrhXxZ&U`A^*6$LFYDW>GJ$q@}a^{3! zT`fwgsWc$QrV}s1)c}Q6blx6mfxvc6OmxPt(iRk+xkibO7f-t}MS(+KQQTM$j#iy+ zTVV*a8#0+2R}}w5^4BcFO#LBoXW)v0l6B*&f+YGm;3g%pv?(@~PsK0XXjxp{T6fbz zwOYR`mX+IesVTXcN=<6Q6ih(kNN#eYQZ84;yTYdErZ(&Krn0qJE!AslZp1gijdVzifej!><@Vja>n zT@`BUTf(}il04p1!BG)0I;#**R<;sUOcgF8EW$>a2$R*zrcfKsH30u{s0?2h` zts+*-zo38o3+R&wk70xQ zI$5zUfhzy664QWsVUFXxP?C#y$R~Nko!UeB$#)+m2EospL8{fsX{M{Kakd9K|QFouqf{dGo#RdvE4bqhTPhuNOb)vkF4r zLSNvU zSRSdvsC(5T1ygR`D38Pz4t$Yd&eDVm3}^x;4Da~#jj-_=K!uD`>_>na zPVnP^5<#(`v}IthVUon6q$nDU`S+r_Dj{*!Yp>VG?0Kj2TZ_8232~ak$$haa=ejH1qhoMZ8oX1xzV~tsr*T zG|k0A*N}yD5l1AX_f0uBEn_7hLfr0wFmDR=Z!B0cq+AlQbH*i|CxG=oY-GGmL|1|| ztxJs7BR5DrKN>(0@_bU7>~vY5^}H|`s6cyUENxo2UzD;nDc7VOwk&u_vWQ*Gi}KHG zdjT6bP{1;iDIGbkX<5d1c~UJU(}@@Qk)>vutaw%{qW7w~-^tM4JZK?(U$`X5cR#mg zvRbzbXQ$iE<_fx?GU0xY!{tNS?34zsfrsnTtqDJ&nI@HGvs2yvjLu;hUA$gtbv6X$ zqBBZ^!0)V5u?=UibLnP4%iV1nd6)ga{mVplyn9i<7cwsm=mUNQ(#T6HQW(Y+MN!7; zyrPYf957OD93wpao}rt^e|pDNq|fZH9$f#heAqgCc%m(wY71vt9b8urHV-zBuiZLn Yn5PZ%L~EXE&9PpYSNCV-!{;FLPyS18KmY&$ literal 0 HcmV?d00001 diff --git a/venhapararecomb/venhapararecomb/__pycache__/wsgi.cpython-311.pyc b/venhapararecomb/venhapararecomb/__pycache__/wsgi.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fe0a8c77e27f6186a9e28e10051edbdc39a500c2 GIT binary patch literal 737 zcmZWn&rcIU6n?V>s*5zn2=O=}Tu5XW4_=5dF%}7+a2Sekz?xvymAyFDNHEpD$ zL?#5=7f6|=jK+$01+EC}p`bmMMmI~6#mH%+!IDHoAv2MZjfSoF%A&<8MH)#99N#QZ zC2jFY(`F>_G1Z7}+n7YJ`94>n_IQWMmKt-i1bvkLQ*YI8t3#uFj)_o5F-qef>Q>~t zzw#qjmPz)og(k>j!32$Lp}h5?vau6X*LQa}D;w3|%}#mm_4@InTesk8G$xWQy;&=`xXzgk-@aU{?`ceR zz0(yUs+Un87?sp-;jiqo@Bk&h9skeIDR{}z@XoW*TRcxo7RLTI(C@9eDiA`hoFbXJ zg4{d+;-1{ibpTKL|F!`*AKmXT{|)B*3toS9>jJhfVY?68gVJKZw0Kckx-2c7%;uWj Hv&H`aPxat= literal 0 HcmV?d00001 diff --git a/venhapararecomb/venhapararecomb/settings.py b/venhapararecomb/venhapararecomb/settings.py index 14a481d..0ec2a6d 100644 --- a/venhapararecomb/venhapararecomb/settings.py +++ b/venhapararecomb/venhapararecomb/settings.py @@ -26,9 +26,9 @@ # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True +#ALLOWED_HOSTS = ['trumpet.db.elephantsql.com', '127.0.0.1'] ALLOWED_HOSTS = [] - # Application definition INSTALLED_APPS = [ @@ -75,6 +75,17 @@ # Database # https://docs.djangoproject.com/en/5.0/ref/settings/#databases +# DATABASES = { +# 'default': { +# 'ENGINE': 'django.db.backends.postgresql', +# 'NAME': 'azixfhyp', +# 'USER': 'azixfhyp', +# 'PASSWORD': 'mx7x20d6m-3JM4MVisx8sicxwyg0NVTI', +# 'HOST': 'trumpet.db.elephantsql.com', +# 'PORT': '5432', +# } +# } + DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', @@ -82,7 +93,6 @@ } } - # Password validation # https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators @@ -105,9 +115,9 @@ # Internationalization # https://docs.djangoproject.com/en/5.0/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = 'pt-br' -TIME_ZONE = 'UTC' +TIME_ZONE = 'America/Sao_Paulo' USE_I18N = True @@ -119,9 +129,6 @@ STATIC_URL = '/static/' -STATICFILES_DIRS = [ - os.path.join(BASE_DIR, 'static') -] # Default primary key field type # https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field From 8928a174850f0b981f2f11017f959e1e068e73aa Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 11 Mar 2024 11:32:51 -0300 Subject: [PATCH 6/8] completed --- README.md | 24 ++++++---- venhapararecomb/Dockerfile | 20 +++++++++ venhapararecomb/db.sqlite3 | Bin 196608 -> 196608 bytes venhapararecomb/docker-compose.yml | 10 +++++ .../__pycache__/__init__.cpython-310.pyc | Bin 168 -> 120 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 182 -> 180 bytes .../__pycache__/admin.cpython-310.pyc | Bin 209 -> 368 bytes .../__pycache__/admin.cpython-312.pyc | Bin 727 -> 725 bytes .../__pycache__/apps.cpython-310.pyc | Bin 455 -> 407 bytes .../__pycache__/apps.cpython-312.pyc | Bin 496 -> 494 bytes .../__pycache__/models.cpython-310.pyc | Bin 206 -> 3267 bytes .../__pycache__/models.cpython-312.pyc | Bin 3889 -> 4753 bytes .../__pycache__/tests.cpython-312.pyc | Bin 0 -> 8688 bytes .../__pycache__/urls.cpython-310.pyc | Bin 299 -> 621 bytes .../__pycache__/urls.cpython-312.pyc | Bin 549 -> 1026 bytes .../__pycache__/views.cpython-310.pyc | Bin 593 -> 6820 bytes .../__pycache__/views.cpython-312.pyc | Bin 5729 -> 10972 bytes .../__pycache__/0001_initial.cpython-310.pyc | Bin 0 -> 1755 bytes .../__pycache__/0001_initial.cpython-312.pyc | Bin 2622 -> 3595 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 179 -> 131 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 193 -> 191 bytes venhapararecomb/notafiscal/tests.py | 41 +++++++++++------- venhapararecomb/notafiscal/views.py | 4 ++ venhapararecomb/requirements.txt | Bin 0 -> 130 bytes venhapararecomb/templates/list_clientes.html | 4 ++ .../__pycache__/__init__.cpython-310.pyc | Bin 173 -> 125 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 187 -> 185 bytes .../__pycache__/settings.cpython-310.pyc | Bin 2335 -> 2351 bytes .../__pycache__/settings.cpython-312.pyc | Bin 2823 -> 2725 bytes .../__pycache__/urls.cpython-310.pyc | Bin 1023 -> 975 bytes .../__pycache__/urls.cpython-312.pyc | Bin 1143 -> 1141 bytes .../__pycache__/wsgi.cpython-310.pyc | Bin 592 -> 544 bytes .../__pycache__/wsgi.cpython-312.pyc | Bin 691 -> 689 bytes 33 files changed, 79 insertions(+), 24 deletions(-) create mode 100644 venhapararecomb/Dockerfile create mode 100644 venhapararecomb/docker-compose.yml create mode 100644 venhapararecomb/notafiscal/__pycache__/tests.cpython-312.pyc create mode 100644 venhapararecomb/notafiscal/migrations/__pycache__/0001_initial.cpython-310.pyc create mode 100644 venhapararecomb/requirements.txt diff --git a/README.md b/README.md index 8c9a32e..523a946 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ - Django: Framework web em Python. - Sqlite3: Serviço de banco de dados local do Django. - HTML, CSS e Bootstrap: para a interface do usuário. +- Docker. ### Funcionalidades Implementadas 1. **Parse de XML**: A função parse_xml recebe um arquivo XML de uma nota fiscal e extrai as informações relevantes, como fornecedor, clientes, endereços e boletos. @@ -22,22 +23,29 @@ ``` git clone https://github.com/jcquadros/venhapararecomb-backend.git ``` -2. Instale o Django: +2. Execute: ``` - pip install django + docker-compose build + docker-compose up ``` -3. Navegue até o diretório do projeto que contenha o arquivo manage.py. + Acesse 'http://localhost:8000/' no navegador. -4. Inicie o servidor: +3. Testes: + Para executar os testes, certifique estar dentro do diretório venhapararecomb/ de instalar as bibliotecas e executar o teste: ``` + pip install -r requirements.txt + python manage.py test + ``` + De forma semelhante, se optar por nao usar o Docker, a aplicação pode ser executada com os seguintes comandos: + ``` + pip install -r requirements.txt python manage.py runserver ``` - -5. Acesse a aplicação em seu navegador, através do endereço 'http://127.0.0.1:8000/'. - + Após isso acesse 'http://127.0.0.1:8000/' no navegador. ## Diferenciais Implementados - Interface de Usuário Responsiva: A interface do usuário foi desenvolvida de forma simples com Bootstrap, mas responsiva. - Tratamento de Erros: O sistema trata erros comuns, como tentativa de envio de nota fiscal fornecedores e clientes duplicados. - Padrão de programação Django MTV (Model, Template, View) - Uso de banco de dados: A aplicação utiliza o Sqlite3 como serviço de banco de dados local. -- Implementação de Testes Unitários: Os testes cobrem as principais funções da aplicação, incluindo o parse de XML, as views e os modelos do Django. \ No newline at end of file +- Implementação de Testes Unitários: Os testes cobrem as principais funções da aplicação, incluindo as views e os modelos do Django. +- Uso de docker. \ No newline at end of file diff --git a/venhapararecomb/Dockerfile b/venhapararecomb/Dockerfile new file mode 100644 index 0000000..b82fc1b --- /dev/null +++ b/venhapararecomb/Dockerfile @@ -0,0 +1,20 @@ +# Imagem base do Python +FROM python:3.10 + +# Configuração do diretório de trabalho dentro do contêiner +WORKDIR /app + +# Copia o arquivo requirements.txt para o contêiner +COPY requirements.txt . + +# Instala as dependências do projeto +RUN pip install -r requirements.txt + +# Copia o restante do código-fonte para o contêiner +COPY . . + +# Expõe a porta 8000 do contêiner +EXPOSE 8000 + +# Comando para executar o servidor Django +CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] diff --git a/venhapararecomb/db.sqlite3 b/venhapararecomb/db.sqlite3 index 8a4d913abaf2f8fc6c8f325230fee31a32463e97..b0dac5efb7e0273c04c9bf3c9d219dad73d179b0 100644 GIT binary patch delta 695 zcmZo@;Av>!nIO%WK2gS*HJw2(nQ>!Eq#h&7InZ?P8Iq^yP zIjJT2+><}(SsAg3@i7}BOD5-JrskETvWfFD8zYOS=B1<-r6%XIZI01jks!dv7s9_wg3W1afPySdhzLkS%A3um^ zHF2WZqymoZ90E*F!2)3E?HmeBhrnErpW$^h}U0;XT`F!ltdA4u8~n0~=kA+rxKec_h?>gE9%4g$PD%)~Fk zz~99$0t_5IUM8lX&4vOu80$-zSbQrTOH)hD3^I}}D^kqOixW-FlFBUev&}M-a&EVCmgT-rpz$jHjj P%*xnO&&^oZt8GJFzM`ew^)dY@cIa&W;%p z5Ch6Ui!wy&01OOFP!wbdA)$(aAwoie1&K%%?HphL33Y)>5K_X%^nLn2e*fkB_V#A? z_Ga(Dj2rL0BF`9Du=mAh_4Oc59()zNb(6Y&mAsAjY^Tz&hP6tkT(vu^Ua&(j3WN)XiSq9GEqmI=XxNfpoo z<%7i!POjkK7z4-P!O`;@?}CE|pF)8nDJ;Dt>#CBG<5DV+4Q7I?NzHy>N|O!Y_x(&xvoqa)|O_ z$?HpaLWwAutgZ#JaaGa--j<$<7nFEL3eW*nku@X1h)h_7B0Ad=S!#NfI0fh2{~7_} z7zi9iVVk%XFE}gLnpfGvqm? zPdt15{7zES`)7PVg`XLhQx_YLh~L4D^S0mH@KL@w@4&%62KJ8@0w2x!-`4RN^&R@~ z-eY26H)tlt;e3G^G$&HNoE^3%$Vot_W3x=MnzrpmTHFq|<%ACD=*TLxs&|HKWw+(V z#)C?%Sz6s>V}|aUbzwx)J!h+(vTNBvbW)AkTfMPt)vIn%R`Z(`ZZhun3@fVSw|Ty% z$^}*3;&bdSt2gt}c#AHNV51Z*h+C*^X4<)Ne>iGqi^WPyX&DJ#bHee2953vkY=gJj zm1-zG>}<)yoKcIi8eI=bR>W~4T^Kb(rpqH%?K%@94%5|cGP6FARGZCjGTBmkRfVWt zMBDwbRN^90F~#mIR?Nq_?}Bu$9PH=$Nd<3Z+~)66rT3HCAaG(zq!nV_FPmm|8I} zg-5M*rJ3Z1aal9P(oSM+Gvj2Pa^G&RX)Qytild~iay=!KR@|yEjL?JaOvUMnRTOcB z8tm8WhIP3An3(u*aDsso?~i>C4o`k17Cqq!2A+7rkKnaeN$EN7RdF#oL!P%Fflk005wn# A0ssI2 diff --git a/venhapararecomb/notafiscal/__pycache__/admin.cpython-310.pyc b/venhapararecomb/notafiscal/__pycache__/admin.cpython-310.pyc index 3e54a1b3db10174ef6125d713758bfb807f3d627..9189878f33a3ee1fa14fd77d0403a28eca35fdc7 100644 GIT binary patch literal 368 zcmYk0Jx;_h5QXi;c0!b0QBrV$G@A<`gg|V$4V}9X4~tj+iR@5Na}g-Hl3S{!-~d#N zR}>k`pWb+^_r|YQ4Z(W*{(*`T@|BxqmDt?ijn4>06g9+BNhwiso06o<2XHb6NzkkgZnlH3i=qhW)9!STJm_|C9_@JzIN8Ah_Q?vEK!3fHSRNWa3 zZiXaoy@A=MX6NT&tK&GBRNp%V0Y<;;8o5@7!R`HK^llFNF%)Q)g!Kwc3=EsVGeky} zQ6mzI8qMnfdmU#8pCq(-mhpSh57X2;%zHZJ^`|X2(`%})(D%i_b>29x5iPl-ZPC(v G&gmadpjb2j literal 209 zcmd1j<>g`k0*S`gsrEqnF^Gc(44TX@fuanW zjJH@5Q*tx&{4|+v@ug%X=B4NBCFkdr6lEqAfecv5P{abHz{D>P{fzwFRQ;^doSe*5 z{j$`&jKqS(qQs)q{F219%;Mz49DT4=dIgoYIBatBQ%ZAE O?HGZE7lSMkU;qGCa5csN diff --git a/venhapararecomb/notafiscal/__pycache__/admin.cpython-312.pyc b/venhapararecomb/notafiscal/__pycache__/admin.cpython-312.pyc index 04e0acae3683fd1130727623708619d7efd1e084..33fd7abc83bdf75f412e933d158da1bca53e86a1 100644 GIT binary patch delta 46 zcmcc4dX<&?G%qg~0}wR7dbg4L3!`X&vsFxJacWUPx# delta 48 zcmcc0dYzT~G%qg~0}zD2e!G$T3!`|DvsFxJacWU7 C>k$C} diff --git a/venhapararecomb/notafiscal/__pycache__/apps.cpython-310.pyc b/venhapararecomb/notafiscal/__pycache__/apps.cpython-310.pyc index 5ff2c474422caa6fb1ed478281c3e71cb9d8f003..ae5645b86dde59ff3c7d710dfdaec228f0a853b6 100644 GIT binary patch delta 32 mcmX@kJe`?0pO=@50SKC3y-S_9kynI~Ra`%@pkQ(sV<7;Jo(UZQ delta 80 zcmbQve4Lp#pO=@50SF`-U#HI4$ScBV>aL%WpPQIlU16NlNsZZTAW>yUocspaX$cF C9uKep diff --git a/venhapararecomb/notafiscal/__pycache__/models.cpython-310.pyc b/venhapararecomb/notafiscal/__pycache__/models.cpython-310.pyc index 7f974977eb247bddc41f97da8c0dc6e8f7f450f7..f55b6fc75df301f9c3430c61f78c5703a2bde552 100644 GIT binary patch literal 3267 zcma);&u`pB6vyqg*X#9qe<&@5@=NA-7fQk}0SAQIZjy?krjZ&hzF4kjk~;F*+wr<0 z5#mA*TzUqnLMkWJ1OGs;`7eCsloJOINImg=GfviRx*NQjw=-|XZ^myv^WJ3LuA|}k zb?`U;x24`SheO;$|BWa8c-_W(I8Z(%APh%!GcFms*zX?r~ zS$?@qxz!6$;}Je`JKG4{5PM|zBV6OplEn&r#hC}d&1bCTtG5z`xK zHs&6u+Gu0*+Ojl%$gto?dg+YA?}LP=JJZ{TJ*c)GHAD;lrB$RcCNC|)r-eu(9m=DJ z>QqK3|5y+|XuH}?nA?CwlcuBpoG06lG_i#KC+Anf$z&zXrr~y+M`5y}{JA{YD_cR3 zPel-P$XEly()X8U?pUt6H-=7W2SFN+c@UIN5Wqr_P~8oJJ4KjOJut_zCYG+pLMUgIb4KgeO`qYx6FUa99UO^q31Ix}~!LZ>>vj6+grHLMlRRGVoB&tyrjO zycrBJ14!|99ED)bJ9wPNQFieeu85V;OX3_R!B~{Uc!%c|IiFxLTLLGS_-SWp08sgq zm#vW+=XYu5Jdlft^Pyh4f+yjWGr4<$Hu?lkv99>qyQuMI~#rFA94j%NFJ7Bc7E zlA|ixRHFvk-7v`nkp+fA1=3xfM)4RdWilK+4Xp}Gbmk5z3SehtY+~_FJk84<<9Ibp zf=LoaJQuHH$YPSjn`8ylwA9yl;w@#iDOXnZX;r~&Nprz@gQj{HV!x*>{U2mXcU3J| z1)mkXUba_p2vqwcviTkf+Ej4?!tc+mxUz0beHVePcO2OIRbaE%QpN?3 zvf?3@vluZhhaUWqRg@jKYoI0BjzBOggobJsJsA}j%F$)=&p^hW4F*SO$ zwkcJU@Zir}CCMqm*>;w474Ae6ixiaP#0Ml^BXJSp&?Z4y<@p>QB}hT%Sacx}37y$u z=koS3jeh}Re{kff8F7QfK}vj%_k1fY$OXQozTdahw<8V75BH6TPkeI{#<_1FeeEg4 zeG0p8qvRALRZ?{I`VZ{Um=o+#V84Wt`w(^ZSi?7Ya~CurMG|vVZ*o)Kl5E*RRAOyJ zsWw^;??AfDLA%R3k}H>W5w-fPhp5#T9wsP$fmn=G6^1LIs#Xmry1qyxrtu`B^oQ#N z+(|*}!f12d%L;jo8p<(q`V>gVuqu*<4a779Cd3z5BA< zHrox;oot!iQa8Y+yhzIotzs=jNQtThrgl@Hi>f$7Htes|g`k0*S`gsg^+cF^Gc(44TX@fuanW zjJMcw^HWlDiv2X1ZgHk$CFZ5)>!l zMq)u?QDRYQa(-@-Zc<`$c4}S IkWB&%0Ez81hyVZp diff --git a/venhapararecomb/notafiscal/__pycache__/models.cpython-312.pyc b/venhapararecomb/notafiscal/__pycache__/models.cpython-312.pyc index 75604b35074d914af0de3eeef34b2cb80f03cf27..88934e4949a51b30fad3a4e3cf289715a1accb77 100644 GIT binary patch literal 4753 zcmcJTO-vlg6@a_vx95*$W?^DuY}z&uCSJ4J%_=`OvDY3TYkNKR3hXEow5?{kz)gC( z$JH}dK$dn6KETQ31gllFC{h$G6NQ|@?qv@?=E5W+4QgpmIdMrGK@`cSyw^2<;2H2r zNgdu)RloXwU%glJmq;YYL0awnC;3l+8`9h z?dCZb_ft-FKjBmlanA|0#*N?SZkA7b9ZfH2`i{}`IhuaZ6pqpKJDLH|3?8E?IGQ2Q z3?HKzn2#hnc5%`P-gaLz=HbVeHC3WpnZ~j>&QmSy%|T{`BV3wSxwK2=({2|>Jaf*@ zHaFm4*EZbGc~+N(RkqRcsNN0Vb5~W*ulk8F<5Gnuo^)V7kOcU73nGu{qnm0!s^F=q1*b~~VI@|lZ**>JY6U}!M7?V}`Lphl*;MrQ?>M;qAd z0kOh8=5W6brwQmj1tWNHc>J}9K4W21>D9-{OH=nOLanKL<6{$3a|K=3$kZcZJWz59 zRVc}r+3AbZO6HfuP!HEn8D?IY(X5Q3Pq9NB&du9?S+??2mKS1;tsJh_g<#OVFo+_z zBfj-?erbMNII)KlPQl&_vTP_>BFlDAmZ8Ifj`^@GKP)JE^$YZ_ni*N9Xd-qX`9PuL z8qrl6#j+=3-!WHc+m+hIy{B~MhxlxPH69v}t}-y!A_WZ>rI zTQl=H+$Zp*dQX6AJ$=so#xubs+^K~yZkoh)O?u^)E=mcP?b1{`*ti)eo)}||Ss|L` zLJV87hBY$q)T}cgfQ;zrRrQP6&t_MDzLr_<|KmH)-q}uE+7>Tw3zr?cOC>~l0#xZq z6o@`Og#y<`dqLQd13T|rYDAkgZjpHh1K7T66Ul3%WAp-Qi?Dqd~-1R~6_D=NNa=a2fSBjonyR;Sm z`plPS%Fz#tH+RH=#YYu!pd=2gXGCKAKohmkP9Lzs{V*uLu~7_PbS@JO_zX-BIH6)QCH^hnW7iU0vB3gZQ? z>Wr2JWK74g9AuL@7<87qXvtunj+arjSuJnb9V&sQiZ17LB||KF9#sCX!1&o7NHoDF z<8{_!i?|lKv5?lxbg;%XUeF{g2?X+TVzujwp3iz#!)wWPPi1JNG&HjP-JfiWSGI*K z#}Z?QN7+6wKk_5!(+-Tn6~f9thBCc~!ZG<_{2andhut}PdqnW=q9_nk>thfNL?Y7S zcqQCd3iqwQx22TB9~8%S;)BaGmH1#OKKQrzQ1Q-A?ELazC3e0PJHK{wYw+vgFNe#q z8^v3Q$5n>MRfY$SaR3jz;4tld#J@QnZx%i^X+eP4Cdl$OX)%mi1#Hb)fwq15n)+f6 zu2ocGkA62JgGj&}xK% zpDum6Eu5)>+Ih5Vqt~IW?K29vOSX?~k?mvKWBb_N*zOF;*`A!DS+-EykoKTnfi5YE zew^3uKr}#&IezPGDSCE&q8xn}JXYlN;{8hGbSZLrJywpqT^#?mHPLe90<;SDEDlzJ zJ*8mJnoI&T{B`5QU0;=pFk?B3u(?ahUnWJ_dgugCFO80Dg=DFzx*n#6jPv zy3!snd+!|X{h{PUp?LC;(uj6zEidsjy`K>7)_Q(b*a*}kPQ=?ghhg}kL_$!HvCN^g z5v;e3s38ZzF!)jt-;ZOuY=Yc(p;~dB4&(n5F1hVO?{IF>4O1)9e-Mb^an?56rWm;5dEfLU9&wD0F@$jIg)u75Xz! z#sjr}0pg{b=lO5A_%~edzDM9sF2`4Tf8D#!L3Y0@z>n0*kll|5_^XTepH3}J?Q@Xb hk9Y8JQ#^gV^mw0x?7k%OCl_a)>Pz~+ImkMP`d=&o3u*uW delta 1521 zcmZ`(&1)M+6rb5I?U&@0-N;sC$ue=9Y*Qyju_4L9PV3Y$DX0e1LKQ)3yd!Ey^_E$; zpkUgR`e0FtYu+I#{Rp|V2Ma>zv8S9u2owbZ4J!Eq+ENHuJ-2Vxin>+ff&J;t+xJHA z{pR;}=fyj@#DjR;B)HD~@h5wv-ASCLP6fBu2_q%yk&+~lonp%IXhYhiB9M@h8v0)G zWKU_RyHdxic^ZpVBrmq9l=PbJ8ZC3q=WA@4c|M0@(#L~~vuDe11&jyf)eo!HmGXHO zTv_)&fS;sNR>xEJY=mp%ao@mptzK*DLwn-rqH91w9)rvBIb#y{o8+;Tf!p$%&Iay! z3VoTWOkNe|^sEN$78;WX#yIe)H2|)X$Qqu?Oe|c(!mV1&)mvuKUtgMA36__tu%KQr zMT;^%dy{ZW%}%d&T8{q3*W_Dik+@Rvsx6Z9``LL{YMGTT3p|M_plR+*9~!}71Z+2% zz2V*Tzw&>{6&~ga&FraW-(*vt9~4usin<5APwSz2;Zhx({{TrK9kp{+@bO&X4CIZ_Lm^ zc-J@?Pekc~TgKqhDg1|)aeir?&8@Ji$AxD2F#&l2E<(#%!#lcM32&Gm$l$n$7toJS za1jBuXOBSMe1ncd)l56{I1)XaJ#SPTPmYX_))^@!;zQoTF^l^2j!%um86BS%@u58b zmurQ-X)hLuvpt=~kzWIKo~W6w)zV*I^B8B#K97l3#SHQj2)`ACbrQa@uhB8c#xuix zQJTd|p+cS!Fb(g-&rBRh;u#SmK!`UGB100Bqi{cdQxR^VJ^C~JEguI?U(%Q?J}L04 zISOAW3Ah_8oHn`&u{|^FzzRFC-8esjC%6($nLN8N$1jAtmNHvhxX9;Wz&U}c`QCmN zK68#|!=6$Y(HX4&v;<8jO*8PjGd3SeC9FD>iq4*KbYP33h_I5QXap+=o8+kkmy%cL z5xAF}IFuIwp_;;T!}uK7{X_3B;v4Z<4K5)(l_{l9Na_h0ZYwHHf0?>IyffS;Xton7 yo%(k_)lO)1X6xd2&8fm5OLmz^|YTH$%rqW7nwGWN7eXwOCqfx3|Y4;^h8$tRK?Zf{68IQ*{ z6P9eHRof%@eCAyKnK}RWU(T7oIvk}8l-u@y2?v}E^AEgGi#c1_x&f6HhG%#-!bDj= z%VOOSF+`1iBh-z&DPoG6{pP5}Z;4v{)+p!aq9y(k=rj9Ed5ho1Tm5#P^E>zwe;Hru zFXwIkJ-pq&*T9T0yyFJLmkI1$qjEpLleU&a>z=$;*WzA}^C1rLurfC(h|*wC6rgS; z!c~EY!b2AO%yQ{)oWz8Xz{iPP>WfRk;jkDAMr7+?BrL=vLADIUBZ3r{Id6;?h!Bb| zm1|S#QL5avQmrjBb7g8>`(3l$H7Qqc@7$Y6 zHR_06-@8_w0r#Qyqh2e&YxcagD_8rZdbPIe`@E>mkQ&t*-0^v}uKlh#RO^8^bE)l% zjHk@EYLHE_cvO&0q1gP~6K-N5n58c;_la#F7$zi6Tb|ek!+ekzly1Z1>oTX3`+I!L z@!((nAS#_DYRAb{PA-kaFOwi2Um$VW5?hE0_&Y=8%9aonDOW6J-*?<=n#w@9UdL*hewbNu~||=?=UcS);l>CxX^zVnk%zcL;aKefeT*W z;HYv3%M5jEtE_Aig~+UkE~5U)_+Z!cc@g~M^!Z`$>(g@!5xD6ztjv|*e2@gu{Y7V* zXM&-(VTp^|r*YMkMVppDgJR44qHGog>HPeXtH2?(&_?9C_$|P7=0Qzkrshbp=18Wd zJz3NK=elpNC2HDJHG!L^-;_V7uFq5-N>(4rRJSIpTkmz<7ZTIqjZW`dVZX0021gZCtoFG5FXxRCPVN;P9iiRbRtl1Q>+I!UEe%+ zrYYi}jw191?g!ywH$b5#s%}?h+$~9WOS-Ku&GqN2f_60}-A#8U{}@;etaGpIppLh| z8h)JW(6fqXvR*qZT2Ya5iH4@uXOfvqeKf%^U#C@*zsM-GDN$&10%p<>N;om$tm^5&;Or!Ct+}=1@xuo>vKL> z9mg!FCln80TOY{t+6@mJrV%Ahp)+ot_ zMw%CONK-Thc`5n<3OTdy_C7t%{Lb~^!R%Nc{rI11Y*Ic5D3Vnfj~6QFGR3z4+JpiDLteQU(t&&f-s737GRa3 zVrbYSXonPV!A10(H<(QWXMT^}tT34S*iFu0KDEi2%)MK7qq$p|iIYO`pDS6dGg|}D zwA+0jZ-Lz($6EnQcn+|XF9EbImU?Wm{X$sy)g**u+y(20#kc6aq})U3ax}NK%MD|+ zeB{4v2VsL@@DbdJc`P)iCT&nBM-gZ`K{E-xFh&=D$(jEWN(zY#6zc$XOd;Pd-@y;u zf!Q?vz;AJxLr+muq}&?ttZJX??|Up*73SwfWtr6r?7X4Cnr%gs;BuMejoKJkKa)>3 zhhcN`&cplAy;Mr;Emx#yWYq#26S_l?jh6+9n4q8fd)WqiDQQ6rgy2X(b}HH2q!68t zz$ONAeSXzIPQhTABZ4>|kBNea-l@J`N#x3@{nGmct^$dcY74Yb)Qh?lF#!albycl& z-|AlJz192ii907!4ecpc$4ySN$Z92#yCbH#cG_B(s~Mb1GnzdccmJRr(7p?v-GX1Q!H>1 zxc#Levz~^`AL1gwJajT#?evHmkWL_+bHFnc6)AUC!W+QA(2Ew8S#~XFJ~3%=5RMtRCtqSelV}9s2eVq4ZK+!114(mk;Bjq=MjPw3`aooxW^8X%UJ@H<=QC& zJa)RF&vS)ZGXDn1A(s%)nq@0DP*WD&we2I_ffx14+k$^vmAF#D&a6FgX!SI1Z#7GdB%|X5M{o=1buV z;ockRhT)WJWEY%E9PV1@lt8FYx_`ry{IFxnpEBuyP-cx#a1bp3p$HFa@~{Q0(PP`0 zJ#csyhfEFWLuL_%5Ga2xLrtG9*}LpOm;4d^COJ!1!WRqo zuB01BQm)gwgjwg>e@5{@2>{t0Qr0IpsV7(4c8UyDT4Yd%D|%|&Zq@}t>8N4URUg$= zq22bT8oE=i9^K_H49|(fr*w~3a{H>ET0XUxE|YdrC1iC{xvhOCz0_!WK~eO3k{~Lo zIrtRS6c2nAwS(qVlsqMxPNf=pQ?9;Usb^rF8{BR#xfuQ@kpI7?yWmJsPEpZ|=n#2x z$!#w3VsfmTLMFt=Cf&qpbji}5zd;&gH_ z;8N}jS&mDX#pz~abJh9Ml{)Vz$k57sadl?W(=;2eS{&ZGumA3`kx?%>G*02$IY z%95n$1W{sip#Ub7+q8BP3t3$si?-?o<{thuSUK(^YxjpUP(8;mU2z( z$ao(l!RPSZeF$R+eF(om2qIiTh$74*hzM5^77@?@smoIiVJ7er0gtOhJXyd)7}oq2 zyJ<0+J2y+= z=2{j=L{zeK3!EDXaDg6DNy>1iLqEwW-vIGJl#eBySSw;l7q-!}v^`kEI~Tpz6Rt-& znmR?^gI@3ljCda4k&$KD@0j}Un7Y3)-gU#g4w%K{v0;E1PzZ(wQTnXryn!$^Y~OV+wno?_YC~d_x}&QG?$nF literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/__pycache__/urls.cpython-310.pyc b/venhapararecomb/notafiscal/__pycache__/urls.cpython-310.pyc index f690233d8575a8fc7f1c58eb68cbe0ed8f70114c..e133bee5ec0bb18de044719cf16fca88cff2932c 100644 GIT binary patch literal 621 zcmZXRy-ve06ou_3X_Mv$N}(X}1YMdPRTWRb!q%mVdYzKWaVjU}Co3}&ufZ#2Whw(R zV&dM`RV!gDNB7IIk1gLK47&`+>({r)Ta0}Y9FG9u7QgZx1sHJ2az5ppK?^L|%B`uz znc!dxYiWZ6?KcalgXDl~$U|yF*N~6Yfxu9RH6}C7DF0?jIW z(!y=pp6e@9{f~)Ej9G9u3>zPoiCPq+wU(vEb~5dd*d%Qdm&7BXwrih+TC78o2&M6H zGrndev?@QC?vX+Adl@IIRji6CNwadE$e2zUtzH^;oENZ`VnXj<4p0IX@W_hz@pOOw E0MNs#mH+?% delta 170 zcmaFMvYJUdpO=@50SFjdUZ>^&>Bk@rGGGOA9Dul3Z=$v)S2|-9YYKZXgC@ts13Jup znrxHLF)I4s;w~-9DM&0SNiE7NUdd1dG7(Jta@Wtu&rQ|OD$U8sOw}(-&C5tENGwV$ kN=?qsP0~$DOwLZtOFV!Z diff --git a/venhapararecomb/notafiscal/__pycache__/urls.cpython-312.pyc b/venhapararecomb/notafiscal/__pycache__/urls.cpython-312.pyc index c25b7fade855b0e4079942c50741d26acdfc9989..6f1d87f71a1da075e1dad36eea1dfe62fda9f430 100644 GIT binary patch literal 1026 zcmZvazi-n(6vxl;IklTOX_6*FElLIyXa*W(qoryq5M4n05XwLrskpgI>(q9lv(wTr zA(k*vriO{YLJWOl3et-8%KoO_a#whOghd_qp#oo!?Jco&Az#%{YaT?IM0>=U5L%inG`2x=YAHW=fn6HR~gTpTpe)zxhSGmhg zP|oc*WLShm4<}J>(0>F)lO8TWxzGsE4^hy=$&{NK!-YItm~zoE+?0olP;Pn*7xi#4 z$|c5d(?f1cECl!CnZzl>GMoczinV=8pPVJau8Q|e2RMRiApDAz4MoQdXq3&YBWkK? zZP2h0G|Jf})vy*-w48M$ge^tYXr&PwEg-C63%hj|u)18X5(AeosuD~cBd+7U^DOCSfB){7eKU z6HFu~Y?erX37ZxoGhy>U!c?39JxpKI!o)DYfpfYAE}q<9Eapv2%wm4+!SiCJuF>lj zcd@ap)D)r+T&n7uw>Op24mOZ?zi3n~rL3AIMJuw4&DZuX#3j9o>Ka}qaq7?hoB4&x z8P9Rt3Ala&V*mU=kebnE{{8y9_12yZZ~cN|GjR|lrrJlTqWN_|Wny|&?9 zns=mRTlgCO96sK$;XMYVTIt?Qt~-oNa)S2bmvw&YcFhAVA$*d?j{ziJ8S!{CR2mHko-PR(WahnJISqx41#_5a}F0O^(U4m=qmvapYtcm&E6# z72o1aNi9jt%mK1*ahDe56eO0Eq!#5BuVnZPvh!DDCJV;}PN^BL^ZjS~Z_vHM;_!i;m7l4RyGQ`2 F4ge4gM#TUC diff --git a/venhapararecomb/notafiscal/__pycache__/views.cpython-310.pyc b/venhapararecomb/notafiscal/__pycache__/views.cpython-310.pyc index b3ec8957668f897e541329b86850a146243f06cf..c4e8ead231bc5a57cbbb47c55c352473887e9aa0 100644 GIT binary patch literal 6820 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 F;om^+Y|{V$ literal 593 zcmZ8ey>8S%5Z)iJeVB^`K`AIGDU5{u0tg{NB9KssbXT2(kmH@4ecAP1cGpQjzA7|y zJVH|Danf!}g?Ixh#zsOX#+pwv-;TcdvDw*43EJKFU+|3*@?%K0jbZW%-91B)L{ddG zT~Ip2Ofk(Fp+rXufee??SF(sDn~_ZX#Cnp^5L;*^*ux6d|CzvuqrXOXbA+C(Q2UhG zr=Ci7h5E=a$sdyq_53>O=?&emo?VL@vf-Zge5~Pb$j4+8VIHmGfjN8Plb*=vYMkLP zL`NTH^AJPpt?9z#QmaoVje;*}gF{{Bwbv?}gjj>GjSOOKo7M+$@b3NoEHJ=uU0Mer zSpo_eAGj}%TfC7y@Z;5?~Z@=Fbwb4+lI;9#Y&Y`VK z)GaMkMjt;vE~`_#(f@qW8eg6?t}0b=-oS;+*PnwJ=N=lmU4)cQSV|GcZ%R{UA0eG3 z;elM0?b76~Hr7|2cjMGy4=<48E&%!d-x=q_*kYu@{VmSkL!nV^++hob#$ob88`&v% OIs8@^BTUIIo$^0`HJNY# diff --git a/venhapararecomb/notafiscal/__pycache__/views.cpython-312.pyc b/venhapararecomb/notafiscal/__pycache__/views.cpython-312.pyc index 267b623e7b73996163d6134d09e4beece72131ab..07e486bdf827d941a9a524598fc95bb92280ec98 100644 GIT binary patch literal 10972 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 delta 2656 zcmZ8jO>7&-72eq&F3BaAOYu({ zclG0BDJn&Q27wL|<{%#gG(H5eVI2(QkQ68iqbH*|goF^tS@@s=zP3=Lo`Rz2n_bef zIso6B@BPipoA-A3a_S$a#c#b{Hw7bk^iO5bw<*@6o15K3QSJ}aO|R?#D#|=ipX>xG z-KXQOO>?q7g@{je5Pt@KN6%QCMCs$R17QdNI}t@`_``Z}U-FV-2ZPdtVz>#Uvo znCAt9%R2D~bf7B$RGi8xWI~6-_sp)IwTqCc*$AL43*mR+s4oZ$(v7g+x{>xqUuh7Qq zdnCLd^hfr6{e+Hd7%Q`5M-Z1f(E%P1SRL?tpj%XiDk6i*Qc&sv54wAbf?HJ|%Cv#|Iz#xC zH^C}0X933&QBC7n@oN;q_fR0l?6_<91$9r$LIcExYySeS-Jyr^GpX6OEIDKk(aByy zjT#b9Am0fjok0E*sO|&`oIpW>c0y08m0#rbdWyn-lcM;~VsO|YhpX0nl}8Ad>$hox z-)VS45(8rfE~4m!rslGZw&YEkZ6>F0bJos|sP!+QR%yAB#DeqpfVW$3dE@+UIclxv zmYXcj?KIcc0`Jo-rIT8-hTKw%J3;9kHK{?#F$2|npc`68O?G^2V$yV~N>Wa&%;!{C zmNK0%OUOw*Y4TcfNlE0>P|I`pe|6nnsw1XRLYjyvZTnht#*&*( zSxF}sbGl~xlEOc(`8abtH-&sbPbShCEtSlf95kM?@{!wOXYc6qxp559e*eXwm)s9S3mQ`}ODoY5tu()9Is&a3U^eLYz>5B29H>@RDi4<_1< z)wM4~X>E9)7yr2W$?AjfE+2b=e+&*V``$1<9g3k>_*!VNqwvo^?O(sSHk)r)MjJsd7#$ z>#LPq>42i%qeti;DQX^Fr2$RQHwn8%D?~U!rwN*)3pQE+RHE+F7a8Kn{DuLW`}8$} zt}|0MnkFd0qzRj2?h#>vQ3=wRk8NZSG{}yyz^<~BESL+P>RhGc9&fw z!W6qiP-z)nO$)9PIKqu{z&_w^aUdMwW(c~?&DrP-*< zsdGbkaN~tkwr#B!GVW@8#!NTJab4P?+V&*yp+OQ;-0j%*;P!dmq}d>lbV8(g0i!!&2;86nht%esULzAo>WRZ z3uKMjcY5*TXpf^GP>RM5Tl52ya(1lY_$J#I?&r`S2U5>u>=*F(lUuOGNa=N%5 zXX95;2mUJF*>8O#>>eZuv6gsDS$5X?KRMr>FUX5I diff --git a/venhapararecomb/notafiscal/migrations/__pycache__/0001_initial.cpython-310.pyc b/venhapararecomb/notafiscal/migrations/__pycache__/0001_initial.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..de66abe056efb93f7534bc6b7783d5c5211d4297 GIT binary patch literal 1755 zcma)7NpIUm6y_$1q82N*lP2Alq^*)xcGC7%6mjG@ND3PPl9MjPnD2=mmEtf%%BX!! zul^71vHzgIq=&ioq#k-LkS^$(AuZd14<*6jeDmggZ{<*QyP-wb%isUNU)q-Sn+E4E zkHCF;iXjbPft^}oo8C_9%-pd%^TwWSJ+i&_Md+a9G*u%!u2M1hiP6M#%_Mid&i8pbe zNoy?#pmkys3Jq%4sAEvKM!gGY#h`vIyJFC4jn*#gTsP=yB}-ax?Zh$uym6^N*Uj!z ze{LA`CVBkUi8FB$cd7mM|ImKNXuk{ZB@Vm~A7}>n@FF98L^#Cuv@>l^yVD-rgj>c^ zV`=H*OD%n3c)F*a!KZ{*U;ww_jGh!xZP+wCcd_~7m7gr~ z{N8JfUz}%58sk;?lDg(A)!IGnmgg#Xm;p+Rg>pFTDChC^z*8MIFGUnfWF>-X=aSEu zJc_=47?DyRiP%%xZWwb{U?u4LawDP~D|p!{q;LlWt) zLHYZPO9J-{h&eDo1w(ieAiFs*6Xc$unM3H>nO_uJc7kD8Hry+9T6`yZSJbu8yqp zfG1njm^-@Wsx>-bvYP7ZBTuq#sXu*~vMix)hJ6*7oYSF5HQ#zR+S-1oR(4r-^jzq% z((PMaxZ=A)tadz}>Y;JDejp~?&`H|F()1;@^ zry;OBhi=cY*PWhy@pk_7{`Gp5q;EU_5DF@^Zujl$w(}RQgnFf4;lByDDjaG#;ow(e zZ{VvNRSt%*Kdk-*!_!2_EpkM)mU5G7lU<{G7G^bjqIU;hSJnH5ej8Td>qy9pYwmyA Cdi+=b literal 0 HcmV?d00001 diff --git a/venhapararecomb/notafiscal/migrations/__pycache__/0001_initial.cpython-312.pyc b/venhapararecomb/notafiscal/migrations/__pycache__/0001_initial.cpython-312.pyc index b47e0ef281958d5f044660eea10fab0a5a0523ef..d57277b3ccaa636f27877c670127105d996cd9a2 100644 GIT binary patch delta 1600 zcmbu7PfR0K9LGDQ|EAD(%D-*5^baipU8F2jS<6=4wM!FNK!Vf*!ZyRaM|WU4!%kaV z@IZ_gjWOBHTpCZDObm^3>|R{r$;8W>WU@o%VDwlIhGaD{o_sUyO5y4pUf%Eb`~E)P z-+S|Z=>2lQ{jQ zKW?S)Pngo-w~|-kuP6oUTKE1N@i#Scku8XHnHBg|%`wXZC_+Y%URdrNIynJXfKU;I z2EgDrp*f56<2(oXLiwR)<10moOZqd>Y@0MI;$X@M7#7d~YBpFZntt=2aZ@@Ism1VoMCoC1C4*FqjnhJitf5uI93!IhU|1Yp66A3$Q!8#WMKx zqUKre7~Ca7jxIys%nv(p)nl?_tB{)+y}5=5r{0 zYkG;jP5*3WX4Z2hD3;c9+1U@)w<{bzkL0s&m@^&H$M!H0kOs-fVGxBUs(Wg9LJm*V zlS=qqMBO>_`cYu4I;{rAQ**AJ}SMg2X zM%1k{?=|F)SNm0eT=vILRuunRh)SJ#11LCN{ZI{#%faz_w-QVv>h1F$XRrHDtBZ7= z4@h6wR~)An#XpOvtn{0G`EU@$l1I~OEGfs5^#^Ei1En9J9ZrcA5yhW*2T&+c-BLpd zIh3eJPgj-DJfiL!MhV?0AqNxn{^$N@el;~Gr{>huikwmsaf_!#ej?WI2Vv=u=VbXJc4t^+6V`?fCpqs`C#&$WxW-s*0; zCR+X681z(nTl$OrQy2e3*SvA^uXh}ER}}6>*87tE#J8vwP1V+ru|(tyG7XrA0GarW zcx7HNP#HD=?IXz%xvV~1)}c|f?-LS1Q?cH8_Nlw)0L-Mbw=HN|+0vS>YuQ<7t=MQ4fA-zuFY&jqN8T{#?NmKd@Df8>q diff --git a/venhapararecomb/notafiscal/migrations/__pycache__/__init__.cpython-310.pyc b/venhapararecomb/notafiscal/migrations/__pycache__/__init__.cpython-310.pyc index b54e270db5ffda517eebcdcb37843bb9d45b421e..0fa3941308c9c3bd0b505b43bdf45efab8df8ea2 100644 GIT binary patch delta 28 icmdnY*v!bC&&$ij00hmi-c97TVO7&lEGU>*V-5gi6bI=5 delta 76 zcmZo>+|0#oL!P%Fflj>06JF> AE&u=k diff --git a/venhapararecomb/notafiscal/tests.py b/venhapararecomb/notafiscal/tests.py index b4abefe..5b61083 100644 --- a/venhapararecomb/notafiscal/tests.py +++ b/venhapararecomb/notafiscal/tests.py @@ -2,40 +2,49 @@ from django.urls import reverse from .models import Fornecedor, NotaFiscal, Cliente, Boleto, Endereco +FORNECEDOR_NOME = 'Fornecedor Test' +FORNECEDOR_CNPJ = '12345678901234' +NF_IDENTIFICADOR = 'NF001' +CLIENTE_NOME = 'Cliente Test' +CLIENTE_TIPO_DOCUMENTO = 'CPF' +CLIENTE_DOCUMENTO = '12345678901' +BOLETO_VALOR = 100.00 +BOLETO_DATA_VENCIMENTO = '2024-01-01' + class ModelTestCase(TestCase): def setUp(self): - self.fornecedor = Fornecedor.objects.create(nome='Fornecedor Test', cnpj='12345678901234') + self.fornecedor = Fornecedor.objects.create(nome=FORNECEDOR_NOME, cnpj=FORNECEDOR_CNPJ) self.endereco = Endereco.objects.create(logradouro='Rua Test', numero='123', bairro='Bairro Test', cidade='Cidade Test', estado='TS', cep='12345678', pais='País Test', telefone='123456789') - self.cliente = Cliente.objects.create(nome='Cliente Test', tipo_documento='CPF', documento='12345678901', + self.cliente = Cliente.objects.create(nome=CLIENTE_NOME, tipo_documento=CLIENTE_TIPO_DOCUMENTO, documento=CLIENTE_DOCUMENTO, endereco=self.endereco) - self.nf = NotaFiscal.objects.create(identificador='NF001', fornecedor=self.fornecedor) - self.boleto = Boleto.objects.create(valor=100.00, data_vencimento='2024-12-31', nota_fiscal=self.nf) + self.nf = NotaFiscal.objects.create(identificador=NF_IDENTIFICADOR, fornecedor=self.fornecedor) + self.boleto = Boleto.objects.create(valor=BOLETO_VALOR, data_vencimento=BOLETO_DATA_VENCIMENTO, nota_fiscal=self.nf) def test_fornecedor_creation(self): - self.assertEqual(self.fornecedor.nome, 'Fornecedor Test') - self.assertEqual(self.fornecedor.cnpj, '12345678901234') + self.assertEqual(self.fornecedor.nome, FORNECEDOR_NOME) + self.assertEqual(self.fornecedor.cnpj, FORNECEDOR_CNPJ) def test_nota_fiscal_creation(self): - self.assertEqual(self.nf.identificador, 'NF001') + self.assertEqual(self.nf.identificador, NF_IDENTIFICADOR) self.assertEqual(self.nf.fornecedor, self.fornecedor) def test_cliente_creation(self): - self.assertEqual(self.cliente.nome, 'Cliente Test') - self.assertEqual(self.cliente.tipo_documento, 'CPF') - self.assertEqual(self.cliente.documento, '12345678901') + self.assertEqual(self.cliente.nome, CLIENTE_NOME) + self.assertEqual(self.cliente.tipo_documento, CLIENTE_TIPO_DOCUMENTO) + self.assertEqual(self.cliente.documento, CLIENTE_DOCUMENTO) self.assertEqual(self.cliente.endereco, self.endereco) def test_boleto_creation(self): - self.assertEqual(self.boleto.valor, 100.00) - self.assertEqual(str(self.boleto.data_vencimento), '2024-12-31') + self.assertEqual(self.boleto.valor, BOLETO_VALOR) + self.assertEqual(str(self.boleto.data_vencimento), BOLETO_DATA_VENCIMENTO) self.assertEqual(self.boleto.nota_fiscal, self.nf) class ViewTestCase(TestCase): def setUp(self) : - self.fornecedor = Fornecedor.objects.create(nome='Fornecedor Test', cnpj='12345678901234') + self.fornecedor = Fornecedor.objects.create(nome=FORNECEDOR_NOME, cnpj=FORNECEDOR_CNPJ) def test_index_view(self): response = self.client.get(reverse('index')) @@ -48,13 +57,13 @@ def test_list_nfs_view(self): self.assertTemplateUsed(response, 'list_nfs.html') def test_detail_nf_view(self): - nf = NotaFiscal.objects.create(identificador='NF002', fornecedor=self.fornecedor) + nf = NotaFiscal.objects.create(identificador=NF_IDENTIFICADOR, fornecedor=self.fornecedor) response = self.client.get(reverse('detail_nf', args=(nf.id,))) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'detail_nf.html') def test_delete_nf_view(self): - nf = NotaFiscal.objects.create(identificador='NF003', fornecedor=self.fornecedor) + nf = NotaFiscal.objects.create(identificador=NF_IDENTIFICADOR, fornecedor=self.fornecedor) response = self.client.post(reverse('delete_nf', args=(nf.id,))) self.assertEqual(response.status_code, 302) @@ -73,7 +82,7 @@ def test_delete_fornecedor_view(self): self.assertEqual(response.status_code, 302) def test_delete_cliente_view(self): - cliente = Cliente.objects.create(nome='Cliente Test', tipo_documento='CPF', documento='12345678901', + cliente = Cliente.objects.create(nome=CLIENTE_NOME, tipo_documento=CLIENTE_TIPO_DOCUMENTO, documento=CLIENTE_DOCUMENTO, endereco=Endereco.objects.create(logradouro='Rua Test', numero='123', bairro='Bairro Test', cidade='Cidade Test', estado='TS', cep='12345678', pais='País Test', telefone='123456789')) diff --git a/venhapararecomb/notafiscal/views.py b/venhapararecomb/notafiscal/views.py index c9096c2..6ec4fa7 100644 --- a/venhapararecomb/notafiscal/views.py +++ b/venhapararecomb/notafiscal/views.py @@ -213,6 +213,10 @@ def delete_cliente(request, id): """ try: cliente = Cliente.objects.get(id=id) + # deletar todas as notas fiscais relacionadas ao cliente + notas = cliente.notas_fiscais.all() + for nota in notas: + nota.delete() cliente.delete() except Cliente.DoesNotExist: pass diff --git a/venhapararecomb/requirements.txt b/venhapararecomb/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..c4805a2d13b8a99a70ba7fd4a1c43bea9c7754e2 GIT binary patch literal 130 zcmW-ZI|_h66a%Lgyo%_mSlM}z1wSa_cPkICW*=dyN%Fm(n~9l=fss}z$!LTlC81-% nv#GP2tz~jin!Pz$In=oHGgu?q%82{GLoXjhe0N$q^MyV9w=WZL literal 0 HcmV?d00001 diff --git a/venhapararecomb/templates/list_clientes.html b/venhapararecomb/templates/list_clientes.html index f206de8..7766ae3 100644 --- a/venhapararecomb/templates/list_clientes.html +++ b/venhapararecomb/templates/list_clientes.html @@ -8,6 +8,10 @@

        Clientes

        + + {% if clientes %}
          diff --git a/venhapararecomb/venhapararecomb/__pycache__/__init__.cpython-310.pyc b/venhapararecomb/venhapararecomb/__pycache__/__init__.cpython-310.pyc index 37936d4d86976cbc77cb6641b4c94984e2ce1537..57b4c59d9b313b2f8e3d088172c516c39fa9e5ab 100644 GIT binary patch delta 27 hcmZ3>Sj(Ny%ge<81kJDBP2{#=RnSi?D41Ad2moSL2hacj delta 75 zcmb#oL!P%Fflj{05_Qr A761SM diff --git a/venhapararecomb/venhapararecomb/__pycache__/settings.cpython-310.pyc b/venhapararecomb/venhapararecomb/__pycache__/settings.cpython-310.pyc index f17795a5fb75964e5562c5dc254a54af66400583..57107b60284869f11087d677c18d90b6740afaa5 100644 GIT binary patch delta 433 zcmYjNKWh|G5Pvf}x9{C%Z|`m|e=fNLEus)a?lYvZk`M@3OtY-cbKPT;T{ovi8j*a0 zux-F3h1iLt5d0u14y*+WON$`JcUL*X{Qk@g49ti4a~zeOPM}}oY zTw(^&lEpl{f*hoCP8o1dBJN99dTysbQnDMLV-6h4Kvvz-K-QMHzQm0jGU9;@c~v%f z&7EF%wIN$Plo4-=cc6C0Uv8cN>@{Qj4t#x!Ujf^*>reC=N7d}{^ZKN}duZ$YMLIc1 z%Va-&Q8 Uf&Mxjx*q*kziB|YOyBtb05?WzcK`qY delta 424 zcmZ8cyGjF55WRDEcJI3G=4pJzP7p*w@Cz&i3kwl^6t@Y{xh5MoiNr@Cf`~t$Y#UHh z*os83_YZ6r`~mG1MAXqroMFzH#~FsX$z9}9?I7?3+uO;DdGOCu6UWzFkU!!*7kri-`F z3lPuBCrJ8f>mK@#SeL$OmG*ZNYi)J@P{pfi%37KpiI3E1(XCXr!pKxAiRzf$c64A8 zXQ$dRt-U1ftM$0xp3P12`<)+nUoO|%O;c{{M^R|X2c}i8vY6$Y?dC>lqq@0mTJ*mk z-?=kOi@c7)_cInMv{1UX>!Bx6f&^E}FZ{qS%t$4{0sQ1V;2!>oSIi^J*&WyZ28#x4 AmH+?% diff --git a/venhapararecomb/venhapararecomb/__pycache__/settings.cpython-312.pyc b/venhapararecomb/venhapararecomb/__pycache__/settings.cpython-312.pyc index ff7fd7a5c08bf0cb9f75411f6f4cebfb5f4b7254..4e944641d0331ce9ff31d14d218576a3c9659d5d 100644 GIT binary patch delta 193 zcmZn{TPn(TnwOW00SKC3y-R)0H<3?*QEQ{RIwMDlbd+Qzv!=}E35@=1N(CjlNkvtH zj=8BtnaPRz!HN0t0g0tK`BfbH#U+U)naTQ-f3qtvN^O?m5N4e0$SExv;cOKXTAW%` z924s18XS{Vnv;{6I=PtBpGym98zT@GOHMw+>B9MejX_Yjf%g-~WO1%wMwQ9gT+)mZ pliRtR73CW^A8_+Ga6I7TZD9Mr!@wuezy+klOfNDB6=?uX002cSHIx7V delta 271 zcmZ1~+AhX-nwOW00SLZtd6T-1cOstzW6DN#b;gOibVa3CGl66n7}6P|BvWLfq$-&; zWjBX0`m@QT=INFe-(n68ajxRfFD^+e$xPP2#Rg$aKF+SdD82awyD+1mKyZj-h^Mog zr;lrJyo+a0@Z?_{GU8FrRxzQ)sYS&xS*1BSnK3S@#n~nK1(UTo{ke33_Avr+vGL>< zP8aqE0zwVEpSUJpvVes*pO=@50SKC3y-Qubk@qGetBihPLBV8cCQ|^K4GE3_ delta 80 zcmZ3$a)E_6pO=@50SMGIlU16NlNsZZTAW>yUocsPsTTl8 Cc@Fsi From d3125fc2ddbdaad251c2233db6e8b03d98a90196 Mon Sep 17 00:00:00 2001 From: Jullie Quadros <109080878+jcquadros@users.noreply.github.com> Date: Mon, 11 Mar 2024 11:34:32 -0300 Subject: [PATCH 7/8] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 523a946..942391e 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ 7. **Listagem de Fornecedores**: A view list_fornecedores lista todos os fornecedores cadastrados no sistema. 8. **Exclusão de Fornecedores**: A view delete_fornecedor permite excluir um fornecedor do banco de dados. Ao excluir um fornecedor do banco de dados as notas fiscais associadas também são apagadas. 9. **Listagem de Clientes**: A view list_clientes lista todos os clientes cadastrados no sistema. -10. **Exclusão de Clientes**: A view delete_cliente permite excluir um cliente do banco de dados. Ao apagar um cliente, as notas fiscais relacionadas não são apagadas. +10. **Exclusão de Clientes**: A view delete_cliente permite excluir um cliente do banco de dados. Ao apagar um cliente, as notas fiscais relacionadas são apagadas. ### Como Executar a Aplicação 1. Clone o repositório do projeto: @@ -48,4 +48,4 @@ - Padrão de programação Django MTV (Model, Template, View) - Uso de banco de dados: A aplicação utiliza o Sqlite3 como serviço de banco de dados local. - Implementação de Testes Unitários: Os testes cobrem as principais funções da aplicação, incluindo as views e os modelos do Django. -- Uso de docker. \ No newline at end of file +- Uso de docker. From 13bfc2a197ee2f20bb0b83acca3990ce6bc37bdb Mon Sep 17 00:00:00 2001 From: Jullie Quadros <109080878+jcquadros@users.noreply.github.com> Date: Mon, 11 Mar 2024 11:37:03 -0300 Subject: [PATCH 8/8] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 942391e..833749f 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ ``` git clone https://github.com/jcquadros/venhapararecomb-backend.git ``` -2. Execute: +2. Certifique-se de estar dentro do diretorio venhapararecomb/ Execute: ``` docker-compose build docker-compose up