From 7a94be02e18bd9a9227415ca19474db3ba38fae0 Mon Sep 17 00:00:00 2001 From: ruuushhh <66899387+ruuushhh@users.noreply.github.com> Date: Thu, 21 Mar 2024 14:00:56 +0530 Subject: [PATCH] handle delete case for categories and projects in expense attributes (#105) * handle delete case for categories and projects in expense attributes * fix lint * fix lint --- .../0025_expenseattributesdeletioncache.py | 28 +++++++++++ fyle_accounting_mappings/models.py | 47 +++++++++++++++++++ setup.py | 2 +- 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 fyle_accounting_mappings/migrations/0025_expenseattributesdeletioncache.py diff --git a/fyle_accounting_mappings/migrations/0025_expenseattributesdeletioncache.py b/fyle_accounting_mappings/migrations/0025_expenseattributesdeletioncache.py new file mode 100644 index 0000000..26200e2 --- /dev/null +++ b/fyle_accounting_mappings/migrations/0025_expenseattributesdeletioncache.py @@ -0,0 +1,28 @@ +# Generated by Django 3.2.14 on 2024-03-20 11:13 + +import django.contrib.postgres.fields +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('workspaces', '0038_alter_workspace_onboarding_state'), + ('fyle_accounting_mappings', '0024_auto_20230922_0819'), + ] + + operations = [ + migrations.CreateModel( + name='ExpenseAttributesDeletionCache', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('category_ids', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=255), default=[], size=None)), + ('project_ids', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=255), default=[], size=None)), + ('workspace', models.OneToOneField(help_text='Reference to Workspace model', on_delete=django.db.models.deletion.PROTECT, to='workspaces.workspace')), + ], + options={ + 'db_table': 'expense_attributes_deletion_cache', + }, + ), + ] diff --git a/fyle_accounting_mappings/models.py b/fyle_accounting_mappings/models.py index c69d8e7..c942c95 100644 --- a/fyle_accounting_mappings/models.py +++ b/fyle_accounting_mappings/models.py @@ -3,6 +3,7 @@ from datetime import datetime from django.db import models, transaction from django.db.models import JSONField +from django.contrib.postgres.fields import ArrayField from .exceptions import BulkError from .utils import assert_valid @@ -106,6 +107,16 @@ def get_existing_source_ids(destination_type: str, workspace_id: int): return existing_source_ids +class ExpenseAttributesDeletionCache(models.Model): + id = models.AutoField(primary_key=True) + category_ids = ArrayField(default=[], base_field=models.CharField(max_length=255)) + project_ids = ArrayField(default=[], base_field=models.CharField(max_length=255)) + workspace = models.OneToOneField(Workspace, on_delete=models.PROTECT, help_text='Reference to Workspace model') + + class Meta: + db_table = 'expense_attributes_deletion_cache' + + class ExpenseAttribute(models.Model): """ Fyle Expense Attributes @@ -146,6 +157,42 @@ def create_or_update_expense_attribute(attribute: Dict, workspace_id): ) return expense_attribute + @staticmethod + def bulk_update_deleted_expense_attributes(attribute_type: str, workspace_id: int): + """ + Bulk update deleted expense attributes + :param attribute_type: Attribute type + :param workspace_id: Workspace Id + """ + expense_attributes_deletion_cache = ExpenseAttributesDeletionCache.objects.get(workspace_id=workspace_id) + attributes_to_be_updated = [] + + if attribute_type == 'CATEGORY': + deleted_attributes = ExpenseAttribute.objects.filter( + attribute_type=attribute_type, workspace_id=workspace_id, active=True + ).exclude(source_id__in=expense_attributes_deletion_cache.category_ids) + expense_attributes_deletion_cache.category_ids = [] + expense_attributes_deletion_cache.save() + else: + deleted_attributes = ExpenseAttribute.objects.filter( + attribute_type=attribute_type, workspace_id=workspace_id, active=True + ).exclude(source_id__in=expense_attributes_deletion_cache.project_ids) + expense_attributes_deletion_cache.project_ids = [] + expense_attributes_deletion_cache.save() + + for attribute in deleted_attributes: + attributes_to_be_updated.append( + ExpenseAttribute( + id=attribute.id, + active=False, + updated_at=datetime.now() + ) + ) + + if attributes_to_be_updated: + ExpenseAttribute.objects.bulk_update( + attributes_to_be_updated, fields=['active', 'updated_at'], batch_size=50) + @staticmethod def bulk_create_or_update_expense_attributes( attributes: List[Dict], attribute_type: str, workspace_id: int, update: bool = False): diff --git a/setup.py b/setup.py index 6e31eb4..234e01e 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setuptools.setup( name='fyle-accounting-mappings', - version='1.31.5', + version='1.32.0', author='Shwetabh Kumar', author_email='shwetabh.kumar@fyle.in', description='Django application to store the fyle accounting mappings in a generic manner',