Projet

Général

Profil

0002-lingo-add-generic-invoice-cell-with-category-filter-.patch

Serghei Mihai, 31 mars 2016 10:25

Télécharger (10,5 ko)

Voir les différences:

Subject: [PATCH 2/5] lingo: add generic invoice cell with "category" filter
 (#10483)

Migrate data from existing items cell to the new one
 combo/apps/lingo/migrations/0018_invoicescell.py   | 38 +++++++++++
 ...9_manual_migrate_invoice_cells_20160330_2154.py | 76 ++++++++++++++++++++++
 combo/apps/lingo/models.py                         | 62 ++++++++++++++++++
 tests/test_lingo_cells.py                          | 16 ++++-
 4 files changed, 191 insertions(+), 1 deletion(-)
 create mode 100644 combo/apps/lingo/migrations/0018_invoicescell.py
 create mode 100644 combo/apps/lingo/migrations/0019_manual_migrate_invoice_cells_20160330_2154.py
combo/apps/lingo/migrations/0018_invoicescell.py
1
# -*- coding: utf-8 -*-
2
from __future__ import unicode_literals
3

  
4
from django.db import models, migrations
5
import ckeditor.fields
6

  
7

  
8
class Migration(migrations.Migration):
9

  
10
    dependencies = [
11
        ('auth', '0001_initial'),
12
        ('data', '0016_feedcell_limit'),
13
        ('lingo', '0017_auto_20160327_0831'),
14
    ]
15

  
16
    operations = [
17
        migrations.CreateModel(
18
            name='InvoicesCell',
19
            fields=[
20
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
21
                ('placeholder', models.CharField(max_length=20)),
22
                ('order', models.PositiveIntegerField()),
23
                ('slug', models.SlugField(verbose_name='Slug', blank=True)),
24
                ('public', models.BooleanField(default=True, verbose_name='Public')),
25
                ('restricted_to_unlogged', models.BooleanField(default=False, verbose_name='Restrict to unlogged users')),
26
                ('regie', models.CharField(max_length=50, verbose_name='Regie', blank=True)),
27
                ('title', models.CharField(max_length=200, verbose_name='Title', blank=True)),
28
                ('text', ckeditor.fields.RichTextField(null=True, verbose_name='Text', blank=True)),
29
                ('category', models.CharField(default=b'active', max_length=128, verbose_name='Category', choices=[(b'active', 'Active'), (b'past', 'Past')])),
30
                ('groups', models.ManyToManyField(to='auth.Group', verbose_name='Groups', blank=True)),
31
                ('page', models.ForeignKey(to='data.Page')),
32
            ],
33
            options={
34
                'verbose_name': 'Invoices',
35
            },
36
            bases=(models.Model,),
37
        ),
38
    ]
combo/apps/lingo/migrations/0019_manual_migrate_invoice_cells_20160330_2154.py
1
# -*- coding: utf-8 -*-
2
from __future__ import unicode_literals
3

  
4
from django.db import models, migrations
5

  
6
def migrate_activeitems_cells(apps, schema_editor):
7
    InvoicesCell = apps.get_model('lingo', 'InvoicesCell')
8
    Page = apps.get_model('data', 'Page')
9
    ActiveItems = apps.get_model('lingo', 'ActiveItems')
10
    for cell in ActiveItems.objects.all():
11
        page = Page.objects.get(pk=cell.page_id)
12
        InvoicesCell.objects.get_or_create(order=cell.order,
13
                        page=page, placeholder=cell.placeholder,
14
                        public=cell.public, regie=cell.regie,
15
                        restricted_to_unlogged=cell.restricted_to_unlogged,
16
                        slug=cell.slug, text=cell.text, title=cell.title,
17
                        category='active'
18
        )
19
        cell.delete()
20

  
21
def migrate_itemshistory_cells(apps, schema_editor):
22
    InvoicesCell = apps.get_model('lingo', 'InvoicesCell')
23
    Page = apps.get_model('data', 'Page')
24
    ItemsHistory = apps.get_model('lingo', 'ItemsHistory')
25
    for cell in ItemsHistory.objects.all():
26
        page = Page.objects.get(pk=cell.page_id)
27
        InvoicesCell.objects.get_or_create(order=cell.order,
28
                        page=page, placeholder=cell.placeholder,
29
                        public=cell.public, regie=cell.regie,
30
                        restricted_to_unlogged=cell.restricted_to_unlogged,
31
                        slug=cell.slug, text=cell.text, title=cell.title,
32
                        category='past'
33
        )
34
        cell.delete()
35

  
36
def restore_activeitems_cells(apps, schema_editor):
37
    InvoicesCell = apps.get_model('lingo', 'InvoicesCell')
38
    Page = apps.get_model('data', 'Page')
39
    ActiveItems = apps.get_model('lingo', 'ActiveItems')
40
    for cell in InvoicesCell.objects.filter(category='active'):
41
        page = Page.objects.get(pk=cell.page_id)
42
        ActiveItems.objects.get_or_create(order=cell.order,
43
                        page=page, placeholder=cell.placeholder,
44
                        public=cell.public, regie=cell.regie,
45
                        restricted_to_unlogged=cell.restricted_to_unlogged,
46
                        slug=cell.slug, text=cell.text, title=cell.title
47
        )
48
        cell.delete()
49

  
50
def restore_itemshistory_cells(apps, schema_editor):
51
    InvoicesCell = apps.get_model('lingo', 'InvoicesCell')
52
    Page = apps.get_model('data', 'Page')
53
    ItemsHistory = apps.get_model('lingo', 'ActiveItems')
54
    for cell in InvoicesCell.objects.filter(category='past'):
55
        page = Page.objects.get(pk=cell.page_id)
56
        ItemsHistory.objects.get_or_create(order=cell.order,
57
                        page=page, placeholder=cell.placeholder,
58
                        public=cell.public, regie=cell.regie,
59
                        restricted_to_unlogged=cell.restricted_to_unlogged,
60
                        slug=cell.slug, text=cell.text, title=cell.title
61
        )
62
        cell.delete()
63

  
64

  
65
class Migration(migrations.Migration):
66

  
67
    dependencies = [
68
        ('lingo', '0018_invoicescell'),
69
    ]
70

  
71
    operations = [
72
        migrations.RunPython(migrate_activeitems_cells,
73
                             restore_activeitems_cells),
74
        migrations.RunPython(migrate_itemshistory_cells,
75
                             restore_itemshistory_cells)
76
    ]
combo/apps/lingo/models.py
55 55
    (eopayment.PAYZEN, _('PayZen')),
56 56
]
57 57

  
58
INVOICE_CATEGORIES = (
59
    ('active', _('Active')),
60
    ('past', _('Past'))
61
)
62

  
58 63
def build_remote_item(data, regie):
59 64
    return RemoteItem(id=data.get('id'), regie=regie,
60 65
                      creation_date=data['created'],
......
358 363
        return basket_template.render(context)
359 364

  
360 365

  
366
@register_cell_class
367
class InvoicesCell(CellBase):
368
    regie = models.CharField(_('Regie'), max_length=50, blank=True)
369
    title = models.CharField(_('Title'), max_length=200, blank=True)
370
    text = RichTextField(_('Text'), blank=True, null=True)
371
    category = models.CharField(_('Category'), max_length=128,
372
                                choices=INVOICE_CATEGORIES, default='active')
373

  
374
    user_dependant = True
375
    template_name = 'lingo/combo/items.html'
376

  
377
    class Meta:
378
        verbose_name = _('Invoices')
379

  
380
    class Media:
381
        js = ('xstatic/jquery-ui.min.js', 'js/gadjo.js',)
382
        css = {'all': ('xstatic/themes/smoothness/jquery-ui.min.css', )}
383

  
384
    @classmethod
385
    def is_enabled(cls):
386
        return Regie.objects.count() > 0
387

  
388
    def get_default_form_class(self):
389
        fields = ['title', 'category', 'text']
390
        widgets = {}
391
        if Regie.objects.count() > 1:
392
            regies = [('', _('All'))]
393
            regies.extend([(r.slug, r.label) for r in Regie.objects.all()])
394
            widgets['regie'] = Select(choices=regies)
395
            fields.insert(0, 'regie')
396
        return model_forms.modelform_factory(self.__class__, fields=fields, widgets=widgets)
397

  
398
    def get_regies(self):
399
        if self.regie:
400
            return [Regie.objects.get(slug=self.regie)]
401
        return Regie.objects.all()
402

  
403
    def get_cell_extra_context(self, context):
404
        ctx = {'title': self.title, 'text': self.text}
405
        invoices = []
406
        for r in self.get_regies():
407
            if self.category == 'active':
408
                invoices.extend(r.get_items(self.context))
409
            elif self.category == 'past':
410
                invoices.extend(r.get_past_items(self.context))
411
        # sort items by creation date
412
        invoices.sort(key=lambda i: i.creation_date, reverse=True)
413
        ctx.update({'items': invoices})
414
        return ctx
415

  
416
    def render(self, context):
417
        self.context = context
418
        if not context.get('synchronous'):
419
            raise NothingInCacheException()
420
        return super(InvoicesCell, self).render(context)
421

  
422

  
361 423
class Items(CellBase):
362 424
    regie = models.CharField(_('Regie'), max_length=50, blank=True)
363 425
    title = models.CharField(_('Title'), max_length=200, blank=True)
tests/test_lingo_cells.py
6 6
from django.utils import timezone
7 7

  
8 8
from combo.data.models import Page
9
from combo.apps.lingo.models import Regie, BasketItem, Transaction
9
from combo.utils import NothingInCacheException
10
from combo.apps.lingo.models import Regie, BasketItem, Transaction, InvoicesCell
10 11
from combo.apps.lingo.models import LingoBasketCell, LingoRecentTransactionsCell
11 12

  
12 13
pytestmark = pytest.mark.django_db
......
68 69

  
69 70
    content = cell.render(context)
70 71
    assert '12345' in content
72

  
73
def test_invoices_cell(regie, user):
74
    page = Page(title='invoices', slug='test_invoices_cell', template_name='standard')
75
    page.save()
76
    cell = InvoicesCell(page=page, placeholder='content', order=0,
77
                        regie=regie.slug, title='Active Invoices', category='active')
78
    context = Context({'request': RequestFactory().get('/')})
79
    context['request'].user = user
80
    assert cell.is_relevant(context) is True
81
    with pytest.raises(NothingInCacheException):
82
        cell.render(context)
83
    context['synchronous'] = True
84
    assert 'Active Invoices' in cell.render(context)
71
-