<commit_before>import logging
import datetime

from uuidfield import UUIDField
from django.core.validators import MaxValueValidator
from django.db import models
from django.db.models import SET_NULL
from django.conf import settings
from django.utils.timezone import utc
from django.core.exceptions import ObjectDoesNotExist

from model_utils.models import TimeStampedModel

from core.utils import getattrd
from core.cloning import clone_model, CloneModelMixin

from eligibility_calculator.models import CaseData
from eligibility_calculator.calculator import EligibilityChecker
from eligibility_calculator.exceptions import PropertyExpectedException

from diagnosis.models import DiagnosisTraversal

# from jsonfield import JSONField

from cla_common.db.mixins import ModelDiffMixin
from cla_common.money_interval.fields import MoneyIntervalField
from cla_common.money_interval.models import MoneyInterval
from cla_common.constants import ELIGIBILITY_STATES, THIRDPARTY_REASON, \
    THIRDPARTY_RELATIONSHIP, ADAPTATION_LANGUAGES, MATTER_TYPE_LEVELS, \
    CONTACT_SAFETY, EXEMPT_USER_REASON, ECF_STATEMENT, REQUIRES_ACTION_BY

from legalaid.fields import MoneyField


logger = logging.getLogger(__name__)


class Category(TimeStampedModel):
    name = models.CharField(max_length=500)
    code = models.CharField(max_length=50, unique=True)
    raw_description = models.TextField(blank=True)
    ecf_available = models.BooleanField(default=False)
    mandatory = models.BooleanField(default=False)
    description = models.TextField(blank=True, editable=False)
    order = models.PositiveIntegerField(default=0)

    class Meta:
        ordering = ['order']
        verbose_name_plural = "categories"

    def __unicode__(self):
        return u'%s' % self.name


class Savings(CloneModelMixin, TimeStampedModel):
    bank_balance = MoneyField(default=None, null=True, blank=True)
    investment_balance = MoneyField(default=None, null=True, blank=True)
    asset_balance = MoneyField(default=None, null=True, blank=True)
    credit_balance = MoneyField(default=None, null=True, blank=True)

    cloning_config = {
        'excludes': ['created', 'modified']
    }<commit_msg>implemented cloning logic when splitting a case<commit_after>import logging
import datetime

from uuidfield import UUIDField
from django.core.validators import MaxValueValidator
from django.db import models
from django.db.models import SET_NULL
from django.conf import settings
from django.utils.timezone import utc
from django.core.exceptions import ObjectDoesNotExist

from model_utils.models import TimeStampedModel

from core.utils import getattrd
from core.cloning import clone_model, CloneModelMixin

from eligibility_calculator.models import CaseData
from eligibility_calculator.calculator import EligibilityChecker
from eligibility_calculator.exceptions import PropertyExpectedException

from diagnosis.models import DiagnosisTraversal

# from jsonfield import JSONField

from cla_common.db.mixins import ModelDiffMixin
from cla_common.money_interval.fields import MoneyIntervalField
from cla_common.money_interval.models import MoneyInterval
from cla_common.constants import ELIGIBILITY_STATES, THIRDPARTY_REASON, \
    THIRDPARTY_RELATIONSHIP, ADAPTATION_LANGUAGES, MATTER_TYPE_LEVELS, \
    CONTACT_SAFETY, EXEMPT_USER_REASON, ECF_STATEMENT, REQUIRES_ACTION_BY

from legalaid.fields import MoneyField


logger = logging.getLogger(__name__)


def clone_model(cls, pk, config={}):
    if not pk:
        return None

    cloned = cls.objects.get(pk=pk)

    excludes = config.get('excludes', [])
    clone_fks = config.get('clone_fks', [])
    override_values = config.get('override_values', {})

    cloned.pk = None

    # excludes
    for field in excludes:
        fk_field = cls._meta.get_field(field)
        setattr(cloned, field, fk_field.get_default())

    # fks
    for field in clone_fks:
        if field in override_values:
            continue

        fk_field = cls._meta.get_field(field)
        fk_id = getattr(cloned, '%s_id' % fk_field.name)
        fk_clazz = fk_field.rel.to
        cloned_fk = fk_clazz.clone_from_obj(fk_id)
        setattr(cloned, fk_field.name, cloned_fk)

    # overrides
    for field, value in override_values.items():
        setattr(cloned, field, value)

    cloned.save(force_insert=True)

    return cloned


class CloneModelMixin(object):
    cloning_config = {
        'excludes': [],
        'clone_fks': [],
        'override_values': {}
    }

    @classmethod
    def clone_from_obj(cls, pk, config=None):
        config = config or cls.cloning_config
        return clone_model(cls, pk, config)


class Category(TimeStampedModel):
    name = models.CharField(max_length=500)
    code = models.CharField(max_length=50, unique=True)
    raw_description = models.TextField(blank=True)
    ecf_available = models.BooleanField(default=False)
    mandatory = models.BooleanField(default=False)
    description = models.TextField(blank=True, editable=False)
    order = models.PositiveIntegerField(default=0)

    class Meta:
        ordering = ['order']
        verbose_name_plural = "categories"

    def __unicode__(self):
        return u'%s' % self.name


class Savings(CloneModelMixin, TimeStampedModel):
    bank_balance = MoneyField(default=None, null=True, blank=True)
    investment_balance = MoneyField(default=None, null=True, blank=True)
    asset_balance = MoneyField(default=None, null=True, blank=True)
    credit_balance = MoneyField(default=None, null=True, blank=True)

    cloning_config = {
        'excludes': ['created', 'modified']
    }
{'fraction_non_alphanumeric': 0.0787922101125603, 'fraction_numerical': 0.0021440057173485795, 'mean_word_length': 4.648839556004036, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '802391', 'n_tokens_mistral': 1762, 'n_tokens_neox': 1690, 'n_words': 383}