def testSetNotMandatory(self): store = self.store store2 = new_store() store3 = new_store() client_form = store.find(UIForm, form_name=u'client').one() field = store.find(UIField, ui_form=client_form, field_name=u'name').one() self.assertEquals(field.mandatory, True) field2 = store2.find(UIField, ui_form=client_form, field_name=u'name').one() dialog = FormFieldEditor(self.store) dialog.forms.select(client_form) self.assertEquals(dialog.fields.get_cell_contents()[7][2], True) setattr(field, 'mandatory', False) dialog.fields.refresh() self.assertEquals(dialog.fields.get_cell_contents()[7][2], False) self.assertEquals(field2.mandatory, True) dialog.confirm() field3 = store3.find(UIField, ui_form=client_form, field_name=u'name').one() self.assertEquals(field3.mandatory, False) store2.close() store3.close() # Restore initial state of the test database. setattr(field, 'mandatory', True) store.commit()
def testCacheInvalidation(self): # First create a new person in an outside transaction outside_store = new_store() outside_person = Person(name=u'doe', store=outside_store) outside_store.commit() # Get this person in the default store default_store = get_default_store() db_person = default_store.find(Person, id=outside_person.id).one() self.assertEqual(db_person.name, u'doe') # Now, select that same person in an inside store inside_store = new_store() inside_person = inside_store.fetch(outside_person) # Change and commit the changes on this inside store inside_person.name = u'john' # Flush to make sure the database was updated inside_store.flush() # Before comminting the other persons should still be 'doe' self.assertEqual(db_person.name, u'doe') self.assertEqual(outside_person.name, u'doe') inside_store.commit() # We expect the changes to reflect on the connection self.assertEqual(db_person.name, u'john') # and also on the outside store self.assertEqual(outside_person.name, u'john') outside_store.close() inside_store.close()
def test_dirty_flag(self): # Creating an object should set its dirty flag to True store = new_store() obj = WillBeCommitted(store=store) obj_id = obj.id store.commit() self.assertTrue(obj.te.dirty) # Reset the flag to test changing the object obj.te.dirty = False store.commit() store.close() # Get the same object from a new connection store = new_store() obj = store.get(WillBeCommitted, obj_id) # The flag must be False self.assertFalse(obj.te.dirty) # Changing the object and commiting should update the flag obj.test_var = u'asd' store.commit() self.assertTrue(obj.te.dirty) store.close()
def test_dirty_flag(self): # Creating an object should set its sync_status to 0 (not synced) store = new_store() obj = WillBeCommitted(store=store) obj_id = obj.id store.commit() self.assertEqual(obj.te.sync_status, '0') # Reset the flag to test changing the object obj.te.sync_status = '1' store.commit() store.close() # Get the same object from a new connection store = new_store() obj = store.get(WillBeCommitted, obj_id) # The bit must still be set to 1 self.assertEqual(obj.te.sync_status, '1') # Changing the object and commiting should update the flag obj.test_var = u'asd' store.commit() self.assertEqual(obj.te.sync_status, '0') store.close()
def test_set_not_mandatory(self, info): store = self.store store2 = new_store() store3 = new_store() client_form = store.find(UIForm, form_name=u'client').one() field = store.find(UIField, ui_form=client_form, field_name=u'name').one() self.assertEqual(field.mandatory, True) field2 = store2.find(UIField, ui_form=client_form, field_name=u'name').one() dialog = FormFieldEditor(self.store) dialog.forms.select(client_form) self.assertEqual(list(dialog.fields.get_cell_contents())[8][2], True) setattr(field, 'mandatory', False) dialog.fields.refresh() self.assertEqual(list(dialog.fields.get_cell_contents())[8][2], False) self.assertEqual(field2.mandatory, True) dialog.confirm() field3 = store3.find(UIField, ui_form=client_form, field_name=u'name').one() self.assertEqual(field3.mandatory, False) store2.close() store3.close() # Restore initial state of the test database. setattr(field, 'mandatory', True) store.commit()
def process(self, store=None): """Do the main logic, create stores, import items etc""" n_items = self.get_n_items() log.info('Importing %d items' % (n_items, )) create_log.info('ITEMS:%d' % (n_items, )) t1 = time.time() imported_items = 0 if not store: store = new_store() self.before_start(store) for i in range(n_items): if self.process_item(store, i): create_log.info('ITEM:%d' % (i + 1, )) imported_items += 1 if not self.dry and i + 1 % 100 == 0: store.commit(close=True) store = new_store() if not self.dry: store.commit(close=True) store = new_store() self.when_done(store) if not self.dry: store.commit(close=True) t2 = time.time() log.info('%s Imported %d entries in %2.2f sec' % ( datetime.datetime.now().strftime('%H:%M:%S'), n_items, t2 - t1)) create_log.info('IMPORTED-ITEMS:%d' % (imported_items, ))
def process(self, store=None): """Do the main logic, create stores, import items etc""" n_items = self.get_n_items() log.info('Importing %d items' % (n_items, )) create_log.info('ITEMS:%d' % (n_items, )) t1 = time.time() imported_items = 0 if not store: store = new_store() self.before_start(store) for i in range(n_items): if self.process_item(store, i): create_log.info('ITEM:%d' % (i + 1, )) imported_items += 1 if not self.dry and i + 1 % 100 == 0: store.commit(close=True) store = new_store() if not self.dry: store.commit(close=True) store = new_store() self.when_done(store) if not self.dry: store.commit(close=True) t2 = time.time() log.info( '%s Imported %d entries in %2.2f sec' % (datetime.datetime.now().strftime('%H:%M:%S'), n_items, t2 - t1)) create_log.info('IMPORTED-ITEMS:%d' % (imported_items, ))
def test_repr(self): store = new_store() ding = Ding(store=store, str_field=u'Foo', int_field=666) dong = Dong(store=store, bool_field=False, ding=ding) store.close() # This never got to database, so there is no id self.assertEqual(repr(dong), '<Dong [id missing] ding_id=None>') store = new_store() ding = Ding(store=store, str_field=u'Foo', int_field=666) dong = Dong(store=store, bool_field=False, ding=ding) # Where we have a full representation of the object self.assertTrue( re.match("<Dong '[a-f0-9-]*' ding_id='[a-f0-9-]*'>", repr(dong))) store.rollback(close=False) self.assertTrue( re.match("<Dong '[a-f0-9-]*' ding_id='\[lost object\]'>", repr(dong))) store.rollback() self.assertTrue( re.match( "<Dong '[a-f0-9-]*' ding_id='\[database connection closed\]'>", repr(dong)))
def test_autoreload(self): # Create 3 stores. store1 = new_store() store2 = new_store() obj1 = WillBeCommitted(store=store1, test_var='ID1') store1.commit() obj2 = store2.get(WillBeCommitted, obj1.id) obj2 store2.close() autoreload_object(obj1)
def _ensure_card_providers(): """ Creates a list of default card providers """ log.info("Creating Card Providers") from stoqlib.domain.payment.card import CreditProvider, CardPaymentDevice providers = { u'VISA': u'VISA', u'MASTER': u'MASTERCARD', u'AMEX': u'AMERICAN EXPRESS' } store = new_store() for short_name, provider_id in providers.items(): provider = CreditProvider.get_provider_by_provider_id( provider_id, store) if not provider.is_empty(): continue CreditProvider(short_name=short_name, provider_id=providers[short_name], open_contract_date=TransactionTimestamp(), store=store) devices = store.find(CardPaymentDevice) if devices.is_empty(): CardPaymentDevice(store=store, description=_(u'Default')) store.commit(close=True)
def _provide_current_station(station_name=None, branch_name=None): if not station_name: station_name = get_hostname() store = new_store() if branch_name: branch = store.find( Person, And(Person.name == branch_name, Branch.person_id == Person.id)).one() else: branches = store.find(Branch) if branches.count() == 0: person = Person(name=u"test", store=store) branch = Branch(person=person, store=store) else: branch = branches[0] provide_utility(ICurrentBranch, branch) station = BranchStation.get_station(store, branch, station_name) if not station: station = BranchStation.create(store, branch, station_name) assert station assert station.is_active provide_utility(ICurrentBranchStation, station) store.commit(close=True)
def _provide_current_station(station_name=None, branch_name=None): if not station_name: station_name = get_hostname() store = new_store() if branch_name: branch = store.find(Person, And(Person.name == branch_name, Branch.person_id == Person.id)).one() else: branches = store.find(Branch) if branches.count() == 0: person = Person(name=u"test", store=store) branch = Branch(person=person, store=store) else: branch = branches[0] provide_utility(ICurrentBranch, branch) station = BranchStation.get_station(store, branch, station_name) if not station: station = BranchStation.create(store, branch, station_name) assert station assert station.is_active provide_utility(ICurrentBranchStation, station) store.commit(close=True)
def tearDown(self): store = new_store() for person in store.find(Person, name=NAME): store.remove(person) store.commit() DomainTest.tearDown(self) store.close()
def install_plugin(self, plugin_name): """Install and enable a plugin @important: Calling this makes a plugin installed, but, it's your responsability to activate it! :param plugin: the :class:`IPlugin` implementation of the plugin """ # Try to get the plugin first. If it was't registered yet, # PluginError will be raised. plugin = self.get_plugin(plugin_name) if plugin_name in self.installed_plugins_names: raise PluginError("Plugin %s is already enabled." % (plugin_name, )) store = new_store() InstalledPlugin(store=store, plugin_name=plugin_name, plugin_version=0) store.commit(close=True) migration = plugin.get_migration() if migration: try: migration.apply_all_patches() except SQLError: # This means a lock could not be obtained. Warn user about this # and let stoq restart, that the schema will be upgraded # correctly error('Não foi possível terminar a instalação do plugin. ' 'Por favor reinicie todas as instancias do Stoq que ' 'estiver executando')
def _register_station(self): # Register the current computer as a branch station from stoqlib.database.runtime import new_store from stoqlib.domain.person import Branch from stoqlib.domain.station import BranchStation from stoqlib.exceptions import StoqlibError from stoqlib.net.socketutils import get_hostname store = new_store() branches = store.find(Branch) if branches: branch = branches[0] else: branch = None try: BranchStation(store=store, is_active=True, branch=branch, name=get_hostname()) except StoqlibError as e: raise SystemExit("ERROR: %s" % e) store.commit() store.close()
def initialize_system(password=None, testsuite=False, force=False): """Call all the necessary methods to startup Stoq applications for every purpose: production usage, testing or demonstration """ log.info("Initialize_system") try: db_settings.clean_database(db_settings.dbname, force=force) create_base_schema() create_log("INIT START") store = new_store() populate_initial_data(store) register_accounts(store) register_payment_methods(store) from stoqlib.domain.uiform import create_default_forms create_default_forms(store) store.commit(close=True) ensure_sellable_constants() ensure_system_parameters() _ensure_card_providers() create_default_profiles() _install_invoice_templates() if not testsuite: create_default_profile_settings() ensure_admin_user(password) except Exception, e: raise if not testsuite: collect_traceback(sys.exc_info(), submit=True) raise SystemExit("Could not initialize system: %r" % (e, ))
def _check_param_online_services(self): from stoqlib.database.runtime import get_default_store, new_store from stoqlib.lib.parameters import sysparam import gtk sparam = sysparam(get_default_store()) if sparam.ONLINE_SERVICES is None: from kiwi.ui.dialogs import HIGAlertDialog # FIXME: All of this is to avoid having to set markup as the default # in kiwi/ui/dialogs:HIGAlertDialog.set_details, after 1.0 # this can be simplified when we fix so that all descriptions # sent to these dialogs are properly escaped dialog = HIGAlertDialog( parent=None, flags=gtk.DIALOG_MODAL, type=gtk.MESSAGE_WARNING) dialog.add_button(_("Not right now"), gtk.RESPONSE_NO) dialog.add_button(_("Enable online services"), gtk.RESPONSE_YES) dialog.set_primary(_('Do you want to enable Stoq online services?')) dialog.set_details(PRIVACY_STRING, use_markup=True) dialog.set_default_response(gtk.RESPONSE_YES) response = dialog.run() dialog.destroy() store = new_store() sysparam(store).ONLINE_SERVICES = int(bool(response == gtk.RESPONSE_YES)) store.commit() store.close()
def _enable_demo(self): from stoqlib.database.runtime import new_store store = new_store() store.execute("UPDATE parameter_data SET field_value = '1' WHERE field_name = 'DEMO_MODE';") store.commit() store.close()
def get(self, param_name, expected_type=None, store=None): detail = self._verify_detail(param_name, expected_type) value = self._values.get(param_name) if value is None: # This parameter should be created on read and not on edit. if param_name == 'USER_HASH': from stoqlib.database.runtime import new_store new_store = new_store() value = self._set_default_value(new_store, u'USER_HASH') new_store.commit() return value # initial value is already of the correct type return detail.initial if expected_type is bool: return value == u'1' elif expected_type in (Decimal, int): try: return expected_type(value) except ValueError: return expected_type(detail.initial) elif isinstance(expected_type, basestring): field_type = detail.get_parameter_type() return store.get(field_type, unicode(value)) return value
def test_get_pending_count_with_savepoint(self): store = new_store() self.assertEqual(store.get_pending_count(), 0) obj = WillBeCommitted(store=store) self.assertEqual(store.get_pending_count(), 1) # savepoint should trigger a flush, making the next change set # obj dirty again store.savepoint("savepoint_a") obj.test_var = u'yyy' self.assertEqual(store.get_pending_count(), 2) store.savepoint("savepoint_b") obj.test_var = u'zzz' self.assertEqual(store.get_pending_count(), 3) store.savepoint("savepoint_c") obj.test_var = u'www' self.assertEqual(store.get_pending_count(), 4) store.rollback_to_savepoint("savepoint_b") self.assertEqual(store.get_pending_count(), 2) store.rollback()
def initialize_system(password=None, testsuite=False, force=False): """Call all the necessary methods to startup Stoq applications for every purpose: production usage, testing or demonstration """ log.info("Initialize_system") try: db_settings.clean_database(db_settings.dbname, force=force) create_base_schema() create_log("INIT START") store = new_store() populate_initial_data(store) register_accounts(store) register_payment_methods(store) from stoqlib.domain.uiform import create_default_forms create_default_forms(store) store.commit(close=True) ensure_sellable_constants() ensure_system_parameters() _ensure_card_providers() create_default_profiles() _install_invoice_templates() if not testsuite: create_default_profile_settings() ensure_admin_user(password) except Exception as e: raise if not testsuite: collect_traceback(sys.exc_info(), submit=True) raise SystemExit("Could not initialize system: %r" % (e, )) create_log("INIT DONE")
def tearDown(self): # Make sure to remove all committed persons from the database with new_store() as store: test_names = [u'dummy transaction test', u'dummy', u'doe', u'john'] store.find(Person, Person.name.is_in(test_names)).remove() DomainTest.tearDown(self)
def _check_branch(self): from stoqlib.database.runtime import (get_default_store, new_store, get_current_station, set_current_branch_station) from stoqlib.domain.person import Company from stoqlib.lib.parameters import sysparam from stoqlib.lib.message import info default_store = get_default_store() compaines = default_store.find(Company) if (compaines.count() == 0 or not sysparam.has_object('MAIN_COMPANY')): from stoqlib.gui.base.dialogs import run_dialog from stoqlib.gui.dialogs.branchdialog import BranchDialog if self._ran_wizard: info(_("You need to register a company before start using Stoq")) else: info(_("Could not find a company. You'll need to register one " "before start using Stoq")) store = new_store() person = run_dialog(BranchDialog, None, store) if not person: raise SystemExit branch = person.branch sysparam.set_object(store, 'MAIN_COMPANY', branch) current_station = get_current_station(store) if current_station is not None: current_station.branch = branch store.commit() store.close() set_current_branch_station(default_store, station_name=None)
def _check_param_online_services(self): from stoqlib.database.runtime import new_store from stoqlib.lib.parameters import sysparam from gi.repository import Gtk if sysparam.get_bool('ONLINE_SERVICES') is None: from kiwi.ui.dialogs import HIGAlertDialog # FIXME: All of this is to avoid having to set markup as the default # in kiwi/ui/dialogs:HIGAlertDialog.set_details, after 1.0 # this can be simplified when we fix so that all descriptions # sent to these dialogs are properly escaped dialog = HIGAlertDialog( parent=None, flags=Gtk.DialogFlags.MODAL, type=Gtk.MessageType.WARNING) dialog.add_button(_("Not right now"), Gtk.ResponseType.NO) dialog.add_button(_("Enable online services"), Gtk.ResponseType.YES) dialog.set_primary(_('Do you want to enable Stoq online services?')) dialog.set_details(PRIVACY_STRING, use_markup=True) dialog.set_default_response(Gtk.ResponseType.YES) response = dialog.run() dialog.destroy() store = new_store() sysparam.set_bool(store, 'ONLINE_SERVICES', response == Gtk.ResponseType.YES) store.commit() store.close()
def _reset_last_doc(self): # Last ecf document is not a sale or a till_entry anymore. store = new_store() printer = store.fetch(self._printer._printer) printer.last_till_entry = None printer.last_sale = None store.commit()
def _cancel_last_document(self): try: self._validate_printer() except DeviceError as e: warning(str(e)) return store = new_store() last_doc = self._get_last_document(store) if not self._confirm_last_document_cancel(last_doc): store.close() return if last_doc.last_till_entry: self._cancel_last_till_entry(last_doc, store) elif last_doc.last_sale: # Verify till balance before cancel the last sale. till = Till.get_current(store) if last_doc.last_sale.total_amount > till.get_balance(): warning(_("You do not have this value on till.")) store.close() return cancelled = self._printer.cancel_last_coupon() if not cancelled: info(_("Cancelling sale failed, nothing to cancel")) store.close() return else: self._cancel_last_sale(last_doc, store) store.commit()
def _cancel_last_document(self): try: self._validate_printer() except DeviceError as e: warning(str(e)) return store = new_store() last_doc = self._get_last_document(store) if not self._confirm_last_document_cancel(last_doc): store.close() return if last_doc.last_till_entry: self._cancel_last_till_entry(last_doc, store) elif last_doc.last_sale: # Verify till balance before cancel the last sale. till = Till.get_current(store) if last_doc.last_sale.total_amount > till.get_balance(): warning(_("You do not have this value on till.")) store.close() return cancelled = self._printer.cancel() if not cancelled: info(_("Cancelling sale failed, nothing to cancel")) store.close() return else: self._cancel_last_sale(last_doc, store) store.commit()
def setUp(self): super(TestPluginManager, self).setUp() # Generate 2 instances of plugins that will be used for testing later. # '_dependent_plugin' will require 'independent_plugin' activation prior # to it's own. self._independent_plugin = _TestPlugin() self._dependent_plugin = _TestDependentPlugin() # Since the plugins are commited inside pluginmanager, try to remove # it first, or we will have problems if STOQLIB_TEST_QUICK is set. store = new_store() plugins = set(InstalledPlugin.get_plugin_names(store=self.store)) expected = set([u'ecf', u'nfe', u'optical']) self.assertTrue(expected.issubset(plugins)) ind_name = self._independent_plugin.name dep_name = self._dependent_plugin.name plugin_names = [ind_name, dep_name] test_plugins = store.find(InstalledPlugin, InstalledPlugin.plugin_name.is_in(plugin_names)) for plugin in test_plugins: store.remove(plugin) store.commit() store.close() self._manager = get_plugin_manager() self._register_test_plugin()
def _register_plugins(self, plugin_names): from stoqlib.database.runtime import new_store from stoqlib.lib.pluginmanager import get_plugin_manager manager = get_plugin_manager() with new_store() as store: for name in plugin_names: manager.pre_install_plugin(store, name)
def _enable_demo(self): from stoqlib.database.runtime import new_store store = new_store() store.execute( "UPDATE parameter_data SET field_value = '1' WHERE field_name = 'DEMO_MODE';" ) store.commit() store.close()
def __init__(self, items, include_services=False, branch=None): store = new_store() branch = branch or get_current_branch(store) address = branch.person.get_main_address() self.state = address.city_location.state load_taxes_csv(self.state) self.items = items self.include_services = include_services
def _set_person_utilities(): store = new_store() branch = sysparam.get_object(store, 'MAIN_COMPANY') provide_utility(ICurrentBranch, branch) station = BranchStation(name=u"Stoqlib station", branch=branch, store=store, is_active=True) provide_utility(ICurrentBranchStation, station) store.commit(close=True)
def after_update(self): # checks if there is new applications and update all the user # profiles on the system store = new_store() update_profile_applications(store) # Updating the parameter list sysparam.ensure_system_parameters(store, update=True) store.commit(close=True)
def create_default_profiles(): store = new_store() log.info("Creating user default profiles") UserProfile.create_profile_template(store, _(u'Administrator'), True) UserProfile.create_profile_template(store, _(u'Manager'), True) UserProfile.create_profile_template(store, _(u'Salesperson'), False) store.commit(close=True)
def after_update(self): # checks if there is new applications and update all the user # profiles on the system store = new_store() update_profile_applications(store) store.commit(close=True) # Updating the parameter list ensure_system_parameters(update=True)
def test_context_manager(self): # Normal store with retval = True (default) with new_store() as store: store.confirm = mock.Mock() store.close = mock.Mock() self.assertCalledOnceWith(store.confirm, commit=True) self.assertCalledOnceWith(store.close) # Normal store with retval = False with new_store() as store: store.confirm = mock.Mock() store.close = mock.Mock() store.retval = False self.assertCalledOnceWith(store.confirm, commit=False) self.assertCalledOnceWith(store.close) # An exception handled inside the context manager should not # impact on the result The store should be committed with new_store() as store: store.confirm = mock.Mock() store.close = mock.Mock() try: raise ValueError except Exception: pass self.assertCalledOnceWith(store.confirm, commit=True) self.assertCalledOnceWith(store.close) # An exception handled outside (or not handled, but we can't not # handle it on tests) should impact on the result. # The store should rollback and close. try: with new_store() as store: store.confirm = mock.Mock() store.close = mock.Mock() raise ValueError except Exception: pass self.assertCalledOnceWith(store.confirm, commit=False) self.assertCalledOnceWith(store.close)
def _create_default_salesperson_role(self): from stoqlib.domain.person import EmployeeRole key = u"DEFAULT_SALESPERSON_ROLE" if self.get_parameter_by_field(key, EmployeeRole): return store = new_store() role = EmployeeRole(name=_(u'Salesperson'), store=store) store.commit(close=True) self._set_schema(key, role.id, is_editable=False)
def download_plugin(self, plugin_name): """Download a plugin from webservice :param plugin_name: the name of the plugin to download :returns: a deferred """ from stoqlib.lib.webservice import WebService default_store = get_default_store() existing_egg = default_store.find(PluginEgg, plugin_name=plugin_name).one() md5sum = existing_egg and existing_egg.egg_md5sum webapi = WebService() r = webapi.download_plugin(plugin_name, md5sum=md5sum) try: response = r.get_response() except Exception as e: return False, _("Failed to do the request: %s" % (e, )) code = response.status_code if code == 204: msg = _("No update needed. The plugin is already up to date.") log.info(msg) return True, msg if code != 200: return_messages = { 400: _("Plugin not available for this stoq version"), 401: _("The instance is not authorized to download the plugin"), 404: _("Plugin does not exist"), 405: _("This instance has not acquired the specified plugin"), } msg = return_messages.get(code, str(code)) log.warning(msg) return False, msg content = response.content md5sum = unicode(hashlib.md5(content).hexdigest()) with new_store() as store: existing_egg = store.find(PluginEgg, plugin_name=plugin_name).one() if existing_egg is not None: existing_egg.egg_content = content existing_egg.egg_md5sum = md5sum else: PluginEgg( store=store, plugin_name=plugin_name, egg_md5sum=md5sum, egg_content=content, ) self._reload() return True, _("Plugin download successful")
def testRollback(self): trans = new_store() trans.find(Person).any() trans.rollback(close=False) # Should be ok to use trans again trans.find(Person).any() trans.rollback(close=True) # Should not be ok to use trans again self.assertRaises(ClosedError, trans.find(Person).any)
def _create_cfop(self, key, description, code): from stoqlib.domain.fiscal import CfopData if self.get_parameter_by_field(key, CfopData): return data = self.store.find(CfopData, code=code).one() if not data: store = new_store() data = CfopData(code=code, description=description, store=store) store.commit(close=True) self._set_schema(key, data.id)