constec 0.5.2__py3-none-any.whl → 0.5.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,91 @@
1
+ # Generated manually for constec automation organization support
2
+
3
+ from django.db import migrations, models
4
+ import django.db.models.deletion
5
+ from django.db.models import Q
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+
10
+ dependencies = [
11
+ ('constec_db', '0006_automation_trigger_action_executionlog_notificationtemplate'),
12
+ ]
13
+
14
+ operations = [
15
+ # Add organization field to Automation
16
+ migrations.AddField(
17
+ model_name='automation',
18
+ name='organization',
19
+ field=models.ForeignKey(
20
+ blank=True,
21
+ db_index=True,
22
+ help_text='Organization para automations compartidas (opcional si se define company)',
23
+ null=True,
24
+ on_delete=django.db.models.deletion.CASCADE,
25
+ to='constec_db.organization'
26
+ ),
27
+ ),
28
+ # Make company field nullable in Automation
29
+ migrations.AlterField(
30
+ model_name='automation',
31
+ name='company',
32
+ field=models.ForeignKey(
33
+ blank=True,
34
+ db_index=True,
35
+ help_text='Company específica (opcional si se define organization)',
36
+ null=True,
37
+ on_delete=django.db.models.deletion.CASCADE,
38
+ to='constec_db.company'
39
+ ),
40
+ ),
41
+ # Add organization field to NotificationTemplate
42
+ migrations.AddField(
43
+ model_name='notificationtemplate',
44
+ name='organization',
45
+ field=models.ForeignKey(
46
+ blank=True,
47
+ db_index=True,
48
+ help_text='Organization para templates compartidos (opcional si se define company)',
49
+ null=True,
50
+ on_delete=django.db.models.deletion.CASCADE,
51
+ to='constec_db.organization'
52
+ ),
53
+ ),
54
+ # Make company field nullable in NotificationTemplate
55
+ migrations.AlterField(
56
+ model_name='notificationtemplate',
57
+ name='company',
58
+ field=models.ForeignKey(
59
+ blank=True,
60
+ db_index=True,
61
+ help_text='Company específica (opcional si se define organization)',
62
+ null=True,
63
+ on_delete=django.db.models.deletion.CASCADE,
64
+ to='constec_db.company'
65
+ ),
66
+ ),
67
+ # Add indexes for organization
68
+ migrations.AddIndex(
69
+ model_name='automation',
70
+ index=models.Index(fields=['organization', 'status'], name='automations_org_status_idx'),
71
+ ),
72
+ migrations.AddIndex(
73
+ model_name='notificationtemplate',
74
+ index=models.Index(fields=['organization', 'channel', 'is_active'], name='templates_org_channel_active_idx'),
75
+ ),
76
+ # Add constraint: at least one of company or organization must be set
77
+ migrations.AddConstraint(
78
+ model_name='automation',
79
+ constraint=models.CheckConstraint(
80
+ check=Q(company__isnull=False) | Q(organization__isnull=False),
81
+ name='automation_requires_company_or_organization'
82
+ ),
83
+ ),
84
+ migrations.AddConstraint(
85
+ model_name='notificationtemplate',
86
+ constraint=models.CheckConstraint(
87
+ check=Q(company__isnull=False) | Q(organization__isnull=False),
88
+ name='template_requires_company_or_organization'
89
+ ),
90
+ ),
91
+ ]
@@ -2,9 +2,11 @@
2
2
 
3
3
  import uuid
4
4
  from django.db import models
5
+ from django.db.models import Q
5
6
  from django.core.exceptions import ValidationError
6
7
  from .base import UUIDModel
7
8
  from .company import Company
9
+ from .organization import Organization
8
10
  from .user import User
9
11
 
10
12
 
@@ -34,8 +36,23 @@ class Automation(UUIDModel):
34
36
  ('retry', 'Retry'),
35
37
  ]
36
38
 
37
- # FKs
38
- company = models.ForeignKey(Company, on_delete=models.CASCADE, db_index=True)
39
+ # FKs - Al menos uno debe estar presente
40
+ company = models.ForeignKey(
41
+ Company,
42
+ on_delete=models.CASCADE,
43
+ null=True,
44
+ blank=True,
45
+ db_index=True,
46
+ help_text="Company específica (opcional si se define organization)"
47
+ )
48
+ organization = models.ForeignKey(
49
+ Organization,
50
+ on_delete=models.CASCADE,
51
+ null=True,
52
+ blank=True,
53
+ db_index=True,
54
+ help_text="Organization para automations compartidas (opcional si se define company)"
55
+ )
39
56
  created_by = models.ForeignKey(
40
57
  User,
41
58
  on_delete=models.CASCADE,
@@ -82,9 +99,16 @@ class Automation(UUIDModel):
82
99
  app_label = 'constec_db'
83
100
  indexes = [
84
101
  models.Index(fields=['company', 'status']),
102
+ models.Index(fields=['organization', 'status']),
85
103
  models.Index(fields=['status', 'next_execution_at']),
86
104
  ]
87
105
  ordering = ['-created_at']
106
+ constraints = [
107
+ models.CheckConstraint(
108
+ check=Q(company__isnull=False) | Q(organization__isnull=False),
109
+ name='automation_requires_company_or_organization'
110
+ )
111
+ ]
88
112
 
89
113
  def __str__(self):
90
114
  return f"{self.name} ({self.status})"
@@ -333,8 +357,23 @@ class NotificationTemplate(UUIDModel):
333
357
  ('push', 'Push Notification'),
334
358
  ]
335
359
 
336
- # FKs
337
- company = models.ForeignKey(Company, on_delete=models.CASCADE, db_index=True)
360
+ # FKs - Al menos uno debe estar presente
361
+ company = models.ForeignKey(
362
+ Company,
363
+ on_delete=models.CASCADE,
364
+ null=True,
365
+ blank=True,
366
+ db_index=True,
367
+ help_text="Company específica (opcional si se define organization)"
368
+ )
369
+ organization = models.ForeignKey(
370
+ Organization,
371
+ on_delete=models.CASCADE,
372
+ null=True,
373
+ blank=True,
374
+ db_index=True,
375
+ help_text="Organization para templates compartidos (opcional si se define company)"
376
+ )
338
377
  created_by = models.ForeignKey(
339
378
  User,
340
379
  on_delete=models.CASCADE,
@@ -367,8 +406,15 @@ class NotificationTemplate(UUIDModel):
367
406
  app_label = 'constec_db'
368
407
  indexes = [
369
408
  models.Index(fields=['company', 'channel', 'is_active']),
409
+ models.Index(fields=['organization', 'channel', 'is_active']),
370
410
  ]
371
411
  ordering = ['name']
412
+ constraints = [
413
+ models.CheckConstraint(
414
+ check=Q(company__isnull=False) | Q(organization__isnull=False),
415
+ name='template_requires_company_or_organization'
416
+ )
417
+ ]
372
418
 
373
419
  def __str__(self):
374
420
  return f"{self.channel}: {self.name}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: constec
3
- Version: 0.5.2
3
+ Version: 0.5.3
4
4
  Summary: Base library for the Constec ecosystem - shared utilities, models, and namespace foundation
5
5
  License: MIT
6
6
  Project-URL: Homepage, https://github.com/TpmyCT/constec-python
@@ -7,9 +7,10 @@ constec/db/migrations/0003_remove_module_level.py,sha256=3GX-VDLSZqqxaZf6KFtuc7U
7
7
  constec/db/migrations/0004_rename_entities_company_cuit_idx_entities_company_e2c50f_idx_and_more.py,sha256=TCkutatVjJhVKxiQwp-RLhBlbOo5rtwSV1qQqao1qCI,11874
8
8
  constec/db/migrations/0005_event.py,sha256=kyvEFOAbOJj3daDzOWcIhfXD8gl5EpIHYvRy3880cZc,2892
9
9
  constec/db/migrations/0006_automation_trigger_action_executionlog_notificationtemplate.py,sha256=sfh1YTRPqUiBb5FIxRNJm_BnlYkDonwm7FEEihgtSe0,13628
10
+ constec/db/migrations/0007_add_organization_to_automations.py,sha256=08yDuetrA4WWwqNriyewr0qCpesLo_9x5YD36CDScj4,3467
10
11
  constec/db/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
12
  constec/db/models/__init__.py,sha256=tzeMhD6Bxs8Z8dBHEGBeIBm1ZrMKk66TlZEOD92InKU,2463
12
- constec/db/models/automation.py,sha256=_toRKPIGeTd54aLSnEsRUkCH42md18gXrj-xnnmTv-g,13712
13
+ constec/db/models/automation.py,sha256=YvNA7Wwd5mLcE93YZotM45_n-WiatiQmO34IXN3UfCg,15252
13
14
  constec/db/models/base.py,sha256=Urbz9iyOtSxdTfgtEYbtBLmTiea2QAcLq0L40tAzEq8,736
14
15
  constec/db/models/company.py,sha256=APYsbiNoqQ-73wxFP0jq3AByHNHn3Jjbe_J_iwpD9gM,1047
15
16
  constec/db/models/contact.py,sha256=VJ66YgzCqp09dzYM5IK9rZZV1jqBepJQO8YK28gA98k,2106
@@ -30,8 +31,8 @@ constec/shared/exceptions.py,sha256=8Bih40RWoH0gVhto09mH2ppSQV_drHPnGWITcoD-0J0,
30
31
  constec/utils/__init__.py,sha256=brf-G4UvU-3CK_rKNPTaHwsVsxnoJSbml_QTZJSM7d0,458
31
32
  constec/utils/cuit.py,sha256=dQKGlA4pRQ5DyR-N4BiV8ZsvAle2Vgjif7PU72zHx_A,2753
32
33
  constec/utils/password.py,sha256=XNpTJ9xZQSoZNjXEAnexAEZuYkwW1dFgX4AY-B5Q0gA,1462
33
- constec-0.5.2.dist-info/licenses/LICENSE,sha256=a1R51ONDGq0UQfV-n3ybsNL7EGhcC2sQ1sXvRANaFVI,1064
34
- constec-0.5.2.dist-info/METADATA,sha256=mbHsxNllNA8FUJYkiB7bAW6e_C85bj4kGs9ua2ZzOXU,2954
35
- constec-0.5.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
36
- constec-0.5.2.dist-info/top_level.txt,sha256=bQ9AydOLlthShsr7tA7t7ivbLvlLPdhHOo0BdWgnh_Y,8
37
- constec-0.5.2.dist-info/RECORD,,
34
+ constec-0.5.3.dist-info/licenses/LICENSE,sha256=a1R51ONDGq0UQfV-n3ybsNL7EGhcC2sQ1sXvRANaFVI,1064
35
+ constec-0.5.3.dist-info/METADATA,sha256=sFbG0NUKTJxcegLdjLG3meQ8h_UuJ4FSzZ90Nkelkzo,2954
36
+ constec-0.5.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
37
+ constec-0.5.3.dist-info/top_level.txt,sha256=bQ9AydOLlthShsr7tA7t7ivbLvlLPdhHOo0BdWgnh_Y,8
38
+ constec-0.5.3.dist-info/RECORD,,