Add basic configure page for Trainwreck
also the beginnings of a "yearly rollover" page which hopefully will prove useful for helping to automate that, once i figure out how best to go about it...
This commit is contained in:
		
							parent
							
								
									94883c1433
								
							
						
					
					
						commit
						3aac855fa1
					
				
					 6 changed files with 234 additions and 17 deletions
				
			
		| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
################################################################################
 | 
					################################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  Rattail -- Retail Software Framework
 | 
					#  Rattail -- Retail Software Framework
 | 
				
			||||||
#  Copyright © 2010-2021 Lance Edgar
 | 
					#  Copyright © 2010-2022 Lance Edgar
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  This file is part of Rattail.
 | 
					#  This file is part of Rattail.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -108,6 +108,7 @@ def before_render(event):
 | 
				
			||||||
    request = event.get('request') or threadlocal.get_current_request()
 | 
					    request = event.get('request') or threadlocal.get_current_request()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    renderer_globals = event
 | 
					    renderer_globals = event
 | 
				
			||||||
 | 
					    renderer_globals['rattail_app'] = request.rattail_config.get_app()
 | 
				
			||||||
    renderer_globals['h'] = helpers
 | 
					    renderer_globals['h'] = helpers
 | 
				
			||||||
    renderer_globals['url'] = request.route_url
 | 
					    renderer_globals['url'] = request.route_url
 | 
				
			||||||
    renderer_globals['rattail'] = rattail
 | 
					    renderer_globals['rattail'] = rattail
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										31
									
								
								tailbone/templates/trainwreck/transactions/configure.mako
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								tailbone/templates/trainwreck/transactions/configure.mako
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,31 @@
 | 
				
			||||||
 | 
					## -*- coding: utf-8; -*-
 | 
				
			||||||
 | 
					<%inherit file="/configure.mako" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%def name="form_content()">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <h3 class="block is-size-3">Hidden Databases</h3>
 | 
				
			||||||
 | 
					  <div class="block" style="padding-left: 2rem;">
 | 
				
			||||||
 | 
					    % for key, engine in six.iteritems(trainwreck_engines):
 | 
				
			||||||
 | 
					        <b-field>
 | 
				
			||||||
 | 
					          <b-checkbox name="hidedb_${key}"
 | 
				
			||||||
 | 
					                      v-model="hiddenDatabases['${key}']"
 | 
				
			||||||
 | 
					                      native-value="true"
 | 
				
			||||||
 | 
					                      @input="settingsNeedSaved = true">
 | 
				
			||||||
 | 
					            ${key}
 | 
				
			||||||
 | 
					          </b-checkbox>
 | 
				
			||||||
 | 
					        </b-field>
 | 
				
			||||||
 | 
					    % endfor
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</%def>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%def name="modify_this_page_vars()">
 | 
				
			||||||
 | 
					  ${parent.modify_this_page_vars()}
 | 
				
			||||||
 | 
					  <script type="text/javascript">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ThisPageData.hiddenDatabases = ${json.dumps(hidden_databases)|n}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  </script>
 | 
				
			||||||
 | 
					</%def>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					${parent.body()}
 | 
				
			||||||
							
								
								
									
										12
									
								
								tailbone/templates/trainwreck/transactions/index.mako
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								tailbone/templates/trainwreck/transactions/index.mako
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					## -*- coding: utf-8; -*-
 | 
				
			||||||
 | 
					<%inherit file="/master/index.mako" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%def name="context_menu_items()">
 | 
				
			||||||
 | 
					  ${parent.context_menu_items()}
 | 
				
			||||||
 | 
					  % if master.has_perm('rollover'):
 | 
				
			||||||
 | 
					      <li>${h.link_to("Yearly Rollover", url('{}.rollover'.format(route_prefix)))}</li>
 | 
				
			||||||
 | 
					  % endif
 | 
				
			||||||
 | 
					</%def>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					${parent.body()}
 | 
				
			||||||
							
								
								
									
										57
									
								
								tailbone/templates/trainwreck/transactions/rollover.mako
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								tailbone/templates/trainwreck/transactions/rollover.mako
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,57 @@
 | 
				
			||||||
 | 
					## -*- coding: utf-8; -*-
 | 
				
			||||||
 | 
					<%inherit file="/page.mako" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%def name="title()">${index_title} » Yearly Rollover</%def>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%def name="content_title()">Yearly Rollover</%def>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%def name="page_content()">
 | 
				
			||||||
 | 
					  <br />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  % if six.text_type(next_year) not in trainwreck_engines:
 | 
				
			||||||
 | 
					      <b-notification type="is-warning">
 | 
				
			||||||
 | 
					        You do not have a database configured for next year (${next_year}). 
 | 
				
			||||||
 | 
					        You should be sure to configure it before next year rolls around.
 | 
				
			||||||
 | 
					      </b-notification>
 | 
				
			||||||
 | 
					  % endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <p class="block">
 | 
				
			||||||
 | 
					    The following Trainwreck databases are configured:
 | 
				
			||||||
 | 
					  </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <b-table :data="engines">
 | 
				
			||||||
 | 
					    <template slot-scope="props">
 | 
				
			||||||
 | 
					      <b-table-column field="key" label="DB Key">
 | 
				
			||||||
 | 
					        {{ props.row.key }}
 | 
				
			||||||
 | 
					      </b-table-column>
 | 
				
			||||||
 | 
					      <b-table-column field="oldest_date" label="Oldest Date">
 | 
				
			||||||
 | 
					        <span v-if="props.row.error" class="has-text-danger">
 | 
				
			||||||
 | 
					          error
 | 
				
			||||||
 | 
					        </span>
 | 
				
			||||||
 | 
					        <span v-if="!props.row.error">
 | 
				
			||||||
 | 
					          {{ props.row.oldest_date }}
 | 
				
			||||||
 | 
					        </span>
 | 
				
			||||||
 | 
					      </b-table-column>
 | 
				
			||||||
 | 
					      <b-table-column field="newest_date" label="Newest Date">
 | 
				
			||||||
 | 
					        <span v-if="props.row.error" class="has-text-danger">
 | 
				
			||||||
 | 
					          error
 | 
				
			||||||
 | 
					        </span>
 | 
				
			||||||
 | 
					        <span v-if="!props.row.error">
 | 
				
			||||||
 | 
					          {{ props.row.newest_date }}
 | 
				
			||||||
 | 
					        </span>
 | 
				
			||||||
 | 
					      </b-table-column>
 | 
				
			||||||
 | 
					    </template>
 | 
				
			||||||
 | 
					  </b-table>
 | 
				
			||||||
 | 
					</%def>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%def name="modify_this_page_vars()">
 | 
				
			||||||
 | 
					  ${parent.modify_this_page_vars()}
 | 
				
			||||||
 | 
					  <script type="text/javascript">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ThisPageData.engines = ${json.dumps(engines_data)|n}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  </script>
 | 
				
			||||||
 | 
					</%def>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					${parent.body()}
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
################################################################################
 | 
					################################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  Rattail -- Retail Software Framework
 | 
					#  Rattail -- Retail Software Framework
 | 
				
			||||||
#  Copyright © 2010-2021 Lance Edgar
 | 
					#  Copyright © 2010-2022 Lance Edgar
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  This file is part of Rattail.
 | 
					#  This file is part of Rattail.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -60,6 +60,7 @@ from webob.compat import cgi_FieldStorage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from tailbone import forms, grids, diffs
 | 
					from tailbone import forms, grids, diffs
 | 
				
			||||||
from tailbone.views import View
 | 
					from tailbone.views import View
 | 
				
			||||||
 | 
					from tailbone.db import Session
 | 
				
			||||||
from tailbone.config import global_help_url
 | 
					from tailbone.config import global_help_url
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4412,14 +4413,19 @@ class MasterView(View):
 | 
				
			||||||
                ])
 | 
					                ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if names:
 | 
					        if names:
 | 
				
			||||||
            self.Session.query(model.Setting)\
 | 
					            # nb. we do not use self.Session b/c that may not point to
 | 
				
			||||||
 | 
					            # the Rattail DB for the subclass
 | 
				
			||||||
 | 
					            Session().query(model.Setting)\
 | 
				
			||||||
                     .filter(model.Setting.name.in_(names))\
 | 
					                     .filter(model.Setting.name.in_(names))\
 | 
				
			||||||
                     .delete(synchronize_session=False)
 | 
					                     .delete(synchronize_session=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_save_settings(self, settings):
 | 
					    def configure_save_settings(self, settings):
 | 
				
			||||||
        model = self.model
 | 
					        model = self.model
 | 
				
			||||||
 | 
					        # nb. we do not use self.Session b/c that may not point to the
 | 
				
			||||||
 | 
					        # Rattail DB for the subclass
 | 
				
			||||||
 | 
					        session = Session()
 | 
				
			||||||
        for setting in settings:
 | 
					        for setting in settings:
 | 
				
			||||||
            self.Session.add(model.Setting(name=setting['name'],
 | 
					            session.add(model.Setting(name=setting['name'],
 | 
				
			||||||
                                      value=setting['value']))
 | 
					                                      value=setting['value']))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ##############################
 | 
					    ##############################
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
################################################################################
 | 
					################################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  Rattail -- Retail Software Framework
 | 
					#  Rattail -- Retail Software Framework
 | 
				
			||||||
#  Copyright © 2010-2021 Lance Edgar
 | 
					#  Copyright © 2010-2022 Lance Edgar
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  This file is part of Rattail.
 | 
					#  This file is part of Rattail.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -29,9 +29,8 @@ from __future__ import unicode_literals, absolute_import
 | 
				
			||||||
import six
 | 
					import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from rattail.time import localtime
 | 
					from rattail.time import localtime
 | 
				
			||||||
from rattail.util import OrderedDict
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from tailbone.db import TrainwreckSession, ExtraTrainwreckSessions
 | 
					from tailbone.db import Session, TrainwreckSession, ExtraTrainwreckSessions
 | 
				
			||||||
from tailbone.views import MasterView
 | 
					from tailbone.views import MasterView
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,6 +52,8 @@ class TransactionView(MasterView):
 | 
				
			||||||
    SessionDefault = TrainwreckSession
 | 
					    SessionDefault = TrainwreckSession
 | 
				
			||||||
    SessionExtras = ExtraTrainwreckSessions
 | 
					    SessionExtras = ExtraTrainwreckSessions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    configurable = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    labels = {
 | 
					    labels = {
 | 
				
			||||||
        'store_id': "Store",
 | 
					        'store_id': "Store",
 | 
				
			||||||
        'cashback': "Cash Back",
 | 
					        'cashback': "Cash Back",
 | 
				
			||||||
| 
						 | 
					@ -139,13 +140,9 @@ class TransactionView(MasterView):
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_db_engines(self):
 | 
					    def get_db_engines(self):
 | 
				
			||||||
        engines = OrderedDict(self.rattail_config.trainwreck_engines)
 | 
					        app = self.get_rattail_app()
 | 
				
			||||||
        hidden = self.rattail_config.getlist('tailbone', 'engines.trainwreck.hidden',
 | 
					        trainwreck_handler = app.get_trainwreck_handler()
 | 
				
			||||||
                                             default=None)
 | 
					        return trainwreck_handler.get_trainwreck_engines(include_hidden=False)
 | 
				
			||||||
        if hidden:
 | 
					 | 
				
			||||||
            for key in hidden:
 | 
					 | 
				
			||||||
                engines.pop(key, None)
 | 
					 | 
				
			||||||
        return engines
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_grid(self, g):
 | 
					    def configure_grid(self, g):
 | 
				
			||||||
        super(TransactionView, self).configure_grid(g)
 | 
					        super(TransactionView, self).configure_grid(g)
 | 
				
			||||||
| 
						 | 
					@ -228,3 +225,116 @@ class TransactionView(MasterView):
 | 
				
			||||||
        f.set_type('discounted_subtotal', 'currency')
 | 
					        f.set_type('discounted_subtotal', 'currency')
 | 
				
			||||||
        f.set_type('tax', 'currency')
 | 
					        f.set_type('tax', 'currency')
 | 
				
			||||||
        f.set_type('total', 'currency')
 | 
					        f.set_type('total', 'currency')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def rollover(self):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        View for performing yearly rollover functions.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        app = self.get_rattail_app()
 | 
				
			||||||
 | 
					        trainwreck_handler = app.get_trainwreck_handler()
 | 
				
			||||||
 | 
					        trainwreck_engines = trainwreck_handler.get_trainwreck_engines()
 | 
				
			||||||
 | 
					        current_year = app.localtime().year
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # find oldest and newest dates for each database
 | 
				
			||||||
 | 
					        engines_data = []
 | 
				
			||||||
 | 
					        for key, engine in six.iteritems(trainwreck_engines):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if key == 'default':
 | 
				
			||||||
 | 
					                session = self.Session()
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                session = ExtraTrainwreckSessions[key]()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            error = False
 | 
				
			||||||
 | 
					            oldest = None
 | 
				
			||||||
 | 
					            newest = None
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                oldest = trainwreck_handler.get_oldest_transaction_date(session)
 | 
				
			||||||
 | 
					                newest = trainwreck_handler.get_newest_transaction_date(session)
 | 
				
			||||||
 | 
					            except:
 | 
				
			||||||
 | 
					                error = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            engines_data.append({
 | 
				
			||||||
 | 
					                'key': key,
 | 
				
			||||||
 | 
					                'oldest_date': app.render_date(oldest) if oldest else None,
 | 
				
			||||||
 | 
					                'newest_date': app.render_date(newest) if newest else None,
 | 
				
			||||||
 | 
					                'error': error,
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return self.render_to_response('rollover', {
 | 
				
			||||||
 | 
					            'instance_title': "Yearly Rollover",
 | 
				
			||||||
 | 
					            'trainwreck_handler': trainwreck_handler,
 | 
				
			||||||
 | 
					            'current_year': current_year,
 | 
				
			||||||
 | 
					            'next_year': current_year + 1,
 | 
				
			||||||
 | 
					            'trainwreck_engines': trainwreck_engines,
 | 
				
			||||||
 | 
					            'engines_data': engines_data,
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def configure_get_context(self):
 | 
				
			||||||
 | 
					        context = super(TransactionView, self).configure_get_context()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        app = self.get_rattail_app()
 | 
				
			||||||
 | 
					        trainwreck_handler = app.get_trainwreck_handler()
 | 
				
			||||||
 | 
					        trainwreck_engines = trainwreck_handler.get_trainwreck_engines()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context['trainwreck_engines'] = trainwreck_engines
 | 
				
			||||||
 | 
					        context['hidden_databases'] = dict([
 | 
				
			||||||
 | 
					            (key, trainwreck_handler.engine_is_hidden(key))
 | 
				
			||||||
 | 
					            for key in trainwreck_engines])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def configure_gather_settings(self, data):
 | 
				
			||||||
 | 
					        settings = super(TransactionView, self).configure_gather_settings(data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        app = self.get_rattail_app()
 | 
				
			||||||
 | 
					        trainwreck_handler = app.get_trainwreck_handler()
 | 
				
			||||||
 | 
					        trainwreck_engines = trainwreck_handler.get_trainwreck_engines()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        hidden = []
 | 
				
			||||||
 | 
					        for key in trainwreck_engines:
 | 
				
			||||||
 | 
					            name = 'hidedb_{}'.format(key)
 | 
				
			||||||
 | 
					            if data.get(name) == 'true':
 | 
				
			||||||
 | 
					                hidden.append(key)
 | 
				
			||||||
 | 
					        settings.append({'name': 'trainwreck.db.hide',
 | 
				
			||||||
 | 
					                         'value': ', '.join(hidden)})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def configure_remove_settings(self):
 | 
				
			||||||
 | 
					        super(TransactionView, self).configure_remove_settings()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        model = self.model
 | 
				
			||||||
 | 
					        names = [
 | 
				
			||||||
 | 
					            'trainwreck.db.hide',
 | 
				
			||||||
 | 
					            'tailbone.engines.trainwreck.hidden', # deprecated
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        # nb. we do not use self.Session b/c that points to trainwreck
 | 
				
			||||||
 | 
					        Session.query(model.Setting)\
 | 
				
			||||||
 | 
					               .filter(model.Setting.name.in_(names))\
 | 
				
			||||||
 | 
					               .delete(synchronize_session=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def defaults(cls, config):
 | 
				
			||||||
 | 
					        cls._trainwreck_defaults(config)
 | 
				
			||||||
 | 
					        cls._defaults(config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def _trainwreck_defaults(cls, config):
 | 
				
			||||||
 | 
					        route_prefix = cls.get_route_prefix()
 | 
				
			||||||
 | 
					        url_prefix = cls.get_url_prefix()
 | 
				
			||||||
 | 
					        permission_prefix = cls.get_permission_prefix()
 | 
				
			||||||
 | 
					        model_title_plural = cls.get_model_title_plural()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # fix perm group title
 | 
				
			||||||
 | 
					        config.add_tailbone_permission_group(permission_prefix,
 | 
				
			||||||
 | 
					                                             model_title_plural)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # rollover
 | 
				
			||||||
 | 
					        config.add_tailbone_permission(permission_prefix,
 | 
				
			||||||
 | 
					                                       '{}.rollover'.format(permission_prefix),
 | 
				
			||||||
 | 
					                                       label="Perform yearly rollover for Trainwreck")
 | 
				
			||||||
 | 
					        config.add_route('{}.rollover'.format(route_prefix),
 | 
				
			||||||
 | 
					                         '{}/rollover'.format(url_prefix))
 | 
				
			||||||
 | 
					        config.add_view(cls, attr='rollover',
 | 
				
			||||||
 | 
					                        route_name='{}.rollover'.format(route_prefix),
 | 
				
			||||||
 | 
					                        permission='{}.rollover'.format(permission_prefix))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue