Remove several references to "buefy" name
class methods, template filenames, etc. also made various edits per newer conventions
This commit is contained in:
parent
96ba039299
commit
c036932ce4
|
@ -33,10 +33,9 @@ from collections import OrderedDict
|
|||
import sqlalchemy as sa
|
||||
from sqlalchemy import orm
|
||||
from sqlalchemy.ext.associationproxy import AssociationProxy, ASSOCIATION_PROXY
|
||||
from wuttjamaican.util import UNSPECIFIED
|
||||
|
||||
from rattail.time import localtime
|
||||
from rattail.util import prettify, pretty_boolean, pretty_quantity
|
||||
from rattail.core import UNSPECIFIED
|
||||
from rattail.util import prettify, pretty_boolean
|
||||
from rattail.db.util import get_fieldnames
|
||||
|
||||
import colander
|
||||
|
@ -50,10 +49,10 @@ from webhelpers2.html import tags, HTML
|
|||
|
||||
from tailbone.db import Session
|
||||
from tailbone.util import raw_datetime, get_form_data, render_markdown
|
||||
from . import types
|
||||
from .widgets import (ReadonlyWidget, PlainDateWidget,
|
||||
JQueryDateWidget, JQueryTimeWidget,
|
||||
MultiFileUploadWidget)
|
||||
from tailbone.forms import types
|
||||
from tailbone.forms.widgets import (ReadonlyWidget, PlainDateWidget,
|
||||
JQueryDateWidget, JQueryTimeWidget,
|
||||
MultiFileUploadWidget)
|
||||
from tailbone.exceptions import TailboneJSONFieldError
|
||||
|
||||
|
||||
|
@ -225,7 +224,7 @@ class CustomSchemaNode(SQLAlchemySchemaNode):
|
|||
if excludes:
|
||||
overrides['excludes'] = excludes
|
||||
|
||||
return super(CustomSchemaNode, self).get_schema_from_relationship(prop, overrides)
|
||||
return super().get_schema_from_relationship(prop, overrides)
|
||||
|
||||
def dictify(self, obj):
|
||||
""" Return a dictified version of `obj` using schema information.
|
||||
|
@ -234,7 +233,7 @@ class CustomSchemaNode(SQLAlchemySchemaNode):
|
|||
This method was copied from upstream and modified to add automatic
|
||||
handling of "association proxy" fields.
|
||||
"""
|
||||
dict_ = super(CustomSchemaNode, self).dictify(obj)
|
||||
dict_ = super().dictify(obj)
|
||||
for node in self:
|
||||
|
||||
name = node.name
|
||||
|
@ -967,7 +966,7 @@ class Form(object):
|
|||
kwargs.setdefault(':configure-fields-help', 'configureFieldsHelp')
|
||||
return HTML.tag(self.component, **kwargs)
|
||||
|
||||
def render_buefy_field(self, fieldname, bfield_attrs={}):
|
||||
def render_field_complete(self, fieldname, bfield_attrs={}):
|
||||
"""
|
||||
Render the given field in a Buefy-compatible way. Note that
|
||||
this is meant to render *editable* fields, i.e. showing a
|
||||
|
@ -1131,7 +1130,8 @@ class Form(object):
|
|||
value = self.obtain_value(record, field_name)
|
||||
if value is None:
|
||||
return ""
|
||||
value = localtime(self.request.rattail_config, value)
|
||||
app = self.get_rattail_app()
|
||||
value = app.localtime(value)
|
||||
return raw_datetime(self.request.rattail_config, value)
|
||||
|
||||
def render_duration(self, record, field_name):
|
||||
|
@ -1160,7 +1160,8 @@ class Form(object):
|
|||
value = self.obtain_value(obj, field)
|
||||
if value is None:
|
||||
return ""
|
||||
return pretty_quantity(value)
|
||||
app = self.get_rattail_app()
|
||||
return app.render_quantity(value)
|
||||
|
||||
def render_percent(self, obj, field):
|
||||
app = self.request.rattail_config.get_app()
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -153,6 +153,7 @@ class DynamicCheckboxWidget(dfwidget.CheckboxWidget):
|
|||
template = 'checkbox_dynamic'
|
||||
|
||||
|
||||
# TODO: deprecate / remove this
|
||||
class PlainSelectWidget(dfwidget.SelectWidget):
|
||||
template = 'select_plain'
|
||||
|
||||
|
|
|
@ -1339,10 +1339,10 @@ class Grid(object):
|
|||
includes the context menu items and grid tools.
|
||||
"""
|
||||
if 'grid_columns' not in kwargs:
|
||||
kwargs['grid_columns'] = self.get_buefy_columns()
|
||||
kwargs['grid_columns'] = self.get_table_columns()
|
||||
|
||||
if 'grid_data' not in kwargs:
|
||||
kwargs['grid_data'] = self.get_buefy_data()
|
||||
kwargs['grid_data'] = self.get_table_data()
|
||||
|
||||
if 'static_data' not in kwargs:
|
||||
kwargs['static_data'] = self.has_static_data()
|
||||
|
@ -1364,10 +1364,11 @@ class Grid(object):
|
|||
warnings.warn("Grid.render_buefy() is deprecated; "
|
||||
"please use Grid.render_complete() instead",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
return self.render_complete(**kwargs)
|
||||
|
||||
def render_buefy_table_element(self, template='/grids/b-table.mako',
|
||||
data_prop='gridData', empty_labels=False,
|
||||
**kwargs):
|
||||
def render_table_element(self, template='/grids/b-table.mako',
|
||||
data_prop='gridData', empty_labels=False,
|
||||
**kwargs):
|
||||
"""
|
||||
This is intended for ad-hoc "small" grids with static data. Renders
|
||||
just a ``<b-table>`` element instead of the typical "full" grid.
|
||||
|
@ -1377,7 +1378,7 @@ class Grid(object):
|
|||
context['data_prop'] = data_prop
|
||||
context['empty_labels'] = empty_labels
|
||||
if 'grid_columns' not in context:
|
||||
context['grid_columns'] = self.get_buefy_columns()
|
||||
context['grid_columns'] = self.get_table_columns()
|
||||
context.setdefault('paginated', False)
|
||||
if context['paginated']:
|
||||
context.setdefault('per_page', 20)
|
||||
|
@ -1572,10 +1573,10 @@ class Grid(object):
|
|||
return True
|
||||
return False
|
||||
|
||||
def get_buefy_columns(self):
|
||||
def get_table_columns(self):
|
||||
"""
|
||||
Return a list of dicts representing all grid columns. Meant for use
|
||||
with Buefy table.
|
||||
Return a list of dicts representing all grid columns. Meant
|
||||
for use with the client-side JS table.
|
||||
"""
|
||||
columns = []
|
||||
for name in self.columns:
|
||||
|
@ -1597,9 +1598,10 @@ class Grid(object):
|
|||
if hasattr(rowobj, 'uuid'):
|
||||
return rowobj.uuid
|
||||
|
||||
def get_buefy_data(self):
|
||||
def get_table_data(self):
|
||||
"""
|
||||
Returns a list of data rows for the grid, for use with Buefy table.
|
||||
Returns a list of data rows for the grid, for use with
|
||||
client-side JS table.
|
||||
"""
|
||||
# filter / sort / paginate to get "visible" data
|
||||
raw_data = self.make_visible_data()
|
||||
|
@ -1635,8 +1637,8 @@ class Grid(object):
|
|||
# instance, when the "display" version is different than raw data.
|
||||
# here is the hack we use for that.
|
||||
columns = list(self.columns)
|
||||
if hasattr(self, 'buefy_data_columns'):
|
||||
columns.extend(self.buefy_data_columns)
|
||||
if hasattr(self, 'raw_data_columns'):
|
||||
columns.extend(self.raw_data_columns)
|
||||
|
||||
# iterate over data fields
|
||||
for name in columns:
|
||||
|
|
|
@ -154,7 +154,7 @@
|
|||
${parent.modify_this_page_vars()}
|
||||
<script type="text/javascript">
|
||||
|
||||
ThisPageData.groups = ${json.dumps(buefy_data)|n}
|
||||
ThisPageData.groups = ${json.dumps(settings_data)|n}
|
||||
ThisPageData.showingGroup = ${json.dumps(current_group or '')|n}
|
||||
|
||||
</script>
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="render_buefy_form()">
|
||||
<%def name="render_form()">
|
||||
<div class="form">
|
||||
<tailbone-form></tailbone-form>
|
||||
<br />
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
</nav>
|
||||
</%def>
|
||||
|
||||
<%def name="render_form()">
|
||||
<%def name="render_form_template()">
|
||||
<script type="text/x-template" id="${form.component}-template">
|
||||
<div class="product-info">
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## -*- coding: utf-8; -*-
|
||||
<%inherit file="/master/view_row.mako" />
|
||||
|
||||
<%def name="render_buefy_form()">
|
||||
<%def name="render_form()">
|
||||
<div class="form">
|
||||
<tailbone-form></tailbone-form>
|
||||
<br />
|
||||
|
|
|
@ -148,7 +148,7 @@
|
|||
</div>
|
||||
</%def>
|
||||
|
||||
<%def name="render_form()">
|
||||
<%def name="render_form_template()">
|
||||
## TODO: should use self.render_form_buttons()
|
||||
## ${form.render_deform(form_id='batch-form', buttons=capture(self.render_form_buttons))|n}
|
||||
${form.render_deform(form_id='batch-form', buttons=capture(buttons))|n}
|
||||
|
@ -206,7 +206,7 @@
|
|||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="render_buefy_form()">
|
||||
<%def name="render_form()">
|
||||
<div class="form">
|
||||
<${form.component} @show-upload="showUploadDialog = true">
|
||||
</${form.component}>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="render_buefy_form()">
|
||||
<%def name="render_form()">
|
||||
<div class="form">
|
||||
<tailbone-form @detach-person="detachPerson">
|
||||
</tailbone-form>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## -*- coding: utf-8; -*-
|
||||
<%inherit file="/master/view.mako" />
|
||||
|
||||
<%def name="render_buefy_form()">
|
||||
<%def name="render_form()">
|
||||
<div class="form">
|
||||
<${form.component} ref="mainForm"
|
||||
% if master.has_perm('confirm_price'):
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
|
||||
<%def name="render_form_buttons()"></%def>
|
||||
|
||||
<%def name="render_form()">
|
||||
<%def name="render_form_template()">
|
||||
${form.render_deform(buttons=capture(self.render_form_buttons))|n}
|
||||
</%def>
|
||||
|
||||
<%def name="render_buefy_form()">
|
||||
<%def name="render_form()">
|
||||
<div class="form">
|
||||
${form.render_vuejs_component()}
|
||||
</div>
|
||||
|
@ -18,7 +18,7 @@
|
|||
<%def name="page_content()">
|
||||
<div class="form-wrapper">
|
||||
<br />
|
||||
${self.render_buefy_form()}
|
||||
${self.render_form()}
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
|
@ -49,7 +49,7 @@
|
|||
|
||||
<%def name="render_this_page_template()">
|
||||
% if form is not Undefined:
|
||||
${self.render_form()}
|
||||
${self.render_form_template()}
|
||||
% endif
|
||||
${parent.render_this_page_template()}
|
||||
</%def>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<div class="panel-block">
|
||||
<div>
|
||||
% for field in form.grouping[group]:
|
||||
${form.render_buefy_field(field)}
|
||||
${form.render_field_complete(field)}
|
||||
% endfor
|
||||
</div>
|
||||
</div>
|
||||
|
@ -26,7 +26,7 @@
|
|||
% endfor
|
||||
% else:
|
||||
% for field in form.fields:
|
||||
${form.render_buefy_field(field)}
|
||||
${form.render_field_complete(field)}
|
||||
% endfor
|
||||
% endif
|
||||
</section>
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
## -*- coding: utf-8; -*-
|
||||
|
||||
## TODO: deprecate / remove this
|
||||
## (tried to add deprecation warning here but it didn't seem to work)
|
||||
<%def name="render_buefy_field(field, bfield_kwargs={})">
|
||||
${form.render_buefy_field(field.name, bfield_attrs=bfield_kwargs)}
|
||||
</%def>
|
|
@ -3,12 +3,12 @@
|
|||
|
||||
<%def name="title()">Clone ${model_title}: ${instance_title}</%def>
|
||||
|
||||
<%def name="render_buefy_form()">
|
||||
<%def name="render_form()">
|
||||
<br />
|
||||
<b-notification :closable="false">
|
||||
You are about to clone the following ${model_title} as a new record:
|
||||
</b-notification>
|
||||
${parent.render_buefy_form()}
|
||||
${parent.render_form()}
|
||||
</%def>
|
||||
|
||||
<%def name="render_form_buttons()">
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
|
||||
<%def name="title()">Delete ${model_title}: ${instance_title}</%def>
|
||||
|
||||
<%def name="render_buefy_form()">
|
||||
<%def name="render_form()">
|
||||
<br />
|
||||
<b-notification type="is-danger" :closable="false">
|
||||
You are about to delete the following ${model_title} and all associated data:
|
||||
</b-notification>
|
||||
${parent.render_buefy_form()}
|
||||
${parent.render_form()}
|
||||
</%def>
|
||||
|
||||
<%def name="render_form_buttons()">
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
${view_profiles_helper([instance])}
|
||||
</%def>
|
||||
|
||||
<%def name="render_buefy_form()">
|
||||
<%def name="render_form()">
|
||||
<div class="form">
|
||||
<tailbone-form v-on:make-user="makeUser"></tailbone-form>
|
||||
</div>
|
||||
|
|
|
@ -1403,10 +1403,10 @@
|
|||
|
||||
% if request.has_perm('people_profile.view_versions'):
|
||||
|
||||
${revisions_grid.render_buefy_table_element(data_prop='revisions',
|
||||
show_footer=True,
|
||||
vshow='viewingHistory',
|
||||
loading='gettingRevisions')|n}
|
||||
${revisions_grid.render_table_element(data_prop='revisions',
|
||||
show_footer=True,
|
||||
vshow='viewingHistory',
|
||||
loading='gettingRevisions')|n}
|
||||
|
||||
<b-modal :active.sync="showingRevisionDialog">
|
||||
|
||||
|
|
|
@ -95,8 +95,8 @@
|
|||
${parent.modify_this_page_vars()}
|
||||
<script type="text/javascript">
|
||||
|
||||
ThisPageData.permissionGroups = ${json.dumps(buefy_perms)|n}
|
||||
ThisPageData.sortedGroups = ${json.dumps(buefy_sorted_groups)|n}
|
||||
ThisPageData.permissionGroups = ${json.dumps(perms_data)|n}
|
||||
ThisPageData.sortedGroups = ${json.dumps(sorted_groups_data)|n}
|
||||
|
||||
</script>
|
||||
</%def>
|
||||
|
@ -113,7 +113,7 @@
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
groupPermissions: ${json.dumps(buefy_perms.get(selected_group, {}).get('permissions', []))|n},
|
||||
groupPermissions: ${json.dumps(perms_data.get(selected_group, {}).get('permissions', []))|n},
|
||||
permissionGroupTerm: '',
|
||||
permissionTerm: '',
|
||||
selectedGroup: ${json.dumps(selected_group)|n},
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
${h.end_form()}
|
||||
</%def>
|
||||
|
||||
<%def name="render_form()">
|
||||
<%def name="render_form_template()">
|
||||
<script type="text/x-template" id="${form.component}-template">
|
||||
${self.render_form_innards()}
|
||||
</script>
|
||||
|
|
|
@ -108,7 +108,7 @@
|
|||
</%def>
|
||||
|
||||
<%def name="lookup_codes_grid()">
|
||||
${lookup_codes['grid'].render_buefy_table_element(data_prop='lookupCodesData')|n}
|
||||
${lookup_codes['grid'].render_table_element(data_prop='lookupCodesData')|n}
|
||||
</%def>
|
||||
|
||||
<%def name="lookup_codes_panel()">
|
||||
|
@ -121,7 +121,7 @@
|
|||
</%def>
|
||||
|
||||
<%def name="sources_grid()">
|
||||
${vendor_sources['grid'].render_buefy_table_element(data_prop='vendorSourcesData')|n}
|
||||
${vendor_sources['grid'].render_table_element(data_prop='vendorSourcesData')|n}
|
||||
</%def>
|
||||
|
||||
<%def name="sources_panel()">
|
||||
|
@ -175,7 +175,7 @@
|
|||
</p>
|
||||
</header>
|
||||
<section class="modal-card-body">
|
||||
${regular_price_history_grid.render_buefy_table_element(data_prop='regularPriceHistoryData', loading='regularPriceHistoryLoading', paginated=True, per_page=10)|n}
|
||||
${regular_price_history_grid.render_table_element(data_prop='regularPriceHistoryData', loading='regularPriceHistoryLoading', paginated=True, per_page=10)|n}
|
||||
</section>
|
||||
<footer class="modal-card-foot">
|
||||
<b-button @click="showingPriceHistory_regular = false">
|
||||
|
@ -194,7 +194,7 @@
|
|||
</p>
|
||||
</header>
|
||||
<section class="modal-card-body">
|
||||
${current_price_history_grid.render_buefy_table_element(data_prop='currentPriceHistoryData', loading='currentPriceHistoryLoading', paginated=True, per_page=10)|n}
|
||||
${current_price_history_grid.render_table_element(data_prop='currentPriceHistoryData', loading='currentPriceHistoryLoading', paginated=True, per_page=10)|n}
|
||||
</section>
|
||||
<footer class="modal-card-foot">
|
||||
<b-button @click="showingPriceHistory_current = false">
|
||||
|
@ -213,7 +213,7 @@
|
|||
</p>
|
||||
</header>
|
||||
<section class="modal-card-body">
|
||||
${suggested_price_history_grid.render_buefy_table_element(data_prop='suggestedPriceHistoryData', loading='suggestedPriceHistoryLoading', paginated=True, per_page=10)|n}
|
||||
${suggested_price_history_grid.render_table_element(data_prop='suggestedPriceHistoryData', loading='suggestedPriceHistoryLoading', paginated=True, per_page=10)|n}
|
||||
</section>
|
||||
<footer class="modal-card-foot">
|
||||
<b-button @click="showingPriceHistory_suggested = false">
|
||||
|
@ -232,7 +232,7 @@
|
|||
</p>
|
||||
</header>
|
||||
<section class="modal-card-body">
|
||||
${cost_history_grid.render_buefy_table_element(data_prop='costHistoryData', loading='costHistoryLoading', paginated=True, per_page=10)|n}
|
||||
${cost_history_grid.render_table_element(data_prop='costHistoryData', loading='costHistoryLoading', paginated=True, per_page=10)|n}
|
||||
</section>
|
||||
<footer class="modal-card-foot">
|
||||
<b-button @click="showingCostHistory = false">
|
||||
|
@ -289,7 +289,7 @@
|
|||
% if request.rattail_config.versioning_enabled() and master.has_perm('versions'):
|
||||
|
||||
ThisPageData.showingPriceHistory_regular = false
|
||||
ThisPageData.regularPriceHistoryDataRaw = ${json.dumps(regular_price_history_grid.get_buefy_data()['data'])|n}
|
||||
ThisPageData.regularPriceHistoryDataRaw = ${json.dumps(regular_price_history_grid.get_table_data()['data'])|n}
|
||||
ThisPageData.regularPriceHistoryLoading = false
|
||||
|
||||
ThisPage.computed.regularPriceHistoryData = function() {
|
||||
|
@ -318,7 +318,7 @@
|
|||
}
|
||||
|
||||
ThisPageData.showingPriceHistory_current = false
|
||||
ThisPageData.currentPriceHistoryDataRaw = ${json.dumps(current_price_history_grid.get_buefy_data()['data'])|n}
|
||||
ThisPageData.currentPriceHistoryDataRaw = ${json.dumps(current_price_history_grid.get_table_data()['data'])|n}
|
||||
ThisPageData.currentPriceHistoryLoading = false
|
||||
|
||||
ThisPage.computed.currentPriceHistoryData = function() {
|
||||
|
@ -348,7 +348,7 @@
|
|||
}
|
||||
|
||||
ThisPageData.showingPriceHistory_suggested = false
|
||||
ThisPageData.suggestedPriceHistoryDataRaw = ${json.dumps(suggested_price_history_grid.get_buefy_data()['data'])|n}
|
||||
ThisPageData.suggestedPriceHistoryDataRaw = ${json.dumps(suggested_price_history_grid.get_table_data()['data'])|n}
|
||||
ThisPageData.suggestedPriceHistoryLoading = false
|
||||
|
||||
ThisPage.computed.suggestedPriceHistoryData = function() {
|
||||
|
@ -377,7 +377,7 @@
|
|||
}
|
||||
|
||||
ThisPageData.showingCostHistory = false
|
||||
ThisPageData.costHistoryDataRaw = ${json.dumps(cost_history_grid.get_buefy_data()['data'])|n}
|
||||
ThisPageData.costHistoryDataRaw = ${json.dumps(cost_history_grid.get_table_data()['data'])|n}
|
||||
ThisPageData.costHistoryLoading = false
|
||||
|
||||
ThisPage.computed.costHistoryData = function() {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
## -*- coding: utf-8; -*-
|
||||
<%inherit file="/form.mako" />
|
||||
<%namespace file="/forms/util.mako" import="render_buefy_field" />
|
||||
|
||||
<%def name="title()">Declare Credit for Row #${row.sequence}</%def>
|
||||
|
||||
|
@ -11,7 +10,7 @@
|
|||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="render_buefy_form()">
|
||||
<%def name="render_form()">
|
||||
|
||||
<p class="block">
|
||||
Please select the "state" of the product, and enter the
|
||||
|
@ -31,22 +30,22 @@
|
|||
if you need to "receive" instead of "convert" the product.
|
||||
</p>
|
||||
|
||||
${parent.render_buefy_form()}
|
||||
${parent.render_form()}
|
||||
|
||||
</%def>
|
||||
|
||||
<%def name="buefy_form_body()">
|
||||
<%def name="form_body()">
|
||||
|
||||
${render_buefy_field(dform['credit_type'])}
|
||||
${form.render_field_complete('credit_type')}
|
||||
|
||||
${render_buefy_field(dform['quantity'])}
|
||||
${form.render_field_complete('quantity')}
|
||||
|
||||
${render_buefy_field(dform['expiration_date'], bfield_kwargs={'v-show': "field_model_credit_type == 'expired'"})}
|
||||
${form.render_field_complete('expiration_date', bfield_attrs={'v-show': "field_model_credit_type == 'expired'"})}
|
||||
|
||||
</%def>
|
||||
|
||||
<%def name="render_form()">
|
||||
${form.render_deform(buttons=capture(self.render_form_buttons), form_body=capture(self.buefy_form_body))|n}
|
||||
<%def name="render_form_template()">
|
||||
${form.render_deform(buttons=capture(self.render_form_buttons), form_body=capture(self.form_body))|n}
|
||||
</%def>
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
## -*- coding: utf-8; -*-
|
||||
<%inherit file="/form.mako" />
|
||||
<%namespace file="/forms/util.mako" import="render_buefy_field" />
|
||||
|
||||
<%def name="title()">Receive for Row #${row.sequence}</%def>
|
||||
|
||||
|
@ -11,7 +10,7 @@
|
|||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="render_buefy_form()">
|
||||
<%def name="render_form()">
|
||||
|
||||
<p class="block">
|
||||
Please select the "state" of the product, and enter the appropriate
|
||||
|
@ -28,22 +27,22 @@
|
|||
if you need to "convert" some already-received amount, into a credit.
|
||||
</p>
|
||||
|
||||
${parent.render_buefy_form()}
|
||||
${parent.render_form()}
|
||||
|
||||
</%def>
|
||||
|
||||
<%def name="buefy_form_body()">
|
||||
<%def name="form_body()">
|
||||
|
||||
${render_buefy_field(dform['mode'])}
|
||||
${form.render_field_complete('mode')}
|
||||
|
||||
${render_buefy_field(dform['quantity'])}
|
||||
${form.render_field_complete('quantity')}
|
||||
|
||||
${render_buefy_field(dform['expiration_date'], bfield_kwargs={'v-show': "field_model_mode == 'expired'"})}
|
||||
${form.render_field_complete('expiration_date', bfield_attrs={'v-show': "field_model_mode == 'expired'"})}
|
||||
|
||||
</%def>
|
||||
|
||||
<%def name="render_form()">
|
||||
${form.render_deform(buttons=capture(self.render_form_buttons), form_body=capture(self.buefy_form_body))|n}
|
||||
<%def name="render_form_template()">
|
||||
${form.render_deform(buttons=capture(self.render_form_buttons), form_body=capture(self.form_body))|n}
|
||||
</%def>
|
||||
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
</style>
|
||||
</%def>
|
||||
|
||||
<%def name="render_buefy_form()">
|
||||
<%def name="render_form()">
|
||||
<div class="form">
|
||||
<p>Please select the type of report you wish to generate.</p>
|
||||
<br />
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
<%def name="content_title()">New Report: ${report.name}</%def>
|
||||
|
||||
<%def name="render_buefy_form()">
|
||||
<%def name="render_form()">
|
||||
<div class="form">
|
||||
<p class="block">
|
||||
${report.__doc__}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
## -*- coding: utf-8; -*-
|
||||
<%inherit file="/master/view.mako" />
|
||||
|
||||
<%def name="render_buefy_form()">
|
||||
${parent.render_buefy_form()}
|
||||
<%def name="render_form()">
|
||||
${parent.render_form()}
|
||||
<email-preview-tools></email-preview-tools>
|
||||
</%def>
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="render_buefy_form()">
|
||||
<%def name="render_form()">
|
||||
<div class="form">
|
||||
<${form.component}
|
||||
% if master.has_perm('execute'):
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<b-select name="tailbone.${user.uuid}.buefy_css"
|
||||
v-model="simpleSettings['tailbone.${user.uuid}.buefy_css']"
|
||||
@input="settingsNeedSaved = true">
|
||||
<option v-for="option in buefyCSSOptions"
|
||||
<option v-for="option in themeStyleOptions"
|
||||
:key="option.value"
|
||||
:value="option.value">
|
||||
{{ option.label }}
|
||||
|
@ -46,7 +46,7 @@
|
|||
${parent.modify_this_page_vars()}
|
||||
<script type="text/javascript">
|
||||
|
||||
ThisPageData.buefyCSSOptions = ${json.dumps(buefy_css_options)|n}
|
||||
ThisPageData.themeStyleOptions = ${json.dumps(theme_style_options)|n}
|
||||
|
||||
</script>
|
||||
</%def>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -32,23 +32,18 @@ import logging
|
|||
import socket
|
||||
import subprocess
|
||||
import tempfile
|
||||
import warnings
|
||||
|
||||
import json
|
||||
import markdown
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import orm
|
||||
|
||||
from rattail.db import model, Session as RattailSession
|
||||
from rattail.db.util import short_session
|
||||
from rattail.threads import Thread
|
||||
from rattail.util import prettify, simple_error
|
||||
from rattail.progress import SocketProgress
|
||||
from rattail.util import simple_error
|
||||
|
||||
import colander
|
||||
import deform
|
||||
from deform import widget as dfwidget
|
||||
from pyramid.renderers import render_to_response
|
||||
from pyramid.response import FileResponse
|
||||
from webhelpers2.html import HTML, tags
|
||||
|
||||
from tailbone import forms, grids
|
||||
|
@ -115,7 +110,7 @@ class BatchMasterView(MasterView):
|
|||
}
|
||||
|
||||
def __init__(self, request):
|
||||
super(BatchMasterView, self).__init__(request)
|
||||
super().__init__(request)
|
||||
self.batch_handler = self.get_handler()
|
||||
# TODO: deprecate / remove this (?)
|
||||
self.handler = self.batch_handler
|
||||
|
@ -167,7 +162,7 @@ class BatchMasterView(MasterView):
|
|||
return self.rattail_config.batch_filepath(batch.batch_key, batch.uuid, filename)
|
||||
|
||||
def template_kwargs_view(self, **kwargs):
|
||||
kwargs = super(BatchMasterView, self).template_kwargs_view(**kwargs)
|
||||
kwargs = super().template_kwargs_view(**kwargs)
|
||||
batch = kwargs['instance']
|
||||
kwargs['batch'] = batch
|
||||
kwargs['handler'] = self.handler
|
||||
|
@ -195,8 +190,8 @@ class BatchMasterView(MasterView):
|
|||
g.set_click_handler('title', "autoFilterStatus(props.row)")
|
||||
kwargs['status_breakdown_data'] = breakdown
|
||||
kwargs['status_breakdown_grid'] = HTML.literal(
|
||||
g.render_buefy_table_element(data_prop='statusBreakdownData',
|
||||
empty_labels=True))
|
||||
g.render_table_element(data_prop='statusBreakdownData',
|
||||
empty_labels=True))
|
||||
|
||||
return kwargs
|
||||
|
||||
|
@ -288,7 +283,8 @@ class BatchMasterView(MasterView):
|
|||
return not batch.executed and not batch.complete
|
||||
|
||||
def configure_grid(self, g):
|
||||
super(BatchMasterView, self).configure_grid(g)
|
||||
super().configure_grid(g)
|
||||
model = self.model
|
||||
|
||||
# created_by
|
||||
CreatedBy = orm.aliased(model.User)
|
||||
|
@ -337,7 +333,7 @@ class BatchMasterView(MasterView):
|
|||
return batch.id_str
|
||||
|
||||
def configure_form(self, f):
|
||||
super(BatchMasterView, self).configure_form(f)
|
||||
super().configure_form(f)
|
||||
|
||||
# id
|
||||
f.set_readonly('id')
|
||||
|
@ -436,9 +432,9 @@ class BatchMasterView(MasterView):
|
|||
|
||||
label = HTML.literal(
|
||||
'{{{{ togglingBatchComplete ? "Working, please wait..." : "{}" }}}}'.format(label))
|
||||
submit = self.make_buefy_button(label, is_primary=True,
|
||||
native_type='submit',
|
||||
**{':disabled': 'togglingBatchComplete'})
|
||||
submit = self.make_button(label, is_primary=True,
|
||||
native_type='submit',
|
||||
**{':disabled': 'togglingBatchComplete'})
|
||||
|
||||
form = [
|
||||
begin_form,
|
||||
|
@ -603,7 +599,7 @@ class BatchMasterView(MasterView):
|
|||
return True
|
||||
|
||||
def configure_row_grid(self, g):
|
||||
super(BatchMasterView, self).configure_row_grid(g)
|
||||
super().configure_row_grid(g)
|
||||
|
||||
g.set_sort_defaults('sequence')
|
||||
g.set_link('sequence')
|
||||
|
@ -644,7 +640,7 @@ class BatchMasterView(MasterView):
|
|||
if batch.executed:
|
||||
self.request.session.flash("You cannot add new rows to a batch which has been executed")
|
||||
return self.redirect(self.get_action_url('view', batch))
|
||||
return super(BatchMasterView, self).create_row()
|
||||
return super().create_row()
|
||||
|
||||
def save_create_row_form(self, form):
|
||||
batch = self.get_instance()
|
||||
|
@ -657,7 +653,7 @@ class BatchMasterView(MasterView):
|
|||
self.handler.refresh_row(row)
|
||||
|
||||
def configure_row_form(self, f):
|
||||
super(BatchMasterView, self).configure_row_form(f)
|
||||
super().configure_row_form(f)
|
||||
|
||||
# sequence
|
||||
f.set_readonly('sequence')
|
||||
|
@ -681,9 +677,9 @@ class BatchMasterView(MasterView):
|
|||
permission_prefix = self.get_permission_prefix()
|
||||
if self.request.has_perm('{}.create_row'.format(permission_prefix)):
|
||||
url = self.get_action_url('create_row', batch)
|
||||
return self.make_buefy_button("New Row", url=url,
|
||||
is_primary=True,
|
||||
icon_left='plus')
|
||||
return self.make_button("New Row", url=url,
|
||||
is_primary=True,
|
||||
icon_left='plus')
|
||||
|
||||
def make_batch_row_grid_tools(self, batch):
|
||||
pass
|
||||
|
@ -719,7 +715,7 @@ class BatchMasterView(MasterView):
|
|||
|
||||
kwargs['main_actions'] = actions
|
||||
|
||||
return super(BatchMasterView, self).make_row_grid_kwargs(**kwargs)
|
||||
return super().make_row_grid_kwargs(**kwargs)
|
||||
|
||||
def make_row_grid_tools(self, batch):
|
||||
return (self.make_default_row_grid_tools(batch) or '') + (self.make_batch_row_grid_tools(batch) or '')
|
||||
|
@ -852,8 +848,11 @@ class BatchMasterView(MasterView):
|
|||
labels = kwargs.setdefault('labels', {})
|
||||
labels[field.name] = field.title
|
||||
|
||||
# auto-convert select widgets for buefy theme
|
||||
# auto-convert select widgets for theme
|
||||
if isinstance(field.widget, forms.widgets.PlainSelectWidget):
|
||||
warnings.warn("PlainSelectWidget is deprecated; "
|
||||
"please use deform.widget.SelectWidget instead",
|
||||
DeprecationWarning)
|
||||
field.widget = dfwidget.SelectWidget(values=field.widget.values)
|
||||
|
||||
if not schema:
|
||||
|
@ -1022,7 +1021,8 @@ class BatchMasterView(MasterView):
|
|||
cxn.close()
|
||||
|
||||
def catchup_versions(self, port, batch_uuid, username, *models):
|
||||
with short_session() as s:
|
||||
app = self.get_rattail_app()
|
||||
with app.short_session() as s:
|
||||
batch = s.get(self.model_class, batch_uuid)
|
||||
batch_id = batch.id_str
|
||||
description = str(batch)
|
||||
|
@ -1048,8 +1048,10 @@ class BatchMasterView(MasterView):
|
|||
"""
|
||||
Thread target for populating batch data with progress indicator.
|
||||
"""
|
||||
app = self.get_rattail_app()
|
||||
model = self.model
|
||||
# mustn't use tailbone web session here
|
||||
session = RattailSession()
|
||||
session = app.make_session()
|
||||
batch = session.get(self.model_class, batch_uuid)
|
||||
user = session.get(model.User, user_uuid)
|
||||
try:
|
||||
|
@ -1107,7 +1109,9 @@ class BatchMasterView(MasterView):
|
|||
# Refresh data for the batch, with progress. Note that we must use the
|
||||
# rattail session here; can't use tailbone because it has web request
|
||||
# transaction binding etc.
|
||||
session = RattailSession()
|
||||
app = self.get_rattail_app()
|
||||
model = self.model
|
||||
session = app.make_session()
|
||||
batch = session.get(self.model_class, batch_uuid)
|
||||
cognizer = session.get(model.User, user_uuid) if user_uuid else None
|
||||
try:
|
||||
|
@ -1160,7 +1164,9 @@ class BatchMasterView(MasterView):
|
|||
"""
|
||||
Thread target for refreshing multiple batches with progress indicator.
|
||||
"""
|
||||
session = RattailSession()
|
||||
app = self.get_rattail_app()
|
||||
model = self.model
|
||||
session = app.make_session()
|
||||
batches = batches.with_session(session).all()
|
||||
user = session.get(model.User, user_uuid)
|
||||
try:
|
||||
|
@ -1257,7 +1263,7 @@ class BatchMasterView(MasterView):
|
|||
self.handler.do_remove_row(row)
|
||||
|
||||
def delete_row_objects(self, rows):
|
||||
deleted = super(BatchMasterView, self).delete_row_objects(rows)
|
||||
deleted = super().delete_row_objects(rows)
|
||||
batch = self.get_instance()
|
||||
|
||||
# decrement rowcount for batch
|
||||
|
@ -1300,7 +1306,9 @@ class BatchMasterView(MasterView):
|
|||
# Execute the batch, with progress. Note that we must use the rattail
|
||||
# session here; can't use tailbone because it has web request
|
||||
# transaction binding etc.
|
||||
session = RattailSession()
|
||||
app = self.get_rattail_app()
|
||||
model = self.model
|
||||
session = app.make_session()
|
||||
batch = self.get_instance_for_key(key, session)
|
||||
user = session.get(model.User, user_uuid)
|
||||
try:
|
||||
|
@ -1375,7 +1383,9 @@ class BatchMasterView(MasterView):
|
|||
"""
|
||||
Thread target for executing multiple batches with progress indicator.
|
||||
"""
|
||||
session = RattailSession()
|
||||
app = self.get_rattail_app()
|
||||
model = self.model
|
||||
session = app.make_session()
|
||||
batches = batches.with_session(session).all()
|
||||
user = session.get(model.User, user_uuid)
|
||||
try:
|
||||
|
@ -1415,7 +1425,7 @@ class BatchMasterView(MasterView):
|
|||
return self.get_index_url()
|
||||
|
||||
def get_row_csv_fields(self):
|
||||
fields = super(BatchMasterView, self).get_row_csv_fields()
|
||||
fields = super().get_row_csv_fields()
|
||||
fields = [field for field in fields
|
||||
if field not in ('uuid', 'batch_uuid', 'removed')]
|
||||
return fields
|
||||
|
@ -1538,7 +1548,7 @@ class FileBatchMasterView(BatchMasterView):
|
|||
return uploads
|
||||
|
||||
def configure_form(self, f):
|
||||
super(FileBatchMasterView, self).configure_form(f)
|
||||
super().configure_form(f)
|
||||
batch = f.model_instance
|
||||
|
||||
# filename
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -26,12 +26,12 @@ Views for handheld batches
|
|||
|
||||
from collections import OrderedDict
|
||||
|
||||
from rattail.db import model
|
||||
from rattail.db.model import HandheldBatch, HandheldBatchRow
|
||||
|
||||
import colander
|
||||
from deform import widget as dfwidget
|
||||
from webhelpers2.html import tags
|
||||
|
||||
from tailbone import forms
|
||||
from tailbone.views.batch import FileBatchMasterView
|
||||
|
||||
|
||||
|
@ -46,14 +46,14 @@ class ExecutionOptions(colander.Schema):
|
|||
action = colander.SchemaNode(
|
||||
colander.String(),
|
||||
validator=colander.OneOf(ACTION_OPTIONS),
|
||||
widget=forms.widgets.PlainSelectWidget(values=ACTION_OPTIONS.items()))
|
||||
widget=dfwidget.SelectWidget(values=ACTION_OPTIONS.items()))
|
||||
|
||||
|
||||
class HandheldBatchView(FileBatchMasterView):
|
||||
"""
|
||||
Master view for handheld batches.
|
||||
"""
|
||||
model_class = model.HandheldBatch
|
||||
model_class = HandheldBatch
|
||||
default_handler_spec = 'rattail.batch.handheld:HandheldBatchHandler'
|
||||
model_title_plural = "Handheld Batches"
|
||||
route_prefix = 'batch.handheld'
|
||||
|
@ -61,7 +61,7 @@ class HandheldBatchView(FileBatchMasterView):
|
|||
execution_options_schema = ExecutionOptions
|
||||
editable = False
|
||||
|
||||
model_row_class = model.HandheldBatchRow
|
||||
model_row_class = HandheldBatchRow
|
||||
rows_creatable = False
|
||||
rows_editable = True
|
||||
|
||||
|
@ -116,7 +116,7 @@ class HandheldBatchView(FileBatchMasterView):
|
|||
]
|
||||
|
||||
def configure_grid(self, g):
|
||||
super(HandheldBatchView, self).configure_grid(g)
|
||||
super().configure_grid(g)
|
||||
device_types = OrderedDict(sorted(self.enum.HANDHELD_DEVICE_TYPE.items(),
|
||||
key=lambda item: item[1]))
|
||||
g.set_enum('device_type', device_types)
|
||||
|
@ -126,7 +126,7 @@ class HandheldBatchView(FileBatchMasterView):
|
|||
return 'notice'
|
||||
|
||||
def configure_form(self, f):
|
||||
super(HandheldBatchView, self).configure_form(f)
|
||||
super().configure_form(f)
|
||||
batch = f.model_instance
|
||||
|
||||
# device_type
|
||||
|
@ -156,13 +156,13 @@ class HandheldBatchView(FileBatchMasterView):
|
|||
return tags.link_to(text, url)
|
||||
|
||||
def get_batch_kwargs(self, batch):
|
||||
kwargs = super(HandheldBatchView, self).get_batch_kwargs(batch)
|
||||
kwargs = super().get_batch_kwargs(batch)
|
||||
kwargs['device_type'] = batch.device_type
|
||||
kwargs['device_name'] = batch.device_name
|
||||
return kwargs
|
||||
|
||||
def configure_row_grid(self, g):
|
||||
super(HandheldBatchView, self).configure_row_grid(g)
|
||||
super().configure_row_grid(g)
|
||||
g.set_type('cases', 'quantity')
|
||||
g.set_type('units', 'quantity')
|
||||
g.set_label('brand_name', "Brand")
|
||||
|
@ -172,7 +172,7 @@ class HandheldBatchView(FileBatchMasterView):
|
|||
return 'warning'
|
||||
|
||||
def configure_row_form(self, f):
|
||||
super(HandheldBatchView, self).configure_row_form(f)
|
||||
super().configure_row_form(f)
|
||||
|
||||
# readonly fields
|
||||
f.set_readonly('upc')
|
||||
|
@ -188,7 +188,7 @@ class HandheldBatchView(FileBatchMasterView):
|
|||
return self.request.route_url('batch.inventory.view', uuid=result.uuid)
|
||||
elif kwargs['action'] == 'make_label_batch':
|
||||
return self.request.route_url('labels.batch.view', uuid=result.uuid)
|
||||
return super(HandheldBatchView, self).get_execute_success_url(batch)
|
||||
return super().get_execute_success_url(batch)
|
||||
|
||||
def get_execute_results_success_url(self, result, **kwargs):
|
||||
if result is True:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -206,7 +206,7 @@ class POSBatchView(BatchMasterView):
|
|||
)
|
||||
|
||||
return HTML.literal(
|
||||
g.render_buefy_table_element(data_prop='taxesData'))
|
||||
g.render_table_element(data_prop='taxesData'))
|
||||
|
||||
def template_kwargs_view(self, **kwargs):
|
||||
kwargs = super().template_kwargs_view(**kwargs)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -26,12 +26,12 @@ Views for generic product batches
|
|||
|
||||
from collections import OrderedDict
|
||||
|
||||
from rattail.db import model
|
||||
from rattail.db.model import ProductBatch, ProductBatchRow
|
||||
|
||||
import colander
|
||||
from deform import widget as dfwidget
|
||||
from webhelpers2.html import HTML
|
||||
|
||||
from tailbone import forms
|
||||
from tailbone.views.batch import BatchMasterView
|
||||
|
||||
|
||||
|
@ -46,15 +46,15 @@ class ExecutionOptions(colander.Schema):
|
|||
action = colander.SchemaNode(
|
||||
colander.String(),
|
||||
validator=colander.OneOf(ACTION_OPTIONS),
|
||||
widget=forms.widgets.PlainSelectWidget(values=ACTION_OPTIONS.items()))
|
||||
widget=dfwidget.SelectWidget(values=ACTION_OPTIONS.items()))
|
||||
|
||||
|
||||
class ProductBatchView(BatchMasterView):
|
||||
"""
|
||||
Master view for product batches.
|
||||
"""
|
||||
model_class = model.ProductBatch
|
||||
model_row_class = model.ProductBatchRow
|
||||
model_class = ProductBatch
|
||||
model_row_class = ProductBatchRow
|
||||
default_handler_spec = 'rattail.batch.product:ProductBatchHandler'
|
||||
route_prefix = 'batch.product'
|
||||
url_prefix = '/batches/product'
|
||||
|
@ -129,7 +129,7 @@ class ProductBatchView(BatchMasterView):
|
|||
]
|
||||
|
||||
def configure_form(self, f):
|
||||
super(ProductBatchView, self).configure_form(f)
|
||||
super().configure_form(f)
|
||||
|
||||
# input_filename
|
||||
if self.creating:
|
||||
|
@ -139,7 +139,8 @@ class ProductBatchView(BatchMasterView):
|
|||
f.set_renderer('input_filename', self.render_downloadable_file)
|
||||
|
||||
def configure_row_grid(self, g):
|
||||
super(ProductBatchView, self).configure_row_grid(g)
|
||||
super().configure_row_grid(g)
|
||||
model = self.model
|
||||
|
||||
g.set_joiner('vendor', lambda q: q.outerjoin(model.Vendor))
|
||||
g.set_sorter('vendor', model.Vendor.name)
|
||||
|
@ -165,7 +166,7 @@ class ProductBatchView(BatchMasterView):
|
|||
return 'warning'
|
||||
|
||||
def configure_row_form(self, f):
|
||||
super(ProductBatchView, self).configure_row_form(f)
|
||||
super().configure_row_form(f)
|
||||
|
||||
f.set_type('upc', 'gpc')
|
||||
|
||||
|
@ -204,10 +205,10 @@ class ProductBatchView(BatchMasterView):
|
|||
return self.request.route_url('labels.batch.view', uuid=result.uuid)
|
||||
elif kwargs['action'] == 'make_pricing_batch':
|
||||
return self.request.route_url('batch.pricing.view', uuid=result.uuid)
|
||||
return super(ProductBatchView, self).get_execute_success_url(batch)
|
||||
return super().get_execute_success_url(batch)
|
||||
|
||||
def get_row_csv_fields(self):
|
||||
fields = super(ProductBatchView, self).get_row_csv_fields()
|
||||
fields = super().get_row_csv_fields()
|
||||
|
||||
if 'vendor_uuid' in fields:
|
||||
i = fields.index('vendor_uuid')
|
||||
|
@ -273,12 +274,12 @@ class ProductBatchView(BatchMasterView):
|
|||
data['report_name'] = (report.name or '') if report else ''
|
||||
|
||||
def get_row_csv_row(self, row, fields):
|
||||
csvrow = super(ProductBatchView, self).get_row_csv_row(row, fields)
|
||||
csvrow = super().get_row_csv_row(row, fields)
|
||||
self.supplement_row_data(row, fields, csvrow)
|
||||
return csvrow
|
||||
|
||||
def get_row_xlsx_row(self, row, fields):
|
||||
xlrow = super(ProductBatchView, self).get_row_xlsx_row(row, fields)
|
||||
xlrow = super().get_row_xlsx_row(row, fields)
|
||||
self.supplement_row_data(row, fields, xlrow)
|
||||
return xlrow
|
||||
|
||||
|
|
|
@ -341,7 +341,7 @@ class CustomerView(MasterView):
|
|||
# people
|
||||
if self.should_expose_people():
|
||||
if self.viewing:
|
||||
f.set_renderer('people', self.render_people_buefy)
|
||||
f.set_renderer('people', self.render_people)
|
||||
else:
|
||||
f.remove('people')
|
||||
else:
|
||||
|
@ -463,20 +463,6 @@ class CustomerView(MasterView):
|
|||
url = self.request.route_url('people.view', uuid=person.uuid)
|
||||
return tags.link_to(text, url)
|
||||
|
||||
# TODO: remove if no longer used
|
||||
def render_people(self, customer, field):
|
||||
people = customer.people
|
||||
if not people:
|
||||
return ""
|
||||
|
||||
items = []
|
||||
for person in people:
|
||||
text = str(person)
|
||||
url = self.request.route_url('people.view', uuid=person.uuid)
|
||||
link = tags.link_to(text, url)
|
||||
items.append(HTML.tag('li', c=[link]))
|
||||
return HTML.tag('ul', c=items)
|
||||
|
||||
def render_shoppers(self, customer, field):
|
||||
route_prefix = self.get_route_prefix()
|
||||
permission_prefix = self.get_permission_prefix()
|
||||
|
@ -504,9 +490,9 @@ class CustomerView(MasterView):
|
|||
)
|
||||
|
||||
return HTML.literal(
|
||||
g.render_buefy_table_element(data_prop='shoppers'))
|
||||
g.render_table_element(data_prop='shoppers'))
|
||||
|
||||
def render_people_buefy(self, customer, field):
|
||||
def render_people(self, customer, field):
|
||||
route_prefix = self.get_route_prefix()
|
||||
permission_prefix = self.get_permission_prefix()
|
||||
|
||||
|
@ -533,7 +519,7 @@ class CustomerView(MasterView):
|
|||
click_handler="$emit('detach-person', props.row._action_url_detach)"))
|
||||
|
||||
return HTML.literal(
|
||||
g.render_buefy_table_element(data_prop='peopleData'))
|
||||
g.render_table_element(data_prop='peopleData'))
|
||||
|
||||
def render_groups(self, customer, field):
|
||||
groups = customer.groups
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -401,7 +401,7 @@ class CustomerOrderItemView(MasterView):
|
|||
)
|
||||
|
||||
table = HTML.literal(
|
||||
g.render_buefy_table_element(data_prop='eventsData'))
|
||||
g.render_table_element(data_prop='eventsData'))
|
||||
elements = [table]
|
||||
|
||||
if self.has_perm('add_note'):
|
||||
|
|
|
@ -144,7 +144,7 @@ class DepartmentView(MasterView):
|
|||
g.main_actions.append(self.make_action('edit', icon='edit'))
|
||||
|
||||
return HTML.literal(
|
||||
g.render_buefy_table_element(data_prop='employeesData'))
|
||||
g.render_table_element(data_prop='employeesData'))
|
||||
|
||||
def template_kwargs_view(self, **kwargs):
|
||||
kwargs = super().template_kwargs_view(**kwargs)
|
||||
|
|
|
@ -30,7 +30,6 @@ import csv
|
|||
import datetime
|
||||
import getpass
|
||||
import shutil
|
||||
import tempfile
|
||||
import logging
|
||||
from collections import OrderedDict
|
||||
|
||||
|
@ -40,12 +39,10 @@ from sqlalchemy import orm
|
|||
import sqlalchemy_continuum as continuum
|
||||
from sqlalchemy_utils.functions import get_primary_keys, get_columns
|
||||
|
||||
from rattail.db import model, Session as RattailSession
|
||||
from rattail.db.continuum import model_transaction_query
|
||||
from rattail.util import simple_error, get_class_hierarchy
|
||||
from rattail.threads import Thread
|
||||
from rattail.csvutil import UnicodeDictWriter
|
||||
from rattail.files import temp_path
|
||||
from rattail.excel import ExcelWriter
|
||||
from rattail.gpc import GPC
|
||||
|
||||
|
@ -54,7 +51,6 @@ import deform
|
|||
from deform import widget as dfwidget
|
||||
from pyramid import httpexceptions
|
||||
from pyramid.renderers import get_renderer, render_to_response, render
|
||||
from pyramid.response import FileResponse
|
||||
from webhelpers2.html import HTML, tags
|
||||
from webob.compat import cgi_FieldStorage
|
||||
|
||||
|
@ -220,7 +216,8 @@ class MasterView(View):
|
|||
to the current thread (one per request), this method should instead
|
||||
return e.g. a new independent ``rattail.db.Session`` instance.
|
||||
"""
|
||||
return RattailSession()
|
||||
app = self.get_rattail_app()
|
||||
return app.make_session()
|
||||
|
||||
@classmethod
|
||||
def get_grid_factory(cls):
|
||||
|
@ -348,7 +345,7 @@ class MasterView(View):
|
|||
|
||||
# return grid data only, if partial page was requested
|
||||
if self.request.params.get('partial'):
|
||||
return self.json_response(grid.get_buefy_data())
|
||||
return self.json_response(grid.get_table_data())
|
||||
|
||||
context = {
|
||||
'grid': grid,
|
||||
|
@ -719,10 +716,11 @@ class MasterView(View):
|
|||
return obj
|
||||
|
||||
def normalize_uploads(self, form, skip=None):
|
||||
app = self.get_rattail_app()
|
||||
uploads = {}
|
||||
|
||||
def normalize(filedict):
|
||||
tempdir = tempfile.mkdtemp()
|
||||
tempdir = app.make_temp_dir()
|
||||
filepath = os.path.join(tempdir, filedict['filename'])
|
||||
tmpinfo = form.deform_form[node.name].widget.tmpstore.get(filedict['uid'])
|
||||
tmpdata = tmpinfo['fp'].read()
|
||||
|
@ -1114,7 +1112,8 @@ class MasterView(View):
|
|||
Thread target for populating new object with progress indicator.
|
||||
"""
|
||||
# mustn't use tailbone web session here
|
||||
session = RattailSession()
|
||||
app = self.get_rattail_app()
|
||||
session = app.make_session()
|
||||
obj = session.get(self.model_class, uuid)
|
||||
try:
|
||||
self.populate_object(session, obj, progress=progress)
|
||||
|
@ -1175,7 +1174,7 @@ class MasterView(View):
|
|||
# return grid only, if partial page was requested
|
||||
if self.request.params.get('partial'):
|
||||
# render grid data only, as JSON
|
||||
return self.json_response(grid.get_buefy_data())
|
||||
return self.json_response(grid.get_table_data())
|
||||
|
||||
context = {
|
||||
'instance': instance,
|
||||
|
@ -1308,7 +1307,7 @@ class MasterView(View):
|
|||
# return grid only, if partial page was requested
|
||||
if self.request.params.get('partial'):
|
||||
# render grid data only, as JSON
|
||||
return self.json_response(grid.get_buefy_data())
|
||||
return self.json_response(grid.get_table_data())
|
||||
|
||||
return self.render_to_response('versions', {
|
||||
'instance': instance,
|
||||
|
@ -1360,6 +1359,7 @@ class MasterView(View):
|
|||
return classes
|
||||
|
||||
def make_revisions_grid(self, obj, empty_data=False):
|
||||
model = self.model
|
||||
route_prefix = self.get_route_prefix()
|
||||
row_url = lambda txn, i: self.request.route_url(f'{route_prefix}.version',
|
||||
uuid=obj.uuid,
|
||||
|
@ -1396,8 +1396,8 @@ class MasterView(View):
|
|||
|
||||
grid = self.make_version_grid(**kwargs)
|
||||
|
||||
grid.set_joiner('user', lambda q: q.outerjoin(self.model.User))
|
||||
grid.set_sorter('user', self.model.User.username)
|
||||
grid.set_joiner('user', lambda q: q.outerjoin(model.User))
|
||||
grid.set_sorter('user', model.User.username)
|
||||
|
||||
grid.set_link('remote_addr')
|
||||
|
||||
|
@ -1465,7 +1465,7 @@ class MasterView(View):
|
|||
else: # no txnid, return grid data
|
||||
obj = self.get_instance()
|
||||
grid = self.make_revisions_grid(obj)
|
||||
return grid.get_buefy_data()
|
||||
return grid.get_table_data()
|
||||
|
||||
def view_version(self):
|
||||
"""
|
||||
|
@ -1770,16 +1770,10 @@ class MasterView(View):
|
|||
path = self.download_path(obj, filename)
|
||||
if not path or not os.path.exists(path):
|
||||
raise self.notfound()
|
||||
response = FileResponse(path, request=self.request)
|
||||
response.content_length = os.path.getsize(path)
|
||||
response = self.file_response(path)
|
||||
content_type = self.download_content_type(path, filename)
|
||||
if content_type:
|
||||
response.content_type = content_type
|
||||
|
||||
# content-disposition
|
||||
filename = os.path.basename(path)
|
||||
response.content_disposition = str('attachment; filename="{}"'.format(filename))
|
||||
|
||||
return response
|
||||
|
||||
def download_content_type(self, path, filename):
|
||||
|
@ -1856,7 +1850,7 @@ class MasterView(View):
|
|||
View for deleting an existing model record.
|
||||
"""
|
||||
if not self.deletable:
|
||||
raise httpexceptions.HTTPForbidden()
|
||||
raise self.forbidden()
|
||||
|
||||
self.deleting = True
|
||||
instance = self.get_instance()
|
||||
|
@ -2111,7 +2105,9 @@ class MasterView(View):
|
|||
"""
|
||||
Thread target for executing an object.
|
||||
"""
|
||||
session = RattailSession()
|
||||
app = self.get_rattail_app()
|
||||
model = self.model
|
||||
session = app.make_session()
|
||||
obj = self.get_instance_for_key(key, session)
|
||||
user = session.get(model.User, user_uuid)
|
||||
try:
|
||||
|
@ -2926,11 +2922,11 @@ class MasterView(View):
|
|||
normal.append(button)
|
||||
return normal
|
||||
|
||||
def make_buefy_button(self, label,
|
||||
type=None, is_primary=False,
|
||||
url=None, target=None, is_external=False,
|
||||
icon_left=None,
|
||||
**kwargs):
|
||||
def make_button(self, label,
|
||||
type=None, is_primary=False,
|
||||
url=None, target=None, is_external=False,
|
||||
icon_left=None,
|
||||
**kwargs):
|
||||
"""
|
||||
Make and return a HTML ``<b-button>`` literal.
|
||||
"""
|
||||
|
@ -2983,7 +2979,7 @@ class MasterView(View):
|
|||
assumed to be external, which affects the icon and causes
|
||||
button click to open link in a new tab.
|
||||
"""
|
||||
# TODO: this should call make_buefy_button()
|
||||
# TODO: this should call make_button()
|
||||
|
||||
# nb. unfortunately HTML.tag() calls its first arg 'tag' and
|
||||
# so we can't pass a kwarg with that name...so instead we
|
||||
|
@ -4067,10 +4063,11 @@ class MasterView(View):
|
|||
"""
|
||||
Download current *row* results as XLSX.
|
||||
"""
|
||||
app = self.get_rattail_app()
|
||||
obj = self.get_instance()
|
||||
results = self.get_effective_row_data(sort=True)
|
||||
fields = self.get_row_xlsx_fields()
|
||||
path = temp_path(suffix='.xlsx')
|
||||
path = app.make_temp_file(suffix='.xlsx')
|
||||
writer = ExcelWriter(path, fields, sheet_title=self.get_row_model_title_plural())
|
||||
writer.write_header()
|
||||
|
||||
|
@ -5039,6 +5036,7 @@ class MasterView(View):
|
|||
"""
|
||||
Generic view for configuring some aspect of the software.
|
||||
"""
|
||||
app = self.get_rattail_app()
|
||||
if self.request.method == 'POST':
|
||||
if self.request.POST.get('remove_settings'):
|
||||
self.configure_remove_settings()
|
||||
|
@ -5053,7 +5051,7 @@ class MasterView(View):
|
|||
uploads = {}
|
||||
for key, value in data.items():
|
||||
if isinstance(value, cgi_FieldStorage):
|
||||
tempdir = tempfile.mkdtemp()
|
||||
tempdir = app.make_temp_dir()
|
||||
filename = os.path.basename(value.filename)
|
||||
filepath = os.path.join(tempdir, filename)
|
||||
with open(filepath, 'wb') as f:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -29,10 +29,8 @@ from rattail.time import localtime
|
|||
|
||||
import colander
|
||||
from deform import widget as dfwidget
|
||||
from pyramid import httpexceptions
|
||||
from webhelpers2.html import tags, HTML
|
||||
|
||||
# from tailbone import forms
|
||||
from tailbone.db import Session
|
||||
from tailbone.views import MasterView
|
||||
from tailbone.util import raw_datetime
|
||||
|
@ -83,15 +81,15 @@ class MessageView(MasterView):
|
|||
|
||||
def index(self):
|
||||
if not self.request.user:
|
||||
raise httpexceptions.HTTPForbidden
|
||||
raise self.forbidden()
|
||||
return super().index()
|
||||
|
||||
def get_instance(self):
|
||||
if not self.request.user:
|
||||
raise httpexceptions.HTTPForbidden
|
||||
raise self.forbidden()
|
||||
message = super().get_instance()
|
||||
if not self.associated_with(message):
|
||||
raise httpexceptions.HTTPForbidden
|
||||
raise self.forbidden()
|
||||
return message
|
||||
|
||||
def associated_with(self, message):
|
||||
|
@ -395,7 +393,7 @@ class MessageView(MasterView):
|
|||
message = self.get_instance()
|
||||
recipient = self.get_recipient(message)
|
||||
if not recipient:
|
||||
raise httpexceptions.HTTPForbidden
|
||||
raise self.forbidden()
|
||||
|
||||
dest = self.request.GET.get('dest')
|
||||
if dest not in ('inbox', 'archive'):
|
||||
|
@ -520,7 +518,7 @@ class RecipientsWidgetBuefy(dfwidget.Widget):
|
|||
"""
|
||||
Custom "message recipients" widget, for use with Buefy / Vue.js themes.
|
||||
"""
|
||||
template = 'message_recipients_buefy'
|
||||
template = 'message_recipients'
|
||||
|
||||
def deserialize(self, field, pstruct):
|
||||
if pstruct is colander.null:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -43,7 +43,7 @@ class PrincipalMasterView(MasterView):
|
|||
def get_fallback_templates(self, template, **kwargs):
|
||||
return [
|
||||
'/principal/{}.mako'.format(template),
|
||||
] + super(PrincipalMasterView, self).get_fallback_templates(template, **kwargs)
|
||||
] + super().get_fallback_templates(template, **kwargs)
|
||||
|
||||
def perm_sortkey(self, item):
|
||||
key, value = item
|
||||
|
@ -74,9 +74,9 @@ class PrincipalMasterView(MasterView):
|
|||
|
||||
context = {'permissions': sorted_perms, 'principals': principals}
|
||||
|
||||
perms = self.get_buefy_perms_data(sorted_perms)
|
||||
context['buefy_perms'] = perms
|
||||
context['buefy_sorted_groups'] = list(perms)
|
||||
perms = self.get_perms_data(sorted_perms)
|
||||
context['perms_data'] = perms
|
||||
context['sorted_groups_data'] = list(perms)
|
||||
|
||||
if permission_group and permission_group not in perms:
|
||||
permission_group = None
|
||||
|
@ -95,7 +95,7 @@ class PrincipalMasterView(MasterView):
|
|||
|
||||
return self.render_to_response('find_by_perm', context)
|
||||
|
||||
def get_buefy_perms_data(self, sorted_perms):
|
||||
def get_perms_data(self, sorted_perms):
|
||||
data = OrderedDict()
|
||||
for gkey, group in sorted_perms:
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -37,8 +37,7 @@ from rattail.db import model, api, auth, Session as RattailSession
|
|||
from rattail.gpc import GPC
|
||||
from rattail.threads import Thread
|
||||
from rattail.exceptions import LabelPrintingError
|
||||
from rattail.util import load_object, pretty_quantity, simple_error
|
||||
from rattail.time import localtime, make_utc
|
||||
from rattail.util import simple_error
|
||||
|
||||
import colander
|
||||
from deform import widget as dfwidget
|
||||
|
@ -417,13 +416,13 @@ class ProductView(MasterView):
|
|||
app = self.get_rattail_app()
|
||||
|
||||
if price.starts:
|
||||
starts = localtime(self.rattail_config, price.starts, from_utc=True)
|
||||
starts = app.localtime(price.starts, from_utc=True)
|
||||
starts = app.render_date(starts.date())
|
||||
else:
|
||||
starts = "??"
|
||||
|
||||
if price.ends:
|
||||
ends = localtime(self.rattail_config, price.ends, from_utc=True)
|
||||
ends = app.localtime(price.ends, from_utc=True)
|
||||
ends = app.render_date(ends.date())
|
||||
else:
|
||||
ends = "??"
|
||||
|
@ -456,23 +455,25 @@ class ProductView(MasterView):
|
|||
default=True)
|
||||
|
||||
def render_regular_price(self, product, field):
|
||||
app = self.get_rattail_app()
|
||||
text = self.render_price(product, field)
|
||||
|
||||
if text and self.show_price_effective_dates():
|
||||
history = self.get_regular_price_history(product)
|
||||
if history:
|
||||
date = localtime(self.rattail_config, history[0]['changed'], from_utc=True).date()
|
||||
date = app.localtime(history[0]['changed'], from_utc=True).date()
|
||||
text = "{} (as of {})".format(text, date)
|
||||
|
||||
return self.add_price_history_link(text, 'regular')
|
||||
|
||||
def render_current_price(self, product, field):
|
||||
app = self.get_rattail_app()
|
||||
text = self.render_price(product, field)
|
||||
|
||||
if text and self.show_price_effective_dates():
|
||||
history = self.get_current_price_history(product)
|
||||
if history:
|
||||
date = localtime(self.rattail_config, history[0]['changed'], from_utc=True).date()
|
||||
date = app.localtime(history[0]['changed'], from_utc=True).date()
|
||||
text = "{} (as of {})".format(text, date)
|
||||
|
||||
return self.add_price_history_link(text, 'current')
|
||||
|
@ -489,10 +490,11 @@ class ProductView(MasterView):
|
|||
if not text:
|
||||
return
|
||||
|
||||
app = self.get_rattail_app()
|
||||
if self.show_price_effective_dates():
|
||||
history = self.get_suggested_price_history(product)
|
||||
if history:
|
||||
date = localtime(self.rattail_config, history[0]['changed'], from_utc=True).date()
|
||||
date = app.localtime(history[0]['changed'], from_utc=True).date()
|
||||
text = "{} (as of {})".format(text, date)
|
||||
|
||||
text = self.warn_if_regprice_more_than_srp(product, text)
|
||||
|
@ -526,13 +528,15 @@ class ProductView(MasterView):
|
|||
inventory = product.inventory
|
||||
if not inventory:
|
||||
return ""
|
||||
return pretty_quantity(inventory.on_hand)
|
||||
app = self.get_rattail_app()
|
||||
return app.render_quantity(inventory.on_hand)
|
||||
|
||||
def render_on_order(self, product, column):
|
||||
inventory = product.inventory
|
||||
if not inventory:
|
||||
return ""
|
||||
return pretty_quantity(inventory.on_order)
|
||||
app = self.get_rattail_app()
|
||||
return app.render_quantity(inventory.on_order)
|
||||
|
||||
def template_kwargs_index(self, **kwargs):
|
||||
kwargs = super().template_kwargs_index(**kwargs)
|
||||
|
@ -1105,7 +1109,8 @@ class ProductView(MasterView):
|
|||
value = product.inventory.on_hand
|
||||
if not value:
|
||||
return ""
|
||||
return pretty_quantity(value)
|
||||
app = self.get_rattail_app()
|
||||
return app.render_quantity(value)
|
||||
|
||||
def render_inventory_on_order(self, product, field):
|
||||
if not product.inventory:
|
||||
|
@ -1113,7 +1118,8 @@ class ProductView(MasterView):
|
|||
value = product.inventory.on_order
|
||||
if not value:
|
||||
return ""
|
||||
return pretty_quantity(value)
|
||||
app = self.get_rattail_app()
|
||||
return app.render_quantity(value)
|
||||
|
||||
def price_history(self):
|
||||
"""
|
||||
|
@ -1136,7 +1142,7 @@ class ProductView(MasterView):
|
|||
if price is not None:
|
||||
history['price'] = float(price)
|
||||
history['price_display'] = app.render_currency(price)
|
||||
changed = localtime(self.rattail_config, history['changed'], from_utc=True)
|
||||
changed = app.localtime(history['changed'], from_utc=True)
|
||||
history['changed'] = str(changed)
|
||||
history['changed_display_html'] = raw_datetime(self.rattail_config, changed)
|
||||
user = history.pop('changed_by')
|
||||
|
@ -1149,6 +1155,7 @@ class ProductView(MasterView):
|
|||
"""
|
||||
AJAX view for fetching cost history for a product.
|
||||
"""
|
||||
app = self.get_rattail_app()
|
||||
product = self.get_instance()
|
||||
data = self.get_cost_history(product)
|
||||
|
||||
|
@ -1162,7 +1169,7 @@ class ProductView(MasterView):
|
|||
history['cost_display'] = "${:0.2f}".format(cost)
|
||||
else:
|
||||
history['cost_display'] = None
|
||||
changed = localtime(self.rattail_config, history['changed'], from_utc=True)
|
||||
changed = app.localtime(history['changed'], from_utc=True)
|
||||
history['changed'] = str(changed)
|
||||
history['changed_display_html'] = raw_datetime(self.rattail_config, changed)
|
||||
user = history.pop('changed_by')
|
||||
|
@ -1388,10 +1395,11 @@ class ProductView(MasterView):
|
|||
Returns a sequence of "records" which corresponds to the given
|
||||
product's regular price history.
|
||||
"""
|
||||
app = self.get_rattail_app()
|
||||
Transaction = continuum.transaction_class(model.Product)
|
||||
ProductVersion = continuum.version_class(model.Product)
|
||||
ProductPriceVersion = continuum.version_class(model.ProductPrice)
|
||||
now = make_utc()
|
||||
now = app.make_utc()
|
||||
history = []
|
||||
|
||||
# first we find all relevant ProductVersion records
|
||||
|
@ -1457,10 +1465,11 @@ class ProductView(MasterView):
|
|||
Returns a sequence of "records" which corresponds to the given
|
||||
product's current price history.
|
||||
"""
|
||||
app = self.get_rattail_app()
|
||||
Transaction = continuum.transaction_class(model.Product)
|
||||
ProductVersion = continuum.version_class(model.Product)
|
||||
ProductPriceVersion = continuum.version_class(model.ProductPrice)
|
||||
now = make_utc()
|
||||
now = app.make_utc()
|
||||
history = []
|
||||
|
||||
# first we find all relevant ProductVersion records
|
||||
|
@ -1599,10 +1608,11 @@ class ProductView(MasterView):
|
|||
Returns a sequence of "records" which corresponds to the given
|
||||
product's SRP history.
|
||||
"""
|
||||
app = self.get_rattail_app()
|
||||
Transaction = continuum.transaction_class(model.Product)
|
||||
ProductVersion = continuum.version_class(model.Product)
|
||||
ProductPriceVersion = continuum.version_class(model.ProductPrice)
|
||||
now = make_utc()
|
||||
now = app.make_utc()
|
||||
history = []
|
||||
|
||||
# first we find all relevant ProductVersion records
|
||||
|
@ -1668,10 +1678,11 @@ class ProductView(MasterView):
|
|||
Returns a sequence of "records" which corresponds to the given
|
||||
product's cost history.
|
||||
"""
|
||||
app = self.get_rattail_app()
|
||||
Transaction = continuum.transaction_class(model.Product)
|
||||
ProductVersion = continuum.version_class(model.Product)
|
||||
ProductCostVersion = continuum.version_class(model.ProductCost)
|
||||
now = make_utc()
|
||||
now = app.make_utc()
|
||||
history = []
|
||||
|
||||
# we just find all relevant (preferred!) ProductCostVersion records
|
||||
|
@ -1948,10 +1959,11 @@ class ProductView(MasterView):
|
|||
"""
|
||||
View for making a new batch from current product grid query.
|
||||
"""
|
||||
app = self.get_rattail_app()
|
||||
supported = self.get_supported_batches()
|
||||
batch_options = []
|
||||
for key, info in list(supported.items()):
|
||||
handler = load_object(info['spec'])(self.rattail_config)
|
||||
handler = app.load_object(info['spec'])(self.rattail_config)
|
||||
handler.spec = info['spec']
|
||||
handler.option_key = key
|
||||
handler.option_title = info.get('title', handler.get_model_title())
|
||||
|
@ -2448,19 +2460,19 @@ class PendingProductView(MasterView):
|
|||
if (self.has_perm('ignore_product')
|
||||
and status in (self.enum.PENDING_PRODUCT_STATUS_PENDING,
|
||||
self.enum.PENDING_PRODUCT_STATUS_READY)):
|
||||
buttons.append(self.make_buefy_button("Ignore Product",
|
||||
type='is-warning',
|
||||
icon_left='ban',
|
||||
**{'@click': "$emit('ignore-product')"}))
|
||||
buttons.append(self.make_button("Ignore Product",
|
||||
type='is-warning',
|
||||
icon_left='ban',
|
||||
**{'@click': "$emit('ignore-product')"}))
|
||||
|
||||
if (self.has_perm('resolve_product')
|
||||
and status in (self.enum.PENDING_PRODUCT_STATUS_PENDING,
|
||||
self.enum.PENDING_PRODUCT_STATUS_READY,
|
||||
self.enum.PENDING_PRODUCT_STATUS_IGNORED)):
|
||||
buttons.append(self.make_buefy_button("Resolve Product",
|
||||
is_primary=True,
|
||||
icon_left='object-ungroup',
|
||||
**{'@click': "$emit('resolve-product')"}))
|
||||
buttons.append(self.make_button("Resolve Product",
|
||||
is_primary=True,
|
||||
icon_left='object-ungroup',
|
||||
**{'@click': "$emit('resolve-product')"}))
|
||||
|
||||
if buttons:
|
||||
text = HTML.tag('span', class_='control', c=[text])
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -28,10 +28,9 @@ from rattail.db.model import PurchaseBatch, PurchaseBatchRow
|
|||
|
||||
import colander
|
||||
from deform import widget as dfwidget
|
||||
from pyramid import httpexceptions
|
||||
from webhelpers2.html import tags, HTML
|
||||
|
||||
from tailbone import forms, grids
|
||||
from tailbone import forms
|
||||
from tailbone.views.batch import BatchMasterView
|
||||
|
||||
|
||||
|
@ -826,7 +825,7 @@ class PurchasingBatchView(BatchMasterView):
|
|||
def render_row_credits(self, row, field):
|
||||
g = self.make_row_credits_grid(row)
|
||||
return HTML.literal(
|
||||
g.render_buefy_table_element(data_prop='rowData.credits'))
|
||||
g.render_table_element(data_prop='rowData.credits'))
|
||||
|
||||
# def before_create_row(self, form):
|
||||
# row = form.fieldset.model
|
||||
|
|
|
@ -310,8 +310,6 @@ class OrderingBatchView(PurchasingBatchView):
|
|||
if not order_date:
|
||||
order_date = localtime(self.rattail_config).date()
|
||||
|
||||
buefy_data = self.get_worksheet_buefy_data(departments)
|
||||
|
||||
return self.render_to_response('worksheet', {
|
||||
'batch': batch,
|
||||
'order_date': order_date,
|
||||
|
@ -324,10 +322,10 @@ class OrderingBatchView(PurchasingBatchView):
|
|||
'get_upc': lambda p: p.upc.pretty() if p.upc else '',
|
||||
'header_columns': self.order_form_header_columns,
|
||||
'ignore_cases': not self.handler.allow_cases(),
|
||||
'worksheet_data': buefy_data,
|
||||
'worksheet_data': self.get_worksheet_data(departments),
|
||||
})
|
||||
|
||||
def get_worksheet_buefy_data(self, departments):
|
||||
def get_worksheet_data(self, departments):
|
||||
data = {}
|
||||
for department in departments.values():
|
||||
for subdepartment in department._order_subdepartments.values():
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -33,12 +33,10 @@ from collections import OrderedDict
|
|||
import humanize
|
||||
|
||||
from rattail import pod
|
||||
from rattail.time import localtime, make_utc
|
||||
from rattail.util import pretty_quantity, prettify, simple_error
|
||||
from rattail.util import prettify, simple_error
|
||||
|
||||
import colander
|
||||
from deform import widget as dfwidget
|
||||
from pyramid import httpexceptions
|
||||
from webhelpers2.html import tags, HTML
|
||||
|
||||
from tailbone import forms, grids
|
||||
|
@ -781,8 +779,8 @@ class ReceivingBatchView(PurchasingBatchView):
|
|||
g.set_click_handler('title', "autoFilterPoVsInvoice(props.row)")
|
||||
kwargs['po_vs_invoice_breakdown_data'] = breakdown
|
||||
kwargs['po_vs_invoice_breakdown_grid'] = HTML.literal(
|
||||
g.render_buefy_table_element(data_prop='poVsInvoiceBreakdownData',
|
||||
empty_labels=True))
|
||||
g.render_table_element(data_prop='poVsInvoiceBreakdownData',
|
||||
empty_labels=True))
|
||||
|
||||
kwargs['allow_edit_catalog_unit_cost'] = self.allow_edit_catalog_unit_cost(batch)
|
||||
kwargs['allow_edit_invoice_unit_cost'] = self.allow_edit_invoice_unit_cost(batch)
|
||||
|
@ -1137,6 +1135,7 @@ class ReceivingBatchView(PurchasingBatchView):
|
|||
"""
|
||||
Primary desktop view for row-level receiving.
|
||||
"""
|
||||
app = self.get_rattail_app()
|
||||
# TODO: this code was largely copied from mobile_receive_row() but it
|
||||
# tries to pave the way for shared logic, i.e. where the latter would
|
||||
# simply invoke this method and return the result. however we're not
|
||||
|
@ -1270,7 +1269,7 @@ class ReceivingBatchView(PurchasingBatchView):
|
|||
if accounted_for:
|
||||
# some product accounted for; button should receive "remainder" only
|
||||
if remainder:
|
||||
remainder = pretty_quantity(remainder)
|
||||
remainder = app.render_quantity(remainder)
|
||||
context['quick_receive_quantity'] = remainder
|
||||
context['quick_receive_text'] = "Receive Remainder ({} {})".format(remainder, context['unit_uom'])
|
||||
else:
|
||||
|
@ -1280,7 +1279,7 @@ class ReceivingBatchView(PurchasingBatchView):
|
|||
else: # nothing yet accounted for, button should receive "all"
|
||||
if not remainder:
|
||||
raise ValueError("why is remainder empty?")
|
||||
remainder = pretty_quantity(remainder)
|
||||
remainder = app.render_quantity(remainder)
|
||||
context['quick_receive_quantity'] = remainder
|
||||
context['quick_receive_text'] = "Receive ALL ({} {})".format(remainder, context['unit_uom'])
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -32,9 +32,8 @@ import logging
|
|||
from collections import OrderedDict
|
||||
|
||||
import rattail
|
||||
from rattail.db import model, Session as RattailSession
|
||||
from rattail.db.model import ReportOutput
|
||||
from rattail.files import resource_path
|
||||
from rattail.time import localtime
|
||||
from rattail.threads import Thread
|
||||
from rattail.util import simple_error
|
||||
|
||||
|
@ -81,6 +80,7 @@ class OrderingWorksheet(View):
|
|||
upc_getter = staticmethod(get_upc)
|
||||
|
||||
def __call__(self):
|
||||
model = self.model
|
||||
if self.request.params.get('vendor'):
|
||||
vendor = Session.get(model.Vendor, self.request.params['vendor'])
|
||||
if vendor:
|
||||
|
@ -104,7 +104,8 @@ class OrderingWorksheet(View):
|
|||
"""
|
||||
Rendering engine for the ordering worksheet report.
|
||||
"""
|
||||
|
||||
app = self.get_rattail_app()
|
||||
model = self.model
|
||||
q = Session.query(model.ProductCost)
|
||||
q = q.join(model.Product)
|
||||
q = q.filter(model.Product.deleted == False)
|
||||
|
@ -127,7 +128,7 @@ class OrderingWorksheet(View):
|
|||
key = '{0} {1}'.format(brand, product.description)
|
||||
return key
|
||||
|
||||
now = localtime(self.request.rattail_config)
|
||||
now = app.localtime()
|
||||
data = dict(
|
||||
vendor=vendor,
|
||||
costs=costs,
|
||||
|
@ -157,7 +158,7 @@ class InventoryWorksheet(View):
|
|||
"""
|
||||
This is the "Inventory Worksheet" report.
|
||||
"""
|
||||
|
||||
model = self.model
|
||||
departments = Session.query(model.Department)
|
||||
|
||||
if self.request.params.get('department'):
|
||||
|
@ -178,6 +179,8 @@ class InventoryWorksheet(View):
|
|||
"""
|
||||
Generates the Inventory Worksheet report.
|
||||
"""
|
||||
app = self.get_rattail_app()
|
||||
model = self.model
|
||||
|
||||
def get_products(subdepartment):
|
||||
q = Session.query(model.Product)
|
||||
|
@ -191,7 +194,7 @@ class InventoryWorksheet(View):
|
|||
q = q.order_by(model.Brand.name, model.Product.description)
|
||||
return q.all()
|
||||
|
||||
now = localtime(self.request.rattail_config)
|
||||
now = app.localtime()
|
||||
data = dict(
|
||||
date=now.strftime('%a %d %b %Y'),
|
||||
time=now.strftime('%I:%M %p'),
|
||||
|
@ -209,7 +212,7 @@ class ReportOutputView(ExportMasterView):
|
|||
"""
|
||||
Master view for report output
|
||||
"""
|
||||
model_class = model.ReportOutput
|
||||
model_class = ReportOutput
|
||||
route_prefix = 'report_output'
|
||||
url_prefix = '/reports/generated'
|
||||
creatable = True
|
||||
|
@ -238,7 +241,7 @@ class ReportOutputView(ExportMasterView):
|
|||
]
|
||||
|
||||
def __init__(self, request):
|
||||
super(ReportOutputView, self).__init__(request)
|
||||
super().__init__(request)
|
||||
self.report_handler = self.get_report_handler()
|
||||
|
||||
def get_report_handler(self):
|
||||
|
@ -246,7 +249,7 @@ class ReportOutputView(ExportMasterView):
|
|||
return app.get_report_handler()
|
||||
|
||||
def configure_grid(self, g):
|
||||
super(ReportOutputView, self).configure_grid(g)
|
||||
super().configure_grid(g)
|
||||
|
||||
g.filters['report_name'].default_active = True
|
||||
g.filters['report_name'].default_verb = 'contains'
|
||||
|
@ -254,7 +257,7 @@ class ReportOutputView(ExportMasterView):
|
|||
g.set_link('filename')
|
||||
|
||||
def configure_form(self, f):
|
||||
super(ReportOutputView, self).configure_form(f)
|
||||
super().configure_form(f)
|
||||
|
||||
# report_type
|
||||
f.set_renderer('report_type', self.render_report_type)
|
||||
|
@ -282,10 +285,10 @@ class ReportOutputView(ExportMasterView):
|
|||
# add help button if report has a link
|
||||
report = self.report_handler.get_report(type_key)
|
||||
if report and report.help_url:
|
||||
button = self.make_buefy_button("Help for this report",
|
||||
url=report.help_url,
|
||||
is_external=True,
|
||||
icon_left='question-circle')
|
||||
button = self.make_button("Help for this report",
|
||||
url=report.help_url,
|
||||
is_external=True,
|
||||
icon_left='question-circle')
|
||||
button = HTML.tag('div', class_='level-item', c=[button])
|
||||
rendered = HTML.tag('div', class_='level-item', c=[rendered])
|
||||
rendered = HTML.tag('div', class_='level-left', c=[rendered, button])
|
||||
|
@ -311,7 +314,7 @@ class ReportOutputView(ExportMasterView):
|
|||
labels={'key': "Name"},
|
||||
)
|
||||
return HTML.literal(
|
||||
g.render_buefy_table_element(data_prop='paramsData'))
|
||||
g.render_table_element(data_prop='paramsData'))
|
||||
|
||||
def get_params_context(self, report):
|
||||
params_data = []
|
||||
|
@ -323,7 +326,7 @@ class ReportOutputView(ExportMasterView):
|
|||
return params_data
|
||||
|
||||
def template_kwargs_view(self, **kwargs):
|
||||
kwargs = super(ReportOutputView, self).template_kwargs_view(**kwargs)
|
||||
kwargs = super().template_kwargs_view(**kwargs)
|
||||
output = kwargs['instance']
|
||||
|
||||
kwargs['params_data'] = self.get_params_context(output)
|
||||
|
@ -339,7 +342,7 @@ class ReportOutputView(ExportMasterView):
|
|||
return kwargs
|
||||
|
||||
def template_kwargs_delete(self, **kwargs):
|
||||
kwargs = super(ReportOutputView, self).template_kwargs_delete(**kwargs)
|
||||
kwargs = super().template_kwargs_delete(**kwargs)
|
||||
|
||||
report = kwargs['instance']
|
||||
kwargs['params_data'] = self.get_params_context(report)
|
||||
|
@ -496,7 +499,9 @@ class ReportOutputView(ExportMasterView):
|
|||
resulting :class:`rattail:~rattail.db.model.reports.ReportOutput`
|
||||
object.
|
||||
"""
|
||||
session = RattailSession()
|
||||
app = self.get_rattail_app()
|
||||
model = self.model
|
||||
session = app.make_session()
|
||||
user = session.get(model.User, user_uuid)
|
||||
try:
|
||||
output = self.report_handler.generate_output(session, report, params, user, progress=progress)
|
||||
|
@ -603,7 +608,7 @@ class ProblemReportView(MasterView):
|
|||
]
|
||||
|
||||
def __init__(self, request):
|
||||
super(ProblemReportView, self).__init__(request)
|
||||
super().__init__(request)
|
||||
|
||||
app = self.get_rattail_app()
|
||||
self.problem_handler = app.get_problem_report_handler()
|
||||
|
@ -660,7 +665,7 @@ class ProblemReportView(MasterView):
|
|||
return ProblemReportSchema()
|
||||
|
||||
def configure_form(self, f):
|
||||
super(ProblemReportView, self).configure_form(f)
|
||||
super().configure_form(f)
|
||||
|
||||
# email_*
|
||||
if self.editing:
|
||||
|
@ -703,10 +708,10 @@ class ProblemReportView(MasterView):
|
|||
g = self.get_grid_factory()('days', [],
|
||||
columns=['weekday_name', 'enabled'],
|
||||
labels={'weekday_name': "Weekday"})
|
||||
return HTML.literal(g.render_buefy_table_element(data_prop='weekdaysData'))
|
||||
return HTML.literal(g.render_table_element(data_prop='weekdaysData'))
|
||||
|
||||
def template_kwargs_view(self, **kwargs):
|
||||
kwargs = super(ProblemReportView, self).template_kwargs_view(**kwargs)
|
||||
kwargs = super().template_kwargs_view(**kwargs)
|
||||
report_info = kwargs['instance']
|
||||
|
||||
data = []
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -29,7 +29,7 @@ import os
|
|||
from sqlalchemy import orm
|
||||
from openpyxl.styles import Font, PatternFill
|
||||
|
||||
from rattail.db import model
|
||||
from rattail.db.model import Role
|
||||
from rattail.db.auth import administrator_role, guest_role, authenticated_role
|
||||
from rattail.excel import ExcelWriter
|
||||
|
||||
|
@ -46,7 +46,7 @@ class RoleView(PrincipalMasterView):
|
|||
"""
|
||||
Master view for the Role model.
|
||||
"""
|
||||
model_class = model.Role
|
||||
model_class = Role
|
||||
has_versions = True
|
||||
touchable = True
|
||||
|
||||
|
@ -77,7 +77,7 @@ class RoleView(PrincipalMasterView):
|
|||
]
|
||||
|
||||
def configure_grid(self, g):
|
||||
super(RoleView, self).configure_grid(g)
|
||||
super().configure_grid(g)
|
||||
|
||||
# name
|
||||
g.filters['name'].default_active = True
|
||||
|
@ -158,6 +158,7 @@ class RoleView(PrincipalMasterView):
|
|||
return True
|
||||
|
||||
def unique_name(self, node, value):
|
||||
model = self.model
|
||||
query = self.Session.query(model.Role)\
|
||||
.filter(model.Role.name == value)
|
||||
if self.editing:
|
||||
|
@ -167,7 +168,7 @@ class RoleView(PrincipalMasterView):
|
|||
raise colander.Invalid(node, "Name must be unique")
|
||||
|
||||
def configure_form(self, f):
|
||||
super(RoleView, self).configure_form(f)
|
||||
super().configure_form(f)
|
||||
role = f.model_instance
|
||||
app = self.get_rattail_app()
|
||||
auth = app.get_auth_handler()
|
||||
|
@ -265,7 +266,7 @@ class RoleView(PrincipalMasterView):
|
|||
g.main_actions.append(self.make_action('edit', icon='edit'))
|
||||
|
||||
return HTML.literal(
|
||||
g.render_buefy_table_element(data_prop='usersData'))
|
||||
g.render_table_element(data_prop='usersData'))
|
||||
|
||||
def get_available_permissions(self):
|
||||
"""
|
||||
|
@ -322,7 +323,7 @@ class RoleView(PrincipalMasterView):
|
|||
"""
|
||||
if data is None:
|
||||
data = form.validated
|
||||
role = super(RoleView, self).objectify(form, data)
|
||||
role = super().objectify(form, data)
|
||||
self.update_permissions(role, data['permissions'])
|
||||
return role
|
||||
|
||||
|
@ -345,6 +346,7 @@ class RoleView(PrincipalMasterView):
|
|||
auth.revoke_permission(role, pkey)
|
||||
|
||||
def template_kwargs_view(self, **kwargs):
|
||||
model = self.model
|
||||
role = kwargs['instance']
|
||||
if role.users:
|
||||
users = sorted(role.users, key=lambda u: u.username)
|
||||
|
@ -390,6 +392,7 @@ class RoleView(PrincipalMasterView):
|
|||
|
||||
def find_principals_with_permission(self, session, permission):
|
||||
app = self.get_rattail_app()
|
||||
model = self.model
|
||||
auth = app.get_auth_handler()
|
||||
|
||||
# TODO: this should search Permission table instead, and work backward to Role?
|
||||
|
@ -408,6 +411,7 @@ class RoleView(PrincipalMasterView):
|
|||
Excel spreadsheet, and returns that file.
|
||||
"""
|
||||
app = self.get_rattail_app()
|
||||
model = self.model
|
||||
auth = app.get_auth_handler()
|
||||
|
||||
roles = self.Session.query(model.Role)\
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -32,8 +32,8 @@ from collections import OrderedDict
|
|||
|
||||
import json
|
||||
|
||||
from rattail.db import model
|
||||
from rattail.settings import Setting
|
||||
from rattail.db.model import Setting
|
||||
from rattail.settings import Setting as AppSetting
|
||||
from rattail.util import import_module_path
|
||||
|
||||
import colander
|
||||
|
@ -81,7 +81,7 @@ class AppInfoView(MasterView):
|
|||
return data
|
||||
|
||||
def configure_grid(self, g):
|
||||
super(AppInfoView, self).configure_grid(g)
|
||||
super().configure_grid(g)
|
||||
|
||||
g.sorters['name'] = g.make_simple_sorter('name', foldcase=True)
|
||||
g.set_sort_defaults('name')
|
||||
|
@ -94,12 +94,12 @@ class AppInfoView(MasterView):
|
|||
g.set_searchable('editable_project_location')
|
||||
|
||||
def template_kwargs_index(self, **kwargs):
|
||||
kwargs = super(AppInfoView, self).template_kwargs_index(**kwargs)
|
||||
kwargs = super().template_kwargs_index(**kwargs)
|
||||
kwargs['configure_button_title'] = "Configure App"
|
||||
return kwargs
|
||||
|
||||
def configure_get_context(self, **kwargs):
|
||||
context = super(AppInfoView, self).configure_get_context(**kwargs)
|
||||
context = super().configure_get_context(**kwargs)
|
||||
|
||||
weblibs = OrderedDict([
|
||||
('vue', "Vue"),
|
||||
|
@ -195,7 +195,7 @@ class SettingView(MasterView):
|
|||
"""
|
||||
Master view for the settings model.
|
||||
"""
|
||||
model_class = model.Setting
|
||||
model_class = Setting
|
||||
model_title = "Raw Setting"
|
||||
model_title_plural = "Raw Settings"
|
||||
bulk_deletable = True
|
||||
|
@ -207,18 +207,19 @@ class SettingView(MasterView):
|
|||
]
|
||||
|
||||
def configure_grid(self, g):
|
||||
super(SettingView, self).configure_grid(g)
|
||||
super().configure_grid(g)
|
||||
g.filters['name'].default_active = True
|
||||
g.filters['name'].default_verb = 'contains'
|
||||
g.set_sort_defaults('name')
|
||||
g.set_link('name')
|
||||
|
||||
def configure_form(self, f):
|
||||
super(SettingView, self).configure_form(f)
|
||||
super().configure_form(f)
|
||||
if self.creating:
|
||||
f.set_validator('name', self.unique_name)
|
||||
|
||||
def unique_name(self, node, value):
|
||||
model = self.model
|
||||
setting = self.Session.get(model.Setting, value)
|
||||
if setting:
|
||||
raise colander.Invalid(node, "Setting name must be unique")
|
||||
|
@ -245,7 +246,7 @@ class SettingView(MasterView):
|
|||
self.rattail_config.beaker_invalidate_setting(setting.name)
|
||||
|
||||
# otherwise delete like normal
|
||||
super(SettingView, self).delete_instance(setting)
|
||||
super().delete_instance(setting)
|
||||
|
||||
|
||||
# TODO: deprecate / remove this
|
||||
|
@ -307,14 +308,14 @@ class AppSettingsView(View):
|
|||
'settings': settings,
|
||||
'config_options': config_options,
|
||||
}
|
||||
context['buefy_data'] = self.get_buefy_data(form, groups, settings)
|
||||
context['settings_data'] = self.get_settings_data(form, groups, settings)
|
||||
# TODO: this seems hacky, and probably only needed if theme changes?
|
||||
if current_group == '(All)':
|
||||
current_group = ''
|
||||
context['current_group'] = current_group
|
||||
return context
|
||||
|
||||
def get_buefy_data(self, form, groups, settings):
|
||||
def get_settings_data(self, form, groups, settings):
|
||||
dform = form.make_deform_form()
|
||||
grouped = dict([(label, [])
|
||||
for label in groups])
|
||||
|
@ -407,7 +408,7 @@ class AppSettingsView(View):
|
|||
module = import_module_path(module)
|
||||
for name in dir(module):
|
||||
obj = getattr(module, name)
|
||||
if isinstance(obj, type) and issubclass(obj, Setting) and obj is not Setting:
|
||||
if isinstance(obj, type) and issubclass(obj, AppSetting) and obj is not AppSetting:
|
||||
if core_only and not obj.core:
|
||||
continue
|
||||
# NOTE: we set this here, and reference it elsewhere
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -28,9 +28,8 @@ import datetime
|
|||
|
||||
import sqlalchemy as sa
|
||||
|
||||
from rattail import enum
|
||||
from rattail.db import model, api
|
||||
from rattail.time import localtime, make_utc, get_sunday
|
||||
from rattail.db import api
|
||||
from rattail.time import get_sunday
|
||||
from rattail.util import hours_as_decimal
|
||||
|
||||
import colander
|
||||
|
@ -83,6 +82,8 @@ class TimeSheetView(View):
|
|||
"""
|
||||
Determine date/store/dept context from user's session and/or defaults.
|
||||
"""
|
||||
app = self.get_rattail_app()
|
||||
model = self.model
|
||||
date = None
|
||||
date_key = 'timesheet.{}.date'.format(self.key)
|
||||
if date_key in self.request.session:
|
||||
|
@ -93,7 +94,7 @@ class TimeSheetView(View):
|
|||
except ValueError:
|
||||
pass
|
||||
if not date:
|
||||
date = localtime(self.rattail_config).date()
|
||||
date = app.today()
|
||||
|
||||
store = None
|
||||
department = None
|
||||
|
@ -113,7 +114,7 @@ class TimeSheetView(View):
|
|||
store = api.get_store(Session(), store)
|
||||
|
||||
employees = Session.query(model.Employee)\
|
||||
.filter(model.Employee.status == enum.EMPLOYEE_STATUS_CURRENT)
|
||||
.filter(model.Employee.status == self.enum.EMPLOYEE_STATUS_CURRENT)
|
||||
if store:
|
||||
employees = employees.join(model.EmployeeStore)\
|
||||
.filter(model.EmployeeStore.store == store)
|
||||
|
@ -132,6 +133,8 @@ class TimeSheetView(View):
|
|||
"""
|
||||
Determine employee/date context from user's session and/or defaults
|
||||
"""
|
||||
app = self.get_rattail_app()
|
||||
model = self.model
|
||||
date = None
|
||||
date_key = 'timesheet.{}.employee.date'.format(self.key)
|
||||
if date_key in self.request.session:
|
||||
|
@ -142,7 +145,7 @@ class TimeSheetView(View):
|
|||
except ValueError:
|
||||
pass
|
||||
if not date:
|
||||
date = localtime(self.rattail_config).date()
|
||||
date = app.today()
|
||||
|
||||
employee = None
|
||||
employee_key = 'timesheet.{}.employee'.format(self.key)
|
||||
|
@ -191,7 +194,7 @@ class TimeSheetView(View):
|
|||
stores = self.get_stores()
|
||||
store_values = [(s.uuid, "{} - {}".format(s.id, s.name)) for s in stores]
|
||||
store_values.insert(0, ('', "(all)"))
|
||||
form.set_widget('store', forms.widgets.PlainSelectWidget(values=store_values))
|
||||
form.set_widget('store', dfwidget.SelectWidget(values=store_values))
|
||||
if context['store']:
|
||||
form.set_default('store', context['store'].uuid)
|
||||
else:
|
||||
|
@ -203,7 +206,7 @@ class TimeSheetView(View):
|
|||
departments = self.get_departments()
|
||||
department_values = [(d.uuid, d.name) for d in departments]
|
||||
department_values.insert(0, ('', "(all)"))
|
||||
form.set_widget('department', forms.widgets.PlainSelectWidget(values=department_values))
|
||||
form.set_widget('department', dfwidget.SelectWidget(values=department_values))
|
||||
if context['department']:
|
||||
form.set_default('department', context['department'].uuid)
|
||||
else:
|
||||
|
@ -292,6 +295,7 @@ class TimeSheetView(View):
|
|||
self.request.session['timesheet.{}.{}'.format(mainkey, key)] = value
|
||||
|
||||
def get_stores(self):
|
||||
model = self.model
|
||||
return Session.query(model.Store).order_by(model.Store.id).all()
|
||||
|
||||
def get_store_options(self, stores):
|
||||
|
@ -299,6 +303,7 @@ class TimeSheetView(View):
|
|||
return tags.Options(options, prompt="(all)")
|
||||
|
||||
def get_departments(self):
|
||||
model = self.model
|
||||
return Session.query(model.Department).order_by(model.Department.name).all()
|
||||
|
||||
def get_department_options(self, departments):
|
||||
|
@ -402,6 +407,7 @@ class TimeSheetView(View):
|
|||
the given params. The cached shift data is attached to each employee.
|
||||
"""
|
||||
app = self.get_rattail_app()
|
||||
model = self.model
|
||||
|
||||
# TODO: a bit hacky, this? display hours as HH:MM by default, but
|
||||
# check config in order to display as HH.HH for certain users
|
||||
|
@ -413,19 +419,19 @@ class TimeSheetView(View):
|
|||
hours_style = 'pretty'
|
||||
|
||||
shift_type = 'scheduled' if cls is model.ScheduledShift else 'worked'
|
||||
min_time = localtime(self.rattail_config, datetime.datetime.combine(weekdays[0], datetime.time(0)))
|
||||
max_time = localtime(self.rattail_config, datetime.datetime.combine(weekdays[-1] + datetime.timedelta(days=1), datetime.time(0)))
|
||||
min_time = app.localtime(datetime.datetime.combine(weekdays[0], datetime.time(0)))
|
||||
max_time = app.localtime(datetime.datetime.combine(weekdays[-1] + datetime.timedelta(days=1), datetime.time(0)))
|
||||
shifts = Session.query(cls)\
|
||||
.filter(cls.employee_uuid.in_([e.uuid for e in employees]))\
|
||||
.filter(sa.or_(
|
||||
sa.and_(
|
||||
cls.start_time >= make_utc(min_time),
|
||||
cls.start_time < make_utc(max_time),
|
||||
cls.start_time >= app.make_utc(min_time),
|
||||
cls.start_time < app.make_utc(max_time),
|
||||
),
|
||||
sa.and_(
|
||||
cls.start_time == None,
|
||||
cls.end_time >= make_utc(min_time),
|
||||
cls.end_time < make_utc(max_time),
|
||||
cls.end_time >= app.make_utc(min_time),
|
||||
cls.end_time < app.make_utc(max_time),
|
||||
)))\
|
||||
.all()
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -80,7 +80,7 @@ class TableView(MasterView):
|
|||
]
|
||||
|
||||
def __init__(self, request):
|
||||
super(TableView, self).__init__(request)
|
||||
super().__init__(request)
|
||||
app = self.get_rattail_app()
|
||||
self.db_handler = app.get_db_handler()
|
||||
|
||||
|
@ -102,7 +102,7 @@ class TableView(MasterView):
|
|||
for row in result]
|
||||
|
||||
def configure_grid(self, g):
|
||||
super(TableView, self).configure_grid(g)
|
||||
super().configure_grid(g)
|
||||
|
||||
# table_name
|
||||
g.sorters['table_name'] = g.make_simple_sorter('table_name', foldcase=True)
|
||||
|
@ -114,7 +114,7 @@ class TableView(MasterView):
|
|||
g.sorters['row_count'] = g.make_simple_sorter('row_count')
|
||||
|
||||
def configure_form(self, f):
|
||||
super(TableView, self).configure_form(f)
|
||||
super().configure_form(f)
|
||||
|
||||
# TODO: should render this instead, by inspecting table
|
||||
if not self.creating:
|
||||
|
@ -169,7 +169,7 @@ class TableView(MasterView):
|
|||
return TableSchema()
|
||||
|
||||
def get_xref_buttons(self, table):
|
||||
buttons = super(TableView, self).get_xref_buttons(table)
|
||||
buttons = super().get_xref_buttons(table)
|
||||
|
||||
if table.get('model_name'):
|
||||
all_views = self.request.registry.settings['tailbone_model_views']
|
||||
|
@ -182,15 +182,15 @@ class TableView(MasterView):
|
|||
if self.request.has_perm('model_views.create'):
|
||||
url = self.request.route_url('model_views.create',
|
||||
_query={'model_name': table['model_name']})
|
||||
buttons.append(self.make_buefy_button("New View",
|
||||
is_primary=True,
|
||||
url=url,
|
||||
icon_left='plus'))
|
||||
buttons.append(self.make_button("New View",
|
||||
is_primary=True,
|
||||
url=url,
|
||||
icon_left='plus'))
|
||||
|
||||
return buttons
|
||||
|
||||
def template_kwargs_create(self, **kwargs):
|
||||
kwargs = super(TableView, self).template_kwargs_create(**kwargs)
|
||||
kwargs = super().template_kwargs_create(**kwargs)
|
||||
app = self.get_rattail_app()
|
||||
model = self.model
|
||||
|
||||
|
@ -301,7 +301,7 @@ class TableView(MasterView):
|
|||
return data
|
||||
|
||||
def configure_row_grid(self, g):
|
||||
super(TableView, self).configure_row_grid(g)
|
||||
super().configure_row_grid(g)
|
||||
|
||||
g.sorters['sequence'] = g.make_simple_sorter('sequence')
|
||||
g.set_sort_defaults('sequence')
|
||||
|
@ -419,7 +419,7 @@ class TablesView(TableView):
|
|||
def __init__(self, request):
|
||||
warnings.warn("TablesView is deprecated; please use TableView instead",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
super(TablesView, self).__init__(request)
|
||||
super().__init__(request)
|
||||
|
||||
|
||||
class TableSchema(colander.Schema):
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -98,4 +98,4 @@ class MasterView(views.MasterView):
|
|||
main_actions=actions,
|
||||
)
|
||||
return HTML.literal(
|
||||
g.render_buefy_table_element(data_prop='probesData'))
|
||||
g.render_table_element(data_prop='probesData'))
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -202,7 +202,7 @@ class TransactionView(MasterView):
|
|||
return 'warning'
|
||||
|
||||
def configure_form(self, f):
|
||||
super(TransactionView, self).configure_form(f)
|
||||
super().configure_form(f)
|
||||
|
||||
# system
|
||||
f.set_enum('system', self.enum.TRAINWRECK_SYSTEM)
|
||||
|
@ -240,10 +240,10 @@ class TransactionView(MasterView):
|
|||
request=self.request)
|
||||
|
||||
return HTML.literal(
|
||||
g.render_buefy_table_element(data_prop='custorderXrefMarkersData'))
|
||||
g.render_table_element(data_prop='custorderXrefMarkersData'))
|
||||
|
||||
def template_kwargs_view(self, **kwargs):
|
||||
kwargs = super(TransactionView, self).template_kwargs_view(**kwargs)
|
||||
kwargs = super().template_kwargs_view(**kwargs)
|
||||
|
||||
form = kwargs['form']
|
||||
if 'custorder_xref_markers' in form:
|
||||
|
@ -266,7 +266,7 @@ class TransactionView(MasterView):
|
|||
return item.transaction
|
||||
|
||||
def configure_row_grid(self, g):
|
||||
super(TransactionView, self).configure_row_grid(g)
|
||||
super().configure_row_grid(g)
|
||||
g.set_sort_defaults('sequence')
|
||||
|
||||
g.set_type('unit_quantity', 'quantity')
|
||||
|
@ -286,7 +286,7 @@ class TransactionView(MasterView):
|
|||
return "Trainwreck Line Item"
|
||||
|
||||
def configure_row_form(self, f):
|
||||
super(TransactionView, self).configure_row_form(f)
|
||||
super().configure_row_form(f)
|
||||
|
||||
# transaction
|
||||
f.set_renderer('transaction', self.render_transaction)
|
||||
|
@ -325,7 +325,7 @@ class TransactionView(MasterView):
|
|||
request=self.request)
|
||||
|
||||
return HTML.literal(
|
||||
g.render_buefy_table_element(data_prop='discountsData'))
|
||||
g.render_table_element(data_prop='discountsData'))
|
||||
|
||||
def template_kwargs_view_row(self, **kwargs):
|
||||
form = kwargs['form']
|
||||
|
@ -401,7 +401,7 @@ class TransactionView(MasterView):
|
|||
]
|
||||
|
||||
def configure_get_context(self):
|
||||
context = super(TransactionView, self).configure_get_context()
|
||||
context = super().configure_get_context()
|
||||
|
||||
app = self.get_rattail_app()
|
||||
trainwreck_handler = app.get_trainwreck_handler()
|
||||
|
@ -415,7 +415,7 @@ class TransactionView(MasterView):
|
|||
return context
|
||||
|
||||
def configure_gather_settings(self, data):
|
||||
settings = super(TransactionView, self).configure_gather_settings(data)
|
||||
settings = super().configure_gather_settings(data)
|
||||
|
||||
app = self.get_rattail_app()
|
||||
trainwreck_handler = app.get_trainwreck_handler()
|
||||
|
@ -432,7 +432,7 @@ class TransactionView(MasterView):
|
|||
return settings
|
||||
|
||||
def configure_remove_settings(self):
|
||||
super(TransactionView, self).configure_remove_settings()
|
||||
super().configure_remove_settings()
|
||||
app = self.get_rattail_app()
|
||||
|
||||
names = [
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -84,7 +84,7 @@ class UserView(PrincipalMasterView):
|
|||
]
|
||||
|
||||
def __init__(self, request):
|
||||
super(UserView, self).__init__(request)
|
||||
super().__init__(request)
|
||||
app = self.get_rattail_app()
|
||||
|
||||
# always get a reference to the auth/merge handler
|
||||
|
@ -92,7 +92,7 @@ class UserView(PrincipalMasterView):
|
|||
self.merge_handler = self.auth_handler
|
||||
|
||||
def query(self, session):
|
||||
query = super(UserView, self).query(session)
|
||||
query = super().query(session)
|
||||
model = self.model
|
||||
|
||||
# bring in the related Person(s)
|
||||
|
@ -102,7 +102,7 @@ class UserView(PrincipalMasterView):
|
|||
return query
|
||||
|
||||
def configure_grid(self, g):
|
||||
super(UserView, self).configure_grid(g)
|
||||
super().configure_grid(g)
|
||||
model = self.model
|
||||
|
||||
del g.filters['salt']
|
||||
|
@ -177,7 +177,7 @@ class UserView(PrincipalMasterView):
|
|||
raise colander.Invalid(node, "Person not found (you must *select* a record)")
|
||||
|
||||
def configure_form(self, f):
|
||||
super(UserView, self).configure_form(f)
|
||||
super().configure_form(f)
|
||||
model = self.model
|
||||
user = f.model_instance
|
||||
|
||||
|
@ -290,12 +290,12 @@ class UserView(PrincipalMasterView):
|
|||
self.make_action('delete', icon='trash',
|
||||
click_handler="$emit('api-token-delete', props.row)")])
|
||||
|
||||
button = self.make_buefy_button("New", is_primary=True,
|
||||
icon_left='plus',
|
||||
**{'@click': "$emit('api-new-token')"})
|
||||
button = self.make_button("New", is_primary=True,
|
||||
icon_left='plus',
|
||||
**{'@click': "$emit('api-new-token')"})
|
||||
|
||||
table = HTML.literal(
|
||||
g.render_buefy_table_element(data_prop='apiTokens'))
|
||||
g.render_table_element(data_prop='apiTokens'))
|
||||
|
||||
return HTML.tag('div', c=[button, table])
|
||||
|
||||
|
@ -329,7 +329,7 @@ class UserView(PrincipalMasterView):
|
|||
'tokens': self.get_api_tokens(user)}
|
||||
|
||||
def template_kwargs_view(self, **kwargs):
|
||||
kwargs = super(UserView, self).template_kwargs_view(**kwargs)
|
||||
kwargs = super().template_kwargs_view(**kwargs)
|
||||
user = kwargs['instance']
|
||||
|
||||
kwargs['api_tokens_data'] = self.get_api_tokens(user)
|
||||
|
@ -377,7 +377,7 @@ class UserView(PrincipalMasterView):
|
|||
# create/update user as per normal
|
||||
if data is None:
|
||||
data = form.validated
|
||||
user = super(UserView, self).objectify(form, data)
|
||||
user = super().objectify(form, data)
|
||||
|
||||
# create/update person as needed
|
||||
names = {}
|
||||
|
@ -487,7 +487,7 @@ class UserView(PrincipalMasterView):
|
|||
.filter(model.UserEvent.user == user)
|
||||
|
||||
def configure_row_grid(self, g):
|
||||
super(UserView, self).configure_row_grid(g)
|
||||
super().configure_row_grid(g)
|
||||
g.width = 'half'
|
||||
g.filterable = False
|
||||
g.set_sort_defaults('occurred', 'desc')
|
||||
|
@ -588,7 +588,7 @@ class UserView(PrincipalMasterView):
|
|||
'themes.style.{}'.format(name))
|
||||
if css:
|
||||
options.append({'value': css, 'label': name})
|
||||
context['buefy_css_options'] = options
|
||||
context['theme_style_options'] = options
|
||||
|
||||
return context
|
||||
|
||||
|
@ -699,12 +699,12 @@ class UserEventView(MasterView):
|
|||
]
|
||||
|
||||
def get_data(self, session=None):
|
||||
query = super(UserEventView, self).get_data(session=session)
|
||||
query = super().get_data(session=session)
|
||||
model = self.model
|
||||
return query.join(model.User)
|
||||
|
||||
def configure_grid(self, g):
|
||||
super(UserEventView, self).configure_grid(g)
|
||||
super().configure_grid(g)
|
||||
model = self.model
|
||||
g.set_joiner('person', lambda q: q.outerjoin(model.Person))
|
||||
g.set_sorter('user', model.User.username)
|
||||
|
|
Loading…
Reference in a new issue