Example #1
0
class RecurringLineItem(models.Model):
    """Extra information needed for a recurring line item, such as a subscription.
    
    To make a trial, put the trial price, tax, etc. into the parent LineItem, and mark this object
    trial=True, trial_length=xxx
    """
    lineitem = models.OneToOneField(LineItem,
                                    verbose_name=_("Line Item"),
                                    primary_key=True,
                                    related_name="recurdetails")
    recurring = models.BooleanField(
        _("Recurring Billing"),
        help_text=
        _("Customer will be charged the regular product price on a periodic basis."
          ),
        default=False)
    recurring_price = CurrencyField("Recurring Price",
                                    default=Decimal('0.00'),
                                    max_digits=18,
                                    decimal_places=2)
    recurring_shipping = CurrencyField("Recurring Shipping Price",
                                       default=Decimal('0.00'),
                                       max_digits=18,
                                       decimal_places=2)
    recurring_times = models.PositiveIntegerField(
        _("Recurring Times"),
        help_text=
        _("Number of payments which will occur at the regular rate.  (optional)"
          ),
        default=0)
    expire_length = models.PositiveIntegerField(
        _("Duration"),
        help_text=_("Length of each billing cycle"),
        null=True,
        blank=True)
    trial = models.BooleanField(_("Trial?"), default=False)
    trial_price = CurrencyField("Trial Price",
                                default=Decimal('0.00'),
                                max_digits=18,
                                decimal_places=2)
    trial_length = models.PositiveIntegerField(
        _("Trial length"),
        help_text="Number of subscription units for the trial",
        default=0)
    trial_times = models.PositiveIntegerField(
        _("Trial Times"), help_text="Number of trial cycles", default=1)
    SUBSCRIPTION_UNITS = (('DAY', _('Days')), ('MONTH', _('Months')))
    expire_unit = models.CharField(_("Expire Unit"),
                                   max_length=5,
                                   choices=SUBSCRIPTION_UNITS,
                                   default="DAY",
                                   null=False)
    SHIPPING_CHOICES = (
        ('0', _('No Shipping Charges')),
        ('1', _('Pay Shipping Once')),
        ('2', _('Pay Shipping Each Billing Cycle')),
    )
Example #2
0
class PaymentBase(models.Model):
    method = models.CharField(_("Payment Method"), max_length=25, blank=True)
    amount = CurrencyField(_("amount"),
                           max_digits=18,
                           decimal_places=2,
                           blank=True,
                           null=True)
    time_stamp = models.DateTimeField(_("timestamp"), blank=True, null=True)
    transaction_id = models.CharField(_("Transaction ID"),
                                      max_length=45,
                                      blank=True,
                                      null=True)
    details = models.CharField(_("Details"),
                               max_length=255,
                               blank=True,
                               null=True)
    reason_code = models.CharField(_('Reason Code'),
                                   max_length=255,
                                   blank=True,
                                   null=True)

    def save(self, *args, **kwargs):
        if not self.pk:
            self.time_stamp = datetime.now()

        super(PaymentBase, self).save(*args, **kwargs)

    class Meta:
        abstract = True
Example #3
0
class Tariff(models.Model):
    """
    digits - префикс передномером 4367890
    name - напрвление Austria-mobile Hutchison 3G
    tariff_plan - номер к какому тарифному плану относится смотреть id TariffPlan
    """
    digits = models.CharField(_(u'Digits'), max_length=45, blank=True, help_text=_(u'matching digits'))
    code = models.PositiveIntegerField(_(u'Code'), default=0)
    # TODO: напрвление
    name = models.CharField(_(u'Направление'), max_length=200, blank=True)
    country_code = models.IntegerField(_(u'Country Code'), default=0)
    name_lcr = models.CharField(_(u'Направление по базе LCR'), max_length=200, blank=True)
    rate = CurrencyField(_(u"Стоимость"), max_digits=18, decimal_places=6, default=Decimal("0.0"), display_decimal=6)
    #price = MoneyField(max_digits=18, decimal_places=2, default=Money(0, Currency.objects.get_default()))
    price =  models.DecimalField(_(u'Price'), default=Decimal("0"), max_digits=18, decimal_places=6)
    price_currency = models.CharField(_(u'Currency name'), max_length=3, default="USD")
    tariff_plan = models.ForeignKey('TariffPlan', related_name='tpg')
    #tariff = models.ForeignKey(TariffPlan)
    date_start = models.DateField(_(u'Date Start'), default=datetime.date.today())
    date_end = models.DateField(_(u'Date End'), default=datetime.date.max)
    enabled = models.BooleanField(_(u'Enable'), default=True)
    weeks = models.SmallIntegerField(_(u'Week'), default=0)

    time_start = models.TimeField(_(u'Time Start'), default=datetime.datetime.strptime("00:00", "%H:%M"))
    time_end = models.TimeField(_(u'Time End'), default=datetime.datetime.strptime("23:59", "%H:%M"))
    cash_min = CurrencyField(_(u"Плата за соединение"), max_digits=18, decimal_places=2, default=Decimal("0.0"), display_decimal=2)
    time_round = models.SmallIntegerField(_(u'Округление'), default=1, help_text=_(u'Округляем время если 1 то до секунды, 60 до минуты, 30 то полминуты'))
    operator_type = models.CharField(_(u'Тип'), choices=OPERATOR_TYPE_CHOICES, max_length=1, default='N')
    #SmallIntegerField(_(u'Тип'), choices=, default=0, help_text=_(u'период за который снимается абонентская плата'))
    objects =TariffManager()
    active_objects = GenericManager( enabled = True ) # only active entries
    inactive_objects = GenericManager( enabled = False ) # only inactive entries

    class Meta:
        #ordering = []
        db_table = 'tariff'
        verbose_name, verbose_name_plural = _(u"Тариф"), _(u"Тарифы")

    def __unicode__(self):
        return self.name

    @models.permalink
    def get_absolute_url(self):
        return ('Tariff', [self.id])

    @property
    def enabled_date(self):
        """docstring for enable_date"""

        de = ''
        if ru_strftime(format=u"%Y", date=self.date_end) != "9999":
            de = u" по %s" % ru_strftime(format=u"%d.%m.%Y", date=self.date_end)
        return u"c {0}{1}".format(ru_strftime(format=u"%d.%m.%Y", date=self.date_start), de)


    def rate_currency(self):
        """docstring for rate_currency"""
        return "%(rate)0.2f %(currency)s" % {'rate': self.rate, 'currency': self.currency}
    rate_currency.short_description = _(u'Цена 1 мин.')

    @property
    def currency(self):
        return u'у.е.'
Example #4
0
class TariffPlan(models.Model):
    """
    Тарифный план
    Для загрузки тарифного плана из cvs файла необходимо установить его формат
    Например
    tariff_format = ;|digits,name,tariff_rate,tariff,date_start=%d.%m.%Y 00:00,date_end
    ; - разделитель
    далее через запятую перечисляются поля для заполнения ВНИМАНИЕ все поля обязательны
    rate стоимость 1 минуты 0.338700
    date_start - Дата начала  01.12.08
    date_end - Дата окончания 31.12.99

    если есть пустая колонка то вставте other
    если формат даты отличается то необходимо указать формат date_start=%d.%m.%Y 00:00
    """
    name = models.CharField(_(u'Name'), max_length=80)
    cash_min = CurrencyField(_(u"Плата за соединение"), max_digits=18, decimal_places=2, default=Decimal("0.00"), display_decimal=2)
    fee = CurrencyField(_(u"Абонплата"), max_digits=18, decimal_places=2, default=Decimal("0.00"), display_decimal=2)
    fee_period = models.SmallIntegerField(_(u'Период'), choices=FEE_TARIFF_CHOICES, default=0, help_text=_(u'период за который снимается абонентская плата'))
    activation = CurrencyField(_(u"Активация"), max_digits=18, decimal_places=2, default=Decimal("0.00"), display_decimal=4, help_text=_(u'стоимость активации тарифного плана'))
    limit_day = models.IntegerField(_(u'Лимит в День'), default=0, help_text=_(u'Лимит безплатных минут в день 0 - без ограничений'))
    limit_month = models.IntegerField(_(u'Лимит в Месяц'), default=0, help_text=_(u'Лимит безплатных минут в месяц 0 - без ограничений'))
    date_start = models.DateField(_(u'Date Start'), default=datetime.date.today())
    date_end = models.DateField(_(u'Date End'), default=datetime.date.max)
    pay_round = models.SmallIntegerField(_(u'Округление'), default=1, help_text=_(u'Округляем стоимость разговора если 1 то до копейки для цен не поумолчанию'))
    enabled = models.BooleanField(_(u'Enable'), default=True)
    primary = models.BooleanField(_(u'По умолчанию'), default=False)
    site = models.ForeignKey(Site, default=1, verbose_name=_('Site'))
    #tariff_format = models.CharField(_(u'Tariff Format'), default="delimiter=';'time_format='%d.%m.%Y 00:00'lcr|country_code|special_digits|name|rate", max_length=250, help_text=_(u'Формат CSV файла для загрузки  тарифного плана'))
    description = models.CharField(_(u'Description'), blank=True, max_length=240)
    objects = models.Manager() # default manager must be always on first place! It's used as default_manager
    active_objects = GenericManager( enabled = True ) # only active entries
    inactive_objects = GenericManager( enabled = False ) # only inactive entries

    class Meta:
        ordering = ['-primary']
        db_table = 'tariff_plan'
        verbose_name, verbose_name_plural = _(u"Тарифный план"), _(u"Тарифные планы")

    def __unicode__(self):
        return self.name

    @models.permalink
    def get_absolute_url(self):
        return ('Tarif', [self.id])


    def fee_view(self):
        """docstring for fee_view"""
        if self.fee_period != 0:
            return "%(rate)0.2f %(currency)s/%(fp)s/" % {'rate': self.fee, 'currency': self.currency, 'fp': self.get_fee_period_display()}
        else:
            return self.get_fee_period_display()
    fee_view.short_description = _(u'Абонплата')


    def cash_currency(self):
        """docstring for rate_currency"""
        return "%(rate)0.2f %(currency)s" % {'rate': self.cash_min, 'currency': self.currency}
    cash_currency.short_description = _(u'Плата за соединение.')

    @property
    def currency(self):
        return u'у.е.'

    @property
    def enabled_date(self):
        """docstring for enable_date"""
        de = ''
        if ru_strftime(format=u"%Y", date=self.date_end) != "9999":
            de = u" по %s" % ru_strftime(format=u"%d.%m.%Y", date=self.date_end)
        return u"c {0}{1}".format(ru_strftime(format=u"%d.%m.%Y", date=self.date_start), de)
Example #5
0
class LineItem(models.Model):
    """A single line item in a purchase.  This is optional, only needed for certain
    gateways such as Google or PayPal."""
    sku = models.CharField(_("SKU"), max_length=7, default="1")
    purchase = models.ForeignKey(Purchase,
                                 verbose_name=_("Purchase"),
                                 related_name="lineitems")
    ordering = models.PositiveIntegerField(_('Ordering'), default=0)
    name = models.CharField(_('Item'), max_length=100)
    description = models.TextField(_('Description'), blank=True)
    quantity = models.DecimalField(_("Quantity"),
                                   max_digits=18,
                                   decimal_places=6,
                                   default=Decimal('1'))
    unit_price = CurrencyField(_("Unit price"),
                               max_digits=18,
                               decimal_places=10)
    sub_total = CurrencyField(_("Line item price"),
                              max_digits=18,
                              decimal_places=10)
    shipping = CurrencyField(_("Shipping price"),
                             max_digits=18,
                             decimal_places=10,
                             default=Decimal('0.00'))
    discount = CurrencyField(_("Line item discount"),
                             max_digits=18,
                             decimal_places=10,
                             default=Decimal('0.00'))
    tax = CurrencyField(_("Line item tax"),
                        max_digits=18,
                        decimal_places=10,
                        default=Decimal('0.00'))
    total = CurrencyField(_("Total"),
                          max_digits=18,
                          decimal_places=2,
                          default=Decimal('0.00'))

    class Meta:
        ordering = ('ordering', )

    @property
    def int_quantity(self):
        return self.quantity.quantize(Decimal('1'), ROUND_UP)

    @property
    def is_recurring(self):
        recur = False
        try:
            if self.recurdetails and self.recurdetails is not None:
                recur = True
        except RecurringLineItem.DoesNotExist:
            pass

        return recur

    def recalc(self):
        """Recalculate totals"""
        self.sub_total = self.quantity * self.unit_price
        self.total = self.sub_total - self.discount + self.tax + self.shipping

    def __unicode__(self):
        return "LineItem: %s - %d" % (self.name, self.total)
Example #6
0
class Purchase(models.Model):
    """
    Collects information about an order and tracks
    its state.
    """
    site = models.ForeignKey(Site, verbose_name=_('Site'))
    client_pk = models.PositiveIntegerField(_(u'Client ID'), null=True)
    client_ct = models.ForeignKey(ContentType,
                                  verbose_name=_(u'Client type'),
                                  null=True)
    client = GenericForeignKey('client_ct', 'client_pk')
    orderno = models.CharField(_("Order Number"), max_length=20)
    first_name = models.CharField(_("First name"), max_length=30)
    last_name = models.CharField(_("Last name"), max_length=30)
    email = models.EmailField(_("Email"), max_length=75, default="")
    phone = models.CharField(_("Phone Number"), max_length=30, default="")
    ship_street1 = models.CharField(_("Street"), max_length=80, default="")
    ship_street2 = models.CharField(_("Street"), max_length=80, default="")
    ship_city = models.CharField(_("City"), max_length=50, default="")
    ship_state = models.CharField(_("State"), max_length=50, default="")
    ship_postal_code = models.CharField(_("Zip Code"),
                                        max_length=30,
                                        default="")
    ship_country = models.CharField(_("Country"), max_length=2, default="")
    bill_street1 = models.CharField(_("Street"), max_length=80, default="")
    bill_street2 = models.CharField(_("Street"), max_length=80, default="")
    bill_city = models.CharField(_("City"), max_length=50, default="")
    bill_state = models.CharField(_("State"), max_length=50, default="")
    bill_postal_code = models.CharField(_("Zip Code"),
                                        max_length=30,
                                        default="")
    bill_country = models.CharField(_("Country"), max_length=2, default="")
    sub_total = CurrencyField(_("Subtotal"),
                              max_digits=18,
                              decimal_places=2,
                              blank=True,
                              null=True,
                              display_decimal=4)
    tax = CurrencyField(_("Tax"),
                        max_digits=18,
                        decimal_places=2,
                        blank=True,
                        null=True,
                        display_decimal=4)
    shipping = CurrencyField(_("Shipping Cost"),
                             max_digits=18,
                             decimal_places=2,
                             blank=True,
                             null=True,
                             display_decimal=4)
    total = CurrencyField(_("Total"),
                          max_digits=18,
                          decimal_places=2,
                          display_decimal=4)
    time_stamp = models.DateTimeField(_("Timestamp"), blank=True, null=True)

    objects = PurchaseManager()

    def __unicode__(self):
        return "Purchase #%s on Order #%s" % (self.id, self.orderno)

    @property
    def authorized_remaining(self):
        """Returns the total value of all un-captured authorizations"""
        auths = [p.amount for p in self.authorizations.filter(complete=False)]
        if auths:
            amount = reduce(operator.add, auths)
        else:
            amount = Decimal('0.00')

        return amount

    @property
    def credit_card(self):
        """Return the credit card associated with this payment.
        """
        for payment in self.payments.order_by('-time_stamp'):
            try:
                return payment.creditcard
            except CreditCardDetail.DoesNotExist:
                pass
        return None

    @property
    def full_bill_street(self, delim="\n"):
        """
        Return both billing street entries separated by delim.
        Note - Use linebreaksbr filter to convert to html in templates.
        """
        if self.bill_street2:
            address = self.bill_street1 + delim + self.bill_street2
        else:
            address = self.bill_street1
        return mark_safe(address)

    def get_pending(self, method, raises=True):
        pending = self.paymentspending.filter(method__exact=method)
        if pending.count() > 0:
            return pending[0]
        elif raises:
            raise PaymentPending.DoesNotExist(method)
        return None

    @property
    def partially_paid(self):
        remaining = self.remaining
        return remaining > 0 and remaining < self.total

    def recalc(self):
        if self.lineitems.count() > 0:
            subtotal = Decimal('0.00')
            shipping = Decimal('0.00')
            tax = Decimal('0.00')
            for item in self.lineitems.all():
                subtotal += item.sub_total
                shipping += item.shipping
                tax += item.tax
            self.sub_total = subtotal
            zero = Decimal('0.00')
            if shipping > zero and self.shipping == zero:
                self.shipping = shipping
            if self.shipping == None:
                self.shipping = zero
            if tax > zero and self.tax == zero:
                self.tax = tax
            if self.tax == None:
                self.tax = zero

        self.total = self.sub_total + self.tax + self.shipping
        log.debug(
            "Purchase #%s recalc: sub_total=%s, shipping=%s, tax=%s, total=%s",
            self.id, self.sub_total, self.shipping, self.tax, self.total)

    def recurring_lineitems(self):
        """Get all recurring lineitems"""
        subscriptions = [
            item for item in self.lineitems.all() if item.is_recurring
        ]
        return subscriptions

    @property
    def remaining(self):
        """Return the total less the payments and auths"""
        return self.total - self.total_payments - self.authorized_remaining

    def save(self, **kwargs):
        """
        Copy addresses from contact. If the order has just been created, set
        the create_date.
        """
        if not self.pk:
            self.time_stamp = datetime.now()

        try:
            site = self.site
        except Site.DoesNotExist:
            site = None
        if not site:
            self.site = Site.objects.get_current()
        super(Purchase, self).save(**kwargs)

    @property
    def total_payments(self):
        """Returns the total value of all completed payments"""
        payments = [p.amount for p in self.payments.filter(success=True)]
        if payments:
            amount = reduce(operator.add, payments)
        else:
            amount = Decimal('0.00')
        log.debug("total payments for %s=%s", self, amount)
        return amount
Example #7
0
class Balance(models.Model):
    """(Balance description)"""
    #accountcode = models.OneToOneField(User, verbose_name=_(u'username'), parent_link=True, primary_key=True)
    #accountcode = models.OneToOneField(User, verbose_name=_(u'username'), blank=False, related_name="balances")
    accountcode = AutoOneToOneField(User,
                                    verbose_name=_(u'username'),
                                    primary_key=True)
    #accountcode = models.ForeignKey(Contact)
    #cash = models.DecimalField(_("Balance"), max_digits=18, decimal_places=2)
    #cash = models.DecimalField(_("Balance"), max_digits=18, decimal_places=2, default=Decimal("0.00"))
    cash = CurrencyField(_("Balance"),
                         max_digits=18,
                         decimal_places=6,
                         default=Decimal("0.00"),
                         display_decimal=2)
    tariff = models.ForeignKey(TariffPlan,
                               default=1,
                               verbose_name=_('Tariff Plan'),
                               related_name='tariffplangroup')
    enabled = models.BooleanField(_(u'Enable'), default=True)
    objects = BalanceManager(
    )  # default manager must be always on first place! It's used as default_manager
    active_objects = GenericManager(enabled=True)  # only active entries
    inactive_objects = GenericManager(enabled=False)  # only inactive entries
    timelimit = models.FloatField(_(u'Limit'),
                                  blank=False,
                                  default=0,
                                  help_text=_(u'Time limit'))
    credit = CurrencyField(
        _("Discount Amount"),
        decimal_places=2,
        display_decimal=2,
        max_digits=8,
        default=Decimal("0.0"),
        help_text=_(u'Total sum for which credit is extended for calls'))
    #credit = models.DecimalField(_(u'Credit'), max_digits=18, decimal_places=2, default=Decimal('0.0'), help_text=_(u'Total sum for which credit is extended for calls'))
    site = models.ForeignKey(Site, default=1, verbose_name=_('Site'))

    class Meta:
        #ordering = []
        db_table = 'balance'
        verbose_name, verbose_name_plural = _(u"Balance"), _(u"Balances")
        permissions = (("api_view", "Can api view"), )


#    def __unicode__(self):
#        return self.accountcode.username

    @models.permalink
    def get_absolute_url(self):
        return ('Balance', [self.id])

    @property
    def vcash(self):
        if self.credit > Decimal('0'):
            cash = self.cash + self.credit
            return "{0:0.2f}".format(cash)
        else:
            return "{0:0.2f}".format(self.cash)

    @property
    def vcredit(self):
        if self.credit > Decimal('0'):
            return "{0:0f}".format(self.credit)
        else:
            return None

    def cash_currency(self):
        """docstring for rate_currency"""
        return u"{0:0.2f} {1}".format(self.cash, self.currency)

    cash_currency.short_description = _(u'Баланс')

    #    def username(self):
    #        #return "<a href='/admin/auth/user/{2}/'>{0} {1}</a>".format(self.accountcode.first_name, self.accountcode.last_name, self.accountcode.pk)
    #        return "{0} {1}".format(self.accountcode.first_name, self.accountcode.last_name)
    #    username.short_description = _(u'Имя Фамилия')
    #
    #    def last_login(self):
    #        return self.accountcode.last_login
    #    last_login.short_description = _('last login')
    #
    #    def date_joined(self):
    #        return self.accountcode.date_joined
    #    date_joined.short_description = _('date joined')
    #
    #    def accountcode_name(self):
    #        return self.accountcode.username
    #    accountcode_name.short_description = _('username')

    @property
    def currency(self):
        return u'у.е.'

    @property
    def is_positiv(self):
        if self.cash > Decimal('0'):
            return True
        else:
            return False

    @property
    def is_tariff(self):
        tcash = "{0:0.2f}{1}".format(self.cash + self.credit, self.credit)
        if len(tcash) > 9:
            return False
        else:
            return True

    def cash_add(self, amount):
        if Decimal(amount) > 0:
            self.cash += Decimal(amount)
        else:
            self.cash -= Decimal(amount)

    def cash_del(self, amount):
        if Decimal(amount) > 0:
            self.cash -= Decimal(amount)
        else:
            self.cash += Decimal(amount)