Add basic docs for "receiving" feature
This commit is contained in:
parent
3a21610219
commit
f2fd88fc63
BIN
docs/_static/truck-dump-rows.png
vendored
Normal file
BIN
docs/_static/truck-dump-rows.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
docs/_static/truck-dump.png
vendored
Normal file
BIN
docs/_static/truck-dump.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
16
docs/features/index.rst
Normal file
16
docs/features/index.rst
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
Feature Layer
|
||||||
|
=============
|
||||||
|
|
||||||
|
Here we'll try stay "high level" and describe some of the features
|
||||||
|
which are provided by the Rattail framework, in a more or less "ready
|
||||||
|
to go" state for use in your app.
|
||||||
|
|
||||||
|
Note that this section is not very far along yet..
|
||||||
|
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:caption: Contents:
|
||||||
|
|
||||||
|
purchasing/index
|
5
docs/features/purchasing/accounting/index.rst
Normal file
5
docs/features/purchasing/accounting/index.rst
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
Accounting
|
||||||
|
==========
|
||||||
|
|
||||||
|
TODO
|
17
docs/features/purchasing/index.rst
Normal file
17
docs/features/purchasing/index.rst
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
Purchasing
|
||||||
|
==========
|
||||||
|
|
||||||
|
Presumably all retailers purchase products from vendors.
|
||||||
|
|
||||||
|
Rattail offers tools to assist with the various workflows involved.
|
||||||
|
It splits the life cycle into 3 "phases" - although some purchases may
|
||||||
|
not explicitly go through every phase. In particular it's possible
|
||||||
|
for the Receiving phase to include everything Accounting does.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
ordering/index
|
||||||
|
receiving/index
|
||||||
|
accounting/index
|
5
docs/features/purchasing/ordering/index.rst
Normal file
5
docs/features/purchasing/ordering/index.rst
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
Ordering
|
||||||
|
========
|
||||||
|
|
||||||
|
TODO
|
32
docs/features/purchasing/receiving/accounting.rst
Normal file
32
docs/features/purchasing/receiving/accounting.rst
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
|
||||||
|
Accounting for Receiving
|
||||||
|
========================
|
||||||
|
|
||||||
|
Rattail provides a separate phase entirely for accounting (see
|
||||||
|
:doc:`../accounting/index`) but in practice it is often lumped into
|
||||||
|
the receiving phase. So here we'll describe how it works in
|
||||||
|
receiving.
|
||||||
|
|
||||||
|
|
||||||
|
The Basics
|
||||||
|
----------
|
||||||
|
|
||||||
|
Where some of the data comes from will depend on the receiving
|
||||||
|
workflow, but in general here is what we're concerned with, for *each*
|
||||||
|
individual line item:
|
||||||
|
|
||||||
|
* case size
|
||||||
|
* case cost
|
||||||
|
* unit cost
|
||||||
|
* cases received
|
||||||
|
* units received
|
||||||
|
* total cost
|
||||||
|
|
||||||
|
Ideally only the "cases/units received" amounts are provided by the
|
||||||
|
user, with all other values being read from PO and/or invoice file.
|
||||||
|
|
||||||
|
Although we also must consider credits for damaged, expired, not
|
||||||
|
shipped etc.
|
||||||
|
|
||||||
|
The "total cost" is normally calculated by multiplying received
|
||||||
|
quantities by cost. It is reduced by any credits present.
|
12
docs/features/purchasing/receiving/index.rst
Normal file
12
docs/features/purchasing/receiving/index.rst
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
Receiving
|
||||||
|
=========
|
||||||
|
|
||||||
|
All about *receiving* product which was ordered from the vendor.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 3
|
||||||
|
|
||||||
|
overview
|
||||||
|
workflows
|
||||||
|
accounting
|
40
docs/features/purchasing/receiving/overview.rst
Normal file
40
docs/features/purchasing/receiving/overview.rst
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
|
||||||
|
Overview
|
||||||
|
========
|
||||||
|
|
||||||
|
Receiving happens when an order is delivered to the retailer after
|
||||||
|
being shipped from the vendor. In most cases an invoice will
|
||||||
|
accompany the order. Depending on the retailer, in some cases the
|
||||||
|
purchase order will already exist, e.g. in Rattail or the POS system.
|
||||||
|
|
||||||
|
Rattail considers the primary concerns for this phase to be:
|
||||||
|
|
||||||
|
* update inventory counts
|
||||||
|
* (optional) record costs from invoice
|
||||||
|
* (optional) request credits from vendor
|
||||||
|
* (optional) detect/highlight other anomalies
|
||||||
|
|
||||||
|
Note that recording costs is "optional" mostly because that can be
|
||||||
|
handled in a separate third phase; see
|
||||||
|
:doc:`/features/purchasing/accounting/index`. Vendor credits are not
|
||||||
|
always applicable but often will be. Anomalies refers to anything you
|
||||||
|
want it to, e.g. if a product cost has increased too much.
|
||||||
|
|
||||||
|
Receiving is done via batch. The user creates a batch via one of the
|
||||||
|
supported workflows:
|
||||||
|
|
||||||
|
* From Scratch - aka. just start scanning items
|
||||||
|
* From Invoice - upload invoice file, then scan "against" it
|
||||||
|
* From Purchase Order - choose existing PO, then scan against it
|
||||||
|
* From Purchase Order, with Invoice - choose PO *and* upload invoice
|
||||||
|
file, scan against it
|
||||||
|
|
||||||
|
We say "scan" above, as it is possible to do these tasks with a mobile
|
||||||
|
phone and bluetooth scanner. But paper-based receiving is also a
|
||||||
|
supported method; in this case after paper check-in has been
|
||||||
|
completed, user would "auto-update" all line items to be "received"
|
||||||
|
and then *undo* that for any exceptions (credits).
|
||||||
|
|
||||||
|
The user then will review the batch, add/modify line items as
|
||||||
|
appropriate. Once satisfied that all data is correct, batch is
|
||||||
|
executed, which typically will update the master purchase record etc.
|
231
docs/features/purchasing/receiving/workflows.rst
Normal file
231
docs/features/purchasing/receiving/workflows.rst
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
|
||||||
|
Receiving Workflows
|
||||||
|
===================
|
||||||
|
|
||||||
|
Here we describe the workflows for "receiving" product, which are
|
||||||
|
supported by Rattail.
|
||||||
|
|
||||||
|
At a fundamental level there are just 2 workflows: you can either
|
||||||
|
receive "from scratch" (i.e. starting from nothing) or you receive
|
||||||
|
"against a document" (PO, invoice, both, other).
|
||||||
|
|
||||||
|
In rare cases a special workflow may be needed, which Rattail refers
|
||||||
|
to as "truck dump" - if you can avoid it you should!
|
||||||
|
|
||||||
|
|
||||||
|
Receive From Scratch
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Receiving "from scratch" just means you're starting from nothing,
|
||||||
|
i.e. you have no invoice file to upload and the purchase order does
|
||||||
|
not yet exist in the system.
|
||||||
|
|
||||||
|
So you effectively create an "empty" batch and then must add items to
|
||||||
|
it. This may be done via mobile or desktop interface; scanner is
|
||||||
|
supported for both.
|
||||||
|
|
||||||
|
Executing the batch would typically *create* the (received) purchase
|
||||||
|
order in the system - Rattail or POS etc.
|
||||||
|
|
||||||
|
|
||||||
|
Receive Against a Document
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
Receiving "against a document" just means you actually have some sort
|
||||||
|
of digital representation of the order, and so can use that as the
|
||||||
|
starting point for your batch, then "update" line items.
|
||||||
|
|
||||||
|
This is fundamentally different than "from scratch" which starts with
|
||||||
|
an empty batch and you must *add* all line items.
|
||||||
|
|
||||||
|
Not all documents types are "equal" for this purpose. Specifically,
|
||||||
|
some (e.g. PO) will contain the *ordered* quantities but not the
|
||||||
|
*shipped* quantities (or accurate cost info). However some
|
||||||
|
(e.g. invoice file) will contain shipped quantities and hopefully,
|
||||||
|
accurate cost info.
|
||||||
|
|
||||||
|
|
||||||
|
Purchase Order
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
If the purchase order (PO) already exists in the system, you can
|
||||||
|
choose it after identifying the vendor. The batch is auto-populated
|
||||||
|
with line items from the PO when it is created.
|
||||||
|
|
||||||
|
Note that a purchase order will have *ordered* quantities but not the
|
||||||
|
*shipped* quantites, or accurate cost info. Usually you need a
|
||||||
|
digital invoice file to get the rest of it.
|
||||||
|
|
||||||
|
|
||||||
|
Invoice File
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
If the user has a digital invoice file (with supported format/parser)
|
||||||
|
then they can upload that when making a new batch, and it will be
|
||||||
|
auto-populated with line items from the invoice file.
|
||||||
|
|
||||||
|
Note that an invoice file may have *ordered* and/or *shipped*
|
||||||
|
quantities. If only one is present, usually the other can be inferred
|
||||||
|
from it.
|
||||||
|
|
||||||
|
Most but perhaps not all invoice files will contain accurate cost
|
||||||
|
data. Sometimes the normal wholesale cost is listed in addition to
|
||||||
|
the "true" cost paid for each item, etc.
|
||||||
|
|
||||||
|
As much data as the invoice contains, should go into the initial
|
||||||
|
batch. But it still likely can't provide *everything* and so when
|
||||||
|
possible a purchase order should also be chosen for the batch.
|
||||||
|
|
||||||
|
|
||||||
|
Purchase Order + Invoice File
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
This of course combines the previous two approaches. User must choose
|
||||||
|
an existing PO and also upload an invoice file.
|
||||||
|
|
||||||
|
On a technical level the batch is first populated from the PO line
|
||||||
|
items, and then the invoice data is "overlaid" onto the batch. This
|
||||||
|
will *update* line items found on the PO, but may also *create* new
|
||||||
|
line items which were not on the PO.
|
||||||
|
|
||||||
|
|
||||||
|
Mobile/Scanner-based Receiving
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
There is a mobile-specific app/interface for use with receiving. It
|
||||||
|
assumes you have a mobile smart phone with bluetooth scanner attached
|
||||||
|
in keyboard wedge mode.
|
||||||
|
|
||||||
|
The user opens (or creates) the batch in the mobile app, then starts
|
||||||
|
scanning physical product from the order. They continue until they've
|
||||||
|
scanned everything physically present.
|
||||||
|
|
||||||
|
If receiving "from scratch" then the batch can be executed when
|
||||||
|
scanning is complete.
|
||||||
|
|
||||||
|
If receiving "against a document" then the mobile app will indicate if
|
||||||
|
any product was "missed" - i.e. what was on the document, that was not
|
||||||
|
yet accounted for. Once the user has addressed any discrepancies, the
|
||||||
|
batch may be executed.
|
||||||
|
|
||||||
|
|
||||||
|
Paper-based Receiving
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
If the receiver does a paper-based check-in, then the process changes
|
||||||
|
a bit on the back-end. The user would always create the receiving
|
||||||
|
batch via the desktop interface.
|
||||||
|
|
||||||
|
If receiving "from scratch" then user has to manually key in every
|
||||||
|
line item! Prone to mistakes and labor-intensive; not advised.
|
||||||
|
|
||||||
|
If receiving "against a document" then user will choose/upload the
|
||||||
|
document per usual, which auto-populates the batch. But each line
|
||||||
|
item will assume zero quantity received at first. So user *could*
|
||||||
|
manually key in the amounts from paperwork, but the easier way is to
|
||||||
|
first "auto-receive" all lines and then manually key in only the
|
||||||
|
exceptions.
|
||||||
|
|
||||||
|
Once the batch data is correct, including any "credits" etc. then it
|
||||||
|
may be executed.
|
||||||
|
|
||||||
|
|
||||||
|
"Truck Dump" Receiving
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
We use the term "truck dump" to refer to a specific scenario which,
|
||||||
|
with any luck, you do not have to deal with and can just skip this
|
||||||
|
section...
|
||||||
|
|
||||||
|
Normally you place an order with the vendor and then you receive it.
|
||||||
|
For some vendors (e.g. distributors) you might place multiple orders
|
||||||
|
at the same time, e.g. one per department. Much of the time even in
|
||||||
|
that case when the orders arrive, they are partitioned somehow and can
|
||||||
|
be received independently.
|
||||||
|
|
||||||
|
But, alas, sometimes multiple orders arrive all mixed together and
|
||||||
|
that is a "truck dump" in Rattail terms. It is not possible to receive
|
||||||
|
them independently because of their being mixed up.
|
||||||
|
|
||||||
|
Rattail tries to address this but as of writing this has not seen
|
||||||
|
enough production use to be called stable. Nonetheless we'll describe
|
||||||
|
it here.
|
||||||
|
|
||||||
|
The basic idea is to acknowledge the facts:
|
||||||
|
|
||||||
|
* we want multiple batches, i.e. one per order, but
|
||||||
|
* we have a pile of product that must be processed as one batch
|
||||||
|
|
||||||
|
So we just do both..by creating a "parent" truck dump batch, which
|
||||||
|
will contain all the received quantities, and then also for each
|
||||||
|
actual order we have a "child" truck dump batch, connected to the
|
||||||
|
parent. Each child batch contains the ordered/shipped quantities.
|
||||||
|
But each line item within a child batch is also connected to and
|
||||||
|
"consumes" some amount of the received quantity from corresponding
|
||||||
|
parent batch line item.
|
||||||
|
|
||||||
|
When the dust has settled we should have a fully reconciled data set,
|
||||||
|
i.e. all items from all child batches have either been accounted for
|
||||||
|
or marked for credit.
|
||||||
|
|
||||||
|
Due to all the complexity involved it is not possible to execute a
|
||||||
|
"child" truck dump batch directly. Instead you must execute the
|
||||||
|
parent batch, which will immediately execute all its child batches.
|
||||||
|
|
||||||
|
.. image:: /_static/truck-dump.png
|
||||||
|
|
||||||
|
On a technical level the line items between parent and child batches
|
||||||
|
are linked via a "claim" which indicates how much of the parent item's
|
||||||
|
received quantity has been "claimed" by a given child item.
|
||||||
|
|
||||||
|
And when credits are identified, those also are "linked" between the
|
||||||
|
parent and child items, although not entirely clear from this picture.
|
||||||
|
|
||||||
|
.. image:: /_static/truck-dump-rows.png
|
||||||
|
|
||||||
|
|
||||||
|
From Scratch (aka. "children last")
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
It's possible to start "from scratch" with truck dump receiving, but
|
||||||
|
the caveat is that you *should* have documents (PO and/or invoice)
|
||||||
|
which can be used to "reconcile" the truck dump batches, before it's
|
||||||
|
all said and done. If you do not have documents to define the
|
||||||
|
individual orders then the truck dump parent batch effectively cannot
|
||||||
|
be split up, and you will just be doing "normal from scratch"
|
||||||
|
receiving at that point.
|
||||||
|
|
||||||
|
So in the "truck dump from scratch" workflow then, you start by
|
||||||
|
creating an empty "parent" batch, then start scanning all products
|
||||||
|
found. When all has been scanned, your truck dump parent batch will
|
||||||
|
have no ordered quantities but should have all received quantities.
|
||||||
|
|
||||||
|
Then you must add each of documents as a separate "child" batch under
|
||||||
|
the parent batch. Each document should have either ordered or shipped
|
||||||
|
quantities. Rattail will auto-reconcile each line item where
|
||||||
|
possible, which means taking the received quantites from parent batch
|
||||||
|
and "divvying" them up to the child batches.
|
||||||
|
|
||||||
|
If everything reconciles cleanly then each line item of each child
|
||||||
|
batch should be fully received. If there are gaps etc. then perhaps
|
||||||
|
not everything was delivered and credits should be requested.
|
||||||
|
|
||||||
|
Once everything is reconciled and data looks good, you must execute
|
||||||
|
the parent batch, which will execute all of the child batches.
|
||||||
|
|
||||||
|
|
||||||
|
Against Documents (aka. "children first")
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Since you need to have documents available in order to do truck dump
|
||||||
|
receiving in the first place, it makes sense to define them up-front.
|
||||||
|
|
||||||
|
In this mode then, you create a truck dump "parent" batch first, and
|
||||||
|
then immediately after will create a "child" batch for each order
|
||||||
|
document, under the parent batch.
|
||||||
|
|
||||||
|
At this point you will scan/receive against the parent batch, which
|
||||||
|
should have all line items and order/ship quantities.
|
||||||
|
|
||||||
|
When finished scanning and all is reconciled, you must execute the
|
||||||
|
parent batch, which will execute all of the child batches.
|
|
@ -15,6 +15,7 @@ the `Rattail Tutorial`_.
|
||||||
This manual is primarily organized around the possible "layers" of a
|
This manual is primarily organized around the possible "layers" of a
|
||||||
Poser/Rattail app:
|
Poser/Rattail app:
|
||||||
|
|
||||||
|
* :doc:`features/index` - app features provided by the framework
|
||||||
* :doc:`base/index` - general app install, command line, plus filemon etc.
|
* :doc:`base/index` - general app install, command line, plus filemon etc.
|
||||||
* :doc:`data/index` - when a DB or data import/export come into it
|
* :doc:`data/index` - when a DB or data import/export come into it
|
||||||
* :doc:`web/index` - all things web
|
* :doc:`web/index` - all things web
|
||||||
|
@ -38,6 +39,7 @@ this document.
|
||||||
readfirst
|
readfirst
|
||||||
quickstart
|
quickstart
|
||||||
background
|
background
|
||||||
|
features/index
|
||||||
base/index
|
base/index
|
||||||
data/index
|
data/index
|
||||||
web/index
|
web/index
|
||||||
|
|
Loading…
Reference in a new issue