Changeset - 2f408c18736e
[Not reviewed]
0 4 1
Lance Edgar - 6 years ago 2019-03-08 14:33:01
ledgar@techsupport.coop
Add `ProductVolatile` model, for "volatile" product attributes

at least that's the idea...hopefully this table "wins the war" for this concept
5 files changed with 100 insertions and 1 deletions:
0 comments (0 inline, 0 general)
rattail/db/alembic/versions/5b393c108673_add_product_volatile.py
Show inline comments
 
new file 100644
 
# -*- coding: utf-8; -*-
 
"""add product_volatile
 

	
 
Revision ID: 5b393c108673
 
Revises: 6118198dc4db
 
Create Date: 2019-03-08 13:14:11.645892
 

	
 
"""
 

	
 
from __future__ import unicode_literals, absolute_import
 

	
 
# revision identifiers, used by Alembic.
 
revision = '5b393c108673'
 
down_revision = '6118198dc4db'
 
branch_labels = None
 
depends_on = None
 

	
 
from alembic import op
 
import sqlalchemy as sa
 
import rattail.db.types
 

	
 

	
 

	
 
def upgrade():
 

	
 
    # product_volatile
 
    op.create_table('product_volatile',
 
                    sa.Column('uuid', sa.String(length=32), nullable=False),
 
                    sa.Column('product_uuid', sa.String(length=32), nullable=False),
 
                    sa.Column('true_cost', sa.Numeric(precision=9, scale=5), nullable=True),
 
                    sa.Column('true_margin', sa.Numeric(precision=8, scale=5), nullable=True),
 
                    sa.ForeignKeyConstraint(['product_uuid'], ['product.uuid'], name='product_volatile_fk_product'),
 
                    sa.PrimaryKeyConstraint('uuid')
 
    )
 

	
 

	
 
def downgrade():
 

	
 
    # product_volatile
 
    op.drop_table('product_volatile')
rattail/db/model/__init__.py
Show inline comments
 
@@ -41,13 +41,14 @@ from .employees import (Employee, EmployeePhoneNumber, EmployeeEmailAddress,
 
                        EmployeeStore, EmployeeDepartment, EmployeeHistory)
 
from .shifts import ScheduledShift, WorkedShift
 

	
 
from .vendors import Vendor, VendorPhoneNumber, VendorEmailAddress, VendorContact
 
from .products import (Brand, Tax, Product, ProductImage, ProductCode,
 
                       ProductCost, ProductFutureCost, ProductPrice,
 
                       ProductInventory, ProductStoreInfo, InventoryAdjustmentReason)
 
                       ProductInventory, ProductStoreInfo, ProductVolatile,
 
                       InventoryAdjustmentReason)
 
from .purchase import (PurchaseBase, PurchaseItemBase, PurchaseCreditBase,
 
                       Purchase, PurchaseItem, PurchaseCredit)
 

	
 
from .custorders import CustomerOrder, CustomerOrderItem, CustomerOrderItemEvent
 

	
 
from .messages import Message, MessageRecipient
rattail/db/model/products.py
Show inline comments
 
@@ -842,12 +842,59 @@ class ProductStoreInfo(Base):
 
    recently_active = sa.Column(sa.Boolean(), nullable=True, doc="""
 
    Flag indicating the product has seen "recent activity" at the store.  How
 
    this is populated and/or interpreted is up to custom app logic.
 
    """)
 

	
 

	
 
class ProductVolatile(Base):
 
    """
 
    This is the place to find "volatile" data for a given product, or at least
 
    it should be...  As of this writing there are a couple other places to look
 
    but hopefully this table can eventually be "the" place.
 

	
 
    Whether any given value in a given record, applies to the "current" app
 
    node only, or if it applies to all nodes, is up to app logic.
 

	
 
    Note that a custom app should (most likely) *not* bother "extending" this
 
    table, but rather should create a separate table with similar pattern.
 
    """
 
    __tablename__ = 'product_volatile'
 
    __table_args__ = (
 
        sa.ForeignKeyConstraint(['product_uuid'], ['product.uuid'], name='product_volatile_fk_product'),
 
    )
 

	
 
    uuid = uuid_column()
 

	
 
    product_uuid = sa.Column(sa.String(length=32), nullable=False)
 
    product = orm.relationship(
 
        Product,
 
        doc="""
 
        Product to which this "volatile" data record pertains.
 
        """,
 
        backref=orm.backref(
 
            'volatile',
 
            uselist=False,
 
            cascade='all, delete-orphan',
 
            doc="""
 
            "Volatile" data record for the product, if any.
 
            """))
 

	
 
    true_cost = sa.Column(sa.Numeric(precision=9, scale=5), nullable=True, doc="""
 
    "True" unit cost for the item, if known.  This might include certain
 
    "allowances" (discounts) currently in effect etc.; really anything which
 
    might not be reflected in "official" unit cost for the product.  Usually,
 
    this value is quite easily calculated and so this field serves as more of
 
    a cache, for sake of SQL access to the values.
 
    """)
 

	
 
    true_margin = sa.Column(sa.Numeric(precision=8, scale=5), nullable=True, doc="""
 
    "True" profit margin for the "regular" unit price vs. the "true" unit cost
 
    (:attr:`true_cost`).
 
    """)
 

	
 

	
 
@six.python_2_unicode_compatible
 
class InventoryAdjustmentReason(Base):
 
    """
 
    Reasons for adjusting product inventory.
 
    """
 
    __tablename__ = 'invadjust_reason'
rattail/importing/model.py
Show inline comments
 
@@ -2239,12 +2239,19 @@ class ProductStoreInfoImporter(ToRattail):
 
    """
 
    Data importer for :class:`rattail.db.model.ProductStoreInfo`.
 
    """
 
    model_class = model.ProductStoreInfo
 

	
 

	
 
class ProductVolatileImporter(ToRattail):
 
    """
 
    Data importer for :class:`~rattail.db.model.products.ProductVolatile`.
 
    """
 
    model_class = model.ProductVolatile
 

	
 

	
 
class LabelProfileImporter(ToRattail):
 
    """
 
    Importer for LabelProfile data
 
    """
 
    model_class = model.LabelProfile
 

	
rattail/importing/rattail.py
Show inline comments
 
@@ -109,12 +109,13 @@ class FromRattailToRattailBase(object):
 
        importers['Brand'] = BrandImporter
 
        importers['Product'] = ProductImporter
 
        importers['ProductCode'] = ProductCodeImporter
 
        importers['ProductCost'] = ProductCostImporter
 
        importers['ProductPrice'] = ProductPriceImporter
 
        importers['ProductStoreInfo'] = ProductStoreInfoImporter
 
        importers['ProductVolatile'] = ProductVolatileImporter
 
        importers['ProductImage'] = ProductImageImporter
 
        importers['LabelProfile'] = LabelProfileImporter
 
        return importers
 

	
 
    def get_default_keys(self):
 
        keys = self.get_importer_keys()
 
@@ -361,12 +362,15 @@ class ProductPriceImporter(FromRattail, model.ProductPriceImporter):
 
        return super(ProductPriceImporter, self).supported_fields + self.product_reference_fields
 

	
 

	
 
class ProductStoreInfoImporter(FromRattail, model.ProductStoreInfoImporter):
 
    pass
 

	
 
class ProductVolatileImporter(FromRattail, model.ProductVolatileImporter):
 
    pass
 

	
 

	
 
class ProductImageImporter(FromRattail, model.ProductImageImporter):
 
    """
 
    Importer for product images.  Note that this uses the "batch" approach
 
    because fetching all data up front is not performant when the host/local
 
    systems are on different machines etc.
0 comments (0 inline, 0 general)