Completed
Push — master ( da0207...5a5796 )
by Mathias
01:37
created

CustomerDirectory.clean()   F

Complexity

Conditions 15

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 26
rs 2.7451
cc 15

How to fix   Complexity   

Complexity

Complex classes like CustomerDirectory.clean() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
# Copyright 2013 Mathias WOLFF
2
# This file is part of pyfreebilling.
3
#
4
# pyfreebilling is free software: you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# pyfreebilling is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with pyfreebilling.  If not, see <http://www.gnu.org/licenses/>
16
17
from django.db import models
18
from django.db.models import permalink, Sum, Avg, Count, Max, Min
19
from django.core.validators import EMPTY_VALUES
20
from django.core.exceptions import ValidationError
21
from django.contrib.auth.models import AbstractUser
22
from django.conf import settings
23
from django.contrib.contenttypes import generic
24
from django.contrib.comments.models import Comment
25
from django.contrib.contenttypes.models import ContentType
26
from django.contrib.contenttypes.generic import GenericRelation
27
from django.utils.translation import ugettext_lazy as _
28
from django.utils.html import format_html
29
30
import datetime
31
import qsstats
32
import vatnumber
33
34
from django_iban.fields import IBANField, SWIFTBICField
35
36
import decimal
37
38
import math
39
40
from django_countries.fields import CountryField
41
42
from netaddr import IPNetwork, AddrFormatError
43
44
import re
45
46
from currencies.models import Currency
47
48
from pyfreebill.validators import validate_cidr
49
50
# CustomUser -- Django 1.6
51
# class CustomUser(AbstractUser):
52
#    keyboard_shortcuts = models.BooleanField(default=True)
53
54
# Finance
55
from django.core.exceptions import ValidationError
56
57
def check_vat(value):
58
    if value != "" and not vatnumber.check_vat(value):
59
        raise ValidationError(u"%s is not a valid VAT number" % value)
60
61
class Company(models.Model):
62
    """Company model."""
63
    name = models.CharField(_(u'name'),
64
                            max_length=200,
65
                            unique=True)
66
    nickname = models.CharField(_('nickname'),
67
                                max_length=50,
68
                                blank=True,
69
                                null=True)
70
    slug = models.SlugField(_('slug'),
71
                            max_length=50,
72
                            unique=True)
73
    about = models.CharField(_(u'about'),
74
                             max_length=250,
75
                             blank=True,
76
                             null=True)
77
    phone_number = GenericRelation(u'PhoneNumber')
78
    email_address = GenericRelation(u'EmailAddress')
79
    web_site = GenericRelation(u'WebSite')
80
    street_address = GenericRelation(u'StreetAddress')
81
    note = GenericRelation(Comment, object_id_field='object_pk')
82
    account_number = models.IntegerField(_(u"Account number"),
83
                                         blank=True,
84
                                         null=True)
85
    vat = models.BooleanField(_(u"VAT Applicable / Not applicable"),
86
                              default=False,
87
                              help_text=_(u"if checked, VAT is applicable."))
88
    vat_number = models.CharField(_(u"VAT number"),
89
                                  max_length=30,
90
                                  blank=True,
91
                                  validators=[check_vat])
92
    vat_number_validated = models.BooleanField(_(u"VAT Vies Validated."),
93
                                               default=False,
94
                                               help_text=_(u"If on, it means that VAT is "
95
                                                           u"validated through <a target='_blank' "
96
                                                           u"href='http://ec.europa.eu/taxation_customs/vies/vatRequest.html'>Vies</a>."))
97
    swift_bic = SWIFTBICField(_(u"SWIFT BIC bank account number"),
98
                              blank=True,
99
                              null=True)
100
    iban = IBANField(_(u"IBAN bank account number"),
101
                     blank=True,
102
                     null=True)
103
    prepaid = models.BooleanField(_(u"Prepaid / Postpaid"),
104
                                  default=True,
105
                                  help_text=_(u"If checked, this account customer is prepaid."))
106
    credit_limit = models.DecimalField(_(u'credit limit'),
107
                                       max_digits=12,
108
                                       decimal_places=4,
109
                                       default=0,
110
                                       help_text=_(u"Credit limit for postpaid account."))
111
    low_credit_alert = models.DecimalField(_(u'low credit level alert'),
112
                                           max_digits=12,
113
                                           decimal_places=4,
114
                                           default="10",
115
                                           help_text=_(u"Low credit limit alert."))
116
    low_credit_alert_sent = models.BooleanField(_(u"low credit alert ON"),
117
                                                default=False)
118
    account_blocked_alert_sent = models.BooleanField(_(u"Customer account blocked - low balance - ON"),
119
                                                     default=False)
120
    email_alert = models.EmailField(_('alert email address'),
121
                                    blank=True,
122
                                    null=True)
123
    customer_balance = models.DecimalField(_(u'customer balance'),
124
                                           max_digits=12,
125
                                           decimal_places=6,
126
                                           default=0,
127
                                           help_text=_(u"Actual customer balance."))
128
    cb_currency = models.ForeignKey(Currency,
129
                                verbose_name=_(u"Currency"))
130
    supplier_balance = models.DecimalField(_(u'supplier balance'),
131
                                           max_digits=12,
132
                                           decimal_places=6,
133
                                           default=0,
134
                                           help_text=_(u"Actual supplier balance."))
135
    max_calls = models.PositiveIntegerField(_(u'max simultaneous calls'),
136
                                            default=1,
137
                                            help_text=_(u"maximum simultaneous calls allowed for this customer account."))
138
    calls_per_second = models.PositiveIntegerField(_(u'max calls per second'),
139
                                                   default=10,
140
                                                   help_text=_(u"maximum calls per seconds allowed for this customer account."))
141
    BILLING_CYCLE_CHOICES = (
142
        ('w', _(u'weekly')),
143
        ('m', _(u'monthly')),
144
    )
145
    billing_cycle = models.CharField(_(u'billing cycle'),
146
                                     max_length=10,
147
                                     choices=BILLING_CYCLE_CHOICES,
148
                                     default='m',
149
                                     help_text=_(u"billinng cycle for invoice generation."))
150
    customer_enabled = models.BooleanField(_(u"Customer Enabled / Disabled"),
151
                                           default=True)
152
    supplier_enabled = models.BooleanField(_(u"Supplier Enabled / Disabled"),
153
                                           default=True)
154
    date_added = models.DateTimeField(_(u'date added'),
155
                                      auto_now_add=True)
156
    date_modified = models.DateTimeField(_(u'date modified'),
157
                                         auto_now=True)
158
159
    class Meta:
160
        db_table = 'company'
161
        ordering = ('name',)
162
        verbose_name = _(u"Company")
163
        verbose_name_plural = _(u"Companies")
164
165
    def clean(self):
166
        if self.vat_number:
167
            try:
168
                vatnumber.check_vies(self.vat_number)
169
            except Exception, e:
170
                raise ValidationError("""Wrong VAT number - validation made throw VIES services. %s""") % e
171
172
    def save(self, *args, **kwargs):
173
        if self.vat_number:
174
            try:
175
                self.vat_number_validated = vatnumber.check_vies(self.vat_number)
176
            except:
177
                self.vat_number_validated = False
178
        else:
179
            self.vat_number_validated = False
180
181
        super(Company, self).save(*args, **kwargs)
182
183
    def __unicode__(self):
184
        return u"%s" % self.name
185
186
    def colored_name(self):
187
        if self.customer_enabled == False and self.supplier_enabled == False:
188
            color = "red"
189
        elif self.customer_enabled == False and self.supplier_enabled == True:
190
            color = "orange"
191
        elif self.customer_enabled == True and self.supplier_enabled == False:
192
            color = "purple"
193
        else:
194
            color = "green"
195
        return " <span style=color:%s>%s</span>" % (color, self.name)
196
    colored_name.allow_tags = True
197
198
    def balance_history(self):
199
        html = '<span><a href="/extranet/pyfreebill/companybalancehistory/?company__id__exact={0}" class="btn btn-inverse btn-mini">Balance history <i class="icon-plus-sign"></i></a></span>'
200
        return format_html(html, (self.id))
201
    balance_history.allow_tags = True
202
    balance_history.short_description = 'balance history'
203
204
205
class Person(models.Model):
206
    """Person model."""
207
    first_name = models.CharField(_('first name'),
208
                                  max_length=100)
209
    last_name = models.CharField(_('last name'),
210
                                 max_length=200)
211
    middle_name = models.CharField(_('middle name'),
212
                                   max_length=200,
213
                                   blank=True,
214
                                   null=True)
215
    suffix = models.CharField(_('suffix'),
216
                              max_length=50,
217
                              blank=True,
218
                              null=True)
219
    nickname = models.CharField(_('nickname'),
220
                                max_length=100,
221
                                blank=True)
222
    slug = models.SlugField(_('slug'),
223
                            max_length=50,
224
                            unique=True)
225
    title = models.CharField(_('title'),
226
                             max_length=200,
227
                             blank=True)
228
    company = models.ForeignKey(Company,
229
                                blank=True,
230
                                null=True)
231
    about = models.TextField(_('about'),
232
                             blank=True)
233
    user = models.OneToOneField(settings.AUTH_USER_MODEL,
234
                                blank=True,
235
                                null=True,
236
                                verbose_name=_('user'))
237
    phone_number = GenericRelation('PhoneNumber')
238
    email_address = GenericRelation('EmailAddress')
239
    instant_messenger = GenericRelation('InstantMessenger')
240
    special_date = GenericRelation('SpecialDate')
241
    note = GenericRelation(Comment,
242
                           object_id_field='object_pk')
243
    date_added = models.DateTimeField(_('date added'),
244
                                      auto_now_add=True)
245
    date_modified = models.DateTimeField(_('date modified'),
246
                                         auto_now=True)
247
248
    class Meta:
249
        db_table = 'contacts_people'
250
        ordering = ('last_name', 'first_name')
251
        verbose_name = _('person')
252
        verbose_name_plural = _('people')
253
254
    def __unicode__(self):
255
        return self.fullname
256
257
    @property
258
    def fullname(self):
259
        return u"%s %s" % (self.first_name, self.last_name)
260
261
262 View Code Duplication
class Group(models.Model):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
263
    """Group model."""
264
    name = models.CharField(_('name'),
265
                            max_length=200,
266
                            unique=True)
267
    slug = models.SlugField(_('slug'),
268
                            max_length=50,
269
                            unique=True)
270
    about = models.TextField(_('about'),
271
                             blank=True)
272
    people = models.ManyToManyField(Person,
273
                                    verbose_name='people',
274
                                    blank=True,
275
                                    null=True)
276
    companies = models.ManyToManyField(Company,
277
                                       verbose_name='companies',
278
                                       blank=True,
279
                                       null=True)
280
    date_added = models.DateTimeField(_('date added'),
281
                                      auto_now_add=True)
282
    date_modified = models.DateTimeField(_('date modified'),
283
                                         auto_now=True)
284
285
    class Meta:
286
        db_table = 'contacts_groups'
287
        ordering = ('name',)
288
        verbose_name = _('group')
289
        verbose_name_plural = _('groups')
290
291
    def __unicode__(self):
292
        return u"%s" % self.name
293
294
PHONE_LOCATION_CHOICES = (
295
    ('work', _('Work')),
296
    ('mobile', _('Mobile')),
297
    ('fax', _('Fax')),
298
    ('pager', _('Pager')),
299
    ('home', _('Home')),
300
    ('other', _('Other')),
301
)
302
303
304
class PhoneNumber(models.Model):
305
    """Phone Number model."""
306
    content_type = models.ForeignKey(ContentType,
307
                                     limit_choices_to={'app_label': 'contacts'})
308
    object_id = models.IntegerField(db_index=True)
309
    content_object = generic.GenericForeignKey()
310
    phone_number = models.CharField(_('number'),
311
                                    max_length=50)
312
    location = models.CharField(_('location'),
313
                                max_length=6,
314
                                choices=PHONE_LOCATION_CHOICES,
315
                                default='work')
316
    date_added = models.DateTimeField(_('date added'),
317
                                      auto_now_add=True)
318
    date_modified = models.DateTimeField(_('date modified'),
319
                                         auto_now=True)
320
321
    def __unicode__(self):
322
        return u"%s (%s)" % (self.phone_number, self.location)
323
324
    class Meta:
325
        db_table = 'contacts_phone_numbers'
326
        verbose_name = 'phone number'
327
        verbose_name_plural = 'phone numbers'
328
329
LOCATION_CHOICES = (
330
    ('work', _('Work')),
331
    ('home', _('Home')),
332
    ('mobile', _('Mobile')),
333
    ('fax', _('Fax')),
334
    ('person', _('Personal')),
335
    ('other', _('Other'))
336
)
337
338
339
class EmailAddress(models.Model):
340
    content_type = models.ForeignKey(ContentType,
341
                                     limit_choices_to={'app_label': 'contacts'})
342
    object_id = models.IntegerField(db_index=True)
343
    content_object = generic.GenericForeignKey()
344
    email_address = models.EmailField(_('email address'))
345
    location = models.CharField(_('location'),
346
                                max_length=6,
347
                                choices=LOCATION_CHOICES,
348
                                default='work')
349
    date_added = models.DateTimeField(_('date added'),
350
                                      auto_now_add=True)
351
    date_modified = models.DateTimeField(_('date modified'),
352
                                         auto_now=True)
353
354
    def __unicode__(self):
355
        return u"%s (%s)" % (self.email_address, self.location)
356
357
    class Meta:
358
        db_table = 'contacts_email_addresses'
359
        verbose_name = 'email address'
360
        verbose_name_plural = 'email addresses'
361
362
IM_SERVICE_CHOICES = (
363
    ('aim', 'AIM'),
364
    ('msn', 'MSN'),
365
    ('icq', 'ICQ'),
366
    ('jabber', 'Jabber'),
367
    ('yahoo', 'Yahoo'),
368
    ('skype', 'Skype'),
369
    ('qq', 'QQ'),
370
    ('sametime', 'Sametime'),
371
    ('gadu-gadu', 'Gadu-Gadu'),
372
    ('google-talk', 'Google Talk'),
373
    ('twitter', 'Twitter'),
374
    ('other', _('Other'))
375
)
376
377
378
class InstantMessenger(models.Model):
379
    content_type = models.ForeignKey(ContentType,
380
                                     limit_choices_to={'app_label': 'contacts'})
381
    object_id = models.IntegerField(db_index=True)
382
    content_object = generic.GenericForeignKey()
383
    im_account = models.CharField(_('im account'),
384
                                  max_length=100)
385
    location = models.CharField(_('location'),
386
                                max_length=6,
387
                                choices=LOCATION_CHOICES,
388
                                default='work')
389
    service = models.CharField(_('service'),
390
                               max_length=11,
391
                               choices=IM_SERVICE_CHOICES,
392
                               default='jabber')
393
    date_added = models.DateTimeField(_('date added'),
394
                                      auto_now_add=True)
395
    date_modified = models.DateTimeField(_('date modified'),
396
                                         auto_now=True)
397
398
    def __unicode__(self):
399
        return u"%s (%s)" % (self.im_account, self.location)
400
401
    class Meta:
402
        db_table = 'contacts_instant_messengers'
403
        verbose_name = 'instant messenger'
404
        verbose_name_plural = 'instant messengers'
405
406
407 View Code Duplication
class WebSite(models.Model):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
408
    content_type = models.ForeignKey(ContentType,
409
                                     limit_choices_to={'app_label': 'contacts'})
410
    object_id = models.IntegerField(db_index=True)
411
    content_object = generic.GenericForeignKey()
412
    url = models.URLField(_('URL'))
413
    location = models.CharField(_('location'),
414
                                max_length=6,
415
                                choices=LOCATION_CHOICES,
416
                                default='work')
417
    date_added = models.DateTimeField(_('date added'),
418
                                      auto_now_add=True)
419
    date_modified = models.DateTimeField(_('date modified'),
420
                                         auto_now=True)
421
422
    def __unicode__(self):
423
        return u"%s (%s)" % (self.url, self.location)
424
425
    class Meta:
426
        db_table = 'contacts_web_sites'
427
        verbose_name = _('web site')
428
        verbose_name_plural = _('web sites')
429
430
    def get_absolute_url(self):
431
        return u"%s?web_site=%s" % (self.content_object.get_absolute_url(), self.pk)
432
433
434
class StreetAddress(models.Model):
435
    content_type = models.ForeignKey(ContentType,
436
                                     limit_choices_to={'app_label': 'contacts'})
437
    object_id = models.IntegerField(db_index=True)
438
    content_object = generic.GenericForeignKey()
439
    street = models.TextField(_('street'),
440
                              blank=True)
441
    city = models.CharField(_('city'),
442
                            max_length=200,
443
                            blank=True)
444
    province = models.CharField(_('province'),
445
                                max_length=200,
446
                                blank=True)
447
    postal_code = models.CharField(_('postal code'),
448
                                   max_length=10,
449
                                   blank=True)
450
    country = CountryField(_('country'))
451
    location = models.CharField(_('location'),
452
                                max_length=6,
453
                                choices=LOCATION_CHOICES,
454
                                default='work')
455
    date_added = models.DateTimeField(_('date added'),
456
                                      auto_now_add=True)
457
    date_modified = models.DateTimeField(_('date modified'),
458
                                         auto_now=True)
459
460
    def __unicode__(self):
461
        return u"%s (%s)" % (self.city, self.location)
462
463
    class Meta:
464
        db_table = 'contacts_street_addresses'
465
        verbose_name = _('street address')
466
        verbose_name_plural = _('street addresses')
467
468
469 View Code Duplication
class SpecialDate(models.Model):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
470
    content_type = models.ForeignKey(ContentType,
471
                                     limit_choices_to={'app_label': 'contacts'})
472
    object_id = models.IntegerField(db_index=True)
473
    content_object = generic.GenericForeignKey()
474
    occasion = models.TextField(_('occasion'),
475
                                max_length=200)
476
    date = models.DateField(_('date'))
477
    every_year = models.BooleanField(_('every year'),
478
                                     default=True)
479
    date_added = models.DateTimeField(_('date added'),
480
                                      auto_now_add=True)
481
    date_modified = models.DateTimeField(_('date modified'),
482
                                         auto_now=True)
483
484
    def __unicode__(self):
485
        return u"%s: %s" % (self.occasion, self.date)
486
487
    class Meta:
488
        db_table = 'contacts_special_dates'
489
        verbose_name = _('special date')
490
        verbose_name_plural = _('special dates')
491
492
493
class CompanyBalanceHistory(models.Model):
494
    """ Company balance history Model """
495
    company = models.ForeignKey(Company,
496
                                verbose_name=_(u"company"))
497
    amount_debited = models.DecimalField(_(u'amount debited'),
498
                                         max_digits=12,
499
                                         decimal_places=4)
500
    amount_refund = models.DecimalField(_(u'amount refund'),
501
                                        max_digits=12,
502
                                        decimal_places=4)
503
    customer_balance = models.DecimalField(_(u'customer balance'),
504
                                           max_digits=12,
505
                                           decimal_places=4,
506
                                           default=0,
507
                                           help_text=_(u"""Resulting customer
508
                                           balance."""))
509
    supplier_balance = models.DecimalField(_(u'provider balance'),
510
                                           max_digits=12,
511
                                           decimal_places=4,
512
                                           default=0,
513
                                           help_text=_(u"""Resulting provider
514
                                           balance."""))
515
    OPERATION_TYPE_CHOICES = (
516
        ('customer', _(u"operation on customer account")),
517
        ('provider', _(u"operation on provider account")),
518
    )
519
    operation_type = models.CharField(_(u"operation type"),
520
                                      max_length=10,
521
                                      choices=OPERATION_TYPE_CHOICES,
522
                                      default='customer')
523
    reference = models.CharField(_(u'public description'),
524
                                 max_length=255,
525
                                 blank=True)
526
    description = models.CharField(_(u'internal description'),
527
                                   max_length=255,
528
                                   blank=True)
529
    date_added = models.DateTimeField(_(u'date added'),
530
                                      auto_now_add=True)
531
    date_modified = models.DateTimeField(_(u'date modified'),
532
                                         auto_now=True)
533
534
    class Meta:
535
        db_table = 'company_balance_history'
536
        ordering = ('company', 'date_added')
537
        verbose_name = _(u'Company balance history')
538
        verbose_name_plural = _(u'Company balance history')
539
540
    def __unicode__(self):
541
        return u"%s %s %s %s" % (self.company,
542
                                 self.amount_debited,
543
                                 self.amount_refund,
544
                                 self.operation_type)
545
546
547
class CustomerDirectory(models.Model):
548
    """ Customer Directory Model """
549
    company = models.ForeignKey(Company,
550
                                verbose_name=_(u"company"))
551
    registration = models.BooleanField(_(u"Registration"),
552
                                       default=False,
553
                                       help_text=_(u"""Is registration needed
554
                                       for calling ? True, the phone needs to
555
                                       register with correct username/password.
556
                                       If false, you must specify a CIDR in SIP
557
                                       IP CIDR !"""))
558
    password = models.CharField(_(u"password"),
559
                                max_length=100,
560
                                blank=True,
561
                                help_text=_(u"""It's recommended to use strong
562
                                passwords for the endpoint."""))
563
    description = models.TextField(_(u'description'),
564
                                   blank=True)
565
    name = models.CharField(_(u"SIP username"),
566
                            max_length=50,
567
                            unique=True,
568
                            help_text=_(u"Ex.: customer SIP username, etc..."))
569
    rtp_ip = models.CharField(_(u"RTP IP CIDR"),
570
                              max_length=100,
571
                              default="auto",
572
                              help_text=_(u"""Internal IP address/mask to bind
573
                              to for RTP. Format : CIDR Ex. 192.168.1.0/32"""))
574
    sip_ip = models.CharField(_(u"SIP IP CIDR"),
575
                              max_length=100,
576
                              null=True,
577
                              blank=True,
578
                              validators=[validate_cidr],
579
                              help_text=_(u"""Internal IP address/mask to bind
580
                              to for SIP. Format : CIDR. Ex. 192.168.1.0/32
581
                              """))
582
    sip_port = models.PositiveIntegerField(_(u"SIP port"),
583
                                           default=5060)
584
    max_calls = models.PositiveIntegerField(_(u'max calls'),
585
                                            default=1,
586
                                            help_text=_(u"""max simultaneous
587
                                            calls allowed for this customer
588
                                            account."""))
589
    calls_per_second = models.PositiveIntegerField(_(u'max calls per second'),
590
                                                   default=10,
591
                                                   help_text=_(u"""maximum
592
                                                   calls per second allowed for
593
                                                   this customer account."""))
594
    log_auth_failures = models.BooleanField(_(u"log auth failures"),
595
                                            default=False,
596
                                            help_text=_(u"""It true, the server
597
                                            will log authentication failures.
598
                                            Required for Fail2ban."""))
599
    MULTIPLE_CODECS_CHOICES = (
600
        ("PCMA,PCMU,G729", _(u"PCMA,PCMU,G729")),
601
        ("PCMU,PCMA,G729", _(u"PCMU,PCMA,G729")),
602
        ("G729,PCMA,PCMU", _(u"G729,PCMA,PCMU")),
603
        ("G729,PCMU,PCMA", _(u"G729,PCMU,PCMA")),
604
        ("PCMA,G729", _(u"PCMA,G729")),
605
        ("PCMU,G729", _(u"PCMU,G729")),
606
        ("G729,PCMA", _(u"G729,PCMA")),
607
        ("G729,PCMU", _(u"G729,PCMU")),
608
        ("PCMA,PCMU", _(u"PCMA,PCMU")),
609
        ("PCMU,PCMA", _(u"PCMU,PCMA")),
610
        ("G722,PCMA,PCMU", _(u"G722,PCMA,PCMU")),
611
        ("G722,PCMU,PCMA", _(u"G722,PCMU,PCMA")),
612
        ("G722", _(u"G722")),
613
        ("G729", _(u"G729")),
614
        ("PCMU", _(u"PCMU")),
615
        ("PCMA", _(u"PCMA")),
616
        ("ALL", _(u"ALL")),
617
    )
618
    codecs = models.CharField(_(u"Codecs"),
619
                              max_length=100,
620
                              default="ALL",
621
                              choices=MULTIPLE_CODECS_CHOICES,
622
                              help_text=_(u"""Codecs allowed - beware about
623
                              order, 1st has high priority """))
624
    MULTIPLE_REG_CHOICES = (
625
        ("call-id", _(u"Call-id")),
626
        ("contact", _(u"Contact")),
627
        ("false", _(u"False")),
628
        ("true", _(u"True")))
629
    multiple_registrations = models.CharField(_(u"multiple registrations"),
630
                                              max_length=100,
631
                                              default="false",
632
                                              choices=MULTIPLE_REG_CHOICES,
633
                                              help_text=_(u"""Used to allow to
634
                                              call one extension and ring
635
                                              several phones."""))
636
    outbound_caller_id_name = models.CharField(_(u"CallerID name"),
637
                                               max_length=50,
638
                                               blank=True,
639
                                               help_text=_(u"""Caller ID name
640
                                               sent to provider on outbound
641
                                               calls."""))
642
    outbound_caller_id_number = models.CharField(_(u"""CallerID
643
                                                   num"""),
644
                                                 max_length=80,
645
                                                 blank=True,
646
                                                 help_text=_(u"""Caller ID
647
                                                 number sent to provider on
648
                                                 outbound calls."""))
649
    IEM_CHOICES = (
650
        ("false", _(u"false")),
651
        ("true", _(u"true")),
652
        ("ring_ready", _(u"ring_ready")))
653
    ignore_early_media = models.CharField(_(u"Ignore early media"),
654
                                          max_length=20,
655
                                          default="false",
656
                                          choices=IEM_CHOICES,
657
                                          help_text=_(u"""Controls if the call
658
                                                      returns on early media
659
                                                      or not. Default is false.
660
                                                      Setting the value to
661
                                                      "ring_ready" will work
662
                                                      the same as
663
                                                      ignore_early_media=true
664
                                                      but also send a SIP 180
665
                                                      to the inbound leg when
666
                                                      the first SIP 183 is
667
                                                      caught.
668
                                                      """))
669
    enabled = models.BooleanField(_(u"Enabled / Disabled"),
670
                                  default=True)
671
    fake_ring = models.BooleanField(_(u"Fake ring"),
672
                                    default=False,
673
                                    help_text=_(u"""Fake ring : Enabled /
674
                                    Disabled - Send a fake ring to the
675
                                    caller."""))
676
    cli_debug = models.BooleanField(_(u"CLI debug"),
677
                                    default=False,
678
                                    help_text=_(u"""CLI debug : Enabled /
679
                                    Disabled - Permit to see all debug
680
                                    messages on cli."""))
681
    vmd = models.BooleanField(_(u"Voicemail detection : Enabled / Disabled"),
682
                              default=False,
683
                              help_text=_(u"""Be carefull with this option, as
684
                              it takes a lot of ressources !."""))
685
    date_added = models.DateTimeField(_(u'date added'),
686
                                      auto_now_add=True)
687
    date_modified = models.DateTimeField(_(u'date modified'),
688
                                         auto_now=True)
689
690
    class Meta:
691
        db_table = 'customer_directory'
692
        ordering = ('company', 'name')
693
        verbose_name = _(u'Customer sip account')
694
        verbose_name_plural = _(u'Customer sip accounts')
695
696
    def __unicode__(self):
697
        return "%s (%s:%s)" % (self.name, self.sip_ip, self.sip_port)
698
699
    def clean(self):
700
        if (self.registration and
701
                (self.password is None or self.password == '')):
702
            raise ValidationError("""You have to specify a password if you
703
                                  want to allow registration""")
704
        if (self.registration is False and
705
                (self.sip_ip is None or self.sip_ip == '')):
706
            raise ValidationError("""You must specify a SIP IP CIDR if you do
707
                                  not want to use registration""")
708
        if self.registration and self.password:
709
            # in future use https://github.com/dstufft/django-passwords ?
710
            MIN_LENGTH = 8
711
            if len(self.password) < MIN_LENGTH:
712
                raise ValidationError("""The password must be at least %d
713
                                      characters long.""" % MIN_LENGTH)
714
            first_isalpha = self.password[0].isalpha()
715
            if all(c.isalpha() == first_isalpha for c in self.password):
716
                raise ValidationError("""The new password must contain
717
                                            at least one letter and at least
718
                                            one digit""")
719
        if self.sip_ip:
720
            m = re.search('/32$', self.sip_ip)
721
            if m:
722
                pass
723
            elif len(IPNetwork(self.sip_ip)) == 1:
724
                self.sip_ip = str(self.sip_ip) + str('/32')
725
                # add name check no space ...
726
727
# Caller ID list
728
729
730
class CalleridPrefixList(models.Model):
731
    """ CallerID List """
732
    name = models.CharField(_(u'name'),
733
                            max_length=128,
734
                            unique=True)
735
    description = models.TextField(_(u'description'),
736
                                   blank=True)
737
    date_added = models.DateTimeField(_(u'date added'),
738
                                      auto_now_add=True)
739
    date_modified = models.DateTimeField(_(u'date modified'),
740
                                         auto_now=True)
741
742
    class Meta:
743
        db_table = 'callerid_prefix_list'
744
        ordering = ('name',)
745
        verbose_name = _(u'CallerID prefix list')
746
        verbose_name_plural = _(u'CallerID prefix lists')
747
748
    def __unicode__(self):
749
        return u"%s" % self.name
750
751
    def prefix(self):
752
        html = '<span><a href="/extranet/pyfreebill/calleridprefix/?calleridprefixlist__id__exact={0}" class="btn btn-inverse btn-mini">Prefix <i class="icon-plus-sign"></i></a></span>'
753
        return format_html(html, (self.id))
754
    prefix.allow_tags = True
755
    prefix.short_description = 'prefix'
756
757
758 View Code Duplication
class CalleridPrefix(models.Model):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
759
    """ Customer Rates Model """
760
    calleridprefixlist = models.ForeignKey(CalleridPrefixList,
761
                                           verbose_name=_(u"callerid prefix list"))
762
    prefix = models.CharField(_(u'numeric prefix'),
763
                              max_length=30,
764
                              db_index=True)
765
    date_added = models.DateTimeField(_(u'date added'),
766
                                      auto_now_add=True)
767
    date_modified = models.DateTimeField(_(u'date modified'),
768
                                         auto_now=True)
769
770
    class Meta:
771
        db_table = 'caller_id_prefix'
772
        ordering = ('calleridprefixlist', 'prefix')
773
        unique_together = ("calleridprefixlist", "prefix")
774
        verbose_name = _(u'Callerid prefix')
775
        verbose_name_plural = _(u'Callerid prefix')
776
777
    def __unicode__(self):
778
        return u"%s" % self.prefix
779
780
# Provider Rates
781
782
783
class ProviderTariff(models.Model):
784
    """ Provider tariff """
785
    name = models.CharField(_(u"name"),
786
                            max_length=128)
787
    carrier = models.ForeignKey(Company,
788
                                verbose_name=_(u"Provider"),
789
                                limit_choices_to={'supplier_enabled': True})
790
    currency = models.ForeignKey(Currency,
791
                                verbose_name=_(u"Currency"))
792
    lead_strip = models.CharField(_(u'lead strip'),
793
                                  blank=True,
794
                                  default='',
795
                                  max_length=15)
796
    tail_strip = models.CharField(_(u'tail strip'),
797
                                  blank=True,
798
                                  default='',
799
                                  max_length=15)
800
    prefix = models.CharField(_(u'prefix'),
801
                              blank=True,
802
                              default='',
803
                              max_length=15)
804
    suffix = models.CharField(_(u'suffix'),
805
                              blank=True,
806
                              default='',
807
                              max_length=15)
808
    description = models.TextField(_(u'description'),
809
                                   blank=True)
810
    CALLERID_FILTER_CHOICES = (
811
        ('1', _(u"No filter")),
812
        ('2', _(u"Prefix authorized")),
813
        ('3', _(u"Prefix prohibited")),
814
    )
815
    callerid_filter = models.CharField(_(u"CallerID Prefix filter"),
816
                                       max_length=2,
817
                                       choices=CALLERID_FILTER_CHOICES,
818
                                       default='1')
819
    callerid_list = models.ForeignKey(CalleridPrefixList,
820
                                      verbose_name=_(u"CallerID prefix List"),
821
                                      blank=True,
822
                                      null=True)
823
    date_start = models.DateTimeField()
824
    date_end = models.DateTimeField()
825
    quality = models.IntegerField(_(u'quality'),
826
                                  blank=True,
827
                                  default='100',
828
                                  help_text=_(u"Order by quality."))
829
    reliability = models.IntegerField(_(u'reliability'),
830
                                      blank=True,
831
                                      default='100',
832
                                      help_text=_(u"Order by reliability."))
833
    cid = models.CharField(_(u'cid'),
834
                           blank=True,
835
                           default='',
836
                           max_length=25,
837
                           help_text=_(u"Regex to modify CallerID number."))
838
    enabled = models.BooleanField(_(u"Enabled / Disabled"),
839
                                  default=True)
840
    date_added = models.DateTimeField(_(u'date added'),
841
                                      auto_now_add=True)
842
    date_modified = models.DateTimeField(_(u'date modified'),
843
                                         auto_now=True)
844
845
    class Meta:
846
        db_table = 'provider_tariff'
847
        ordering = ('enabled',
848
                    'quality',
849
                    'reliability')
850
        verbose_name = _(u'provider ratecard')
851
        verbose_name_plural = _(u'provider ratecards')
852
853
    def __unicode__(self):
854
        return u"%s" % self.name
855
856
    def rates(self):
857
        html = '<span><a href="/extranet/pyfreebill/providerrates/?provider_tariff__id__exact={0}" class="btn btn-inverse btn-mini">Rates <i class="icon-plus-sign"></i></a></span>'
858
        return format_html(html, (self.id))
859
    rates.allow_tags = True
860
    rates.short_description = 'rates'
861
862
863
class ProviderRates(models.Model):
864
    """ Provider Rates Model """
865
    destination = models.CharField(_(u'destination'),
866
                                   blank=True,
867
                                   default='',
868
                                   null=True,
869
                                   max_length=128,
870
                                   db_index=True)
871
    digits = models.CharField(_(u'numeric prefix'),
872
                              max_length=30,
873
                              db_index=True)
874
    cost_rate = models.DecimalField(_(u'Cost rate'),
875
                                    max_digits=11,
876
                                    decimal_places=5)
877
    block_min_duration = models.IntegerField(_(u'block min duration'),
878
                                             default=1)
879
    init_block = models.DecimalField(_(u'Init block rate'),
880
                                     max_digits=11,
881
                                     decimal_places=5,
882
                                     default=0)
883
    provider_tariff = models.ForeignKey(ProviderTariff)
884
    date_start = models.DateTimeField()
885
    date_end = models.DateTimeField()
886
    enabled = models.BooleanField(_(u"Enabled / Disabled"), default=True)
887
    date_added = models.DateTimeField(_(u'date added'), auto_now_add=True)
888
    date_modified = models.DateTimeField(_(u'date modified'), auto_now=True)
889
890
    class Meta:
891
        db_table = 'provider_rates'
892
        ordering = ('enabled', 'provider_tariff', 'digits')
893
        index_together = [
894
            ["provider_tariff", "digits", "enabled"],
895
        ]
896
        unique_together = ("digits", "provider_tariff")
897
        verbose_name = _(u'provider rate')
898
        verbose_name_plural = _(u'provider rates')
899
900
    def __unicode__(self):
901
        return u"%s %s %s " % (self.digits,
902
                               self.cost_rate,
903
                               self.provider_tariff)
904
905
    def set_bar(self, value):
906
        self.bar = value
907
    simple_import_methods = ('set_bar',)
908
909
910
# LCR
911
912
913 View Code Duplication
class LCRGroup(models.Model):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
914
    """ LCR group model """
915
    name = models.CharField(_(u"name"),
916
                            max_length=128,
917
                            unique=True)
918
    description = models.TextField(_(u'description'),
919
                                   blank=True)
920
    LCR_TYPE_CHOICES = (
921
        ('p', _(u"lower price")),
922
        ('q', _(u"best quality")),
923
        ('r', _(u"best reliability")),
924
        ('l', _(u"load balance")),
925
    )
926
    lcrtype = models.CharField(_(u"lcr type"),
927
                               max_length=10,
928
                               choices=LCR_TYPE_CHOICES,
929
                               default='p')
930
    date_added = models.DateTimeField(_(u'date added'),
931
                                      auto_now_add=True)
932
    date_modified = models.DateTimeField(_(u'date modified'),
933
                                         auto_now=True)
934
935
    class Meta:
936
        db_table = 'lcr_group'
937
        ordering = ('name',)
938
        verbose_name = _(u'LCR')
939
        verbose_name_plural = _(u'LCRs')
940
941
    def __unicode__(self):
942
        return u"%s %s " % (self.name, self.lcrtype)
943
944
945 View Code Duplication
class LCRProviders(models.Model):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
946
    """ LCR group model """
947
    lcr = models.ForeignKey(LCRGroup,
948
                            verbose_name=_(u"LCR"))
949
    provider_tariff = models.ForeignKey(ProviderTariff,
950
                                        verbose_name=_(u"Provider tariff"))
951
    date_added = models.DateTimeField(_(u'date added'),
952
                                      auto_now_add=True)
953
    date_modified = models.DateTimeField(_(u'date modified'),
954
                                         auto_now=True)
955
956
    class Meta:
957
        db_table = 'lcr_providers'
958
        verbose_name = _(u'LCR provider')
959
        verbose_name_plural = _(u'LCR providers')
960
961
    def __unicode__(self):
962
        return u"%s - %s " % (self.lcr, self.provider_tariff)
963
964
    def rates(self):
965
        html = '<span><a href="/extranet/pyfreebill/providerrates/?provider_tariff__id__exact={0}" class="btn btn-inverse btn-mini">Rates <i class="icon-plus-sign"></i></a></span>'
966
        return format_html(html, (self.provider_tariff))
967
    rates.allow_tags = True
968
    rates.short_description = 'rates'
969
970
971
# Ratecard
972
973
974
class RateCard(models.Model):
975
    """ RateCard Model """
976
    name = models.CharField(_(u'name'),
977
                            max_length=128,
978
                            unique=True)
979
    description = models.TextField(_(u'description'),
980
                                   blank=True)
981
    currency = models.ForeignKey(Currency,
982
                                verbose_name=_(u"Currency"))
983
    lcrgroup = models.ForeignKey(LCRGroup,
984
                                 verbose_name=_(u"lcr"))
985
    CALLERID_FILTER_CHOICES = (
986
        ('1', _(u"No filter")),
987
        ('2', _(u"Prefix authorized")),
988
        ('3', _(u"Prefix prohibited")),
989
    )
990
    callerid_filter = models.CharField(_(u"CallerID Prefix filter"),
991
                                       max_length=2,
992
                                       choices=CALLERID_FILTER_CHOICES,
993
                                       default='1')
994
    callerid_list = models.ForeignKey(CalleridPrefixList,
995
                                      verbose_name=_(u"CallerID prefix List"),
996
                                      blank=True,
997
                                      null=True)
998
    enabled = models.BooleanField(_(u"Enabled / Disabled"),
999
                                  default=True)
1000
    date_added = models.DateTimeField(_(u'date added'),
1001
                                      auto_now_add=True)
1002
    date_modified = models.DateTimeField(_(u'date modified'),
1003
                                         auto_now=True)
1004
1005
    class Meta:
1006
        db_table = 'ratecard'
1007
        ordering = ('name', 'enabled')
1008
        verbose_name = _(u'Customer ratecard')
1009
        verbose_name_plural = _(u'Customer ratecards')
1010
1011
    def __unicode__(self):
1012
        return u"%s" % self.name
1013
1014
    def rates(self):
1015
        html = '<span><a href="/extranet/pyfreebill/customerrates/?ratecard__id__exact={0}" class="btn btn-inverse btn-mini">Rates <i class="icon-plus-sign"></i></a></span>'
1016
        return format_html(html, (self.id))
1017
    rates.allow_tags = True
1018
    rates.short_description = 'Rates'
1019
1020
    def lcr(self):
1021
        html = '<span><a href="/extranet/pyfreebill/lcrgroup/{0}/" class="btn btn-inverse btn-mini">LCR <i class="icon-plus-sign"></i></a></span>'
1022
        return format_html(html, (self.lcrgroup.pk))
1023
    lcr.allow_tags = True
1024
    lcr.short_description = 'lcr'
1025
1026
1027
class CustomerRates(models.Model):
1028
    """ Customer Rates Model """
1029
    ratecard = models.ForeignKey(RateCard,
1030
                                 verbose_name=_(u"ratecard"))
1031
    destination = models.CharField(_(u'destination'),
1032
                                   blank=True,
1033
                                   default='',
1034
                                   null=True,
1035
                                   max_length=128,
1036
                                   db_index=True)
1037
    prefix = models.CharField(_(u'numeric prefix'),
1038
                              max_length=30,
1039
                              db_index=True)
1040
    rate = models.DecimalField(_(u'sell rate'),
1041
                               max_digits=11,
1042
                               decimal_places=5,
1043
                               help_text=_(u"to block the prefix, put -1"))
1044
    block_min_duration = models.IntegerField(_(u'block min duration'),
1045
                                             default=1)
1046
    init_block = models.DecimalField(_(u'Init block rate'),
1047
                                     max_digits=11,
1048
                                     decimal_places=5,
1049
                                     default=0)
1050
    date_start = models.DateTimeField()
1051
    date_end = models.DateTimeField()
1052
    enabled = models.BooleanField(_(u"Enabled"),
1053
                                  default=True)
1054
    date_added = models.DateTimeField(_(u'date added'),
1055
                                      auto_now_add=True)
1056
    date_modified = models.DateTimeField(_(u'date modified'),
1057
                                         auto_now=True)
1058
1059
    class Meta:
1060
        db_table = 'customer_rates'
1061
        ordering = ('ratecard', 'prefix', 'enabled')
1062
        unique_together = ("ratecard", "prefix")
1063
        verbose_name = _(u'customer rate')
1064
        verbose_name_plural = _(u'customer rates')
1065
1066
    def __unicode__(self):
1067
        return u"%s" % self.ratecard
1068
1069
1070
class CustomerRateCards(models.Model):
1071
    """ Customer rates Cards Model """
1072
    company = models.ForeignKey(Company,
1073
                                verbose_name=_(u"company"))
1074
    ratecard = models.ForeignKey(RateCard,
1075
                                 verbose_name=_(u"ratecard"))
1076
    description = models.TextField(_(u'description'),
1077
                                   blank=True)
1078
    tech_prefix = models.CharField(_(u"technical prefix"),
1079
                                   blank=True,
1080
                                   default='',
1081
                                   null=True,
1082
                                   max_length=7)
1083
    DEFAULT_PRIORITY_CHOICES = (
1084
        (1, _(u'1')),
1085
        (2, _(u'2')),
1086
        (3, _(u'3')),
1087
    )
1088
    priority = models.IntegerField(_(u'priority'),
1089
                                   choices=DEFAULT_PRIORITY_CHOICES,
1090
                                   help_text=_(u"""Priority order, 1 is the
1091
                                               higher priority and 3 the
1092
                                               lower one. Correct values
1093
                                               are : 1, 2 or 3 !."""))
1094
    discount = models.DecimalField(_(u'discount'),
1095
                                   max_digits=3,
1096
                                   decimal_places=2,
1097
                                   default=0,
1098
                                   help_text=_(u"""ratecard discount. For
1099
                                               10% discount, enter 10 !"""))
1100
    allow_negative_margin = models.BooleanField(_(u"""Allow calls with
1101
                                                  negative margin"""),
1102
                                                default=False)
1103
    date_added = models.DateTimeField(_(u'date added'),
1104
                                      auto_now_add=True)
1105
    date_modified = models.DateTimeField(_(u'date modified'),
1106
                                         auto_now=True)
1107
1108
    class Meta:
1109
        db_table = 'customer_ratecards'
1110
        ordering = ('company', 'priority', 'ratecard')
1111
        verbose_name = _(u'Customer Ratecard Allocation')
1112
        verbose_name_plural = _(u'Customer ratecard Allocations')
1113
1114
    def __unicode__(self):
1115
        return u"%s - Priority: %s Desc: %s" % (self.ratecard,
1116
                                                self.priority,
1117
                                                self.description)
1118
1119
1120
# NORMALIZATION
1121
1122
1123 View Code Duplication
class DestinationNumberRules(models.Model):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1124
    """ Destination Number Normalization Rules """
1125
    prefix = models.CharField(_(u'numeric prefix'),
1126
                              max_length=30)
1127
    description = models.TextField(_(u'description'),
1128
                                   blank=True)
1129
    format_num = models.CharField(_(u"Rule format"),
1130
                                  max_length=150,
1131
                                  help_text=_(u"""example for Tunisia :
1132
                                      ^216[%d][%d][%d][%d][%d][%d][%d][%d]
1133
                                      $"""))
1134
    date_added = models.DateTimeField(_(u'date added'),
1135
                                      auto_now_add=True)
1136
    date_modified = models.DateTimeField(_(u'date modified'),
1137
                                         auto_now=True)
1138
1139
    class Meta:
1140
        db_table = 'destination_norm_rules'
1141
        ordering = ('prefix',)
1142
        verbose_name = _(u'Destination Number Normalization Rule')
1143
        verbose_name_plural = _(u'Destination Number Normalization Rules')
1144
1145
    def __unicode__(self):
1146
        return u"%s -> %s " % (self.prefix, self.format_num)
1147
1148
1149 View Code Duplication
class CustomerNormalizationRules(models.Model):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1150
    """ Customer Normalization Rules """
1151
    company = models.ForeignKey(Company,
1152
                                verbose_name=_(u"customer"))
1153
    prefix = models.CharField(_(u'rule title'),
1154
                              max_length=30)
1155
    description = models.TextField(_(u'description'),
1156
                                   blank=True)
1157
    remove_prefix = models.CharField(_(u"remove prefix"),
1158
                                     blank=True,
1159
                                     default='',
1160
                                     max_length=15)
1161
    add_prefix = models.CharField(_(u"add prefix"),
1162
                                  blank=True,
1163
                                  default='',
1164
                                  max_length=15)
1165
    date_added = models.DateTimeField(_(u'date added'),
1166
                                      auto_now_add=True)
1167
    date_modified = models.DateTimeField(_(u'date modified'),
1168
                                         auto_now=True)
1169
1170
    class Meta:
1171
        db_table = 'customer_norm_rules'
1172
        ordering = ('company', 'prefix')
1173
        verbose_name = _(u'Customer Normalization Rule')
1174
        verbose_name_plural = _(u'Customer Normalization Rules')
1175
1176
    def __unicode__(self):
1177
        return u"%s -> %s -%s +%s" % (self.company,
1178
                                      self.prefix,
1179
                                      self.remove_prefix,
1180
                                      self.add_prefix)
1181
1182
1183 View Code Duplication
class CarrierNormalizationRules(models.Model):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1184
    """ Carrier Normalization Rules """
1185
    company = models.ForeignKey(Company,
1186
                                verbose_name=_(u"provider"))
1187
    prefix = models.CharField(_(u'rule title'),
1188
                              max_length=30)
1189
    description = models.TextField(_(u'description'),
1190
                                   blank=True)
1191
    remove_prefix = models.CharField(_(u"remove prefix"),
1192
                                     blank=True,
1193
                                     default='',
1194
                                     max_length=15)
1195
    add_prefix = models.CharField(_(u"add prefix"),
1196
                                  blank=True,
1197
                                  default='',
1198
                                  max_length=15)
1199
    date_added = models.DateTimeField(_(u'date added'),
1200
                                      auto_now_add=True)
1201
    date_modified = models.DateTimeField(_(u'date modified'),
1202
                                         auto_now=True)
1203
1204
    class Meta:
1205
        db_table = 'carrier_norm_rules'
1206
        ordering = ('company', 'prefix')
1207
        verbose_name = _(u'Provider Normalization Rule')
1208
        verbose_name_plural = _(u'Provider Normalization Rules')
1209
1210
    def __unicode__(self):
1211
        return u"%s -> %s -%s +%s" % (self.company,
1212
                                      self.prefix,
1213
                                      self.remove_prefix,
1214
                                      self.add_prefix)
1215
1216
1217 View Code Duplication
class CustomerCIDNormalizationRules(models.Model):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1218
    """ Customer Caller ID Number Normalization Rules """
1219
    company = models.ForeignKey(Company,
1220
                                verbose_name=_(u"customer"))
1221
    prefix = models.CharField(_(u'rule title'),
1222
                              max_length=30)
1223
    description = models.TextField(_(u'description'),
1224
                                   blank=True)
1225
    remove_prefix = models.CharField(_(u"remove prefix"),
1226
                                     blank=True,
1227
                                     default='',
1228
                                     max_length=15)
1229
    add_prefix = models.CharField(_(u"add prefix"),
1230
                                  blank=True,
1231
                                  default='',
1232
                                  max_length=15)
1233
    date_added = models.DateTimeField(_(u'date added'),
1234
                                      auto_now_add=True)
1235
    date_modified = models.DateTimeField(_(u'date modified'),
1236
                                         auto_now=True)
1237
1238
    class Meta:
1239
        db_table = 'customer_cid_norm_rules'
1240
        ordering = ('company', )
1241
        verbose_name = _(u'Customer CallerID Normalization Rule')
1242
        verbose_name_plural = _(u'Customer CallerID Normalization Rules')
1243
1244
    def __unicode__(self):
1245
        return u"%s -> -%s +%s" % (self.company,
1246
                                   self.remove_prefix,
1247
                                   self.add_prefix)
1248
1249
1250 View Code Duplication
class CarrierCIDNormalizationRules(models.Model):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1251
    """ Carrier Caller ID Number Normalization Rules """
1252
    company = models.ForeignKey(Company,
1253
                                verbose_name=_(u"provider"))
1254
    prefix = models.CharField(_(u'rule title'),
1255
                              max_length=30)
1256
    description = models.TextField(_(u'description'),
1257
                                   blank=True)
1258
    remove_prefix = models.CharField(_(u"remove prefix"),
1259
                                     blank=True,
1260
                                     default='',
1261
                                     max_length=15)
1262
    add_prefix = models.CharField(_(u"add prefix"),
1263
                                  blank=True,
1264
                                  default='',
1265
                                  max_length=15)
1266
    date_added = models.DateTimeField(_(u'date added'),
1267
                                      auto_now_add=True)
1268
    date_modified = models.DateTimeField(_(u'date modified'),
1269
                                         auto_now=True)
1270
1271
    class Meta:
1272
        db_table = 'carrier_cid_norm_rules'
1273
        ordering = ('company', )
1274
        verbose_name = _(u'Provider CallerID Normalization Rule')
1275
        verbose_name_plural = _(u'Provider CallerID Normalization Rules')
1276
1277
    def __unicode__(self):
1278
        return u"%s -> -%s +%s" % (self.company,
1279
                                   self.remove_prefix,
1280
                                   self.add_prefix)
1281
1282
# ACL
1283
1284
1285 View Code Duplication
class AclLists(models.Model):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1286
    """ ACL list model """
1287
    acl_name = models.CharField(_(u'name'),
1288
                                max_length=128)
1289
    DEFAULT_POLICY_CHOICES = (
1290
        ('deny', _(u'deny')),
1291
        ('allow', _(u'allow')),
1292
    )
1293
    default_policy = models.CharField(_(u'default policy'),
1294
                                      max_length=10,
1295
                                      choices=DEFAULT_POLICY_CHOICES,
1296
                                      default='deny')
1297
    date_added = models.DateTimeField(_(u'date added'),
1298
                                      auto_now_add=True)
1299
    date_modified = models.DateTimeField(_(u'date modified'),
1300
                                         auto_now=True)
1301
1302
    class Meta:
1303
        db_table = 'acl_lists'
1304
        ordering = ('acl_name',)
1305
        verbose_name = _(u'ACL list')
1306
        verbose_name_plural = _(u'ACL lists')
1307
1308
    def __unicode__(self):
1309
        return u"%s" % self.acl_name
1310
1311
1312 View Code Duplication
class AclNodes(models.Model):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1313
    """ ACL NODES model """
1314
    company = models.ForeignKey(Company,
1315
                                verbose_name=_(u"company"))
1316
    cidr = models.CharField(_(u"ip/cidr Address"),
1317
                            max_length=100,
1318
                            help_text=_(u"Customer IP or cidr address."))
1319
    POLICY_CHOICES = (
1320
        ('deny', _('deny')),
1321
        ('allow', _('allow')),
1322
    )
1323
    policy = models.CharField(_(u"policy"),
1324
                              max_length=10,
1325
                              choices=POLICY_CHOICES,
1326
                              default='allow')
1327
    acllist = models.ForeignKey(AclLists,
1328
                                verbose_name=_(u"acl list"))
1329
    date_added = models.DateTimeField(_(u'date added'),
1330
                                      auto_now_add=True)
1331
    date_modified = models.DateTimeField(_(u'date modified'),
1332
                                         auto_now=True)
1333
1334
    class Meta:
1335
        db_table = 'acl_nodes'
1336
        ordering = ('company', 'policy', 'cidr')
1337
        verbose_name = _(u'ACL node')
1338
        verbose_name_plural = _(u'ACL nodes')
1339
1340
    def __unicode__(self):
1341
        return u"%s %s" % (self.company, self.cidr)
1342
1343
# VOIP SWITCH
1344
1345
1346
class VoipSwitch(models.Model):
1347
    """ VoipSwitch Profile """
1348
    name = models.CharField(_(u"Switch name"),
1349
                            max_length=50,
1350
                            help_text=_(u"Switch name"))
1351
    ip = models.CharField(_(u"switch IP"),
1352
                          max_length=100,
1353
                          default="auto",
1354
                          help_text=_(u"Switch IP."))
1355
    esl_listen_ip = models.CharField(_(u"event socket switch IP"),
1356
                                     max_length=100,
1357
                                     default="127.0.0.1",
1358
                                     help_text=_(u"Event socket switch IP."))
1359
    esl_listen_port = models.PositiveIntegerField(_(u"""event socket switch
1360
                                                    port"""),
1361
                                                  default="8021",
1362
                                                  help_text=_(u"""Event socket
1363
                                                              switch port."""))
1364
    esl_password = models.CharField(_(u"event socket switch password"),
1365
                                    max_length=30,
1366
                                    default="ClueCon",
1367
                                    help_text=_(u"""Event socket switch
1368
                                                password."""))
1369
    date_added = models.DateTimeField(_(u'date added'),
1370
                                      auto_now_add=True)
1371
    date_modified = models.DateTimeField(_(u'date modified'),
1372
                                         auto_now=True)
1373
1374
    class Meta:
1375
        db_table = 'voip_switch'
1376
        ordering = ('name', )
1377
        verbose_name = _(u'VoIP Switch')
1378
        verbose_name_plural = _(u'VoIP Switches')
1379
1380
    def __unicode__(self):
1381
        return u"%s (:%s)" % (self.name, self.ip)
1382
1383
# SOFIA
1384
1385
1386
class SipProfile(models.Model):
1387
    """ Sofia Sip profile """
1388
    name = models.CharField(_(u"SIP profile name"),
1389
                            max_length=50,
1390
                            unique=True,
1391
                            help_text=_(u"""E.g.: the name you want ..."""))
1392
    user_agent = models.CharField(_(u"User agent name"),
1393
                                  max_length=50,
1394
                                  default="pyfreebilling",
1395
                                  help_text=_(u"""E.g.: the user agent
1396
                                              you want ... - take care
1397
                                              with certain characters
1398
                                              such as @ could cause others sip
1399
                                              proxies reject yours messages as
1400
                                              invalid ! """))
1401
    ext_rtp_ip = models.CharField(_(u"external RTP IP"),
1402
                                  max_length=100,
1403
                                  default="auto",
1404
                                  help_text=_(u"""External/public IP
1405
                                    address to bind to for RTP."""))
1406
    ext_sip_ip = models.CharField(_(u"external SIP IP"),
1407
                                  max_length=100,
1408
                                  default="auto",
1409
                                  help_text=_(u"""External/public IP
1410
                                              address to bind to for
1411
                                              SIP."""))
1412
    rtp_ip = models.CharField(_(u"RTP IP"),
1413
                              max_length=100,
1414
                              default="auto",
1415
                              help_text=_(u"""Internal IP address to bind
1416
                                          to for RTP."""))
1417
    sip_ip = models.CharField(_(u"SIP IP"),
1418
                              max_length=100,
1419
                              default="auto",
1420
                              help_text=_(u"""Internal IP address to bind
1421
                                          to for SIP."""))
1422
    sip_port = models.PositiveIntegerField(_(u"SIP port"),
1423
                                           default=5060)
1424
    disable_transcoding = models.BooleanField(_(u"disable transcoding"),
1425
                                              default=True,
1426
                                              help_text=_(u"""If true, you
1427
                                                          can not use
1428
                                                          transcoding."""))
1429
    accept_blind_reg = models.BooleanField(_(u"accept blind registration"),
1430
                                           default=False,
1431
                                           help_text=_(u"""If true, anyone can
1432
                                                       register to the server
1433
                                                       and will not be
1434
                                                       challenged for
1435
                                                       username/password
1436
                                                       information."""))
1437
    disable_register = models.BooleanField(_(u"disable register"),
1438
                                           default=True,
1439
                                           help_text=_(u"""disable register
1440
                                                       which may be undesirable
1441
                                                       in a public switch """))
1442
    apply_inbound_acl = models.BooleanField(_(u"Apply an inbound ACL"),
1443
                                            default=True,
1444
                                            help_text=_(u"""If true, FS will
1445
                                                      apply the default acl
1446
                                                      list : domains """))
1447
    auth_calls = models.BooleanField(_(u"authenticate calls"),
1448
                                     default=True,
1449
                                     help_text=_(u"""If true, FreeeSWITCH will
1450
                                                 authorize all calls on this
1451
                                                 profile, i.e. challenge the
1452
                                                 other side for
1453
                                                 username/password information.
1454
                                                 """))
1455
    log_auth_failures = models.BooleanField(_(u"log auth failures"),
1456
                                            default=False,
1457
                                            help_text=_(u"""It true, log
1458
                                                      authentication failures.
1459
                                                      Required for Fail2ban.
1460
                                                      """))
1461
    MULTIPLE_CODECS_CHOICES = (
1462
        ("PCMA,PCMU,G729", _(u"PCMA,PCMU,G729")),
1463
        ("PCMU,PCMA,G729", _(u"PCMU,PCMA,G729")),
1464
        ("G729,PCMA,PCMU", _(u"G729,PCMA,PCMU")),
1465
        ("G729,PCMU,PCMA", _(u"G729,PCMU,PCMA")),
1466
        ("PCMA,G729", _(u"PCMA,G729")),
1467
        ("PCMU,G729", _(u"PCMU,G729")),
1468
        ("G729,PCMA", _(u"G729,PCMA")),
1469
        ("G729,PCMU", _(u"G729,PCMU")),
1470
        ("PCMA,PCMU", _(u"PCMA,PCMU")),
1471
        ("PCMU,PCMA", _(u"PCMU,PCMA")),
1472
        ("G722,PCMA,PCMU", _(u"G722,PCMA,PCMU")),
1473
        ("G722,PCMU,PCMA", _(u"G722,PCMU,PCMA")),
1474
        ("G722", _(u"G722")),
1475
        ("G729", _(u"G729")),
1476
        ("PCMU", _(u"PCMU")),
1477
        ("PCMA", _(u"PCMA")),
1478
        ("ALL", _(u"ALL")),
1479
    )
1480
    inbound_codec_prefs = models.CharField(_(u"inbound codec prefs"),
1481
                                           max_length=100,
1482
                                           choices=MULTIPLE_CODECS_CHOICES,
1483
                                           default="G729,PCMU,PCMA",
1484
                                           help_text=_(u"""Define allowed
1485
                                                       preferred codecs for
1486
                                                       inbound calls."""))
1487
    outbound_codec_prefs = models.CharField(_(u"outbound codec prefs"),
1488
                                            max_length=100,
1489
                                            choices=MULTIPLE_CODECS_CHOICES,
1490
                                            default="G729,PCMU,PCMA",
1491
                                            help_text=_(u"""Define allowed
1492
                                                        preferred codecs for
1493
                                                        outbound calls."""))
1494
    aggressive_nat_detection = models.BooleanField(_(u"""Agressive NAT
1495
                                                     detection"""),
1496
                                                   default=False,
1497
                                                   help_text=_(u"""This will
1498
                                                               enable NAT mode
1499
                                                               if the network
1500
                                                               IP/port from
1501
                                                               which therequest
1502
                                                               was received
1503
                                                               differs from the
1504
                                                               IP/Port
1505
                                                               combination in
1506
                                                               the SIP Via:
1507
                                                               header, or if
1508
                                                               the Via: header
1509
                                                               contains the
1510
                                                               received
1511
                                                               parameter"""))
1512
    NDLB_rec_in_nat_reg_c = models.BooleanField(_(u"""NDLB received
1513
                                                  in nat reg contact"""),
1514
                                                default=False,
1515
                                                help_text=_(u"""add a;received=
1516
                                                            "ip:port"
1517
                                                            to the contact when
1518
                                                            replying to
1519
                                                            register
1520
                                                            for nat handling
1521
                                                            """))
1522
    NDLB_FP_CHOICES = (
1523
        ("true", _(u"true")),
1524
        ("safe", _(u"safe")),
1525
    )
1526
    NDLB_force_rport = models.CharField(_(u"""NDLB Force rport"""),
1527
                                        max_length=10,
1528
                                        choices=NDLB_FP_CHOICES,
1529
                                        null=True,
1530
                                        blank=True,
1531
                                        default="Null",
1532
                                        help_text=_(u"""This will force
1533
                                                    FreeSWITCH to send
1534
                                                    SIP responses to the
1535
                                                    network port from
1536
                                                    which they were received.
1537
                                                    Use at your own risk!"""))
1538
    NDLB_broken_auth_hash = models.BooleanField(_(u"""NDLB broken auth hash
1539
                                                  """),
1540
                                                default=False,
1541
                                                help_text=_(u"""Used for when
1542
                                                            phones respond to a
1543
                                                            challenged ACK
1544
                                                            with method INVITE
1545
                                                            in the hash"""))
1546
    enable_timer = models.BooleanField(_(u"""Enable timer"""),
1547
                                       default=False,
1548
                                       help_text=_(u"""This enables or disables
1549
                                                   support for RFC 4028 SIP
1550
                                                   Session Timers"""))
1551
    session_timeout = models.PositiveIntegerField(_(u"""Session timeout"""),
1552
                                                  default=1800,
1553
                                                  help_text=_(u"""session
1554
                                                              timers for all
1555
                                                              call to expire
1556
                                                              after the
1557
                                                              specified seconds
1558
                                                              Then it will send
1559
                                                              another invite
1560
                                                              --re-invite. If
1561
                                                              not specified
1562
                                                              defaults to 30
1563
                                                              minutes. Some
1564
                                                              gateways may
1565
                                                              reject values
1566
                                                              less than 30
1567
                                                              minutes. This
1568
                                                              values refers to
1569
                                                              Session-Expires
1570
                                                              in RFC 4028 -The
1571
                                                              time at which
1572
                                                              an element will
1573
                                                              consider the
1574
                                                              session timed
1575
                                                              out, if no
1576
                                                              successful
1577
                                                              session refresh
1578
                                                              transaction
1579
                                                              occurs
1580
                                                              beforehand-
1581
                                                              """))
1582
    rtp_rewrite_timestamps = models.BooleanField(_(u"""RTP rewrite timestamps"""),
1583
                                       default=False,
1584
                                       help_text=_(u"""If you don't want to pass
1585
                                           through timestampes from 1 RTP call
1586
                                           to another"""))
1587
    pass_rfc2833 = models.BooleanField(_(u"""pass rfc2833"""),
1588
                                       default=False,
1589
                                       help_text=_(u"""pass rfc2833"""))
1590
    date_added = models.DateTimeField(_(u'date added'),
1591
                                      auto_now_add=True)
1592
    date_modified = models.DateTimeField(_(u'date modified'),
1593
                                         auto_now=True)
1594
1595
    class Meta:
1596
        db_table = 'sip_profile'
1597
        ordering = ('name', )
1598
        unique_together = ("sip_ip", "sip_port")
1599
        verbose_name = _(u'SIP profile')
1600
        verbose_name_plural = _(u'SIP profiles')
1601
1602
    def __unicode__(self):
1603
        return u"%s (%s:%s)" % (self.name, self.sip_ip, self.sip_port)
1604
1605
    def get_gateways(self):
1606
        """Get all gateways in the system assigned to this sip profile."""
1607
        retval = []
1608
        accounts = Company.objects.filter(supplier_enabled=True)
1609
        for account in accounts:
1610
            for gateway in account.sofiagateway_set.all():
1611
                if gateway.sip_profile.id == self.id:
1612
                    retval.append(gateway)
1613
        return retval
1614
1615
1616
class SofiaGateway(models.Model):
1617
    name = models.CharField(_(u"name"),
1618
                            max_length=100,
1619
                            unique=True)
1620
    sip_profile = models.ForeignKey('SipProfile',
1621
                                    verbose_name=_(u"SIP profile"),
1622
                                    help_text=_(u"""Which Sip Profile
1623
                                        communication with this gateway will
1624
                                        take place on."""))
1625
    company = models.ForeignKey(Company,
1626
                                verbose_name=_(u"Provider"),
1627
                                db_index=True)
1628
    channels = models.PositiveIntegerField(_(u"channels number"),
1629
                                           default=1,
1630
                                           help_text=_(u"""maximum simultaneous
1631
                                               calls allowed for this gateway.
1632
                                               """))
1633
    enabled = models.BooleanField(_(u"Enabled"),
1634
                                  default=True)
1635
    prefix = models.CharField(_(u'prefix'),
1636
                              blank=True,
1637
                              default='',
1638
                              max_length=15)
1639
    suffix = models.CharField(_(u'suffix'),
1640
                              blank=True,
1641
                              default='',
1642
                              max_length=15)
1643
    MULTIPLE_CODECS_CHOICES = (
1644
        ("PCMA,PCMU,G729", _(u"PCMA,PCMU,G729")),
1645
        ("PCMU,PCMA,G729", _(u"PCMU,PCMA,G729")),
1646
        ("G729,PCMA,PCMU", _(u"G729,PCMA,PCMU")),
1647
        ("G729,PCMU,PCMA", _(u"G729,PCMU,PCMA")),
1648
        ("PCMA,G729", _(u"PCMA,G729")),
1649
        ("PCMU,G729", _(u"PCMU,G729")),
1650
        ("G729,PCMA", _(u"G729,PCMA")),
1651
        ("G729,PCMU", _(u"G729,PCMU")),
1652
        ("PCMA,PCMU", _(u"PCMA,PCMU")),
1653
        ("PCMU,PCMA", _(u"PCMU,PCMA")),
1654
        ("G722,PCMA,PCMU", _(u"G722,PCMA,PCMU")),
1655
        ("G722,PCMU,PCMA", _(u"G722,PCMU,PCMA")),
1656
        ("G722", _(u"G722")),
1657
        ("G729", _(u"G729")),
1658
        ("PCMU", _(u"PCMU")),
1659
        ("PCMA", _(u"PCMA")),
1660
        ("ALL", _(u"ALL")),
1661
    )
1662
    codec = models.CharField(_(u"Codecs"),
1663
                              max_length=30,
1664
                              default="ALL",
1665
                              choices=MULTIPLE_CODECS_CHOICES,
1666
                              help_text=_(u"""Codecs allowed - beware about
1667
                              order, 1st has high priority """))
1668
    username = models.CharField(_(u"username"),
1669
                                blank=True,
1670
                                default='',
1671
                                max_length=35)
1672
    password = models.CharField(_(u"password"),
1673
                                blank=True,
1674
                                default='',
1675
                                max_length=35)
1676
    register = models.BooleanField(_(u"register"),
1677
                                   default=False)
1678
    proxy = models.CharField(_(u"proxy"),
1679
                             max_length=48,
1680
                             default="",
1681
                             help_text=_(u"IP if register is False."))
1682
    extension = models.CharField(_(u"extension number"),
1683
                                 max_length=50,
1684
                                 blank=True,
1685
                                 default="",
1686
                                 help_text=_(u"""Extension for inbound calls.
1687
                                     Same as username, if blank."""))
1688
    realm = models.CharField(_(u"realm"),
1689
                             max_length=50,
1690
                             blank=True,
1691
                             default="",
1692
                             help_text=_(u"""Authentication realm. Same as
1693
                                 gateway name, if blank."""))
1694
    from_domain = models.CharField(_(u"from domain"),
1695
                                   max_length=50,
1696
                                   blank=True,
1697
                                   default="",
1698
                                   help_text=_(u"""Domain to use in from field.
1699
                                       Same as realm if blank."""))
1700
    expire_seconds = models.PositiveIntegerField(_(u"expire seconds"),
1701
                                                 default=3600,
1702
                                                 null=True)
1703
    retry_seconds = models.PositiveIntegerField(_(u"retry seconds"),
1704
                                                default=30,
1705
                                                null=True,
1706
                                                help_text=_(u"""How many
1707
                                                    seconds before a retry when
1708
                                                    a failure or timeout occurs
1709
                                                    """))
1710
    caller_id_in_from = models.BooleanField(_(u"caller ID in From field"),
1711
                                            default=True,
1712
                                            help_text=_(u"""Use the callerid of
1713
                                                an inbound call in the from
1714
                                                field on outbound calls via
1715
                                                this gateway."""))
1716
    SIP_CID_TYPE_CHOICES = (
1717
        ('none', _(u'none')),
1718
        ('default', _(u'default')),
1719
        ('pid', _(u'pid')),
1720
        ('rpid', _(u'rpid')),
1721
    )
1722
    sip_cid_type = models.CharField(_(u'SIP CID type'),
1723
                                    max_length=10,
1724
                                    choices=SIP_CID_TYPE_CHOICES,
1725
                                    default='rpid',
1726
                                    help_text=_(u"""Modify callerID in SDP
1727
                                        Headers."""))
1728
    date_added = models.DateTimeField(_(u'date added'),
1729
                                      auto_now_add=True)
1730
    date_modified = models.DateTimeField(_(u'date modified'),
1731
                                         auto_now=True)
1732
1733
    class Meta:
1734
        db_table = 'sofia_gateway'
1735
        ordering = ('company', 'name')
1736
        verbose_name = _(u"Sofia gateway")
1737
        verbose_name_plural = _(u"Sofia gateways")
1738
1739
    def __unicode__(self):
1740
        return u"%s" % self.name
1741
1742
# Hangup Cause
1743
1744
1745 View Code Duplication
class HangupCause(models.Model):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1746
    """ Hangup Cause Model """
1747
    code = models.PositiveIntegerField(_(u"Hangup code"),
1748
                                       unique=True,
1749
                                       help_text=_(u"ITU-T Q.850 Code."))
1750
    enumeration = models.CharField(_(u"enumeration"),
1751
                                   max_length=100,
1752
                                   null=True,
1753
                                   blank=True,
1754
                                   help_text=_(u"enumeration."))
1755
    cause = models.CharField(_(u"cause"),
1756
                             max_length=100,
1757
                             null=True,
1758
                             blank=True,
1759
                             help_text=_(u"Cause."))
1760
    description = models.TextField(_(u'description'),
1761
                                   blank=True)
1762
    date_added = models.DateTimeField(_(u'date added'),
1763
                                      auto_now_add=True)
1764
    date_modified = models.DateTimeField(_(u'date modified'),
1765
                                         auto_now=True)
1766
1767
    class Meta:
1768
        db_table = 'hangup_cause'
1769
        ordering = ('code',)
1770
        verbose_name = _(u"hangupcause")
1771
        verbose_name_plural = _(u"hangupcauses")
1772
1773
    def __unicode__(self):
1774
        return u"[%s] %s" % (self.code, self.enumeration)
1775
1776
# CDR
1777
1778
1779
class CDR(models.Model):
1780
    """ CDR Model    """
1781
    customer = models.ForeignKey(Company, verbose_name=_(u"customer"), null=True, related_name="customer_related")
1782
    customer_ip = models.CharField(_(u"customer IP address"), max_length=100, null=True, help_text=_(u"Customer IP address."))
1783
    uuid = models.CharField(_(u"UUID"), max_length=100, null=True)
1784
    bleg_uuid = models.CharField(_(u"b leg UUID"), null=True, default="", max_length=100)
1785
    caller_id_number = models.CharField(_(u"caller ID num"), max_length=100, null=True)
1786
    destination_number = models.CharField(_(u"Dest. number"), max_length=100, null=True)
1787
    chan_name = models.CharField(_(u"channel name"), max_length=100, null=True)
1788
    start_stamp = models.DateTimeField(_(u"start time"), null=True, db_index=True)
1789
    answered_stamp = models.DateTimeField(_(u"answered time"), null=True)
1790
    end_stamp = models.DateTimeField(_(u"hangup time"), null=True)
1791
    duration = models.IntegerField(_(u"global duration"), null=True)
1792
    effectiv_duration = models.IntegerField(_(u"total duration"), null=True, help_text=_(u"Global call duration since call has been received by the switch in ms."))
1793
    effective_duration = models.IntegerField(_(u"effective duration"), null=True, help_text=_(u"real call duration in s."))
1794
    billsec = models.IntegerField(_(u"billed duration"), null=True, help_text=_(u"billed call duration in s."))
1795
    read_codec = models.CharField(_(u"read codec"), max_length=20, null=True)
1796
    write_codec = models.CharField(_(u"write codec"), max_length=20, null=True)
1797
    hangup_cause = models.CharField(_(u"hangup cause"), max_length=50, null=True, db_index=True)
1798
    hangup_cause_q850 = models.IntegerField(_(u"q.850"), null=True)
1799
    gateway = models.ForeignKey(SofiaGateway, verbose_name=_(u"gateway"), null=True)
1800
    cost_rate = models.DecimalField(_(u'buy rate'), max_digits=11, decimal_places=5, default="0", null=True)
1801
    total_sell = models.DecimalField(_(u'total sell'), max_digits=11, decimal_places=5, default="0", null=True)
1802
    total_cost = models.DecimalField(_(u'total cost'), max_digits=11, decimal_places=5, default="0", null=True)
1803
    prefix = models.CharField(_(u'Prefix'), max_length=30, null=True)
1804
    country = models.CharField(_(u'Country'), max_length=100, null=True)
1805
    rate = models.DecimalField(_(u'sell rate'), max_digits=11, decimal_places=5, null=True)
1806
    init_block = models.DecimalField(_(u'Init block rate'), max_digits=11, decimal_places=5, null=True)
1807
    block_min_duration = models.IntegerField(_(u'block min duration'), null=True)
1808
    lcr_carrier_id = models.ForeignKey(Company, verbose_name=_(u"provider"), null=True, related_name="carrier_related")
1809
    ratecard_id = models.ForeignKey(RateCard, null=True, verbose_name=_(u"ratecard"))
1810
    lcr_group_id = models.ForeignKey(LCRGroup, null=True, verbose_name=_(u"lcr group"))
1811
    sip_user_agent = models.CharField(_(u'sip user agent'), null=True, max_length=100)
1812
    sip_rtp_rxstat = models.CharField(_(u'sip rtp rx stat'), null=True, max_length=30)
1813
    sip_rtp_txstat = models.CharField(_(u'sip rtp tx stat'), null=True, max_length=30)
1814
    switchname = models.CharField(_(u"switchname"), null=True, default="", max_length=100)
1815
    switch_ipv4 = models.CharField(_(u"switch ipv4"), null=True, default="", max_length=100)
1816
    hangup_disposition = models.CharField(_(u"hangup disposition"), null=True, default="", max_length=100)
1817
    sip_hangup_cause = models.CharField(_(u"SIP hangup cause"), null=True, default="", max_length=100)
1818
    sell_destination = models.CharField(_(u'sell destination'), blank=True, default='', null=True, max_length=128, db_index=True)
1819
    cost_destination = models.CharField(_(u'cost destination'), blank=True, default='', null=True, max_length=128, db_index=True)
1820
1821
    class Meta:
1822
        db_table = 'cdr'
1823
        ordering = ('start_stamp', 'customer')
1824
        verbose_name = _(u"CDR")
1825
        verbose_name_plural = _(u"CDRs")
1826
1827
    def __unicode__(self):
1828
        if self.start_stamp:
1829
            return self.start_stamp
1830
        else:
1831
            return self.custom_alias_name
1832
1833
    def hangup_cause_colored(self):
1834
        if self.billsec == 0:
1835
            color = "red"
1836
        else:
1837
            color = "green"
1838
        return " <span style=color:%s>%s</span>" % (color, self.hangup_cause)
1839
    hangup_cause_colored.allow_tags = True
1840
1841
    @property
1842
    def daily_total_answered_calls(self):
1843
        return qsstats.QuerySetStats(self.objects.all().exclude(effective_duration="0").filter(hangup_cause="NORMAL_CLEARING"), 'start_stamp', aggregate=Count('id')).this_day()
1844
1845
    @property
1846
    def daily_total_calls(self):
1847
        return qsstats.QuerySetStats(self.objects.all(), 'start_stamp', aggregate=Count('id')).this_day()
1848
1849
    @property
1850
    def daily_total_effective_duration_calls(self):
1851
        return qsstats.QuerySetStats(self.objects.all().exclude(effective_duration="0").filter(hangup_cause="NORMAL_CLEARING"), 'start_stamp', aggregate=Sum('effective_duration')).this_day()
1852
1853
    @property
1854
    def daily_total_sell_calls(self):
1855
        return qsstats.QuerySetStats(self.objects.all().exclude(effective_duration="0").filter(hangup_cause="NORMAL_CLEARING"), 'start_stamp', aggregate=Sum('total_sell')).this_day()
1856
1857
    @property
1858
    def daily_total_cost_calls(self):
1859
        return qsstats.QuerySetStats(self.objects.all().exclude(effective_duration="0").filter(hangup_cause="NORMAL_CLEARING"), 'start_stamp', aggregate=Sum('total_cost')).this_day()
1860
1861
    def _get_min_effective_duration(self):
1862
        if self.effective_duration:
1863
            min = int(self.effective_duration / 60)
1864
            sec = int(self.effective_duration % 60)
1865
        else:
1866
            min = 0
1867
            sec = 0
1868
1869
        return "%02d:%02d" % (min, sec)
1870
    min_effective_duration = property(_get_min_effective_duration)
1871
1872
    def _get_total_sell(self):
1873
        if self.rate and self.rate != 0:
1874
            totalsell = decimal.Decimal(self.billsec) * decimal.Decimal(self.rate) / 60
1875
        else:
1876
            totalsell = 0.000000
1877
        if self.init_block:
1878
            totalsell = decimal.Decimal(totalsell) + decimal.Decimal(self.init_block)
1879
        return round(totalsell, 6)
1880
    total_sell_py = property(_get_total_sell)
1881
1882
    def _get_total_cost(self):
1883
        if self.cost_rate:
1884
            totalcost = decimal.Decimal(self.effective_duration) * decimal.Decimal(self.cost_rate) / 60
1885
        else:
1886
            totalcost = 0.000000
1887
        return round(totalcost, 6)
1888
    total_cost_py = property(_get_total_cost)
1889
1890
    def _get_effective_duration(self):
1891
        if self.effectiv_duration:
1892
            effdur = math.ceil(self.effectiv_duration / 1000.0)
1893
        else:
1894
            effdur = 0
1895
        return int(effdur)
1896
    effective_duration_py = property(_get_effective_duration)
1897
1898
    def _get_billsec(self):
1899
        if self.block_min_duration and self.effective_duration:
1900
            if self.effective_duration < self.block_min_duration:
1901
                billsec = self.block_min_duration
1902
            else:
1903
                billsec = math.ceil(self.effective_duration / self.block_min_duration) * self.block_min_duration
1904
        else:
1905
            billsec = self.effective_duration
1906
        return int(billsec)
1907
    billsec_py = property(_get_billsec)
1908
1909
    def success_cdr(self):
1910
        return self.CDR.objects.exclude(effective_duration="0")
1911
1912
# STATS
1913
1914
1915
class DimDate(models.Model):
1916
    """ Date dimension """
1917
    date = models.DateTimeField()
1918
    day = models.CharField(_(u'day'), max_length=2)
1919
    day_of_week = models.CharField(_(u'day of the week'), max_length=30)
1920
    hour = models.CharField(_(u'hour'), max_length=2, null=True, blank=True)
1921
    month = models.CharField(_(u'month'), max_length=2)
1922
    quarter = models.CharField(_(u'quarter'), max_length=2)
1923
    year = models.CharField(_(u'year'), max_length=4)
1924
1925
    class Meta:
1926
        db_table = 'date_dimension'
1927
        ordering = ('date',)
1928
        verbose_name = _(u"date dimension")
1929
        verbose_name_plural = _(u"date dimensions")
1930
1931
    def __unicode__(self):
1932
        return u"%s" % self.date
1933
1934
1935
class DimCustomerHangupcause(models.Model):
1936
    """ Dimension Customer / Hangupcause Model """
1937
    customer = models.ForeignKey(Company, verbose_name=_(u"customer"))
1938
    destination = models.CharField(_(u'destination'), max_length=250, null=True, blank=True)
1939
    hangupcause = models.CharField(_(u'hangupcause'), max_length=100, null=True, blank=True)
1940
    date = models.ForeignKey(DimDate, verbose_name=_(u"date"))
1941
    total_calls = models.IntegerField(_(u"total calls"))
1942
1943
    class Meta:
1944
        db_table = 'dim_customer_hangupcause'
1945
        ordering = ('date', 'customer', 'hangupcause')
1946
        verbose_name = _(u"Customer Hangupcause stats")
1947
        verbose_name_plural = _(u"Customer Hangupcause stats")
1948
1949
    def __unicode__(self):
1950
        return u"%s -c: %s -h: %s" % (self.date, self.customer, self.hangupcause)
1951
1952
1953
class DimCustomerSipHangupcause(models.Model):
1954
    """ Dimension Customer / SIP Hangupcause Model """
1955
    customer = models.ForeignKey(Company, verbose_name=_(u"customer"))
1956
    destination = models.CharField(_(u'destination'), max_length=250, null=True, blank=True)
1957
    sip_hangupcause = models.CharField(_(u'sip hangupcause'), max_length=100, null=True, blank=True)
1958
    date = models.ForeignKey(DimDate, verbose_name=_(u"date"))
1959
    total_calls = models.IntegerField(_(u"total calls"))
1960
1961
    class Meta:
1962
        db_table = 'dim_customer_sip_hangupcause'
1963
        ordering = ('date', 'customer', 'sip_hangupcause')
1964
        verbose_name = _(u"Customer SIP Hangupcause stats")
1965
        verbose_name_plural = _(u"Customer SIP Hangupcause stats")
1966
1967
    def __unicode__(self):
1968
        return u"%s -c: %s -h: %s" % (self.date, self.customer, self.sip_hangupcause)
1969
1970
1971
class DimProviderHangupcause(models.Model):
1972
    """ Dimension Provider / Hangupcause Model """
1973
    provider = models.ForeignKey(Company, verbose_name=_(u"provider"))
1974
    destination = models.CharField(_(u'destination'), max_length=250, null=True, blank=True)
1975
    hangupcause = models.CharField(_(u'hangupcause'), max_length=100, null=True, blank=True)
1976
    date = models.ForeignKey(DimDate, verbose_name=_(u"date"))
1977
    total_calls = models.IntegerField(_(u"total calls"))
1978
1979
    class Meta:
1980
        db_table = 'dim_provider_hangupcause'
1981
        ordering = ('date', 'provider', 'hangupcause')
1982
        verbose_name = _(u"Provider Hangupcause stats")
1983
        verbose_name_plural = _(u"Provider Hangupcause stats")
1984
1985
    def __unicode__(self):
1986
        return u"%s -c: %s -h: %s" % (self.date, self.provider, self.hangupcause)
1987
1988
1989
class DimProviderSipHangupcause(models.Model):
1990
    """ Dimension Provider / SIP Hangupcause Model """
1991
    provider = models.ForeignKey(Company, verbose_name=_(u"provider"))
1992
    destination = models.CharField(_(u'destination'), max_length=250, null=True, blank=True)
1993
    sip_hangupcause = models.CharField(_(u'sip hangupcause'), max_length=100, null=True, blank=True)
1994
    date = models.ForeignKey(DimDate, verbose_name=_(u"date"))
1995
    total_calls = models.IntegerField(_(u"total calls"))
1996
1997
    class Meta:
1998
        db_table = 'dim_provider_sip_hangupcause'
1999
        ordering = ('date', 'provider', 'sip_hangupcause')
2000
        verbose_name = _(u"Provider SIP Hangupcause stats")
2001
        verbose_name_plural = _(u"Provider SIP Hangupcause stats")
2002
2003
    def __unicode__(self):
2004
        return u"%s -c: %s -h: %s" % (self.date, self.provider, self.sip_hangupcause)
2005
2006
2007
class DimCustomerDestination(models.Model):
2008
    """ Dimension Customer / Destination Model """
2009
    customer = models.ForeignKey(Company, verbose_name=_(u"customer"))
2010
    destination = models.CharField(_(u'destination'), max_length=250, null=True, blank=True)
2011
    date = models.ForeignKey(DimDate, verbose_name=_(u"date"))
2012
    total_calls = models.IntegerField(_(u"total calls"), default=0)
2013
    success_calls = models.IntegerField(_(u"success calls"), default=0)
2014
    total_duration = models.IntegerField(_(u"total duration"), default=0)
2015
    avg_duration = models.IntegerField(_(u"average duration"), default=0)
2016
    max_duration = models.IntegerField(_(u"max duration"), default=0)
2017
    min_duration = models.IntegerField(_(u"min duration"), default=0)
2018
    total_sell = models.DecimalField(_(u'total sell'), max_digits=12, decimal_places=2)
2019
    total_cost = models.DecimalField(_(u'total cost'), max_digits=12, decimal_places=2)
2020
2021
    class Meta:
2022
        db_table = 'dim_customer_destination'
2023
        ordering = ('date', 'customer', 'destination')
2024
        verbose_name = _(u"Customer destination stats")
2025
        verbose_name_plural = _(u"Customer destination stats")
2026
2027
    def __unicode__(self):
2028
        return u"%s -c: %s -d: %s" % (self.date, self.customer, self.destination)
2029
2030
    def _get_margin(self):
2031
        if self.total_sell and self.total_cost:
2032
            margin = self.total_sell - self.total_cost
2033
        else:
2034
            margin = 0
2035
        return round(margin, 2)
2036
    margin = property(_get_margin)
2037
2038
2039
class DimProviderDestination(models.Model):
2040
    """ Dimension Provider / Destination Model """
2041
    provider = models.ForeignKey(Company, verbose_name=_(u"provider"))
2042
    destination = models.CharField(_(u'destination'), max_length=250, null=True, blank=True)
2043
    date = models.ForeignKey(DimDate, verbose_name=_(u"date"))
2044
    total_calls = models.IntegerField(_(u"total calls"), default=0)
2045
    success_calls = models.IntegerField(_(u"success calls"), default=0)
2046
    total_duration = models.IntegerField(_(u"total duration"), default=0)
2047
    avg_duration = models.IntegerField(_(u"average duration"), default=0)
2048
    max_duration = models.IntegerField(_(u"max duration"), default=0)
2049
    min_duration = models.IntegerField(_(u"min duration"), default=0)
2050
    total_sell = models.DecimalField(_(u'total sell'), max_digits=12, decimal_places=2)
2051
    total_cost = models.DecimalField(_(u'total cost'), max_digits=12, decimal_places=2)
2052
2053
    class Meta:
2054
        db_table = 'dim_provider_destination'
2055
        ordering = ('date', 'provider', 'destination')
2056
        verbose_name = _(u"Provider destination stats")
2057
        verbose_name_plural = _(u"Provider destination stats")
2058
2059
    def __unicode__(self):
2060
        return u"%s -p: %s -d: %s" % (self.date, self.provider, self.destination)
2061
2062
    def get_daily_providers_stats(self, today, delta, interval):
2063
        qs = self.model._default_manager.filter(date__lte=lastday)
2064
        qss = qsstats.QuerySetStats(qs, 'date')
2065
        lastday = today - datetime.timedelta(days=delta)
2066
        return qss.time_series(lastday, today, interval)
2067
2068
    def get_current_week_daily_provider_stats(self, period, interval):
2069
        today = datetime.date.today()
2070
        return self.get_daily_providers_stats(today, period, interval)
2071
2072
    def get_day_total_calls(self):
2073
        qs = DimProviderDestination.objects.all()
2074
        day_qs = qs.values('date').annotate(day_total_calls=Sum('total_calls'), day_success_calls=Sum('success_calls'), day_total_duration=Sum('total_duration'), day_total_sell=Sum('total_sell'), day_total_cost=Sum('total_cost')).order_by('date')
2075
        return [t[1] for t in day_qs]
2076