def test_apply_discount(self, run_dialog): sellable = self.create_sellable(price=100, product=True) sellable.barcode = u'123' wizard = SaleQuoteWizard(self.store) self.click(wizard.next_button) step = wizard.get_current_step() step.barcode.set_text(u'123') self.activate(step.barcode) self.click(step.add_sellable_button) label = step.summary.get_value_widget() self.assertEqual(label.get_text(), '$100.00') # 10% of discount step.model.set_items_discount(decimal.Decimal(10)) run_dialog.return_value = True self.click(step.discount_btn) run_dialog.assert_called_once_with( DiscountEditor, step.parent, step.store, step.model, user=api.get_current_user(step.store)) self.assertEqual(label.get_text(), '$90.00') # Cancelling the dialog this time run_dialog.reset_mock() run_dialog.return_value = None self.click(step.discount_btn) run_dialog.assert_called_once_with( DiscountEditor, step.parent, step.store, step.model, user=api.get_current_user(step.store)) self.assertEqual(label.get_text(), '$90.00')
def create_model(self, store): return Calls(date=datetime.date.today(), description=u'', message=u'', person=self.person, attendant=api.get_current_user(self.store), store=store)
def on_confirm(self): till = self.model.till removed = abs(self.model.value) if removed: # We need to do this inside a new transaction, because if the # till closing fails further on, this still needs to be recorded # in the database store = api.new_store() t_till = store.fetch(till) TillRemoveCashEvent.emit(till=t_till, value=removed) reason = _('Amount removed from Till by %s') % ( api.get_current_user(self.store).get_description(), ) till_entry = t_till.add_debit_entry(removed, reason) # Financial transaction _create_transaction(store, till_entry) # DB transaction store.confirm(True) store.close() if self._close_ecf: try: retval = TillCloseEvent.emit(till=till, previous_day=self._previous_day) except (TillError, DeviceError), e: warning(str(e)) return None # If the event was captured and its return value is False, then we # should not close the till. if retval is False: return False
def on_ManageStock__activate(self, action): user = api.get_current_user(self.store) if not user.profile.check_app_permission(u'inventory'): return warning(_('Only users with access to the inventory app can' ' change the stock quantity')) product = self.results.get_selected().product if product.storable and product.storable.is_batch: return warning(_("It's not possible to change the stock quantity of" " a batch product")) branch = self.branch_filter.combo.get_selected() if not branch: return warning(_('You must select a branch first')) if (api.sysparam.get_bool('SYNCHRONIZED_MODE') and branch != api.get_current_branch(self.store)): return warning(_('You can only change the stock of your current branch')) with api.new_store() as store: self.run_dialog(ProductStockQuantityEditor, store, store.fetch(product), branch=branch) if store.committed: self.refresh()
def on_cost__validate(self, widget, value): sellable = self.proxy.model.sellable if not sellable: return # Dont allow numbers bigger than MAX_INT (see stoqlib.lib.defaults) if value > MAX_INT: return ValidationError(_("Price cannot be bigger than %s") % MAX_INT) if value <= 0: return ValidationError(_(u"Cost must be greater than zero.")) if self.validate_price: category = getattr(self.model, "client_category", None) default_price = sellable.get_price_for_category(category) if not sysparam.get_bool("ALLOW_HIGHER_SALE_PRICE") and value > default_price: return ValidationError(_(u"The sell price cannot be greater " "than %s.") % default_price) manager = self.manager or api.get_current_user(self.store) client = getattr(self.model, "client", None) category = client and client.category extra_discount = self.get_extra_discount(sellable) valid_data = sellable.is_valid_price(value, category, manager, extra_discount=extra_discount) if not valid_data["is_valid"]: return ValidationError((_(u"Max discount for this product is %.2f%%.") % valid_data["max_discount"]))
def on_cost__validate(self, widget, value): sellable = self.proxy.model.sellable if not sellable: return if value <= 0: return ValidationError(_(u'Cost must be greater than zero.')) if self.validate_price: category = getattr(self.model, 'client_category', None) default_price = sellable.get_price_for_category(category) if (not sysparam.get_bool('ALLOW_HIGHER_SALE_PRICE') and value > default_price): return ValidationError(_(u'The sell price cannot be greater ' 'than %s.') % default_price) manager = self.manager or api.get_current_user(self.store) client = getattr(self.model, 'client', None) category = client and client.category extra_discount = self.get_extra_discount(sellable) valid_data = sellable.is_valid_price(value, category, manager, extra_discount=extra_discount) if not valid_data['is_valid']: return ValidationError( (_(u'Max discount for this product is %.2f%%.') % valid_data['max_discount']))
def on_SalesCancel__activate(self, action): sale_view = self.results.get_selected() can_cancel = api.sysparam.get_bool('ALLOW_CANCEL_LAST_COUPON') if can_cancel and ECFIsLastSaleEvent.emit(sale_view.sale): info(_("That is last sale in ECF. Return using the menu " "ECF - Cancel Last Document")) return store = api.new_store() sale = store.fetch(sale_view.sale) msg_text = _(u"This will cancel the sale, Are you sure?") model = SaleComment(store=store, sale=sale, author=api.get_current_user(store)) retval = self.run_dialog( NoteEditor, store, model=model, attr_name='comment', message_text=msg_text, label_text=_(u"Reason"), mandatory=True, ok_button_label=_(u"Cancel sale"), cancel_button_label=_(u"Don't cancel")) if not retval: store.rollback() return sale.cancel() store.commit(close=True) self.refresh()
def on_price__validate(self, widget, value): if value <= 0: return ValidationError(_(u"The price must be greater than zero.")) if (not sysparam.get_bool('ALLOW_HIGHER_SALE_PRICE') and value > self.model.base_price): return ValidationError(_(u'The sell price cannot be greater ' 'than %s.') % self.model.base_price) sellable = self.model.sellable manager = self.manager or api.get_current_user(self.store) if api.sysparam.get_bool('REUTILIZE_DISCOUNT'): extra_discount = self.model.sale.get_available_discount_for_items( user=manager, exclude_item=self.model) else: extra_discount = None valid_data = sellable.is_valid_price( value, category=self.model.sale.client_category, user=manager, extra_discount=extra_discount) if not valid_data['is_valid']: return ValidationError( (_(u'Max discount for this product is %.2f%%.') % valid_data['max_discount']))
def _create_receiving_order(self): # since we will create a new receiving order, we should confirm the # purchase first. Note that the purchase may already be confirmed if self.model.status in [PurchaseOrder.ORDER_PENDING, PurchaseOrder.ORDER_CONSIGNED]: self.model.confirm() temporary_identifier = None if self.wizard.is_for_another_branch(): temporary_identifier = ReceivingOrder.get_temporary_identifier(self.store) receiving_invoice = ReceivingInvoice( store=self.store, supplier=self.model.supplier, branch=self.model.branch, responsible=api.get_current_user(self.store)) receiving_model = ReceivingOrder( identifier=temporary_identifier, receiving_invoice=receiving_invoice, responsible=receiving_invoice.responsible, branch=self.model.branch, invoice_number=None, store=self.store) receiving_model.add_purchase(self.model) # Creates ReceivingOrderItem's for item in self.model.get_pending_items(): receiving_model.add_purchase_item(item) self.wizard.receiving_model = receiving_model
def test_price_validation(self): user = api.get_current_user(self.store) user.profile.max_discount = 2 editor = self._create_editor() with self.sysparam(ALLOW_HIGHER_SALE_PRICE=True): editor.price.update(101) self.assertValid(editor, ['price']) editor.price.update(98) self.assertValid(editor, ['price']) editor.price.update(97) self.assertInvalid(editor, ['price']) editor.price.update(-1) self.assertInvalid(editor, ['price']) with self.sysparam(ALLOW_HIGHER_SALE_PRICE=False): editor.price.update(101) self.assertInvalid(editor, ['price']) editor.price.update(98) self.assertValid(editor, ['price']) editor.price.update(97) self.assertInvalid(editor, ['price']) editor.price.update(-1) self.assertInvalid(editor, ['price']) with self.sysparam(REUTILIZE_DISCOUNT=True): editor.price.update(10) self.assertInvalid(editor, ['price']) with self.sysparam(REUTILIZE_DISCOUNT=False): editor.price.update(10) self.assertInvalid(editor, ['price'])
def fields(self): # Only users with admin or purchase permission can modify transporters user = api.get_current_user(self.store) can_modify_transporter = any(( user.profile.check_app_permission(u'admin'), user.profile.check_app_permission(u'purchase'), )) freight_types = [(v, k) for k, v in Delivery.freights.items()] states = [(v, v) for v in api.get_l10n_field('state').state_list] return collections.OrderedDict( recipient=PersonQueryField(_("Recipient"), proxy=True, mandatory=True, person_type=self.person_type), transporter_id=PersonField(_("Transporter"), proxy=True, person_type=Transporter, can_add=can_modify_transporter, can_edit=can_modify_transporter), address=AddressField(_("Address"), proxy=True, mandatory=True), freight_type=ChoiceField(_("Freight type"), proxy=True, values=freight_types), price=PriceField(_("Delivery cost"), proxy=True), estimated_fix_date=DateField(_("Estimated delivery date"), proxy=True), volumes_kind=TextField(_("Volumes kind"), proxy=True), volumes_quantity=IntegerField(_("Volumes quantity"), proxy=True), volumes_net_weight=NumericField(_("Volumes net weight"), proxy=True, digits=3), volumes_gross_weight=NumericField(_("Volumes gross weight"), proxy=True, digits=3), vehicle_license_plate=TextField(_("Vehicle license plate"), proxy=True), vehicle_state=ChoiceField(_("Vehicle state"), proxy=True, use_entry=True, values=states), vehicle_registration=TextField(_("Vehicle registration"), proxy=True), )
def on_ChangePassword__activate(self, action): from stoqlib.gui.slaves.userslave import PasswordEditor store = api.new_store() user = api.get_current_user(store) retval = run_dialog(PasswordEditor, self, store, user) store.confirm(retval) store.close()
def test_show(self): workorder = self.create_workorder(description=u'Test equipment') workorder.client = self.create_client() workorder.client.category = self.create_client_category() product = self.create_product(stock=10) sellable = product.sellable storable = product.storable item = workorder.add_sellable(sellable) editor = _WorkOrderItemEditor(self.store, model=item) self.check_editor(editor, 'editor-workorderitem-show') self.assertValid(editor, ['price']) editor.price.update(0) self.assertInvalid(editor, ['price']) editor.price.update(-1) self.assertInvalid(editor, ['price']) with mock.patch.object(sellable, 'is_valid_price') as ivp: ivp.return_value = { 'is_valid': False, 'min_price': decimal.Decimal('10.00'), 'max_discount': decimal.Decimal('0.00'), } editor.price.update(1) ivp.assert_called_once_with(1, workorder.client.category, api.get_current_user(self.store)) self.assertInvalid(editor, ['price']) self.assertValid(editor, ['quantity']) with mock.patch.object(storable, 'get_balance_for_branch') as gbfb: gbfb.return_value = 0 editor.quantity.update(20) gbfb.assert_called_once_with(workorder.branch) self.assertInvalid(editor, ['quantity'])
def get_columns(self): columns = [SearchColumn('code', title=_(u'Code'), data_type=str), SearchColumn('barcode', title=_('Barcode'), data_type=str, sort_func=sort_sellable_code, width=80), SearchColumn('category_description', title=_('Category'), data_type=str, width=120), SearchColumn('description', title=_('Description'), data_type=str, expand=True, sorted=True), SearchColumn('location', title=_('Location'), data_type=str, visible=False), SearchColumn('manufacturer', title=_('Manufacturer'), data_type=str, visible=False), SearchColumn('model', title=_('Model'), data_type=str, visible=False)] user = api.get_current_user(self.store) if user.profile.check_app_permission('purchase'): columns.append(SearchColumn('cost', title=_(u'Cost'), data_type=currency, visible=True)) if hasattr(self.search_spec, 'price'): columns.append(SearchColumn('price', title=_(u'Price'), data_type=currency, visible=True)) if hasattr(self.search_spec, 'minimum_quantity'): columns.append(SearchColumn('minimum_quantity', title=_(u'Minimum Qty'), data_type=Decimal, visible=False)) if hasattr(self.search_spec, 'stock'): columns.append(QuantityColumn('stock', title=_(u'In Stock'))) return columns
def _create_receiving_order(self): supplier_id = self.purchases[0].supplier_id branch_id = self.purchases[0].branch_id # If the receiving is for another branch, we need a temporary identifier temporary_identifier = None if (api.sysparam.get_bool('SYNCHRONIZED_MODE') and api.get_current_branch(self.store).id != branch_id): temporary_identifier = ReceivingOrder.get_temporary_identifier(self.store) # We cannot create the model in the wizard since we haven't # selected a PurchaseOrder yet which ReceivingOrder depends on # Create the order here since this is the first place where we # actually have a purchase selected receiving_invoice = ReceivingInvoice( supplier=supplier_id, store=self.store, branch=branch_id, responsible=api.get_current_user(self.store)) self.wizard.model = self.model = ReceivingOrder( identifier=temporary_identifier, receiving_invoice=receiving_invoice, responsible=receiving_invoice.responsible, invoice_number=None, branch=branch_id, store=self.store) for row in self.purchases: self.model.add_purchase(row.purchase)
def __init__(self, resource, manager, compact=False): self._resource = resource self._compact = compact self._manager = manager user = api.get_current_user(api.get_default_store()) self._is_admin = user.profile.check_app_permission(u'admin') super(ResourceStatusBox, self).__init__(spacing=6) if compact: self.props.margin = 6 else: self.props.margin = 12 self.img = Gtk.Image() self.pack_start(self.img, False, True, 0) self.lbl = Gtk.Label() self.lbl.set_xalign(0) self.lbl.set_line_wrap(True) self.pack_start(self.lbl, False, True, 0) self.buttonbox = Gtk.Box() self.buttonbox.set_valign(Gtk.Align.CENTER) self.buttonbox.get_style_context().add_class('linked') if not compact: self.pack_end(self.buttonbox, False, True, 0)
def finish(self): for payment in self.model.group.payments: if payment.is_preview(): # Set payments created on SaleReturnPaymentStep as pending payment.set_pending() total_amount = self.model.total_amount # If the user chose to create credit for the client instead of returning # money, there is no need to display this messages. if not self.credit: if total_amount == 0: info(_("The client does not have a debt to this sale anymore. " "Any existing unpaid installment will be cancelled.")) elif total_amount < 0: info(_("A reversal payment to the client will be created. " "You can see it on the Payable Application.")) login_user = api.get_current_user(self.store) self.model.return_(method_name=u'credit' if self.credit else u'money', login_user=login_user) SaleReturnWizardFinishEvent.emit(self.model) self.retval = self.model self.close() # Commit before printing to avoid losing data if something breaks self.store.confirm(self.retval) if self.credit: if yesno(_(u'Would you like to print the credit letter?'), gtk.RESPONSE_YES, _(u"Print Letter"), _(u"Don't print")): print_report(ClientCreditReport, self.model.client)
def _check_client_birthdays(self): if not api.sysparam.get_bool('BIRTHDAY_NOTIFICATION'): return # Display the info bar once per day date = api.user_settings.get('last-birthday-check') last_check = date and datetime.datetime.strptime(date, '%Y-%m-%d').date() if last_check and last_check >= datetime.date.today(): return # Only display the infobar if the user has access to calendar (because # clicking on the button will open it) and to sales (because it # requires that permission to be able to check client details) user = api.get_current_user(self.store) if not all([user.profile.check_app_permission(u'calendar'), user.profile.check_app_permission(u'sales')]): return branch = api.get_current_branch(self.store) clients_count = ClientWithSalesView.find_by_birth_date( self.store, datetime.datetime.today(), branch=branch).count() if clients_count: msg = stoqlib_ngettext( _("There is %s client doing birthday today!"), _("There are %s clients doing birthday today!"), clients_count) % (clients_count, ) button = gtk.Button(_("Check the calendar")) button.connect('clicked', self._on_check_calendar__clicked) self._birthdays_bar = self.add_info_bar( gtk.MESSAGE_INFO, "<b>%s</b>" % (glib.markup_escape_text(msg), ), action_widget=button)
def create_actions(self): group = get_accels('app.financial') actions = [ ('Import', Gtk.STOCK_ADD, _('Import...'), group.get('import'), _('Import a GnuCash or OFX file')), ('ConfigurePaymentMethods', None, _('Payment methods'), group.get('configure_payment_methods'), _('Select accounts for the payment methods on the system')), ('Delete', None, _('Delete...')), ("NewAccount", Gtk.STOCK_NEW, _("Account..."), group.get('new_account'), _("Add a new account")), ("NewTransaction", Gtk.STOCK_NEW, _("Transaction..."), group.get('new_store'), _("Add a new transaction")), ("Edit", Gtk.STOCK_EDIT, _("Edit..."), group.get('edit')), ] self.financial_ui = self.add_ui_actions(actions) self.set_help_section(_("Financial help"), 'app-financial') user = api.get_current_user(self.store) if not user.profile.check_app_permission(u'admin'): self.set_sensitive([self.ConfigurePaymentMethods], False)
def on_SalesCancel__activate(self, action): sale_view = self.results.get_selected() can_cancel = api.sysparam.get_bool('ALLOW_CANCEL_LAST_COUPON') # A plugin (e.g. ECF) can avoid the cancelation of a sale # because it wants it to be cancelled using another way if can_cancel and SaleAvoidCancelEvent.emit(sale_view.sale): return store = api.new_store() sale = store.fetch(sale_view.sale) msg_text = _(u"This will cancel the sale, Are you sure?") model = SaleComment(store=store, sale=sale, author=api.get_current_user(store)) retval = self.run_dialog( NoteEditor, store, model=model, attr_name='comment', message_text=msg_text, label_text=_(u"Reason"), mandatory=True, ok_button_label=_(u"Cancel sale"), cancel_button_label=_(u"Don't cancel")) if not retval: store.rollback() return sale.cancel() store.commit(close=True) self.refresh()
def test_create(self, set_message): sellable = self.create_sellable() self.create_storable(product=sellable.product) sale_item = TemporarySaleItem(sellable=sellable, quantity=1) user = api.get_current_user(self.store) with mock.patch.object(user.profile, 'check_app_permission') as has_acess: has_acess.side_effect = [False] search = SaleSellableSearch(self.store, sale_items=[sale_item], quantity=1) self.assertRaises(TypeError, SaleSellableSearch, self.store, sale_items=[sale_item], selection_mode=Gtk.SelectionMode.MULTIPLE) self.assertRaises(TypeError, SaleSellableSearch, self.store, sale_items=[sale_item], quantity=None) search = SaleSellableSearch(self.store) search.search.refresh() self.check_search(search, 'sale-sellable-no-filter') search = SaleSellableSearch(self.store, info_message='test') set_message.assert_called_once_with('test') search = SaleSellableSearch(self.store, search_str='cal') self.check_search(search, 'sale-sellable-string-filter')
def search_products(self): with api.new_store() as store: profile = api.get_current_user(store).profile can_create = (profile.check_app_permission('admin') or profile.check_app_permission('purchase')) run_dialog(ProductSearch, None, store, hide_footer=True, hide_toolbar=not can_create, hide_cost_column=not can_create)
def _create_model(self, store): user = api.get_current_user(store) source_responsible = store.find(Employee, person=user.person).one() return TransferOrder( source_branch=api.get_current_branch(store), source_responsible=source_responsible, destination_branch=Branch.get_active_remote_branches(store)[0], store=store)
def _create_model(self, store): loan = Loan(responsible=api.get_current_user(store), branch=api.get_current_branch(store), store=store) # Temporarily save the client_category, so it works fine with # SaleQuoteItemStep loan.client_category = None return loan
def create_model(self, store): return CreditCheckHistory(check_date=localtoday().date(), identifier=u'', status=CreditCheckHistory.STATUS_NOT_INCLUDED, client=self._client, notes=u'', user=api.get_current_user(self.store), store=store)
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 on_receive_button__clicked(self, event): if yesno(_(u'Receive pending returned sale?'), gtk.RESPONSE_NO, _(u'Receive'), _(u"Don't receive")): current_user = api.get_current_user(self.store) self.model.returned_sale.confirm(current_user) SaleReturnWizardFinishEvent.emit(self.model.returned_sale) self.store.commit(close=False) self._setup_status()
def __init__(self, store): self.open_date = localnow() self.branch = api.get_current_branch(store) self.branch_name = self.branch.get_description() self.user = api.get_current_user(store) self.product_manufacturer = None self.product_brand = None self.product_family = None
def test_apply_discount(self, run_dialog, run_person_role_dialog): client = self.create_client() self.create_address(person=client.person) run_person_role_dialog.return_value = client sellable = self.create_sellable(price=100, product=True) sellable.barcode = u'123' wizard = OpticalSaleQuoteWizard(self.store) step = wizard.get_current_step() self.click(step.create_client) self.click(wizard.next_button) step = wizard.get_current_step() slave = step.slaves['WO 1'] slave.patient.update('Patient') slave.estimated_finish.update(localdate(2020, 1, 5)) self.click(wizard.next_button) step = wizard.get_current_step() step.item_slave.barcode.set_text(u'123') self.activate(step.item_slave.barcode) self.click(step.item_slave.add_sellable_button) label = step.item_slave.summary.get_value_widget() self.assertEqual(label.get_text(), '$100.00') # 10% of discount step.model.set_items_discount(decimal.Decimal(10)) run_dialog.return_value = True self.click(step.item_slave.discount_btn) run_dialog.assert_called_once_with( DiscountEditor, step.item_slave.parent, step.item_slave.store, step.item_slave.model, user=api.get_current_user(step.store)) self.assertEqual(label.get_text(), '$90.00') # Cancelling the dialog this time run_dialog.reset_mock() run_dialog.return_value = None self.click(step.item_slave.discount_btn) run_dialog.assert_called_once_with( DiscountEditor, step.item_slave.parent, step.item_slave.store, step.item_slave.model, user=api.get_current_user(step.store)) self.assertEqual(label.get_text(), '$90.00')
def on_RemoveSettingsCache__activate(self, action): keys = ["app-ui", "launcher-geometry"] keys.append("search-columns-%s" % (api.get_current_user(api.get_default_store()).username,)) for key in keys: try: api.user_settings.remove(key) except KeyError: pass
def create_actions(self): group = get_accels('app.calendar') actions = [ # File ('NewClientCall', None, _("Client call"), group.get('new_client_call'), _("Add a new client call")), ('NewPayable', None, _("Account payable"), group.get('new_payable'), _("Add a new account payable")), ('NewReceivable', None, _("Account receivable"), group.get('new_receivable'), _("Add a new account receivable")), ('NewWorkOrder', None, _("Work order"), group.get('new_work_order'), _("Add a new work order")), # View ('Back', gtk.STOCK_GO_BACK, _("Back"), group.get('go_back'), _("Go back")), ('Forward', gtk.STOCK_GO_FORWARD, _("Forward"), group.get('go_forward'), _("Go forward")), ('Today', STOQ_CALENDAR_TODAY, _("Show today"), group.get('show_today'), _("Show today")), ('CalendarEvents', None, _("Calendar events")), ('CurrentView', None, _("Display view as")), ] self.calendar_ui = self.add_ui_actions('', actions, filename='calendar.xml') self.set_help_section(_("Calendar help"), 'app-calendar') toggle_actions = [ ('AccountsPayableEvents', None, _("Accounts payable"), None, _("Show accounts payable in the list")), ('AccountsReceivableEvents', None, _("Accounts receivable"), None, _("Show accounts receivable in the list")), ('PurchaseEvents', None, _("Purchases"), None, _("Show purchases in the list")), ('ClientCallEvents', None, _("Client Calls"), None, _("Show client calls in the list")), ('ClientBirthdaysEvents', None, _("Client Birthdays"), None, _("Show client birthdays in the list")), ('WorkOrderEvents', None, _("Work orders"), None, _("Show work orders in the list")), ] self.add_ui_actions('', toggle_actions, 'ToggleActions', 'toggle') events_info = dict( in_payments=(self.AccountsReceivableEvents, self.NewReceivable, u'receivable'), out_payments=(self.AccountsPayableEvents, self.NewPayable, u'payable'), purchase_orders=(self.PurchaseEvents, None, u'stock'), client_calls=(self.ClientCallEvents, self.NewClientCall, u'sales'), client_birthdays=(self.ClientBirthdaysEvents, None, u'sales'), work_orders=(self.WorkOrderEvents, self.NewWorkOrder, u'services'), ) user = api.get_current_user(self.store) events = self._calendar.get_events() for event_name, value in events_info.items(): view_action, new_action, app = value view_action.props.active = events[event_name] # Disable feature if user does not have acces to required # application if not user.profile.check_app_permission(app): view_action.props.active = False view_action.set_sensitive(False) if new_action: new_action.set_sensitive(False) view_action.connect('notify::active', self._update_events) self._update_events() radio_actions = [ ('ViewMonth', STOQ_CALENDAR_MONTH, _("View as month"), '', _("Show one month")), ('ViewWeek', STOQ_CALENDAR_WEEK, _("View as week"), '', _("Show one week")), ('ViewDay', STOQ_CALENDAR_LIST, _("View as day"), '', _("Show one day")), ] self.add_ui_actions('', radio_actions, 'RadioActions', 'radio') self.ViewMonth.set_short_label(_("Month")) self.ViewWeek.set_short_label(_("Week")) self.ViewDay.set_short_label(_("Day")) self.ViewMonth.props.is_important = True self.ViewWeek.props.is_important = True self.ViewDay.props.is_important = True view = api.user_settings.get('calendar-view', 'month') if view == 'month': self.ViewMonth.props.active = True elif view == 'basicWeek': self.ViewWeek.props.active = True else: self.ViewDay.props.active = True
def create_model(self, store): return OpticalPatientVisualAcuity(client_id=self._client.id, store=store, responsible=api.get_current_user(store))
def create_model(self, store): return OpticalPatientHistory(store=store, client_id=self._client.id, responsible=api.get_current_user(store))
def finish(self): self.model.receive_responsible = get_current_user(self.store) self.model.receive(api.get_current_user(self.store)) self.retval = self.model self.close()
def on_confirm(self): if self.model.salary != self._original_salary: ClientSalaryHistory.add(self.store, self._original_salary, self.model, api.get_current_user(self.store))
def _needs_password_confirmation(self): current_user = api.get_current_user(self.store) return not current_user.profile.check_app_permission(u'admin')
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 _create_headerbar(self): # User/help menu user = api.get_current_user(self.store) xml = MENU_XML.format(username=api.escape(user.get_description()), preferences=_('Preferences...'), password=_('Change password...'), signout=_('Sign out...'), help=_('Help'), contents=_('Contents'), translate=_('Translate Stoq...'), get_support=_('Get support online...'), chat=_('Online chat...'), about=_('About'), quit=_('Quit')) builder = Gtk.Builder.new_from_string(xml, -1) # Header bar self.header_bar = Gtk.HeaderBar() self.toplevel.set_titlebar(self.header_bar) # Right side self.close_btn = self.create_button('fa-power-off-symbolic', action='stoq.quit') self.close_btn.set_relief(Gtk.ReliefStyle.NONE) self.min_btn = self.create_button('fa-window-minimize-symbolic') self.min_btn.set_relief(Gtk.ReliefStyle.NONE) #self.header_bar.pack_end(self.close_btn) #self.header_bar.pack_end(self.min_btn) box = Gtk.Box.new(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) box.pack_start(self.min_btn, False, False, 0) box.pack_start(self.close_btn, False, False, 0) self.header_bar.pack_end(box) self.user_menu = builder.get_object('app-menu') self.help_section = builder.get_object('help-section') self.user_button = self.create_button('fa-cog-symbolic', menu_model=self.user_menu) self.search_menu = Gio.Menu() self.search_button = self.create_button('fa-search-symbolic', _('Searches'), menu_model=self.search_menu) self.main_menu = Gio.Menu() self.menu_button = self.create_button('fa-bars-symbolic', _('Actions'), menu_model=self.main_menu) self.header_bar.pack_end( ButtonGroup( [self.menu_button, self.search_button, self.user_button])) self.sign_button = self.create_button('', _('Sign now'), style_class='suggested-action') #self.header_bar.pack_end(self.sign_button) # Left side self.home_button = self.create_button(STOQ_LAUNCHER, style_class='suggested-action') self.new_menu = Gio.Menu() self.new_button = self.create_button('fa-plus-symbolic', _('New'), menu_model=self.new_menu) self.header_bar.pack_start( ButtonGroup([ self.home_button, self.new_button, ])) self.domain_header = None self.header_bar.show_all() self.notifications = NotificationCounter(self.home_button, blink=True)
def on_confirm(self): self.model.adjust(api.get_current_user(self.store), self._invoice_number)
def create_actions(self): group = get_accels('app.calendar') actions = [ # File ('NewClientCall', None, _("Client call"), group.get('new_client_call'), _("Add a new client call")), ('NewPayable', None, _("Account payable"), group.get('new_payable'), _("Add a new account payable")), ('NewReceivable', None, _("Account receivable"), group.get('new_receivable'), _("Add a new account receivable")), ('NewWorkOrder', None, _("Work order"), group.get('new_work_order'), _("Add a new work order")), # View ('Back', Gtk.STOCK_GO_BACK, _("Back"), group.get('go_back'), _("Go back")), ('Forward', Gtk.STOCK_GO_FORWARD, _("Forward"), group.get('go_forward'), _("Go forward")), ('Today', None, _("Show today"), group.get('show_today'), _("Show today")), ] self.calendar_ui = self.add_ui_actions(actions) self.set_help_section(_("Calendar help"), 'app-calendar') toggle_actions = [ ('AccountsPayableEvents', None, _("Accounts payable"), None, _("Show accounts payable in the list")), ('AccountsReceivableEvents', None, _("Accounts receivable"), None, _("Show accounts receivable in the list")), ('PurchaseEvents', None, _("Purchases"), None, _("Show purchases in the list")), ('ClientCallEvents', None, _("Client Calls"), None, _("Show client calls in the list")), ('ClientBirthdaysEvents', None, _("Client Birthdays"), None, _("Show client birthdays in the list")), ('WorkOrderEvents', None, _("Work orders"), None, _("Show work orders in the list")), ] self.add_ui_actions(toggle_actions, 'ToggleActions') events_info = dict( in_payments=(self.AccountsReceivableEvents, self.NewReceivable, u'receivable'), out_payments=(self.AccountsPayableEvents, self.NewPayable, u'payable'), purchase_orders=(self.PurchaseEvents, None, u'stock'), client_calls=(self.ClientCallEvents, self.NewClientCall, u'sales'), client_birthdays=(self.ClientBirthdaysEvents, None, u'sales'), work_orders=(self.WorkOrderEvents, self.NewWorkOrder, u'services'), ) user = api.get_current_user(self.store) events = self._calendar.get_events() for event_name, value in events_info.items(): view_action, new_action, app = value view_action.set_state(GLib.Variant.new_boolean(events[event_name])) # Disable feature if user does not have acces to required # application if not user.profile.check_app_permission(app): view_action.set_state(GLib.Variant.new_boolean(False)) self.set_sensitive([view_action], False) if new_action: self.set_sensitive([new_action], False) view_action.connect('change-state', self._view_option_state_changed) self._update_events()