def _get_products(self, sort_by_name=True, additional_query=False): # FIXME: This is a kind of workaround until we have the # SQLCompletion funcionality, then we will not need to sort the # data. if sort_by_name: attr = ProductFullStockView.description else: attr = ProductFullStockView.category_description products = [] query = Eq(Product.is_grid, False) if additional_query: # XXX For now, we are not allowing package_product to have another # package_product or batch_product as component exclude_batch = Or(Eq(Storable.is_batch, False), Eq(Storable.is_batch, None)) query = And(query, exclude_batch) for product_view in self.store.find(ProductFullStockView, query).order_by(attr): if product_view.product is self._product: continue description = product_view.get_product_and_category_description() products.append((description, product_view.product)) return products
def get_extra_query(self, states): query = And(Eq(PurchaseReceivingView.purchase_group, None), Eq(PurchaseReceivingView.receiving_invoice, None)) # Dont let the user receive purchases from other branches when working # in synchronized mode if (api.sysparam.get_bool('SYNCHRONIZED_MODE') and not api.can_see_all_branches()): branch = api.get_current_branch(self.store) query = And(query, PurchaseReceivingView.branch_id == branch.id) return query
def get_sellable_view_query(self): branch = api.get_current_branch(self.store) branch_query = Or(Field('_stock_summary', 'branch_id') == branch.id, Eq(Field('_stock_summary', 'branch_id'), None)) query = And(branch_query, Sellable.get_available_sellables_query(self.store)) return self.sellable_view, query
def get_sellables_for_inventory(cls, store, branch, extra_query=None): """Returns a generator with the necessary data about the stock to open an Inventory :param store: The store to fetch data from :param branch: The branch that is being inventoried :param query: A query that should be used to restrict the storables for the inventory. This can filter based on categories or other aspects of the product. :returns: a generator of the following objects: (Sellable, Product, Storable, StorableBatch, ProductStockItem) """ # XXX: If we should want all storables to be inclued in the inventory, even if if # never had a ProductStockItem before, than we should inclue this query in the # LeftJoin with ProductStockItem below query = ProductStockItem.branch_id == branch.id if extra_query: query = And(query, extra_query) tables = [ Sellable, Join(Product, Product.id == Sellable.id), Join(Storable, Storable.id == Product.id), LeftJoin(StorableBatch, StorableBatch.storable_id == Storable.id), LeftJoin( ProductStockItem, And( ProductStockItem.storable_id == Storable.id, Or(ProductStockItem.batch_id == StorableBatch.id, Eq(ProductStockItem.batch_id, None)))), ] return store.using(*tables).find( (Sellable, Product, Storable, StorableBatch, ProductStockItem), query)
def get_sellable_view_query(self): branch = api.get_current_branch(self.store) branch_query = Or(ProductStockItem.branch_id == branch.id, Eq(ProductStockItem.branch_id, None)) query = And(branch_query, Sellable.get_available_sellables_query(self.store)) return self.sellable_view, query
def get_insert_identity(self, primary_key, primary_variables): equals = [] for column, variable in zip(primary_key, primary_variables): if not variable.is_defined(): variable = currval(column) equals.append(Eq(column, variable)) return And(*equals)
def find_by_branch(cls, store, branch): if branch is None: return store.find(cls) # When we need to filter on the branch, we also need to add the branch # column on the ProductStockItem subselect, so the filter works. We cant # keep the branch_id on the main subselect, since that will cause the # results to be duplicate when not filtering by branch (probably the # most common case). So, we need all of this workaround # Make sure that the join we are replacing is the correct one. assert cls.tables[3].right == _StockSummary # Highjack the class being queried, since we need to add the branch # on the ProductStockItem subselect to filter it later class HighjackedViewable(cls): tables = cls.tables[:] tables[3] = LeftJoin( _StockBranchSummary, Field('_stock_summary', 'storable_id') == Storable.id) # Also show products that were never purchased. query = Or( Field('_stock_summary', 'branch_id') == branch.id, Eq(Field('_stock_summary', 'branch_id'), None)) return store.find(HighjackedViewable, query)
def get_pre_plugin_names(cls, store): """Returns a list of pre enabled plugin names :param store: a store :returns: names of the pre enabled plugins """ query = Eq(cls.plugin_version, None) return [p.plugin_name for p in store.find(cls, query)]
def get_sellable_view_query(self): # The stock quantity of consigned products can not be # decreased manually. See bug 5212. query = And(Eq(Product.consignment, False), self.sellable_view.branch_id == self.model.branch_id, Sellable.get_available_sellables_query(self.store)) return self.sellable_view, query
def get_insert_identity(self, primary_key, primary_variables): equals = [] for column, variable in zip(primary_key, primary_variables): if not variable.is_defined(): variable = SQLRaw(self._raw_cursor.lastrowid) equals.append(Eq(column, variable)) return And(*equals)
def executer_query(self, store): branch_id = self.branch_filter.get_state().value if branch_id is None: branch = None else: branch = store.get(Branch, branch_id) results = self.search_spec.find_by_branch(store, branch) return results.find(Eq(Product.is_composed, False))
def remove(self): """Remove this return and it's items from the database""" # XXX: Why do we remove this object from the database # We must remove children_items before we remove its parent_item for item in self.returned_items.find(Eq(ReturnedSaleItem.parent_item_id, None)): [self.remove_item(child) for child in getattr(item, 'children_items')] self.remove_item(item) self.store.remove(self)
def find_by_branch(cls, store, branch): if branch: # We need the OR part to be able to list services query = Or(ProductStockItem.branch == branch, Eq(ProductStockItem.branch_id, None)) return store.find(cls, query) return store.find(cls)
def get_sellable_view_query(self): return ( self.sellable_view, # FIXME: How to do this using sellable_view.find_by_branch ? And( Or(ProductStockItem.branch_id == self.model.branch.id, Eq(ProductStockItem.branch_id, None)), Sellable.get_available_sellables_query(self.store)))
def get_items(self, with_children=True): """Get the items of the purchase order :param with_children: indicate if we should fetch children_items or not """ query = PurchaseItem.order == self if not with_children: query = And(query, Eq(PurchaseItem.parent_item_id, None)) return self.store.find(PurchaseItem, query)
def get_insert_identity(self, primary_key, primary_variables): equals = [] for column, variable in zip(primary_key, primary_variables): if not variable.is_defined(): # The Select here prevents PostgreSQL from going nuts and # performing a sequential scan when there *is* an index. # http://tinyurl.com/2n8mv3 variable = Select(currval(column)) equals.append(Eq(column, variable)) return And(*equals)
def get_sellable_view_query(self): return ( self.sellable_view, # FIXME: How to do this using sellable_view.find_by_branch ? And( Or( Field('_stock_summary', 'branch_id') == self.model.branch.id, Eq(Field('_stock_summary', 'branch_id'), None)), Sellable.get_available_sellables_query(self.store)))
def get_sellable_view_query(self): branch = self.model.branch # Also include products that are not storable branch_query = Or(self.sellable_view.branch_id == branch.id, Eq(self.sellable_view.branch_id, None)) # The stock quantity of consigned products can not be # decreased manually. See bug 5212. query = And(branch_query, Sellable.get_available_sellables_query(self.store)) return self.sellable_view, query
class OpticalMedicView(Viewable): medic = OpticalMedic id = Person.id name = Person.name crm_number = OpticalMedic.crm_number partner = OpticalMedic.partner phone_number = Person.phone_number tables = [Person, Join(OpticalMedic, Person.id == OpticalMedic.person_id)] clause = Eq(Person.merged_with_id, None)
def get_divergent_payments(self): """Returns a :class:`Payment` sequence that meet the following requirements: * The payment due date, paid date or cancel date is the current PaymentFlowHistory date. * The payment was paid/received with different values (eg with discount or surcharge). * The payment was scheduled to be paid/received on the current, but it was not. * The payment was not expected to be paid/received on the current date. """ from stoqlib.domain.payment.payment import Payment date = self.history_date query = And(Or(Date(Payment.due_date) == date, Date(Payment.paid_date) == date, Date(Payment.cancel_date) == date), Or(Eq(Payment.paid_value, None), Payment.value != Payment.paid_value, Eq(Payment.paid_date, None), Date(Payment.due_date) != Date(Payment.paid_date))) return self.store.find(Payment, query)
def get_tags(store): lfm = liblfm.LastFM(CONFIG['lastfm']['key']) for track in store.find(Track, Eq(Track.tags, None)): print "Processing %s - %s ..." % (track.artist, track.title) try: track.tags = lfm.top_tags(track.artist, track.title) except LookupError as e: print "--- %s" % repr(e) continue except: print "WTF ??? %s" % repr(e) store.commit() time.sleep(1.0)
def has_batch_item(self): """Fetch the storables from this purchase order and returns ``True`` if any of them is a batch storable. :returns: ``True`` if this purchase order has batch items, ``False`` if it doesn't. """ return not self.store.find(Storable, And(self.id == PurchaseOrder.id, PurchaseOrder.id == PurchaseItem.order_id, PurchaseItem.sellable_id == Sellable.id, Sellable.id == Storable.id, Eq(Storable.is_batch, True))).is_empty()
def _setup_widgets(self): self._setup_status() returned_sale = self.model.returned_sale self.undo_button.set_sensitive(returned_sale.can_undo()) self.returned_items_list.set_columns(self._get_returned_items_columns()) r_items = returned_sale.returned_items for r_item in r_items.find(Eq(ReturnedSaleItem.parent_item_id, None)): self.returned_items_list.append(None, r_item) for child in r_item.children_items: self.returned_items_list.append(r_item, child) self._update_reason()
def get_by_station_and_type(cls, store, station, type, exclude=None): """Fetch the settings for a specific station and type. Note that one station can have only one active device of a given type. :param store: a store :param station: a BranchStation instance :param type: device type :param exclude: a device to exclude from search """ except_id = exclude and exclude.id return store.find(cls, And(cls.station == station, cls.type == type, Eq(cls.is_active, True), cls.id != except_id)).one()
def get_items_for_adjustment(self): """Returns all the inventory items that needs adjustment, that is the recorded quantity is different from the actual quantity. :returns: items :rtype: a sequence of :class:`InventoryItem` """ query = And(InventoryItem.inventory_id == self.id, InventoryItem.recorded_quantity != InventoryItem.actual_quantity, Eq(InventoryItem.cfop_data_id, None), InventoryItem.reason == u"") return self.store.find(InventoryItem, query)
def search_completed(self, results): results = list(results) if results: obj = results[0] # Build a cache of parent produts to make the results load faster. # Also, the parents will show up in the results even if they would # normally not, but if one of its children shows up. parents = obj.store.find(type(obj), Eq(Product.is_grid, True)) self._cache = {} for item in parents: self._cache[item.id] = item super(_ProductSearchResultTreeView, self).search_completed(results)
def get_items_for_adjustment(self): """Gets all the inventory items that needs adjustment An item needing adjustment is any :class:`InventoryItem` with :attr:`InventoryItem.recorded_quantity` different from :attr:`InventoryItem.counted_quantity`. :returns: items :rtype: a sequence of :class:`InventoryItem` """ return self.inventory_items.find( And(InventoryItem.recorded_quantity != InventoryItem.counted_quantity, Eq(InventoryItem.is_adjusted, False)))
class PublisherView(Viewable): publiser = BookPublisher id = Person.id name = Person.name publisher_id = BookPublisher.id status = BookPublisher.status tables = [ Person, Join(BookPublisher, Person.id == BookPublisher.person_id), ] clause = Eq(Person.merged_with_id, None)
def get_storables_without_stock_item(cls, store, branch): """Get |storables| without a |productstockitem| This will get all storables that doesn't have a |productstockitem| on the given branch. :param store: the store used to query the storables :param branch: the |branch| used to check for the stock item existence :returns: a result set of |storables| """ join = LeftJoin(ProductStockItem, And(ProductStockItem.storable_id == cls.id, ProductStockItem.branch_id == branch.id)) return store.using(cls, join).find(cls, Eq(ProductStockItem.id, None))
def get_permission(cls, store, profile, app): """Check if a profile has access to an app :param store: A store :param profile: The :class:`.UserProfile` to check for permission :param app: The name of the application :return: Whether the profile has access to the profile or not """ apps = [app] + cls.virtual_apps.get(app, []) res = store.find( cls, And(cls.user_profile_id == profile.id, Eq(cls.has_permission, True), cls.app_dir_name.is_in(apps))) res.config(limit=1) return res.one() is not None