Esempio n. 1
0
    def test_cancel_order(self, new_store, yesno):
        new_store.return_value = self.store
        yesno.return_value = True

        self.clean_domain(
            [ReceivingOrderItem, ReceivingOrder, PurchaseItem, PurchaseOrder])

        purchase = self.create_purchase_order()
        purchase.add_item(self.create_sellable(), 2)
        purchase.status = PurchaseOrder.ORDER_PENDING

        api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0')
        app = self.create_app(PurchaseApp, u'purchase')

        olist = app.results
        olist.select(olist[0])

        with mock.patch.object(self.store, 'close'):
            with mock.patch.object(self.store, 'commit'):
                self.activate(app.Cancel)
                yesno.assert_called_once_with(
                    u'The selected order will be '
                    u'cancelled.', gtk.RESPONSE_YES, u"Cancel order",
                    u"Don't cancel")
                self.assertEquals(purchase.status,
                                  PurchaseOrder.ORDER_CANCELLED)
Esempio n. 2
0
    def testCommissionCreateAtEnd(self):
        api.sysparam(self.store).update_parameter(
            u'SALE_PAY_COMMISSION_WHEN_CONFIRMED', u'0')

        sale = self.create_sale()
        self.add_product(sale, quantity=1, price=200)
        sale.order()
        self.add_payments(sale, method_type=u'bill', installments=10)

        for p in sale.payments:
            self.assertEqual(
                self.store.find(Commission, payment=p).count(), 0)

        sale.confirm()
        transaction = IPaymentTransaction(sale)
        fake = lambda p: None
        # Mimic out old behaviour of only creating commissions for payments
        # when all payments on a sale are set as paid.
        with mock.patch.object(transaction, 'create_commission', new=fake):
            for p in sale.payments:
                # Confirming should not create commissions
                self.assertEqual(
                    self.store.find(Commission, payment=p).count(), 0)
                # Since we are mimicking the old behaviour, commission
                # should not be created here.
                p.pay()
                self.assertEqual(
                    self.store.find(Commission, payment=p).count(), 0)

        # Setting as paid should create all the missing commissions
        sale.set_paid()
        for p in sale.payments:
            self.assertEqual(
                self.store.find(Commission, payment=p).count(), 1)
Esempio n. 3
0
    def test_cancel_workorder_confirm(self, new_store, yesno):
        new_store.return_value = self.store

        self.clean_domain([WorkOrderItem, WorkOrder])
        workorder = self.create_workorder()

        api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0')
        app = self.create_app(MaintenanceApp, u'maintenance')

        olist = app.results
        olist.select(olist[0])

        # Initial status for the order is Opened
        self.assertEquals(workorder.status, WorkOrder.STATUS_OPENED)
        self.assertSensitive(app, ['Cancel'])

        with mock.patch.object(self.store, 'close'):
            with mock.patch.object(self.store, 'commit'):
                # Click the cancel order, and confirm the change
                yesno.return_value = True
                self.activate(app.Cancel)

                yesno.assert_called_once_with(
                    u"This will cancel the selected "
                    u"order. Are you sure?", gtk.RESPONSE_NO, u"Cancel order",
                    u"Don't cancel")

                # Status should be updated to cancelled.
                self.assertEquals(workorder.status, WorkOrder.STATUS_CANCELLED)
Esempio n. 4
0
    def test_cancel_workorder_confirm(self, new_store, yesno):
        new_store.return_value = self.store

        self.clean_domain([WorkOrderItem, WorkOrder])
        workorder = self.create_workorder()

        api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0')
        app = self.create_app(MaintenanceApp, u'maintenance')

        olist = app.results
        olist.select(olist[0])

        # Initial status for the order is Opened
        self.assertEquals(workorder.status, WorkOrder.STATUS_OPENED)
        self.assertSensitive(app, ['Cancel'])

        with mock.patch.object(self.store, 'close'):
            with mock.patch.object(self.store, 'commit'):
                # Click the cancel order, and confirm the change
                yesno.return_value = True
                self.activate(app.Cancel)

                yesno.assert_called_once_with(u"This will cancel the selected "
                                              u"order. Are you sure?",
                                              gtk.RESPONSE_NO, u"Cancel order",
                                              u"Don't cancel")

                # Status should be updated to cancelled.
                self.assertEquals(workorder.status, WorkOrder.STATUS_CANCELLED)
Esempio n. 5
0
    def test_cancel_workorder_confirm(self, new_store, run_dialog):
        new_store.return_value = self.store

        self.clean_domain([WorkOrderItem, WorkOrder])
        workorder = self.create_workorder()

        api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0')
        app = self.create_app(MaintenanceApp, u'maintenance')

        olist = app.results
        olist.select(olist[0])

        # Initial status for the order is Opened
        self.assertEquals(workorder.status, WorkOrder.STATUS_OPENED)
        self.assertSensitive(app, ['Cancel'])

        with mock.patch.object(self.store, 'close'):
            with mock.patch.object(self.store, 'commit'):
                # Click the cancel order, and confirm the change
                run_dialog.return_value = Note(notes=u'xxx')
                self.activate(app.Cancel)

                run_dialog.assert_called_once_with(
                    NoteEditor,
                    self.store,
                    message_text=(u'This will cancel the selected order. '
                                  u'Are you sure?'),
                    model=Note(),
                    mandatory=True,
                    label_text=u'Reason')

                # Status should be updated to cancelled.
                self.assertEquals(workorder.status, WorkOrder.STATUS_CANCELLED)
Esempio n. 6
0
    def test_cancel_workorder_confirm(self, new_store, run_dialog):
        new_store.return_value = self.store

        self.clean_domain([WorkOrderItem, WorkOrder])
        workorder = self.create_workorder()

        api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0')
        app = self.create_app(MaintenanceApp, u'maintenance')

        olist = app.results
        olist.select(olist[0])

        # Initial status for the order is Opened
        self.assertEquals(workorder.status, WorkOrder.STATUS_OPENED)
        self.assertSensitive(app, ['Cancel'])

        with mock.patch.object(self.store, 'close'):
            with mock.patch.object(self.store, 'commit'):
                # Click the cancel order, and confirm the change
                run_dialog.return_value = Note(notes=u'xxx')
                self.activate(app.Cancel)

                run_dialog.assert_called_once_with(
                    NoteEditor, self.store,
                    message_text=(u'This will cancel the selected order. '
                                  u'Are you sure?'),
                    model=Note(), mandatory=True, label_text=u'Reason')

                # Status should be updated to cancelled.
                self.assertEquals(workorder.status, WorkOrder.STATUS_CANCELLED)
Esempio n. 7
0
 def __init__(self, app, store=None):
     self._pages = {}
     self.accounts = AccountTree()
     AppWindow.__init__(self, app, store=store)
     self._tills_account = api.sysparam(self.store).TILLS_ACCOUNT
     self._imbalance_account = api.sysparam(self.store).IMBALANCE_ACCOUNT
     self._banks_account = api.sysparam(self.store).BANKS_ACCOUNT
Esempio n. 8
0
    def test_confirm_order(self, new_store, yesno):
        new_store.return_value = self.store
        yesno.return_value = True

        self.clean_domain([ReceivingOrderItem, ReceivingOrder,
                           PurchaseItem, PurchaseOrder])

        purchase = self.create_purchase_order()
        purchase.add_item(self.create_sellable(), 2)
        purchase.status = PurchaseOrder.ORDER_PENDING

        api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0')
        app = self.create_app(PurchaseApp, u'purchase')

        olist = app.results
        olist.select(olist[0])

        with mock.patch.object(self.store, 'close'):
            with mock.patch.object(self.store, 'commit'):
                self.activate(app.Confirm)
                yesno.assert_called_once_with(u'The selected order will be '
                                              u'marked as sent.',
                                              gtk.RESPONSE_YES,
                                              u"Confirm order", u"Don't confirm")
                self.assertEquals(purchase.status, PurchaseOrder.ORDER_CONFIRMED)
Esempio n. 9
0
    def test_batch_number_suggestion(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(), '')

        api.sysparam(self.store).update_parameter(u'SUGGEST_BATCH_NUMBER', u'1')
        try:
            storable.register_initial_stock(1, self.create_branch(), 0,
                                            batch_number=u'123')
            dialog = BatchIncreaseSelectionDialog(self.store, storable, 10)
            # Make sure it suggested right
            self.assertEqual(dialog._last_entry.get_text(), '124')

            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(), '125')
            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(), '126')
        finally:
            api.sysparam(self.store).update_parameter(u'SUGGEST_BATCH_NUMBER', u'0')
Esempio n. 10
0
    def testCommissionCreateOnPay(self):
        api.sysparam(self.store).update_parameter(
            u'SALE_PAY_COMMISSION_WHEN_CONFIRMED', u'0')

        sale = self.create_sale()
        self.add_product(sale, quantity=1, price=200)
        sale.order()
        self.add_payments(sale, method_type=u'bill', installments=10)

        for p in sale.payments:
            self.assertEqual(
                self.store.find(Commission, payment=p).count(), 0)

        sale.confirm()
        for p in sale.payments:
            # Confirming should not create commissions
            self.assertEqual(
                self.store.find(Commission, payment=p).count(), 0)
            # Paying should create the commission
            p.pay()
            self.assertEqual(
                self.store.find(Commission, payment=p).count(), 1)

        # Setting as paid should not create another commission
        sale.set_paid()
        for p in sale.payments:
            self.assertEqual(
                self.store.find(Commission, payment=p).count(), 1)
Esempio n. 11
0
 def __init__(self, window, store=None):
     # Account id -> TransactionPage
     self._pages = {}
     self.accounts = AccountTree()
     ShellApp.__init__(self, window, store=store)
     self._tills_account = api.sysparam(self.store).TILLS_ACCOUNT
     self._imbalance_account = api.sysparam(self.store).IMBALANCE_ACCOUNT
     self._banks_account = api.sysparam(self.store).BANKS_ACCOUNT
Esempio n. 12
0
    def test_print_report(self, print_report):
        api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0')
        app = self.create_app(PurchaseApp, u'purchase')

        self.activate(app.window.Print)
        self.assertEquals(print_report.call_count, 1)

        args, kwargs = print_report.call_args
        report, results, views = args
        self.assertEquals(report, PurchaseReport)
        self.assertTrue(isinstance(results, SearchResultListView))
        for view in views:
            self.assertTrue(isinstance(view, PurchaseOrderView))
Esempio n. 13
0
    def test_print_report(self, print_report):
        api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0')
        app = self.create_app(PurchaseApp, u'purchase')

        self.activate(app.launcher.Print)
        self.assertEquals(print_report.call_count, 1)

        args, kwargs = print_report.call_args
        report, results, views = args
        self.assertEquals(report, PurchaseReport)
        self.assertTrue(isinstance(results, SearchResults))
        for view in views:
            self.assertTrue(isinstance(view, PurchaseOrderView))
Esempio n. 14
0
    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(), '')

        try:
            api.sysparam(self.store).update_parameter(u'SUGGEST_BATCH_NUMBER', u'1')
            # We need to do this by hand sincr update_parameter won't let us
            # update value for some parameters (SYNCHRONIZED_MODE is one of them)
            api.sysparam(self.store).SYNCHRONIZED_MODE = u'1'
            api.sysparam(self.store).rebuild_cache_for(u'SYNCHRONIZED_MODE')
            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)
            # FIXME: Why is this not working? If i put a print before .update
            # and one after, I can see the traceback raises between the prints,
            # GUITest will say that there was an unhandled exception (this one)
            # and assertRaisesRegexp will say that ValueError wasn't raised. WTF???
            #with self.assertRaisesRegexp(
            #    ValueError,
            #    ("branch 'Moda Stoq' needs an acronym since we are on "
            #     "synchronized mode")):
            #    spinbutton.update(1)
        finally:
            api.sysparam(self.store).update_parameter(u'SUGGEST_BATCH_NUMBER', u'0')
            api.sysparam(self.store).SYNCHRONIZED_MODE = u'0'
            api.sysparam(self.store).rebuild_cache_for(u'SYNCHRONIZED_MODE')
Esempio n. 15
0
    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(self.store).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])
Esempio n. 16
0
    def get_batch_item(self, batch):
        if batch is not None:
            return batch.batch_number
        if not api.sysparam(self.store).SUGGEST_BATCH_NUMBER:
            return None

        return self._get_next_batch_number()
Esempio n. 17
0
    def cookie_login(self):
        if api.sysparam(api.get_default_store()).DISABLE_COOKIES:
            log.info("Cookies disable by parameter")
            return

        cookie_file = get_utility(ICookieFile)
        try:
            username, password = cookie_file.get()
        except CookieError:
            log.info("Not using cookie based login")
            return

        def is_md5(password):
            # This breaks for passwords that are 32 characters long,
            # uses only digits and lowercase a-f, pretty unlikely as
            # real-world password
            if len(password) != 32:
                return False
            for c in '1234567890abcdef':
                password = password.replace(c, '')
            return password == ''

        # Migrate old passwords to md5 hashes.
        if not is_md5(password):
            password = LoginUser.hash(password)
            cookie_file.store(username, password)

        try:
            user = self._check_user(username, password)
        except (LoginError, UserProfileError, DatabaseError) as e:
            log.info("Cookie login failed: %r" % e)
            return

        log.info("Logging in using cookie credentials")
        return user
Esempio n. 18
0
    def _get_sellable(self):
        barcode = self.barcode.get_text()
        if not barcode:
            raise StoqlibError("_get_sellable needs a barcode")
        barcode = unicode(barcode)

        fmt = api.sysparam(self.store).SCALE_BARCODE_FORMAT

        # Check if this barcode is from a scale
        info = parse_barcode(barcode, fmt)
        if info:
            barcode = info.code
            weight = info.weight

        sellable = self.store.find(Sellable, barcode=barcode,
                                   status=Sellable.STATUS_AVAILABLE).one()

        # If the barcode didnt match, maybe the user typed the product code
        if not sellable:
            sellable = self.store.find(Sellable, code=barcode,
                                       status=Sellable.STATUS_AVAILABLE).one()

        # If the barcode has the price information, we need to calculate the
        # corresponding weight.
        if info and sellable and info.mode == BarcodeInfo.MODE_PRICE:
            weight = info.price / sellable.price

        if info and sellable:
            self.quantity.set_value(weight)

        return sellable
Esempio n. 19
0
File: shell.py Progetto: romaia/stoq
    def run_embedded(self, appdesc, app_window, params=None):
        app = self._load_app(appdesc, app_window)
        app.launcher = app_window

        self._current_app = app
        self._appname = appdesc.name

        if appdesc.name in self._blocked_apps:
            app_window.show()
            return

        app.run(params)

        # Possibly correct window position (livecd workaround for small
        # screens)
        from stoqlib.lib.pluginmanager import get_plugin_manager
        manager = get_plugin_manager()
        from stoqlib.api import api
        if (api.sysparam(api.get_default_store()).DEMO_MODE
            and manager.is_active(u'ecf')):
            pos = app.main_window.toplevel.get_position()
            if pos[0] < 220:
                app.main_window.toplevel.move(220, pos[1])

        return app
Esempio n. 20
0
    def on_estimated_start__validate(self, widget, value):
        sysparam_ = api.sysparam(self.store)
        if (value < datetime.date.today() and
                not sysparam_.ALLOW_OUTDATED_OPERATIONS):
            return ValidationError(u"The start date cannot be on the past")

        self.estimated_finish.validate(force=True)
Esempio n. 21
0
    def on_estimated_start__validate(self, widget, value):
        sysparam_ = api.sysparam(self.store)
        if (value < localtoday().date()
                and not sysparam_.ALLOW_OUTDATED_OPERATIONS):
            return ValidationError(u"The start date cannot be on the past")

        self.estimated_finish.validate(force=True)
Esempio n. 22
0
    def get_namespace(self):
        store = self.loan.store
        sysparam_ = api.sysparam(store)

        order_identifier = unicode(self.loan.identifier)
        print_promissory_note = sysparam_.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=drawer_person.name,
            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,
        )
Esempio n. 23
0
    def create_ui(self):
        if api.sysparam(self.store).SMART_LIST_LOADING:
            self.search.enable_lazy_search()

        self.popup = self.uimanager.get_widget('/StockSelection')
        self.window.add_new_items([self.NewReceiving, self.NewTransfer,
                                   self.NewStockDecrease, self.LoanNew])
        self.window.add_search_items([
            self.SearchStockItems,
            self.SearchStockDecrease,
            self.SearchClosedStockItems,
            self.SearchProductHistory,
            self.SearchPurchasedStockItems,
            self.SearchTransfer,
        ])
        self.window.Print.set_tooltip(
            _("Print a report of these products"))
        self._inventory_widgets = [self.NewTransfer, self.NewReceiving,
                                   self.StockInitial, self.NewStockDecrease,
                                   self.LoanNew, self.LoanClose]
        self.register_sensitive_group(self._inventory_widgets,
                                      lambda: not self.has_open_inventory())

        self.image_viewer = None

        self.image = gtk.Image()
        self.edit_button = self.uimanager.get_widget('/toolbar/AppToolbarPH/EditProduct')
        self.edit_button.set_icon_widget(self.image)
        self.image.show()

        self.search.set_summary_label(column='stock',
                                      label=_('<b>Stock Total:</b>'),
                                      format='<b>%s</b>',
                                      parent=self.get_statusbar_message_area())
Esempio n. 24
0
    def create_ui(self):
        if api.sysparam(self.store).SMART_LIST_LOADING:
            self.search.enable_lazy_search()

        self.window.add_new_items([
            self.NewOrder,
            self.NewQuote,
            self.NewProduct,
            self.NewConsignment])
        self.window.add_search_items([
            self.Products,
            self.Suppliers,
            self.SearchQuotes,
            self.Services])
        self.search.set_summary_label(column='total',
                                      label=('<b>%s</b>' %
                                             api.escape(_('Orders total:'))),
                                      format='<b>%s</b>',
                                      parent=self.get_statusbar_message_area())
        self.results.set_selection_mode(gtk.SELECTION_MULTIPLE)
        self.Confirm.set_sensitive(False)

        self._inventory_widgets = [self.NewConsignment,
                                   self.CloseInConsignment]
        self.register_sensitive_group(self._inventory_widgets,
                                      lambda: not self.has_open_inventory())
Esempio n. 25
0
    def get_namespace(self):
        store = self.loan.store
        sysparam_ = api.sysparam(store)

        order_identifier = unicode(self.loan.identifier)
        print_promissory_note = sysparam_.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,
        )
Esempio n. 26
0
    def _pay(self, payable_views):
        """
        Pay a list of items from a payable_views, note that
        the list of payable_views must reference the same order
        @param payables_views: a list of payable_views
        """
        assert self._can_pay(payable_views)

        # Do not allow confirming the payment if the purchase was not
        # completely received.
        purchase_order = payable_views[0].purchase

        if (purchase_order and
            api.sysparam(self.store).BLOCK_INCOMPLETE_PURCHASE_PAYMENTS and
            not purchase_order.status == PurchaseOrder.ORDER_CLOSED):

            return warning(_("Can't confirm the payment if the purchase "
                             "is not completely received yet."))

        with api.trans() as store:
            payments = [store.fetch(view.payment) for view in payable_views]

            run_dialog(PurchasePaymentConfirmSlave, self, store,
                       payments=payments)

        if store.committed:
            # We need to refresh the whole list as the payment(s) can possibly
            # disappear for the selected view
            self.refresh()

        self._update_widgets()
Esempio n. 27
0
    def cookie_login(self):
        if api.sysparam(api.get_default_store()).DISABLE_COOKIES:
            log.info("Cookies disable by parameter")
            return

        cookie_file = get_utility(ICookieFile)
        try:
            username, password = cookie_file.get()
        except CookieError:
            log.info("Not using cookie based login")
            return

        def is_md5(password):
            # This breaks for passwords that are 32 characters long,
            # uses only digits and lowercase a-f, pretty unlikely as
            # real-world password
            if len(password) != 32:
                return False
            for c in '1234567890abcdef':
                password = password.replace(c, '')
            return password == ''

        # Migrate old passwords to md5 hashes.
        if not is_md5(password):
            password = _encrypt_password(password)
            cookie_file.store(username, password)

        try:
            user = self._check_user(username, password)
        except (LoginError, UserProfileError, DatabaseError) as e:
            log.info("Cookie login failed: %r" % e)
            return

        log.info("Logging in using cookie credentials")
        return user
Esempio n. 28
0
    def create_ui(self):
        if api.sysparam(self.store).SMART_LIST_LOADING:
            self.search.enable_lazy_search()

        self.popup = self.uimanager.get_widget('/StockSelection')
        self.window.add_new_items([self.NewReceiving, self.NewTransfer,
                                   self.NewStockDecrease, self.LoanNew])
        self.window.add_search_items([
            self.SearchStockItems,
            self.SearchStockDecrease,
            self.SearchClosedStockItems,
            self.SearchProductHistory,
            self.SearchPurchasedStockItems,
            self.SearchTransfer,
        ])
        self.window.Print.set_tooltip(
            _("Print a report of these products"))
        self._inventory_widgets = [self.NewTransfer, self.NewReceiving,
                                   self.StockInitial, self.NewStockDecrease,
                                   self.LoanNew, self.LoanClose]
        self.register_sensitive_group(self._inventory_widgets,
                                      lambda: not self.has_open_inventory())

        self.image_viewer = None

        self.image = gtk.Image()
        self.edit_button = self.uimanager.get_widget('/toolbar/AppToolbarPH/EditProduct')
        self.edit_button.set_icon_widget(self.image)
        self.image.show()

        self.search.set_summary_label(column='stock',
                                      label=_('<b>Stock Total:</b>'),
                                      format='<b>%s</b>',
                                      parent=self.get_statusbar_message_area())
Esempio n. 29
0
    def _pay(self, payable_views):
        """
        Pay a list of items from a payable_views, note that
        the list of payable_views must reference the same order
        @param payables_views: a list of payable_views
        """
        assert self._can_pay(payable_views)

        # Do not allow confirming the payment if the purchase was not
        # completely received.
        purchase_order = payable_views[0].purchase

        if (purchase_order
                and api.sysparam(self.store).BLOCK_INCOMPLETE_PURCHASE_PAYMENTS
                and not purchase_order.status == PurchaseOrder.ORDER_CLOSED):

            return warning(
                _("Can't confirm the payment if the purchase "
                  "is not completely received yet."))

        with api.trans() as store:
            payments = [store.fetch(view.payment) for view in payable_views]

            run_dialog(PurchasePaymentConfirmSlave,
                       self,
                       store,
                       payments=payments)

        if store.committed:
            # We need to refresh the whole list as the payment(s) can possibly
            # disappear for the selected view
            self.refresh()

        self._update_widgets()
Esempio n. 30
0
File: pos.py Progetto: tmaxter/stoq
    def _get_sellable(self):
        barcode = self.barcode.get_text()
        if not barcode:
            raise StoqlibError("_get_sellable needs a barcode")
        barcode = unicode(barcode)

        fmt = api.sysparam(self.store).SCALE_BARCODE_FORMAT

        # Check if this barcode is from a scale
        info = parse_barcode(barcode, fmt)
        if info:
            barcode = info.code
            weight = info.weight

        sellable = self.store.find(Sellable,
                                   barcode=barcode,
                                   status=Sellable.STATUS_AVAILABLE).one()

        # If the barcode didnt match, maybe the user typed the product code
        if not sellable:
            sellable = self.store.find(Sellable,
                                       code=barcode,
                                       status=Sellable.STATUS_AVAILABLE).one()

        # If the barcode has the price information, we need to calculate the
        # corresponding weight.
        if info and sellable and info.mode == BarcodeInfo.MODE_PRICE:
            weight = info.price / sellable.price

        if info and sellable:
            self.quantity.set_value(weight)

        return sellable
Esempio n. 31
0
    def _delete_account(self, account_view):
        store = api.new_store()
        account = store.fetch(account_view.account)
        methods = PaymentMethod.get_by_account(store, account)
        if methods.count() > 0:
            if not yesno(
                _('This account is used in at least one payment method.\n'
                  'To be able to delete it the payment methods needs to be'
                  're-configured first'), gtk.RESPONSE_NO,
                _("Configure payment methods"), _("Keep account")):
                store.close()
                return
        elif not yesno(
            _('Are you sure you want to remove account "%s" ?') % (
                (account_view.description, )), gtk.RESPONSE_NO,
            _("Remove account"), _("Keep account")):
            store.close()
            return

        if account_view.id in self._pages:
            account_page = self._pages[account_view.id]
            self._close_page(account_page)

        self.accounts.remove(account_view)
        self.accounts.flush()

        imbalance = api.sysparam(store).IMBALANCE_ACCOUNT
        for method in methods:
            method.destination_account = imbalance

        account.remove(store)
        store.commit(close=True)
Esempio n. 32
0
 def _search_product(self):
     hide_cost_column = not api.sysparam(
         self.store).SHOW_COST_COLUMN_IN_SALES
     self.run_dialog(ProductSearch,
                     self.store,
                     hide_footer=True,
                     hide_toolbar=True,
                     hide_cost_column=hide_cost_column)
Esempio n. 33
0
def test_sellable_tax_constant():  # pragma nocover
    ec = api.prepare_test()
    tax_constant = api.sysparam(ec.store).DEFAULT_PRODUCT_TAX_CONSTANT
    run_dialog(SellableTaxConstantEditor,
               parent=None,
               store=ec.store,
               model=tax_constant)
    print(tax_constant)
Esempio n. 34
0
 def get_uri(self):
     if locale.getlocale()[0] == 'pt_BR' or platform.system() == 'Windows':
         content = environ.find_resource('html', 'welcome-pt_BR.html')
     else:
         content = environ.find_resource('html', 'welcome.html')
     if api.sysparam(api.get_default_store()).DEMO_MODE:
         content += '?demo-mode'
     return 'file:///' + content
Esempio n. 35
0
 def create_ui(self):
     if api.sysparam(self.store).SMART_LIST_LOADING:
         self.search.enable_lazy_search()
     self.results.set_selection_mode(gtk.SELECTION_MULTIPLE)
     self.search.set_summary_label(column='value',
                                   label='<b>%s</b>' % (_('Total'), ),
                                   format='<b>%s</b>',
                                   parent=self.get_statusbar_message_area())
     self.results.set_cell_data_func(self._on_results__cell_data_func)
Esempio n. 36
0
 def create_ui(self):
     if api.sysparam(self.store).SMART_LIST_LOADING:
         self.search.enable_lazy_search()
     self.results.set_selection_mode(gtk.SELECTION_MULTIPLE)
     self.search.set_summary_label(column='value',
                                   label='<b>%s</b>' % (_('Total'), ),
                                   format='<b>%s</b>',
                                   parent=self.get_statusbar_message_area())
     self.results.set_cell_data_func(self._on_results__cell_data_func)
Esempio n. 37
0
File: pos.py Progetto: rosalin/stoq
    def _create_sale(self, store):
        user = api.get_current_user(store)
        branch = api.get_current_branch(store)
        salesperson = user.person.salesperson
        cfop = api.sysparam(store).DEFAULT_SALES_CFOP
        group = PaymentGroup(store=store)
        sale = Sale(
            store=store,
            branch=branch,
            salesperson=salesperson,
            group=group,
            cfop=cfop,
            coupon_id=None,
            operation_nature=api.sysparam(store).DEFAULT_OPERATION_NATURE)

        if self._delivery:
            sale.client = store.fetch(self._delivery.client)
            sale.storeporter = store.fetch(self._delivery.transporter)
            delivery = Delivery(
                store=store,
                address=store.fetch(self._delivery.address),
                transporter=store.fetch(self._delivery.transporter),
            )
        else:
            delivery = None
            sale.client = self._suggested_client

        for fake_sale_item in self.sale_items:
            sale_item = sale.add_sellable(
                store.fetch(fake_sale_item.sellable),
                price=fake_sale_item.price,
                quantity=fake_sale_item.quantity,
                quantity_decreased=fake_sale_item.quantity_decreased,
                batch=store.fetch(fake_sale_item.batch))
            sale_item.notes = fake_sale_item.notes
            sale_item.estimated_fix_date = fake_sale_item.estimated_fix_date

            if delivery and fake_sale_item.deliver:
                delivery.add_item(sale_item)
            elif delivery and fake_sale_item == self._delivery_item:
                delivery.service_item = sale_item

        return sale
Esempio n. 38
0
 def _maybe_print_labels(self):
     param = api.sysparam(self.store).LABEL_TEMPLATE_PATH
     if not param.path:
         return
     if not yesno(_(u'Do you want to print the labels for the received products?'),
                  gtk.RESPONSE_YES, _(u'Print labels'), _(u"Don't print")):
         return
     label_data = run_dialog(SkipLabelsEditor, self, self.store)
     if label_data:
         print_labels(label_data, self.store, self.model.purchase)
Esempio n. 39
0
    def _setup_widgets(self):
        quote_group = str(self.wizard.quote_group.identifier)
        self.quote_group.set_text(quote_group)

        branches = Branch.get_active_branches(self.store)
        self.branch_combo.prefill(api.for_person_combo(branches))
        sync_mode = api.sysparam(self.store).SYNCHRONIZED_MODE
        self.branch_combo.set_sensitive(not sync_mode)

        self.notes.set_accepts_tab(False)
Esempio n. 40
0
    def setUp(self):
        super(TestBooklet, self).setUp()

        api.sysparam(self.store).BOOKLET_INSTRUCTIONS = (
            u"Instruction line 1\n"
            u"Instruction line 2\n"
            u"Instruction line 3\n"
            u"Instruction line 4\n"
            # This should not appear as it's limited to 4 lines
            u"Instruction line 5\n")
Esempio n. 41
0
    def test_edit_quote_order(self, run_dialog):
        api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0')
        purchase = self.create_purchase_order()

        app = self.create_app(PurchaseApp, u'purchase')
        for purchase in app.results:
            purchase.open_date = datetime.datetime(2012, 1, 1)
        olist = app.results
        olist.select(olist[0])

        with mock.patch('stoq.gui.purchase.api', new=self.fake.api):
            self.fake.set_retval(purchase)
            self.activate(app.NewQuote)

            self.assertEquals(run_dialog.call_count, 1)
            args, kwargs = run_dialog.call_args
            wizard, store, edit_mode = args
            self.assertEquals(wizard, QuotePurchaseWizard)
            self.assertTrue(store is not None)
            self.assertEquals(edit_mode, None)
Esempio n. 42
0
    def setUp(self):
        super(TestBooklet, self).setUp()

        api.sysparam(self.store).BOOKLET_INSTRUCTIONS = (
            u"Instruction line 1\n"
            u"Instruction line 2\n"
            u"Instruction line 3\n"
            u"Instruction line 4\n"
            # This should not appear as it's limited to 4 lines
            u"Instruction line 5\n"
        )
Esempio n. 43
0
    def test_edit_quote_order(self, run_dialog):
        api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0')
        purchase = self.create_purchase_order()

        app = self.create_app(PurchaseApp, u'purchase')
        for purchase in app.main_window.results:
            purchase.open_date = datetime.datetime(2012, 1, 1)
        olist = app.main_window.results
        olist.select(olist[0])

        with mock.patch('stoq.gui.purchase.api', new=self.fake.api):
            self.fake.set_retval(purchase)
            self.activate(app.main_window.NewQuote)

            self.assertEquals(run_dialog.call_count, 1)
            args, kwargs = run_dialog.call_args
            wizard, store, edit_mode = args
            self.assertEquals(wizard, QuotePurchaseWizard)
            self.assertTrue(store is not None)
            self.assertEquals(edit_mode, None)
Esempio n. 44
0
    def _create_sale(self, store):
        user = api.get_current_user(store)
        branch = api.get_current_branch(store)
        salesperson = user.person.salesperson
        cfop = api.sysparam(store).DEFAULT_SALES_CFOP
        group = PaymentGroup(store=store)
        sale = Sale(store=store,
                    branch=branch,
                    salesperson=salesperson,
                    group=group,
                    cfop=cfop,
                    coupon_id=None,
                    operation_nature=api.sysparam(store).DEFAULT_OPERATION_NATURE)

        if self._delivery:
            sale.client = store.fetch(self._delivery.client)
            sale.storeporter = store.fetch(self._delivery.transporter)
            delivery = Delivery(
                store=store,
                address=store.fetch(self._delivery.address),
                transporter=store.fetch(self._delivery.transporter),
            )
        else:
            delivery = None
            sale.client = self._suggested_client

        for fake_sale_item in self.sale_items:
            sale_item = sale.add_sellable(
                store.fetch(fake_sale_item.sellable),
                price=fake_sale_item.price, quantity=fake_sale_item.quantity,
                quantity_decreased=fake_sale_item.quantity_decreased,
                batch=store.fetch(fake_sale_item.batch))
            sale_item.notes = fake_sale_item.notes
            sale_item.estimated_fix_date = fake_sale_item.estimated_fix_date

            if delivery and fake_sale_item.deliver:
                delivery.add_item(sale_item)
            elif delivery and fake_sale_item == self._delivery_item:
                delivery.service_item = sale_item

        return sale
Esempio n. 45
0
    def test_new_product(self, new_store, run_dialog):
        new_store.return_value = self.store

        self.clean_domain([ReceivingOrderItem, ReceivingOrder,
                           PurchaseItem, PurchaseOrder])

        purchase = self.create_purchase_order()
        purchase.add_item(self.create_sellable(), 2)
        purchase.status = PurchaseOrder.ORDER_PENDING

        api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0')
        app = self.create_app(PurchaseApp, u'purchase')

        olist = app.main_window.results
        olist.select(olist[0])

        with mock.patch.object(self.store, 'close'):
            with mock.patch.object(self.store, 'commit'):
                self.activate(app.main_window.NewProduct)
                run_dialog.assert_called_once_with(ProductEditor,
                                                   self.store, model=None)
Esempio n. 46
0
    def test_details_dialog(self, run_dialog):
        self.clean_domain(
            [ReceivingOrderItem, ReceivingOrder, PurchaseItem, PurchaseOrder])

        purchase = self.create_purchase_order()
        purchase.add_item(self.create_sellable(), 2)

        api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0')
        app = self.create_app(PurchaseApp, u'purchase')

        olist = app.results
        olist.select(olist[0])
        olist.double_click(0)

        self.assertEquals(run_dialog.call_count, 1)
        args, kwargs = run_dialog.call_args
        dialog, store = args

        self.assertEquals(dialog, PurchaseDetailsDialog)
        self.assertTrue(store is not None)
        self.assertEquals(kwargs[u'model'], purchase)
Esempio n. 47
0
    def test_details_dialog(self, run_dialog):
        self.clean_domain([ReceivingOrderItem, ReceivingOrder,
                           PurchaseItem, PurchaseOrder])

        purchase = self.create_purchase_order()
        purchase.add_item(self.create_sellable(), 2)

        api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0')
        app = self.create_app(PurchaseApp, u'purchase')

        olist = app.main_window.results
        olist.select(olist[0])
        olist.double_click(0)

        self.assertEquals(run_dialog.call_count, 1)
        args, kwargs = run_dialog.call_args
        dialog, store = args

        self.assertEquals(dialog, PurchaseDetailsDialog)
        self.assertTrue(store is not None)
        self.assertEquals(kwargs[u'model'], purchase)
Esempio n. 48
0
    def test_new_product(self, new_store, run_dialog):
        new_store.return_value = self.store

        self.clean_domain(
            [ReceivingOrderItem, ReceivingOrder, PurchaseItem, PurchaseOrder])

        purchase = self.create_purchase_order()
        purchase.add_item(self.create_sellable(), 2)
        purchase.status = PurchaseOrder.ORDER_PENDING

        api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0')
        app = self.create_app(PurchaseApp, u'purchase')

        olist = app.results
        olist.select(olist[0])

        with mock.patch.object(self.store, 'close'):
            with mock.patch.object(self.store, 'commit'):
                self.activate(app.NewProduct)
                run_dialog.assert_called_once_with(ProductEditor,
                                                   self.store,
                                                   model=None)
Esempio n. 49
0
    def setup_widgets(self):
        self.get_toplevel().set_size_request(*self.size)
        self.notification_label.set_text('')
        self.notification_label.set_color('black')

        if api.sysparam(api.get_default_store()).DISABLE_COOKIES:
            self.remember.hide()
            self.remember.set_active(False)

        gtkimage = gtk.Image()
        gtkimage.set_from_pixbuf(render_logo_pixbuf('login'))
        self.logo_container.add(gtkimage)
        self.logo_container.show_all()
Esempio n. 50
0
    def setup_widgets(self):
        self.get_toplevel().set_size_request(*self.size)
        self.notification_label.set_text('')
        self.notification_label.set_color('black')

        if api.sysparam(api.get_default_store()).DISABLE_COOKIES:
            self.remember.hide()
            self.remember.set_active(False)

        gtkimage = gtk.Image()
        gtkimage.set_from_pixbuf(render_logo_pixbuf('login'))
        self.logo_container.add(gtkimage)
        self.logo_container.show_all()
Esempio n. 51
0
    def test_finish_order(self, new_store, run_dialog):
        new_store.return_value = self.store
        self.clean_domain(
            [ReceivingOrderItem, ReceivingOrder, PurchaseItem, PurchaseOrder])

        purchase = self.create_purchase_order()
        purchase.add_item(self.create_sellable(), 2)
        purchase.get_items()[0].quantity_received = 2
        purchase.status = PurchaseOrder.ORDER_CONFIRMED
        purchase.received_quantity = 2

        api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0')
        app = self.create_app(PurchaseApp, u'purchase')

        olist = app.results
        olist.select(olist[0])

        with mock.patch.object(self.store, 'close'):
            with mock.patch.object(self.store, 'commit'):
                self.activate(app.Finish)
                run_dialog.assert_called_once_with(PurchaseFinishWizard,
                                                   self.store, purchase)
Esempio n. 52
0
    def test_finish_workorder_dont_confirm(self, new_store, yesno):
        new_store.return_value = self.store

        self.clean_domain([WorkOrderItem, WorkOrder])
        workorder = self.create_workorder()

        # Setted WorkOrder status for Work in Progress
        workorder.status = WorkOrder.STATUS_WORK_IN_PROGRESS

        api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0')
        app = self.create_app(MaintenanceApp, u'maintenance')

        olist = app.results
        olist.select(olist[0])

        self.assertNotSensitive(app, ['Finish'])
        workorder.add_sellable(self.create_sellable())
        # Selecting again will update actions sensitivity
        olist.select(olist[0])
        self.assertSensitive(app, ['Finish'])
        # Initial status for the order is Opened
        self.assertEquals(workorder.status, WorkOrder.STATUS_WORK_IN_PROGRESS)
        self.assertTrue(workorder.can_finish())

        with mock.patch.object(self.store, 'close'):
            with mock.patch.object(self.store, 'commit'):
                # Click the finish order, but dont confirm the change
                yesno.return_value = False
                self.activate(app.Finish)

                yesno.assert_called_once_with(
                    u"This will finish the selected "
                    "order, marking the work as done."
                    " Are you sure?", gtk.RESPONSE_NO, u"Finish order",
                    u"Don't finish")

        # Status should not be altered. ie, its still in Progress
        self.assertEquals(workorder.status, WorkOrder.STATUS_WORK_IN_PROGRESS)
Esempio n. 53
0
    def test_new_quote_order(self, new_store, run_dialog, select_result):
        new_store.return_value = self.store

        self.clean_domain(
            [ReceivingOrderItem, ReceivingOrder, PurchaseItem, PurchaseOrder])

        quotation = self.create_quotation()
        quotation.purchase.add_item(self.create_sellable(), 2)
        quotation.purchase.status = PurchaseOrder.ORDER_PENDING

        api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0')
        app = self.create_app(PurchaseApp, u'purchase')

        olist = app.results
        olist.select(olist[0])
        self.store.retval = olist[0]

        with mock.patch.object(self.store, 'close'):
            with mock.patch.object(self.store, 'commit'):
                self.activate(app.Edit)
                run_dialog.assert_called_once_with(PurchaseWizard, self.store,
                                                   quotation.purchase, False)
                select_result.assert_called_once_with(olist[0])
Esempio n. 54
0
    def testLoanReceipt(self):
        sysparam_ = api.sysparam(self.store)
        client = self.create_client()
        address = self.create_address()
        address.person = client.person
        loan = self.create_loan(client=client)

        for i in range(3):
            self.create_loan_item(loan=loan, quantity=i)

        sysparam_.update_parameter(u'PRINT_PROMISSORY_NOTE_ON_LOAN', u'0')
        self._diff_expected(LoanReceipt, 'loan-receipt', loan)

        sysparam_.update_parameter(u'PRINT_PROMISSORY_NOTE_ON_LOAN', u'1')
        self._diff_expected(LoanReceipt, 'loan-receipt-with-pn', loan)
Esempio n. 55
0
    def _configure_boleto(self, number, account, agency, **kwargs):
        bill = PaymentMethod.get_by_name(self.store, u'bill')
        bank_account = BankAccount(account=bill.destination_account,
                                   bank_account=account,
                                   bank_branch=agency,
                                   bank_number=int(number),
                                   store=self.store)

        for key, value in kwargs.items():
            BillOption(store=self.store,
                       bank_account=bank_account,
                       option=unicode(key),
                       value=value)
        api.sysparam(
            self.store).BILL_INSTRUCTIONS = u'Primeia linha da instrução'
Esempio n. 56
0
File: pos.py Progetto: tmaxter/stoq
    def __init__(self, window, store=None):
        self._suggested_client = None
        self._current_store = None
        self._trade = None
        self._trade_infobar = None

        ShellApp.__init__(self, window, store=store)

        self._delivery = None
        self.param = api.sysparam(self.store)
        self._coupon = None
        # Cant use self._coupon to verify if there is a sale, since
        # CONFIRM_SALES_ON_TILL doesnt create a coupon
        self._sale_started = False
        self._scale_settings = DeviceSettings.get_scale_settings(self.store)