Beispiel #1
0
    def _setup_summary_labels(self):
        value_format = "<b>%s</b>"
        total_label = "<b>%s</b>" % stoq_api.escape(_("Total:"))
        total_summary_label = SummaryLabel(klist=self.payments_list,
                                           column='value',
                                           label=total_label,
                                           value_format=value_format)
        total_summary_label.show()
        self.payments_vbox.pack_start(total_summary_label, False, True, 0)

        total_label = "<b>%s</b>" % stoq_api.escape(_("Total paid:"))
        total_paid_summary_label = SummaryLabel(klist=self.payments_list,
                                                column='paid_value',
                                                label=total_label,
                                                value_format=value_format)
        total_paid_summary_label.show()
        self.payments_vbox.pack_start(total_paid_summary_label, False, True, 0)

        total_label = "<b>%s</b>" % stoq_api.escape(_("Total:"))
        transaction_summary_label = SummaryLabel(
            klist=self.stock_transactions_list,
            column='total',
            label=total_label,
            value_format=value_format)
        transaction_summary_label.show()
        self.stock_transactions_vbox.pack_start(transaction_summary_label,
                                                False, True, 0)

        total_label = "<b>%s</b>" % stoq_api.escape(_("Total:"))
        sale_summary_label = SummaryLabel(klist=self.sales_list,
                                          column='total',
                                          label=total_label,
                                          value_format=value_format)
        sale_summary_label.show()
        self.sales_vbox.pack_start(sale_summary_label, False, True, 0)
Beispiel #2
0
    def describe_item(self, person_view):
        details = []
        birth_date = (person_view.birth_date
                      and person_view.birth_date.strftime('%x'))
        for label, value in [(_("Phone"), person_view.phone_number),
                             (_("Mobile"), person_view.mobile_number),
                             (self._person_l10n.label, person_view.cpf),
                             (self._company_l10n.label, person_view.cnpj),
                             (_("RG"), person_view.rg_number),
                             (_("Birth date"), birth_date),
                             (_("Category"),
                              getattr(person_view, 'client_category', None)),
                             (_("Address"), format_address(person_view))]:
            if not value:
                continue
            details.append('%s: %s' % (label, stoq_api.escape(value)))

        name = "<big>%s</big>" % (stoq_api.escape(
            person_view.get_description()), )
        if details:
            short = name + '\n<span size="small">%s</span>' % (stoq_api.escape(
                ', '.join(details[:1])))
            complete = name + '\n<span size="small">%s</span>' % (
                stoq_api.escape('\n'.join(details)))
        else:
            short = name
            complete = name

        return short, complete
Beispiel #3
0
 def setup_proxies(self):
     receiving_date = self.model.receival_date_str
     branch_name = self.model.branch_name
     text = _('Received in <b>%s</b> for branch <b>%s</b>')
     header_text = text % (stoq_api.escape(receiving_date),
                           stoq_api.escape(branch_name))
     self.header_label.set_markup(header_text)
     self.add_proxy(self.model, ['notes'])
    def __init__(self, cert_name, retry=False):
        super(CertificatePasswordDialog, self).__init__(None)

        text = _("Enter the password for <b>%s</b>:") % (
            stoq_api.escape(cert_name), )
        if retry:
            error_text = '<b><span color="red">%s</span></b>' % (
                stoq_api.escape(_("Wrong password provided...")), )
            text = "%s\n%s" % (error_text, text)
        self.info_lbl.set_markup(text)
Beispiel #5
0
    def search_completed(self, results):
        # We are only interested in the workorders whose status are in one of our
        # columns
        results = results.find(WorkOrder.status.is_in(self.status_columns))
        for work_order_view in results.order_by(WorkOrder.open_date):
            work_order = work_order_view.work_order
            status_name = WorkOrder.statuses.get(work_order.status)
            # Skip cancel/delivered etc
            if status_name is None:
                continue

            # Since this column isnt one of the |work_order| status
            if work_order.client_informed_date:
                status_name = _('Client informed')

            column = self.get_column_by_title(status_name)
            if column is None:
                continue

            if work_order_view.sellable:
                description = '%s - %s' % (work_order_view.sellable,
                                           work_order_view.description)
            else:
                description = work_order_view.description

            # FIXME: Figure out a better way of rendering
            work_order_view.markup = '<b>%s</b>\n%s\n%s' % (
                description, str(stoq_api.escape(work_order_view.client_name)),
                work_order_view.open_date.strftime('%x'))

            column.append_item(work_order_view)
Beispiel #6
0
 def _update_title(self):
     # Workaround to get the current calendar date
     view = self.get_view()
     view.run_javascript("document.title = $('.fc-header-title').text()")
     title = view.get_property('title')
     self.app.date_label.set_markup(
         '<big><b>%s</b></big>' % stoq_api.escape(title))
Beispiel #7
0
    def create_ui(self):
        if api.sysparam.get_bool('SMART_LIST_LOADING'):
            self.search.enable_lazy_search()

        self.window.add_print_items2([
            (_("Print quote..."), 'work_order.PrintQuote'),
            (_("Print receipt..."), 'work_order.PrintReceipt'),
        ])
        self.window.add_export_items()
        self.window.add_extra_items2([
            (_("Send orders..."), 'work_order.SendOrders'),
            (_("Receive orders..."), 'work_order.ReceiveOrders'),
        ])
        self.window.add_extra_items([self.ViewKanban, self.ViewList])
        self.window.add_new_items2([
            (_("Work order..."), 'work_order.NewOrder'),
        ])

        self.window.add_search_items([
            self.Products,
            self.Services,
            self.Categories,
            self.Clients,
        ])

        self.search.set_summary_label(column='total',
                                      label=('<b>%s</b>' %
                                             stoq_api.escape(_('Total:'))),
                                      format='<b>%s</b>',
                                      parent=self.get_statusbar_message_area())

        self.results.set_cell_data_func(self._on_results__cell_data_func)
Beispiel #8
0
    def refresh(self):
        if stoq.trial_mode:
            self.status = ResourceStatus.STATUS_NA
            self.reason = (
                _('Online features are not available in trial mode'))
            self.reason_long = _(
                'Online features require a subscription of Stoq.link')
            return

        if not api.sysparam.get_bool('ONLINE_SERVICES'):
            self.status = ResourceStatus.STATUS_NA
            self.reason = (_("Online services (Stoq.link integration, backup, "
                             "etc) not enabled..."))
            self.reason_long = _('Enable the parameter "Online Services" '
                                 'on the "Admin" app to solve this issue')
            return

        if self._check_running():
            self.status = self.STATUS_OK
            self.reason = _("Online services data hub is running fine.")
            self.reason_long = None
        else:
            self.status = ResourceStatus.STATUS_ERROR
            self.reason = _("Online services data hub not found...")
            package = '<a href="apt://stoq-server">stoq-server</a>'
            self.reason_long = safe_str(
                stoq_api.escape(
                    _("Install and configure the %s package "
                      "to solve this issue")) % (package, ))
Beispiel #9
0
    def _update_account_type(self, account_type):
        if not self.account_type.get_sensitive():
            return
        if account_type != Account.TYPE_BANK:
            self._remove_bank_widgets()
            self._remove_bank_option_widgets()
            self.code.set_sensitive(True)
            return

        self.code.set_sensitive(False)
        self.bank_type = ProxyComboBox()
        self._add_widget(stoq_api.escape(_("Bank:")), self.bank_type)
        self.bank_type.connect('content-changed',
                               self._on_bank_type__content_changed)
        self.bank_type.show()

        banks = [(_('Generic'), None)]
        banks.extend([(b.description, b.bank_number) for b in get_all_banks()])
        self.bank_type.prefill(banks)

        if self.model.bank:
            try:
                self.bank_type.select(self.model.bank.bank_number)
            except KeyError:
                self.bank_type.select(None)

        self._update_bank_type()
Beispiel #10
0
    def _setup_widgets(self):
        is_package = self.model.product.is_package
        component_list = list(self._get_products(additional_query=is_package))
        if component_list:
            self.component_combo.prefill(component_list)
        else:
            self.sort_components_check.set_sensitive(False)

        self.yield_quantity.set_adjustment(
            Gtk.Adjustment(lower=0, upper=MAX_INT, step_increment=1))

        self.component_tree.set_columns(self._get_columns())
        self._populate_component_tree()
        self.component_label = SummaryLabel(klist=self.component_tree,
                                            column='total_production_cost',
                                            label='<b>%s</b>' %
                                            stoq_api.escape(_(u'Total:')),
                                            value_format='<b>%s</b>')
        self.component_label.show()
        self.component_tree_vbox.pack_start(self.component_label, False, True,
                                            0)
        self.info_label.set_bold(True)
        self._update_widgets()
        if self.visual_mode:
            self.component_combo.set_sensitive(False)
            self.add_button.set_sensitive(False)
            self.sort_components_check.set_sensitive(False)
Beispiel #11
0
    def _check_demo_mode(self):
        if not api.sysparam.get_bool('DEMO_MODE'):
            return

        if api.user_settings.get('hide-demo-warning'):
            return

        button_label = _('Use my own data')
        title = _('You are using Stoq with example data.')
        desc = (_("Some features are limited due to fiscal reasons. "
                  "Click on '%s' to remove the limitations.")
                % button_label)
        msg = '<b>%s</b>\n%s' % (stoq_api.escape(title), stoq_api.escape(desc))

        button = Gtk.Button(button_label)
        button.connect('clicked', self._on_enable_production__clicked)
        self.add_info_bar(Gtk.MessageType.WARNING, msg, action_widget=button)
Beispiel #12
0
 def _setup_summary_labels(self):
     order_summary_label = SummaryLabel(
         klist=self.ordered_items,
         column='total',
         label='<b>%s</b>' % stoq_api.escape(_(u"Total")),
         value_format='<b>%s</b>')
     order_summary_label.show()
     self.ordered_vbox.pack_start(order_summary_label, False, True, 0)
Beispiel #13
0
    def _setup_widgets(self):
        self.branch_label.set_markup(
            _(u"Fixing stock cost for products in <b>%s</b>") %
            stoq_api.escape(self._branch.get_description()))

        items = ProductWithStockView.find_by_branch(self.store, self._branch)
        self._storables = [_TemporaryItem(s) for s in items]
        self.slave.listcontainer.add_items(self._storables)
Beispiel #14
0
 def _setup_summary_labels(self):
     summary_label = SummaryLabel(klist=self.payments_list,
                                  column='paid_value',
                                  label='<b>%s</b>' %
                                  stoq_api.escape(_(u"Total:")),
                                  value_format='<b>%s</b>')
     summary_label.show()
     self.payments_vbox.pack_start(summary_label, False, True, 0)
Beispiel #15
0
    def _create_headerbar(self):
        # User/help menu
        user = api.get_current_user(self.store)
        xml = MENU_XML.format(username=stoq_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)
Beispiel #16
0
    def describe_item(self, view):
        details = []
        for label, value in [(_("Name"), view.name),
                             (_("CRM"), view.crm_number)]:
            if not value:
                continue
            details.append('%s: %s' % (label, stoq_api.escape(value)))
        name = "<big>%s</big>" % (stoq_api.escape(view.name), )
        if details:
            short = name + '\n<span size="small">%s</span>' % (stoq_api.escape(
                ', '.join(details[:1])))
            complete = name + '\n<span size="small">%s</span>' % (
                stoq_api.escape('\n'.join(details)))
        else:
            short = name
            complete = name

        return short, complete
Beispiel #17
0
    def create_filters(self):
        self.set_text_field_columns(['description'])

        self.date_filter = DateSearchFilter(_('Date:'))
        self.date_filter.select(Today)
        self.add_filter(self.date_filter, columns=['date'])
        # add summary label
        value_format = '<b>%s</b>'
        total_label = '<b>%s</b>' % stoq_api.escape(_(u'Total:'))
        self.search.set_summary_label('value', total_label, value_format)
Beispiel #18
0
    def setup_widgets(self):
        super(ProductStockSearch, self).setup_widgets()

        difference_label = Gtk.Label()
        difference_label.set_markup("<small><b>%s</b></small>" %
                                    stoq_api.escape(
                                        _("The DIFFERENCE column is equal to "
                                          "IN STOCK minus MINIMUM columns")))
        difference_label.show()
        self.search.vbox.pack_end(difference_label, False, False, 6)
Beispiel #19
0
    def describe_item(self, person_view):
        details = []
        for label, value in [(self._person_l10n.label, person_view.cpf)]:
            if not value:
                continue
            details.append('%s: %s' % (label, stoq_api.escape(value)))

        name = "<big>%s</big>" % (stoq_api.escape(
            person_view.get_description()), )
        if details:
            short = name + '\n<span size="small">%s</span>' % (stoq_api.escape(
                ', '.join(details[:1])))
            complete = name + '\n<span size="small">%s</span>' % (
                stoq_api.escape('\n'.join(details)))
        else:
            short = name
            complete = name

        return short, complete
Beispiel #20
0
    def _create_summary_labels(self):
        parent = self.get_statusbar_message_area()
        self.search.set_summary_label(
            column='net_total',
            label=('<b>%s</b>' % stoq_api.escape(_('Gross total:'))),
            format='<b>%s</b>',
            parent=parent)
        # Add an extra summary beyond the main one
        # XXX: Should we modify the summary api to make it support more than one
        # summary value? This is kind of ugly
        if self._extra_summary:
            parent.remove(self._extra_summary)

        self._extra_summary = LazySummaryLabel(
            klist=self.search.result_view,
            column='net_total',
            label=('<b>%s</b>' % stoq_api.escape(_('Net total:'))),
            value_format='<b>%s</b>')
        parent.pack_start(self._extra_summary, False, False, 0)
        self._extra_summary.show()
Beispiel #21
0
    def search_completed(self, results, states):
        if len(results):
            return

        base_msg = ''
        url_msg = ''
        state = states[1]
        if state and state.value is None:
            # Base search with no filters
            base_msg = _(u"No work orders could be found.")
            url = u"<a href='new_order'>%s</a>" % (stoq_api.escape(
                _(u"create a new work order")), )
            url_msg = _(u"Would you like to %s ?") % (url, )
        else:
            kind, value = state.value.value.split(':')
            # Search filtering by status
            if kind == 'status':
                if value == 'pending':
                    base_msg = _(u"No pending work orders could be found.")
                elif value == 'in-progress':
                    base_msg = _(u"No work orders in progress could be found.")
                elif value == 'finished':
                    base_msg = _(u"No finished work orders could be found.")
                elif value == 'delivered':
                    base_msg = _(u"No delivered or cancelled work "
                                 u"orders could be found.")
            # Search filtering by category
            elif kind == 'category':
                base_msg = _(u"No work orders in the category %s "
                             u"could be found.") % ('<b>%s</b>' % (value, ), )
                url = u"<a href='new_order?%s'>%s</a>" % (
                    urllib.parse.quote(value),
                    stoq_api.escape(_(u"create a new work order")),
                )
                url_msg = _(u"Would you like to %s ?") % (url, )

        if not base_msg:
            return

        msg = '\n\n'.join([base_msg, url_msg])
        self.search.set_message(msg)
Beispiel #22
0
    def search_completed(self, results, states):
        if len(results):
            return

        supplier, status = states[:2]
        if len(states) > 2 or (supplier.text == '' and status.value is None):
            self.search.set_message("%s\n\n%s" % (
                _("No orders could be found."),
                _("Would you like to %s ?") % (
                    '<a href="new_order">%s</a>' % (
                        stoq_api.escape(_("create a new order"), )))
            ))
Beispiel #23
0
    def describe_item(self, sale_token_view):
        details = []
        for label, value in [(_("Status"), sale_token_view.status_str),
                             (_("Sale"), sale_token_view.sale_identifier_str),
                             (_("Client"), sale_token_view.client_name)]:
            if not value:
                continue
            details.append('{}: {}'.format(label, stoq_api.escape(value)))

        name = "<big>{}</big>".format(
            stoq_api.escape(sale_token_view.sale_token.description))

        if details:
            short = name + '\n<span size="small">{}</span>'.format(
                stoq_api.escape(', '.join(details[:1])))
            complete = name + '\n<span size="small">{}</span>'.format(
                stoq_api.escape('\n'.join(details)))
        else:
            short = name
            complete = name

        return short, complete
Beispiel #24
0
    def setup_widgets(self):
        value_format = '<b>%s</b>'
        balance_label = "<b>%s</b>" % stoq_api.escape(_("Balance:"))

        account_summary_label = SummaryLabel(
            klist=self.klist,
            column='paid_value',
            label=balance_label,
            value_format=value_format,
            data_func=lambda p: p.is_outpayment())

        account_summary_label.show()
        self.pack_start(account_summary_label, False, True, 0)
Beispiel #25
0
    def search_completed(self, results, states):
        if len(results):
            return

        state = states[1]
        if state and state.value is None:
            not_found = _("No payments found.")
            payment_url = '<a href="new_payment">%s</a>?' % (stoq_api.escape(
                _("create a new payment")))
            new_payment = _("Would you like to %s") % (payment_url, )
            msg = "%s\n\n%s" % (not_found, new_payment)
        else:
            v = state.value.value
            if v == 'status:late':
                msg = _("No late payments found.")
            elif v == 'status:paid':
                msg = _("No paid payments found.")
            elif v == 'status:not-paid':
                if self.search_spec == InPaymentView:
                    msg = _("No payments to receive found.")
                else:
                    msg = _("No payments to pay found.")
            elif v.startswith('category:'):
                category = v.split(':')[1]

                not_found = _(
                    "No payments in the <b>%s</b> category were found.") % (
                        stoq_api.escape(category), )
                payment_url = '<a href="new_payment?%s">%s</a>?' % (
                    urllib.parse.quote(category), _("create a new payment"))
                msg = "%s\n\n%s" % (not_found, _("Would you like to %s") %
                                    (payment_url, ))
            else:
                return

        self.search.set_message(msg)
Beispiel #26
0
    def _update_till_status(self, closed, blocked):
        # Three different situations:
        #
        # - Till is closed
        # - Till is opened
        # - Till was not closed the previous fiscal day (blocked)

        self.set_sensitive([self.TillOpen], closed)
        self.set_sensitive([self.TillClose], not closed or blocked)
        widgets = [self.TillVerify, self.TillAddCash, self.TillRemoveCash,
                   self.SearchTillHistory, self.search_holder, self.PaymentReceive]
        self.set_sensitive(widgets, not closed and not blocked)

        def large(s):
            return '<span weight="bold" size="xx-large">%s</span>' % (
                stoq_api.escape(s), )

        if closed:
            text = large(_(u"Till closed"))
            self.search_holder.hide()
            self.footer_hbox.hide()
            self.large_status.show()
            self.clear()
            self.setup_focus()
            # Adding the label on footer without the link
            self.small_status.set_text(text)

            if not blocked:
                text += '\n\n<span size="large"><a href="open-till">%s</a></span>' % (
                    stoq_api.escape(_('Open till')))
            self.status_link.set_markup(text)
        elif blocked:
            self.search_holder.hide()
            self.footer_hbox.hide()
            text = large(_(u"Till blocked"))
            self.status_link.set_markup(text)
            self.small_status.set_text(text)
        else:
            self.search_holder.show()
            self.footer_hbox.show()
            self.large_status.hide()
            till = Till.get_current(self.store, api.get_current_station(self.store))
            text = _(u"Till opened on %s") % till.opening_date.strftime('%x')
            self.small_status.set_text(text)
        self._update_toolbar_buttons()
        self._update_total()
        if sysparam.get_bool('SHOW_TOTAL_PAYMENTS_ON_TILL'):
            self._update_payment_total()
    def _setup_widgets(self):
        self._setup_status()

        self.product_list.set_columns(self._get_product_columns())
        products = self.store.find(TransferOrderItem,
                                   transfer_order=self.model)
        self.product_list.add_list(list(products))

        value_format = '<b>%s</b>'
        total_label = value_format % stoq_api.escape(_("Total:"))
        products_summary_label = SummaryLabel(klist=self.product_list,
                                              column='total',
                                              label=total_label,
                                              value_format=value_format)
        products_summary_label.show()
        self.products_vbox.pack_start(products_summary_label, False, True, 0)
Beispiel #28
0
    def update_ui(self):
        resource = self._resource
        if self._compact:
            # Only show waring and error messages in compact mode
            self.set_visible(
                resource.status in
                [ResourceStatus.STATUS_ERROR, ResourceStatus.STATUS_WARNING])

        status_icon, _ignored = _status_mapper[resource.status]
        icon_size = Gtk.IconSize.LARGE_TOOLBAR
        if self._compact:
            icon_size = Gtk.IconSize.BUTTON
        self.img.set_from_icon_name(status_icon, icon_size)

        tooltip = ''
        if self._compact and resource.reason:
            text = stoq_api.escape(resource.reason)
            tooltip = "<b>%s</b>: %s\n<i>%s</i>" % (stoq_api.escape(
                resource.label), stoq_api.escape(
                    resource.reason), stoq_api.escape(resource.reason_long))
        elif resource.reason and resource.reason_long:
            text = "<b>%s</b>: %s\n<i>%s</i>" % (stoq_api.escape(
                resource.label), stoq_api.escape(
                    resource.reason), stoq_api.escape(resource.reason_long))
        elif resource.reason:
            text = "<b>%s</b>: %s" % (stoq_api.escape(
                resource.label), stoq_api.escape(resource.reason))
        else:
            text = _("Status not available...")

        # Remove old actions and add new ones
        for child in self.buttonbox.get_children():
            self.buttonbox.remove(child)
        for action in resource.get_actions():
            self.add_action(action)

        self.lbl.set_markup(text)
        self.set_tooltip_markup(tooltip)
Beispiel #29
0
    def _create_summary_label(self, report, column='value', label=None):
        # Setting tha data
        obj_list = getattr(self, report + '_list')
        box = getattr(self, report + '_vbox')
        if label is None:
            label = _('Total:')
        label = '<b>%s</b>' % stoq_api.escape(label)
        value_format = '<b>%s</b>'

        # Creating the label
        label = SummaryLabel(klist=obj_list,
                             column=column,
                             label=label,
                             value_format=value_format)

        # Displaying the label
        box.pack_start(label, False, False, 0)
        label.show()
        return label
Beispiel #30
0
    def get_sellable_model(self, sellable, batch=None):
        """Create a Settable containing multiple information to be used on the
        slave.

        :param sellable: a |sellable| we are adding to wizard
        :returns: a Settable containing some information of the item
        """
        minimum = Decimal(0)
        stock = Decimal(0)
        cost = currency(0)
        quantity = Decimal(0)
        description = u''
        unit_label = u''

        children = {}
        if sellable:
            description = "<b>%s</b>" % stoq_api.escape(
                sellable.get_description())
            cost = getattr(sellable, self.value_column)
            quantity = Decimal(1)
            storable = sellable.product_storable
            unit_label = sellable.unit_description
            if storable:
                minimum = storable.minimum_quantity
                stock = storable.get_balance_for_branch(self.model.branch)

            product = sellable.product
            if product:
                for component in product.get_components():
                    child_sellable = component.component.sellable
                    children[child_sellable] = self.get_sellable_model(
                        child_sellable)

        return Settable(quantity=quantity,
                        cost=cost,
                        sellable=sellable,
                        minimum_quantity=minimum,
                        stock_quantity=stock,
                        sellable_description=description,
                        unit_label=unit_label,
                        batch=batch,
                        children=children)