Esempio n. 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)
Esempio n. 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)
Esempio n. 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)
Esempio n. 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)
Esempio n. 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)
Esempio n. 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)
Esempio n. 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()
Esempio n. 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()
Esempio n. 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
Esempio n. 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
Esempio n. 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
Esempio n. 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()
Esempio n. 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()
Esempio n. 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()
Esempio n. 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()
Esempio n. 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()
Esempio n. 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
Esempio n. 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
Esempio n. 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))
Esempio n. 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))
Esempio n. 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)
Esempio n. 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)
Esempio n. 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)
Esempio n. 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
Esempio n. 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)
Esempio n. 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()
Esempio n. 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()
Esempio n. 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
Esempio n. 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"))
Esempio n. 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"))
Esempio n. 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()
Esempio n. 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()
Esempio n. 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
Esempio n. 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"))
Esempio n. 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)
Esempio n. 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)
Esempio n. 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)
Esempio n. 38
0
File: till.py Progetto: esosaja/stoq
    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()
Esempio n. 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)
Esempio n. 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)
Esempio n. 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)
Esempio n. 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
Esempio n. 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
Esempio n. 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
Esempio n. 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
Esempio n. 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
Esempio n. 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())
Esempio n. 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
Esempio n. 49
0
 def on_Edit__activate(self, action):
     try:
         Till.get_current(self.store)
     except TillError, e:
         warning(str(e))
         return
Esempio n. 50
0
def current_till(store, example_creator, current_station):
    return Till.get_current(store, current_station) or example_creator.create_till()
Esempio n. 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
Esempio n. 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
Esempio n. 53
0
File: ecfui.py Progetto: romaia/stoq
            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:
Esempio n. 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())
Esempio n. 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
Esempio n. 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)