Source code for collecting_society_web.views.forms.add_declaration

# For copyright and license terms, see COPYRIGHT.rst (top level of repository)
# Repository: https://github.com/C3S/collecting_society_web

import logging

import colander
import deform
from pyramid.httpexceptions import HTTPBadRequest

from portal_web.models import Tdb, Country
from portal_web.views.forms import FormController
from portal_web.views.forms.deform.money_input import MoneyInputField

from ...services import _
from ...resources import DeclarationsResource
from ...models import (
    Artist,
    Event,
    Declaration,
    DistributionPlan,
    Location,
    LocationCategory,
    Tariff,
    TariffAdjustmentCategory,
    TariffCategory,
    TariffRelevance,
    TariffRelevanceCategory,
)
from .datatables import (
    LocationSequence,
    PerformanceSequence,
    TariffAdjustmentSequence,
)

log = logging.getLogger(__name__)


[docs] class AddDeclarationLive(FormController): """ form controller for creation of declarations with tariff live """
[docs] def controller(self): self.form = live_form(self.request) self.render() if self.submitted(): if self.validate(): self.create_declaration() return self.response
# --- Stages -------------------------------------------------------------- # --- Conditions ---------------------------------------------------------- # --- Actions -------------------------------------------------------------
[docs] @Tdb.transaction(readonly=False) def create_declaration(self): from pprint import pformat log.debug(pformat({ 'data': self.data, 'appstruct': self.appstruct, 'post': self.request.POST, 'get': self.request.GET, })) # appstruct shortcuts _event = self.appstruct['event'] _location = _event['location'][0] _estimation = self.appstruct['estimation'] _utilisation = self.appstruct['utilisation'] _adjustments = _utilisation['adjustments'] # prepare: tariff tariff_category_code = self.request.view_name tariff_category_codes = [ tariff_category.code for tariff_category in TariffCategory.search_all() ] if tariff_category_code not in tariff_category_codes: raise HTTPBadRequest() tariff = Tariff.search_latest_by_category_code(self.request.view_name) if not tariff: raise HTTPBadRequest() # prepare: period if tariff.category.code in ['L']: period = 'onetime' else: period = self.appstruct['utilisation']['period'] # prepare: adjustments adjustments_vlist = [] for adjustment in _adjustments: category = TariffAdjustmentCategory.search_by_code( adjustment['category'], tariff.category.code) adjustments_vlist.append({ 'category': category, 'value': category.value_default, }) # prepare: others web_user = self.request.web_user distribution_plan = DistributionPlan.search_latest() location_category = LocationCategory.search_by_code( _location['category']) country = Country.search_by_code(_location['country']) tariff_relevance_category = TariffRelevanceCategory.search_by_oid( _utilisation['relevance']) # create location location_vlist = { 'name': _location['name'], 'category': location_category, 'public': False, 'street': _location['street'], 'postal_code': _location['postal_code'], 'city': _location['city'], 'country': country, 'entity_origin': 'indirect', 'entity_creator': web_user.party, } location, = Location.create([location_vlist]) # create event event_vlist = { 'name': _event['name'], 'description': _event['description'], 'location': location, 'performances': [('create', [{ 'start': performance['start'], 'end': performance['end'], 'artist': Artist.search_by_code( performance['artist'][0]['code']), } for performance in _event['performances']])], 'estimated_start': _estimation['start'], 'estimated_end': _estimation['end'], 'estimated_attendants': _estimation['attendants'], 'estimated_max_attendants': _estimation['max_attendants'], 'estimated_max_admission': _estimation['max_admission'], 'estimated_turnover_tickets': _estimation['turnover_tickets'], 'estimated_turnover_benefit': _estimation['turnover_benefit'], 'estimated_expenses_musicians': _estimation['expenses_musicians'], 'estimated_expenses_production': _estimation['expenses_production'], } event, = Event.create([event_vlist]) # create tariff relevance tariff_relevance_vlist = { 'category': tariff_relevance_category, 'value': tariff_relevance_category.value_default, } tariff_relevance, = TariffRelevance.create([tariff_relevance_vlist]) # create declaration declaration_vlist = { 'licensee': web_user.party, 'state': 'submitted', 'tariff': tariff, 'period': period, 'context': event, 'utilisations': [('create', [{ 'licensee': web_user.party, 'state': 'estimated', 'tariff': tariff, 'distribution_plan': distribution_plan, 'context': event, 'estimated_relevance': tariff_relevance, 'estimated_adjustments': [('create', adjustments_vlist)] }])] } declaration = Declaration.create([declaration_vlist]) # user feedback if not declaration: log.info("declaration add failed for %s: %s" % ( web_user, declaration_vlist)) self.request.session.flash( _(u"Declaration could not be added."), 'main-alert-danger' ) self.redirect(DeclarationsResource) return declaration = declaration[0] log.info("declaration add successful for %s: %s" % ( web_user, declaration)) self.request.session.flash( _(u"Declaration added."), 'main-alert-success' ) # redirect self.redirect(DeclarationsResource)
# --- Validators -------------------------------------------------------------- # --- Options ----------------------------------------------------------------- period_options = ( ('monthly', _('Monthly')), ('quarterly', _('Quarterly')), ('yearly', _('Yearly')), ) # --- Widgets ----------------------------------------------------------------- @colander.deferred def current_tariff_relevance_category_select_widget(node, kw): tariff_category = None tariff_categories = TariffCategory.search_all() for category in tariff_categories: if category.code == kw['request'].view_name: tariff_category = category break values = [] if tariff_category: values = [(category.oid, f"{category.name} ({category.value_default})") for category in tariff_category.relevance_categories] widget = deform.widget.SelectWidget(values=values) return widget # --- Fields ------------------------------------------------------------------ @colander.deferred def deferred_period_missing(node, kw): tariff_category_code = kw['request'].view_name if tariff_category_code in ['L']: return "" return colander.required # --- Utilisation
[docs] class PeriodField(colander.SchemaNode): oid = "period" schema_type = colander.String widget = deform.widget.SelectWidget(values=period_options) missing = deferred_period_missing
[docs] class RelevanceField(colander.SchemaNode): oid = "relevance" schema_type = colander.String widget = current_tariff_relevance_category_select_widget
# --- EventIndicators
[docs] class EventStartField(colander.SchemaNode): oid = "start" schema_type = colander.DateTime
[docs] class EventEndField(colander.SchemaNode): oid = "end" schema_type = colander.DateTime
[docs] class EventAttendantsField(colander.SchemaNode): oid = "attendants" schema_type = colander.Integer
[docs] class EventMaxAttendantsField(colander.SchemaNode): oid = "max_attendants" schema_type = colander.Integer
[docs] class EventMaxAdmissionField(MoneyInputField): oid = "max_admission"
[docs] class EventTurnoverTicketsField(MoneyInputField): oid = "turnover_tickets"
[docs] class EventTurnoverBenefitField(MoneyInputField): oid = "turnover_benefit"
[docs] class EventExpensesMusiciansField(MoneyInputField): oid = "expenses_musicians"
[docs] class EventExpensesProductionField(MoneyInputField): oid = "expenses_production"
# --- Event
[docs] class EventNameField(colander.SchemaNode): oid = "name" schema_type = colander.String
[docs] class EventDescriptionField(colander.SchemaNode): oid = "description" schema_type = colander.String widget = deform.widget.TextAreaWidget() missing = ""
# --- Schemas -----------------------------------------------------------------
[docs] class UtilisationOnetimeSchema(colander.Schema): title = _("Adjustments") widget = deform.widget.MappingWidget(template='navs/mapping') relevance = RelevanceField() adjustments = TariffAdjustmentSequence(title=_("Adjustments"))
[docs] class UtilisationPeriodSchema(colander.Schema): title = _("Adjustments") widget = deform.widget.MappingWidget(template='navs/mapping') relevance = RelevanceField() period = PeriodField() adjustments = TariffAdjustmentSequence(title=_("Adjustments"))
[docs] class EventIndicatorsSchema(colander.Schema): title = _("Estimation") widget = deform.widget.MappingWidget(template='navs/mapping') start = EventStartField() end = EventEndField() attendants = EventAttendantsField() max_attendants = EventMaxAttendantsField() max_admission = EventMaxAdmissionField() turnover_tickets = EventTurnoverTicketsField() turnover_benefit = EventTurnoverBenefitField() expenses_musicians = EventExpensesMusiciansField() expenses_production = EventExpensesProductionField()
[docs] class EventSchema(colander.Schema): title = _("Event") widget = deform.widget.MappingWidget(template='navs/mapping') name = EventNameField() description = EventDescriptionField() location = LocationSequence(title=_("Location"), min_len=1, max_len=1) performances = PerformanceSequence(title=_("Performances"), min_len=1)
[docs] class LiveSchema(colander.Schema): widget = deform.widget.FormWidget(template='navs/form', navstyle='tabs') event = EventSchema() estimation = EventIndicatorsSchema() utilisation = UtilisationOnetimeSchema()
# --- Forms -------------------------------------------------------------------
[docs] def live_form(request): return deform.Form( schema=LiveSchema().bind(request=request), buttons=[ deform.Button('submit', _("Submit")), ] )