Revert "lingo: add generic cell handling all invoice categories (#10483)"
This reverts commit 58822107c8
.
This commit is contained in:
parent
fcc6cc2148
commit
34c5ee1281
|
@ -1,39 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import multiselectfield.db.fields
|
||||
import ckeditor.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('auth', '0001_initial'),
|
||||
('data', '0016_feedcell_limit'),
|
||||
('lingo', '0017_auto_20160327_0831'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='InvoicesCell',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('placeholder', models.CharField(max_length=20)),
|
||||
('order', models.PositiveIntegerField()),
|
||||
('slug', models.SlugField(verbose_name='Slug', blank=True)),
|
||||
('public', models.BooleanField(default=True, verbose_name='Public')),
|
||||
('restricted_to_unlogged', models.BooleanField(default=False, verbose_name='Restrict to unlogged users')),
|
||||
('regie', models.CharField(max_length=50, verbose_name='Regie', blank=True)),
|
||||
('title', models.CharField(max_length=200, verbose_name='Title', blank=True)),
|
||||
('text', ckeditor.fields.RichTextField(null=True, verbose_name='Text', blank=True)),
|
||||
('categories', multiselectfield.db.fields.MultiSelectField(max_length=11, verbose_name='Categories', choices=[(b'active', 'Active'), (b'past', 'Past')])),
|
||||
('groups', models.ManyToManyField(to='auth.Group', verbose_name='Groups', blank=True)),
|
||||
('page', models.ForeignKey(to='data.Page')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Invoices',
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
]
|
|
@ -1,76 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
def migrate_activeitems_cells(apps, schema_editor):
|
||||
InvoicesCell = apps.get_model('lingo', 'InvoicesCell')
|
||||
Page = apps.get_model('data', 'Page')
|
||||
ActiveItems = apps.get_model('lingo', 'ActiveItems')
|
||||
for cell in ActiveItems.objects.all():
|
||||
page = Page.objects.get(pk=cell.page_id)
|
||||
InvoicesCell.objects.get_or_create(order=cell.order,
|
||||
page=page, placeholder=cell.placeholder,
|
||||
public=cell.public, regie=cell.regie,
|
||||
restricted_to_unlogged=cell.restricted_to_unlogged,
|
||||
slug=cell.slug, text=cell.text, title=cell.title,
|
||||
categories='active'
|
||||
)
|
||||
cell.delete()
|
||||
|
||||
def migrate_itemshistory_cells(apps, schema_editor):
|
||||
InvoicesCell = apps.get_model('lingo', 'InvoicesCell')
|
||||
Page = apps.get_model('data', 'Page')
|
||||
ItemsHistory = apps.get_model('lingo', 'ItemsHistory')
|
||||
for cell in ItemsHistory.objects.all():
|
||||
page = Page.objects.get(pk=cell.page_id)
|
||||
InvoicesCell.objects.get_or_create(order=cell.order,
|
||||
page=page, placeholder=cell.placeholder,
|
||||
public=cell.public, regie=cell.regie,
|
||||
restricted_to_unlogged=cell.restricted_to_unlogged,
|
||||
slug=cell.slug, text=cell.text, title=cell.title,
|
||||
categories='past'
|
||||
)
|
||||
cell.delete()
|
||||
|
||||
def restore_activeitems_cells(apps, schema_editor):
|
||||
InvoicesCell = apps.get_model('lingo', 'InvoicesCell')
|
||||
Page = apps.get_model('data', 'Page')
|
||||
ActiveItems = apps.get_model('lingo', 'ActiveItems')
|
||||
for cell in InvoicesCell.objects.filter(categories__contains='active'):
|
||||
page = Page.objects.get(pk=cell.page_id)
|
||||
ActiveItems.objects.get_or_create(order=cell.order,
|
||||
page=page, placeholder=cell.placeholder,
|
||||
public=cell.public, regie=cell.regie,
|
||||
restricted_to_unlogged=cell.restricted_to_unlogged,
|
||||
slug=cell.slug, text=cell.text, title=cell.title
|
||||
)
|
||||
cell.delete()
|
||||
|
||||
def restore_itemshistory_cells(apps, schema_editor):
|
||||
InvoicesCell = apps.get_model('lingo', 'InvoicesCell')
|
||||
Page = apps.get_model('data', 'Page')
|
||||
ItemsHistory = apps.get_model('lingo', 'ItemsHistory')
|
||||
for cell in InvoicesCell.objects.filter(categories__contains='past'):
|
||||
page = Page.objects.get(pk=cell.page_id)
|
||||
ItemsHistory.objects.get_or_create(order=cell.order,
|
||||
page=page, placeholder=cell.placeholder,
|
||||
public=cell.public, regie=cell.regie,
|
||||
restricted_to_unlogged=cell.restricted_to_unlogged,
|
||||
slug=cell.slug, text=cell.text, title=cell.title
|
||||
)
|
||||
cell.delete()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('lingo', '0018_invoicescell'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(migrate_activeitems_cells,
|
||||
restore_activeitems_cells),
|
||||
migrations.RunPython(migrate_itemshistory_cells,
|
||||
restore_itemshistory_cells)
|
||||
]
|
|
@ -36,15 +36,12 @@ from django.core.exceptions import PermissionDenied
|
|||
from django.utils.http import urlencode
|
||||
|
||||
from ckeditor.fields import RichTextField
|
||||
from multiselectfield import MultiSelectField
|
||||
|
||||
from combo.data.models import CellBase
|
||||
from combo.data.library import register_cell_class
|
||||
from combo.utils import NothingInCacheException, sign_url
|
||||
|
||||
EXPIRED = 9999
|
||||
ACTIVE_ITEMS = 'active'
|
||||
PAST_ITEMS = 'past'
|
||||
|
||||
|
||||
SERVICES = [
|
||||
|
@ -58,11 +55,6 @@ SERVICES = [
|
|||
(eopayment.PAYZEN, _('PayZen')),
|
||||
]
|
||||
|
||||
INVOICE_CATEGORIES = (
|
||||
(ACTIVE_ITEMS, _('Active')),
|
||||
(PAST_ITEMS, _('Past'))
|
||||
)
|
||||
|
||||
def build_remote_item(data, regie):
|
||||
return RemoteItem(id=data.get('id'), regie=regie,
|
||||
creation_date=data['created'],
|
||||
|
@ -366,62 +358,6 @@ class LingoBasketLinkCell(CellBase):
|
|||
return basket_template.render(context)
|
||||
|
||||
|
||||
@register_cell_class
|
||||
class InvoicesCell(CellBase):
|
||||
regie = models.CharField(_('Regie'), max_length=50, blank=True)
|
||||
title = models.CharField(_('Title'), max_length=200, blank=True)
|
||||
text = RichTextField(_('Text'), blank=True, null=True)
|
||||
categories = MultiSelectField(_('Categories'), choices=INVOICE_CATEGORIES)
|
||||
|
||||
user_dependant = True
|
||||
template_name = 'lingo/combo/items.html'
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Invoices')
|
||||
|
||||
class Media:
|
||||
js = ('xstatic/jquery-ui.min.js', 'js/gadjo.js',)
|
||||
css = {'all': ('xstatic/themes/smoothness/jquery-ui.min.css', )}
|
||||
|
||||
@classmethod
|
||||
def is_enabled(cls):
|
||||
return Regie.objects.count() > 0
|
||||
|
||||
def get_default_form_class(self):
|
||||
fields = ['title', 'categories', 'text']
|
||||
widgets = {}
|
||||
if Regie.objects.count() > 1:
|
||||
regies = [('', _('All'))]
|
||||
regies.extend([(r.slug, r.label) for r in Regie.objects.all()])
|
||||
widgets['regie'] = Select(choices=regies)
|
||||
fields.insert(0, 'regie')
|
||||
return model_forms.modelform_factory(self.__class__, fields=fields, widgets=widgets)
|
||||
|
||||
def get_regies(self):
|
||||
if self.regie:
|
||||
return [Regie.objects.get(slug=self.regie)]
|
||||
return Regie.objects.all()
|
||||
|
||||
def get_cell_extra_context(self, context):
|
||||
ctx = {'title': self.title, 'text': self.text}
|
||||
invoices = []
|
||||
for r in self.get_regies():
|
||||
if ACTIVE_ITEMS in self.categories:
|
||||
invoices.extend(r.get_items(self.context))
|
||||
if PAST_ITEMS in self.categories:
|
||||
invoices.extend(r.get_past_items(self.context))
|
||||
# sort items by creation date
|
||||
invoices.sort(key=lambda i: i.creation_date, reverse=True)
|
||||
ctx.update({'items': invoices})
|
||||
return ctx
|
||||
|
||||
def render(self, context):
|
||||
self.context = context
|
||||
if not context.get('synchronous'):
|
||||
raise NothingInCacheException()
|
||||
return super(InvoicesCell, self).render(context)
|
||||
|
||||
|
||||
class Items(CellBase):
|
||||
regie = models.CharField(_('Regie'), max_length=50, blank=True)
|
||||
title = models.CharField(_('Title'), max_length=200, blank=True)
|
||||
|
|
143
combo/fields.py
143
combo/fields.py
|
@ -1,143 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# This is a modified copy of https://github.com/goinnn/django-multiselectfield
|
||||
#
|
||||
# Copyright (c) 2012 by Pablo Martín <goinnn@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this programe. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import sys
|
||||
|
||||
import django
|
||||
|
||||
from django.db import models
|
||||
from django.core import validators
|
||||
from django import forms
|
||||
from django.utils.text import capfirst
|
||||
from django.core import exceptions
|
||||
|
||||
if sys.version_info[0] == 2:
|
||||
string_type = unicode
|
||||
else:
|
||||
string_type = str
|
||||
|
||||
# Code from six egg https://bitbucket.org/gutworth/six/src/a3641cb211cc360848f1e2dd92e9ae6cd1de55dd/six.py?at=default
|
||||
|
||||
def get_max_length(choices, max_length, default=200):
|
||||
if max_length is None:
|
||||
if choices:
|
||||
return len(','.join([string_type(key) for key, label in choices]))
|
||||
else:
|
||||
return default
|
||||
return max_length
|
||||
|
||||
|
||||
class MaxValueMultiFieldValidator(validators.MaxLengthValidator):
|
||||
clean = lambda self, x: len(','.join(x))
|
||||
code = 'max_multifield_value'
|
||||
|
||||
|
||||
class MultiSelectFormField(forms.MultipleChoiceField):
|
||||
widget = forms.CheckboxSelectMultiple
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.max_choices = kwargs.pop('max_choices', None)
|
||||
self.max_length = kwargs.pop('max_length', None)
|
||||
super(MultiSelectFormField, self).__init__(*args, **kwargs)
|
||||
self.max_length = get_max_length(self.choices, self.max_length)
|
||||
self.validators.append(MaxValueMultiFieldValidator(self.max_length))
|
||||
|
||||
|
||||
class MultiSelectField(models.CharField):
|
||||
""" Choice values can not contain commas. """
|
||||
|
||||
__metaclass__ = models.SubfieldBase
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.max_choices = kwargs.pop('max_choices', None)
|
||||
super(MultiSelectField, self).__init__(*args, **kwargs)
|
||||
self.max_length = get_max_length(self.choices, self.max_length)
|
||||
self.validators[0] = MaxValueMultiFieldValidator(self.max_length)
|
||||
|
||||
@property
|
||||
def flatchoices(self):
|
||||
return None
|
||||
|
||||
def get_choices_default(self):
|
||||
return self.get_choices(include_blank=False)
|
||||
|
||||
def get_choices_selected(self, arr_choices):
|
||||
choices_selected = []
|
||||
for choice_selected in arr_choices:
|
||||
choices_selected.append(string_type(choice_selected[0]))
|
||||
return choices_selected
|
||||
|
||||
def value_to_string(self, obj):
|
||||
value = self._get_val_from_obj(obj)
|
||||
return self.get_prep_value(value)
|
||||
|
||||
def validate(self, value, model_instance):
|
||||
arr_choices = self.get_choices_selected(self.get_choices_default())
|
||||
for opt_select in value:
|
||||
if (opt_select not in arr_choices):
|
||||
raise exceptions.ValidationError(self.error_messages['invalid_choice'] % value)
|
||||
|
||||
def get_default(self):
|
||||
default = super(MultiSelectField, self).get_default()
|
||||
if isinstance(default, int):
|
||||
default = string_type(default)
|
||||
return default
|
||||
|
||||
def formfield(self, **kwargs):
|
||||
defaults = {'required': not self.blank,
|
||||
'label': capfirst(self.verbose_name),
|
||||
'help_text': self.help_text,
|
||||
'choices': self.choices,
|
||||
'max_length': self.max_length,
|
||||
'max_choices': self.max_choices}
|
||||
if self.has_default():
|
||||
defaults['initial'] = self.get_default()
|
||||
defaults.update(kwargs)
|
||||
return MultiSelectFormField(**defaults)
|
||||
|
||||
def get_prep_value(self, value):
|
||||
return '' if value is None else ",".join(value)
|
||||
|
||||
def to_python(self, value):
|
||||
if value:
|
||||
return value if isinstance(value, list) else value.split(',')
|
||||
|
||||
def contribute_to_class(self, cls, name):
|
||||
super(MultiSelectField, self).contribute_to_class(cls, name)
|
||||
if self.choices:
|
||||
def get_list(obj):
|
||||
fieldname = name
|
||||
choicedict = dict(self.choices)
|
||||
display = []
|
||||
if getattr(obj, fieldname):
|
||||
for value in getattr(obj, fieldname):
|
||||
item_display = choicedict.get(value, None)
|
||||
if item_display is None:
|
||||
try:
|
||||
item_display = choicedict.get(int(value), value)
|
||||
except (ValueError, TypeError):
|
||||
item_display = value
|
||||
display.append(string_type(item_display))
|
||||
return display
|
||||
|
||||
def get_display(obj):
|
||||
return ", ".join(get_list(obj))
|
||||
|
||||
setattr(cls, 'get_%s_list' % self.name, get_list)
|
||||
setattr(cls, 'get_%s_display' % self.name, get_display)
|
|
@ -70,7 +70,6 @@ INSTALLED_APPS = (
|
|||
'combo.apps.fargo',
|
||||
'combo.apps.usersearch',
|
||||
'xstatic.pkg.chartnew_js',
|
||||
'multiselectfield'
|
||||
)
|
||||
|
||||
INSTALLED_APPS = plugins.register_plugins_apps(INSTALLED_APPS)
|
||||
|
|
|
@ -15,7 +15,6 @@ Depends: ${misc:Depends}, ${python:Depends},
|
|||
python-feedparser,
|
||||
python-django-cmsplugin-blurp,
|
||||
python-xstatic-chartnew-js
|
||||
python-django-multiselectfield
|
||||
Recommends: python-django-mellon
|
||||
Conflicts: python-lingo
|
||||
Description: Portal Management System (Python module)
|
||||
|
|
1
setup.py
1
setup.py
|
@ -113,7 +113,6 @@ setup(
|
|||
'XStatic-ChartNew.js',
|
||||
'eopayment>=1.3',
|
||||
'python-dateutil',
|
||||
'django-multiselectfield',
|
||||
],
|
||||
zip_safe=False,
|
||||
cmdclass={
|
||||
|
|
|
@ -6,9 +6,7 @@ from django.template import Context
|
|||
from django.utils import timezone
|
||||
|
||||
from combo.data.models import Page
|
||||
from combo.utils import NothingInCacheException
|
||||
from combo.apps.lingo.models import Regie, BasketItem, Transaction
|
||||
from combo.apps.lingo.models import ACTIVE_ITEMS, InvoicesCell
|
||||
from combo.apps.lingo.models import LingoBasketCell, LingoRecentTransactionsCell
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
@ -70,16 +68,3 @@ def test_basket_cell(regie, user):
|
|||
|
||||
content = cell.render(context)
|
||||
assert '12345' in content
|
||||
|
||||
def test_invoices_cell(regie, user):
|
||||
page = Page(title='invoices', slug='test_invoices_cell', template_name='standard')
|
||||
page.save()
|
||||
cell = InvoicesCell(page=page, placeholder='content', order=0,
|
||||
regie=regie.slug, title='Active Invoices', categories=ACTIVE_ITEMS)
|
||||
context = Context({'request': RequestFactory().get('/')})
|
||||
context['request'].user = user
|
||||
assert cell.is_relevant(context) is True
|
||||
with pytest.raises(NothingInCacheException):
|
||||
cell.render(context)
|
||||
context['synchronous'] = True
|
||||
assert 'Active Invoices' in cell.render(context)
|
||||
|
|
Loading…
Reference in New Issue