diff --git a/docs/_static/truck-dump-rows.png b/docs/_static/truck-dump-rows.png new file mode 100644 index 0000000..5e3d7b7 Binary files /dev/null and b/docs/_static/truck-dump-rows.png differ diff --git a/docs/_static/truck-dump.png b/docs/_static/truck-dump.png new file mode 100644 index 0000000..e40e228 Binary files /dev/null and b/docs/_static/truck-dump.png differ diff --git a/docs/features/index.rst b/docs/features/index.rst new file mode 100644 index 0000000..576d038 --- /dev/null +++ b/docs/features/index.rst @@ -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 diff --git a/docs/features/purchasing/accounting/index.rst b/docs/features/purchasing/accounting/index.rst new file mode 100644 index 0000000..92c890b --- /dev/null +++ b/docs/features/purchasing/accounting/index.rst @@ -0,0 +1,5 @@ + +Accounting +========== + +TODO diff --git a/docs/features/purchasing/index.rst b/docs/features/purchasing/index.rst new file mode 100644 index 0000000..165a0f5 --- /dev/null +++ b/docs/features/purchasing/index.rst @@ -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 diff --git a/docs/features/purchasing/ordering/index.rst b/docs/features/purchasing/ordering/index.rst new file mode 100644 index 0000000..45cd73b --- /dev/null +++ b/docs/features/purchasing/ordering/index.rst @@ -0,0 +1,5 @@ + +Ordering +======== + +TODO diff --git a/docs/features/purchasing/receiving/accounting.rst b/docs/features/purchasing/receiving/accounting.rst new file mode 100644 index 0000000..e1336d4 --- /dev/null +++ b/docs/features/purchasing/receiving/accounting.rst @@ -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. diff --git a/docs/features/purchasing/receiving/index.rst b/docs/features/purchasing/receiving/index.rst new file mode 100644 index 0000000..d713a5e --- /dev/null +++ b/docs/features/purchasing/receiving/index.rst @@ -0,0 +1,12 @@ + +Receiving +========= + +All about *receiving* product which was ordered from the vendor. + +.. toctree:: + :maxdepth: 3 + + overview + workflows + accounting diff --git a/docs/features/purchasing/receiving/overview.rst b/docs/features/purchasing/receiving/overview.rst new file mode 100644 index 0000000..ee425dd --- /dev/null +++ b/docs/features/purchasing/receiving/overview.rst @@ -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. diff --git a/docs/features/purchasing/receiving/workflows.rst b/docs/features/purchasing/receiving/workflows.rst new file mode 100644 index 0000000..7a30c6b --- /dev/null +++ b/docs/features/purchasing/receiving/workflows.rst @@ -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. diff --git a/docs/index.rst b/docs/index.rst index 5b393f9..2f1de20 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -15,6 +15,7 @@ the `Rattail Tutorial`_. This manual is primarily organized around the possible "layers" of a Poser/Rattail app: +* :doc:`features/index` - app features provided by the framework * :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:`web/index` - all things web @@ -38,6 +39,7 @@ this document. readfirst quickstart background + features/index base/index data/index web/index