Example #1
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()

        SaleReturnWizardFinishEvent.emit(self.model)

        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."))

        self.model.return_(method_name=u'credit' if self.credit else u'money')
        self.retval = self.model
        self.close()

        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)
Example #2
0
    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()
Example #3
0
File: pos.py Project: pkaislan/stoq
    def _add_sellable(self, sellable, batch=None):
        quantity = self._read_quantity()
        if quantity == 0:
            return

        if not sellable.is_valid_quantity(quantity):
            warning(
                _(u"You cannot sell fractions of this product. "
                  u"The '%s' unit does not allow that") %
                sellable.unit_description)
            return

        if sellable.product:
            # If the sellable has a weight unit specified and we have a scale
            # configured for this station, go and check what the scale says.
            if (sellable and sellable.unit
                    and sellable.unit.unit_index == UnitType.WEIGHT
                    and self._scale_settings):
                self._read_scale(sellable)

        storable = sellable.product_storable
        if storable is not None:
            if not self._check_available_stock(storable, sellable):
                info(
                    _("You cannot sell more items of product %s. "
                      "The available quantity is not enough.") %
                    sellable.get_description())
                self.barcode.set_text('')
                self.barcode.grab_focus()
                return

        self._update_list(sellable, batch=batch)
        self.barcode.grab_focus()
Example #4
0
    def _change_status(self, work_order, new_status):
        with api.new_store() as store:
            work_order = store.fetch(work_order)

            reason = self._ask_reason(work_order, new_status)
            if reason is False:
                store.retval = False
                return

            # FIXME Redo this logic, it wont unset if the user go further back on
            # status
            if work_order.status == new_status:
                if work_order.client_informed_date:
                    work_order.unset_client_informed(reason)
                return True

            try:
                work_order.change_status(new_status, reason)
            except InvalidStatus as e:
                info(str(e))
                store.retval = False
            except NeedReason as e:
                info(str(e), _("Make the change on the order's menu so "
                               "you can specify a reason"))
                store.retval = False

        return store.retval
Example #5
0
def return_sale(parent, sale, store):
    from stoqlib.gui.wizards.salereturnwizard import SaleReturnWizard

    cancel_last_coupon = sysparam.get_bool('ALLOW_CANCEL_LAST_COUPON')
    if cancel_last_coupon and ECFIsLastSaleEvent.emit(sale):
        info(_("That is last sale in ECF. Return using the menu "
               "ECF - Cancel Last Document"))
        return

    if sale.can_return():
        need_document = not sysparam.get_bool('ACCEPT_SALE_RETURN_WITHOUT_DOCUMENT')
        if need_document and not sale.get_client_document():
            warning(_('It is not possible to accept a returned sale from clients '
                      'without document. Please edit the client document or change '
                      'the sale client'))
            return

        returned_sale = sale.create_sale_return_adapter()
        retval = run_dialog(SaleReturnWizard, parent, store, returned_sale)
    elif sale.can_cancel():
        retval = cancel_sale(sale)
    else:
        retval = False

    return retval
Example #6
0
    def _run_product_component_dialog(self, product_component=None):
        update = True
        if product_component is None:
            update = False
            component = self.component_combo.get_selected_data()
            product_component = TemporaryProductComponent(
                product=self._product, component=component)
            # If we try to add a component which is already in tree,
            # just edit it
            for component in self.component_tree:
                if component.component == product_component.component:
                    update = True
                    product_component = component
                    break

        if not self._can_add_component(product_component):
            product_desc = self._product.sellable.get_description()
            component_desc = product_component.description
            info(_(u'You can not add this product as component, since '
                   '%s is composed by %s' % (component_desc, product_desc)))
            return

        toplevel = self.get_toplevel().get_toplevel()
        # We cant use savepoint here, since product_component
        # is not an ORM object.
        model = run_dialog(ProductComponentEditor, toplevel, self.store,
                           product_component)
        if not model:
            return

        if update:
            self.component_tree.update(model)
        else:
            self._add_to_component_tree(model)
        self._update_widgets()
Example #7
0
    def _can_add_payment(self):
        if self.base_value.read() is ValueUnset:
            return False

        if self._outstanding_value <= 0:
            return False

        payments = self.model.group.get_valid_payments()
        payment_count = payments.find(
            Payment.method_id == self._method.id).count()
        if payment_count >= self._method.max_installments:
            info(_(u'You can not add more payments using the %s '
                   'payment method.') % self._method.description)
            return False

        # If we are creaing out payments (PurchaseOrder) or the Sale does not
        # have a client, assume all options available are creatable.
        if (isinstance(self.model, (PurchaseOrder, StockDecrease))
            or not self.model.client):
            return True

        method_values = {self._method: self._holder.value}
        for i, payment in enumerate(self.model.group.payments):
            method_values.setdefault(payment.method, 0)
            method_values[payment.method] += payment.value
        for method, value in method_values.items():
            try:
                self.model.client.can_purchase(method, value)
            except SellError as e:
                warning(str(e))
                return False

        return True
Example #8
0
    def _cancel_last_document(self):
        try:
            self._validate_printer()
        except DeviceError as e:
            warning(str(e))
            return

        store = new_store()
        last_doc = self._get_last_document(store)
        if not self._confirm_last_document_cancel(last_doc):
            store.close()
            return

        if last_doc.last_till_entry:
            self._cancel_last_till_entry(last_doc, store)
        elif last_doc.last_sale:
            # Verify till balance before cancel the last sale.
            till = Till.get_current(store)
            if last_doc.last_sale.total_amount > till.get_balance():
                warning(_("You do not have this value on till."))
                store.close()
                return
            cancelled = self._printer.cancel()
            if not cancelled:
                info(_("Cancelling sale failed, nothing to cancel"))
                store.close()
                return
            else:
                self._cancel_last_sale(last_doc, store)
        store.commit()
Example #9
0
    def _check_branch(self):
        from stoqlib.database.runtime import (get_default_store, new_store,
                                              get_current_station,
                                              set_current_branch_station)
        from stoqlib.domain.person import Company
        from stoqlib.lib.parameters import sysparam
        from stoqlib.lib.message import info

        default_store = get_default_store()

        compaines = default_store.find(Company)
        if (compaines.count() == 0 or
                not sysparam.has_object('MAIN_COMPANY')):
            from stoqlib.gui.base.dialogs import run_dialog
            from stoqlib.gui.dialogs.branchdialog import BranchDialog
            if self._ran_wizard:
                info(_("You need to register a company before start using Stoq"))
            else:
                info(_("Could not find a company. You'll need to register one "
                       "before start using Stoq"))
            store = new_store()
            person = run_dialog(BranchDialog, None, store)
            if not person:
                raise SystemExit
            branch = person.branch
            sysparam.set_object(store, 'MAIN_COMPANY', branch)
            current_station = get_current_station(store)
            if current_station is not None:
                current_station.branch = branch
            store.commit()
            store.close()

        set_current_branch_station(default_store, station_name=None)
Example #10
0
File: admin.py Project: relsi/stoq
    def _open_sintegra(self):
        branch = api.get_current_branch(self.app.store)
        if branch.manager is None:
            info(_("You must define a manager to this branch before you can create" " a sintegra archive"))
            return

        self.app.run_dialog(SintegraDialog, self.app.store)
Example #11
0
def apply_patch(store):
    info(u'The schema update might take a long time to complete, depending '
         'the size of your database and your hardware.')

    for payment in store.find(Payment).order_by(['due_date',
                                                 'paid_date',
                                                 'cancel_date']):
        if payment.is_preview():
            continue

        if payment.due_date:
            history_date = payment.due_date.date()
        else:
            history_date = payment.open_date.date()

        PaymentFlowHistory.add_payment(store, payment, history_date)

        if payment.is_paid():
            PaymentFlowHistory.add_paid_payment(store, payment,
                                                payment.paid_date.date())
        elif payment.is_cancelled():
            if payment.paid_date:
                PaymentFlowHistory.add_paid_payment(store, payment,
                                                    payment.paid_date.date())
                PaymentFlowHistory.remove_paid_payment(store, payment,
                                                       payment.cancel_date.date())
            else:
                PaymentFlowHistory.remove_payment(store, payment,
                                                  payment.due_date.date())
Example #12
0
 def _set_done(self):
     # XXX: Better text here
     info(_("Stoq.Link registration successful! You may "
            "manage your installation from there now"))
     self._done = True
     self.confirm()
     self._set_processing(False)
Example #13
0
 def validate_confirm(self):
     try:
         self.model.add_lost(self.quantity.read())
     except (ValueError, AssertionError):
         info(_(u"Can not lose this quantity. Not enough materials " "allocated to this production."))
         return False
     return True
Example #14
0
 def next_step(self):
     self.wizard.all_products = self.all_products.get_active()
     if self.wizard.is_for_another_branch() and self.model.identifier > 0:
         info(_('The identifier for this purchase will be defined when it '
                'is synchronized to the detination branch'))
         self.model.identifier = self.wizard.temporary_identifier
     return PurchaseItemStep(self.wizard, self, self.store, self.model)
Example #15
0
 def post_init(self):
     self.register_validate_function(self._validation_func)
     self.force_validation()
     missing_value = self.slave.get_missing_change_value()
     if missing_value < 0:
         info(_(u"Your payments total is greater than the sale total. Maybe"
                " you want to correct them."))
Example #16
0
def print_cheques_for_payment_group(store, group):
    """ Given a instance that implements the PaymentGroup interface, iterate
    over all its items printing a cheque for them.
    """
    payments = group.get_valid_payments()
    printer = get_current_cheque_printer_settings(store)
    if not printer:
        return
    printer_banks = printer.get_banks()
    current_branch = get_current_branch(store)
    main_address = current_branch.person.get_main_address()
    if not main_address:
        raise ValueError("The cheque can not be printed since there is no "
                         "main address defined for the current branch.")

    max_len = printer.get_capability("cheque_city").max_len
    city = main_address.city_location.city[:max_len]
    for idx, payment in enumerate(payments):
        if payment.method.method_name == 'check':
            continue
        check_data = payment.method.operation.get_check_data_by_payment(
            payment)
        bank_id = check_data.bank_data.bank_id
        try:
            bank = printer_banks[bank_id]
        except KeyError:
            continue
        thirdparty = group.recipient
        info(_(u"Insert Cheque %d") % (idx + 1))
        max_len = printer.get_capability("cheque_thirdparty").max_len
        thirdparty = thirdparty and thirdparty.name[:max_len] or ""
        printer.print_cheque(bank, payment.value, thirdparty, city)
Example #17
0
File: pos.py Project: romaia/stoq
    def _update_list(self, sellable):
        assert isinstance(sellable, Sellable)
        try:
            sellable.check_taxes_validity()
        except TaxError as strerr:
            # If the sellable icms taxes are not valid, we cannot sell it.
            warning(strerr)
            return

        quantity = self.sellableitem_proxy.model.quantity

        is_service = sellable.service
        if is_service and quantity > 1:
            # It's not a common operation to add more than one item at
            # a time, it's also problematic since you'd have to show
            # one dialog per service item. See #3092
            info(_("It's not possible to add more than one service "
                   "at a time to an order. So, only one was added."))

        sale_item = TemporarySaleItem(sellable=sellable,
                                      quantity=quantity)
        if is_service:
            with api.trans() as store:
                rv = self.run_dialog(ServiceItemEditor, store, sale_item)
            if not rv:
                return
        self._update_added_item(sale_item)
Example #18
0
    def checkout(self, cancel_clear=False):
        """Initiates the sale wizard to confirm sale.

        :param cancel_clear: If cancel_clear is true, the sale will be cancelled
          if the checkout is cancelled.
        """
        assert len(self.sale_items) >= 1

        if self._current_store:
            store = self._current_store
            savepoint = 'before_run_fiscalprinter_confirm'
            store.savepoint(savepoint)
        else:
            store = api.new_store()
            savepoint = None

        if self._trade:
            if self._get_subtotal() < self._trade.returned_total:
                info(_("Traded value is greater than the new sale's value. "
                       "Please add more items or return it in Sales app, "
                       "then make a new sale"))
                return

            sale = self._create_sale(store)
            self._trade.new_sale = sale
            self._trade.trade()
        else:
            sale = self._create_sale(store)

        if sysparam.get_bool('CONFIRM_SALES_ON_TILL'):
            sale.order()
            store.commit()
        else:
            assert self._coupon

            ordered = self._coupon.confirm(sale, store, savepoint,
                                           subtotal=self._get_subtotal())
            # Dont call store.confirm() here, since coupon.confirm()
            # above already did it
            if not ordered:
                # FIXME: Move to TEF plugin
                manager = get_plugin_manager()
                if manager.is_active('tef') or cancel_clear:
                    self._cancel_order(show_confirmation=False)
                elif not self._current_store:
                    # Just do that if a store was created above and
                    # if _cancel_order wasn't called (it closes the connection)
                    store.rollback(close=True)
                return

            log.info("Checking out")

        self._coupon = None
        POSConfirmSaleEvent.emit(sale, self.sale_items[:])

        # We must close the connection only after the event is emmited, since it
        # may use value from the sale that will become invalid after it is
        # closed
        store.close()
        self._clear_order()
Example #19
0
 def validate_confirm(self):
     try:
         self.model.allocate(self.quantity.read())
     except (ValueError, AssertionError):
         info(_(u'Can not allocate this quantity.'))
         return False
     return True
Example #20
0
    def _setup_widgets(self):
        self.quoting_list.set_columns(self._get_columns())
        self._populate_quoting_list()

        if not len(self.quoting_list) > 0:
            info(_(u'No supplier have been found for any of the selected '
                   'items.\nThis quote will be cancelled.'))
            self.wizard.finish()
Example #21
0
 def _on_SaleAvoidCancel(self, sale):
     if not sysparam.get_bool('ALLOW_CANCEL_LAST_COUPON'):
         return False
     if self._is_ecf_last_sale(sale):
         info(_("That is last sale in ECF. Return using the menu "
                "ECF - Cancel Last Document"))
         return True
     return False
Example #22
0
 def _on_coupon__cancel(self, coupon):
     if coupon.closed:
         # In this case, the Sale and TillEntries will be rolled back by
         # fiscalprinter. We only need to cancel the last coupon on the ecf
         if not self._printer.cancel_last_coupon():
             info(_("Coupon cancellation failed..."))
     else:
         coupon.cancel()
Example #23
0
File: admin.py Project: relsi/stoq
    def _open_invoice_printers(self):
        if self.app.store.find(InvoiceLayout).is_empty():
            info(_("You must create at least one invoice layout " "before adding an invoice printer"))
            return

        store = api.new_store()
        model = self.app.run_dialog(InvoicePrinterDialog, store)
        store.confirm(model)
        store.close()
Example #24
0
    def validate_confirm(self):
        query = self._get_sellables_query()
        sellables = Inventory.get_sellables_for_inventory(self.store, self.model.branch, query)
        if sellables.is_empty():
            info(_(u'No products have been found in the selected '
                   'categories.'))
            return False

        return True
    def validate_confirm(self):
        # This is a generator. It'll be evaluated to True
        # even if it's len should be 0. Use a list for comparison instead.
        if not list(self._get_sellables()):
            info(_(u'No products have been found in the selected '
                   'categories.'))
            return False

        return True
Example #26
0
 def _cancel_last_sale(self, last_doc, store):
     if last_doc.last_sale.status == Sale.STATUS_RETURNED:
         return
     sale = store.fetch(last_doc.last_sale)
     returned_sale = sale.create_sale_return_adapter()
     returned_sale.reason = _(u"Cancelling last document on ECF")
     returned_sale.return_()
     last_doc.last_sale = None
     info(_("Document was cancelled"))
Example #27
0
 def delete_model(self, model, store):
     sellables = store.find(Sellable, tax_constant=model)
     quantity = sellables.count()
     if quantity > 0:
         msg = _(u"You can't remove this tax, since %d products or "
                 "services are taxed with '%s'.") % (quantity,
                                                     model.get_description())
         info(msg)
     else:
         store.remove(model)
Example #28
0
    def validate_confirm(self):
        if self.document.is_empty():
            if self._initial_document_type == FiscalSaleHistory.TYPE_CPF:
                doc = 'CPF'
            else:
                doc = 'CNPJ'
            info(_("The %s cannot be empty") % doc)
            return False

        return True
Example #29
0
 def on_confirm(self):
     # We are using this hook as a callback for the OK button
     productions = [p.obj for p in self.productions if p.selected]
     store = api.new_store()
     group = self.model.create_quote_group(productions, store)
     store.confirm(group)
     store.close()
     info(_(u'The quote group was succesfully created and it is available '
             'in the Purchase application.'))
     self.retval = group
Example #30
0
 def _populate_ecf_printer(self, status):
     serial = unicode(status.printer.get_serial())
     if self.store.find(ECFPrinter, device_serial=serial):
         status.stop()
         status.get_port().close()
         info(_("This printer is already known to the system"))
         return False
     self.model.device_serial = serial
     self._populate_constants(self.model, status)
     return True
Example #31
0
 def validate_confirm(self):
     if not len(self.component_tree) > 0:
         info(_(u'There is no component in this product.'))
         return False
     return True
Example #32
0
 def _open_stoq_link_connect(self):
     if stoq.trial_mode:
         return info(_('Online features are not available in trial mode'))
     self.app.run_dialog(PinDialog, self.app.store)
Example #33
0
 def confirm(self, *args):
     self.store.confirm(True)
     BasicDialog.confirm(self, *args)
     info(_("Changes will be applied after all instances of Stoq are restarted."))
Example #34
0
    def update(self, plugins=True, backup=True):
        log.info("Upgrading database (plugins=%r, backup=%r)" %
                 (plugins, backup))

        try:
            log.info("Locking database")
            self.default_store.lock_database()
        except DatabaseError:
            msg = _(
                'Could not lock database. This means there are other clients '
                'connected. Make sure to close every Stoq client '
                'before updating the database')
            error(msg)

        # Database migration is actually run in subprocesses, We need to unlock
        # the tables again and let the upgrade continue
        log.info("Releasing database lock")
        self.default_store.unlock_database()

        sucess = db_settings.test_connection()
        if not sucess:
            # FIXME: Improve this message after 1.5 is released
            msg = _(u'Could not connect to the database using command line '
                    'tool! Aborting.') + ' '
            msg += _(u'Please, check if you can connect to the database '
                     'using:') + ' '
            msg += _(u'psql -l -h <server> -p <port> -U <username>')
            error(msg)
            return

        if backup:
            temporary = tempfile.mktemp(prefix="stoq-dump-")
            log.info("Making a backup to %s" % (temporary, ))
            create_log.info("BACKUP-START:")
            success = db_settings.dump_database(temporary)
            if not success:
                info(_(u'Could not create backup! Aborting.'))
                info(_(u'Please contact stoq team to inform this problem.\n'))
                return

        # We have to wrap a try/except statement inside a try/finally to
        # support python previous to 2.5 version.
        try:
            try:
                super(StoqlibSchemaMigration, self).update()
                if plugins:
                    self.update_plugins()
            except Exception:
                exc = sys.exc_info()
                tb_str = ''.join(traceback.format_exception(*exc))
                collect_traceback(exc, submit=True)
                create_log.info("ERROR:%s" % (tb_str, ))

                if backup:
                    log.info("Restoring backup %s" % (temporary, ))
                    create_log.info("RESTORE-START:")
                    new_name = db_settings.restore_database(temporary)
                    create_log.info("RESTORE-DONE:%s" % (new_name, ))
                return False
        finally:
            if backup is True:
                os.unlink(temporary)
        log.info("Migration done")
        return True
Example #35
0
 def _printer_status__timeout(self, status):
     self.progress_dialog.stop()
     info(
         _("Could not find a %s printer connected to %s") %
         (self.model.model_name, status.get_device_name()))
Example #36
0
 def edit_item(self, item):
     if item.brand == 'virtual':
         info(_("Cant edit a virtual printer"))
         return False
     return ModelListSlave.edit_item(self, item)
Example #37
0
 def validate_confirm(self):
     if not self._is_valid_cost(self.cost.read()):
         info(self._cost_msg)
         return False
     return True
Example #38
0
 def on_ExportFilizola__activate(self, action):
     dest = generate_filizola_file(self.store)
     info(_('File saved in %s') % dest)