class SellableBranchOverride(Domain): __storm_table__ = 'sellable_branch_override' status = EnumCol() base_price = PriceCol() price_last_updated = DateTimeCol() max_discount = PercentCol() tax_constant_id = IdCol() tax_constant = Reference(tax_constant_id, 'SellableTaxConstant.id') default_sale_cfop_id = IdCol() default_sale_cfop = Reference(default_sale_cfop_id, 'CfopData.id') on_sale_price = PriceCol() on_sale_start_date = DateTimeCol() on_sale_end_date = DateTimeCol() branch_id = IdCol() branch = Reference(branch_id, 'Branch.id') sellable_id = IdCol() sellable = Reference(sellable_id, 'Sellable.id')
class SellableBranchOverride(Domain): __storm_table__ = 'sellable_branch_override' status = EnumCol() base_price = PriceCol() price_last_updated = DateTimeCol() max_discount = PercentCol() tax_constant_id = IdCol() tax_constant = Reference(tax_constant_id, 'SellableTaxConstant.id') default_sale_cfop_id = IdCol() default_sale_cfop = Reference(default_sale_cfop_id, 'CfopData.id') on_sale_price = PriceCol() on_sale_start_date = DateTimeCol() on_sale_end_date = DateTimeCol() branch_id = IdCol() branch = Reference(branch_id, 'Branch.id') sellable_id = IdCol() sellable = Reference(sellable_id, 'Sellable.id') #: specifies whether the product requires kitchen production requires_kitchen_production = BoolCol() @classmethod def find_by_sellable(cls, sellable, branch): return sellable.store.find(cls, sellable=sellable, branch=branch).one()
class TransactionEntry(ORMObject): """ A TransactionEntry keeps track of state associated with a database transaction. It's main use case is to know information about the system when a domain object is created or modified. Such information will be used by stoq when syncing databases """ __storm_table__ = 'transaction_entry' id = IntCol(primary=True, default=AutoReload) #: last time this object was modified te_time = DateTimeCol(allow_none=False) metadata = JsonCol() #: A bit string that stores information about this object syncronization status. #: a bit with value '0' means the object was changed and need to be sent to the server/client. #: a bit with value '1' means this object is already synced with the server/client. #: Note that on the client this column will have a size of 1. On the server it may vary sync_status = BitStringCol(default=AutoReload) #: For use of the sync conector te_server = DateTimeCol()
class PaymentChangeHistory(Domain): """ A class to hold information about changes to a payment. Only one tuple (last_due_date, new_due_date) or (last_status, new_status) should be non-null at a time. See also: `schema <http://doc.stoq.com.br/schema/tables/payment_change_history.html>`__ """ __storm_table__ = 'payment_change_history' payment_id = IdCol() #: the changed |payment| payment = Reference(payment_id, 'Payment.id') #: the reason of the change change_reason = UnicodeCol(default=None) #: when the changed happened change_date = DateTimeCol(default_factory=localnow) #: the due date that was set before the changed last_due_date = DateTimeCol(default=None) #: the due date that was set after changed new_due_date = DateTimeCol(default=None) #: status before the change last_status = EnumCol(allow_none=False, default=Payment.STATUS_PREVIEW) #: status after change new_status = EnumCol(allow_none=False, default=Payment.STATUS_PREVIEW)
class Sale(Domain): __storm_table__ = 'sale' close_date = DateTimeCol() confirm_date = DateTimeCol() client_id = IntCol() client = Reference(client_id, Client.id) transporter_id = IntCol() transporter = Reference(transporter_id, Transporter.id) def get_items(self): return self.store.find(SaleItem, sale=self).order_by(SaleItem.id)
class StorableBatch(Domain): """Batch information for storables. A batch is a colection of products (storable) that were produced at the same time and thus they have some common information, such as expiration date. This information is useful since sometimes its necessary to make decisions based on the batch like a special promotion for older batches (if it is close to the expiration date, for instance) or if a batch is somehow defective and we need to contact the clients that purchased items from this batch. """ __storm_table__ = 'storable_batch' #: The sequence number for this batch. Should be unique for a given #: storable batch_number = UnicodeCol(allow_none=False) #: The date this batch was created create_date = DateTimeCol(default_factory=localnow) #: An expiration date, specially for perishable products, like milk and food in #: general expire_date = DateTimeCol() #: Some space for the users to add notes to this batch. notes = UnicodeCol() storable_id = IdCol(allow_none=False) #: The storable that is in this batch storable = Reference(storable_id, 'Storable.id') def get_balance_for_branch(self, branch): """Return the stock balance for this |batch| in a |branch|. :param branch: the |branch| to get the stock balance for :returns: the amount of stock available in the |branch| """ store = self.store stock_items = store.find(ProductStockItem, storable=self.storable, batch=self, branch=branch) return stock_items.sum(ProductStockItem.quantity) or Decimal(0) # # IDescribable # def get_description(self): return self.batch_number
class TransactionEntry(ORMObject): """ A TransactionEntry keeps track of state associated with a database transaction. It's main use case is to know information about the system when a domain object is created or modified. Such information will be used by stoq when syncing databases """ __storm_table__ = 'transaction_entry' id = IntCol(primary=True, default=AutoReload) #: last time this object was modified te_time = DateTimeCol(allow_none=False) #: id of the last |loginuser| that modified this object user_id = IdCol(default=None) #: id of the last |branchstation| this object was modified on station_id = IdCol(default=None) #: It this object was modified since the last time it was synced #: After the object is synced, this property will be set to ``False``, so #: that when the next sync begins, only the objects that are **dirty** will be #: processed dirty = BoolCol(default=True)
class OpticalPatientVisualAcuity(Domain): __storm_table__ = 'optical_patient_visual_acuity' create_date = DateTimeCol(default_factory=StatementTimestamp) client_id = IdCol(allow_none=False) #: The related client client = Reference(client_id, 'Client.id') responsible_id = IdCol(allow_none=False) #: The user that registred this information responsible = Reference(responsible_id, 'LoginUser.id') be_distance_glasses = UnicodeCol() le_distance_glasses = UnicodeCol() re_distance_glasses = UnicodeCol() be_distance_lenses = UnicodeCol() le_distance_lenses = UnicodeCol() re_distance_lenses = UnicodeCol() be_near_glasses = UnicodeCol() be_near_lenses = UnicodeCol() #: Free notes notes = UnicodeCol() @property def responsible_name(self): return self.responsible.get_description()
class SaleComment(Domain): __storm_table__ = 'sale_comment' date = DateTimeCol(default_factory=localnow) comment = UnicodeCol() author_id = IdCol() sale_id = IdCol()
class ProductIcmsTemplate(BaseICMS): __storm_table__ = 'product_icms_template' REASON_LIVESTOCK = 3 REASON_OTHERS = 9 REASON_AGRICULTURAL_AGENCY = 12 product_tax_template_id = IdCol() product_tax_template = Reference(product_tax_template_id, 'ProductTaxTemplate.id') # Simples Nacional p_cred_sn_valid_until = DateTimeCol(default=None) # Motivo de Desoneração do ICMS mot_des_icms = IntCol(default=None) def is_p_cred_sn_valid(self): """Returns if p_cred_sn has expired.""" if not self.p_cred_sn_valid_until: # If we don't have a valid_until, means p_cred_sn will never # expire. Therefore, p_cred_sn is valid. return True elif self.p_cred_sn_valid_until.date() < localtoday().date(): return False return True
class Sale(Domain): __storm_table__ = 'sale' return_date = DateTimeCol(default=None) branch_id = IntCol() branch = Reference(branch_id, Branch.id) def get_items(self): return self.store.find(SaleItem, sale_id=self.id).order_by(SaleItem.id)
class CreditProvider(Domain): """A credit provider This is the institution that provides the credit to the client, for instance: American Express, Visanet, Redecard, etc... """ __storm_table__ = 'credit_provider' #: A short description of this provider short_name = UnicodeCol() #: An identification for this provider provider_id = UnicodeCol(default=u'') #: the maximum number of installments for a |sale| using this credit provider. max_installments = IntCol(default=1) default_device_id = IdCol() #: The default device for this credit provider. This will be suggested to #: the user when he selects this provider in the checkout dialog default_device = Reference(default_device_id, 'CardPaymentDevice.id') #: The date when we start working with this provider open_contract_date = DateTimeCol() # # IDescribable # def get_description(self): return self.short_name # # Public API # @classmethod def get_provider_by_provider_id(cls, provider_id, store): """Get a provider given a provider id string :param provider_id: a string representing the provider :param store: a database store """ return store.find(cls, provider_id=provider_id) @classmethod def get_card_providers(cls, store): """Get a list of all credit card providers. :param store: a database store """ return store.find(cls) @classmethod def has_card_provider(cls, store): """Find out if there is a card provider :param store: a database store :returns: if there is a card provider """ return bool(store.find(cls).count())
class TransactionEntry(ORMObject): __storm_table__ = 'transaction_entry' id = IntCol(primary=True, default=AutoReload) te_time = DateTimeCol(allow_none=False) user_id = IntCol(default=None) station_id = IntCol(default=None) dirty = BoolCol(default=True)
class Message(Domain): """A message that will be displayed at the launcher screen. """ __storm_table__ = 'message' #: The content of the message content = UnicodeCol(default=u'') #: When this message was created created_at = DateTimeCol(default_factory=localnow) #: Until when this message will be shown expire_at = DateTimeCol() created_by_id = IdCol(default=None) #: The user that created this message created_by = Reference(created_by_id, 'LoginUser.id') branch_id = IdCol() #: the branch this message will be displayed at branch = Reference(branch_id, 'Branch.id') profile_id = IdCol() #: the user this message will be displayed to profile = Reference(profile_id, 'UserProfile.id') user_id = IdCol() #: the user profile this message will be displayed to user = Reference(user_id, 'LoginUser.id') @classmethod def find_active(cls, store): branch = api.get_current_branch(store) user = api.get_current_user(store) profile = user.profile now = localnow() query = And( # All fields are optional, so default to the current user (or now) if they are missing Coalesce(cls.expire_at, now) >= now, Coalesce(cls.branch_id, branch.id) == branch.id, Coalesce(cls.user_id, user.id) == user.id, Coalesce(cls.profile_id, profile.id) == profile.id, ) return store.find(cls, query)
class TransactionEntry(ORMObject): __storm_table__ = 'transaction_entry' (CREATED, MODIFIED) = range(2) id = IntCol(primary=True) te_time = DateTimeCol(allow_none=False) user_id = IntCol(default=None) station_id = IntCol(default=None) type = IntCol()
class StockTransactionHistory(Domain): __storm_table__ = 'stock_transaction_history' TYPE_IMPORTED = 15 product_stock_item_id = IntCol() stock_cost = PriceCol() quantity = QuantityCol() responsible_id = IntCol() date = DateTimeCol() object_id = IntCol() type = IntCol()
class FiscalDayHistory(Domain): """This represents the information that needs to be used to generate a Sintegra file of type 60A. """ __storm_table__ = 'fiscal_day_history' emission_date = DateTimeCol() station_id = IdCol() station = Reference(station_id, 'BranchStation.id') serial = UnicodeCol() serial_id = IntCol() coupon_start = IntCol() coupon_end = IntCol() cro = IntCol() crz = IntCol() period_total = PriceCol() total = PriceCol() taxes = ReferenceSet('id', 'FiscalDayTax.fiscal_day_history_id') reduction_date = DateTimeCol()
class TillEntry(IdentifiableDomain): """A TillEntry is a representing cash added or removed in a |till|. * A positive value represents addition. * A negative value represents removal. """ __storm_table__ = 'till_entry' #: A numeric identifier for this object. This value should be used instead of #: :obj:`Domain.id` when displaying a numerical representation of this object to #: the user, in dialogs, lists, reports and such. identifier = IdentifierCol() #: the date the entry was created date = DateTimeCol(default_factory=localnow) #: A small string describing what was done description = UnicodeCol() #: value of transaction value = PriceCol() till_id = IdCol(allow_none=False) #: the |till| the entry takes part of till = Reference(till_id, 'Till.id') payment_id = IdCol(default=None) #: |payment| of this entry, if any payment = Reference(payment_id, 'Payment.id') branch_id = IdCol() #: |branch| that received or gave money branch = Reference(branch_id, 'Branch.id') station_id = IdCol(allow_none=False) #: The station this object was created at station = Reference(station_id, 'BranchStation.id') @property def time(self): """The time of the entry Note that this is the same as :obj:`.date.time()`, but with microseconds replaced to *0*. """ time = self.date.time() return time.replace(microsecond=0) @property def branch_name(self): return self.branch.get_description()
class CreditProvider(Domain): """A credit provider This is the institution that provides the credit to the client, for instance: American Express, Visanet, Redecard, etc... """ __storm_table__ = 'credit_provider' implements(IDescribable) #: A short description of this provider short_name = UnicodeCol() #: An identification for this provider provider_id = UnicodeCol(default=u'') #: The date when we start working with this provider open_contract_date = DateTimeCol() # # IDescribable # def get_description(self): return self.short_name # # Public API # @classmethod def get_provider_by_provider_id(cls, provider_id, store): """Get a provider given a provider id string :param provider_id: a string representing the provider :param store: a database store """ return store.find(cls, provider_id=provider_id) @classmethod def get_card_providers(cls, store): """Get a list of all credit card providers. :param store: a database store """ return store.find(cls) @classmethod def has_card_provider(cls, store): """Find out if there is a card provider :param store: a database store :returns: if there is a card provider """ return bool(store.find(cls).count())
class Certificate(Domain): __storm_table__ = 'certificate' TYPE_PKCS11 = u'pkcs11' TYPE_PKCS12 = u'pkcs12' types_str = collections.OrderedDict([ (TYPE_PKCS11, _("A3: Smartcard")), (TYPE_PKCS12, _("A1: Digital certificate")), ]) #: The type of the certificate type = EnumCol(allow_none=False, default=TYPE_PKCS12) #: If the certificate is active or not active = BoolCol(default=True) #: The name of the certificate/lib when it was uploaded to the dataabse name = UnicodeCol(default=u'') #: The content of the certificate. The library file for PKCS11 #: or the certificate itself for PKCS12 content = BLOBCol() #: The certificate password. If it is ``None`` it means that the user #: should be asked each time it is going to be used (for PKCS11 only) _password = BLOBCol(name='password', allow_none=True, default=None) #: The certificate expiration date. expiration_date = DateTimeCol(default=None) @property def password(self): po = PasswordObfuscator() po.hashed_password = self._password and self._password return po @password.setter def password(self, password): assert isinstance(password, PasswordObfuscator) hashed = password.hashed_password self._password = hashed @property def type_str(self): return self.types_str[self.type] @classmethod def get_active_certs(cls, store, exclude=None): """Get active certificates except the one given in exclude parameter""" except_id = exclude and exclude.id return store.find(cls, And(Eq(cls.active, True), cls.id != except_id))
class Delivery(Domain): __storm_table__ = 'delivery' (STATUS_INITIAL, STATUS_SENT, STATUS_RECEIVED) = range(3) status = IntCol(default=STATUS_INITIAL) open_date = DateTimeCol(default=None) deliver_date = DateTimeCol(default=None) receive_date = DateTimeCol(default=None) tracking_code = UnicodeCol(default=u'') address_id = IntCol() address = Reference(address_id, Address.id) transporter_id = IntCol() transporter = Reference(transporter_id, Transporter.id) service_item_id = IntCol() service_item = Reference(service_item_id, SaleItem.id) def add_item(self, item): item.delivery = self
class ProductionItemQualityResult(Domain): """This table stores the test results for every produced item. """ implements(IDescribable) __storm_table__ = 'production_item_quality_result' produced_item_id = IntCol() produced_item = Reference(produced_item_id, 'ProductionProducedItem.id') quality_test_id = IntCol() quality_test = Reference(quality_test_id, 'ProductQualityTest.id') tested_by_id = IntCol() tested_by = Reference(tested_by_id, 'LoginUser.id') tested_date = DateTimeCol(default=None) result_value = UnicodeCol() test_passed = BoolCol(default=False) def get_description(self): return self.quality_test.description @property def result_value_str(self): return _(self.result_value) def get_boolean_value(self): if self.result_value == u'True': return True elif self.result_value == u'False': return False else: raise ValueError def get_decimal_value(self): return Decimal(self.result_value) def set_value(self, value): if isinstance(value, bool): self.set_boolean_value(value) else: self.set_decimal_value(value) def set_boolean_value(self, value): self.test_passed = self.quality_test.result_value_passes(value) self.result_value = unicode(value) self.produced_item.check_tests() def set_decimal_value(self, value): self.test_passed = self.quality_test.result_value_passes(value) self.result_value = u'%s' % (value, ) self.produced_item.check_tests()
class PaymentComment(Domain): __storm_table__ = 'payment_comment' author_id = IdCol() author = Reference(author_id, 'LoginUser.id') payment_id = IdCol() payment = Reference(payment_id, 'Payment.id') date = DateTimeCol(default_factory=localnow) comment = UnicodeCol() # # IDescribable implementation # def get_description(self): return u"[%s] %s" % (self.author.person.name, self.comment)
class ECFDocumentHistory(Domain): """Documents emitted by the fiscal printer. This does not include fiscal coupons """ (TYPE_MEMORY_READ, TYPE_Z_REDUCTION, TYPE_SUMMARY) = range(3) __storm_table__ = 'ecf_document_history' printer_id = IdCol() printer = Reference(printer_id, 'ECFPrinter.id') type = IntCol() coo = IntCol(default=0) gnf = IntCol(default=0) crz = IntCol(default=None) emission_date = DateTimeCol(default_factory=datetime.datetime.now)
class ReturnedSale(Domain): __storm_table__ = 'returned_sale' identifier = IntCol(default=AutoReload) return_date = DateTimeCol(default_factory=datetime.datetime.now) invoice_number = IntCol(default=None) reason = UnicodeCol(default=u'') sale_id = IntCol() sale = Reference(sale_id, Sale.id) new_sale_id = IntCol() new_sale = Reference(new_sale_id, Sale.id) responsible_id = IntCol() responsible = Reference(responsible_id, LoginUser.id) branch_id = IntCol() branch = Reference(branch_id, Branch.id)
class ECFDocumentHistory(Domain): """Documents emitted by the fiscal printer. This does not include fiscal coupons """ TYPE_MEMORY_READ = u'memory-read' TYPE_Z_REDUCTION = u'z-reduction' TYPE_SUMMARY = u'summary' __storm_table__ = 'ecf_document_history' printer_id = IdCol() printer = Reference(printer_id, 'ECFPrinter.id') type = EnumCol() coo = IntCol(default=0) gnf = IntCol(default=0) crz = IntCol(default=None) emission_date = DateTimeCol(default_factory=datetime.datetime.now)
class ProductIcmsTemplate(BaseICMS): __storm_table__ = 'product_icms_template' product_tax_template_id = IdCol() product_tax_template = Reference(product_tax_template_id, 'ProductTaxTemplate.id') # Simples Nacional p_cred_sn_valid_until = DateTimeCol(default=None) def is_p_cred_sn_valid(self): """Returns if p_cred_sn has expired.""" if not self.p_cred_sn_valid_until: # If we don't have a valid_until, means p_cred_sn will never # expire. Therefore, p_cred_sn is valid. return True elif self.p_cred_sn_valid_until.date() < localtoday().date(): return False return True
class BranchSynchronization(ORMObject): """Created once per branch. Contains a string which is a reference to a policy defined in stoqlib.database.policy and a timestamp which is updated each time a synchronization is done. """ __storm_table__ = 'branch_synchronization' id = IntCol(primary=True, default=AutoReload) #: last time updated sync_time = DateTimeCol(allow_none=False) branch_id = IdCol() #: a |branch| branch = Reference(branch_id, 'Branch.id') #: policy used to update the branch policy = UnicodeCol(allow_none=False)
class NFePayment(Domain): __storm_table__ = "nfe_payment" nfe_purchase_id = IdCol() nfe_purchase = Reference(nfe_purchase_id, "NFePurchase.id") method_id = IdCol() #: Payment method (ex: bill, credit card, etc) method = Reference(method_id, "PaymentMethod.id") #: The final value of the payment value = PriceCol() #: Installment number duplicate_number = UnicodeCol() #: The final date for the payment due_date = DateTimeCol(default=None) #: The description generated by the system for the payment description = UnicodeCol(default=u"")
class SystemTable(ORMObject): """Stores information about database schema migration I{update}: the date when the database schema was updated I{patchlevel}: the version of the schema installed """ __storm_table__ = 'system_table' id = IntCol(primary=True, default=AutoReload) updated = DateTimeCol() patchlevel = IntCol() generation = IntCol() @classmethod def is_available(cls, store): """Checks if Stoqlib database is properly installed :param store: a store """ if not store.table_exists(u'system_table'): return False return bool(store.find(cls))