def test_create(self): storable = self.create_storable(is_batch=True) batch = self.create_storable_batch(storable=storable, batch_number=u'1') batch.create_date = datetime.date(2010, 10, 10) batch = self.create_storable_batch(storable=storable, batch_number=u'2') batch.create_date = datetime.date(2011, 11, 11) batch = self.create_storable_batch(storable=storable, batch_number=u'3') batch.create_date = datetime.date(2012, 12, 12) storable.register_initial_stock(10, api.get_current_branch(self.store), 1, u'1') storable.register_initial_stock(15, api.get_current_branch(self.store), 1, u'2') storable.register_initial_stock(8, api.get_current_branch(self.store), 1, u'3') dialog = BatchSelectionDialog(self.store, storable, 33) for entry in dialog._spins.keys(): entry.update(1) dialog._spins[entry].update(12) for entry in dialog._spins.keys()[1:]: entry.update(2) dialog._spins[entry].update(7) for entry in dialog._spins.keys()[2:]: entry.update(3) dialog._spins[entry].update(8) dialog.existing_batches_expander.set_expanded(True) self.check_dialog(dialog, 'dialog-batch-selection-dialog-create')
def test_auto_reserve(self, yesno): # Data setup client = self.create_client() medic = self.create_optical_medic(crm_number=u'999') auto = self.create_storable( branch=api.get_current_branch(self.store), stock=10) auto.product.sellable.barcode = u'auto_reserve' OpticalProduct(store=self.store, product=auto.product, auto_reserve=True) not_auto = self.create_storable( branch=api.get_current_branch(self.store), stock=10) not_auto.product.sellable.barcode = u'not_auto_reserve' OpticalProduct(store=self.store, product=not_auto.product, auto_reserve=False) wizard = OpticalSaleQuoteWizard(self.store) # First step: Client step = wizard.get_current_step() step.client_gadget.set_value(client) self.click(wizard.next_button) # Second Step: optical data step = wizard.get_current_step() slave = step.slaves['WO 1'] slave.patient.update('Patient') slave.medic_gadget.set_value(medic) slave.estimated_finish.update(localdate(2020, 1, 5)) # Third Step: Products self.click(wizard.next_button) step = wizard.get_current_step() # Add two items: One auto reserved and another not. Both with initially # 10 items on stock for barcode in ['auto_reserve', 'not_auto_reserve']: step.barcode.set_text(barcode) self.activate(step.barcode) step.quantity.update(5) self.click(step.add_sellable_button) # Finish the wizard yesno.return_value = False with mock.patch.object(self.store, 'commit'): self.click(wizard.next_button) # Now check the stock for the two items. The auto reverd should have the # stock decreased to 5. The one that not auto reserves should still be # at 10 self.assertEqual(auto.get_total_balance(), 5) self.assertEqual(not_auto.get_total_balance(), 10)
def test_get(self): with self.sysparam(DEMO_MODE=True): with self.fake_store(): api.get_current_branch(self.store) s = self.login() sellable = self.create_sellable() img = self.create_image() img.image = b'foobar' img.sellable_id = sellable.id rv = self.client.get('/image/' + sellable.id, headers={'stoq-session': s}) self.assertEqual(rv.status_code, 200) self.assertEqual(rv.data, b'foobar')
def _check_user(self, username, password): username = unicode(username) password = unicode(password) # This function is really just a post-validation item. default_store = api.get_default_store() user = default_store.find(LoginUser, username=username).one() if not user: raise LoginError(_("Invalid user or password")) if not user.is_active: raise LoginError(_('This user is inactive')) branch = api.get_current_branch(default_store) # current_branch may not be set if we are registering a new station if branch and not user.has_access_to(branch): raise LoginError(_('This user does not have access to this branch')) if user.pw_hash != password: raise LoginError(_("Invalid user or password")) # Dont know why, but some users have this empty. Prevent user from # login in, since it will break later if not user.profile: msg = (_("User '%s' has no profile set, " "but this should not happen.") % user.username + '\n\n' + _("Please contact your system administrator or Stoq team.")) warning(msg) raise LoginError(_("User does not have a profile")) user.login() # ICurrentUser might already be provided which is the case when # creating a new database, thus we need to replace it. provide_utility(ICurrentUser, user, replace=True) return user
def _get_next_batch_number(self): max_db = StorableBatch.get_max_value(self.store, StorableBatch.batch_number) max_used = max_value_for(self._get_used_batches() | set([max_db])) if not api.sysparam.get_bool('SYNCHRONIZED_MODE'): return next_value_for(max_used) # On synchronized mode we need to append the branch acronym # to avoid conflicts max_used_list = max_used.split('-') if len(max_used_list) == 1: # '123' max_used = max_used_list[0] elif len(max_used_list) == 2: # '123-AB' max_used = max_used_list[0] else: # '123-456-AB' max_used = ''.join(max_used_list[:-1]) branch = api.get_current_branch(self.store) if not branch.acronym: raise ValueError("branch '%s' needs an acronym since we are on " "synchronized mode" % (branch.get_description(),)) return '-'.join([next_value_for(max_used), branch.acronym])
def __init__(self, store): self.model = None self.sync_mode = api.sysparam.get_bool('SYNCHRONIZED_MODE') self.current_branch = api.get_current_branch(store) first_step = ReceivingSelectionStep(self, store) BaseWizard.__init__(self, store, first_step, self.model) self.next_button.set_sensitive(False)
def _check_user(self, username, pw_hash): username = unicode(username) pw_hash = unicode(pw_hash) # This function is really just a post-validation item. default_store = api.get_default_store() current_branch = api.get_current_branch(default_store) user = LoginUser.authenticate(default_store, username, pw_hash, current_branch) # Dont know why, but some users have this empty. Prevent user from # login in, since it will break later if not user.profile: msg = (_("User '%s' has no profile set, " "but this should not happen.") % user.username + '\n\n' + _("Please contact your system administrator or Stoq team.")) warning(msg) raise LoginError(_("User does not have a profile")) user.login() # ICurrentUser might already be provided which is the case when # creating a new database, thus we need to replace it. provide_utility(ICurrentUser, user, replace=True) return user
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 test_batch_number_suggestion_synchronized_mode(self): branch = api.get_current_branch(self.store) branch.acronym = u'AB' storable = self.create_storable(is_batch=True) storable2 = self.create_storable(is_batch=True) dialog = BatchIncreaseSelectionDialog(self.store, storable, 10) self.assertEqual(dialog._last_entry.get_text(), '') with self.sysparam(SUGGEST_BATCH_NUMBER=True, SYNCHRONIZED_MODE=True): storable.register_initial_stock(1, self.create_branch(), 0, batch_number=u'130') dialog = BatchIncreaseSelectionDialog(self.store, storable, 10) # Make sure it suggested right self.assertEqual(dialog._last_entry.get_text(), '131-AB') spinbutton = dialog.get_spin_by_entry(dialog._last_entry) spinbutton.update(5) # Updating the spinbutton should append a new entry with the suggestion self.assertEqual(dialog._last_entry.get_text(), '132-AB') self.click(dialog.main_dialog.ok_button) dialog = BatchIncreaseSelectionDialog(self.store, storable2, 10) # Since the dialog above was confirmed on the same store this one is, # it should consider it's batch numbers for the next suggestion self.assertEqual(dialog._last_entry.get_text(), '133-AB') branch.acronym = None spinbutton = dialog.get_spin_by_entry(dialog._last_entry)
def test_existing_batches(self): branch = api.get_current_branch(self.store) storable = self.create_storable(is_batch=True) batch1 = self.create_storable_batch(storable=storable, batch_number=u'1') batch2 = self.create_storable_batch(storable=storable, batch_number=u'2') self.create_storable_batch(storable=storable, batch_number=u'3') storable.increase_stock(10, branch, 0, None, batch=batch1) storable.increase_stock(10, branch, 0, None, batch=batch2) dialog = BatchSelectionDialog(self.store, storable, 5) # The last batch should not appear since it doesn't have a storable self.assertEqual(set([view.batch for view in dialog.existing_batches]), set([batch1, batch2])) last_spin = dialog.get_spin_by_entry(dialog._last_entry) # The spin (at the moment, the only one appended) should be filled # with the total value (100, passed on the constructor) self.assertEqual(last_spin.read(), 5) view1 = self.store.find(StorableBatchView, StorableBatchView.id == batch1.id).one() dialog.existing_batches.emit('row-activated', view1) self.assertEqual(last_spin.read(), 5)
def _get_or_create_quote_group(self, order, store): if order is not None: quotation = store.find(Quotation, purchase=order).one() return quotation.group else: return QuoteGroup(branch=api.get_current_branch(store), store=store)
def create_filters(self): self.executer.set_query(self._query) self.set_text_field_columns(['description']) self.branch_filter = ComboSearchFilter( _('Show by:'), self._get_branches()) self.branch_filter.select(api.get_current_branch(self.store)) self.add_filter(self.branch_filter, position=SearchFilterPosition.TOP)
def _update_widgets(self): branch = api.get_current_branch(self.store) is_main_branch = self.branch_filter.get_state().value is branch item = self.results.get_selected() sellable = item and item.product.sellable if sellable: if sellable.has_image: thumbnail = sellable.image.thumbnail pixbuf = self.pixbuf_converter.from_string(thumbnail) else: pixbuf = None self._update_edit_image(pixbuf) if self.image_viewer: self.image_viewer.set_sellable(sellable) else: self._update_edit_image() self.set_sensitive([self.EditProduct], bool(item)) self.set_sensitive([self.ProductStockHistory], bool(item) and is_main_branch) # We need more than one branch to be able to do transfers # Note that 'all branches' is not a real branch has_branches = len(self.branch_filter.combo) > 2 transfer_active = self.NewTransfer.get_sensitive() self.set_sensitive([self.NewTransfer], transfer_active and has_branches) self.set_sensitive([self.SearchTransfer], has_branches)
def test_confirm(self, yesno, print_report): client = self.create_client() branch = api.get_current_branch(self.store) storable = self.create_storable(branch=branch, stock=1) sellable = storable.product.sellable wizard = NewLoanWizard(self.store) step = wizard.get_current_step() step.client.update(client) step.expire_date.update(localtoday().date()) self.check_wizard(wizard, 'new-loan-wizard-start-step') self.click(wizard.next_button) step = wizard.get_current_step() step.barcode.set_text(sellable.barcode) step.sellable_selected(sellable) step.quantity.update(1) self.click(step.add_sellable_button) loan_item = self.store.find(LoanItem, sellable=sellable).one() module = 'stoqlib.gui.events.NewLoanWizardFinishEvent.emit' with mock.patch(module) as emit: self.click(wizard.next_button) self.assertEquals(emit.call_count, 1) args, kwargs = emit.call_args self.assertTrue(isinstance(args[0], Loan)) self.check_wizard(wizard, 'new-loan-wizard-item-step', [wizard.retval, loan_item]) yesno.assert_called_once_with(_('Would you like to print the receipt now?'), gtk.RESPONSE_YES, 'Print receipt', "Don't print") self.assertEquals(print_report.call_count, 1) # verifies if stock was decreased correctly self.assertEquals(storable.get_balance_for_branch(branch), 0)
def test_search(self): self._create_domain() search = self._show_search() search.date_filter.select(Any) self.check_search(search, 'product-sold-no-filter') search.set_searchbar_search_string('bot') search.search.refresh() self.check_search(search, 'product-sold-string-filter') search.set_searchbar_search_string('') search.branch_filter.set_state(api.get_current_branch(self.store).id) search.search.refresh() self.check_search(search, 'product-sold-branch-filter') search.branch_filter.set_state(None) search.date_filter.select(DateSearchFilter.Type.USER_DAY) search.date_filter.start_date.update(datetime.date.today()) search.search.refresh() self.check_search(search, 'product-sold-date-today-filter') search.date_filter.select(DateSearchFilter.Type.USER_INTERVAL) search.date_filter.start_date.update(datetime.date(2012, 1, 1)) search.date_filter.end_date.update(datetime.date(2012, 2, 2)) search.search.refresh() self.check_search(search, 'product-sold-date-day-filter')
def _create_payment(self): group = PaymentGroup() group.payer = self.client.person method = PaymentMethod.get_by_name(self.store, u'credit') branch = api.get_current_branch(self.store) if self.model.value < 0: payment_type = Payment.TYPE_IN else: payment_type = Payment.TYPE_OUT # Set status to PENDING now, to avoid calling set_pending on # on_confirm for payments that shoud not have its status changed. payment = Payment(open_date=localtoday(), branch=branch, status=Payment.STATUS_PENDING, description=self.model.description, value=abs(self.model.value), base_value=abs(self.model.value), due_date=localtoday(), method=method, group=group, till=None, category=None, payment_type=payment_type, bill_received=False) payment.pay() return payment
def _collect_client_birthdays(self, start, end, day_events, store): branch = api.get_current_branch(store) for v in ClientWithSalesView.find_by_birth_date( store, (start, end), branch=branch): for year in xrange(start.year, end.year + 1): date, ev = self._create_client_birthday(v, year) self._append_event(day_events, date, 'client_birthdays', ev)
def _add_product_sellable(self, sellable, quantity, batch=None): product = sellable.product if product.storable and not batch and product.storable.is_batch: available_batches = list( product.storable.get_available_batches( api.get_current_branch(self.store))) # The trivial case, where there's just one batch, use it directly if len(available_batches) == 1: batch = available_batches[0] sale_item = TemporarySaleItem( sellable=sellable, quantity=quantity, batch=batch) self._update_added_item(sale_item) return rv = self.run_dialog( BatchDecreaseSelectionDialog, self.store, model=sellable.product_storable, quantity=quantity) if not rv: return for batch, b_quantity in rv.items(): sale_item = TemporarySaleItem( sellable=sellable, quantity=b_quantity, batch=batch) self._update_added_item(sale_item) else: sale_item = TemporarySaleItem( sellable=sellable, quantity=quantity, batch=batch) self._update_added_item(sale_item)
def _update_widgets(self): branch = api.get_current_branch(self.store) is_main_branch = self.branch_filter.get_state().value is branch item = self.results.get_selected() sellable = item and item.product.sellable if sellable: if item.has_image: thumbnail = sellable.image.thumbnail pixbuf = self.pixbuf_converter.from_string(thumbnail) else: pixbuf = None self._update_edit_image(pixbuf) if self.image_viewer: self.image_viewer.set_sellable(sellable) else: self._update_edit_image() self.set_sensitive([self.EditProduct, self.PrintLabels], bool(item)) self.set_sensitive([self.ProductStockHistory], bool(item) and is_main_branch) # We need more than one branch to be able to do transfers # Note that 'all branches' is not a real branch has_branches = len(self.branch_filter.combo) > 2 transfer_active = self.NewTransfer.get_sensitive() self.set_sensitive([self.NewTransfer], transfer_active and has_branches) # Building a list of searches that we must disable if there is no # branches other than the main company searches = [self.SearchTransfer, self.SearchTransferItems, self.SearchPendingReturnedSales] self.set_sensitive(searches, has_branches)
def test_wizard_create_payment(self, yesno): yesno.return_value = False sysparam.set_bool(self.store, 'CREATE_PAYMENTS_ON_STOCK_DECREASE', True) till = self.create_till() till.open_till() branch = api.get_current_branch(self.store) storable = self.create_storable(branch=branch, stock=1) sellable = storable.product.sellable wizard = StockDecreaseWizard(self.store) step = wizard.get_current_step() self.assertTrue(step.create_payments.get_visible()) step.create_payments.update(True) step.reason.update('reason') self.check_wizard(wizard, 'start-stock-decrease-step-create-payments') self.assertSensitive(wizard, ['next_button']) self.click(wizard.next_button) step = wizard.get_current_step() step.barcode.set_text(sellable.barcode) step.sellable_selected(sellable) step.quantity.update(1) self.click(step.add_sellable_button) self.click(wizard.next_button) step = wizard.get_current_step() self.assertTrue(isinstance(step, PaymentMethodStep))
def test_synchronized_mode(self): # This is a non editable parameter with self.sysparam(SYNCHRONIZED_MODE=True): current = api.get_current_branch(self.store) other_branch = self.create_branch() # One sale on one branch sale1 = self.create_sale(branch=current) self.add_product(sale1) sale1.order() self.add_payments(sale1, method_type=u'check') sale1.confirm() sale1.confirm_date = localdate(2011, 01, 01).date() sale1.salesperson.person.name = u'salesperson1' # And another one on a second branch sale2 = self.create_sale(branch=other_branch) sale2.salesperson = sale1.salesperson self.add_product(sale2) sale2.order() self.add_payments(sale2, method_type=u'money') sale2.confirm() sale2.confirm_date = sale1.confirm_date dialog = SalesPersonSalesSearch(self.store) dialog.date_filter.select(DateSearchFilter.Type.USER_INTERVAL) dialog.date_filter.start_date.update(sale1.confirm_date) dialog.date_filter.end_date.update(sale1.confirm_date) self.click(dialog.search.search_button) self.check_dialog(dialog, 'sales-person-sales-synchronized-show')
def test_wizard_remove_delivery(self, yesno): yesno.return_value = True branch = api.get_current_branch(self.store) storable = self.create_storable(branch=branch, stock=1) sellable = storable.product.sellable # Run the wizard wizard = StockDecreaseWizard(self.store) step = wizard.get_current_step() step.reason.update('test') self.click(wizard.next_button) step = wizard.get_current_step() self.assertNotSensitive(step, ['delivery_button']) step.sellable_selected(sellable) step.quantity.update(1) self.click(step.add_sellable_button) self.assertSensitive(step, ['delivery_button']) delivery_sellable = sysparam.get_object(self.store, 'DELIVERY_SERVICE').sellable delivery = CreateDeliveryModel(price=delivery_sellable.price, recipient=wizard.model.person) module = 'stoqlib.gui.wizards.stockdecreasewizard.run_dialog' with mock.patch(module) as run_dialog: # Delivery set run_dialog.return_value = delivery self.click(step.delivery_button) self.assertEqual(step._delivery, delivery) self.assertTrue(isinstance(step._delivery_item, StockDecreaseItem)) # Remove the delivery item run_dialog.return_value = delivery step.slave.klist.select(step.slave.klist[1]) self.click(step.slave.delete_button) self.assertIsNone(step._delivery) self.assertIsNone(step._delivery_item)
def create_filters(self): self.search.set_query(self._query) self.set_text_field_columns(["description", "code", "barcode", "category_description", "manufacturer"]) branches = Branch.get_active_branches(self.store) self.branch_filter = ComboSearchFilter(_("Show by:"), api.for_combo(branches, empty=_("All branches"))) self.branch_filter.select(api.get_current_branch(self.store)) self.add_filter(self.branch_filter, position=SearchFilterPosition.TOP)
def _show_search(self): search = ProductionHistorySearch(self.store) search.branch_filter.set_state(api.get_current_branch(self.store).id) search.date_filter.select(Any) search.search.refresh() search.results.select(search.results[0]) return search
def test_confirm(self, save, generator, localtoday): save.return_value = True value = datetime.datetime(2012, 1, 31) localtoday.return_value = value # we need to create a system table because it is used by the sintegra # dialog to populate the date filter SystemTable(updated=datetime.datetime(2012, 1, 1), patchlevel=0, generation=1, store=self.store) branch = api.get_current_branch(self.store) branch.manager = self.create_employee() dialog = SintegraDialog(self.store) with mock.patch.object(generator, 'write'): self.click(dialog.ok_button) self.check_dialog(dialog, 'dialog-sintegra-confirm', [dialog.retval]) self.assertEquals(save.call_count, 1) args, kwargs = save.call_args label, toplevel, filename = args self.assertEquals(label, _("Save Sintegra file")) self.assertTrue(isinstance(toplevel, gtk.Dialog)) self.assertEquals(filename, 'sintegra-2012-01.txt')
def test_save_new_sale(self, new_store): new_store.return_value = self.store with contextlib.nested( self.sysparam(USE_SALE_TOKEN=True), mock.patch.object(self.store, 'close'), mock.patch.object(self.store, 'commit')): pos = self.create_app(PosApp, u'pos') self._pos_open_till(pos) token = self.create_sale_token( u'foobar', branch=api.get_current_branch(self.store)) self._open_token(pos, token) pos.barcode.set_text(u'1598756984265') self.activate(pos.barcode) _sale = [] original_create_sale = pos._create_sale def _create_sale(*args, **kwargs): sale = original_create_sale(*args, **kwargs) _sale.append(sale) return sale with mock.patch.object(pos, '_create_sale') as create_sale: create_sale.side_effect = _create_sale self.click(pos.save_button) sale = _sale[0] self.assertEqual(sale.status, Sale.STATUS_ORDERED) self.assertEqual(sale.current_sale_token, token) items = list(sale.get_items()) self.assertEqual(len(items), 1) self.assertEqual(items[0].sellable.barcode, u'1598756984265')
def test_wizard(self, receipt_dialog): branch = api.get_current_branch(self.store) storable = self.create_storable(branch=branch, stock=1) sellable = storable.product.sellable wizard = StockDecreaseWizard(self.store) step = wizard.get_current_step() self.assertFalse(step.create_payments.get_visible()) self.assertNotSensitive(wizard, ['next_button']) step.reason.update('text') self.assertSensitive(wizard, ['next_button']) self.check_wizard(wizard, 'start-stock-decrease-step') self.click(wizard.next_button) step = wizard.get_current_step() self.assertNotSensitive(wizard, ['next_button']) step.barcode.set_text(sellable.barcode) step.sellable_selected(sellable) step.quantity.update(1) self.click(step.add_sellable_button) self.check_wizard(wizard, 'decrease-item-step') self.assertSensitive(wizard, ['next_button']) module = 'stoqlib.gui.events.StockDecreaseWizardFinishEvent.emit' with mock.patch(module) as emit: with mock.patch.object(self.store, 'commit'): self.click(wizard.next_button) self.assertEqual(emit.call_count, 1) args, kwargs = emit.call_args self.assertTrue(isinstance(args[0], StockDecrease)) self.assertEqual(receipt_dialog.call_count, 1) # Assert wizard decreased stock. self.assertEqual(storable.get_balance_for_branch(branch), 0)
def get_namespace(self): store = self.loan.store order_identifier = unicode(self.loan.identifier) print_promissory_note = api.sysparam.get_bool('PRINT_PROMISSORY_NOTE_ON_LOAN') branch = api.get_current_branch(store) drawer_person = self.loan.branch.person drawee_person = self.loan.client.person emission_address = branch.person.get_main_address() emission_location = emission_address.city_location promissory_data = Settable( order_identifier=order_identifier, payment_number=None, drawee=drawee_person.name, drawer=branch.get_description(), drawee_document=self._get_person_document(drawee_person), drawer_document=self._get_person_document(drawer_person), drawee_address=self._get_person_address(drawee_person), drawer_address=self._get_person_address(drawer_person), due_date=self.loan.expire_date, value=self.loan.get_total_amount(), emission_city=emission_location.city, emission_date=datetime.date.today(), ) return dict( subtitle=_("Loan number: %s") % order_identifier, loan=self.loan, print_promissory_note=print_promissory_note, promissory_data=promissory_data, )
def _update_view(self): self.proxy.update("status_str") has_open_inventory = bool(Inventory.has_open(self.store, api.get_current_branch(self.store))) tab = self._get_tab("execution_holder") # If it's not opened, it's at least approved. # So, we can enable the execution slave tab.set_sensitive( self.model.status == WorkOrder.STATUS_WORK_IN_PROGRESS and not has_open_inventory and not self.visual_mode ) has_items = bool(self.model.order_items.count()) if self.model.can_approve(): label = _("Approve") elif self.model.can_work() and not has_items: label = _("Start") elif self.model.can_work(): label = _("Continue") elif self.model.can_pause(): label = _("Pause") else: label = "" self.toggle_status_btn.set_label(label) self.toggle_status_btn.set_sensitive(not self.visual_mode and self.model.client is not None) self.toggle_status_btn.set_visible(bool(label)) stock_id, tooltip = get_workorder_state_icon(self.model) if stock_id is not None: self.state_icon.set_from_stock(stock_id, gtk.ICON_SIZE_MENU) self.state_icon.set_visible(True) self.state_icon.set_tooltip_text(tooltip) else: self.state_icon.hide()
def test_wizard_with_cost_center(self, yesno): sysparam.set_bool(self.store, 'CREATE_PAYMENTS_ON_STOCK_DECREASE', True) yesno.return_value = False branch = api.get_current_branch(self.store) storable = self.create_storable(branch=branch, stock=1) sellable = storable.product.sellable cost_center = self.create_cost_center() wizard = StockDecreaseWizard(self.store) entry = self.store.find(CostCenterEntry, cost_center=wizard.model.cost_center) self.assertEqual(len(list(entry)), 0) step = wizard.get_current_step() step.reason.update('test') step.cost_center.select(cost_center) self.check_wizard(wizard, 'stock-decrease-with-cost-center') self.click(wizard.next_button) step = wizard.get_current_step() step.barcode.set_text(sellable.barcode) step.sellable_selected(sellable) step.quantity.update(1) self.click(step.add_sellable_button) with mock.patch.object(self.store, 'commit'): self.click(wizard.next_button) self.assertEqual(wizard.model.cost_center, cost_center) entry = self.store.find(CostCenterEntry, cost_center=wizard.model.cost_center) self.assertEqual(len(list(entry)), 1)
def has_open_inventory(self): return Inventory.has_open(self.store, api.get_current_branch(self.store))
def _has_open_inventory(self): store = self._parent.store has_open = Inventory.has_open(store, api.get_current_branch(store)) return bool(has_open)
def test_complete_receiving(self, yesno, run_dialog, warning): yesno.return_value = True run_dialog.return_value = Settable(skip=Decimal('0')) branch = api.get_current_branch(self.store) order = self.create_purchase_order(branch=branch) order.identifier = 65432 order.open_date = localdatetime(2012, 10, 9) order.expected_receival_date = localdatetime(2012, 9, 25) sellable = self.create_sellable() package = self.create_product(description=u'Package', is_package=True) component = self.create_product(description=u'Component', stock=2) self.create_product_component(product=package, component=component) order.add_item(sellable, 1) parent = order.add_item(package.sellable, 1) order.add_item(component.sellable, 1, parent=parent) order.status = PurchaseOrder.ORDER_PENDING order.confirm(self.current_user) wizard = ReceivingOrderWizard(self.store) step = wizard.get_current_step() self.assertNotSensitive(wizard, ['next_button']) self.click(step.search.search_button) order_view = step.search.results[0] step.search.results.select(order_view) self.assertSensitive(wizard, ['next_button']) self.check_wizard(wizard, 'purchase-selection-step') self.click(wizard.next_button) step = wizard.get_current_step() self.assertSensitive(wizard, ['next_button']) self.check_wizard(wizard, 'receiving-order-product-step') self.click(wizard.next_button) step = wizard.get_current_step() self.assertNotSensitive(wizard, ['next_button']) step.invoice_slave.invoice_number.update(1) self.assertSensitive(wizard, ['next_button']) self.check_wizard(wizard, 'receiving-invoice-step') module = 'stoq.lib.gui.events.ReceivingOrderWizardFinishEvent.emit' with contextlib.nested(mock.patch(module), mock.patch.object(wizard.model, 'confirm'), mock.patch.object(self.store, 'commit')) as (emit, confirm, _): # When this parameter is empty, the user should not be asked # to print labels with self.sysparam(LABEL_TEMPLATE_PATH=u''): self.click(wizard.next_button) self.assertEqual(confirm.call_count, 1) self.assertEqual(yesno.call_count, 0) emit.assert_called_once_with(wizard.model) emit.reset_mock() confirm.reset_mock() # When the file exists, it should ask to print labels, although it # will fail as the file is not valid with self.sysparam(LABEL_TEMPLATE_PATH=u'non-existing-file'): self.click(wizard.next_button) self.assertEqual(emit.call_count, 1) self.assertEqual(confirm.call_count, 1) emit.assert_called_once_with(wizard.model) yesno.assert_called_once_with( "Do you want to print the labels for the received products?", Gtk.ResponseType.YES, "Print labels", "Don't print") run_dialog.assert_called_once_with(SkipLabelsEditor, wizard, self.store) warning.assert_called_once_with( "It was not possible to print the labels. The template " "file was not found.")
def test_get(self): with self.fake_store(): token = self.login() b = api.get_current_branch(self.store) s1 = self.create_sellable(description='s1') self.create_storable(product=s1.product, stock=10, branch=b) s2 = self.create_sellable(description='s2') s2.short_description = '2' self.create_storable(product=s2.product, stock=20, branch=b) s3 = self.create_sellable(description='s3') self.create_storable(product=s3.product, stock=30, branch=b) s4 = self.create_sellable(description='s4') c1 = self.create_sellable_category(description='c1') c2 = self.create_sellable_category(description='c2') c3 = self.create_sellable_category(description='c3') c4 = self.create_sellable_category(description='c4') c2.category = c1 s1.category = c1 s2.category = c2 s3.category = c3 s4.category = c2 img = self.create_image() img.image = b'foobar' img.sellable_id = s1.id img.is_main = True c_ids = [c1.id, c2.id, c3.id, c4.id] def adjust_categories(obj): if isinstance(obj, dict): del obj['id'] for c in obj['children']: adjust_categories(c) obj['products'].sort(key=lambda k: k['description']) for p in obj['products']: del p['id'] elif isinstance(obj, list): obj.sort(key=lambda k: k['description']) for o in obj[:]: if o['id'] not in c_ids: obj.remove(o) else: adjust_categories(o) return obj rv = self.client.get('/data', headers={'Authorization': token}) self.assertEqual(rv.status_code, 200) retval = json.loads(rv.data.decode()) self.assertEqual(retval['branch'], b.id) self.assertEqual( retval['parameters'], { 'NFCE_CAN_SEND_DIGITAL_INVOICE': False, 'NFE_SEFAZ_TIMEOUT': 10, 'PASSBOOK_FIDELITY': None, 'SCALE_BARCODE_FORMAT': 0, 'INCLUDE_CASH_FUND_ON_TILL_CLOSING': False, 'AUTOMATIC_LOGOUT': 0, }) # Those are the default payment methods created by example data self.assertEqual(retval['payment_methods'], [{ 'name': 'bill', 'max_installments': 12 }, { 'name': 'card', 'max_installments': 12, 'card_types': ['credit', 'debit'] }, { 'name': 'check', 'max_installments': 12 }, { 'name': 'credit', 'max_installments': 1 }, { 'name': 'money', 'max_installments': 1 }, { 'name': 'multiple', 'max_installments': 12 }, { 'name': 'store_credit', 'max_installments': 1 }]) self.assertTrue(isinstance(retval['categories'], list)) self.assertEqual(adjust_categories( retval['categories']), [{ 'children': [{ 'children': [], 'description': 'c2', 'order': 0, 'products': [{ 'availability': { b.id: '20.000' }, 'order': '0', 'category_prices': {}, 'color': '', 'description': 's2', 'short_description': '2', 'code': '', 'barcode': '', 'price': '10', 'requires_kitchen_production': False, 'has_image': False }, { 'availability': None, 'order': '0', 'category_prices': {}, 'color': '', 'code': '', 'barcode': '', 'description': 's4', 'short_description': '', 'price': '10', 'requires_kitchen_production': False, 'has_image': False }] }], 'description': 'c1', 'order': 0, 'products': [{ 'availability': { b.id: '10.000' }, 'order': '0', 'category_prices': {}, 'color': '', 'description': 's1', 'short_description': '', 'code': '', 'barcode': '', 'price': '10', 'requires_kitchen_production': False, 'has_image': True }] }, { 'children': [], 'description': 'c3', 'order': 0, 'products': [{ 'availability': { b.id: '30.000' }, 'order': '0', 'category_prices': {}, 'color': '', 'description': 's3', 'short_description': '', 'code': '', 'barcode': '', 'price': '10', 'requires_kitchen_production': False, 'has_image': False }] }, { 'children': [], 'description': 'c4', 'order': 0, 'products': [] }])
def has_open_inventory(self): has_open = Inventory.has_open(self.store, api.get_current_branch(self.store)) return bool(has_open)
def _fill_person_combo(self): items = Person.get_items( self.store, Person.branch != api.get_current_branch(self.store)) self.person.prefill(items)
def create_model(self, store): self._current_branch = api.get_current_branch(store) return Settable(branch=self._current_branch)
def testConfirm(self, create_main_branch): create_main_branch.return_value = api.get_current_branch(self.store) editor = BranchDialog(self.store) editor.name.set_text('minha empresa') editor.cnpj.set_text('00.000.000/0000-00') self.click(editor.main_dialog.ok_button)
def create_model(self, store): return SaleToken(store=self.store, code=u'', name=u'', branch=api.get_current_branch(self.store))
def _query(self, store): branch = api.get_current_branch(self.store) return self.search_spec.find_by_branch(store, branch)
def create_model(self, store): # TODO: Add a parameter for getting a default destination branch return WorkOrderPackage(store=store, identifier=u'', send_responsible=api.get_current_user(store), source_branch=api.get_current_branch(store))
def _get_existing_batches(self): branch = api.get_current_branch(self.store) return StorableBatchView.find_available_by_storable( self.store, self.model, branch=branch)
def testCreate(self, create_main_branch): create_main_branch.return_value = api.get_current_branch(self.store) editor = BranchDialog(self.store) self.check_editor(editor, 'dialog-branch-create', models=[editor.model])
def _create_model(self, store): branch = api.get_current_branch(store) return ProductionOrder(branch=branch, station=api.get_current_station(store), store=store)
def __init__(self, wizard, store, model): self.branch = api.get_current_branch(store) manager = get_plugin_manager() self._nfe_is_active = manager.is_active('nfe') WizardEditorStep.__init__(self, store, wizard, model)
def _get_query(self, state): branch = api.get_current_branch(self.store) return self.search_spec.branch_id == branch.id
def test_get(self): with self.fake_store(): s = self.login() b = api.get_current_branch(self.store) s1 = self.create_sellable(description='s1') self.create_storable(product=s1.product, stock=10, branch=b) s2 = self.create_sellable(description='s2') self.create_storable(product=s2.product, stock=20, branch=b) s3 = self.create_sellable(description='s3') self.create_storable(product=s3.product, stock=30, branch=b) s4 = self.create_sellable(description='s4') c1 = self.create_sellable_category(description='c1') c2 = self.create_sellable_category(description='c2') c3 = self.create_sellable_category(description='c3') c4 = self.create_sellable_category(description='c4') c2.category = c1 s1.category = c1 s2.category = c2 s3.category = c3 s4.category = c2 c_ids = [c1.id, c2.id, c3.id, c4.id] def adjust_categories(obj): if isinstance(obj, dict): del obj['id'] for c in obj['children']: adjust_categories(c) obj['products'].sort(key=lambda k: k['description']) for p in obj['products']: del p['id'] elif isinstance(obj, list): obj.sort(key=lambda k: k['description']) for o in obj[:]: if o['id'] not in c_ids: obj.remove(o) else: adjust_categories(o) return obj rv = self.client.get('/data', headers={'stoq-session': s}) self.assertEqual(rv.status_code, 200) retval = json.loads(rv.data.decode()) self.assertEqual(retval['branch'], b.id) # Those are the default payment methods created by example data self.assertEqual(retval['payment_methods'], [{ 'name': 'bill', 'max_installments': 12 }, { 'name': 'card', 'max_installments': 12, 'card_types': ['credit', 'debit'] }, { 'name': 'check', 'max_installments': 12 }, { 'name': 'credit', 'max_installments': 1 }, { 'name': 'money', 'max_installments': 1 }, { 'name': 'multiple', 'max_installments': 12 }, { 'name': 'store_credit', 'max_installments': 1 }]) self.assertEqual(adjust_categories(retval['categories']), [{ 'children': [{ 'children': [], 'description': 'c2', 'products': [{ 'availability': { b.id: '20.000' }, 'order': '0', 'category_prices': {}, 'color': '', 'description': 's2', 'price': '10' }, { 'availability': None, 'order': '0', 'category_prices': {}, 'color': '', 'description': 's4', 'price': '10' }] }], 'description': 'c1', 'products': [{ 'availability': { b.id: '10.000' }, 'order': '0', 'category_prices': {}, 'color': '', 'description': 's1', 'price': '10' }] }, { 'children': [], 'description': 'c3', 'products': [{ 'availability': { b.id: '30.000' }, 'order': '0', 'category_prices': {}, 'color': '', 'description': 's3', 'price': '10' }] }, { 'children': [], 'description': 'c4', 'products': [] }])
def test_post(self): with self.sysparam(DEMO_MODE=True): with self.fake_store() as es: b = api.get_current_branch(self.store) e = es.enter_context( mock.patch('stoqserver.lib.restful.SaleConfirmedRemoteEvent.emit')) d = datetime.datetime(2018, 3, 6) now = es.enter_context( mock.patch('stoqserver.lib.restful.localnow')) now.return_value = d tt = es.enter_context( mock.patch('stoqlib.domain.sale.TransactionTimestamp')) tt.return_value = d s = self.login() p1 = self.create_product(price=10) p1.manage_stock = False s1 = p1.sellable p2 = self.create_product(price=currency('20.5')) p2.manage_stock = False s2 = p2.sellable c = self.create_client() c.person.individual.cpf = '333.341.828-27' rv = self.client.post( '/sale', headers={'stoq-session': s}, content_type='application/json', data=json.dumps({ 'client_document': '333.341.828-27', 'products': [ {'id': s1.id, 'price': str(s1.price), 'quantity': 2}, {'id': s2.id, 'price': str(s2.price), 'quantity': 1}, ], 'payments': [ {'method': 'money', 'installments': 1, 'value': '10.5'}, {'method': 'card', 'installments': 2, 'value': '30', 'card_type': 'credit'}, ], }), ) self.assertEqual(rv.status_code, 200) self.assertEqual(json.loads(rv.data.decode())['branch'], b.id) # This should be the sale made by the call above sale = self.store.find(Sale).order_by(Desc(Sale.open_date)).first() self.assertEqual(sale.get_total_sale_amount(), currency('40.5')) self.assertEqual(sale.open_date, d) self.assertEqual(sale.confirm_date, d) self.assertEqual( {(i.sellable, i.quantity, i.price) for i in sale.get_items()}, {(s1, 2, s1.price), (s2, 1, s2.price)}) self.assertEqual( {(p.method.method_name, p.due_date, p.value) for p in sale.group.get_items()}, {('card', d, currency('15')), ('card', datetime.datetime(2018, 4, 6), currency('15')), ('money', d, currency('10.5'))} ) self.assertEqual(e.call_count, 1) (sale, doc), _ = e.call_args_list[0] self.assertEqual(doc, '333.341.828-27') # Test the same sale again, but this time, lets mimic an exception # happening in SaleConfirmedRemoteEvent e.side_effect = Exception('foobar exception') # NOTE: This will print the original traceback to stdout, that # doesn't mean that the test is failing (unless it really fail) rv = self.client.post( '/sale', headers={'stoq-session': s}, content_type='application/json', data=json.dumps({ 'client_document': '333.341.828-27', 'products': [ {'id': s1.id, 'price': str(s1.price), 'quantity': 2}, {'id': s2.id, 'price': str(s2.price), 'quantity': 1}, ], 'payments': [ {'method': 'money', 'value': '40.5'}, ], }), ) self.assertEqual(rv.status_code, 500) self.assertEqual(json.loads(rv.data.decode()), {'message': 'foobar exception'})
def test_confirm(self, run_dialog, yesno): WorkOrderCategory(store=self.store, name=u'Category', color=u'#ff0000') client = self.create_client() medic = self.create_optical_medic() self.create_address(person=client.person) yesno.return_value = False # Test for reserve without storable sellable = self.create_sellable() sellable.barcode = u'12345678' # Test for reserve with storable sellable2 = self.create_sellable() sellable2.barcode = u'12345679' self.create_storable(product=sellable2.product, branch=api.get_current_branch(self.store), stock=10) # Test for reserve for a batch with storable sellable3 = self.create_sellable() sellable3.barcode = u'12345680' storable, batch = self.create_storable(product=sellable3.product, branch=api.get_current_branch( self.store), is_batch=True, stock=10) # Test for return_to_stock sellable4 = self.create_sellable() sellable4.barcode = u'12345681' self.create_storable(product=sellable4.product) wizard = OpticalSaleQuoteWizard(self.store) step = wizard.get_current_step() step.client_gadget.set_value(client) run_dialog.return_value = False self.click(step.notes_button) self.assertEquals(run_dialog.call_count, 1) args, kwargs = run_dialog.call_args editor, parent, store, model, comment = args self.assertEquals(editor, NoteEditor) self.assertEquals(parent, wizard) self.assertTrue(store is not None) self.assertTrue(isinstance(model, SaleComment)) self.assertEquals(comment, 'comment') self.assertEquals(kwargs['title'], _("Additional Information")) self.check_wizard(wizard, 'wizard-optical-start-sale-quote-step') self.click(wizard.next_button) step = wizard.get_current_step() slave = step.slaves['WO 1'] slave.patient.update('Patient') slave.medic_combo.update(medic) slave.estimated_finish.update(localdate(2020, 1, 5)) sale = wizard.model self.check_wizard(wizard, 'wizard-optical-work-order-step') self.click(wizard.next_button) step = wizard.get_current_step() for barcode in [ batch.batch_number, sellable.barcode, sellable2.barcode, sellable4.barcode ]: step.barcode.set_text(barcode) self.activate(step.barcode) step.quantity.update(1) self.click(step.add_sellable_button) for item in step.slave.klist: if item.sellable == sellable4: wo_item = WorkOrderItem.get_from_sale_item(self.store, item) wo_item.quantity_decreased = 10 self.check_wizard(wizard, 'wizard-optical-item-step', [sale, client] + list(sale.get_items().order_by('te_id'))) module = 'stoqlib.gui.events.SaleQuoteWizardFinishEvent.emit' with mock.patch(module) as emit: with mock.patch.object(self.store, 'commit'): self.click(wizard.next_button) self.assertEquals(emit.call_count, 1) args, kwargs = emit.call_args self.assertTrue(isinstance(args[0], Sale)) self.assertEqual(wizard.model.payments.count(), 0) yesno.assert_called_once_with( _('Would you like to print the quote ' 'details now?'), gtk.RESPONSE_YES, _("Print quote details"), _("Don't print")) # Test get_saved_items, using the existing model here wizard2 = OpticalSaleQuoteWizard(self.store, model=wizard.model) self.click(wizard2.next_button) self.click(wizard2.next_button)
def __init__(self, wizard, previous, store, model): self.branch = api.get_current_branch(store) SellableItemStep.__init__(self, wizard, previous, store, model)
def __init__(self, wizard, store, model): self.branch = api.get_current_branch(store) WizardEditorStep.__init__(self, store, wizard, model)
def test_confirm(self, yesno, print_report): client = self.create_client() branch = api.get_current_branch(self.store) storable = self.create_storable(branch=branch, stock=1, unit_cost=10) sellable = storable.product.sellable wizard = NewLoanWizard(self.store) step = wizard.get_current_step() step.client_gadget.set_value(client) step.expire_date.update(localtoday().date()) self.check_wizard(wizard, 'new-loan-wizard-start-step') self.click(wizard.next_button) step = wizard.get_current_step() step.barcode.set_text(sellable.barcode) step.sellable_selected(sellable) # This is a workaround to be able to set a value bigger than MAX_INT, # so we can get its validation step.quantity.get_adjustment().set_upper(MAX_INT + 1) # Checking values bigger than MAX_INT for quantity step.quantity.update(MAX_INT + 1) self.assertInvalid(step, ['quantity']) # Checking values bigger than we have on stock step.quantity.update(2) self.assertInvalid(step, ['quantity']) # Checking negative value step.quantity.update(-1) self.assertInvalid(step, ['quantity']) # Checking valid values step.quantity.update(1) self.assertValid(step, ['quantity']) # Checking negative value step.cost.update(-1) self.assertInvalid(step, ['cost']) # This is a workaround to be able to set a value bigger than MAX_INT, # so we can get its validation step.cost.get_adjustment().set_upper(MAX_INT + 1) # Checking values bigger than MAX_INT for cost step.cost.update(MAX_INT + 1) self.assertInvalid(step, ['cost']) # Checking valid value step.cost.update(10) self.assertValid(step, ['cost']) self.click(step.add_sellable_button) loan_item = self.store.find(LoanItem, sellable=sellable).one() module = 'stoq.lib.gui.events.NewLoanWizardFinishEvent.emit' with mock.patch(module) as emit: with mock.patch.object(self.store, 'commit'): self.click(wizard.next_button) self.assertEqual(emit.call_count, 1) args, kwargs = emit.call_args self.assertTrue(isinstance(args[0], Loan)) self.check_wizard(wizard, 'new-loan-wizard-item-step', [wizard.retval, loan_item]) yesno.assert_called_once_with('Would you like to print the receipt now?', Gtk.ResponseType.YES, 'Print receipt', "Don't print") self.assertEqual(print_report.call_count, 1) # verifies if stock was decreased correctly self.assertEqual(storable.get_balance_for_branch(branch), 0)
def __init__(self, store, model=None, visual_mode=False): from stoq.lib.gui.slaves.sellableslave import CategoryPriceSlave is_new = not model self._sellable = None self._demo_mode = sysparam.get_bool('DEMO_MODE') self._requires_weighing_text = ( "<b>%s</b>" % stoq_api.escape(_("This unit type requires weighing"))) if self.ui_form_name: self.db_form = DatabaseForm(self.ui_form_name) else: self.db_form = None BaseEditor.__init__(self, store, model, visual_mode) self.enable_window_controls() if self._demo_mode: self._add_demo_warning() # Code suggestion. We need to do this before disabling sensitivity, # otherwise, the sellable will not be updated. if not self.code.read(): self._update_default_sellable_code() edit_code_product = sysparam.get_bool('EDIT_CODE_PRODUCT') self.code.set_sensitive(not edit_code_product and not self.visual_mode) self.description.grab_focus() self.table.set_focus_chain([self.code, self.barcode, self.default_sale_cfop, self.description, self.cost_hbox, self.price_hbox, self.category_combo, self.tax_hbox, self.unit_combo, ]) self._print_labels_btn = self.add_button('print_labels', Gtk.STOCK_PRINT) self._print_labels_btn.connect('clicked', self.on_print_labels_clicked, 'print_labels') label = self._print_labels_btn.get_children()[0] label = label.get_children()[0].get_children()[1] label.set_label(_(u'Print labels')) self.setup_widgets() if not is_new and not self.visual_mode: # Although a sellable can be both removed/closed, we show only one, # to avoid having *lots* of buttons. If it's closed, provide a way # to reopen it, else, show a delete button if it can be removed # or a close button if it can be closed if self._sellable.is_closed(api.get_current_branch(self.store)): self._add_reopen_button() elif self._sellable.can_remove(): self._add_delete_button() elif self._sellable.can_close(): self._add_close_button() self.set_main_tab_label(self.model_name) image_gallery_slave = ImageGallerySlave( self.store, self.model.sellable, self.visual_mode) self.add_extra_tab(_(u'Images'), image_gallery_slave) price_slave = CategoryPriceSlave(self.store, self.model.sellable, self.visual_mode) self.add_extra_tab(_(u'Category Prices'), price_slave) self._setup_ui_forms() self._update_print_labels() self._update_price()
def __init__(self, store, wizard, transfer_order, previous): self.store = store self.transfer_order = transfer_order self.branch = api.get_current_branch(self.store) BaseWizardStep.__init__(self, self.store, wizard, previous) self.setup_proxies()
def _get_orders(self): branch = api.get_current_branch(self.store) query = Eq(WorkOrderView.branch_id, branch.id) result = WorkOrderView.find_pending(self.store).find(query) return result.order_by(WorkOrder.estimated_finish, WorkOrder.status)
def _setup_widgets(self): if self._is_batch: self._add_batches_tab() self.receiving_list.set_columns(self._get_receiving_columns()) self.sales_list.set_columns(self._get_sale_columns()) self.transfer_list.set_columns(self._get_transfer_columns()) self.loan_list.set_columns(self._get_loan_columns()) self.decrease_list.set_columns(self._get_decrease_columns()) self.inventory_list.set_columns(self._get_inventory_columns()) self.returned_list.set_columns(self._get_returned_columns()) current_branch = api.get_current_branch(self.store) items = self.store.find(ReceivingItemView, sellable_id=self.model.id) if api.sysparam.get_bool('SYNCHRONIZED_MODE'): items = items.find(Branch.id == current_branch.id) self.receiving_list.add_list(list(items)) items = SaleItemsView.find_confirmed(self.store, sellable=self.model) if api.sysparam.get_bool('SYNCHRONIZED_MODE'): items = items.find(Branch.id == current_branch.id) self.sales_list.add_list(list(items)) items = TransferItemView.find_by_branch(self.store, self.model, current_branch) self.transfer_list.add_list(list(items)) items = self.store.find(LoanItemView, sellable_id=self.model.id) if api.sysparam.get_bool('SYNCHRONIZED_MODE'): items = items.find(Branch.id == current_branch.id) self.loan_list.add_list(list(items)) items = self.store.find(StockDecreaseItemsView, sellable=self.model.id) if api.sysparam.get_bool('SYNCHRONIZED_MODE'): items = items.find(Branch.id == current_branch.id) self.decrease_list.add_list(list(items)) items = InventoryItemsView.find_by_product(self.store, self.model.product) if api.sysparam.get_bool('SYNCHRONIZED_MODE'): items = items.find(Branch.id == current_branch.id) self.inventory_list.add_list(items) items = self.store.find(ReturnedSaleItemsView, sellable_id=self.model.id) if api.sysparam.get_bool('SYNCHRONIZED_MODE'): items = items.find(Branch.id == current_branch.id) self.returned_list.add_list(items) value_format = '<b>%s</b>' total_label = "<b>%s</b>" % api.escape(_("Total:")) receiving_summary_label = SummaryLabel(klist=self.receiving_list, column='quantity', label=total_label, value_format=value_format) receiving_summary_label.show() self.receiving_vbox.pack_start(receiving_summary_label, False) sales_summary_label = SummaryLabel(klist=self.sales_list, column='quantity', label=total_label, value_format=value_format) sales_summary_label.show() self.sales_vbox.pack_start(sales_summary_label, False) transfer_summary_label = SummaryLabel(klist=self.transfer_list, column='item_quantity', label=total_label, value_format=value_format) transfer_summary_label.show() self.transfer_vbox.pack_start(transfer_summary_label, False) loan_summary_label = SummaryLabel(klist=self.loan_list, column='quantity', label=total_label, value_format=value_format) self.loan_vbox.pack_start(loan_summary_label, False) decrease_summary_label = SummaryLabel(klist=self.decrease_list, column='quantity', label=total_label, value_format=value_format) decrease_summary_label.show() self.decrease_vbox.pack_start(decrease_summary_label, False)
def get_title(self): # This method must be redefined in child when it's needed branch = api.get_current_branch(self.store) return _('[%s] - %s') % (branch.get_description(), self.app_title)
def get_title(self): return _('Stoq - Till for Branch %03d') % (api.get_current_branch( self.store).id, )
def get_title(self): return _('[%s] - Till') % ( api.get_current_branch(self.store).get_description(), )