From 21978f74206cffbdc64a617a0f902846d49bb33b Mon Sep 17 00:00:00 2001 From: Francisco_Borja Date: Sun, 15 Dec 2024 20:41:05 -0600 Subject: [PATCH] first commit --- .gitignore | 1 + Inventario/__init__.py | 0 .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 167 bytes Inventario/__pycache__/admin.cpython-313.pyc | Bin 0 -> 211 bytes Inventario/__pycache__/apps.cpython-313.pyc | Bin 0 -> 539 bytes Inventario/__pycache__/forms.cpython-313.pyc | Bin 0 -> 8538 bytes Inventario/__pycache__/models.cpython-313.pyc | Bin 0 -> 4781 bytes Inventario/__pycache__/views.cpython-313.pyc | Bin 0 -> 15392 bytes .../__pycache__/viewspdf.cpython-313.pyc | Bin 0 -> 3891 bytes Inventario/admin.py | 3 + Inventario/apps.py | 6 + Inventario/forms.py | 99 +++++ Inventario/migrations/0001_initial.py | 76 ++++ ...iento_inventario_observaciones_and_more.py | 138 +++++++ ...rticulo_codigo_articulo_articulo_medida.py | 22 ++ Inventario/migrations/__init__.py | 0 .../__pycache__/0001_initial.cpython-313.pyc | Bin 0 -> 4073 bytes ...rio_observaciones_and_more.cpython-313.pyc | Bin 0 -> 4612 bytes ...o_articulo_articulo_medida.cpython-313.pyc | Bin 0 -> 998 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 178 bytes Inventario/models.py | 58 +++ Inventario/templates/Base.html | 105 ++++++ Inventario/templates/articulo_nuevo.html | 51 +++ Inventario/templates/articulo_registro.html | 44 +++ Inventario/templates/articulo_update.html | 29 ++ Inventario/templates/bodega_nuevo.html | 51 +++ Inventario/templates/bodega_registro.html | 60 ++++ Inventario/templates/bodega_update.html | 43 +++ Inventario/templates/grafico_chartjs.html | 36 ++ Inventario/templates/index.html | 181 ++++++++++ Inventario/templates/inventario_nuevo.html | 52 +++ Inventario/templates/inventario_registro.html | 45 +++ .../templates/mov_inventario_registro.html | 41 +++ Inventario/templates/pdf.html | 36 ++ Inventario/templates/proveedor_nuevo.html | 56 +++ Inventario/templates/proveedor_registro.html | 56 +++ Inventario/templates/proveedor_update.html | 43 +++ Inventario/templates/signin.html | 28 ++ Inventario/templates/tipo_articulo_nuevo.html | 44 +++ .../templates/tipo_articulo_registro.html | 51 +++ .../templates/tipo_articulo_update.html | 43 +++ Inventario/tests.py | 3 + Inventario/views.py | 338 ++++++++++++++++++ Inventario/viewspdf.py | 83 +++++ TiendAlfa/__init__.py | 2 + .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 254 bytes .../__pycache__/settings.cpython-313.pyc | Bin 0 -> 2688 bytes TiendAlfa/__pycache__/urls.cpython-313.pyc | Bin 0 -> 3099 bytes TiendAlfa/__pycache__/wsgi.cpython-313.pyc | Bin 0 -> 658 bytes TiendAlfa/asgi.py | 16 + TiendAlfa/settings.py | 132 +++++++ TiendAlfa/urls.py | 54 +++ TiendAlfa/wsgi.py | 16 + manage.py | 22 ++ 54 files changed, 2164 insertions(+) create mode 100644 .gitignore create mode 100644 Inventario/__init__.py create mode 100644 Inventario/__pycache__/__init__.cpython-313.pyc create mode 100644 Inventario/__pycache__/admin.cpython-313.pyc create mode 100644 Inventario/__pycache__/apps.cpython-313.pyc create mode 100644 Inventario/__pycache__/forms.cpython-313.pyc create mode 100644 Inventario/__pycache__/models.cpython-313.pyc create mode 100644 Inventario/__pycache__/views.cpython-313.pyc create mode 100644 Inventario/__pycache__/viewspdf.cpython-313.pyc create mode 100644 Inventario/admin.py create mode 100644 Inventario/apps.py create mode 100644 Inventario/forms.py create mode 100644 Inventario/migrations/0001_initial.py create mode 100644 Inventario/migrations/0002_rename_descripcion_movimiento_inventario_observaciones_and_more.py create mode 100644 Inventario/migrations/0003_remove_articulo_codigo_articulo_articulo_medida.py create mode 100644 Inventario/migrations/__init__.py create mode 100644 Inventario/migrations/__pycache__/0001_initial.cpython-313.pyc create mode 100644 Inventario/migrations/__pycache__/0002_rename_descripcion_movimiento_inventario_observaciones_and_more.cpython-313.pyc create mode 100644 Inventario/migrations/__pycache__/0003_remove_articulo_codigo_articulo_articulo_medida.cpython-313.pyc create mode 100644 Inventario/migrations/__pycache__/__init__.cpython-313.pyc create mode 100644 Inventario/models.py create mode 100644 Inventario/templates/Base.html create mode 100644 Inventario/templates/articulo_nuevo.html create mode 100644 Inventario/templates/articulo_registro.html create mode 100644 Inventario/templates/articulo_update.html create mode 100644 Inventario/templates/bodega_nuevo.html create mode 100644 Inventario/templates/bodega_registro.html create mode 100644 Inventario/templates/bodega_update.html create mode 100644 Inventario/templates/grafico_chartjs.html create mode 100644 Inventario/templates/index.html create mode 100644 Inventario/templates/inventario_nuevo.html create mode 100644 Inventario/templates/inventario_registro.html create mode 100644 Inventario/templates/mov_inventario_registro.html create mode 100644 Inventario/templates/pdf.html create mode 100644 Inventario/templates/proveedor_nuevo.html create mode 100644 Inventario/templates/proveedor_registro.html create mode 100644 Inventario/templates/proveedor_update.html create mode 100644 Inventario/templates/signin.html create mode 100644 Inventario/templates/tipo_articulo_nuevo.html create mode 100644 Inventario/templates/tipo_articulo_registro.html create mode 100644 Inventario/templates/tipo_articulo_update.html create mode 100644 Inventario/tests.py create mode 100644 Inventario/views.py create mode 100644 Inventario/viewspdf.py create mode 100644 TiendAlfa/__init__.py create mode 100644 TiendAlfa/__pycache__/__init__.cpython-313.pyc create mode 100644 TiendAlfa/__pycache__/settings.cpython-313.pyc create mode 100644 TiendAlfa/__pycache__/urls.cpython-313.pyc create mode 100644 TiendAlfa/__pycache__/wsgi.cpython-313.pyc create mode 100644 TiendAlfa/asgi.py create mode 100644 TiendAlfa/settings.py create mode 100644 TiendAlfa/urls.py create mode 100644 TiendAlfa/wsgi.py create mode 100644 manage.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eba74f4 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +venv/ \ No newline at end of file diff --git a/Inventario/__init__.py b/Inventario/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Inventario/__pycache__/__init__.cpython-313.pyc b/Inventario/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..45c559e94d79f167609892ed794400be81513062 GIT binary patch literal 167 zcmey&%ge<81Ul6b=^*+sh=2h`DC08=kTI1Zok5e)ZzV$!6Oi{ABz4Qp*(xTqIJKxa zCaowjFFD2~wK%&ZzaXYOzbL!7ATc>L#xW-?(KD|sHLoPGC^J6>i5VZCnU`4-AFo$X hd5gm)H$SB`C)KWq6=*ET+F}snBQql-V-Yiu1pvLBD*6Bb literal 0 HcmV?d00001 diff --git a/Inventario/__pycache__/admin.cpython-313.pyc b/Inventario/__pycache__/admin.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8b9af74c888c63110398c1a2a48c88c4b31e266c GIT binary patch literal 211 zcmey&%ge<81Ul6b=}tiUF^B^LOi;#W0U%>4Loh=yqc?*WV-ceQLpqZt^GlGlCgUyE z#FX63JU>mQTYM>5iFxVyddc~DB}JJ@Ma)12D;Yk6)ZKD+wu%WYPAw{qNh?asOOA0# zEzT~UEpMNTwoEhcI)%2#Sc`kjIADV*y?>Bp znP_A;U{3$%%*LXo-2-}?-+Xmu-bQBc_o3eBPh4A#^bTUgV4hLP%|u1vxJIh7UF^OC dlR7nj5L4QH*%;$@wDMiH@Z96g57OaJ^$Wc_kuU%N literal 0 HcmV?d00001 diff --git a/Inventario/__pycache__/forms.cpython-313.pyc b/Inventario/__pycache__/forms.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b8fe11019716ced405d695bbe8159abe465c0925 GIT binary patch literal 8538 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 J3YzA4{tYsw7s&ts literal 0 HcmV?d00001 diff --git a/Inventario/__pycache__/models.cpython-313.pyc b/Inventario/__pycache__/models.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..69f475c025c003b9dd32eaafbd8f165eef38c8d9 GIT binary patch literal 4781 zcmb_gO>7&-72f6l&n`*x$8}^$rYOoSVMlIUyN!dwwQP!rq93`HZj)F2R`O-`{7hMis_^hBSkoZ_CE_R_0%d!VpDPCc=w0%GocZAx{wXK?gO=saP{3}FR^ zcm$Ss%f36*SpDJ*UcN{0USmlB__32b90A`a_<d#RAsGZ-dl&Ee?yhD`xQVzuVEkUdNcv#3G+U4r^h<(SMZ+Yb=wwcuWxg{VhOLh9O6tsEJk^ZPSn-*I(999cFwdE_LevR~ zq9$$0pdliPpm#^bJ|~L5-jUP}CoYPc3NcJo(PT{*MS|yc!nf{8q@>7dl^)Ltugeci zI(DK}*{Bd@yQ1hCNuqEDKS+X$7A4ap%Epc<8=&Yk@JI&9DI|DJlwimBK9Jurhp9K3 zsaZQU+aOlza((qMak`nv+KKF*X(cY!m%sI}{+z1=SDkKcdI@l=oBg%}#n=!00^ zisuhPdDkLn-?c)Fd=Gxf86#X4#gAXcz7sNKRo>J!olK%c zxT+Aj(!&&)#k zDELXJ7AORr6!m09+XZ*rRkjrHf1Tt(E6E{2FuabT<5Yd0>Y;W%JLDs}7RM{^4=S@( zeD)wT+i&sk7>i%RlOUjm8u3kJAVHKHh#fFudZL-m+v)ti*GgZh-$q+>K!%dTZSe=- zyqYb>Wf0)wXAd-*fdY_WBEZM%8EBLr1U^UIod&p}3j{EdJkw0h*~z)a z6)X8eNEL&rqZ|2DilzMJvKJ*cRehnNz~=%Gn)2n2Erja8#oVXPXy ziW?3ax)<`WnjB~};o_4p27Jt80}c3HNF_i53#)-fHH1Jz65?Qr#=*>S(Iobv?=q}( zfk!b&R$)xmklaQRMdAjb^vEFO@I}d#*Oe`~Qvh$u6?k1y{LyL%@#nau+ws;eG;iPr zh)Qw?iGXAs2~D)Tz5$QST?xx(fc&tU`7R10!IK!j2Liz=l4wSz?a1_A(TWtHK*sWG z&Q8xAoWJ&U>F;ZQU9-|c{WitmYvVWf;ulu*XM@r2<5d^W_+@Ja4$A*uNm@;xuWq>S z&xy{sqHFk~oR@aYd-Lwgm|!*T_*d~y1~*b?VS<*FeRqbALeD+$h;Twbbsxgli3lS2 zTsM9T;M1& literal 0 HcmV?d00001 diff --git a/Inventario/__pycache__/views.cpython-313.pyc b/Inventario/__pycache__/views.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7fdd3c45c3205154c2b5db8e1689943348fa6fa8 GIT binary patch literal 15392 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 aY3}}c&chwzR=1>^IIfc5tRCmsQvM%6_}9t+ literal 0 HcmV?d00001 diff --git a/Inventario/__pycache__/viewspdf.cpython-313.pyc b/Inventario/__pycache__/viewspdf.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cbef3894f8effe4d32b29966ef7a44de649ca2b8 GIT binary patch literal 3891 zcmbtXO>7&-6`uVexfCVwM?a2bSz&0wHf@XQj|ACPoItj$KO(k6nrdswU{}kLwAN~u znO*%@KoA-zAiF4_q^My9C=eGtv@TGEUEqdvZj0{uRRDgl{lACP#lAiiz$R!n; z0St5i&b)c^W@cyRecyZBYiephP=3~ReeMxR|DheH@MU4|w;IaN;+{K1k+a0WDuW0sXoU^8pz zCcZ=!bJ$8-crmNV7KXlZrx%l+GraCjxf6k^-jR-%1^EE1RNY0YZ{3W3%qP9c zhBJIOO1ZjG)OTr3%4TL`^VXtf`>GdduKDF`R#O$(QVqQqOdh~{D28sqO{cA!S-jSz z>YA$K!SJlAVO?It=OP4W4PxOKm`DEGa-n41Gpxdsnkrq0K4J!&)>`{TLJSg?weTF) zF_B65%J9h9u=)}%m%gxR$<~q?1#g7&*&bu&239Q77GzB$^rZ-W5F*mbO)b0^2nHvC zMQi~R67|>~>RGTAp_gJyjvLt?c8FEW7TK94Qg%4oN4+au+SsJahfBpCxo~zmWnyAZ z&k|WzriZb)U>Vuz6@x68Sy{o;L)xr7UU9sB-9~8?_uRhPn%(?qcY8A#{8zbRriAZJ={=V#|LlH@5BX++4^vpU92wx=~~6 z#=Cdk-5l8R9mx$dt9ItoXwEoe* z{fF{heGjL;NPnKr_g&0)j{M6k_>*}l`PA2vySxYAgT8|&2^0)Ze}4@;MJhC*b15!C zU#g}6ez+8`(G^+g1)_TYHP94BQ;Z1dq(lWfr8St&UzHunL2?TkOCzL<--B4O9>P*$ zBIK-7Z4<3k*^$7q-I1$p;*F~8NMPCF$ki6K)E#O{ugl?)FnUi$$cNwt-gJy!Y_GlkVV-tdyLsxRlylUSy}|@h?!XcYQ~($7#JtU zT0$RjEhbx*tjtrRI+T*GQd4YIGgl*oa%D7VOLV*J%~j2oegb%$F^mP)!e#k)>Gbvk@c!eCIwr#bffL9f)5$doJYX1l- zMhgw0qPOEqZ^xFmGk1R5>)SYZ=O76Fqq+0H7<=JH{_|XJbX#< z6$6n%AW{q*Ed-7}2^_yIZc7at-aFop`|b^VGO#)PS^U#@v9rI>+5gb`;=|8BEDl^P z3|!4mUMo&2g-Iok)gsOoa5f+M;E6<@3n&((ESES0>QYH^Ngm=NmlRT5Qe<(l5~b_0M+BwzMPk4+W$c;)jN*E~ zVg;z748}^L!XSTwBJ)?*W)9-GwT zjT8ql-wiR}!mC!VVlJ1k*Yn!ggDEBG5z0W(=92ddptjvB1l*k1QmHjoY5+%~FoT?+ z)k#{NqE!#AVzlaoDk?GnF{F^wRNDuYNrMN)ObIcsgi(5ovtV+D+TMkV;U&=d$Bu%( zkGg2eanWZ@fsJdwytXNAHNBM^p$_X?zkKWRm#w3Z#j)?hOY?^Rj(@ZDvjd+VxZnMU zlfOGzj0_ecgMYdDx9g9t7tdWQoV%8v{&{g)EljKV1*5pITv%Anzp?T}T4i`)VY(g` zs3);_`T~UiFF#FjEohQA`Cer55aYl{j7Wk~O-)Hu5KtYs!oLTxh(;A%&>^G!&Pu?t zuu>hgz%1}?HcQm`sS0*d@Yf?Hq{Jj2FZl7X{GlIiw{>l|ho8HIKKC9H8a=y6aCyFc;X%PM z?pr%}+N9t8`!|Pr#eYa`Lw#a2WOrq5$oiZSqlqg~XJYb_H6P1h#UQd}5R=ebwtZ!z zdH4^-KuNkmO$O*#dwI;sfn%CM;}T1xZSN}0gMUPGQI<&u%EsnAr1Hv=WwKP;b}vGt z)XdTY&@6?8D26+BT@Mf=`w~Q@x50Wz!|#w0u%sMsEuaW<2)Ubnk zcTmR;IhxgCm=qsOQqcyNYDA!iVmdRQ%u)f(SfuZW;%)Uu({89kl4rk E4~lj?$N&HU literal 0 HcmV?d00001 diff --git a/Inventario/admin.py b/Inventario/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/Inventario/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/Inventario/apps.py b/Inventario/apps.py new file mode 100644 index 0000000..96b6bd7 --- /dev/null +++ b/Inventario/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class InventarioConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'Inventario' diff --git a/Inventario/forms.py b/Inventario/forms.py new file mode 100644 index 0000000..2d57d19 --- /dev/null +++ b/Inventario/forms.py @@ -0,0 +1,99 @@ +from django import forms +from .models import proveedor, bodega, tipo_articulo, articulo,inventario,tipo_inv_movimiento + +class formulario_proveedor(forms.ModelForm): + class Meta: + model = proveedor + fields = '__all__' + widgets={ + 'nombre_proveedor': forms.TextInput(attrs={'class': 'form-control' , 'placeholder': 'Escribe el nombre del proveedor'}), + 'email': forms.EmailInput(attrs={'class':'form-control','placeholder':'email del proveedor'}), + 'direccion': forms.Textarea(attrs={'class':'form-control','placeholder':'direccion del proveedor','rows':'5'}), + 'telefono': forms.TextInput(attrs={'type':'tel','class':'form-control','placeholder':'0000-0000','maxlength':'9' ,'oninput':'formatearInput(this)'}), + } + +class formulario_bodega(forms.ModelForm): + class Meta: + model = bodega + fields = '__all__' + widgets={ + 'nombre_bodega': forms.TextInput(attrs={'class': 'form-control' , 'placeholder': 'Escribe el nombre de la bodega'}), + 'estado': forms.CheckboxInput(attrs={'class':'form-check-input'}), + 'direccion_bodega': forms.Textarea(attrs={'class':'form-control','placeholder':'direccion de la bodega','rows':'5'}), + 'codigo_bodega': forms.TextInput(attrs={'class': 'form-control' , 'placeholder': 'Escribe el codigo de la bodega','oninput':'permitirSoloNumeros(this)'}), + } + +class formulario_tipo(forms.ModelForm): + class Meta: + model = tipo_articulo + fields = '__all__' + widgets={ + 'tipo_articulo': forms.TextInput(attrs={'class': 'form-control' , 'placeholder': 'escriba el tipo de articulo'}), + 'descripcion': forms.Textarea(attrs={'class':'form-control','placeholder':'escriba una descripcion de este tipo de articulo','rows':'5'}), + } + +class formulario_articulo(forms.ModelForm): + tipo_articulo=forms.ModelChoiceField(queryset=tipo_articulo.objects.all(), + empty_label="Selecciona un tipo de articulo", + widget=forms.Select(attrs={'class': 'btn btn-secondary dropdown-toggle', 'data-bs-toggle': 'dropdown', 'aria-expanded': 'false'}), + label="tipo_articulo") + proveedor=forms.ModelChoiceField(queryset=proveedor.objects.all(), + empty_label="Selecciona un proveedor", + widget=forms.Select(attrs={'class': 'btn btn-secondary dropdown-toggle ', 'data-bs-toggle': 'dropdown', 'aria-expanded': 'false'}), + label="proveedor") + class Meta: + model = articulo + fields = '__all__' + widgets={ + 'nombre_articulo': forms.TextInput(attrs={'class': 'form-control' , 'placeholder': 'escriba el nombre del articulo'}), + 'medida': forms.TextInput(attrs={'class':'form-control','placeholder':'medida del producto lts, cm, etc'}), + 'descripcion': forms.Textarea(attrs={'class':'form-control','placeholder':'describa el producto','rows':'5'}), + } + +class formilario_inventarios(forms.ModelForm): + + articulo=forms.ModelChoiceField(queryset=articulo.objects.all(), + empty_label="selecciones un articulo", + widget=forms.Select(attrs={'class': 'btn btn-secondary dropdown-toggle', 'data-bs-toggle': 'dropdown', 'aria-expanded': 'false'}), + label="articulo") + bodega=forms.ModelChoiceField(queryset=bodega.objects.all(), + empty_label="Selecciona una bodega", + widget=forms.Select(attrs={'class': 'btn btn-secondary dropdown-toggle ', 'data-bs-toggle': 'dropdown', 'aria-expanded': 'false'}), + label="bodega") + class Meta: + model = inventario + fields = '__all__' + widgets={ + 'cantidad': forms.TextInput(attrs={'class': 'form-control' , 'placeholder': 'Cantidad de productos','oninput':'permitirSoloNumeros(this)',}), + 'precio': forms.NumberInput(attrs={'class':'form-control','placeholder':'Ej: 99.99','step': '0.01','min':'0','max':'10000',}), + } + +class formilario_inventario(forms.ModelForm): + tipo_inventario=forms.ModelChoiceField(queryset=tipo_inv_movimiento.objects.all(), + empty_label="selecciones un articulo", + widget=forms.Select(attrs={'class': 'btn btn-secondary dropdown-toggle', 'data-bs-toggle': 'dropdown', 'aria-expanded': 'false'}), + label="tipo de inventario") + bodega=forms.ModelChoiceField(queryset=bodega.objects.all(), + empty_label="Selecciona una bodega", + widget=forms.Select(attrs={'class': 'btn btn-secondary dropdown-toggle ', 'data-bs-toggle': 'dropdown', 'aria-expanded': 'false'}), + label="bodega") + articulo=forms.ModelChoiceField(queryset=articulo.objects.all(), + empty_label="Selecciona una bodega", + widget=forms.Select(attrs={'class': 'btn btn-secondary dropdown-toggle ', 'data-bs-toggle': 'dropdown', 'aria-expanded': 'false'}), + label="articulo") + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + # Personaliza cómo se muestran las opciones en el dropdown + self.fields['articulo'].label_from_instance = lambda obj: f"{obj.nombre_articulo} ({obj.medida})" if obj.medida else obj.nombre_articulo + self.fields['bodega'].label_from_instance = lambda obj: f"{obj.nombre_bodega} ({obj.codigo_bodega})" if obj.codigo_bodega else obj.nombre_bodega + + + class Meta: + model = inventario + fields = '__all__' + widgets={ + 'fecha': forms.DateInput(attrs={'type': 'date','class': 'form-control','placeholder': 'Seleccione una fecha'}), + 'precio': forms.NumberInput(attrs={'class':'form-control','placeholder':'Ej: 99.99','step': '0.01','min':'0','max':'10000',}), + 'cantidad': forms.TextInput(attrs={'class': 'form-control' , 'placeholder': 'Cantidad de productos','oninput':'permitirSoloNumeros(this)',}), + 'observacion': forms.Textarea(attrs={'class':'form-control','placeholder':'observacion','rows':'5'}), + } diff --git a/Inventario/migrations/0001_initial.py b/Inventario/migrations/0001_initial.py new file mode 100644 index 0000000..1790f77 --- /dev/null +++ b/Inventario/migrations/0001_initial.py @@ -0,0 +1,76 @@ +# Generated by Django 5.1.4 on 2024-12-11 06:38 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='bodega', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('codigo_bodega', models.IntegerField()), + ('nombre_bodega', models.CharField(max_length=40)), + ('estado', models.BooleanField(default=True)), + ], + ), + migrations.CreateModel( + name='proveedor', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('nombre_proveedor', models.CharField(max_length=100)), + ('email', models.EmailField(blank=True, max_length=254, null=True)), + ('telefono', models.CharField(blank=True, max_length=20, null=True)), + ('direccion', models.TextField(blank=True, null=True)), + ('estado', models.BooleanField(default=True)), + ], + ), + migrations.CreateModel( + name='tipo_articulo', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('tipo_articulo', models.CharField(max_length=100)), + ], + ), + migrations.CreateModel( + name='tipo_inv_movimiento', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('tipo_movimiento', models.CharField(max_length=100)), + ], + ), + migrations.CreateModel( + name='articulo', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('nombre_articulo', models.CharField(max_length=100)), + ('precio_articulo', models.DecimalField(decimal_places=2, max_digits=10)), + ('stock', models.IntegerField()), + ('creado', models.DateTimeField(auto_now_add=True)), + ('actualizado', models.DateTimeField(auto_now=True)), + ('activo', models.BooleanField(default=True)), + ('bodega', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='bodega', to='Inventario.bodega')), + ('proveedor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='productos', to='Inventario.proveedor')), + ], + ), + migrations.CreateModel( + name='movimiento_inventario', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('cantidad', models.IntegerField()), + ('descripcion', models.TextField(blank=True)), + ('total_costo', models.DecimalField(decimal_places=2, max_digits=10)), + ('numero_mov', models.IntegerField()), + ('fecha', models.DateTimeField(auto_now_add=True)), + ('articulo', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='articulos', to='Inventario.articulo')), + ('tipo_movimiento', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='mov_inv', to='Inventario.tipo_inv_movimiento')), + ], + ), + ] diff --git a/Inventario/migrations/0002_rename_descripcion_movimiento_inventario_observaciones_and_more.py b/Inventario/migrations/0002_rename_descripcion_movimiento_inventario_observaciones_and_more.py new file mode 100644 index 0000000..09b6323 --- /dev/null +++ b/Inventario/migrations/0002_rename_descripcion_movimiento_inventario_observaciones_and_more.py @@ -0,0 +1,138 @@ +# Generated by Django 5.1.4 on 2024-12-13 02:59 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('Inventario', '0001_initial'), + ] + + operations = [ + migrations.RenameField( + model_name='movimiento_inventario', + old_name='descripcion', + new_name='observaciones', + ), + migrations.RenameField( + model_name='movimiento_inventario', + old_name='total_costo', + new_name='precio', + ), + migrations.RemoveField( + model_name='articulo', + name='activo', + ), + migrations.RemoveField( + model_name='articulo', + name='actualizado', + ), + migrations.RemoveField( + model_name='articulo', + name='bodega', + ), + migrations.RemoveField( + model_name='articulo', + name='creado', + ), + migrations.RemoveField( + model_name='articulo', + name='precio_articulo', + ), + migrations.RemoveField( + model_name='articulo', + name='stock', + ), + migrations.RemoveField( + model_name='movimiento_inventario', + name='numero_mov', + ), + migrations.RemoveField( + model_name='movimiento_inventario', + name='tipo_movimiento', + ), + migrations.RemoveField( + model_name='proveedor', + name='estado', + ), + migrations.AddField( + model_name='articulo', + name='codigo_articulo', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='articulo', + name='descripcion', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='articulo', + name='tipo_articulo', + field=models.ForeignKey(default=40, on_delete=django.db.models.deletion.CASCADE, to='Inventario.tipo_articulo'), + preserve_default=False, + ), + migrations.AddField( + model_name='bodega', + name='direccion_bodega', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='movimiento_inventario', + name='bodega', + field=models.ForeignKey(default=60, on_delete=django.db.models.deletion.CASCADE, to='Inventario.bodega'), + preserve_default=False, + ), + migrations.AddField( + model_name='movimiento_inventario', + name='tipo_inventario', + field=models.ForeignKey(default=100, on_delete=django.db.models.deletion.CASCADE, to='Inventario.tipo_inv_movimiento'), + preserve_default=False, + ), + migrations.AddField( + model_name='tipo_articulo', + name='descripcion', + field=models.TextField(blank=True), + ), + migrations.AlterField( + model_name='articulo', + name='proveedor', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='Inventario.proveedor'), + ), + migrations.AlterField( + model_name='bodega', + name='codigo_bodega', + field=models.IntegerField(null=True), + ), + migrations.AlterField( + model_name='movimiento_inventario', + name='articulo', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='Inventario.articulo'), + ), + migrations.AlterField( + model_name='movimiento_inventario', + name='cantidad', + field=models.IntegerField(null=True), + ), + migrations.AlterField( + model_name='movimiento_inventario', + name='fecha', + field=models.DateTimeField(null=True), + ), + migrations.AlterField( + model_name='tipo_articulo', + name='tipo_articulo', + field=models.CharField(max_length=40), + ), + migrations.CreateModel( + name='inventario', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('cantidad', models.IntegerField(null=True)), + ('precio', models.DecimalField(decimal_places=2, max_digits=10)), + ('articulo', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='Inventario.articulo')), + ('bodega', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='Inventario.bodega')), + ], + ), + ] diff --git a/Inventario/migrations/0003_remove_articulo_codigo_articulo_articulo_medida.py b/Inventario/migrations/0003_remove_articulo_codigo_articulo_articulo_medida.py new file mode 100644 index 0000000..21ed427 --- /dev/null +++ b/Inventario/migrations/0003_remove_articulo_codigo_articulo_articulo_medida.py @@ -0,0 +1,22 @@ +# Generated by Django 5.1.4 on 2024-12-15 18:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('Inventario', '0002_rename_descripcion_movimiento_inventario_observaciones_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='articulo', + name='codigo_articulo', + ), + migrations.AddField( + model_name='articulo', + name='medida', + field=models.CharField(blank=True, max_length=100, null=True), + ), + ] diff --git a/Inventario/migrations/__init__.py b/Inventario/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Inventario/migrations/__pycache__/0001_initial.cpython-313.pyc b/Inventario/migrations/__pycache__/0001_initial.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..32fc5421ef7097a8e1431c21db0aee57e9a19971 GIT binary patch literal 4073 zcmcgvPf#1z8DFiWMUwd=0p>qKRs^+dBVj-xVv-D)KQ6dQu@+L>(ad(yKI9G3uJU$8 z0zEV{o$2(LOJ_Lb;A?O6RB{TP9OC2d`moHqG&4PMBSU-b^n1GtXkx&0I%9c|_I>a7 ze&6@~zVE$#K51!*F!0%)cv}9Zm0|u#2dAH)_i(ZZ4}WHOhW9;Uun&ION9?j6``Moa=-}ftOCnXdj742m6^(FJRYDc5>y9aUjd!V38|8%s>CoXdsqQq5bDG42_h9e?gw(oAQB4mJb20 z^CDc%GXf?InA2z)puiR3Z{&S|Xa+=2!<6^vcx$1EY=CdgvzNx(cI|khm&OwFVrd6N z-zBkhK<=G+KSX@YTyzsmhZ{4*UFu{GWXtV=iYm1%wFzU_DWBE*Y?!^ ze|j3Ywx_{2dE(=Mh+kNPAwI$1a%zwS%$vIS9l#_my<0KRSJH9W{YWtAtyJmseRNtSl`Oc4)(kf4ZFL|RI!B$rjeV{1{=>N-Z=@QCh-v=3gI;+H}NDP{dR z;gF__k_y%)32lh=iVknpfWyUY$fzP|BwWMl7DAGWNz~&zvm8l4NrI><%9W%4P2 zLs{7ps_K?pm64*Wq|Grl7(!?GHZQhwLk+yh=Zr@zcsZhX3rMk5g1M?#5o#5&gfv$Z zkWSV$64Z3Hv`IKBy(5iV2}S)v5GAODSkmiMe0MVBlnEvY2NUv^x)WPcwjf#&%WB3g z1gH{L6#=d%NQaVPRG~F>OU6Q4RAQ-K(p7DzvtjX>%;e^I$^uB@v6E0qRCHMqAt(uH zB`nt*Reg@C1gnJY9&p8rQUYp4YLmeb*$wv@KL;x>Ry@KGmSr9%4v1miVs7(+yWUT2GSwV^lh9+5&b?9W$ETI}w zB&3vNq+xp5BRA%p*8hm!>TrNsnjgsJS=bbdv@uEZlA@zB!tN+M_gwTIn;)oZ1&N9~ z5m}(k>48?!m%6ul-faMP)G`kRS(U5ETeGNQB$t&(u-7>0Gf^q4gq7Aw$f+PSE@_&Z z<>zMS7f3{{q0<}aO+kR&1pOqjaaJOZgFM5_}--CL8WPWUI z|LWm!z}Lxr^{e9$6Yj7>aVr!*jP?E)yZQB&-F?UEzOx^AnKGUUhJwv*&4}uUvBZlJ zJDIbRxmU?4Bl@0a7`Kw+`|DrcT@IC9+H z;A!AWPw%|=#2(IB!?}YFb9ljsE*{2uc1P^KyH?-bz0|?P%T=?lU_|-DSpV)P_TZ>B zIJ!4~PLg9t6y|OYwSaElo7G2*lRa5L@EP*c=s{q)TS< zff1cM4*Dqz2P~}(EF)L4BwsArsYxp}dEhrw^G0;x5|;k|jpZ=r5KmdDse{jrwcnVj zCr0$Cr{1X5H~OkCYedJqI%Tc??Eb3RPqR3T#b0oCV$w=X?n`E3&WO%mP)*Nt&+5Oo zxAnK}zi!)856!8E_SA|wwPH^_F{hpwW%Zb0>b_sHKQYX}5(|UaGV7HjYsItsBj2UJ zP21DU=Jc{X&70G_J^iUU{i*R;9k9RiJ*EqX3eG~FJ?@B5bz4B)fd+MNU#W}J6=T-m z*sH;DBRb*bHfANppe+-$Ej`nOm6$lVZ#?GB#HtZpJB$tPZrMZQ*3kH?p-Cf}^OVb2 zeVP4vv(N2uhdpBrX7;;1OZ&M%qyB|Bd*^94Kq%*;PCWF0cu@%@@+5?^sLc?=Rb zwaHnj+yVDP`0rtRX2qOYv1gu|Gf(Xq(VP*D+BPiwy-%PEhkxrV6xrigm`czL5|n%& zwsU`2#;d2hI?a(@_YlfR>lycdxtY_G2!BiumhjoUb9Oq%rF$&U!^fpsqrlMn?$P`q segZ=u{Ast~>)7w}`A#^-ck3U_?SF9#J|FjW#Ez!SXzJe#9XS;L1z2Flt^fc4 literal 0 HcmV?d00001 diff --git a/Inventario/migrations/__pycache__/0002_rename_descripcion_movimiento_inventario_observaciones_and_more.cpython-313.pyc b/Inventario/migrations/__pycache__/0002_rename_descripcion_movimiento_inventario_observaciones_and_more.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b3af699d1467edc1b207e16429ad8d1cb8fdaf53 GIT binary patch literal 4612 zcmcgwO>Eo96{bi@mSicB<^L#h9L4cQY05a;Yz)~!0LN}p+ubJcc#9xW!BXN_VN8+Q zA*EfrC{Un4Zw2;JVDG(TPu-sCoO0=5kD@LV=CTX)L&m9O6)5lOq9m@|*mIK!lAT3C?m; zT$V$^B@P7(!j@~TW59cUBzR8}DhG0*LpJ$Mj;FDTS|+lk8oEit6+^+AS@MA1@AdZN zZ@XYa@zcXgJSH0Zhx&%GuJav;jyNl2lqG+^VM(-h?dGtY^Z=VAHcoOIa#54E| z`D+U(`V(f88<>rNZvLojeg@iezWdhOPyD&Kgjh$I_tj3LTit$g!x!;$B!c!$U)cnj zfRle4E#!lD`9T>1A_A6f`C7VzK19FB^MLuu_YHjZ?Jw`4^0TZ~?((-o=x(0BJxwOj zM`WseFSkgeA9vpQhwxJ8*ezgPuVdYkiE7aJ!otEGN!3+Ll{GqEG3shX1)%|JUC^+C z%@R?oCAc`ygi$mxsmpAF&71(23U-l@bh(0Q#L$%XNXMUfqhZUiWKAj=re)A@m0-}M z5t&$Osiwh-T(Z=g1M!lOag&M++2WKG?d6+jfhL0P8Z62WYK(X%0SO@zR5X_v;`hWr&ya$5`-CAnI51U7XTPNZBq8fdgNVxU?H~XVK3LOe)q$KN>s>lj(g-b7G;3`&;KbJJDm#vpH22MNW#;XeD*Vl4E z8kcKOWNb$*tkB^qQ7baplXmeQjRFZ!jp{z8@j50&!^CbS9r6&-A-nBD5noWCjw(=B zRZT8o)AI=1sahr^;O<=5-8u6sxcW}hh~(OkBpQ=|0;Q&57{?{)Q>Zgmb1=IoNjoYr zElt(2ZZNTet5{dCUQ)41*qxdVZ()Xh#EODVfX((KvZ5&NG6^zZd|kJ2850i~-Nv6= z-Z1vaAXqKyn~-W)c_r&*gYrs|M%?0HM{HYY5()dHQyaLpEzT#^hOKs0a6?d-xDz?Y+c zU0o`C0y|+Ac8IK(3TxQhwTx=vGlT4!Rp7j^qV341^-$;;p8lCpfd2BKL|o3Gth;Tb zrwV&Ijr6_VBFVY}ID*CM9tlHC?hk8XW)3L+3wIReq8}Uy{8;!;zdnj_(NQNd(~Qit zCdJlxwlzL?JQR$^d<2=Zf~&2O>En<9@JNpxSe@}*^~d_JW_>M8om~}MBN^XS9}C$Z z#G7tL(yd8|H`_{0IjQT-)b-bQ?bJeVrd`a8i^(=q+1F!sO7z9dx|nOt)V0?S59Z(I z-sGI64SQ+BSwi*_a+Y4$OD`I~-?vkLXl1g;(GV~fcbW6NTxpG58{`G@oj#Wr(@t5w zUciEvuN&v;!M(TnH+g4y(_Y?mmbdNYZD+Y)FBgtDt{8a8A9LL3D(`D(9yYpvxS3`o z ztFsQe%I|hCYb5J!1Gk##TVL1zwfE0GXYsMU_}E!|YA-%@ z7N6OR&lg+B&T;XiMX?N0B=h3T}{aYdyldj9|sJ8hTz zinYCHSMK(Ex0id(hqXq})F%uWx$nJ29*}1+4ZzpD3O`3eAP_hSbAhYhayR}PUgZPf SFJew|&Q8w#k7F~}#Qy;(mi0#f literal 0 HcmV?d00001 diff --git a/Inventario/migrations/__pycache__/0003_remove_articulo_codigo_articulo_articulo_medida.cpython-313.pyc b/Inventario/migrations/__pycache__/0003_remove_articulo_codigo_articulo_articulo_medida.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ce8a412ce81a206eb2b8f0f10b32a481a9e70f64 GIT binary patch literal 998 zcmZ`%K~EDw6rR~_m+iKdS}~#+gvwg{R?n`%+(XOl4`s)~IOwePRwVm|?*!o@>W7q|*^0&`cz8 zDy>e!c$5a?8idN1&frjiBjh8%9s=-6|?jmiFh1ldn&OPMXm{&DX1zVi*3Op_7&~86={?F zIzpsFR0pgVafK^{yy?*>ABD(CLfQh-ED|w~6CGx}%VWmlK=2f_wzAyhYEJ%4-z@EQ z#&QG&9V>0@Q5Z&?q{~N=-zFr@l>7mqSq7rj%M=j=rc}v5Z6rTztopAMOR3)m8VCL+ zPxrH=>%UE4Kkd?h`|DAgjwSG~!SS!L#xW-?(KD|sHLoPGC^J6>iJ6<3UX)mpnV(l2 s6Ca2KczG$)vkyYXamRv#URE + + + + + Tienda la esquina + + + + + + + +{% block content %} + +{% endblock %} + + + + + + + \ No newline at end of file diff --git a/Inventario/templates/articulo_nuevo.html b/Inventario/templates/articulo_nuevo.html new file mode 100644 index 0000000..f8e8eb1 --- /dev/null +++ b/Inventario/templates/articulo_nuevo.html @@ -0,0 +1,51 @@ +{% extends "Base.html" %} + +{% block content %} + +
+
+
+
+
+
+ <- volver +

Registro articulo

+ +
+
+ {% if error %} + + {% endif %} + {% if mensaje %} + + {% endif %} + {% csrf_token %} + {{form.as_p}} + +
+ +
+ +
+
+
+
+
+
+ + + +{% endblock %} \ No newline at end of file diff --git a/Inventario/templates/articulo_registro.html b/Inventario/templates/articulo_registro.html new file mode 100644 index 0000000..907fff9 --- /dev/null +++ b/Inventario/templates/articulo_registro.html @@ -0,0 +1,44 @@ +{% extends "Base.html" %} + +{% block content %} +
+
+
+
+
+

Vista articulo

+ Nuevo articulo +
+ + + + + + + + + + + + + + + {% for articulo in persona %} + + + + + + + + + + {% endfor %} + +
#nombre del articulomedidadescripciontipo_articuloproveedorsactualizar
{{ articulo.id }} {{ articulo.nombre_articulo }} {{ articulo.medida }} {{ articulo.descripcion }} {{ articulo.tipo_articulo.tipo_articulo }} {{ articulo.proveedor.nombre_proveedor }} Editar
+
+
+
+
+ +{% endblock %} diff --git a/Inventario/templates/articulo_update.html b/Inventario/templates/articulo_update.html new file mode 100644 index 0000000..6b7b0ea --- /dev/null +++ b/Inventario/templates/articulo_update.html @@ -0,0 +1,29 @@ +{% extends "Base.html" %} + +{% block content %} +
+
+
+
+
+
+ <- volver +

Actualizar articulo

+ +
+
+ {% csrf_token %} + {{form.as_p}} + +
+ +
+ +
+
+
+
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/Inventario/templates/bodega_nuevo.html b/Inventario/templates/bodega_nuevo.html new file mode 100644 index 0000000..a0bbba0 --- /dev/null +++ b/Inventario/templates/bodega_nuevo.html @@ -0,0 +1,51 @@ +{% extends "Base.html" %} + +{% block content %} + +
+
+
+
+
+
+ <- volver +

Registro bodega

+
+
+ {% if error %} + + {% endif %} + {% if mensaje %} + + {% endif %} + {% csrf_token %} + {{form}} + +
+ +
+ +
+
+
+
+
+
+ + + + +{% endblock %} diff --git a/Inventario/templates/bodega_registro.html b/Inventario/templates/bodega_registro.html new file mode 100644 index 0000000..1bbd654 --- /dev/null +++ b/Inventario/templates/bodega_registro.html @@ -0,0 +1,60 @@ +{% extends "Base.html" %} + +{% block content %} +
+
+
+
+ {% if error %} + + {% endif %} + {% if mensaje %} + + {% endif %} +
+

Vista Bodega

+ Nueva bodega +
+ + + + + + + + + + + + + {% for bodega in persona %} + + + + + {% if bodega.estado %} + + {% else %} + + {% endif %} + + + + {% endfor %} + +
#codigo de la bodeganombre del supervisorestadoDireccionEditar
{{bodega.id}} {{bodega.codigo_bodega}} {{bodega.nombre_bodega}} activo inactivo {{bodega.direccion_bodega}} Editar
+
+
+
+
+ +{% endblock %} diff --git a/Inventario/templates/bodega_update.html b/Inventario/templates/bodega_update.html new file mode 100644 index 0000000..b2f6806 --- /dev/null +++ b/Inventario/templates/bodega_update.html @@ -0,0 +1,43 @@ +{% extends "Base.html" %} + +{% block content %} +
+
+
+
+
+
+ <- volver +

Actualizar bodega

+
+
+ {% if error %} + + {% endif %} + {% if mensaje %} + + {% endif %} + {% csrf_token %} + {{form}} + +
+ +
+ +
+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/Inventario/templates/grafico_chartjs.html b/Inventario/templates/grafico_chartjs.html new file mode 100644 index 0000000..0016d87 --- /dev/null +++ b/Inventario/templates/grafico_chartjs.html @@ -0,0 +1,36 @@ + + + + Gráfico Interactivo + + + +

Gráfico de cantidad de productos

+ + + volver + + + \ No newline at end of file diff --git a/Inventario/templates/index.html b/Inventario/templates/index.html new file mode 100644 index 0000000..a95d814 --- /dev/null +++ b/Inventario/templates/index.html @@ -0,0 +1,181 @@ +{% extends "Base.html" %} + +{% block content %} +{% if user.is_authenticated %} +
+
+
+
+
+

Precio promedio de cada tipo articulo

+
+ +
+
+
+
+
+
+
+

articulos en bodegas

+
+ +
+
+
+
+
+
+
+

Cantidad de tipos de articulos

+
+ +
+
+
+

Reportes del inventario

+ Descargar PDF + Descargar Excel + Descargar CSV +
+
+

Grafico de productos

+ +
+
+
+
+
+
+

Cantidad de tipos de articulos

+
+ +
+
+
+
+ + +
+ +{% else %} +{% endif %} + +{% endblock %} diff --git a/Inventario/templates/inventario_nuevo.html b/Inventario/templates/inventario_nuevo.html new file mode 100644 index 0000000..009d2a6 --- /dev/null +++ b/Inventario/templates/inventario_nuevo.html @@ -0,0 +1,52 @@ +{% extends "Base.html" %} + +{% block content %} + +
+
+
+
+
+
+ <- volver +

Registro inventario

+ +
+
+ {% if error %} + + {% endif %} + {% if mensaje %} + + {% endif %} + {% csrf_token %} + {{form.as_p}} + +
+ +
+ +
+
+
+
+
+
+ + + +{% endblock %} \ No newline at end of file diff --git a/Inventario/templates/inventario_registro.html b/Inventario/templates/inventario_registro.html new file mode 100644 index 0000000..542891a --- /dev/null +++ b/Inventario/templates/inventario_registro.html @@ -0,0 +1,45 @@ +{% extends "Base.html" %} + +{% block content %} +
+
+
+
+
+

Vista inventario

+
+ Descargar PDF + Descargar Excel + Descargar CSV + grafico +
+ + + + + + + + + + + + + {% for inventario in persona %} + + + + + + + + + {% endfor %} + +
#articuloDescripcion de articulobodegacantidadprecio
{{ inventario.id }} {{ inventario.articulo.nombre_articulo }} {{inventario.articulo.medida}} {{ inventario.articulo.descripcion }} {{ inventario.bodega.nombre_bodega }} {{ inventario.cantidad }} {{ inventario.precio }}
+
+
+
+
+ +{% endblock %} diff --git a/Inventario/templates/mov_inventario_registro.html b/Inventario/templates/mov_inventario_registro.html new file mode 100644 index 0000000..bfdf02f --- /dev/null +++ b/Inventario/templates/mov_inventario_registro.html @@ -0,0 +1,41 @@ +{% extends "Base.html" %} + +{% block content %} +
+
+
+
+
+

Vista inventario

+ Nuevo movimiento de inventario +
+ + + + + + + + + + + + + {% for movimiento_inventario in persona %} + + + + + + + + + {% endfor %} + +
#bodegaarticulocantidadpreciotipo de movimiento
{{ movimiento_inventario.id }} {{ movimiento_inventario.articulo.nombre_articulo }} {{movimiento_inventario.articulo.medida}} {{ movimiento_inventario.bodega.nombre_bodega }} {{ movimiento_inventario.cantidad }} {{ movimiento_inventario.precio }} {{ movimiento_inventario.tipo_inventario }}
+
+
+
+
+ +{% endblock %} diff --git a/Inventario/templates/pdf.html b/Inventario/templates/pdf.html new file mode 100644 index 0000000..02d5c73 --- /dev/null +++ b/Inventario/templates/pdf.html @@ -0,0 +1,36 @@ + + + + + + +

Reporte de Inventario

+ + + + + + + + + + + + {% for item in inventarios %} + + + + + + + + {% endfor %} + +
IDBodegaArtículoCantidadPrecio
{{ item.id }}{{ item.bodega.nombre_bodega }}{{ item.articulo.nombre_articulo }}{{ item.cantidad }}{{ item.precio }}
+ + \ No newline at end of file diff --git a/Inventario/templates/proveedor_nuevo.html b/Inventario/templates/proveedor_nuevo.html new file mode 100644 index 0000000..ae93b0f --- /dev/null +++ b/Inventario/templates/proveedor_nuevo.html @@ -0,0 +1,56 @@ + +{% extends "Base.html" %} + +{% block content %} + +
+
+
+
+
+
+ <- volver +

Registro Proveedor

+ +
+
+ {% if error %} + + {% endif %} + {% if mensaje %} + + {% endif %} + {% csrf_token %} + {{form}} + +
+ +
+ +
+
+
+
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/Inventario/templates/proveedor_registro.html b/Inventario/templates/proveedor_registro.html new file mode 100644 index 0000000..19d9323 --- /dev/null +++ b/Inventario/templates/proveedor_registro.html @@ -0,0 +1,56 @@ +{% extends "Base.html" %} + +{% block content %} +
+
+
+
+ {% if error %} + + {% endif %} + {% if mensaje %} + + {% endif %} +
+

Proveedores

+ Nuevo proveedor +
+ + + + + + + + + + + + + {% for proveedor in persona %} + + + + + + + + + {% endfor %} + +
#NombreEmailTelefonoDireccionEditar
{{proveedor.id}} {{proveedor.nombre_proveedor}} {{proveedor.email}} {{proveedor.telefono}} {{proveedor.direccion}} Editar
+
+
+
+
+ +{% endblock %} diff --git a/Inventario/templates/proveedor_update.html b/Inventario/templates/proveedor_update.html new file mode 100644 index 0000000..d0fd843 --- /dev/null +++ b/Inventario/templates/proveedor_update.html @@ -0,0 +1,43 @@ +{% extends "Base.html" %} + +{% block content %} +
+
+
+
+
+
+ <- volver +

Actualizar Proveedor

+ +
+
+ {% if error %} + + {% endif %} + {% if mensaje %} + + {% endif %} + {% csrf_token %} + {{form}} + +
+ +
+ +
+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/Inventario/templates/signin.html b/Inventario/templates/signin.html new file mode 100644 index 0000000..8ac8644 --- /dev/null +++ b/Inventario/templates/signin.html @@ -0,0 +1,28 @@ +{% extends "Base.html" %} + +{% block content %} + +
+
+
+
+

Login

+ {% csrf_token %} +
+ + +
+
+ + +
+ +
+
+
+
+ + +{% endblock %} diff --git a/Inventario/templates/tipo_articulo_nuevo.html b/Inventario/templates/tipo_articulo_nuevo.html new file mode 100644 index 0000000..4a90802 --- /dev/null +++ b/Inventario/templates/tipo_articulo_nuevo.html @@ -0,0 +1,44 @@ +{% extends "Base.html" %} + +{% block content %} + +
+
+
+
+
+
+ <- volver +

Registro tipo articulo

+ +
+
+ {% if error %} + + {% endif %} + {% if mensaje %} + + {% endif %} + {% csrf_token %} + {{form}} + +
+ +
+ +
+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/Inventario/templates/tipo_articulo_registro.html b/Inventario/templates/tipo_articulo_registro.html new file mode 100644 index 0000000..bf03a29 --- /dev/null +++ b/Inventario/templates/tipo_articulo_registro.html @@ -0,0 +1,51 @@ +{% extends "Base.html" %} + +{% block content %} +
+
+
+
+ {% if error %} + + {% endif %} + {% if mensaje %} + + {% endif %} +
+

Tipos de articulos

+ Nuevo tipo de articulo +
+ + + + + + + + + + + {% for tipo_articulo in persona %} + + + + + + {% endfor %} + +
#tipo de articuloDescripcionActualizar
{{tipo_articulo.id}} {{tipo_articulo.tipo_articulo}} {{tipo_articulo.descripcion}} Editar
+
+
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/Inventario/templates/tipo_articulo_update.html b/Inventario/templates/tipo_articulo_update.html new file mode 100644 index 0000000..80d194f --- /dev/null +++ b/Inventario/templates/tipo_articulo_update.html @@ -0,0 +1,43 @@ +{% extends "Base.html" %} + +{% block content %} +
+
+
+
+
+
+ <- volver +

Actualizar tipo de articulo

+ +
+
+ {% if error %} + + {% endif %} + {% if mensaje %} + + {% endif %} + {% csrf_token %} + {{form}} + +
+ +
+ +
+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/Inventario/tests.py b/Inventario/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/Inventario/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/Inventario/views.py b/Inventario/views.py new file mode 100644 index 0000000..b943dfa --- /dev/null +++ b/Inventario/views.py @@ -0,0 +1,338 @@ +from django.shortcuts import render,redirect,get_object_or_404 +from django.template.loader import get_template +from django.http import HttpResponse +from django.contrib.auth.forms import AuthenticationForm +from django.contrib.auth import login, logout, authenticate +from django.db import transaction +from django.utils import timezone +from django.contrib.auth.decorators import login_required +from django.db.models import Avg, Sum +from decimal import Decimal +from .forms import formulario_proveedor,formulario_bodega, formulario_tipo, formulario_articulo,formilario_inventario +from .models import proveedor, bodega, tipo_articulo, articulo,inventario,tipo_inv_movimiento,movimiento_inventario + +# Create your views here. +def base(request): + return render(request, 'index.html') + +def generar_grafico_chartjs(request): + # Gráfico de Pastel: Cantidad por tipo de artículo + tipos_articulo = tipo_articulo.objects.all() + tipos_nombres = [t.tipo_articulo for t in tipos_articulo] + cantidades_por_tipo = [articulo.objects.filter(tipo_articulo=t).count() for t in tipos_articulo] + + # Gráfico de Barras: Cantidad de artículos por bodega + bodegas = bodega.objects.all() + bodegas_nombres = [b.nombre_bodega for b in bodegas] + cantidades_por_bodega = [inventario.objects.filter(bodega=b).count() for b in bodegas] + + # Gráfico de Línea: Movimientos en el tiempo + + tipos_movimientos = tipo_inv_movimiento.objects.all() + nombres_tipos = [mov.tipo_movimiento for mov in tipos_movimientos] + + # Obtener la cantidad total movida para cada tipo de movimiento + cantidades_por_tipos = [ + movimiento_inventario.objects.filter(tipo_inventario=mov).aggregate(total=Sum('cantidad'))['total'] or 0 + for mov in tipos_movimientos + ] + tipos_articulo_prom = [t.tipo_articulo for t in tipos_articulo] + + precios_promedio = [ + float(inventario.objects.filter(articulo__tipo_articulo=t).aggregate(avg=Avg('precio'))['avg'] or 0) + for t in tipos_articulo + ] + + context = { + 'tipos_articulo': tipos_nombres, + 'cantidades_por_tipo': cantidades_por_tipo, + 'bodegas': bodegas_nombres, + 'cantidades_por_bodega': cantidades_por_bodega, + 'tipos_articulo_prom': tipos_articulo_prom, + 'precios_promedio': precios_promedio, + 'nombres_tipos': nombres_tipos, + 'cantidades_por_tipos': cantidades_por_tipos, + } + return render(request, 'index.html', context) + +def signin(request): + if request.method == 'GET': + return render ( request, 'signin.html',{ + 'form': AuthenticationForm + }) + else: + user=authenticate(request, username=request.POST['username'], password=request.POST['password']) + if user is None: + return render ( request, 'signin.html',{ + 'form': AuthenticationForm , + 'error': 'Username or password is incorrect' + }) + else: + login(request, user) + return redirect('home') + +@login_required +def signout(request): + logout(request) + return redirect('home') + +@login_required +def proveedor_registro(request): + if request.method=='GET': + return render(request, 'proveedor_nuevo.html',{ + 'form': formulario_proveedor + }) + else: + try: + form = formulario_proveedor (request.POST) + form.save() + form = formulario_proveedor () + return render(request, 'proveedor_nuevo.html',{ + 'form': formulario_proveedor, + 'mensaje':'Please provide valid data' + }) + except ValueError: + return render(request, 'proveedor_nuevo.html',{ + 'form': formulario_proveedor, + 'error':'Please provide valid data' + }) + +@login_required +def proveedor_lista(request): + persona = proveedor.objects.all + return render(request,"proveedor_registro.html", {'persona':persona}) + +@login_required +def Proveedor_update(request,task_id): + if request.method == 'GET': + tarea = get_object_or_404 (proveedor, pk=task_id) + form = formulario_proveedor(instance=tarea) + return render(request, 'proveedor_update.html',{'tasks':tarea, 'form':form} ) + else: + try: + tarea=get_object_or_404(proveedor,pk=task_id) + form = formulario_proveedor(request.POST, instance=tarea) + form.save() + return redirect('proveedor') + except ValueError: + return render(request, 'proveedor_update.html',{'tasks':tarea, 'form':form, 'error': 'error updating task'} ) + +@login_required +def bodega_registro(request): + if request.method=='GET': + return render(request, 'bodega_nuevo.html',{ + 'form': formulario_bodega + }) + else: + try: + form = formulario_bodega (request.POST) + form.save() + form = formulario_bodega () + return render(request, 'bodega_nuevo.html',{ + 'form': formulario_bodega, + 'mensaje':'Please provide valid data' + }) + except ValueError: + return render(request, 'bodega_nuevo.html',{ + 'form': formulario_bodega, + 'error':'Please provide valid data' + }) + +@login_required +def bodega_vista(request): + persona = bodega.objects.all + return render(request,"bodega_registro.html", {'persona':persona}) + +@login_required +def bodega_update(request,task_id): + if request.method == 'GET': + tarea = get_object_or_404 (bodega, pk=task_id) + form = formulario_bodega(instance=tarea) + return render(request, 'bodega_update.html',{'tasks':tarea, 'form':form} ) + else: + try: + tarea=get_object_or_404(bodega,pk=task_id) + form = formulario_bodega(request.POST, instance=tarea) + form.save() + return redirect('bodega_vista') + except ValueError: + return render(request, 'bodega_update.html',{'tasks':tarea, 'form':form, 'error': 'error updating task'} ) + +@login_required +def tipo_registro(request): + if request.method=='GET': + return render(request, 'tipo_articulo_nuevo.html',{ + 'form': formulario_tipo + }) + else: + try: + form = formulario_tipo (request.POST) + form.save() + form = formulario_tipo () + return render(request, 'tipo_articulo_nuevo.html',{ + 'form': formulario_tipo, + 'mensaje':'Please provide valid data' + }) + except ValueError: + return render(request, 'tipo_articulo_nuevo.html',{ + 'form': formulario_tipo, + 'error':'Please provide valid data' + }) + +@login_required +def tipo_vista(request): + persona = tipo_articulo.objects.all + return render(request,"tipo_articulo_registro.html", {'persona':persona}) + +@login_required +def tipo_update(request,task_id): + if request.method == 'GET': + tarea = get_object_or_404 (tipo_articulo, pk=task_id) + form = formulario_tipo(instance=tarea) + return render(request, 'tipo_articulo_update.html',{'tasks':tarea, 'form':form} ) + else: + try: + tarea=get_object_or_404(tipo_articulo,pk=task_id) + form = formulario_tipo(request.POST, instance=tarea) + form.save() + return redirect('tipo_vista') + except ValueError: + return render(request, 'tipo_articulo_update.html',{'tasks':tarea, 'form':form, 'error': 'error updating task'} ) + +@login_required +def articulo_registro(request): + if request.method=='GET': + return render(request, 'articulo_nuevo.html',{ + 'form': formulario_articulo + }) + else: + try: + form = formulario_articulo (request.POST) + form.save() + form = formulario_articulo () + return redirect('articulo_registro') + + except ValueError: + return render(request, 'articulo_nuevo.html',{ + 'form': formulario_articulo, + 'error':'Please provide valid data' + }) + +@login_required +def articulo_vista(request): + persona = articulo.objects.select_related('tipo_articulo','proveedor').all() + return render(request,"articulo_registro.html", {'persona':persona}) + +@login_required +def articulo_update(request,task_id): + if request.method == 'GET': + tarea = get_object_or_404 (articulo, pk=task_id) + form = formulario_articulo(instance=tarea) + return render(request, 'articulo_update.html',{'tasks':tarea, 'form':form} ) + else: + try: + tarea=get_object_or_404(articulo,pk=task_id) + form = formulario_articulo(request.POST, instance=tarea) + form.save() + return redirect('articulo_vista') + except ValueError: + return render(request, 'articulo_update.html',{'tasks':tarea, 'form':form, 'error': 'error updating'} ) + +@login_required +def inventario_registro(request): + if request.method=='GET': + return render(request, 'inventario_nuevo.html',{ + 'form': formilario_inventario + }) + else: + try: + form = formilario_inventario (request.POST) + form.save() + form = formilario_inventario () + return render(request, 'inventario_nuevo.html',{ + 'form': formilario_inventario, + 'mensaje':'Please provide valid data' + }) + except ValueError: + return render(request, 'inventario_nuevo.html',{ + 'form': formilario_inventario, + 'error':'Please provide valid data' + }) + +@login_required +def inventario_vista(request): + persona = inventario.objects.select_related('articulo','bodega').all() + return render(request,"inventario_registro.html", {'persona':persona}) + +def registrar_movimiento_y_actualizar_inventario(movimiento_data): + """ + Registra un movimiento de inventario y actualiza el inventario relacionado. + """ + try: + with transaction.atomic(): + # Registrar el movimiento de inventario + movimiento = movimiento_inventario.objects.create( + articulo=movimiento_data['articulo'], + bodega=movimiento_data['bodega'], + tipo_inventario=movimiento_data['tipo_inventario'], + cantidad=movimiento_data['cantidad'], + precio=movimiento_data['precio'], + observaciones=movimiento_data.get('observaciones', '') + ) + + # Buscar o crear el inventario correspondiente + inventario_obj, created = inventario.objects.get_or_create( + articulo=movimiento.articulo, + bodega=movimiento.bodega, + defaults={'cantidad': 0, 'precio': movimiento.precio} + ) + + # Actualizar stock según el tipo de movimiento + if movimiento.tipo_inventario.id == 1: # Asegúrate de que 'nombre' sea un campo válido + inventario_obj.cantidad += movimiento.cantidad + elif movimiento.tipo_inventario.id == 2: + if inventario_obj.cantidad < movimiento.cantidad: + raise ValueError( + f"No hay suficiente stock. Disponible: {inventario_obj.cantidad}, solicitado: {movimiento.cantidad}" + ) + inventario_obj.cantidad -= movimiento.cantidad + + # Actualizar el precio en Inventario si es necesario + if inventario_obj.precio != movimiento.precio: + inventario_obj.precio = movimiento.precio + + # Guardar los cambios en el inventario + inventario_obj.save() + + return movimiento, inventario_obj + + except Exception as e: + raise ValueError(f"Error al registrar movimiento y actualizar inventario: {str(e)}") + + +def registrar_movimiento(request): + """ + Vista para registrar un nuevo movimiento de inventario. + """ + if request.method == 'POST': + form = formilario_inventario(request.POST) + if form.is_valid(): + movimiento_data = form.cleaned_data + try: + movimiento, inventario_obj = registrar_movimiento_y_actualizar_inventario(movimiento_data) + return redirect('registrar_movimiento') # Redirigir a una página de éxito + except ValueError as e: + return render(request, 'inventario_nuevo.html', { + 'form': form, + 'error': str(e) + }) + else: + form = formilario_inventario() + + return render(request, 'inventario_nuevo.html', {'form': form}) + +@login_required +def vista_inventario_mov(request): + persona = movimiento_inventario.objects.select_related('articulo','bodega','tipo_inventario').all() + return render(request,"mov_inventario_registro.html", {'persona':persona}) + diff --git a/Inventario/viewspdf.py b/Inventario/viewspdf.py new file mode 100644 index 0000000..77b98ac --- /dev/null +++ b/Inventario/viewspdf.py @@ -0,0 +1,83 @@ +from django.contrib.auth.decorators import login_required +from django.http import HttpResponse +import openpyxl +import csv +from django.template.loader import get_template +from xhtml2pdf import pisa +from django.shortcuts import render +from .models import inventario + +@login_required +def generar_reporte_pdf(request): + # Obtener datos del inventario + inventarios = inventario.objects.all() + + # Cargar la plantilla + template = get_template('pdf.html') + context = {'inventarios': inventarios} + + # Renderizar la plantilla a HTML + html = template.render(context) + + # Crear un objeto de respuesta PDF + response = HttpResponse(content_type='application/pdf') + response['Content-Disposition'] = 'inline; filename="reporte.pdf"' + + # Convertir HTML a PDF + pisa_status = pisa.CreatePDF(html, dest=response) + + if pisa_status.err: + return HttpResponse(f'Error al generar PDF: {pisa_status.err}', status=500) + + return response + +@login_required +def generar_reporte_excel(request): + # Crear un nuevo libro de Excel + wb = openpyxl.Workbook() + ws = wb.active + ws.title = 'Reporte de Inventario' + + # Encabezados + headers = ['ID', 'Bodega', 'Artículo', 'Cantidad', 'Precio'] + ws.append(headers) + + # Datos del inventario + for item in inventario.objects.all(): + ws.append([item.id, item.bodega.nombre_bodega, item.articulo.nombre_articulo, item.cantidad, item.precio]) + + # Configurar la respuesta HTTP + response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') + response['Content-Disposition'] = 'attachment; filename="reporte_inventario.xlsx"' + + # Guardar el archivo en la respuesta + wb.save(response) + return response + +@login_required +def generar_reporte_csv(request): + # Configurar la respuesta HTTP + response = HttpResponse(content_type='text/csv') + response['Content-Disposition'] = 'attachment; filename="reporte_inventario.csv"' + + writer = csv.writer(response) + + # Encabezados + writer.writerow(['ID', 'Bodega', 'Artículo', 'Cantidad', 'Precio']) + + # Datos del inventario + for item in inventario.objects.all(): + writer.writerow([item.id, item.bodega.nombre_bodega, item.articulo.nombre_articulo, item.cantidad, item.precio]) + + return response + +@login_required +def generar_grafico_chartjs(request): + inventarios = inventario.objects.all() + productos = [item.articulo.nombre_articulo for item in inventarios] + cantidades = [item.cantidad for item in inventarios] + + return render(request, 'grafico_chartjs.html', { + 'productos': productos, + 'cantidades': cantidades, + }) \ No newline at end of file diff --git a/TiendAlfa/__init__.py b/TiendAlfa/__init__.py new file mode 100644 index 0000000..063cd2c --- /dev/null +++ b/TiendAlfa/__init__.py @@ -0,0 +1,2 @@ +import pymysql +pymysql.install_as_MySQLdb() diff --git a/TiendAlfa/__pycache__/__init__.cpython-313.pyc b/TiendAlfa/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1560d07f86919870b905eae6f5607361757d0d24 GIT binary patch literal 254 zcmey&%ge<81m6lG()ED!V-N=hn4pZ$AepHQ!3@ES-V8+yF$_U48JJ2St;ApoOlWax zQE^OKQDRPO4oI2hdbTATAaG5+9fu85wUg@ZDfwzs?|ai9zZrgG><{ GPyztZK|dk@ literal 0 HcmV?d00001 diff --git a/TiendAlfa/__pycache__/settings.cpython-313.pyc b/TiendAlfa/__pycache__/settings.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0b3f29467b533d75b1ba03e74d26192b49d7d592 GIT binary patch literal 2688 zcmb7G&2QVr5+`L@-;!lVvE3wnk4Xx*N*mH{>NNdGUTKMT)X0*frIR)gO3>0uW=xUl z?#iio(!D^@%e%j8&;3UdyhDsV8R)4uB|&@ckdkac3DA_1mb1I_`_1g^%&uOg(+L5d z%Rd?IUo(R6o8K8fv61lVPZ0hqAb|)-M4@})*C7&;gnHBhg!Ax7pI zAsIA>vS=PHpmQjP&Z9*+vMQ1}w1k#HZwb8mMI@1>_T~H)Q-%d5ijPgF?Mf6gW;tytwOk_U7IvDd-7=*vaUbIblM{(8>|kOt z+?4i?r1zTv>blwNSdK)QN!Up9eW^!*M;g(t%WLu{fZhbwj!Up)Ibfh;GRt)&__BQq zOjzlY#&Rlo^4CEMVaKb z&X#04O)!KlA|0A`57U2Qi{RFTq2K-e&5Jy|W3qj3V-y9;p}5f__W%$sOo6yA9 zKK@i*h0j_(>g9$e ztRK@iF#ECgZcHhk#_nRHaIsWFJf`mK7=aY6?&zgz1$h_FLiU8V zE!pgLA=1G%@@Nyc%%07><&pK~-dO}YNA!D}Cjz)xG@TtFztPpG9JEh zWA$b}!XsK`t5nf=xT0=DyNk3MkL{=kJ*?Kixw}=Q!&y0}-b4)5;NYJ+s^nv_0q zNz;JC$!Z23%DWU3mH8FlV;ET-%Z6HGM-PS?F7fWXEz`E;Se;&{jGZ>yKg0j$ZSlkE z+8OzHM)1|!5>$E}OsvN1471p|-lKeGS1))`xI&=H6fdSwtL<2h;=MaE0DIGMo7krE zhSi38bT=(*H!JyN9yJWOCk%r}yKoxY)*hLGAoG}E_@|UVPB3-tL(C&xIFua5V;d^c z{6ygiq!ntKZrszp<+DX?V|Rn%GYaB0@afpFNqs^1m;hW|e;WWg@;1>Staq z#xfz8&IwtmpBlu3oF*P;7mjnwCn@QrFncvKn2F{RFXE}$$Y3Uu4)x;$Nyx1}6|z7* zn>k+i=s0`nIJ66raKYo&&>&H%D0g*vU$Sm~}C&}~RNJ3a#e zX?x?C96IEfBfW9t&+twUnrepWp{L$pn4a6WYe`NsVy5+sS8u=j+4tT)t)%_b)fE!p z_xGJ_@qN1>{J}cTFKQc~9<>O<&q7)tLfV)1-|}twi61e$Uelc}(FMe4bHuUI-7e7sgi`}&7_RAFm*@jx{KSxLru$uD00`tk47x-Zh$#lmyOaQUyK_Hiy1S0N1Ou57~5X&CK zj7!V{vFbsbb%{A35+207OT>UU??Ie%iG@t-_PPhL=n_jnBt3|@OGrSZJcwnNSOLOo zC$BO>ijaxo7qNu=BW(WA&h~AT)6{}etP6IFkLN{VhEqE!v7Bk-dmLqq!tey+#Sb#PMF2u6wu{>lx{l@gY9jC72X zAq2lY!>H&jZL)WWn zjwj8-a;GbCw2{vvSw%{@q7fsBP=RP=RDPM2D-~O8q{;bJn`bLv3plYtm^{_5!5wTt$qF`%TC1)URYe7%VbnsfsrE6>YecfzUAxxnno^En83y}ZB};G- zHaF2~!>%T!6xB!?vi>Zql3w?{YR+JG(dC=SwN zBW|FuJ#s2am(AHB0)|r2BrC)&w)iJ|1GC7`-^-;FT9!BhS_IAeQnZ_e#@ zOgl=C(|3y1=LpSOMI7mLsocpZ0<(^F30 z_wWR2t+z27u!fzN zNFQt1DTxfQhJ8Uum^JLoLn5qUXB#rY8g_;uW2|9k6>AFRDj9wuL3KD_*^IQ^U0_NxEYrr8;z zow2t;Dqdj92rw59FTQD`;)>Hx9j1<7P;r^{qX*a=TA)J8@c+;Fo(wSua%0nvd*q+RRSvoNL<}nphoEkr>niB~+0W8 zaIC(vLB%Va8a-Mw$5!dsYCY*joH|}Jr`PH9dj0DMRNQ7$&m2_E$P$e#)z`kE;tf7^ z;y7TUBt@{KM^yZdYa>Uq=4gVB!UDFbm}XPQkJ`-P1RVy+_Ev8nIhr>|*Xbxk_?C)~ fK8KAR-7upm8co%&eNV;5AEe11|4$tx2DkPf72H-e literal 0 HcmV?d00001 diff --git a/TiendAlfa/__pycache__/wsgi.cpython-313.pyc b/TiendAlfa/__pycache__/wsgi.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e39e22319079da3f441f8e6c2fa9783b34b9abe4 GIT binary patch literal 658 zcmYjPPjAyO6nB!cPARL<#CEnOE|nnJ4!ukhQbkME4LWJ*1cykem%L=&96PeTmhH9^ zpMVpefNwJd5+WxM;=m2mFMzYI+up%`&riQU@5!^36&IPn^lkRhLg-gjETVRk%#KX* z0R>2+zzXa=OIqf3_Uv6pIv9o4!SVufcONwF@+OQVwu37B#tnO`@s;D($koKgl)u>x?9wJy}Q z?VfV0tFN2IdJVyRYraHPc`VUWtERJ&{6dk-Lp}y zcXvC({(cnnMx(*7A4ISByN9oO7pu4PdkVCsJX5WDS&t%PB8o~|sPfU=iWi#+yoy*l zMyjj>pHL}y=^9`HDLG@hY~0iQgl3hevh!j)JX9c6m`cLqunX!`iz1u~d8!H$Ls+eU zz$a!Hvq=%&S_&&QuQ)H4cjgO!E}MqYd?Tbb&GFZRAcQ4&< cXzepvyIS|IHoIR@?`L!4OY_NPLq0U1|9qstqW}N^ literal 0 HcmV?d00001 diff --git a/TiendAlfa/asgi.py b/TiendAlfa/asgi.py new file mode 100644 index 0000000..208551f --- /dev/null +++ b/TiendAlfa/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for TiendAlfa 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.1/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'TiendAlfa.settings') + +application = get_asgi_application() diff --git a/TiendAlfa/settings.py b/TiendAlfa/settings.py new file mode 100644 index 0000000..ecf49b9 --- /dev/null +++ b/TiendAlfa/settings.py @@ -0,0 +1,132 @@ +""" +Django settings for TiendAlfa project. + +Generated by 'django-admin startproject' using Django 5.1.4. + +For more information on this file, see +https://docs.djangoproject.com/en/5.1/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/5.1/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.1/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-f)f0@t_(a&ht0mo$&#nftao+_=s&^31u9))d=685^vs8&np=5k' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = ['store.stevz.dev','127.0.0.1'] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'Inventario', + +] + +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 = 'TiendAlfa.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 = 'TiendAlfa.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/5.1/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', # Motor de MySQL + 'NAME': 'ttienda', # Nombre de la base de datos + 'USER': 'ttienda', # Usuario de MySQL + 'PASSWORD': 'Tienda$2024', # Contraseña de MySQL + 'HOST': '10.138.214.232', # Dirección del servidor (por defecto localhost) + 'PORT': '3306', # Puerto de MySQL (por defecto 3306) + } +} + + + +# Password validation +# https://docs.djangoproject.com/en/5.1/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.1/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.1/howto/static-files/ + +STATIC_URL = 'static/' + +LOGIN_URL= '/signin/' + +# Default primary key field type +# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/TiendAlfa/urls.py b/TiendAlfa/urls.py new file mode 100644 index 0000000..cd6fca4 --- /dev/null +++ b/TiendAlfa/urls.py @@ -0,0 +1,54 @@ +""" +URL configuration for TiendAlfa project. + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/5.1/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 +from Inventario import views, viewspdf + +urlpatterns = [ + path('admin/', admin.site.urls), + path('',views.generar_grafico_chartjs, name='home'), + path('logout/',views.signout, name ='logout'), + path('signin/',views.signin, name ='signin'), + path('proveedor/',views.proveedor_lista, name ='proveedor'), + path('proveedor/crear/',views.proveedor_registro, name ='proveedor_registro'), + path('proveedor//',views.Proveedor_update, name ='Proveedor_update'), + path('bodega/',views.bodega_vista, name ='bodega_vista'), + path('bodega/crearbodega/',views.bodega_registro, name ='bodega_registro'), + path('bodega//',views.bodega_update, name ='bodega_update'), + path('tipo/',views.tipo_vista, name ='tipo_vista'), + path('tipo/creartipo_articulo/',views.tipo_registro, name ='tipo_registro'), + path('tipo//',views.tipo_update, name ='tipo_update'), + path('articulo/',views.articulo_vista, name ='articulo_vista'), + path('articulo/crear/',views.articulo_registro, name ='articulo_registro'), + path('articulo//',views.articulo_update, name ='articulo_update'), + path('inventario/',views.inventario_vista, name ='inventario_vista'), + path('inventariomov/crear/',views.registrar_movimiento, name ='registrar_movimiento'), + path('inventariomov/',views.vista_inventario_mov, name ='vista_inventario_mov'), + path('reporte/pdf/',viewspdf.generar_reporte_pdf, name ='generar_reporte_pdf'), + path('reporte/excel/',viewspdf.generar_reporte_excel, name ='generar_reporte_excel'), + path('reporte/csv/',viewspdf.generar_reporte_csv, name ='generar_reporte_csv'), + path('grafico/chartjs/',viewspdf.generar_grafico_chartjs, name ='generar_grafico_chartjs'), + + + + + + + + + +] diff --git a/TiendAlfa/wsgi.py b/TiendAlfa/wsgi.py new file mode 100644 index 0000000..b2070e8 --- /dev/null +++ b/TiendAlfa/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for TiendAlfa 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.1/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'TiendAlfa.settings') + +application = get_wsgi_application() diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..7740509 --- /dev/null +++ b/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', 'TiendAlfa.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()