Skip to content

Commit

Permalink
Merge tag '58_custom_primary_key' into develop
Browse files Browse the repository at this point in the history
Fix Issue 58
0.6.5
  • Loading branch information
Ramez Ashraf committed Jan 27, 2023
2 parents e77029f + a840d48 commit a405958
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 12 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes to this project will be documented in this file.

## [0.6.5]
- Fix Issue with group_by field pointing to model with custom primary key Issue #58


## [0.6.4]
- Fix highchart cache to target the specific chart
- Added initial and required to report_form_factory
Expand Down
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
master_doc = 'index'

# The full version, including alpha/beta/rc tags
release = '0.6.4'
release = '0.6.5'

# -- General configuration ---------------------------------------------------

Expand Down
4 changes: 2 additions & 2 deletions slick_reporting/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
default_app_config = 'slick_reporting.apps.ReportAppConfig'

VERSION = (0, 6, 4)
VERSION = (0, 6, 5)

__version__ = '0.6.4'
__version__ = '0.6.5'
20 changes: 13 additions & 7 deletions slick_reporting/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,14 +206,12 @@ def __init__(self, report_model=None, main_queryset=None, start_date=None, end_d
except IndexError:
raise ImproperlyConfigured(
f'Can not find group_by field:{self.group_by} in report_model {self.report_model} ')
self.focus_field_as_key = self.group_by_field
if '__' not in self.group_by:
self.group_by_field_attname = self.group_by_field.attname
else:
self.group_by_field_attname = self.group_by

else:
self.focus_field_as_key = None
self.group_by_field_attname = None

# doc_types = form.get_doc_type_plus_minus_lists()
Expand Down Expand Up @@ -340,6 +338,13 @@ def _prepare_report_dependencies(self):
report_class.init_preparation(q_filters, date_filter)
self.report_fields_classes[name] = report_class

@staticmethod
def get_primary_key_name(model):
for field in model._meta.fields:
if field.primary_key:
return field.attname
return ''

def _get_record_data(self, obj, columns):
"""
the function is run for every obj in the main_queryset
Expand All @@ -348,12 +353,15 @@ def _get_record_data(self, obj, columns):
:return: a dict object containing all needed data
"""

# todo , if columns are empty for whatever reason this will throw an error
display_link = self.list_display_links or columns[0]
data = {}
group_by_val = None
if self.group_by:
column_data = obj.get(self.group_by_field_attname, obj.get('id'))
if self.group_by_field.related_model and '__' not in self.group_by:
primary_key_name = self.get_primary_key_name(self.group_by_field.related_model)
else:
primary_key_name = self.group_by_field_attname

column_data = obj.get(primary_key_name, obj.get('id'))
group_by_val = str(column_data)

for window, window_cols in columns:
Expand All @@ -379,8 +387,6 @@ def _get_record_data(self, obj, columns):

else:
data[name] = obj.get(name, '')
# if self.group_by and name in display_link:
# data[name] = make_linkable_field(self.group_by_field.related_model, group_by_val, data[name])
return data

def get_report_data(self):
Expand Down
44 changes: 44 additions & 0 deletions tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,25 @@ class Meta:
verbose_name_plural = _('Products')


class ProductCustomID(models.Model):
CATEGORY_CHOICES = (
('tiny', 'tiny'),
('small', 'small'),
('medium', 'medium'),
('big', 'big'),
)
hash = models.AutoField(primary_key=True)
slug = models.CharField(max_length=200, verbose_name=_('Slug'))
name = models.CharField(max_length=200, verbose_name=_('Name'))
sku = models.CharField(max_length=200, default='', blank=True)
category = models.CharField(max_length=10, choices=CATEGORY_CHOICES)
notes = models.TextField()

class Meta:
verbose_name = _('Product')
verbose_name_plural = _('Products')


class Contact(models.Model):
address = models.CharField(max_length=200, verbose_name=_('Name'))

Expand Down Expand Up @@ -65,6 +84,31 @@ class Meta:
ordering = ['-created_at']


class SalesProductWithCustomID(models.Model):
slug = models.SlugField()
doc_date = models.DateTimeField(_('date'), db_index=True)
client = models.ForeignKey(Client, on_delete=models.CASCADE)
product = models.ForeignKey(ProductCustomID, on_delete=models.CASCADE)
quantity = models.DecimalField(_('quantity'), max_digits=19, decimal_places=2, default=0)
price = models.DecimalField(_('price'), max_digits=19, decimal_places=2, default=0)
value = models.DecimalField(_('value'), max_digits=19, decimal_places=2, default=0)
created_at = models.DateTimeField(null=True, verbose_name=_('Created at'))
flag = models.CharField(max_length=50, default='sales')

content_type = models.ForeignKey(ContentType, on_delete=models.DO_NOTHING, null=True)
object_id = models.PositiveIntegerField(null=True)
content_object = GenericForeignKey('content_type', 'object_id')

def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
self.value = self.quantity * self.price
super().save(force_insert, force_update, using, update_fields)

class Meta:
verbose_name = _('Sale')
verbose_name_plural = _('Sales')
ordering = ['-created_at']


class SalesWithFlag(models.Model):
slug = models.SlugField()
doc_date = models.DateTimeField(_('date'), db_index=True)
Expand Down
9 changes: 8 additions & 1 deletion tests/report_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from slick_reporting.fields import SlickReportField, PercentageToBalance
from slick_reporting.generator import ReportGenerator
from .models import Client, SimpleSales, Product, SalesWithFlag
from .models import Client, SimpleSales, Product, SalesWithFlag, SalesProductWithCustomID
from .models import OrderLine


Expand Down Expand Up @@ -82,6 +82,13 @@ class ProductTotalSales(ReportGenerator):
columns = ['slug', 'name', '__balance__', '__balance_quantity__']


class ProductTotalSalesProductWithCustomID(ReportGenerator):
report_model = SalesProductWithCustomID
date_field = 'doc_date'
group_by = 'product'
columns = ['slug', 'name', '__balance__', '__balance_quantity__']


class ProductTotalSalesWithPercentage(ReportGenerator):
report_model = SimpleSales
date_field = 'doc_date'
Expand Down
24 changes: 23 additions & 1 deletion tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
from tests.report_generators import ClientTotalBalance, ProductClientSalesMatrix2, GroupByCharField, \
GroupByCharFieldPlusTimeSeries, TimeSeriesWithOutGroupBy
from . import report_generators
from .models import Client, Contact, Product, SimpleSales, UserJoined, SalesWithFlag, ComplexSales, TaxCode
from .models import Client, Contact, Product, SimpleSales, UserJoined, SalesWithFlag, ComplexSales, TaxCode, \
ProductCustomID, SalesProductWithCustomID
from .views import SlickReportView

User = get_user_model()
Expand Down Expand Up @@ -49,6 +50,9 @@ def setUpTestData(cls):
cls.product2 = Product.objects.create(name='Product 2', category='medium')
cls.product3 = Product.objects.create(name='Product 3', category='big')

cls.product_w_custom_id1 = ProductCustomID.objects.create(name='Product 1', category='small')
cls.product_w_custom_id2 = ProductCustomID.objects.create(name='Product 2', category='medium')

SimpleSales.objects.create(
doc_date=datetime.datetime(year, 1, 2), client=cls.client1,
product=cls.product1, quantity=10, price=10, created_at=datetime.datetime(year, 1, 5))
Expand Down Expand Up @@ -107,6 +111,18 @@ def setUpTestData(cls):
sale3.tax.add(cls.tax1)
sale4.tax.add(cls.tax2)

SalesProductWithCustomID.objects.create(
doc_date=datetime.datetime(year, 1, 2), client=cls.client1,
product=cls.product_w_custom_id1, quantity=10, price=10, created_at=datetime.datetime(year, 1, 5))
SalesProductWithCustomID.objects.create(
doc_date=datetime.datetime(year, 2, 2), client=cls.client1,
product=cls.product_w_custom_id1, quantity=10, price=10, created_at=datetime.datetime(year, 2, 3))

SalesProductWithCustomID.objects.create(
doc_date=datetime.datetime(year, 3, 2), client=cls.client1,
product=cls.product_w_custom_id2, quantity=10, price=10, created_at=datetime.datetime(year, 3, 3))



# @override_settings(ROOT_URLCONF='reporting_tests.urls', RA_CACHE_REPORTS=False, USE_TZ=False)
class ReportTest(BaseTestData, TestCase):
Expand All @@ -118,6 +134,12 @@ def test_client_balance(self):
self.assertEqual(data[0].get('__balance__'), 300, data[0])

def test_product_total_sales(self):
report = report_generators.ProductTotalSalesProductWithCustomID()
data = report.get_report_data()
self.assertEqual(data[0]['__balance__'], 200)
self.assertEqual(data[1]['__balance__'], 100)

def test_product_total_sales_product_custom_id(self):
report = report_generators.ProductTotalSales()
data = report.get_report_data()
self.assertEqual(data[0]['__balance__'], 1800)
Expand Down

0 comments on commit a405958

Please sign in to comment.