Changeset - 2d32439da5f8
[Not reviewed]
0 3 0
Lance Edgar (lance) - 12 years ago 2012-04-16 00:47:26
lance@edbob.org
more batch changes (save point)
3 files changed with 204 insertions and 23 deletions:
0 comments (0 inline, 0 general)
rattail/batches.py
Show inline comments
 
@@ -85,24 +85,33 @@ class BatchTerminal(edbob.Object):
 
        pass
 

	
 
    @property
 
    @requires_impl()
 
    def fieldmap_internal(self):
 
        pass
 

	
 
    @property
 
    @requires_impl()
 
    def fieldmap_user(self):
 
        pass
 

	
 
    @requires_impl()
 
    def provide_rows(self, session, rowclass, dictionary, query=None, **kwargs):
 
        """
 
        Generator which yields (new) batch row instances.  This is used to
 
        populate batches.
 
        """
 

	
 
        raise NotImplementedError
 

	
 
    # def get_elements(self, elements, fieldmap, *required):
 
    #     """
 
    #     Returns the proper element list according to current context.
 
    #     """
 

	
 
    #     if elements is None:
 
    #         elements = sorted(fieldmap)
 
    #     self.require_elements(elements, *required)
 
    #     return elements
 

	
 
    # def require_elements(self, using, *required):
 
    #     """
 
@@ -115,58 +124,70 @@ class BatchTerminal(edbob.Object):
 
    #             if element not in using:
 
    #                 raise sil.ElementRequiredError(element, using)
 

	
 

	
 
class RattailBatchTerminal(BatchTerminal):
 
    """
 
    Defines the core batch terminal for Rattail.
 
    """
 
    
 
    name = 'rattail'
 
    description = "Rattail (local)"
 

	
 
    # source = True
 
    # target = True
 

	
 
    # fieldmap_internal = {
 
    #     'F01'           : 'upc',
 
    #     'F02'           : 'description',
 
    #     'F4001'         : 'description2',
 
    #     }
 

	
 
    # fieldmap_user = {
 
    #     'F01'           : "UPC",
 
    #     'F02'           : "Description",
 
    #     'F4001'         : "Description 2",
 
    #     }
 

	
 
    source_columns = {
 
        'ITEM_DCT': [
 
            'F01',
 
            'F02',
 
            ],
 
        }
 

	
 
    target_columns = {
 
        'DEPT_DCT': [
 
            'F03',
 
            'F238',
 
            ],
 
        'ITEM_DCT': [
 
            'F01',
 
            'F02',
 
            'F03',
 
            'F22',
 
            'F155',
 
            ],
 
        }
 

	
 
    def provide_rows(self, session, rowclass, dictionary, query=None, **kwargs):
 

	
 
        if dictionary.name == 'DEPT_DCT':
 
            if not query:
 
                query = session.query(rattail.Department)
 
            for dept in query:
 
                yield rowclass(
 
                    F03=dept.number,
 
                    F238=dept.name,
 
                    )
 
            return
 

	
 
        elif dictionary.name == 'ITEM_DCT':
 
            if not query:
 
                query = session.query(rattail.Product)
 
            for product in query:
 
                yield rowclass(
 
                    F01=int(product.upc),
 
                    F02=product.description[:20],
 
                    F155=product.brand.name if product.brand else None,
 
                    )
 
            return
 

	
 
        assert False, "FIXME"
 

	
 
    # def import_main_item(self, session, elements=None, progress_factory=None):
 
    #     """
 
    #     Create a main item (ITEM_DCT) batch from current Rattail data.
 
    #     """
 

	
 
    #     elements = self.get_elements(elements, self.fieldname_map_main_item, 'F01')
 
    #     batch = make_batch(self.name, elements, session,
 
    #                        description="Main item data from Rattail")
 

	
 
    #     products = session.query(rattail.Product)
 
    #     prog = None
 
    #     if progress_factory:
 
@@ -182,63 +203,218 @@ class RattailBatchTerminal(BatchTerminal):
 
    #         prog.destroy()
 

	
 
    #     return batch
 

	
 
    def add_departments(self, session, batch):
 
        for row in batch.provide_rows():
 
            dept = rattail.Department()
 
            dept.number = row.F03
 
            dept.name = row.F238
 
            session.add(dept)
 
            session.flush()
 

	
 
    def add_replace_departments(self, session, batch):
 
        for row in batch.provide_rows():
 
            q = session.query(rattail.Department)
 
            q = q.filter_by(number=row.F03)
 
            if q.count():
 
                prods = session.query(rattail.Product)
 
                prods = prods.filter_by(department_uuid=q.first().uuid)
 
                if prods.count():
 
                    prods.update(dict(department_uuid=None), synchronize_session='fetch')
 
                q.delete(synchronize_session=False)
 

	
 
            dept = rattail.Department()
 
            dept.number = row.F03
 
            dept.name = row.F238
 
            session.add(dept)
 
            session.flush()
 

	
 
    def add_products(self, session, batch):
 
        q = session.query(rattail.Department)
 
        depts = {}
 
        for dept in q:
 
            depts[dept.number] = dept
 

	
 
        q = session.query(rattail.Brand)
 
        brands = {}
 
        for brand in q:
 
            brands[brand.name] = brand
 

	
 
        for row in batch.provide_rows():
 
            if row.F155 in brands:
 
                brand = brands[row.F155]
 
            else:
 
                brand = rattail.Brand(name=row.F155)
 
                session.add(brand)
 
                session.flush()
 
                brands[brand.name] = brand
 
            dept = None
 
            if row.F03:
 
                if row.F03 in depts:
 
                    dept = depts[row.F03]
 
                else:
 
                    dept = rattail.Department(number=row.F03)
 
                    session.add(dept)
 
                    session.flush()
 
                    depts[dept.number] = dept
 

	
 
            brand = None
 
            if row.F155:
 
                if row.F155 in brands:
 
                    brand = brands[row.F155]
 
                else:
 
                    brand = rattail.Brand(name=row.F155)
 
                    session.add(brand)
 
                    session.flush()
 
                    brands[brand.name] = brand
 

	
 
            prod = rattail.Product()
 
            prod.upc = row.F01
 
            prod.description = row.F02
 
            prod.size = row.F22
 
            prod.department = dept
 
            prod.brand = brand
 
            session.add(prod)
 
            session.flush()
 

	
 
    def add_replace_products(self, session, batch):
 
        q = session.query(rattail.Department)
 
        depts = {}
 
        for dept in q:
 
            depts[dept.number] = dept
 

	
 
        q = session.query(rattail.Brand)
 
        brands = {}
 
        for brand in q:
 
            brands[brand.name] = brand
 

	
 
        products = session.query(rattail.Product)
 
        for row in batch.provide_rows():
 
            dept = None
 
            if row.F03:
 
                if row.F03 in depts:
 
                    dept = depts[row.F03]
 
                else:
 
                    dept = rattail.Department(number=row.F03)
 
                    session.add(dept)
 
                    session.flush()
 
                    depts[dept.number] = dept
 

	
 
            brand = None
 
            if row.F155:
 
                if row.F155 in brands:
 
                    brand = brands[row.F155]
 
                else:
 
                    brand = rattail.Brand(name=row.F155)
 
                    session.add(brand)
 
                    session.flush()
 
                    brands[brand.name] = brand
 

	
 
            q = products.filter_by(upc=row.F01)
 
            if q.count():
 
                q.delete(synchronize_session=False)
 

	
 
            prod = rattail.Product()
 
            prod.upc = row.F01
 
            prod.description = row.F02
 
            prod.size = row.F22
 
            prod.department = dept
 
            prod.brand = brand
 
            session.add(prod)
 
            session.flush()
 

	
 
    def change_departments(self, session, batch):
 
        depts = session.query(rattail.Department)
 
        for row in batch.provide_rows():
 
            dept = depts.filter_by(number=row.F03).first()
 
            if dept:
 
                dept.name = row.F238
 
                session.flush()
 

	
 
    def change_products(self, session, batch):
 
        q = session.query(rattail.Department)
 
        depts = {}
 
        for dept in q:
 
            depts[dept.number] = dept
 

	
 
        products = session.query(rattail.Product)
 
        for row in batch.provide_rows():
 
            prod = products.filter_by(upc=row.F01).first()
 
            if prod:
 
                dept = None
 
                if row.F03:
 
                    if row.F03 in depts:
 
                        dept = depts[row.F03]
 
                    else:
 
                        dept = rattail.Department(number=row.F03)
 
                        session.add(dept)
 
                        session.flush()
 
                        depts[dept.number] = dept
 
                prod.dept = dept
 
                prod.size = row.F22
 
                session.flush()
 

	
 
    def execute_batch(self, batch):
 
        """
 
        Executes ``batch``, which should be a :class:`rattail.Batch` instance.
 
        """
 

	
 
        session = object_session(batch)
 

	
 
        if batch.action_type == rattail.BATCH_ADD:
 

	
 
            if batch.dictionary.name == 'DEPT_DCT':
 
                self.add_departments(session, batch)
 
                return
 
            if batch.dictionary.name == 'ITEM_DCT':
 
                self.add_products(session, batch)
 
                return
 

	
 
        if batch.action_type == rattail.BATCH_ADD_REPLACE:
 
            if batch.dictionary.name == 'DEPT_DCT':
 
                return self.add_replace_departments(session, batch)
 
            if batch.dictionary.name == 'ITEM_DCT':
 
                return self.add_replace_products(session, batch)
 

	
 
        if batch.action_type == rattail.BATCH_CHANGE:
 

	
 
            if batch.dictionary.name == 'DEPT_DCT':
 
                self.change_departments(session, batch)
 
                return
 

	
 
            if batch.dictionary.name == 'ITEM_DCT':
 
                return self.change_products(session, batch)
 

	
 
        if batch.action_type == rattail.BATCH_REMOVE:
 
            if batch.dictionary.name == 'DEPT_DCT':
 
                return self.remove_departments(session, batch)
 
            if batch.dictionary.name == 'ITEM_DCT':
 
                return self.remove_products(session, batch)
 

	
 
        assert False, "FIXME"
 

	
 
    def remove_departments(self, session, batch):
 
        depts = session.query(rattail.Department)
 
        products = session.query(rattail.Product)
 
        for row in batch.provide_rows():
 
            dept = depts.filter_by(number=row.F03).first()
 
            if dept:
 
                q = products.filter_by(department_uuid=dept.uuid)
 
                if q.count():
 
                    q.update({'department_uuid': None}, synchronize_session=False)
 
                session.delete(dept)
 
                session.flush()
 

	
 
    def remove_products(self, session, batch):
 
        products = session.query(rattail.Product)
 
        for row in batch.provide_rows():
 
            prod = products.filter_by(upc=row.F01).first()
 
            if prod:
 
                session.delete(prod)
 
                session.flush()
 

	
 

	
 
# def make_batch(source, elements, session, batch_id=None, **kwargs):
 
#     """
 
#     Create and return a new SIL-based :class:`rattail.Batch` instance.
 
#     """
 

	
 
#     if not batch_id:
 
#         batch_id = next_batch_id(source, consume=True)
 

	
 
#     kwargs['source'] = source
 
#     kwargs['batch_id'] = batch_id
 
#     kwargs['target'] = target
rattail/db.py
Show inline comments
 
@@ -33,41 +33,44 @@ import rattail
 

	
 
def init_database(session):
 
    """
 
    Initialize an ``edbob`` database for use with Rattail.
 
    """
 

	
 
    activate_extension('rattail', session.bind)
 

	
 
    columns = [
 
        ('F01',         'UPC',                  'GPC(14)'),
 
        ('F02',         'Description',          'CHAR(20)'),
 
        ('F03',         'Department Number',    'NUMBER(4,0)'),
 
        ('F22',         'Size',                 'CHAR(30)'),
 
        ('F155',        'Brand',                'CHAR(30)'),
 
        ('F238',        'Department Name',      'CHAR(30)'),
 
        ]
 

	
 
    for name, disp, dtype in columns:
 
        session.add(rattail.SilColumn(
 
                sil_name=name, display=disp, data_type=dtype))
 
        session.flush()
 

	
 
    dictionaries = [
 
        ('DEPT_DCT', 'Department', [
 
                ('F03', True),
 
                'F238',
 
                ]),
 
        ('ITEM_DCT', 'Product', [
 
                ('F01', True),
 
                'F02',
 
                'F03',
 
                'F22',
 
                'F155',
 
                ]),
 
        # ('PRICE_DCT', 'Price', []),
 
        # ('FCOST_DCT', 'Future Cost', []),
 
        # ('FSPRICE_DCT', 'Future Sale Price', []),
 
        # ('CLASS_GROUP', 'Scale Class / Group', []),
 
        # ('NUTRITION', 'Scale Nutrition', []),
 
        # ('SCALE_TEXT', 'Scale Text', []),
 
        # ('VENDOR_DCT', 'Vendor', []),
 
        ]
 

	
 
    for name, desc, cols in dictionaries:
rattail/model.py
Show inline comments
 
@@ -515,36 +515,38 @@ class Department(Base):
 
    """
 

	
 
    __tablename__ = 'departments'
 

	
 
    uuid = uuid_column()
 
    number = Column(Integer)
 
    name = Column(String(30))
 

	
 
    def __repr__(self):
 
        return "<Department: %s>" % self.name
 

	
 
    def __str__(self):
 
        return str(self.name)
 
        return str(self.name or '')
 

	
 

	
 
class Product(Base):
 
    """
 
    Represents a product for sale and/or purchase.
 
    """
 

	
 
    __tablename__ = 'products'
 

	
 
    uuid = uuid_column()
 
    upc = Column(BigInteger)
 
    department_uuid = Column(String(32), ForeignKey('departments.uuid'))
 
    brand_uuid = Column(String(32), ForeignKey('brands.uuid'))
 
    description = Column(String(60))
 
    description2 = Column(String(60))
 
    size = Column(String(30))
 

	
 
    department = relationship(Department)
 
    brand = relationship(Brand)
 

	
 
    def __repr__(self):
 
        return "<Product: %s>" % self.description
 

	
 
    def __str__(self):
 
        return str(self.description or '')
0 comments (0 inline, 0 general)