add button to install sample data, for root user only

sample data is very minimal but probably we need to ship that separate
to give a more complete sample.  this is better than nothing for now.
This commit is contained in:
Lance Edgar 2026-01-03 16:05:59 -06:00
parent 94597f4703
commit 17d0099429
13 changed files with 194 additions and 1 deletions

View file

@ -0,0 +1,4 @@
uuid,customer_id,name,account_holder_uuid,phone_number,email_address
06958b42-e542-7914-8000-841155e871ba,001,Fred Flintstone,06958b40-8610-7caa-8000-28c14769a3f5,,
06958b43-5daf-7af5-8000-7fe6c8e19b73,002,Barney Rubble,06958b40-23ee-7eba-8000-7a6081601e4c,,
06958b43-d443-7fb0-8000-5585fb86c3ce,003,Betty Boop,06958b40-f601-7a3c-8000-638088595cea,,
1 uuid customer_id name account_holder_uuid phone_number email_address
2 06958b42-e542-7914-8000-841155e871ba 001 Fred Flintstone 06958b40-8610-7caa-8000-28c14769a3f5
3 06958b43-5daf-7af5-8000-7fe6c8e19b73 002 Barney Rubble 06958b40-23ee-7eba-8000-7a6081601e4c
4 06958b43-d443-7fb0-8000-5585fb86c3ce 003 Betty Boop 06958b40-f601-7a3c-8000-638088595cea

View file

@ -0,0 +1,3 @@
uuid,department_id,name,for_products,for_personnel,exempt_from_gross_sales
06958b44-cc3c-7b56-8000-997dd91c0d51,01,Grocery,True,False,False
06958b45-8bb4-79ed-8000-e61ebf1d545d,02,Books,True,False,False
1 uuid department_id name for_products for_personnel exempt_from_gross_sales
2 06958b44-cc3c-7b56-8000-997dd91c0d51 01 Grocery True False False
3 06958b45-8bb4-79ed-8000-e61ebf1d545d 02 Books True False False

View file

@ -0,0 +1,2 @@
uuid,person_uuid,name,public_name,active
06958b42-17ae-78bd-8000-56322ad38684,06958b40-8610-7caa-8000-28c14769a3f5,Fred Flintstone,,True
1 uuid person_uuid name public_name active
2 06958b42-17ae-78bd-8000-56322ad38684 06958b40-8610-7caa-8000-28c14769a3f5 Fred Flintstone True

View file

@ -0,0 +1,4 @@
uuid,type_code,name
06958b49-eee0-7a8e-8000-8fa8d1648d55,1,Manual
06958b4a-7e73-7443-8000-c9a826760dbd,2,Receiving
06958b4a-c9b8-736d-8000-ee9974208f34,3,Sales
1 uuid type_code name
2 06958b49-eee0-7a8e-8000-8fa8d1648d55 1 Manual
3 06958b4a-7e73-7443-8000-c9a826760dbd 2 Receiving
4 06958b4a-c9b8-736d-8000-ee9974208f34 3 Sales

View file

@ -0,0 +1,4 @@
uuid,full_name,first_name,middle_name,last_name
06958b40-23ee-7eba-8000-7a6081601e4c,Barney Rubble,Barney,,Rubble
06958b40-8610-7caa-8000-28c14769a3f5,Fred Flintstone,Fred,,Flintstone
06958b40-f601-7a3c-8000-638088595cea,Betty Boop,Betty,,Boop
1 uuid full_name first_name middle_name last_name
2 06958b40-23ee-7eba-8000-7a6081601e4c Barney Rubble Barney Rubble
3 06958b40-8610-7caa-8000-28c14769a3f5 Fred Flintstone Fred Flintstone
4 06958b40-f601-7a3c-8000-638088595cea Betty Boop Betty Boop

View file

@ -0,0 +1,3 @@
uuid,product_id,brand_name,description,size,sold_by_weight,department_uuid,special_order,case_size,unit_cost,unit_price_reg,notes
06958b47-6c11-7bf9-8000-d47cf9ecabbd,07430500132,Bragg's,Apple Cider Vinegar,32oz,False,06958b44-cc3c-7b56-8000-997dd91c0d51,False,12.0000,3.99000,5.990,This is what notes look like for a product.
06958b49-46ce-7ded-8000-f5e2504ccb81,07430500116,Bragg's,Apple Cider Vinegar,16oz,False,06958b44-cc3c-7b56-8000-997dd91c0d51,False,12.0000,2.79000,4.490,
1 uuid product_id brand_name description size sold_by_weight department_uuid special_order case_size unit_cost unit_price_reg notes
2 06958b47-6c11-7bf9-8000-d47cf9ecabbd 07430500132 Bragg's Apple Cider Vinegar 32oz False 06958b44-cc3c-7b56-8000-997dd91c0d51 False 12.0000 3.99000 5.990 This is what notes look like for a product.
3 06958b49-46ce-7ded-8000-f5e2504ccb81 07430500116 Bragg's Apple Cider Vinegar 16oz False 06958b44-cc3c-7b56-8000-997dd91c0d51 False 12.0000 2.79000 4.490

View file

@ -0,0 +1,2 @@
uuid,store_id,name,active
06958b38-22d3-79c4-8000-5ac6198dee37,001,Main Store,True
1 uuid store_id name active
2 06958b38-22d3-79c4-8000-5ac6198dee37 001 Main Store True

View file

@ -0,0 +1,3 @@
uuid,tax_id,name,rate
06958b3c-c350-7820-8000-0650492afa09,1,Food,3.00000
06958b3d-3d8a-7ae4-8000-461c96456694,2,Non-Food,5.00000
1 uuid tax_id name rate
2 06958b3c-c350-7820-8000-0650492afa09 1 Food 3.00000
3 06958b3d-3d8a-7ae4-8000-461c96456694 2 Non-Food 5.00000

View file

@ -0,0 +1,4 @@
uuid,tender_id,name,notes,is_cash,is_foodstamp,allow_cashback,kick_drawer,active
06958b39-d29b-7f62-8000-914f55432288,CASH,Cash,,True,False,True,True,True
06958b3a-906d-7d16-8000-369bde264e74,CHECK,Check,,False,False,False,True,True
06958b3b-bd36-765e-8000-b68a1d64a8de,FS,Food Stamps,,False,True,False,False,True
1 uuid tender_id name notes is_cash is_foodstamp allow_cashback kick_drawer active
2 06958b39-d29b-7f62-8000-914f55432288 CASH Cash True False True True True
3 06958b3a-906d-7d16-8000-369bde264e74 CHECK Check False False False True True
4 06958b3b-bd36-765e-8000-b68a1d64a8de FS Food Stamps False True False False True

View file

@ -0,0 +1,2 @@
uuid,terminal_id,name
06958b39-0ef2-72f1-8000-24b87acb7c6d,099,Test Terminal
1 uuid terminal_id name
2 06958b39-0ef2-72f1-8000-24b87acb7c6d 099 Test Terminal

View file

@ -0,0 +1,38 @@
## -*- coding: utf-8; -*-
<%inherit file="wuttaweb:templates/appinfo/index.mako" />
<%def name="middle_buttons()">
${parent.middle_buttons()}
% if request.is_root:
<b-button type="is-warning"
icon-pack="fas"
icon-left="table"
@click="installSampleData()"
:disabled="installingSampleData">
{{ installingSampleData ? "Working, please wait..." : "Install Sample Data" }}
</b-button>
${h.form(request.route_url(f"{route_prefix}.install_sample_data"), ref="installSampleDataForm")}
${h.csrf_token(request)}
${h.end_form()}
% endif
</%def>
<%def name="modify_vue_vars()">
${parent.modify_vue_vars()}
% if request.is_root:
<script>
ThisPageData.installingSampleData = false
ThisPage.methods.installSampleData = function() {
if (confirm("Really install sample data?")) {
this.installingSampleData = true
this.$refs.installSampleDataForm.submit()
}
}
</script>
% endif
</%def>

View file

@ -31,7 +31,11 @@ def includeme(config):
# wuttaweb
essential.defaults(
config, **{"wuttaweb.views.common": "wuttapos.server.views.common"}
config,
**{
"wuttaweb.views.common": "wuttapos.server.views.common",
"wuttaweb.views.settings": "wuttapos.server.views.settings",
}
)
# wuttapos

View file

@ -0,0 +1,120 @@
# -*- coding: utf-8; -*-
################################################################################
#
# WuttaPOS -- Point of Sale system based on Wutta Framework
# Copyright © 2026 Lance Edgar
#
# This file is part of WuttaPOS.
#
# WuttaPOS is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# WuttaPOS is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# WuttaPOS. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
Views for app settings
"""
import glob
import os
import logging
from wuttaweb.views import settings as base
log = logging.getLogger(__name__)
class AppInfoView(base.AppInfoView):
"""
We override this view to add the :meth:`install_sample_data()` route.
See also parent docs, :class:`~wuttaweb:wuttaweb.views.settings.AppInfoView`
"""
def install_sample_data(self):
"""
Special view to install sample data. Probably just temporary until
something better can be worked out...
Requires root access; imports (create only) from small CSV
files within the WuttaPOS code base.
"""
# only root gets to do this
if not self.request.is_root:
raise self.forbidden()
# we can't (yet?) tell the importer to import "everything"
# because it will think that means "all models" as opposed to
# "all files" found, and that raises error for missing files.
# so we first inspect the folder to see what's there.
models = []
samples = self.app.resource_path("wuttapos:sample-data")
# nb. should use root_dir param for glob() but requires python 3.10
for path in glob.glob(os.path.join(samples, "*.csv")):
name, ext = os.path.splitext(os.path.basename(path))
models.append(name)
# import all CSV files found in wuttapos/sample-data, but only
# allow new records to be created, never update/delete
try:
handler = self.app.get_import_handler("import.to_wutta.from_csv")
models = [name for name in models if name in handler.importers]
kw = dict(input_file_path=samples, allow_update=False, allow_delete=False)
handler.process_data(*models, **kw)
except Exception as err:
log.warning("failed to install sample data", exc_info=True)
self.request.session.flash(
f"Install failed: {self.app.render_error(err)}", "error"
)
else:
self.request.session.flash("Sample data has been installed.")
return self.redirect(self.get_index_url())
@classmethod
def defaults(cls, config): # pylint: disable=empty-docstring
""" """
cls._defaults(config)
cls._appinfo_defaults(config)
cls._wuttapos_defaults(config)
@classmethod
def _wuttapos_defaults(cls, config):
route_prefix = cls.get_route_prefix()
permission_prefix = cls.get_permission_prefix()
url_prefix = cls.get_url_prefix()
# install sample data
config.add_route(
f"{route_prefix}.install_sample_data",
f"{url_prefix}/install-sample-data",
request_method="POST",
)
config.add_view(
cls,
attr="install_sample_data",
route_name=f"{route_prefix}.install_sample_data",
)
def defaults(config, **kwargs): # pylint: disable=missing-function-docstring
local = globals()
AppInfoView = kwargs.get("AppInfoView", local["AppInfoView"])
base.defaults(config, **{"AppInfoView": AppInfoView})
def includeme(config): # pylint: disable=missing-function-docstring
defaults(config)