Пример #1
0
 def before_start(self, store):
     till = Till.get_current(store)
     if till is None:
         till = Till(store=store,
                     station=get_current_station(store))
         till.open_till()
         assert till == Till.get_current(store)
Пример #2
0
    def testGetCurrentTillClose(self):
        station = get_current_station(self.store)
        self.assertEqual(Till.get_current(self.store), None)
        till = Till(store=self.store, station=station)
        till.open_till()

        self.assertEqual(Till.get_current(self.store), till)
        till.close_till()
        self.assertEqual(Till.get_current(self.store), None)
Пример #3
0
    def test_get_current_till_close(self):
        station = get_current_station(self.store)
        self.assertEqual(Till.get_current(self.store), None)
        till = Till(store=self.store, station=station)
        till.open_till()

        self.assertEqual(Till.get_current(self.store), till)
        till.close_till()
        self.assertEqual(Till.get_current(self.store), None)
Пример #4
0
    def testGetCurrentTillOpen(self):
        self.assertEqual(Till.get_current(self.store), None)

        station = get_current_station(self.store)
        till = Till(store=self.store, station=station)

        self.assertEqual(Till.get_current(self.store), None)
        till.open_till()
        self.assertEqual(Till.get_current(self.store), till)
        self.assertEqual(till.opening_date.date(), localtoday().date())
        self.assertEqual(till.status, Till.STATUS_OPEN)

        self.assertRaises(TillError, till.open_till)
Пример #5
0
    def test_get_current_till_close(self):
        self.assertEqual(Till.get_current(self.store, self.current_station),
                         None)
        till = Till(store=self.store,
                    branch=self.current_branch,
                    station=self.current_station)
        till.open_till(self.current_user)

        self.assertEqual(Till.get_current(self.store, self.current_station),
                         till)
        till.close_till(self.current_user)
        self.assertEqual(Till.get_current(self.store, self.current_station),
                         None)
Пример #6
0
    def test_get_current_till_open(self):
        self.assertEqual(Till.get_current(self.store), None)

        station = get_current_station(self.store)
        till = Till(store=self.store, station=station)

        self.assertEqual(Till.get_current(self.store), None)
        till.open_till()
        self.assertEqual(Till.get_current(self.store), till)
        self.assertEqual(till.opening_date.date(), localtoday().date())
        self.assertEqual(till.status, Till.STATUS_OPEN)

        self.assertRaises(TillError, till.open_till)
Пример #7
0
    def on_Edit__activate(self, action):
        try:
            Till.get_current(self.store)
        except TillError as e:
            warning(str(e))
            return

        store = api.new_store()
        views = self.results.get_selected_rows()
        sale = store.fetch(views[0].sale)
        retval = run_dialog(SalePaymentsEditor, self, store, sale)

        if store.confirm(retval):
            self.refresh()
        store.close()
Пример #8
0
    def on_Edit__activate(self, action):
        try:
            Till.get_current(self.store, api.get_current_station(self.store))
        except TillError as e:
            warning(str(e))
            return

        store = api.new_store()
        views = self.results.get_selected_rows()
        sale = store.fetch(views[0].sale)
        retval = run_dialog(SalePaymentsEditor, self, store, sale)

        if store.confirm(retval):
            self.refresh()
        store.close()
Пример #9
0
    def create_sale(self, id_=None, branch=None, client=None):
        from stoqlib.domain.sale import Sale
        from stoqlib.domain.till import Till

        till = Till.get_current(self.store)
        if till is None:
            till = self.create_till()
            till.open_till()
        salesperson = self.create_sales_person()
        group = self.create_payment_group()
        if client:
            group.payer = client.person

        sale = Sale(
            coupon_id=0,
            open_date=TransactionTimestamp(),
            salesperson=salesperson,
            branch=branch or get_current_branch(self.store),
            cfop=sysparam(self.store).DEFAULT_SALES_CFOP,
            group=group,
            client=client,
            store=self.store,
        )
        if id_:
            sale.id = id_
            sale.identifier = id_
        return sale
Пример #10
0
    def _open_till(self, store):
        till = Till(store=store, station=api.get_current_station(store))
        till.open_till()

        TillOpenEvent.emit(till=till)
        self.assertEquals(till, Till.get_current(store))
        return till
Пример #11
0
    def open_till(self):
        """Opens the till
        """
        try:
            current_till = Till.get_current(self.store)
        except TillError as e:
            warning(str(e))
            return False

        if current_till is not None:
            warning(_("You already have a till operation opened. "
                      "Close the current Till and open another one."))
            return False

        store = api.new_store()
        try:
            model = run_dialog(TillOpeningEditor, self._parent, store)
        except TillError as e:
            warning(str(e))
            model = None

        retval = store.confirm(model)
        store.close()
        if retval:
            self._till_status_changed(closed=False, blocked=False)
        return retval
Пример #12
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, self.PaymentReceive], not closed
                           or blocked)

        widgets = [
            self.TillVerify, self.TillAddCash, self.TillRemoveCash,
            self.SearchTillHistory, self.app_vbox
        ]
        self.set_sensitive(widgets, not closed and not blocked)

        if closed:
            text = _(u"Till closed")
            self.clear()
            self.setup_focus()
        elif blocked:
            text = _(u"Till blocked from previous day")
        else:
            till = Till.get_current(self.store)
            text = _(u"Till opened on %s") % till.opening_date.strftime('%x')

        self.till_status_label.set_text(text)

        self._update_toolbar_buttons()
        self._update_total()
Пример #13
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, self.PaymentReceive],
                           not closed or blocked)

        widgets = [self.TillVerify, self.TillAddCash, self.TillRemoveCash,
                   self.SearchTillHistory, self.app_vbox]
        self.set_sensitive(widgets, not closed and not blocked)

        if closed:
            text = _(u"Till closed")
            self.clear()
            self.setup_focus()
        elif blocked:
            text = _(u"Till blocked from previous day")
        else:
            till = Till.get_current(self.store)
            text = _(u"Till opened on %s") % till.opening_date.strftime('%x')

        self.till_status_label.set_text(text)

        self._update_toolbar_buttons()
        self._update_total()
Пример #14
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()
Пример #15
0
    def _receive(self):
        with api.new_store() as store:
            till = Till.get_current(store)
            assert till

            in_payment = self.results.get_selected()
            payment = store.fetch(in_payment.payment)
            assert self._can_receive(payment)

            retval = run_dialog(SalePaymentConfirmSlave, self, store,
                                payments=[payment], show_till_info=False)
            if not retval:
                return

            try:
                TillAddCashEvent.emit(till=till, value=payment.value)
            except (TillError, DeviceError, DriverError) as e:
                warning(str(e))
                return

            till_entry = till.add_credit_entry(payment.value,
                                               _(u'Received payment: %s') % payment.description)

            TillAddTillEntryEvent.emit(till_entry, store)

        if store.committed:
            self.search.refresh()
Пример #16
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_last_coupon()
            if not cancelled:
                info(_("Cancelling sale failed, nothing to cancel"))
                store.close()
                return
            else:
                self._cancel_last_sale(last_doc, store)
        store.commit()
Пример #17
0
    def open_till(self):
        """Opens the till
        """
        try:
            current_till = Till.get_current(
                self.store, api.get_current_station(self.store))
        except TillError as e:
            warning(str(e))
            return False

        if current_till is not None:
            warning(
                _("You already have a till operation opened. "
                  "Close the current Till and open another one."))
            return False

        store = api.new_store()
        try:
            model = run_dialog(TillOpeningEditor, self._parent, store)
        except TillError as e:
            warning(str(e))
            model = None

        retval = store.confirm(model)
        store.close()
        if retval:
            self._till_status_changed(closed=False, blocked=False)
        return retval
Пример #18
0
    def _open_till(self, store):
        till = Till(store=store, station=api.get_current_station(store))
        till.open_till()

        TillOpenEvent.emit(till=till)
        self.assertEqual(till, Till.get_current(store))
        return till
Пример #19
0
 def create_model(self, store):
     till = Till.get_current(self.store)
     return Settable(employee=None,
                     payment=None,
                     # FIXME: should send in consts.now()
                     open_date=None,
                     till=till,
                     balance=till.get_balance(),
                     value=currency(0))
Пример #20
0
 def create_model(self, store):
     till = Till.get_current(self.store)
     return Settable(employee=None,
                     payment=None,
                     # FIXME: should send in consts.now()
                     open_date=None,
                     till=till,
                     balance=till.get_balance(),
                     value=currency(0))
Пример #21
0
    def test_get_current_till_open(self):
        self.assertEqual(Till.get_current(self.store, self.current_station),
                         None)

        till = Till(store=self.store,
                    branch=self.current_branch,
                    station=self.current_station)

        self.assertEqual(Till.get_current(self.store, self.current_station),
                         None)
        till.open_till(self.current_user)
        self.assertEqual(Till.get_current(self.store, self.current_station),
                         till)
        self.assertEqual(till.opening_date.date(), localtoday().date())
        self.assertEqual(till.status, Till.STATUS_OPEN)

        with self.assertRaises(TillError):
            till.open_till(self.current_user)
Пример #22
0
    def testCreateInPayment(self):
        payment = self.createInPayment()
        self.failUnless(isinstance(payment, Payment))
        self.assertEqual(payment.value, Decimal(100))
        self.assertEqual(payment.till, Till.get_current(self.store))

        payment_without_till = self.createInPayment(till=None)
        self.failUnless(isinstance(payment, Payment))
        self.assertEqual(payment_without_till.value, Decimal(100))
        self.assertEqual(payment_without_till.till, None)
Пример #23
0
    def testCreateInPayment(self):
        payment = self.createInPayment()
        self.failUnless(isinstance(payment, Payment))
        self.assertEqual(payment.value, Decimal(100))
        self.assertEqual(payment.till, Till.get_current(self.store))

        payment_without_till = self.createInPayment(till=None)
        self.failUnless(isinstance(payment, Payment))
        self.assertEqual(payment_without_till.value, Decimal(100))
        self.assertEqual(payment_without_till.till, None)
Пример #24
0
 def when_done(self, store):
     # This is sort of hack, set the opening/closing dates to the date before
     # it's run, so we can open/close the till in the tests, which uses
     # the examples.
     till = Till.get_current(store)
     # Do not leave anything in the till.
     till.add_debit_entry(till.get_balance(), _(u"Amount removed from Till"))
     till.close_till()
     yesterday = localtoday() - datetime.timedelta(1)
     till.opening_date = yesterday
     till.closing_date = yesterday
Пример #25
0
    def test_till_open_yesterday(self):
        yesterday = localnow() - datetime.timedelta(1)

        # Open a till, set the opening_date to yesterday
        till = Till(branch=self.current_branch,
                    station=self.current_station,
                    store=self.store)
        till.open_till(self.current_user)
        till.opening_date = yesterday

        with self.assertRaises(TillError):
            Till.get_current(self.store, self.current_station)
        # This is used to close a till
        self.assertEqual(
            Till.get_last_opened(self.store, self.current_station), till)

        till.close_till(self.current_user)

        self.assertEqual(Till.get_current(self.store, self.current_station),
                         None)
Пример #26
0
    def _get_till_balance(self):
        """Returns the balance of till operations"""
        try:
            till = Till.get_current(self.store)
        except TillError:
            till = None

        if till is None:
            return currency(0)

        return till.get_balance()
Пример #27
0
    def on_Renegotiate__activate(self, action):
        try:
            Till.get_current(self.store)
        except TillError as e:
            warning(str(e))
            return
        receivable_views = self.results.get_selected_rows()
        if not self._can_renegotiate(receivable_views):
            warning(_('Cannot renegotiate selected payments'))
            return
        store = api.new_store()

        groups = list(set([store.fetch(v.group) for v in receivable_views]))
        retval = run_dialog(PaymentRenegotiationWizard, self, store, groups)

        if store.confirm(retval):
            # FIXME: Storm is not expiring the groups correctly.
            # Figure out why. See bug 5087
            self.refresh()
            self._update_widgets()
        store.close()
Пример #28
0
 def when_done(self, store):
     # This is sort of hack, set the opening/closing dates to the date before
     # it's run, so we can open/close the till in the tests, which uses
     # the examples.
     till = Till.get_current(store)
     # Do not leave anything in the till.
     till.add_debit_entry(till.get_balance(),
                          _(u'Amount removed from Till'))
     till.close_till()
     yesterday = localtoday() - datetime.timedelta(1)
     till.opening_date = yesterday
     till.closing_date = yesterday
Пример #29
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)
     value = sale.total_amount
     reason = _(u"Cancelling last document on ECF")
     sale.cancel(reason, force=True)
     till = Till.get_current(store)
     # TRANSLATORS: cash out = sangria
     till.add_debit_entry(value, _(u"Cash out: last sale cancelled"))
     last_doc.last_sale = None
     info(_("Document was cancelled"))
Пример #30
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)
     value = sale.total_amount
     reason = _(u"Cancelling last document on ECF")
     sale.cancel(reason, force=True)
     till = Till.get_current(store)
     # TRANSLATORS: cash out = sangria
     till.add_debit_entry(value, _(u"Cash out: last sale cancelled"))
     last_doc.last_sale = None
     info(_("Document was cancelled"))
Пример #31
0
    def on_Renegotiate__activate(self, action):
        try:
            Till.get_current(self.store)
        except TillError as e:
            warning(str(e))
            return
        receivable_views = self.results.get_selected_rows()
        if not self._can_renegotiate(receivable_views):
            warning(_('Cannot renegotiate selected payments'))
            return
        store = api.new_store()

        groups = list(set([store.fetch(v.group) for v in receivable_views]))
        retval = run_dialog(PaymentRenegotiationWizard, self, store,
                            groups)

        if store.confirm(retval):
            # FIXME: Storm is not expiring the groups correctly.
            # Figure out why. See bug 5087
            self.refresh()
            self._update_widgets()
        store.close()
Пример #32
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>' % (
                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>' % (
                    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()
Пример #33
0
    def open_till(self):
        """Opens the till
        """
        if Till.get_current(self.store) is not None:
            warning("You already have a till operation opened. "
                    "Close the current Till and open another one.")
            return False

        store = api.new_store()
        try:
            model = run_dialog(TillOpeningEditor, self._parent, store)
        except TillError, e:
            warning(str(e))
            model = None
Пример #34
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)
     value = sale.total_amount
     sale.cancel()
     comment = _(u"Cancelling last document on ECF")
     SaleComment(store=store, sale=sale, comment=comment,
                 author=api.get_current_user(store))
     till = Till.get_current(store)
     # TRANSLATORS: cash out = sangria
     till.add_debit_entry(value, _(u"Cash out: last sale cancelled"))
     last_doc.last_sale = None
     info(_("Document was cancelled"))
Пример #35
0
    def test_till_open_yesterday(self):
        yesterday = localnow() - datetime.timedelta(1)

        # Open a till, set the opening_date to yesterday
        till = Till(station=get_current_station(self.store), store=self.store)
        till.open_till()
        till.opening_date = yesterday

        self.assertRaises(TillError, Till.get_current, self.store)
        # This is used to close a till
        self.assertEqual(Till.get_last_opened(self.store), till)

        till.close_till()

        self.assertEqual(Till.get_current(self.store), None)
Пример #36
0
    def test_till_open_yesterday(self):
        yesterday = localnow() - datetime.timedelta(1)

        # Open a till, set the opening_date to yesterday
        till = Till(station=get_current_station(self.store), store=self.store)
        till.open_till()
        till.opening_date = yesterday

        self.assertRaises(TillError, Till.get_current, self.store)
        # This is used to close a till
        self.assertEqual(Till.get_last_opened(self.store), till)

        till.close_till()

        self.assertEqual(Till.get_current(self.store), None)
Пример #37
0
    def next_step(self):
        self.wizard.create_payments = self.create_payments.read()

        if self.wizard.create_payments:
            try:
                till = Till.get_current(self.store)
            except TillError as e:
                warning(str(e))
                return self

            if not till:
                warning(_("You need to open the till before doing this operation."))
                return self

        return DecreaseItemStep(self.wizard, self, self.store, self.model)
Пример #38
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>' % (
                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>' % (
                    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)
            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()
Пример #39
0
    def _update_widgets(self, sale_view):
        sale = sale_view and sale_view.sale
        try:
            till = Till.get_current(self.store)
        except TillError:
            till = None

        can_edit = bool(sale and sale.can_edit())
        # We need an open till to return sales
        if sale and till:
            can_return = sale.can_return() or sale.can_cancel()
        else:
            can_return = False

        self._sale_toolbar.return_sale_button.set_sensitive(can_return)
        self._sale_toolbar.edit_button.set_sensitive(can_edit)
Пример #40
0
    def _update_widgets(self, sale_view):
        sale = sale_view and sale_view.sale
        try:
            till = Till.get_current(self.store)
        except TillError:
            till = None

        can_edit = bool(sale and sale.can_edit())
        # We need an open till to return sales
        if sale and till:
            can_return = sale.can_return() or sale.can_cancel()
        else:
            can_return = False

        self._sale_toolbar.return_sale_button.set_sensitive(can_return)
        self._sale_toolbar.edit_button.set_sensitive(can_edit)
Пример #41
0
    def next_step(self):
        self.wizard.create_payments = self.create_payments.read()

        if self.wizard.create_payments:
            try:
                till = Till.get_current(self.store)
            except TillError as e:
                warning(str(e))
                return self

            if not till:
                warning(
                    _("You need to open the till before doing this operation.")
                )
                return self

        return DecreaseItemStep(self.wizard, self, self.store, self.model)
Пример #42
0
 def _cancel_last_till_entry(self, last_doc, store):
     last_till_entry = store.fetch(last_doc.last_till_entry)
     value = last_till_entry.value
     till = Till.get_current(store)
     try:
         self._printer.cancel_last_coupon()
         if last_till_entry.value > 0:
             till_entry = till.add_debit_entry(
                 # TRANSLATORS: cash out = sangria, cash in = suprimento
                 value, _(u"Cash out: last cash in cancelled"))
             self._set_last_till_entry(till_entry, store)
         else:
             till_entry = till.add_credit_entry(
                 # TRANSLATORS: cash out = sangria, cash in = suprimento
                 -value, _(u"Cash in: last cash out cancelled"))
             self._set_last_till_entry(till_entry, store)
         info(_("Document was cancelled"))
     except Exception:
         info(_("Cancelling failed, nothing to cancel"))
         return
Пример #43
0
 def _cancel_last_till_entry(self, last_doc, store):
     last_till_entry = store.fetch(last_doc.last_till_entry)
     value = last_till_entry.value
     till = Till.get_current(store)
     try:
         self._printer.cancel_last_coupon()
         if last_till_entry.value > 0:
             till_entry = till.add_debit_entry(
                 # TRANSLATORS: cash out = sangria, cash in = suprimento
                 value, _(u"Cash out: last cash in cancelled"))
             self._set_last_till_entry(till_entry, store)
         else:
             till_entry = till.add_credit_entry(
                 # TRANSLATORS: cash out = sangria, cash in = suprimento
                 -value, _(u"Cash in: last cash out cancelled"))
             self._set_last_till_entry(till_entry, store)
         info(_("Document was cancelled"))
     except Exception:
         info(_("Cancelling failed, nothing to cancel"))
         return
Пример #44
0
    def _check_needs_closing(self):
        needs_closing = self.needs_closing()

        # DB and ECF are ok
        if needs_closing is CLOSE_TILL_NONE:
            self._previous_day = False
            # We still need to check if the till is open or closed.
            till = Till.get_current(self.store,
                                    api.get_current_station(self.store))
            self._till_status_changed(closed=not till, blocked=False)
            return True

        close_db = needs_closing in (CLOSE_TILL_DB, CLOSE_TILL_BOTH)
        close_ecf = needs_closing in (CLOSE_TILL_ECF, CLOSE_TILL_BOTH)

        # DB or ECF is open from a previous day
        self._till_status_changed(closed=False, blocked=True)
        self._previous_day = True

        # Save this statuses in case the user chooses not to close now.
        self._close_db = close_db
        self._close_ecf = close_ecf

        manager = get_plugin_manager()
        if close_db and (close_ecf or not manager.is_active('ecf')):
            msg = _("You need to close the till from the previous day before "
                    "creating a new order.\n\nClose the Till?")
        elif close_db and not close_ecf:
            msg = _("The till in Stoq is opened, but in ECF "
                    "is closed.\n\nClose the till in Stoq?")
        elif close_ecf and not close_db:
            msg = _("The till in stoq is closed, but in ECF "
                    "is opened.\n\nClose the till in ECF?")

        if yesno(msg, Gtk.ResponseType.NO, _("Close Till"), _("Not now")):
            return self.close_till(close_db, close_ecf)

        return False
Пример #45
0
    def _check_needs_closing(self):
        needs_closing = self.needs_closing()

        # DB and ECF are ok
        if needs_closing is CLOSE_TILL_NONE:
            self._previous_day = False
            # We still need to check if the till is open or closed.
            till = Till.get_current(self.store)
            self._till_status_changed(closed=not till, blocked=False)
            return True

        close_db = needs_closing in (CLOSE_TILL_DB, CLOSE_TILL_BOTH)
        close_ecf = needs_closing in (CLOSE_TILL_ECF, CLOSE_TILL_BOTH)

        # DB or ECF is open from a previous day
        self._till_status_changed(closed=False, blocked=True)
        self._previous_day = True

        # Save this statuses in case the user chooses not to close now.
        self._close_db = close_db
        self._close_ecf = close_ecf

        manager = get_plugin_manager()
        if close_db and (close_ecf or not manager.is_active('ecf')):
            msg = _("You need to close the till from the previous day before "
                    "creating a new order.\n\nClose the Till?")
        elif close_db and not close_ecf:
            msg = _("The till in Stoq is opened, but in ECF "
                    "is closed.\n\nClose the till in Stoq?")
        elif close_ecf and not close_db:
            msg = _("The till in stoq is closed, but in ECF "
                    "is opened.\n\nClose the till in ECF?")

        if yesno(msg, gtk.RESPONSE_NO, _("Close Till"), _("Not now")):
            return self.close_till(close_db, close_ecf)

        return False
Пример #46
0
    def create_sale(self, id_=None, branch=None, client=None):
        from stoqlib.domain.sale import Sale
        from stoqlib.domain.till import Till
        till = Till.get_current(self.store)
        if till is None:
            till = self.create_till()
            till.open_till()
        salesperson = self.create_sales_person()
        group = self.create_payment_group()
        if client:
            group.payer = client.person

        sale = Sale(coupon_id=0,
                    open_date=TransactionTimestamp(),
                    salesperson=salesperson,
                    branch=branch or get_current_branch(self.store),
                    cfop=sysparam(self.store).DEFAULT_SALES_CFOP,
                    group=group,
                    client=client,
                    store=self.store)
        if id_:
            sale.id = id_
            sale.identifier = id_
        return sale
Пример #47
0
 def create_model(self, store):
     till = Till.get_current(store)
     return Settable(value=currency(0),
                     reason=u'',
                     till=till,
                     balance=till.get_balance())
Пример #48
0
    def confirm(self, sale, store, savepoint=None, subtotal=None):
        """Confirms a |sale| on fiscalprinter and database

        If the sale is confirmed, the store will be committed for you.
        There's no need for the callsite to call store.confirm().
        If the sale is not confirmed, for instance the user cancelled the
        sale or there was a problem with the fiscal printer, then the
        store will be rolled back.

        :param sale: the |sale| to be confirmed
        :param trans: a store
        :param savepoint: if specified, a database savepoint name that
            will be used to rollback to if the sale was not confirmed.
        :param subtotal: the total value of all the items in the sale
        """
        # Actually, we are confirming the sale here, so the sale
        # confirmation process will be available to others applications
        # like Till and not only to the POS.
        payments_total = sale.group.get_total_confirmed_value()
        sale_total = sale.get_total_sale_amount()

        payment = get_formatted_price(payments_total)
        amount = get_formatted_price(sale_total)
        msg = _(u"Payment value (%s) is greater than sale's total (%s). "
                "Do you want to confirm it anyway?") % (payment, amount)
        if (sale_total < payments_total and not
            yesno(msg, gtk.RESPONSE_NO, _(u"Confirm Sale"), _(u"Don't Confirm"))):
            return False

        model = run_dialog(ConfirmSaleWizard, self._parent, store, sale,
                           subtotal=subtotal, total_paid=payments_total,
                           current_document=self._current_document)

        if not model:
            CancelPendingPaymentsEvent.emit()
            store.rollback(name=savepoint, close=False)
            return False

        if sale.client and not self.is_customer_identified():
            self.identify_customer(sale.client.person)

        try:
            if not self.totalize(sale):
                store.rollback(name=savepoint, close=False)
                return False

            if not self.setup_payments(sale):
                store.rollback(name=savepoint, close=False)
                return False

            if not self.close(sale, store):
                store.rollback(name=savepoint, close=False)
                return False

            if not self.print_receipts(sale):
                store.rollback(name=savepoint, close=False)
                return False

            # FIXME: This used to be done inside sale.confirm. Maybe it would
            # be better to do a proper error handling
            till = Till.get_current(store)
            assert till
            sale.confirm(till=till)

            # Only finish the transaction after everything passed above.
            store.confirm(model)
        except Exception as e:
            warning(_("An error happened while trying to confirm the sale. "
                      "Cancelling the coupon now..."), str(e))
            self.cancel()
            store.rollback(name=savepoint, close=False)
            return False

        print_cheques_for_payment_group(store, sale.group)

        # Try to print only after the transaction is commited, to prevent
        # losing data if something fails while printing
        group = sale.group
        booklets = list(group.get_payments_by_method_name(u'store_credit'))
        bills = list(group.get_payments_by_method_name(u'bill'))

        if (booklets and
            yesno(_("Do you want to print the booklets for this sale?"),
                  gtk.RESPONSE_YES, _("Print booklets"), _("Don't print"))):
            try:
                print_report(BookletReport, booklets)
            except ReportError:
                warning(_("Could not print booklets"))

        if (bills and BillReport.check_printable(bills) and
            yesno(_("Do you want to print the bills for this sale?"),
                  gtk.RESPONSE_YES, _("Print bills"), _("Don't print"))):
            try:
                print_report(BillReport, bills)
            except ReportError:
                # TRANSLATORS: bills here refers to "boletos" in pt_BR
                warning(_("Could not print bills"))

        return True
Пример #49
0
 def on_Edit__activate(self, action):
     try:
         Till.get_current(self.store)
     except TillError, e:
         warning(str(e))
         return
Пример #50
0
def current_till(store, example_creator, current_station):
    return Till.get_current(store, current_station) or example_creator.create_till()
Пример #51
0
    def create_payment(self,
                       payment_type,
                       payment_group,
                       branch,
                       value,
                       due_date=None,
                       description=None,
                       base_value=None,
                       till=ValueUnset,
                       payment_number=None):
        """Creates a new payment according to a payment method interface

        :param payment_type: the kind of payment, in or out
        :param payment_group: a :class:`PaymentGroup` subclass
        :param branch: the :class:`branch <stoqlib.domain.person.Branch>`
          associated with the payment, for incoming payments this is the
          branch receiving the payment and for outgoing payments this is the
          branch sending the payment.
        :param value: value of payment
        :param due_date: optional, due date of payment
        :param details: optional
        :param description: optional, description of the payment
        :param base_value: optional
        :param till: optional
        :param payment_number: optional
        :returns: a :class:`payment <stoqlib.domain.payment.Payment>`
        """
        store = self.store

        if due_date is None:
            due_date = TransactionTimestamp()

        if payment_type == Payment.TYPE_IN:
            query = And(Payment.group_id == payment_group.id,
                        Payment.method_id == self.id,
                        Payment.payment_type == Payment.TYPE_IN,
                        Payment.status != Payment.STATUS_CANCELLED)
            payment_count = store.find(Payment, query).count()
            if payment_count == self.max_installments:
                raise PaymentMethodError(
                    _('You can not create more inpayments for this payment '
                      'group since the maximum allowed for this payment '
                      'method is %d') % self.max_installments)
            elif payment_count > self.max_installments:
                raise DatabaseInconsistency(
                    _('You have more inpayments in database than the maximum '
                      'allowed for this payment method'))

        if not description:
            description = self.describe_payment(payment_group)

        # If till is unset, do some clever guessing
        if till is ValueUnset:
            # We only need a till for inpayments
            if payment_type == Payment.TYPE_IN:
                till = Till.get_current(store)
            elif payment_type == Payment.TYPE_OUT:
                till = None
            else:
                raise AssertionError(payment_type)

        payment = Payment(store=store,
                          branch=branch,
                          payment_type=payment_type,
                          due_date=due_date,
                          value=value,
                          base_value=base_value,
                          group=payment_group,
                          method=self,
                          category=None,
                          till=till,
                          description=description,
                          payment_number=payment_number)
        self.operation.payment_create(payment)
        return payment
Пример #52
0
    def confirm(self, sale, store, savepoint=None, subtotal=None):
        """Confirms a |sale| on fiscalprinter and database

        If the sale is confirmed, the store will be committed for you.
        There's no need for the callsite to call store.confirm().
        If the sale is not confirmed, for instance the user cancelled the
        sale or there was a problem with the fiscal printer, then the
        store will be rolled back.

        :param sale: the |sale| to be confirmed
        :param trans: a store
        :param savepoint: if specified, a database savepoint name that
            will be used to rollback to if the sale was not confirmed.
        :param subtotal: the total value of all the items in the sale
        """
        # Actually, we are confirming the sale here, so the sale
        # confirmation process will be available to others applications
        # like Till and not only to the POS.
        payments_total = sale.group.get_total_confirmed_value()
        sale_total = sale.get_total_sale_amount()

        payment = get_formatted_price(payments_total)
        amount = get_formatted_price(sale_total)
        msg = _(u"Payment value (%s) is greater than sale's total (%s). "
                "Do you want to confirm it anyway?") % (payment, amount)
        if (sale_total < payments_total
                and not yesno(msg, gtk.RESPONSE_NO, _(u"Confirm Sale"),
                              _(u"Don't Confirm"))):
            return False

        model = run_dialog(ConfirmSaleWizard,
                           self._parent,
                           store,
                           sale,
                           subtotal=subtotal,
                           total_paid=payments_total)

        if not model:
            CancelPendingPaymentsEvent.emit()
            store.rollback(name=savepoint, close=False)
            return False

        if sale.client and not self.is_customer_identified():
            self.identify_customer(sale.client.person)

        if not self.totalize(sale):
            store.rollback(name=savepoint, close=False)
            return False

        if not self.setup_payments(sale):
            store.rollback(name=savepoint, close=False)
            return False

        if not self.close(sale, store):
            store.rollback(name=savepoint, close=False)
            return False

        # FIXME: This used to be done inside sale.confirm. Maybe it would be
        # better to do a proper error handling
        till = Till.get_current(store)
        assert till

        try:
            sale.confirm(till=till)
        except SellError as err:
            warning(str(err))
            store.rollback(name=savepoint, close=False)
            return False

        if not self.print_receipts(sale):
            warning(_("The sale was cancelled"))
            sale.cancel(force=True)

        print_cheques_for_payment_group(store, sale.group)

        # Only finish the transaction after everything passed above.
        store.confirm(model)

        # Try to print only after the transaction is commited, to prevent
        # losing data if something fails while printing
        group = sale.group
        booklets = list(group.get_payments_by_method_name(u'store_credit'))
        bills = list(group.get_payments_by_method_name(u'bill'))

        if (booklets and yesno(
                _("Do you want to print the booklets for this sale?"),
                gtk.RESPONSE_YES, _("Print booklets"), _("Don't print"))):
            try:
                print_report(BookletReport, booklets)
            except ReportError:
                warning(_("Could not print booklets"))

        if (bills and BillReport.check_printable(bills) and yesno(
                _("Do you want to print the bills for this sale?"),
                gtk.RESPONSE_YES, _("Print bills"), _("Don't print"))):
            try:
                print_report(BillReport, bills)
            except ReportError:
                # TRANSLATORS: bills here refers to "boletos" in pt_BR
                warning(_("Could not print bills"))

        return True
Пример #53
0
            self._validate_printer()
        except DeviceError, 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()

    def _till_summarize(self):
        try:
Пример #54
0
 def create_model(self, store):
     till = Till.get_current(store, api.get_current_station(store))
     return Settable(value=currency(0),
                     reason=u'',
                     till=till,
                     balance=till.get_balance())
Пример #55
0
    def create_payment(self, payment_type, payment_group, branch, value,
                       due_date=None, description=None, base_value=None,
                       till=ValueUnset, payment_number=None):
        """Creates a new payment according to a payment method interface

        :param payment_type: the kind of payment, in or out
        :param payment_group: a :class:`PaymentGroup` subclass
        :param branch: the :class:`branch <stoqlib.domain.person.Branch>`
          associated with the payment, for incoming payments this is the
          branch receiving the payment and for outgoing payments this is the
          branch sending the payment.
        :param value: value of payment
        :param due_date: optional, due date of payment
        :param details: optional
        :param description: optional, description of the payment
        :param base_value: optional
        :param till: optional
        :param payment_number: optional
        :returns: a :class:`payment <stoqlib.domain.payment.Payment>`
        """
        store = self.store

        if due_date is None:
            due_date = TransactionTimestamp()

        if payment_type == Payment.TYPE_IN:
            query = And(Payment.group_id == payment_group.id,
                        Payment.method_id == self.id,
                        Payment.payment_type == Payment.TYPE_IN,
                        Payment.status != Payment.STATUS_CANCELLED)
            payment_count = store.find(Payment, query).count()
            if payment_count == self.max_installments:
                raise PaymentMethodError(
                    _('You can not create more inpayments for this payment '
                      'group since the maximum allowed for this payment '
                      'method is %d') % self.max_installments)
            elif payment_count > self.max_installments:
                raise DatabaseInconsistency(
                    _('You have more inpayments in database than the maximum '
                      'allowed for this payment method'))

        if not description:
            description = self.describe_payment(payment_group)

        # If till is unset, do some clever guessing
        if till is ValueUnset:
            # We only need a till for inpayments
            if payment_type == Payment.TYPE_IN:
                till = Till.get_current(store)
            elif payment_type == Payment.TYPE_OUT:
                till = None
            else:
                raise AssertionError(payment_type)

        payment = Payment(store=store,
                          branch=branch,
                          payment_type=payment_type,
                          due_date=due_date,
                          value=value,
                          base_value=base_value,
                          group=payment_group,
                          method=self,
                          category=None,
                          till=till,
                          description=description,
                          payment_number=payment_number)
        self.operation.payment_create(payment)
        return payment
Пример #56
0
 def before_start(self, store):
     till = Till.get_current(store)
     if till is None:
         till = Till(store=store, station=get_current_station(store))
         till.open_till()
         assert till == Till.get_current(store)