Esempio n. 1
0
def date_hierarchy(cl):
    """
    Displays the date hierarchy for date drill-down functionality.
    """
    if cl.date_hierarchy:
        field_name = cl.date_hierarchy
        field = get_fields_from_path(cl.model, field_name)[-1]
        dates_or_datetimes = 'datetimes' if isinstance(
            field, models.DateTimeField) else 'dates'
        year_field = '%s__year' % field_name
        month_field = '%s__month' % field_name
        day_field = '%s__day' % field_name
        field_generic = '%s__' % field_name
        year_lookup = cl.params.get(year_field)
        month_lookup = cl.params.get(month_field)
        day_lookup = cl.params.get(day_field)

        link = lambda filters: cl.get_query_string(filters, [field_generic])

        if not (year_lookup or month_lookup or day_lookup):
            # select appropriate start level
            date_range = cl.queryset.aggregate(first=models.Min(field_name),
                                               last=models.Max(field_name))
            if date_range['first'] and date_range['last']:
                if date_range['first'].year == date_range['last'].year:
                    year_lookup = date_range['first'].year
                    if date_range['first'].month == date_range['last'].month:
                        month_lookup = date_range['first'].month
        if year_lookup and month_lookup and day_lookup:
            day = datetime.date(int(year_lookup), int(month_lookup),
                                int(day_lookup))
            return {
                'field_name':
                field.verbose_name,
                'show':
                True,
                'back': {
                    'link':
                    link({
                        year_field: year_lookup,
                        month_field: month_lookup
                    }),
                    'title':
                    capfirst(formats.date_format(day, 'YEAR_MONTH_FORMAT'))
                },
                'choices': [{
                    'title':
                    capfirst(formats.date_format(day, 'MONTH_DAY_FORMAT'))
                }]
            }
        elif year_lookup and month_lookup:
            days = cl.queryset.filter(**{
                year_field: year_lookup,
                month_field: month_lookup
            })
            days = getattr(days, dates_or_datetimes)(field_name, 'day')
            return {
                'show':
                True,
                'field_name':
                field.verbose_name,
                'current_filter':
                capfirst(MONTHS.get(int(month_lookup), 'UNKNOWN')),
                'back': {
                    'link': link({year_field: year_lookup}),
                    'title': str(year_lookup)
                },
                'choices': [{
                    'link':
                    link({
                        year_field: year_lookup,
                        month_field: month_lookup,
                        day_field: day.day
                    }),
                    'title':
                    capfirst(formats.date_format(day, 'MONTH_DAY_FORMAT'))
                } for day in days]
            }
        elif year_lookup:
            months = cl.queryset.filter(**{year_field: year_lookup})
            months = getattr(months, dates_or_datetimes)(field_name, 'month')
            return {
                'show':
                True,
                'field_name':
                field.verbose_name,
                'current_filter':
                year_lookup,
                'back': {
                    'link': link({}),
                    'title': _('All dates')
                },
                'choices': [{
                    'link':
                    link({
                        year_field: year_lookup,
                        month_field: month.month
                    }),
                    'title':
                    capfirst(formats.date_format(month, 'YEAR_MONTH_FORMAT'))
                } for month in months]
            }
        else:
            years = getattr(cl.queryset, dates_or_datetimes)(field_name,
                                                             'year')
            return {
                'show':
                True,
                'current_filter':
                _('All'),
                'field_name':
                field.verbose_name,
                'choices': [{
                    'link': link({year_field: str(year.year)}),
                    'title': str(year.year),
                } for year in years]
            }
Esempio n. 2
0
    def test_create_dynamic_db_model_instance(self):
        
        # Support MyModel.objects.none()
        empt = KingBook.objects.all()
        self.assertEqual(str(empt), '<QuerySet []>')

        # Support MyModel.objects.create()
        bk1 = KingBook.objects.create(name="Tony Stark", rate=3.5)
        
        bk2 = KingBook.objects.create(name="John Wick", rate=5)
        
        
        self.assertEqual(bk1.__class__.__name__, "KingBook")
        self.assertEqual(bk2.name, "John Wick")
        # self.assertEqual(bk3.rate, 1.0)

        # Support MyModel.objects.get()
        bk5 = KingBook.objects.get(name="Tony Stark")
        self.assertEqual(bk5.name, bk1.name)
        
        # Support MyModel.objects.get_or_create()
        bk6, bk6_created = KingBook.objects.get_or_create(name="John Wick") # Get
        self.assertEqual(bk6.name, "John Wick")
        bk7, bk7_created = KingBook.objects.get_or_create(name="Will Smith", rate=3.5)  # Create
        self.assertEqual(bk7.id, 63)
        
        # Support MyModel.objects.count()
        all = KingBook.objects.all()
        cnt = KingBook.objects.count()
        self.assertEqual(len(all), cnt)

        # Support Save method
        bk8 = KingBook(name="Brad Pete")
        bk8.save()
        
        
        # Support default value
        bk9 = KingBook.objects.get(id=64)
        self.assertEqual(bk9.name, "Brad Pete")
        self.assertEqual(bk9.rate, '1.0')
        self.assertEqual(bk9.weight, 'None')

        # Support instance update
        bk9.rate = 1.33
        bk9.save()
        bk10 = KingBook.objects.get(name="Brad Pete")
        self.assertEqual(bk10.rate, '1.33')

        # Support complex filter
        bk11 = KingBook.objects.filter(id__gt=62)
        self.assertEqual(len(bk11), 2)
        
        
        # Support Aggregation
        higher_rate = KingBook.objects.aggregate(models.Max('rate'))
        self.assertEqual(higher_rate, {'rate__max': '5'})
        lower_rate = KingBook.objects.aggregate(models.Min('rate'))
        self.assertEqual(lower_rate, {'rate__min': '1.33'})
        
        # SUM bugs with Postgres db
        # sum_rate = KingBook.objects.aggregate(models.Sum('rate'))
        # self.assertEqual(sum_rate, {'rate__sum': 13.33})
        
        # Support delete()
        bk12 = KingBook.objects.create(name="Tony Stark2", rate=3.5)
        bk13 = KingBook.objects.create(name="John Wick1", rate=5)
        bk14 = KingBook.objects.create(name="John Wick2", rate=5)
        bk15 = KingBook.objects.create(name="John Wick3", rate=5)
        bk16 = KingBook.objects.create(name="John Wick4", rate=5)
        bk17 = KingBook.objects.create(name="John Wick5", rate=5)
        bk18 = KingBook.objects.create(name="John Wick6", rate=5)
        bk19 = KingBook.objects.create(name="John Wick7", rate=5)

        deleted = KingBook.objects.get(name="John Wick6").delete()
        
        self.assertEqual(deleted, (8, {'django_dynamic_database.KingBook': 8}))
        
        # Support update()
        bk20 = KingBook.objects.filter(id__lt=66).update(rate=1.5)
        bk12 = KingBook.objects.get(name="Tony Stark2")
        self.assertEqual(bk12.rate, '1.5')
Esempio n. 3
0
    def create_refund_lines(self, order, supplier, created_by, refund_data):
        context = self.get_context_from_order_source(order)

        lines = order.lines.all()
        if supplier:
            lines = lines.filter(supplier=supplier)

        index = lines.aggregate(models.Max("ordering"))["ordering__max"]
        tax_proportions = self._get_tax_class_proportions(order)

        refund_lines = []

        product_summary = order.get_product_summary(supplier)
        available_for_refund = order.get_total_unrefunded_amount(
            supplier=supplier)
        zero = Money(0, order.currency)
        total_refund_amount = zero

        for refund in refund_data:
            index += 1
            amount = refund.get("amount", zero)
            quantity = refund.get("quantity", 0)
            parent_line = refund.get("line", "amount")
            if not settings.SHUUP_ALLOW_ARBITRARY_REFUNDS and (
                    not parent_line or parent_line == "amount"):
                raise RefundArbitraryRefundsNotAllowedException

            restock_products = refund.get("restock_products")
            refund_line = None

            assert parent_line
            assert quantity

            if parent_line == "amount":
                refund_line = self._refund_amount(
                    context,
                    order,
                    index,
                    refund.get("text", _("Misc refund")),
                    amount,
                    tax_proportions,
                    supplier=supplier,
                )
            else:
                # ensure the amount to refund and the order line amount have the same signs
                if (amount > zero and parent_line.taxful_price.amount < zero
                    ) or (amount < zero
                          and parent_line.taxful_price.amount > zero):
                    raise InvalidRefundAmountException

                if abs(amount) > abs(parent_line.max_refundable_amount):
                    raise RefundExceedsAmountException

                # If restocking products, calculate quantity of products to restock
                product = parent_line.product

                # ensure max refundable quantity is respected for products
                if product and quantity > parent_line.max_refundable_quantity:
                    raise RefundExceedsQuantityException

                if restock_products and quantity and product:
                    from shuup.core.suppliers.enums import StockAdjustmentType

                    # restock from the unshipped quantity first
                    unshipped_quantity_to_restock = min(
                        quantity, product_summary[product.pk]["unshipped"])
                    shipped_quantity_to_restock = min(
                        quantity - unshipped_quantity_to_restock,
                        product_summary[product.pk]["ordered"] -
                        product_summary[product.pk]["refunded"],
                    )

                    if unshipped_quantity_to_restock > 0:
                        product_summary[product.pk][
                            "unshipped"] -= unshipped_quantity_to_restock
                        if parent_line.supplier.stock_managed:
                            parent_line.supplier.adjust_stock(
                                product.id,
                                unshipped_quantity_to_restock,
                                created_by=created_by,
                                type=StockAdjustmentType.RESTOCK_LOGICAL,
                            )
                    if shipped_quantity_to_restock > 0 and parent_line.supplier.stock_managed:
                        parent_line.supplier.adjust_stock(
                            product.id,
                            shipped_quantity_to_restock,
                            created_by=created_by,
                            type=StockAdjustmentType.RESTOCK,
                        )
                    product_summary[product.pk]["refunded"] += quantity

                base_amount = amount if order.prices_include_tax else amount / (
                    1 + parent_line.tax_rate)

                from shuup.core.models import OrderLine, OrderLineType

                refund_line = OrderLine.objects.create(
                    text=_("Refund for %s" % parent_line.text),
                    order=order,
                    type=OrderLineType.REFUND,
                    parent_line=parent_line,
                    ordering=index,
                    base_unit_price_value=-(base_amount / (quantity or 1)),
                    quantity=quantity,
                    supplier=parent_line.supplier,
                )
                for line_tax in parent_line.taxes.all():
                    tax_base_amount = amount / (1 + parent_line.tax_rate)
                    tax_amount = tax_base_amount * line_tax.tax.rate
                    refund_line.taxes.create(
                        tax=line_tax.tax,
                        name=_("Refund for %s" % line_tax.name),
                        amount_value=-tax_amount,
                        base_amount_value=-tax_base_amount,
                        ordering=line_tax.ordering,
                    )

            total_refund_amount += refund_line.taxful_price.amount
            refund_lines.append(refund_line)

        if abs(total_refund_amount) > available_for_refund:
            raise RefundExceedsAmountException

        return refund_lines
Esempio n. 4
0
 def get_highest_value_for_treatment_type(self, treatment_type):
     return (self.treatment_attempts.filter(
         treatment_type=treatment_type).aggregate(highest=models.Max(
             "value", output_field=models.IntegerField(
                 default=0)))["highest"] or 0)
Esempio n. 5
0
 def get_last_id(cls):
     return cls.objects.all().aggregate(
         models.Max('color_id')).get('color_id__max')
Esempio n. 6
0
    def actions(self) -> List:
        last_updated_action_ts = Action.objects.filter(
            team_id=self.team_id).aggregate(
                models.Max("updated_at"))["updated_at__max"]

        actions = (
            Action.objects.filter(
                team_id=self.team_id,
                steps__event=self.event,
                deleted=False,  # filter by event name to narrow down
            ).distinct("id").prefetch_related(
                Prefetch("steps", queryset=ActionStep.objects.order_by("id"))))
        if not self._can_use_cached_query(last_updated_action_ts):
            TEAM_ACTION_QUERY_CACHE[
                self.team_id], _ = actions.query.sql_with_params()
            if len(actions) == 0:
                return []
            events: models.QuerySet[Any] = Event.objects.filter(pk=self.pk)
            for action in actions:
                events = events.annotate(
                    **{
                        "action_{}".format(action.pk):
                        Event.objects.filter(pk=self.pk).query_db_by_action(
                            action).values("id")[:1]
                    })
            # This block is a little cryptic so bear with me
            # We grab the query and the params from the ORM here
            q, p = events.query.sql_with_params()

            # We then take the parameters and replace the event id's with a placeholder
            # We use this later to sub back in future event id's
            # The rest of the parameters are shared between action types
            qp = tuple(["%s" if i == self.pk else i for i in p])

            # Create a cache item and add it to the cache keyed on team_id and event id
            qcache = {self.event: (q, qp)}
            TEAM_EVENT_ACTION_QUERY_CACHE[self.team_id].update(qcache)

            # Update the last updated team action timestamp for future reference
            LAST_UPDATED_TEAM_ACTION[self.team_id] = last_updated_action_ts
        else:

            # If we have reached this block we are about to use the sql query cache
            # Grab the actions using the cached action query
            actions.raw(TEAM_ACTION_QUERY_CACHE[self.team_id])

            # Grab the cached query and query params, we will need to replace some params
            q, p = TEAM_EVENT_ACTION_QUERY_CACHE[self.team_id][self.event]

            # Replace the query param placeholders with the event id (opposite of what we did above)
            qp = tuple([self.pk if i == "%s" else i for i in p])

            with connection.cursor() as cursor:
                # Format and execute the cached query using the mostly cached params
                qstring = cursor.mogrify(q, qp)
                cursor.execute(qstring)
                events = namedtuplefetchall(cursor)

        event = [event for event in events][0]
        filtered_actions = [
            action for action in actions
            if getattr(event, "action_{}".format(action.pk), None)
        ]
        return filtered_actions
Esempio n. 7
0
 def set_position(self):
     if self.position is None:
         self.position = self.field.option_set.aggregate(
             max_position=Coalesce(models.Max('position'), 0)
         ).get('max_position', 0) + 10
Esempio n. 8
0
 def get_max_priority(self, customer):
     aggr = self.get_queryset().filter(customer=customer).aggregate(
         models.Max('priority'))
     priority = aggr['priority__max'] or 0
     return priority
Esempio n. 9
0
 def _folder(self, related, filters, option=None, order_by=None):
     """Base code, in common to the folders."""
     qs = self.all() if option == OPTION_MESSAGES else QuerySet(
         self.model, PostmanQuery(self.model), using=self._db)
     if related:
         qs = qs.select_related(*related)
     if order_by:
         qs = qs.order_by(order_by)
     if isinstance(filters, (list, tuple)):
         lookups = models.Q()
         for filter in filters:
             lookups |= models.Q(**filter)
     else:
         lookups = models.Q(**filters)
     if option == OPTION_MESSAGES:
         return qs.filter(lookups)
         # Adding a 'count' attribute, to be similar to the by-conversation case,
         # should not be necessary. Otherwise add:
         # .extra(select={'count': 'SELECT 1'})
     else:
         qs = qs.extra(
             select={'count': '{0}.count'.format(qs.query.pm_alias_prefix)})
         qs.query.pm_set_extra(table=(
             # extra columns are always first in the SELECT query
             # for tests with the version 2.4.1 of sqlite3 in py26, add to the select: , 'id': 'postman_message.id'
             self.filter(lookups, thread_id__isnull=True).extra(select={'count': 0})\
                 .values_list('id', 'count').order_by(),
             # use separate annotate() to keep control of the necessary order
             self.filter(lookups, thread_id__isnull=False).values('thread').annotate(count=models.Count('pk')).annotate(id=models.Max('pk'))\
                 .values_list('id', 'count').order_by(),
         ))
         return qs
Esempio n. 10
0
def get_latest_peers(latest=LATEST_PEERS):

    if latest > 0:
        peers = [
            c['key_remote_jid'] for c in Messages.objects.using(
                'msgstore').values('key_remote_jid').exclude(
                    Q(key_remote_jid=-1) | Q(key_remote_jid__icontains='-')
                    | Q(key_remote_jid__startswith='Server')).annotate(
                        models.Max('timestamp')).order_by('-timestamp__max')
            [:latest]
        ]
    else:
        peers = [
            c['key_remote_jid'] for c in Messages.objects.using(
                'msgstore').values('key_remote_jid').exclude(
                    Q(key_remote_jid=-1) | Q(key_remote_jid__icontains='-')
                    | Q(key_remote_jid__startswith='Server')).annotate(
                        models.Max('timestamp')).order_by('-timestamp__max')
        ]

    ret = []

    for peer in peers:
        data = Messages.objects.using('msgstore').filter(
            key_remote_jid=peer).values(
                'data', '_id', 'media_wa_type', get_raw_column()).annotate(
                    models.Max('timestamp')).order_by('-timestamp__max')[:1][0]

        try:
            peer_data = WaContacts.objects.filter(jid=peer).values(
                'display_name', 'status')[0]
        except:
            peer_data = {}
            peer_data['display_name'] = 'N/A'
            peer_data['status'] = 'N/A'

        newdata = {
            'key_remote_jid': peer,
            'media_wa_type': data['media_wa_type'],
            '_id': data['_id'],
            'timestamp': timestamp2utc(float(data['timestamp__max']) / 1000),
            'data': data['data'],
            'display_name': peer_data['display_name'],
            'status': peer_data['status'],
            'number': '+' + peer.split('@')[0]
        }

        if data['data'] is not None:
            newdata['img'] = set_media(data['media_wa_type'], data['data'],
                                       peer, str(data['_id']), False)
        elif data[get_raw_column()] is not None:
            newdata['img'] = set_media(data['media_wa_type'],
                                       data[get_raw_column()], peer,
                                       str(data['_id']), True)

        if newdata['data'] is None:
            newdata['data'] = ''

        ret.append(newdata)

    return ret