From 34d6321e11a76e94f48737b6cef1c7b5483b6583 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Mon, 2 Feb 2026 18:25:39 +0000 Subject: [PATCH] Autosave: 20260202-182538 --- core/__pycache__/models.cpython-311.pyc | Bin 33137 -> 35523 bytes core/__pycache__/urls.cpython-311.pyc | Bin 8735 -> 9651 bytes core/__pycache__/views.cpython-311.pyc | Bin 85937 -> 102298 bytes .../0016_expensecategory_expense.py | 43 +++ ...16_expensecategory_expense.cpython-311.pyc | Bin 0 -> 3007 bytes core/models.py | 26 +- core/templates/base.html | 22 +- core/templates/core/customers.html | 1 + core/templates/core/expense_categories.html | 202 ++++++++++ core/templates/core/expenses.html | 220 +++++++++++ core/templates/core/inventory.html | 1 + core/templates/core/invoice_edit.html | 306 +++++++++++++++ core/templates/core/invoices.html | 44 +++ core/templates/core/pagination.html | 47 +++ core/templates/core/purchase_returns.html | 1 + core/templates/core/purchases.html | 1 + core/templates/core/quotations.html | 1 + core/templates/core/sales_returns.html | 1 + core/templates/core/suppliers.html | 1 + core/templates/core/users.html | 1 + core/urls.py | 9 + core/views.py | 364 +++++++++++++++++- 22 files changed, 1272 insertions(+), 19 deletions(-) create mode 100644 core/migrations/0016_expensecategory_expense.py create mode 100644 core/migrations/__pycache__/0016_expensecategory_expense.cpython-311.pyc create mode 100644 core/templates/core/expense_categories.html create mode 100644 core/templates/core/expenses.html create mode 100644 core/templates/core/invoice_edit.html create mode 100644 core/templates/core/pagination.html diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index 933112cb97018ae4b49126d2200e1d0996dc06cf..a1d345bf8003092b9d560e34f612a0e29591428a 100644 GIT binary patch delta 8615 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 delta 7330 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 diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index cd848e1399468470a237790ee37f45443518e85a..a855790def0c45f36b1d1106a20bcc766c8a52f2 100644 GIT binary patch delta 2314 zcmaKt?@wD*7{_V*u(bS+`$5}FTbRHg8|!|+W(H$0#xmBQtfiFB@nh{BYhhh!3v*;! z@s&pR!g-=Hf351GB%21q8_nM63tt!$bFMjw37LO@iP7tO<2?5~y&ajxOZw#be$VGT z&pG#;T<)FP@YH=)TU%AZpPznRNp?zi>a51c)n9h}SVe+{%KEotQ_8E2YERn^waW$RtddXHOyvh}`ZeZZ|?+4@kk?s03hY!$iH`4P9ym938-Zu`_! zQSpHP@VR4%g%Y2HDmw3P{9X0Ep{+5QUb>o$%Q?54Nao#r$#ni$X0G48S)=JG9NqY? z<~38nBEOW8(>acAn)P(KLC@UrtUQyK-J5kKX9|sFTbW46^D-x%_9&w`vb>{=#(AmP ztJ$R1>^XEj^3+pzx%I!$e>G?pO0bz$|~-jEx% zZ!?6+^<94!Hf!~EQ%gzt+UE9hU9stBOzeT?vn${`!hxo83EZl_G%=bz#7`@GSPR`e zkT)A&Y0heApVdw~tDSE)q=m2+#bH|WT(KP!9{By9BhaRkDtLIy_Dxsz8)M zRP7PKkrL2cY-79o=+Fd(m;yC11~K)hAo|G54x8t=$osd_$LQb~g@^(X1`+jy00s;t zVs~+vweosf8V(u+a*}*4N#-FGr^sV2hEbd)PbA6jLE+UaIg6F7xrg@oDEJldGw`cE zMEp7;c6XAFOi`FtV4A_S8bBmS0#3<1iXuW@Z<5U8D5B&GE+$aKh|(k#&ZBryFWa@Y z$lUy`rYOuQFvnm{y@1H1j)=}@Xkd=QyaMwK=G7@g5{SGiy&SuDIF1)gdZ`Upg6!eMCNtG zy}pwj4AEGQLSBJ9gS>hLkt|2Zaffwp4s~9iA{zJ7lOYOW1;Px%>LMabw&1w;mnrF+u3*2DG=Q}0CzaRuTG;_9Fg@5%ol zLx`Nw5!-4Hle&n_Sz{T&p|eJ^-)XaWP$CQ+SF!{A#b2N>slX(INp%sCC2gOcYbb8$JYUHDy7d@^0R;va45&8| zxTOOfYi$qR-&8+cX90l$6M58ZvkaQ>R88a;u7*&ZF_9FeIJ7>@x_va9 zq>xe|#UQ165b^3r_qxoEjMC^;3K<153^J+@5xYNOuhmRjNqX3pV&8;nR>5Cn7ksHW+aHfla^|C?)~>5IcZPMG_K_ zIp$O)nl?qfWP6IGs*)=%NKp^HwU=nNnnVAEo;uum>@v@*B30ehKF!bXH*e)PGkX$y zJ9YV;&1P*fuJ9j6kACiWeYwN(yY;8u4_0|4p8w{4Q{S5tx$QUUycJERHwiy(7_@H9#_+FW)KT6Lm-`kdUexaZSX1 zwaXZPt9IQjNbMGGZE8`Dre1cw+WWd%Tct3j!x)1x-YT+f|C6;9$eF0q-sv=|`9(~0 zx{UEwXSWf*62JT?#verdOT>@6Ts~2`A1ikqx3G@h+5v^24nYP%J|NPAB;|5chs4+~ zRI0eNtE}fXok&qg>yT!U=EFi5X$aSAS6N?-&X*}vbf_?>@Ebz7*$}SPT3GJ{jVw{f z>X2oS<(~>+v>|kBKIRV6$z=*FIwV#Ytnh#^?lcVhae%4*`Z|S(4iN?sJ}&aXixuwB z&?1G54jBd+j*Xrmt4_y9p9%SMa_Cg$kR%{XG^eUeBFswUfyXfrMY<<7syek6)*Yb1 z1cjsyNd`$CLnTfWm#QQXk`mc=JLEZ}1v2MStBVL3vy@jWuxnu&eMn(LhYbcBdLP`b4kZR9zKY5hrXs4$l0RKGc@0w=*Jr`Y5ULYMvZy+vAWYEn=mn$S(#&5T?nNTa{-JX2~nJ zT8$zkEsa&{(E`jfdU}^aREH>oD4#fP*YuRyOpNd9SUU~$_&c<1u6%oB0eb7MDf|=LrjH<)2GUl&5ivK u@~KM^gz4tSs*A48(By^FGlR;ksr1zXY#>Tg7fw%9C`Ya5_io1cdjA8??B(eI diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 0c44493d52af748b74093d63192f5898d175aee9..6fb611488104b9856133f35f805ae4b06a2d9bb9 100644 GIT binary patch delta 30660 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ɚpbwM%nBLiMhtUD3`@g?rI$NGh7A$JhQSqh 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 Vt~2)TJR~*=yJ3`=bPj+e|9>GKKyLs5 diff --git a/core/migrations/0016_expensecategory_expense.py b/core/migrations/0016_expensecategory_expense.py new file mode 100644 index 0000000..98ccf52 --- /dev/null +++ b/core/migrations/0016_expensecategory_expense.py @@ -0,0 +1,43 @@ +# Generated by Django 5.2.7 on 2026-02-02 17:15 + +import django.db.models.deletion +import django.utils.timezone +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0015_userprofile'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='ExpenseCategory', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name_en', models.CharField(max_length=100, verbose_name='Name (English)')), + ('name_ar', models.CharField(max_length=100, verbose_name='Name (Arabic)')), + ('description', models.TextField(blank=True, verbose_name='Description')), + ], + options={ + 'verbose_name_plural': 'Expense Categories', + }, + ), + migrations.CreateModel( + name='Expense', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('amount', models.DecimalField(decimal_places=3, max_digits=15, verbose_name='Amount')), + ('date', models.DateField(default=django.utils.timezone.now, verbose_name='Date')), + ('description', models.TextField(blank=True, verbose_name='Description')), + ('attachment', models.FileField(blank=True, null=True, upload_to='expense_attachments/', verbose_name='Attachment')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='expenses', to=settings.AUTH_USER_MODEL)), + ('payment_method', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='expenses', to='core.paymentmethod')), + ('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='expenses', to='core.expensecategory')), + ], + ), + ] diff --git a/core/migrations/__pycache__/0016_expensecategory_expense.cpython-311.pyc b/core/migrations/__pycache__/0016_expensecategory_expense.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4a3e0c72b870be60939cc3acff25246c4aa1f1dd GIT binary patch literal 3007 zcmbtWJ#gDb76w5Q{1GLQvSgVeZPB)Di#~@`9LF=BWRfuYaT3e&g_3nTDmOTgyQCn2 z00V%wq)J6*k}_RXrc#nI3l}L=q;TnSHG@L4X)=?_9X)pC>fSB@%CbF|WC9QmZ})xg zXZO9g;1B)%aRIK*uRH3GQ9<~f4g4$YG0#?j`A$Fr3TQ$lz~3T&i(0T5s)Pbe7SzH` zsUkHal}JDkg_{BjeI=kUme#?pd+h}U;Q>7ERf(d&qL7!Ku;D^JK%*A6ZB=hrd6CAO zYQt1))zB>}H4TI{tLEwP*9mX%>?+v%PQW~_iiiTDfP?EHABw~4lF#o2z&kwd)etKY zj_pNT4j(#P$?D#kc& zz{lai^`y_Qr+VCw&!J2w`)c&)PpuK1=AQiAy8C|yjdyad?f+Sh9ParHb~c)4~u7xthV9{3$0fc1-i&pNvF2Ah+|ZT?}j>7!^- zzH|B2%r#=2e;m&QRQ(vb0$ukOjotP;4B9PJGfYgAQ&VrhE4M9dwoIe0YM2hrZnm&) z;c3Oj4a3}`qKcO0sQBqjK135r+cxByi9v{HU&~aRin%3k;4K;h8>*tI+n6TqVY6yj zSk{#$rV&PEtUo~z`u4yAjB=B+dP7sKwLI^8WmDF$-muq9R%M=oVs7`l*pjJK)monR zA#Bx5wZ)DI+Bb7F03+e5rsx~4{)v~}%Pp;KD%$ptx2&AEE)`q(APw;drMikWWYLJh zZ3E+hsiZWGwr)RRC)krg7MxV#GoU+wa1EBPfd{3AEjYhm9Y}4cw&lhVLa<9TGy@bO zj38WB+M4ak;)-o6wY4VJ?d@Ug?znt3XBBC@)I;P$CM#EnwykM2)^2Hrf@It9OnK=5 zbvRMo4C%&wSwV=#eOYyjMm;xHKFrOTlgwt!&}BGkF+`d$vBvW1rcJaBI?z(KScq~H z+iM2e9%409@Fv|k8m)m2E0pbFF7>?lv-zM|06%7tktrZ~(PTAjjsaQ7XJ}OB{$!cP zWf_kBwuXUE$nuwMMdPI-o9q~-!`6MJ)l#Y;M;J;JVZF9xvdqxI(%q#`4< znb~=o=pi7_v~QXh>}~c?#K&r*1f@L35>I2(Yl`WyOL)_E*~E;SUr)f&=&}-8 zSM-KK!);sDEE=`dCf+u5OoOoPG&ToaA-T8SMnJz6(mu6;Z+-PC%YxtA!3}O~u+$pXZO~z4T4oiC+3K>P&ug z5G^^;Qa2nNmUia52_ZJlWM>Xj=YC6#kkQNE-g8DT?}r{wkcv!nlZ;viqn0yjk)(Z? z8Y9^&yK_$V%6^c1Rw3EdgY2r4T_wpcj>#SuNw#v3tvJ~VNv zi{w@gaw|@5g(UyojfIB?x&uP$BDwTlHz_)PLhqo)F?^kcTYO${KJbsUvaM9bgteamH(2oa*$S>v_g{A z{}bzB>NFWI?%s38ix1JGVe)ySD+u=k(;~cbGvZTDpK}T`sacULyu%dU0r>db!T6jr zK1Y%_xnPP3U_%~Fkn)OCUUkYZD?o62cyCe;KV zXUX|%-(PpmU)#U-2$AJ4oMqWrt~<+yv%CqIPsB2V{>!y7!EFEq8$f*<8FIR?yX>4U z?4SH4?cDg(xlwj*RETN;U@LHk;m-V%c?SxbK$+&}V)sNG(iiS$83Xd1k!~h4B<+00 zZgbwR%zTWd-F7RWYQgwP VE4)s=jXTMSr%dqt4N@NA{{YMPGT8tC literal 0 HcmV?d00001 diff --git a/core/models.py b/core/models.py index 6d25482..4c5b59e 100644 --- a/core/models.py +++ b/core/models.py @@ -104,6 +104,30 @@ class PaymentMethod(models.Model): def __str__(self): return f"{self.name_en} / {self.name_ar}" +class ExpenseCategory(models.Model): + name_en = models.CharField(_("Name (English)"), max_length=100) + name_ar = models.CharField(_("Name (Arabic)"), max_length=100) + description = models.TextField(_("Description"), blank=True) + + class Meta: + verbose_name_plural = _("Expense Categories") + + def __str__(self): + return f"{self.name_en} / {self.name_ar}" + +class Expense(models.Model): + category = models.ForeignKey(ExpenseCategory, on_delete=models.CASCADE, related_name="expenses") + amount = models.DecimalField(_("Amount"), max_digits=15, decimal_places=3) + date = models.DateField(_("Date"), default=timezone.now) + description = models.TextField(_("Description"), blank=True) + payment_method = models.ForeignKey(PaymentMethod, on_delete=models.SET_NULL, null=True, blank=True, related_name="expenses") + created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name="expenses") + attachment = models.FileField(_("Attachment"), upload_to="expense_attachments/", blank=True, null=True) + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return f"Expense {self.id} - {self.amount} ({self.category.name_en})" + class Sale(models.Model): PAYMENT_TYPE_CHOICES = [ ('cash', _('Cash')), @@ -357,4 +381,4 @@ def create_user_profile(sender, instance, created, **kwargs): def save_user_profile(sender, instance, **kwargs): if not hasattr(instance, 'profile'): UserProfile.objects.create(user=instance) - instance.profile.save() + instance.profile.save() \ No newline at end of file diff --git a/core/templates/base.html b/core/templates/base.html index 96b77d5..dd1e563 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -121,6 +121,26 @@ + + +