Add more docs for Feature Layer

not complete, but progress..
This commit is contained in:
Lance Edgar 2022-03-20 13:57:06 -05:00
parent f2fd88fc63
commit db50895459
40 changed files with 998 additions and 14 deletions

BIN
docs/_static/batch-pattern.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View file

@ -23,7 +23,7 @@ master_doc = 'index'
# -- Project information ----------------------------------------------------- # -- Project information -----------------------------------------------------
project = 'Rattail Manual' project = 'Rattail Manual'
copyright = '2021, Lance Edgar' copyright = '2021-2022, Lance Edgar'
author = 'Lance Edgar' author = 'Lance Edgar'

View file

@ -20,6 +20,10 @@ of a batch however do belong to the Data Layer, so are described here.
Beyond that vague conceptual definition, a "batch" in Rattail also implies the Beyond that vague conceptual definition, a "batch" in Rattail also implies the
use of its "batch framework" - meaning there is a "batch handler" involved etc. use of its "batch framework" - meaning there is a "batch handler" involved etc.
And here is something hopefully worth 1000 words:
.. image:: /_static/batch-pattern.png
Batch Workflow Batch Workflow
-------------- --------------

View file

@ -0,0 +1,6 @@
Cancellations / Other
=====================
TODO: obviously sometimes a customer may cancel their order before it
arrives...then what? i'm sure it depends, as always...

View file

@ -0,0 +1,52 @@
Entry
=====
Entering a new Customer Order into the system is very likely the most
complicated part. Consider:
The "Customer" (or in some cases a "Person") must be identified, whose
order this will be. What if they're a new Customer/Person, not yet in
the system? Can they be added directly to Rattail and other systems
will be updated accordingly? Or must they be first added to the other
system and then imported back to Rattail? (For sake of the order, can
a "Pending Customer" record be created and then sort the rest out
later?)
One or more "Products" will be added to the Order. Can they order
*any* (e.g. unit) amount or is there a "cases only" policy etc.?
Perhaps also some other restrictions based on Department, e.g. no more
than X cases of frozen product due to space limitations.
Where does all that Customer and Product data come from anyway? Is it
accurate enough to be used for creating "reliable" Order data? Is the
Customer to be charged according to whatever price is calculated in
the Order, or are they charged "whatever the POS rings up" etc.? Are
discounts ever quoted in the order, vs. handled only by POS?
Speaking of payments, does the customer need to pay up-front when
first placing the order? Or do they pay later when they pick it up?
Wait, what if they want to order a Product which is not yet in the
system? Is this allowed, and if so what are the policies surrounding
that?
So, the Rattail feature tries to accommodate all of the above
regardless of how you answer.
First of all the Customer/Person and Product data should already be
*imported* to Rattail from your POS or other system(s), before
tackling Customer Orders. This feature assumes the underlying data is
already squared away and accurate (within reason).
Second, it's worth noting that the New Customer Order tool is
implemented as a batch (see also :doc:`/data/batch/native/custorder`).
This is important because it makes it possible to use the New Customer
Order tool as the entry workflow for a Customer Order *even if* you do
not track those primarily in Rattail. In other words when the batch
is executed, it can "push" the Order data to whatever system is
needed.
But of course the Rattail DB has its own schema for tracking these
Customer Orders, so the default "new batch" execution will create the
Order directly in Rattail.

View file

@ -0,0 +1,20 @@
Fulfilment
==========
In the context of Customer Orders, "fulfilment" requires that:
* customer has paid for the product
* customer has possession of the product
* order data reflects these facts
Some places will require the Customer to pay for the Order when they
place it, in which case the first is taken care of already. But if
not, then the physical product can be rang up at POS when they come to
pick up.
If the product is paid for upon pick-up then Rattail has a way to
"automatically detect" that fulfilment has occurred (by monitoring the
POS Transactions). But if payment happens up-front then likely some
User must explicitly indicate to Rattail that fulfilment is complete,
i.e. product was picked up by Customer.

View file

@ -0,0 +1,32 @@
Customer Orders
===============
Presumably all retailers sell products to customers. Most will have a
dedicated point of sale (POS) system for that.
Additionally, some retailers let customers place orders for product
which will arrive in store for pickup at a later date. These are
often referred to as "special orders" or "case orders" etc.
Rattail offers tools to facilitate entry and tracking for such orders,
providing visibility and workflows for their full life cycle.
.. note::
Now that we all know what "COVID" means, online orders with
curbside and delivery options have risen in prominence. For the
moment Rattail does not directly provide features with those in
mind. However this "customer orders" feature is clearly related,
and probably a lot of the schema and/or logic could be shared
between scenarios. But so far only the classic "special/case
order" scenario is being addressed.
.. toctree::
:maxdepth: 1
entry/index
purchasing/index
receiving/index
fulfilment/index
cancellation/index
reporting/index

View file

@ -0,0 +1,12 @@
Purchasing
==========
In the context of Customer Orders, our concern here is making sure the
Buyer knows about them and includes them in the Purchase Order(s)
which they are already placing to the Vendor per normal procedure.
TODO: this has been implemented a couple of different ways thus far
but the "best" has yet to be decided...in particular (how) should the
customer orders and purchase orders be linked? it is a slight hassle
up front but then can be leveraged during the receiving process...

View file

@ -0,0 +1,15 @@
Receiving
=========
In the context of Customer Orders, our concern here is making sure the
Receiver knows about them and sets them aside while receiving the
Purchase Order, once it's arrived from the Vendor.
Another concern is how/when/who should contact the Customer to notify
them that their order has arrived. If the Customer account has a
valid email address on file then perhaps they are emailed
automatically; otherwise an Employee must call their phone number etc.
In either case the *attempt* to contact the Customer should be
recorded somehow, along with notes e.g. indicating if it was
successful.

View file

@ -0,0 +1,52 @@
Reporting
=========
Reporting on Customer Orders data is possible but as of writing is
still being worked out.
The asumption here is that you want to track "sales" which are
attributable to Customer Orders.
The "easiest" way, though potentially inaccurate, is simply to query
the Customer Orders data and assume that if a given Order's "status"
reflects that e.g. it has been paid for, then include it in the
report.
On the other hand the precise amount paid by the customer may or may
not even be in the Customer Order data. Even if it is there, is it
correct, or was it just an "estimate" and really a related POS
Transaction must be consulted for the true price.
However the Order status likely *is* important on some level, to
detect cancellations etc. Presumably if a refund is given, the POS
Transaction would have that amount, but there likely is nothing to tie
that back to the particular Order which was canceled.
So at the moment the focus is on recording "links" between a given
Customer Order and POS Transaction. This is done by way of a
Trainwreck DB (see also :doc:`../../transactions/importing/index`):
A transaction is imported to Trainwreck as per usual, but in addition
to the normal stuff, the transaction is inspected for any "indicators"
of Customer Orders. (Often the cashier scans or enters some ID for
the Order when ringing it up.) Such indicators are then stored in a
dedicated place within Trainwreck. This takes care of the "high
level" meaning we now have links between a POS Transaction and
Customer Order.
But really, a POS Transaction has "line items" and so does a Customer
Order. So we actually need a link between the relevant line items.
The line item links are established in a second phase. So the first
phase is focused on importing POS Transaction data, and we've done
that. But now Trainwreck has all those line items and so the
item-level reconciliation can be done "natively". Again we already
have the high-level links, so we fetch a linked pair (Transaction and
Order) and then crawl each to identify item-level links, and record
any which are found.
Once that is complete, a Customer Orders report can more easily obtain
accurate payment amounts from the POS Transaction data (although it
reads from Trainwreck instead for convenience). And of course it can
still leverage the Customer Order status etc. as needed.

View file

@ -2,15 +2,19 @@
Feature Layer Feature Layer
============= =============
Here we'll try stay "high level" and describe some of the features Here we'll try to stay "high level" and describe some of the features
which are provided by the Rattail framework, in a more or less "ready which are provided by the Rattail framework, in a more or less "ready
to go" state for use in your app. to go" state for use in your app. We'll also describe some
"potential" features to consider, depending on your needs.
Note that this section is not very far along yet..
While technically the Rattail framework can be used for "any"
application, the following features reflect its retail roots.
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
:caption: Contents:
people/index
products/index
purchasing/index purchasing/index
transactions/index
custorders/index

View file

@ -0,0 +1,64 @@
Customers
=========
In many cases it's best for Customer data to live in Rattail (usually
in addition to POS, which is considered the authority). But possibly
not, so let's first look at *why* you might want/need to have it in
Rattail.
And quickly even before that, let's just say that we're defining a
"Customer" simply as a "patron" (shopper) of the retailer. In some
cases Customer data is held not only in POS but also in a separate CRM
system, etc. Your own definition of "Customer" is free to vary a bit
in terms of how you must represent real-world concerns.
If your POS does not expose a web app, then often there will only be a
few machines which can be used for account lookup etc. Rattail web
app can let you view this data directly (if it can be accessed via
SQL), i.e. *without* importing it to Rattail. However such
"dedicated" views for various tables in other systems are not given a
lot of priority in terms of aesthetic or utility.
Importing the data to Rattail means the web app can show you the data
in (hopefully) the "best" way. That's obviously a loaded term but
what is meant here, is that the views for native Rattail data are
given the most attention and are what various other features are built
on top of.
So if we assume you *are* importing Customer data into Rattail, then
what? You can view it, but can/should you edit it? That again
depends on whether or not you can (or how difficult it is to) export
the changes back to the source (or other) systems. It's *possible*
for instance, to allow edits in Rattail web app, which then are
automatically synced back to the POS in real-time (by a separate
datasync daemon process). But that is a more advanced topic, and in
most cases, at least in the beginning, you should only edit data in
one system, which likely is *not* Rattail.
If you want to track *extra* data for Customer records in Rattail,
then things change again. You *would* (probably) want to import the
data to Rattail, *not* allow edit for that particular data, but then
*do* allow edit for only the "extra" fields. With this approach you
get to start tracking that data while avoiding the need to export
anything back to POS etc. Reports can be created in Rattail which
leverage data from both systems.
And speaking of "extra data" - that is essentially what is happening
with the Customer Orders feature in Rattail. Underlying it is the
Customer record itself, which was likely imported from POS, but then
when an order is created, that is just extra data on top which never
needs to be synced back to the POS. See also
:doc:`../../custorders/index`.
Finally again there is the concept of :doc:`../entry/batches`. In
fact when creating a new Customer Order, really you are creating a
batch and then adding items to it, finally "executing" which submits
the order for further processing. But batch logic can be crafted to
do anything you need with regard to Customer data maintenance. And in
some cases a Customer-related batch may be more "accurate" if it does
*not* use Rattail data but instead reads directly from the source
(e.g. POS) when making the batch. Also a "New Customers" batch by
definition would contain data not yet "in the system" - so importing
the data to Rattail is not a requirement in order to use batch
features generally.

View file

@ -0,0 +1,32 @@
Employees
=========
Employee data normally comes from the POS, if it indeed comes into
play at all. You may or may not have a reason to import or otherwise
act on Employee data using Rattail.
It is the User record in Rattail which is given attribution for
changes made etc. and not the Employee. So even if a certain User is
also an Employee, when logged in and making changes their User account
is deemed responsible.
Whereas a User record does not technically need to tie back to a
Person record, an Employee record *must* tie back to a Person. When
importing Employee data from POS, both the Person and Employee records
are created in Rattail.
There are certain places where an Employee *is* assumed, for instance
the "Buyer" of a Purchase Order will reference an Employee record and
not a User. Whereas the creation and execution of a "batch" related
to purchasing will reference a User. (See also
:doc:`../../purchasing/index`.)
Rattail could also be used as a "time clock" system in which case the
Employee records must obviously be present, for tracking times.
You also can use Rattail to track additional info for each Employee,
e.g. the start/end dates for their employment over time. Often an
employee might come and go more than once, and the POS will rarely
have a way to track historical dates. Rattail has a basic way to do
that built-in, but more "data extensions" are of course possible.

View file

@ -0,0 +1,36 @@
Batches
=======
Batches are a sort of hybrid of import/edit/export. They assume a
certain "data set" will be brought into a dedicated workspace, using
whatever (sometimes custom) logic, then the user previews the
"results" before committing to it. See also :doc:`/data/batch/index`.
For instance one common type of batch is for new Customer entry.
Maybe there is a web form which some users fill out to enter new
Customer records, but in fact those go into a "queue" / batch and are
not truly injected to the system proper until the batch is reviewed
and executed by some (possibly more highly authorized) user. This can
be helpful not only for workflow optimization but also custom data
validation, and/or preventing duplicates from entering the system.
Another type might be for a periodic import to "sync" 2 systems which
do not normally stay in sync. For instance if your POS and CRM do not
stay in sync all the time, but maybe once a month you export the data
from one system to Excel file, for import to the other. It is of
course possible to make a Rattail "importer" (or "exporter" depending
on your perspective) which could automate this. But for sake of
better visibility and instilling confidence in the logic, you might
prefer a batch.
In the above example the process might be like:
* export data from CRM to Excel
* upload file as new batch in Rattail
* preview the changes; execute the batch
* which generates yet another file, e.g. CSV
* which you then import to the POS
There are many possibilities here; for instance more likely the batch
writes directly to POS when executed.

View file

@ -0,0 +1,32 @@
Editing
=======
Rattail makes it possible to edit most data it contains regardless of
its nature. This of course includes Person-related data.
However just because you *can* edit data in Rattail, does not mean you
*should* do so. You must keep in mind, "which system is the
authority?" for any given data point.
In other words if you import Customer records from your POS, but then
do not configure an export mechanism to get any changes made in
Rattail *back* into the POS system, then by far the easiest thing is
to just not allow editing in Rattail. But you still can view the
data, and use various app features which leverage the data (e.g.
:doc:`../../custorders/index`).
However if you *do* configure export mechanisms then you may want to
allow editing directly in Rattail. This can be any data point which
is supported by the export mechanism. For instance if you allow
editing of a Customer name in Rattail, the change could be synced back
to POS.
But it's also possible for Rattail to contain "more" data than the
source (e.g. POS) system does. For instance your POS DB may have a
field to track the "birthday" for each Customer, but maybe you also
need to track their "favorite color" and the POS DB does not provide a
way to do that. In this case you can import Customer records from POS
into Rattail, and then allow editing in Rattail only for the "favorite
color" field. Best of both worlds, you can now track whatever you
want with no need to export data back to the source system.

View file

@ -0,0 +1,42 @@
Exporting
=========
Once you have Person-related data in Rattail, you can export it
"anywhere else" you need. This may be an Excel file, SQL DB, web API
etc. but for the sake of this discussion we'll assume data is to be
exported back to the POS system.
In fact the export features do not require you to first import the
data to Rattail. Every export that could be done "from Rattail DB"
could also be done e.g. "from POS DB". For instance that's exactly
what happens when data is imported from the POS into Rattail, it is
just another way of saying "export from POS to Rattail" and therefore
you can export straight from your POS to e.g. some web API for mailing
list or online shopping etc.
An export is "reading" data from e.g. Rattail or POS DB, and then
"writing" it somewhere else. The reading part is pretty
straightforward but the writing part may have limitations depending on
your target. As a rule Rattail is willing to read directly from a SQL
DB but will always write data via some more "official" route,
i.e. documented API. Which means the writing "possibilities" are
limited to what the API exposes. Whereas exporting to e.g. Excel file
would not have such a limitation, but may have others (e.g. file
size).
So how is data exported back to the POS specifically, for example?
That definitely will depend on your POS system, and as of writing only
3 are well supported.
If you're lucky enough to run a SIL-compliant POS then a great deal is
possible; Rattail can generate SIL files which add/modify data of
nearly any kind.
If your POS exposes a web API then Rattail can use that to write some
data. At this point in time these are rather limited though.
If writing directly to POS SQL DB is an option for you, then Rattail
can certainly accommodate. It should be stressed that this is **not
ideal** as it would likely bypass any data validation, audit trail
etc. that the POS may be doing were an official channel used instead.

View file

@ -0,0 +1,27 @@
Importing
=========
The most common scenario involves Rattail importing most
Person-related data from other (e.g. POS or CRM) systems.
However it should be noted that Rattail is meant to live "alongside"
the other systems, it is not normally going to "replace" them - and
this means Rattail must *continually* import data from the other
systems, to remain accurate. This may be done nightly, or hourly, or
even in "real-time" (e.g. once every few seconds, or 5 minutes) -
whatever is needed and/or is possible given the system constraints.
One immediate feature that comes "for free" when importing data into
Rattail, is its versioning history, aka. audit trail. Each time an
import actually *changes* a record in Rattail, the new data is
separately stored as a "version" record along with the timestamp and
the "user" who made the change. In the case of import, the "user" is
the system from which data is being imported; a dedicated User account
is created for this purpose (which does not tie back to any Person).
We're talking here of importing data from e.g. POS into Rattail. But
if it's also possible to "import" e.g. new Customer records into your
POS or other system, then Rattail can also be used as a workflow tool
to assist with organizing new records for import to your other system.
See :doc:`batches` for more about that.

View file

@ -0,0 +1,16 @@
Entry
=====
Here we'll discuss how various Person-related records are first
entered into the system, and how they are maintained going forward.
.. toctree::
:maxdepth: 1
overview
importing
editing
exporting
batches
merging

View file

@ -0,0 +1,44 @@
Merging
=======
Rattail ostensibly supports merging any 2 records, of any kind. But
the devil is always in the details...
In most cases a merge involves:
* inspect differences between 2 records
* choose which one to "keep" vs. "remove"
* perform the merge, which:
* may *update* the "keep" record, with certain data from the "remove" record
* then *deletes* the "remove" record
For some things this can be pretty straightforward, for instance if
your User records are maintained only in Rattail and aren't imported
from elsewhere, then a merge of 2 User records could by definition
only affect Rattail anyway.
Although even that example can be tricky, because a User is often
involved in some audit trail(s) of various other data records. In
such cases Rattail can update the historical records to reflect the
new "keep" User record; but in practice there may be edge cases as yet
unexplored.
Customer and Employee records etc. can present more of a challenge,
because often that data lives in multiple systems. The question
becomes, what should a merge actually *do*, i.e. what should the
ideal outcome be?
In particular your POS may have 2 customer records which you'd like to
merge, but even if your ideal outcome is for one of them to be deleted
(i.e. typical use case described above), the problem of historical
data may come up again. Often times both of the customer records will
already have accrued some transaction history within your POS, and it
may not be possible or practical to correct those with the new
("keep") customer reference.
But the merge tool is meant to be as flexible as is reasonable. Your
merge logic might be able to go ahead with certain "simple" merges but
then raise an error when complex situations are encountered. Then you
can look more closely at those and see what can be done (if anything).

View file

@ -0,0 +1,32 @@
Overview
========
In most cases the Person-related data already lives in a (e.g. POS)
SQL database and may be queried directly by Rattail. This means you
may view that data directly in the web app.
All of the Person-related records may also be *imported* into Rattail
from other systems, and this is usually the best place to get started;
see :doc:`importing`.
Once the data lives in Rattail you obviously may view it within the
web app (so, reading from Rattail DB instead of POS DB now). But this
also sets the stage for other features which require such data to be
in place; for instance :doc:`../../custorders/index`.
You also may want to allow editing for some or perhaps all aspects;
see :doc:`editing`.
The data (and any changes made via editing, if applicable) may also be
exported back to the source and/or other systems; see
:doc:`exporting`.
Sometimes you need to process a "set" of data, for instance taking an
export file from one system and then preparing it for import to
another system. This is a broad topic; for a starting point see
:doc:`batches`.
Duplicate records are an ongoing problem in many systems, when it
comes to Person-related data. Rattail does allow merging of 2 records
but it can be tricky; see :doc:`merging`.

View file

@ -0,0 +1,53 @@
Household / Shared Accounts
===========================
A common scenario is where a Customer (or Employee, or Member) is able
to "share" benefits of their account, with their immediate household.
There may be other variations but we'll stick with that example here.
Although to clarify, while many e.g. retail food co-ops may consider
the "Household" concept to be an extension of a "Member" account
specifically, Rattail instead considers it a logical extension of the
"Customer" account. This is because the benefits which are extended
to the household normally apply to "shopping" specifically, and
Rattail uses the "Customer" concept to represent that. (Same holds
true for a more traditional retailer which might extend benefits to
the Household of an Employee - the Household will still fall under a
Customer account logically.)
So it might be possible for Rattail to add a broader / more generic
"Household" concept later, but for now it's all about Customers. (And
a Member account is normally tied to a Customer account, so it's not
much more than a difference of semantics.)
Okay! With that out of the way...
Household accounts can be tricky. For instance are these people
actually tracked in your system? (Do they need to be?) If so are
they tracked as separate accounts or just minimal (e.g. name) info
somehow tacked onto the main account? In particular how are the
accounts represented in your POS system?
Rattail can be used to help track e.g. Household-related links between
various Person and/or Customer records. What you do with such links
is up to you of course, but some ideas:
If your POS allows for it, you might have Rattail keep the POS in sync
for (at least certain types of) changes to Household-related accounts.
For instance in the dynamic coupon scenario, let's say you do maintain
separate POS accounts for the "parent" Customer as well as the
Household "shopper". When a coupon is given it may be enabled for
both of the accounts, but then when it is redeemed by either it
becomes disabled for both.
Now, maybe your POS already has a way to link Household accounts, and
even a way to handle the dynamic coupon example. But then that sounds
like you already have a good enough system and don't need Rattail to
be the Household "system" at all. Although it could still be used for
reporting and similar needs, etc.
So if your current situation is "not ideal" then Rattail is here to
help in whatever way it can; however it's difficult to describe the
scenarios it might best be suited for, until more real-world scenarios
are dealt with.

View file

@ -0,0 +1,22 @@
People
======
Rattail considers the Person to be a central concept, which underpins
various other concepts such as User, Customer etc. and ideally ties
them together (e.g. one Person may be both a Customer and Employee).
Rattail can import this data from other (e.g. POS) systems, but it
also can *export* data to other systems. And once this data is in
Rattail it can be used for other features as needed; for instance
:doc:`../custorders/index`.
.. toctree::
:maxdepth: 2
entry/index
users/index
employees/index
customers/index
members/index
household/index

View file

@ -0,0 +1,80 @@
Members
=======
As with Employee and Customer data, the first questions regarding
Member data are: What is it, and what does it have to do with Rattail?
Rattail's concept of a "Member" comes primarily from the world of
retail food co-ops, where a Member is more like a Customer than an
Employee. But there exist also worker co-ops, where a Member is
really more like an Employee. Rattail's Member features are meant to
acommodate both scenarios.
Members often have some equity account associated with them, with join
and (where applicable) withdrawal dates, and usually also a payment
history for the equity.
So if your organization has a membership component, then you most
likely already have some way to track accounts and equity etc. Why
bring it into Rattail?
As usual the first answer is simple visibility. For instance you
might be tracking accounts in a spreadsheet or Microsoft Access, or
any of a number of similar "undesirable" solutions. Even if you
continue with that tracking approach, you also could periodically
import data to Rattail just so it can be more easily viewed by others
via the web app.
And part of visibility is cross-referencing related data. Maybe you
already have a good way to view accounts, but you have no way to view
an account alongside its equity, or perhaps POS Transaction history
etc. Showing the various types of data on one screen (maybe with a
link back to the other system) can be quite helpful in some cases.
Another potential feature is to send email reminders to Members who
have an upcoming payment due, etc. based on their account details.
And it's possible to monitor an IMAP folder for any "bounces" that
result from sending such reminders, in which case can e.g. flag the
account as having a bad email on file.
Similarly a Member account status may dynamically affect which
discounts are available to their Customer account at the POS. This
idea depends on the ability to effect certain changes in the POS
system, e.g. add/remove electronic coupons for an account.
But..everything just stated is technically possible *without*
importing the data to Rattail. So still at this point we've not
established a good reason to actually import it.
You can of course create batches for performing account maintenance in
whatever way is needed. Same general "rules" apply as for other
(e.g. Customer) tables. Member data need not be imported into Rattail
in order to use the batch features.
But unlike the Customer data, where the POS is frequently the obvious
"authority", many times Member data is *not* tracked (well) by the
POS, and so custom spreadsheet workflows or similar tactics are
employed to keep track of it.
So this finally is why you *might* want to import it into Rattail.
Any tasks being managed via spreadsheet workflows (or whatever) can
instead be managed directly in the web app.
If you choose this route, a couple of implications:
Rattail becomes your primary Member system, and you (presumably /
ideally) no longer need your previous system for that, other than to
keep it as an archive.
Data is maintained directly in the web app, for instance creating a
new Member account, or withdrawing one etc. Also equity payments
could be entered directly if they happen outside of the POS, e.g. when
someone mails a check.
But equity payments still likely will happen in the POS also. And for
this to work "seamlessly" it means Rattail must monitor the POS
Transactions which occur, at whatever frequency is acceptable. Near
real-time is possible and in some cases necessary for sake of dynamic
coupons etc. But in other cases a nightly processing of the previous
day's transactions may be sufficient.

View file

@ -0,0 +1,39 @@
Users
=====
Users are a bit unique in the realm of Person-related data, because
it's often the case that they are *not* imported from some other
system, being instead maintained only in Rattail. (Of course it *is*
still possible to import User records from another system.)
When you first setup a Rattail system you create the first "admin"
User. You then login as that User and can create other Users as
needed, depending on who needs access. For more info see also
:doc:`/data/auth`.
It's possible to tie a User record to a Person record, although
technically not required. It is recommended since it opens up other
possibilities, for instance the app might present different features
based on some other related aspects e.g. of the Employee record of the
current User.
It's also common to create dedicated User accounts to represent the
other systems involved, e.g. your POS. Such accounts do not tie back
to any Person and exist only for sake of attributing changes to the
applicable system, when data is imported to Rattail.
The username for each User must be unique. Passwords are stored using
1-way encryption, so are not recoverable and must be reset if lost.
It is possible to authenticate users against something other than
Rattail, instead of or in addition to normal Rattail authentication.
For instance it can check LDAP, or a corresponding employee table in
your POS DB (e.g. if those credentials are stored as plain text).
It is also possible for Rattail to auto-create users upon first login,
if authenticating from another system like that. If your permissions
are setup such that *any* "authenticated" (i.e. logged in) user has
access to certain features, this may be a useful option for you. In
some cases you may also need to add logic to auto-assign the
newly-created user to some particular role(s) based on whatever...

View file

@ -0,0 +1,5 @@
Entry
=====
TODO

View file

@ -0,0 +1,14 @@
Products
========
stuff here
.. toctree::
:maxdepth: 1
entry/index
vendors/index
pricing/index
labels/index
inventory/index

View file

@ -0,0 +1,5 @@
Inventory
=========
TODO

View file

@ -0,0 +1,5 @@
Labels
======
TODO

View file

@ -0,0 +1,5 @@
Pricing
=======
TODO

View file

@ -0,0 +1,5 @@
Vendors / Catalogs
==================
TODO

View file

@ -2,4 +2,7 @@
Accounting Accounting
========== ==========
TODO TODO: while this is "virtually" supported as a 3rd phase, it has not
been "fully" implemented in production. in practice the 2nd
(receiving) phase is taking care of accounting duties thus far. see
also :doc:`../receiving/accounting`.

View file

@ -1,16 +1,21 @@
Purchasing Purchase Orders
========== ===============
Presumably all retailers purchase products from vendors. Presumably all retailers purchase products from vendors.
Rattail offers tools to assist with the various workflows involved. Rattail offers tools to assist with the various workflows involved.
It splits the life cycle into 3 "phases" - although some purchases may It splits the life cycle into 3 "phases" - Ordering, Receiving,
not explicitly go through every phase. In particular it's possible Accounting.
for the Receiving phase to include everything Accounting does.
Some purchases may not explicitly go through every phase. In
particular it's possible for the Receiving phase to include everything
Accounting does, and in many cases Ordering is skipped (wrt the
system), with the PO first "entering the system" in the Receiving
phase.
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 2
ordering/index ordering/index
receiving/index receiving/index

View file

@ -0,0 +1,22 @@
Adding Items
============
When creating a new Purchase Order using Rattail, the user first makes
a new Ordering batch, then adds items to it.
There are three main "workflows" for adding the items.
The first is where the user sees the (at first empty) batch and then
does some sort of product lookup to identify an item to add. The
lookup/add process is repeated as needed.
The other way is what Rattail calls the "worksheet view" - but it's
only suitable for vendors with relatively small product lines. In
this view the user is presented with a "worksheet" form. All items
available from the vendor are visible on the worksheet, and the user
enters desired quantities for applicable line items.
There also is a mobile interface for ordering, which if used on a
smart phone with bluetooth scanner attached, can be used for
"in-aisle" ordering by scanning shelf tags.

View file

@ -0,0 +1,21 @@
Converting a PO
===============
This is given its own section just to better clarify.
The "purpose" of an Ordering batch in Rattail can vary. Presumably
the most common use is to actually assemble a new PO, to be submitted
to the vendor.
But this batch type can also be used to "convert" any arbitrary PO
data, to any other format/system. You might have multiple different
ordering "systems" which vary by vendor etc. If so then you could
process PO data from each of these, as separate Ordering batches.
Executing each batch would then produce whatever output you needed for
them to be in a "common" format etc.
Probably the most common scenario for this is where you want to import
the PO data into your POS system. This lets it know that the product
is "on order" and will be what receiving happens against, once the
order arrives from the vendor.

View file

@ -0,0 +1,22 @@
Batch Execution
===============
Often the user will have made an Ordering batch and added items to it
"manually" when assembling their order.
But in some cases the PO data will have been imported from some other
system, or perhaps a CSV file, with the goal being just to get it into
the POS system.
Regardless of how the batch data was obtained (e.g. from file, or user
input), ultimately the batch will be executed. So what does that do?
This basically depends on what you need it to do... For instance in
the CSV file example just mentioned, if your goal is merely to get the
PO data into the POS system, then that's what executing the batch
should do.
It is possible also to make batch execution actually "submit"
(e.g. email) the purchase order to the vendor, although this is less
common in practice.

View file

@ -2,4 +2,12 @@
Ordering Ordering
======== ========
TODO All about *ordering* product from the vendor.
.. toctree::
:maxdepth: 3
overview
additems
execution
convertpo

View file

@ -0,0 +1,27 @@
Overview
========
Ordering is when the retailer expresses to the vendor, their interest
in purchasing some of their product for resale to their customers.
The retailer promises to pay for the product, so the vendor should
ship it to them ASAP.
If the retailer has things "dialed in" then ordering may be fully or
partially automatic, aka. "suggested ordering" where the purchase
order is auto-generated based on current inventory levels.
Rattail does not (yet?) offer any tools for suggested ordering. It
does though offer tools for the more classic scenario, where the buyer
"manually" assembles the purchase order.
It does this using a batch. The buyer creates a new Ordering batch
for the given vendor, and then adds items to it.
Adding items may be done in a few ways. These are discussed in
:doc:`additems`.
One way or another the batch is populated, then ultimately executed.
Read more about that in :doc:`execution`.
We also share some thoughts here, on :doc:`convertpo`.

View file

@ -0,0 +1,47 @@
Importing
=========
So, the POS is ringing transactions but now you want to *import* those
to another system? Why?
The most frequent "use" for transaction data is probably to report on
sales trends etc. That is covered more in the next section,
:doc:`../reporting/index`. And commonly, it is done directly from the
POS DB.
But there are other uses for the data, and even if reporting is your
*only* use, it still may be helpful to import it first, as will
(hopefully) be explained.
Rattail has a separate / dedicated DB for this scenario, meant to
contain only POS (and similar) transaction data. This is referred to
as the "Trainwreck" DB; see also :doc:`/data/trainwreck`.
If you *do* import transaction data then here are some implications:
* you ultimately decide the schema, though default is likely sufficient
* schema is ideally *simpler* than "raw" POS transaction data
* (in some cases POS transaction data is not even in SQL DB, but a file)
* SQL reporting can then happen on the (simple!) Trainwreck data
But those are just the obvious ones; here are some more advanced:
* additional calculations may be made, e.g. custom "patronage" amount
for each transaction
* other data points known at time of transaction, may be recorded
within it; e.g.:
* current account status of customer or member
* current [sub]department of each product sold
* "links" between transaction/items and related customer order(s)
* (this makes reporting on the Customer Orders possible, or at
least much easier!)
* transaction may later be "re-assigned" to a [different] customer,
with subsequent reports reflecting the change
* (e.g. for attributing patronage to correct member for annual refund)

View file

@ -0,0 +1,17 @@
POS Transactions
================
Presumably all retailers have a dedicated point of sale (POS) system
which is where most if not all transactions occur.
Rattail is not and likely will never be a POS system, so it's not
concerned with faciliating the transaction, but rather in "harvesting"
its data for whatever purposes you may have.
.. toctree::
:maxdepth: 1
importing/index
reporting/index

View file

@ -0,0 +1,57 @@
Reporting
=========
Reporting on POS Transaction data is obviously standard practice.
Almost certainly your POS system already provides a way to do that.
Rattail considers its job here to be, "make more things more easily
possible" - which is only needed if your existing reports are lacking
in some way. Some specific goals here include:
If your POS Transaction data is already held in a SQL database, which
you can query, then the "hardest" part of a report really should just
be crafting the SQL query. For the common use case of generating an
Excel file with report data, Rattail can provide basically everything
but the SQL statement.
Reports available to Rattail may be generated via the web app. A
report may accept/require certain parameters, which the user provides
when generating.
When a report is generated the output file is "saved" for later
viewing in the web app, along with details of who generated it etc.
It's possible to automate report generation, although at this time it
can't be done via web app.
So that's why you might want to use Rattail for reporting on POS
Transaction data generally. But it's often the case that the "raw"
(native) schema for POS Transaction data is a bit complex, and this
can make crafting the SQL queries difficult.
Additionally, the POS Transaction data may not even be in a SQL DB to
begin with; some store it in a file, e.g. XML.
And not to mention, this data may not even have everything you need
for your report. You may need to query additional systems etc. to
supplement the transaction data in order to "complete" the report.
So first of all that is of course possible. Any report can read data
from any "normal" place - SQL DB, file, web API, etc. and combine such
data as needed.
But in the case of POS Transactions specifically, the process of
reading data from disparate sources and combining, can be "expensive"
in terms of compute power/time. Also you *may* need to do essentially
the same thing for multiple reports.
And this is where Trainwreck comes in - the idea being that you
*import* the POS Transactions data from the source, into the
Trainwreck DB. It's a *little* like running a one-time report to
"translate" the transaction data into a simpler format, with all
supplemental data merged in as needed.
Once the data is in Trainwreck you can write reports against that to
your heart's content. They will get to query a simpler schema and all
that extra data is right there with it.