Exemple #1
0
    def test_run_dialog(self):
        observations = (
            u"Mussum ipsum cacilds, vidis litro abertis. "
            "Consetis adipiscings elitis. Pra la , depois "
            "divoltis porris, paradis. Paisis, filhis, "
            "espiritis santis. Me faiz elementum girarzis, "
            "nisi eros vermeio, in elementis me pra quem e "
            "amistosis quis leo. Manduma pindureta quium dia "
            "nois paga. Sapien in monti palavris qui num "
            "significa nadis i pareci latim. Interessantiss "
            "quisso pudia ce receita de bolis, mais bolis eu num gostis.")
        till = self.create_till()
        till.open_till()
        till.close_till(observations)

        model = self.store.find(TillClosedView, id=till.id).one()
        self.assertEquals(observations, model.observations)
        self.assertEquals(get_current_user(self.store).get_description(),
                          model.responsible_open_name)
        self.assertEquals(get_current_user(self.store).get_description(),
                          model.responsible_close_name)
        self.assertEquals(observations, model.observations)

        dialog = TillClosedSearch(self.store)
        dialog.search.refresh()
        self.assertNotSensitive(dialog._details_slave, ['details_button'])
        with mock.patch("stoqlib.gui.search.tillsearch.run_dialog") as r_dialog:
            dialog.results.select(model)
            self.assertSensitive(dialog._details_slave, ['details_button'])
            self.click(dialog._details_slave.details_button)
            r_dialog.assert_called_once_with(TillDetailsDialog, dialog,
                                             dialog.store, model)
Exemple #2
0
    def test_run_dialog(self):
        observations = (
            u"Mussum ipsum cacilds, vidis litro abertis. "
            "Consetis adipiscings elitis. Pra la , depois "
            "divoltis porris, paradis. Paisis, filhis, "
            "espiritis santis. Me faiz elementum girarzis, "
            "nisi eros vermeio, in elementis me pra quem e "
            "amistosis quis leo. Manduma pindureta quium dia "
            "nois paga. Sapien in monti palavris qui num "
            "significa nadis i pareci latim. Interessantiss "
            "quisso pudia ce receita de bolis, mais bolis eu num gostis.")
        till = self.create_till()
        till.open_till()
        till.close_till(observations)

        model = self.store.find(TillClosedView, id=till.id).one()
        self.assertEquals(observations, model.observations)
        self.assertEquals(
            get_current_user(self.store).get_description(),
            model.responsible_open_name)
        self.assertEquals(
            get_current_user(self.store).get_description(),
            model.responsible_close_name)
        self.assertEquals(observations, model.observations)

        dialog = TillClosedSearch(self.store)
        dialog.search.refresh()
        self.assertNotSensitive(dialog._details_slave, ['details_button'])
        with mock.patch(
                "stoqlib.gui.search.tillsearch.run_dialog") as r_dialog:
            dialog.results.select(model)
            self.assertSensitive(dialog._details_slave, ['details_button'])
            self.click(dialog._details_slave.details_button)
            r_dialog.assert_called_once_with(TillDetailsDialog, dialog,
                                             dialog.store, model)
Exemple #3
0
    def test_trade_without_sale(self):
        # With discount
        branch = get_current_branch(self.store)
        returned_sale = ReturnedSale(store=self.store,
                                     responsible=get_current_user(self.store),
                                     branch=branch)
        storable = self.create_storable(branch=branch,
                                        stock=10)
        ReturnedSaleItem(store=self.store,
                         quantity=1,
                         price=10,
                         sellable=storable.product.sellable,
                         returned_sale=returned_sale)
        new_sale = self.create_sale()
        returned_sale.new_sale = new_sale
        balance_before_trade = storable.get_balance_for_branch(branch)

        with self.sysparam(USE_TRADE_AS_DISCOUNT=True):
            returned_sale.trade()
            self.assertEqual(new_sale.discount_value, currency(10))

        self.assertEqual(returned_sale.status, ReturnedSale.STATUS_CONFIRMED)
        self.assertEqual(storable.get_balance_for_branch(branch),
                         balance_before_trade + 1)

        # Without discount
        returned_sale2 = ReturnedSale(store=self.store,
                                      responsible=get_current_user(self.store),
                                      branch=branch)
        storable = self.create_storable(branch=branch,
                                        stock=10)
        ReturnedSaleItem(store=self.store,
                         quantity=1,
                         price=10,
                         sellable=storable.product.sellable,
                         returned_sale=returned_sale2)
        new_sale = self.create_sale()
        returned_sale2.new_sale = new_sale
        balance_before_trade = storable.get_balance_for_branch(branch)

        returned_sale2.trade()
        self.assertEqual(returned_sale.status, ReturnedSale.STATUS_CONFIRMED)
        self.assertEqual(new_sale.discount_value, currency(0))

        group = new_sale.group
        payment = group.payments[0]
        self.assertEqual(group.payments.count(), 1)
        self.assertEqual(payment.value, returned_sale2.returned_total)
        self.assertEqual(storable.get_balance_for_branch(branch),
                         balance_before_trade + 1)
Exemple #4
0
    def test_trade_without_sale(self):
        # With discount
        branch = get_current_branch(self.store)
        returned_sale = ReturnedSale(store=self.store,
                                     responsible=get_current_user(self.store),
                                     branch=branch)
        storable = self.create_storable(branch=branch,
                                        stock=10)
        ReturnedSaleItem(store=self.store,
                         quantity=1,
                         price=10,
                         sellable=storable.product.sellable,
                         returned_sale=returned_sale)
        new_sale = self.create_sale()
        returned_sale.new_sale = new_sale
        balance_before_trade = storable.get_balance_for_branch(branch)

        with self.sysparam(USE_TRADE_AS_DISCOUNT=True):
            returned_sale.trade()
            self.assertEqual(new_sale.discount_value, currency(10))

        self.assertEqual(returned_sale.status, ReturnedSale.STATUS_CONFIRMED)
        self.assertEqual(storable.get_balance_for_branch(branch),
                         balance_before_trade + 1)

        # Without discount
        returned_sale2 = ReturnedSale(store=self.store,
                                      responsible=get_current_user(self.store),
                                      branch=branch)
        storable = self.create_storable(branch=branch,
                                        stock=10)
        ReturnedSaleItem(store=self.store,
                         quantity=1,
                         price=10,
                         sellable=storable.product.sellable,
                         returned_sale=returned_sale2)
        new_sale = self.create_sale()
        returned_sale2.new_sale = new_sale
        balance_before_trade = storable.get_balance_for_branch(branch)

        returned_sale2.trade()
        self.assertEqual(returned_sale.status, ReturnedSale.STATUS_CONFIRMED)
        self.assertEqual(new_sale.discount_value, currency(0))

        group = new_sale.group
        payment = group.payments[0]
        self.assertEqual(group.payments.count(), 1)
        self.assertEqual(payment.value, returned_sale2.returned_total)
        self.assertEqual(storable.get_balance_for_branch(branch),
                         balance_before_trade + 1)
Exemple #5
0
    def confirm(self, confirm_date=None):
        """Confirms the purchase order

        :param confirm_data: optional, datetime
        """
        if confirm_date is None:
            confirm_date = TransactionTimestamp()

        if self.status not in [PurchaseOrder.ORDER_PENDING,
                               PurchaseOrder.ORDER_CONSIGNED]:
            raise ValueError(
                _(u'Invalid order status, it should be '
                  u'ORDER_PENDING or ORDER_CONSIGNED, got %s') % (
                      self.get_status_str(), ))

        transaction = IPaymentTransaction(self)
        transaction.confirm()

        if self.supplier:
            self.group.recipient = self.supplier.person

        self.responsible = get_current_user(self.store)
        self.status = PurchaseOrder.ORDER_CONFIRMED
        self.confirm_date = confirm_date

        Event.log(Event.TYPE_ORDER,
                  _(u"Order %s, total value %2.2f, supplier '%s' "
                    u"is now confirmed") % (self.identifier,
                                            self.get_purchase_total(),
                                            self.supplier.person.name))
Exemple #6
0
    def create_for_receiving_order(cls, receiving_order):
        store = receiving_order.store
        current_user = get_current_user(store)
        employee = current_user.person.employee
        cfop_id = sysparam.get_object_id('DEFAULT_STOCK_DECREASE_CFOP')
        return_stock_decrease = cls(
            store=store,
            receiving_order=receiving_order,
            branch=get_current_branch(store),
            responsible=current_user,
            removed_by=employee,
            cfop_id=cfop_id)

        for receiving_item in receiving_order.get_items(with_children=False):
            if receiving_item.is_totally_returned():
                # Exclude items already totally returned
                continue

            if receiving_item.children_items.count():
                for child in receiving_item.children_items:
                    StockDecreaseItem.create_for_receiving_item(
                        return_stock_decrease, child)
            else:
                StockDecreaseItem.create_for_receiving_item(return_stock_decrease,
                                                            receiving_item)
        return return_stock_decrease
Exemple #7
0
    def _update_te(self):
        user = get_current_user(self.store)
        station = get_current_station(self.store)

        self.te_modified.te_time = TransactionTimestamp()
        self.te_modified.user_id = user and user.id
        self.te_modified.station_id = station and station.id
Exemple #8
0
    def open_till(self):
        """Open the till.

        It can only be done once per day.
        The final cash amount of the previous till will be used
        as the initial value in this one after opening it.
        """
        if self.status == Till.STATUS_OPEN:
            raise TillError(_('Till is already open'))

        # Make sure that the till has not been opened today
        today = localtoday().date()
        if not self.store.find(Till,
                               And(Date(Till.opening_date) >= today,
                                   Till.station_id == self.station.id)).is_empty():
            raise TillError(_("A till has already been opened today"))

        last_till = self._get_last_closed_till()
        if last_till:
            if not last_till.closing_date:
                raise TillError(_("Previous till was not closed"))

            initial_cash_amount = last_till.final_cash_amount
        else:
            initial_cash_amount = 0

        self.initial_cash_amount = initial_cash_amount

        self.opening_date = TransactionTimestamp()
        self.status = Till.STATUS_OPEN
        self.responsible_open = get_current_user(self.store)
Exemple #9
0
    def test_on_confirm_without_discount(self):
        events_before = self.store.find(Event).count()

        sale_item = self.create_sale_item()

        current_user = get_current_user(self.store)
        current_user.profile.max_discount = Decimal('5')

        # A manager to authorize the discount
        manager = self.create_user()
        manager.profile.max_discount = Decimal('10')

        editor = SaleQuoteItemEditor(self.store, sale_item)
        slave = editor.item_slave
        # Try applying 10% of discount
        slave.price.update(currency('9.00'))

        # The user is not allowed to give 10% discount
        self.assertNotSensitive(editor.main_dialog, ['ok_button'])

        # Lets call the manager and ask for permission
        with mock.patch('stoq.lib.gui.editors.saleeditor.run_dialog') as rd:
            rd.return_value = manager
            slave.price.emit('icon-press', Gtk.EntryIconPosition.PRIMARY, None)

        # Forget about the discount
        slave.price.update(currency('10'))

        # This will not trigger an event
        self.click(editor.main_dialog.ok_button)
        events_after = self.store.find(Event).count()
        # The number of events doesn't changed
        self.assertEqual(events_after, events_before)
Exemple #10
0
    def create_for_receiving_order(cls, receiving_order):
        store = receiving_order.store
        current_user = get_current_user(store)
        employee = current_user.person.employee
        cfop_id = sysparam.get_object_id('DEFAULT_STOCK_DECREASE_CFOP')
        return_stock_decrease = cls(store=store,
                                    receiving_order=receiving_order,
                                    branch=get_current_branch(store),
                                    responsible=current_user,
                                    removed_by=employee,
                                    cfop_id=cfop_id)

        for receiving_item in receiving_order.get_items(with_children=False):
            if receiving_item.is_totally_returned():
                # Exclude items already totally returned
                continue

            if receiving_item.children_items.count():
                for child in receiving_item.children_items:
                    StockDecreaseItem.create_for_receiving_item(
                        return_stock_decrease, child)
            else:
                StockDecreaseItem.create_for_receiving_item(
                    return_stock_decrease, receiving_item)
        return return_stock_decrease
Exemple #11
0
    def confirm(self, confirm_date=None):
        """Confirms the purchase order

        :param confirm_data: optional, datetime
        """
        if confirm_date is None:
            confirm_date = TransactionTimestamp()

        if self.status not in [PurchaseOrder.ORDER_PENDING,
                               PurchaseOrder.ORDER_CONSIGNED]:
            raise ValueError(
                _(u'Invalid order status, it should be '
                  u'ORDER_PENDING or ORDER_CONSIGNED, got %s') % (
                      self.get_status_str(), ))

        transaction = IPaymentTransaction(self)
        transaction.confirm()

        if self.supplier:
            self.group.recipient = self.supplier.person

        self.responsible = get_current_user(self.store)
        self.status = PurchaseOrder.ORDER_CONFIRMED
        self.confirm_date = confirm_date

        Event.log(self.store, Event.TYPE_ORDER,
                  _(u"Order %s, total value %2.2f, supplier '%s' "
                    u"is now confirmed") % (self.identifier,
                                            self.get_purchase_total(),
                                            self.supplier.person.name))
Exemple #12
0
 def create_loan(self, branch=None, client=None):
     from stoqlib.domain.loan import Loan
     user = get_current_user(self.store)
     return Loan(responsible=user,
                 client=client,
                 branch=branch or get_current_branch(self.store),
                 store=self.store)
Exemple #13
0
    def _update_wizard_model(self):
        wizard_model = self.wizard.model
        if wizard_model:
            # We are replacing the model. Remove old one
            for item in wizard_model.returned_items:
                item.delete(item.id, store=item.store)
            wizard_model.delete(wizard_model.id, store=wizard_model.store)

        sale_view = self.slave.results.get_selected()
        # FIXME: Selecting a sale and then clicking on unknown_sale_check
        # will not really deselect it, not until the results are sensitive
        # again. This should be as simple as 'if sale_view'.
        if sale_view and not self.unknown_sale_check.get_active():
            sale = self.store.fetch(sale_view.sale)
            model = sale.create_sale_return_adapter()
            for item in model.returned_items:
                _adjust_returned_sale_item(item)
        else:
            assert self._allow_unknown_sales()
            model = ReturnedSale(
                store=self.store,
                responsible=get_current_user(self.store),
                branch=get_current_branch(self.store),
            )

        self.wizard.model = model
Exemple #14
0
 def create_payment_renegotiation(self, group=None):
     from stoqlib.domain.payment.renegotiation import PaymentRenegotiation
     return PaymentRenegotiation(responsible=get_current_user(self.store),
                                 branch=get_current_branch(self.store),
                                 group=group or self.create_payment_group(),
                                 client=self.create_client(),
                                 store=self.store)
Exemple #15
0
    def confirm(self, confirm_date=None):
        """Confirms the purchase order

        :param confirm_data: optional, datetime
        """
        if confirm_date is None:
            confirm_date = TransactionTimestamp()

        if self.status not in [PurchaseOrder.ORDER_PENDING,
                               PurchaseOrder.ORDER_CONSIGNED]:
            fmt = _(u'Invalid order status, it should be '
                    u'ORDER_PENDING or ORDER_CONSIGNED, got %s')
            raise ValueError(fmt % (self.status_str, ))

        # In consigned purchases there is no payments at this point.
        if self.status != PurchaseOrder.ORDER_CONSIGNED and self.group:
            for payment in self.payments:
                payment.set_pending()

        if self.supplier and self.group:
            self.group.recipient = self.supplier.person

        self.responsible = get_current_user(self.store)
        self.status = PurchaseOrder.ORDER_CONFIRMED
        self.confirm_date = confirm_date

        Event.log(self.store, Event.TYPE_ORDER,
                  _(u"Order %s, total value %2.2f, supplier '%s' "
                    u"is now confirmed") % (self.identifier,
                                            self.purchase_total,
                                            self.supplier.person.name))
Exemple #16
0
    def _update_te(self):
        user = get_current_user(self.store)
        station = get_current_station(self.store)

        self.te_modified.te_time = TransactionTimestamp()
        self.te_modified.user_id = user and user.id
        self.te_modified.station_id = station and station.id
Exemple #17
0
    def _update_wizard_model(self):
        wizard_model = self.wizard.model
        if wizard_model:
            # We are replacing the model. Remove old one
            for item in wizard_model.returned_items:
                item.delete(item.id, store=item.store)
            wizard_model.delete(wizard_model.id,
                                store=wizard_model.store)

        sale_view = self.slave.results.get_selected()
        # FIXME: Selecting a sale and then clicking on unknown_sale_check
        # will not really deselect it, not until the results are sensitive
        # again. This should be as simple as 'if sale_view'.
        if sale_view and not self.unknown_sale_check.get_active():
            sale = self.store.fetch(sale_view.sale)
            model = sale.create_sale_return_adapter()
            for item in model.returned_items:
                _adjust_returned_sale_item(item)
        else:
            assert self._allow_unknown_sales()
            model = ReturnedSale(
                store=self.store,
                responsible=get_current_user(self.store),
                branch=get_current_branch(self.store),
            )

        self.wizard.model = model
    def test_on_confirm_with_discount(self):
        events_before = self.store.find(Event).count()

        sale_item = self.create_sale_item()
        sale_item.sale.identifier = 333123

        current_user = get_current_user(self.store)
        current_user.profile.max_discount = Decimal('5')

        # A manager to authorize the discount
        manager = self.create_user()
        manager.profile.max_discount = Decimal('10')

        editor = SaleQuoteItemEditor(self.store, sale_item)

        # Try applying 9% of discount
        editor.price.update(currency('9.10'))

        # The user is not allowed to give 10% discount
        self.assertNotSensitive(editor.main_dialog, ['ok_button'])

        # Lets call the manager and ask for permission
        with mock.patch('stoqlib.gui.editors.saleeditor.run_dialog') as rd:
            rd.return_value = manager
            editor.price.emit('icon-press', gtk.ENTRY_ICON_PRIMARY, None)

        # Now it should be possible to confirm
        self.click(editor.main_dialog.ok_button)
        events_after = self.store.find(Event).count()
        self.assertEquals(events_after, events_before + 1)

        last_event = self.store.find(Event).order_by(Event.id).last()
        expected = (u'Sale 333123: User username authorized 9.00 % '
                    u'of discount changing\n Description value from $10.00 to $9.10.')
        self.assertEquals(last_event.description, expected)
Exemple #19
0
 def create_loan(self, branch=None, client=None):
     from stoqlib.domain.loan import Loan
     user = get_current_user(self.store)
     return Loan(responsible=user,
                 client=client,
                 branch=branch or get_current_branch(self.store),
                 store=self.store)
    def test_on_confirm_without_discount(self):
        events_before = self.store.find(Event).count()

        sale_item = self.create_sale_item()

        current_user = get_current_user(self.store)
        current_user.profile.max_discount = Decimal('5')

        # A manager to authorize the discount
        manager = self.create_user()
        manager.profile.max_discount = Decimal('10')

        editor = SaleQuoteItemEditor(self.store, sale_item)
        # Try applying 10% of discount
        editor.price.update(currency('9.00'))

        # The user is not allowed to give 10% discount
        self.assertNotSensitive(editor.main_dialog, ['ok_button'])

        # Lets call the manager and ask for permission
        with mock.patch('stoqlib.gui.editors.saleeditor.run_dialog') as rd:
            rd.return_value = manager
            editor.price.emit('icon-press', gtk.ENTRY_ICON_PRIMARY, None)

        # Forget about the discount
        editor.price.update(currency('10'))

        # This will not trigger an event
        self.click(editor.main_dialog.ok_button)
        events_after = self.store.find(Event).count()
        # The number of events doesn't changed
        self.assertEquals(events_after, events_before)
Exemple #21
0
def orm_get_unittest_value(klass, test, tables_dict, name, column):
    value = None
    if isinstance(column, PropertyColumn):
        if column.variable_factory.keywords['value'] is not Undef:
            value = column.variable_factory.keywords['value']
        else:
            try:
                value = orm_get_random(column)
            except ValueError:
                raise ORMTestError(u"No default for %r" % (column, ))

    elif isinstance(column, Reference):
        if name == 'te':
            return None
        if isinstance(column._remote_key, basestring):
            cls = tables_dict[column._remote_key.split('.')[0]]
        else:
            cls = column._remote_key[0].cls
        if cls.__name__ == 'LoginUser':
            # Avoid unique problems on domains that defines 2 references
            # to LoginUser (e.g. WorkOrder)
            from stoqlib.database.runtime import get_current_user
            value = get_current_user(test.store)
        elif cls.__name__ == 'StorableBatch':
            # StorableBatch needs some very specific information, that is
            # related to other objects. Thus, it cannot be created with random
            # value.
            value = None
        else:
            value = test.create_by_type(cls)
        if value is None:
            raise ORMTestError(u"No example for %s" % cls)
    return value
Exemple #22
0
    def confirm(self, confirm_date=None):
        """Confirms the purchase order

        :param confirm_data: optional, datetime
        """
        if confirm_date is None:
            confirm_date = TransactionTimestamp()

        if self.status not in [PurchaseOrder.ORDER_PENDING,
                               PurchaseOrder.ORDER_CONSIGNED]:
            fmt = _(u'Invalid order status, it should be '
                    u'ORDER_PENDING or ORDER_CONSIGNED, got %s')
            raise ValueError(fmt % (self.status_str, ))

        # In consigned purchases there is no payments at this point.
        if self.status != PurchaseOrder.ORDER_CONSIGNED:
            for payment in self.payments:
                payment.set_pending()

        if self.supplier:
            self.group.recipient = self.supplier.person

        self.responsible = get_current_user(self.store)
        self.status = PurchaseOrder.ORDER_CONFIRMED
        self.confirm_date = confirm_date

        Event.log(self.store, Event.TYPE_ORDER,
                  _(u"Order %s, total value %2.2f, supplier '%s' "
                    u"is now confirmed") % (self.identifier,
                                            self.purchase_total,
                                            self.supplier.person.name))
Exemple #23
0
    def open_till(self):
        """Open the till.

        It can only be done once per day.
        The final cash amount of the previous till will be used
        as the initial value in this one after opening it.
        """
        if self.status == Till.STATUS_OPEN:
            raise TillError(_('Till is already open'))

        # Make sure that the till has not been opened today
        today = localtoday().date()
        if not self.store.find(
                Till,
                And(
                    Date(Till.opening_date) >= today, Till.station_id
                    == self.station.id)).is_empty():
            raise TillError(_("A till has already been opened today"))

        last_till = self._get_last_closed_till()
        if last_till:
            if not last_till.closing_date:
                raise TillError(_("Previous till was not closed"))

            initial_cash_amount = last_till.final_cash_amount
        else:
            initial_cash_amount = 0

        self.initial_cash_amount = initial_cash_amount

        self.opening_date = TransactionTimestamp()
        self.status = Till.STATUS_OPEN
        self.responsible_open = get_current_user(self.store)
Exemple #24
0
def orm_get_unittest_value(klass, test, tables_dict, name, column):
    value = None
    if isinstance(column, PropertyColumn):
        if column.variable_factory.keywords['value'] is not Undef:
            value = column.variable_factory.keywords['value']
        else:
            try:
                value = orm_get_random(column)
            except ValueError:
                raise ORMTestError(u"No default for %r" % (column, ))

    elif isinstance(column, Reference):
        if name == 'te':
            return None
        if isinstance(column._remote_key, str):
            cls = tables_dict[column._remote_key.split('.')[0]]
        else:
            cls = column._remote_key[0].cls
        if cls.__name__ == 'LoginUser':
            # Avoid unique problems on domains that defines 2 references
            # to LoginUser (e.g. WorkOrder)
            from stoqlib.database.runtime import get_current_user
            value = get_current_user(test.store)
        elif cls.__name__ == 'StorableBatch':
            # StorableBatch needs some very specific information, that is
            # related to other objects. Thus, it cannot be created with random
            # value.
            value = None
        else:
            value = test.create_by_type(cls)
        if value is None:
            raise ORMTestError(u"No example for %s" % cls)
    return value
Exemple #25
0
 def create_payment_renegotiation(self, group=None):
     from stoqlib.domain.payment.renegotiation import PaymentRenegotiation
     return PaymentRenegotiation(responsible=get_current_user(self.store),
                                 branch=get_current_branch(self.store),
                                 group=group or self.create_payment_group(),
                                 client=self.create_client(),
                                 store=self.store)
Exemple #26
0
    def _update_te(self):
        user = get_current_user(self.store)
        station = get_current_station(self.store)

        self.te.dirty = True
        self.te.te_time = StatementTimestamp()
        self.te.user_id = user and user.id
        self.te.station_id = station and station.id
Exemple #27
0
 def create_purchase_order(self, supplier=None, branch=None):
     from stoqlib.domain.purchase import PurchaseOrder
     group = self.create_payment_group()
     return PurchaseOrder(supplier=supplier or self.create_supplier(),
                          branch=branch or self.create_branch(),
                          group=group,
                          responsible=get_current_user(self.store),
                          store=self.store)
Exemple #28
0
    def _update_te(self):
        user = get_current_user(self.store)
        station = get_current_station(self.store)

        self.te.dirty = True
        self.te.te_time = StatementTimestamp()
        self.te.user_id = user and user.id
        self.te.station_id = station and station.id
Exemple #29
0
    def set_consigned(self):
        if self.status != PurchaseOrder.ORDER_PENDING:
            raise ValueError(
                _(u'Invalid order status, it should be '
                  u'ORDER_PENDING, got %s') % (self.status_str, ))

        self.responsible = get_current_user(self.store)
        self.status = PurchaseOrder.ORDER_CONSIGNED
Exemple #30
0
 def create_purchase_order(self, supplier=None, branch=None):
     from stoqlib.domain.purchase import PurchaseOrder
     group = self.create_payment_group()
     return PurchaseOrder(supplier=supplier or self.create_supplier(),
                          branch=branch or self.create_branch(),
                          group=group,
                          responsible=get_current_user(self.store),
                          store=self.store)
Exemple #31
0
    def set_consigned(self):
        if self.status != PurchaseOrder.ORDER_PENDING:
            raise ValueError(
                _(u'Invalid order status, it should be '
                  u'ORDER_PENDING, got %s') % (self.status_str, ))

        self.responsible = get_current_user(self.store)
        self.status = PurchaseOrder.ORDER_CONSIGNED
Exemple #32
0
    def apply(self):
        if self.test_type == ProductQualityTest.TYPE_BOOLEAN:
            value = self.model.boolean_value
        else:
            value = self.model.decimal_value

        for item in self._items:
            result = item.set_test_result_value(self.model.quality_test, value,
                                                get_current_user(self.store))
            self.emit('test-updated', item, self.model.quality_test, result)
    def apply(self):
        if self.test_type == ProductQualityTest.TYPE_BOOLEAN:
            value = self.model.boolean_value
        else:
            value = self.model.decimal_value

        for item in self._items:
            result = item.set_test_result_value(self.model.quality_test, value,
                                                get_current_user(self.store))
            self.emit('test-updated', item, self.model.quality_test, result)
Exemple #34
0
 def test_set_consigned(self):
     order = self.create_purchase_order()
     order.status = PurchaseOrder.ORDER_PENDING
     order.set_consigned()
     current = get_current_user(store=self.store)
     self.assertEquals(current, order.responsible)
     self.assertEquals(order.status, order.ORDER_CONSIGNED)
     order.status = PurchaseOrder.ORDER_CONFIRMED
     with self.assertRaises(ValueError):
         order.set_consigned()
Exemple #35
0
 def test_set_consigned(self):
     order = self.create_purchase_order()
     order.status = PurchaseOrder.ORDER_PENDING
     order.set_consigned()
     current = get_current_user(store=self.store)
     self.assertEquals(current, order.responsible)
     self.assertEquals(order.status, order.ORDER_CONSIGNED)
     order.status = PurchaseOrder.ORDER_CONFIRMED
     with self.assertRaises(ValueError):
         order.set_consigned()
Exemple #36
0
 def _logout(self):
     from stoqlib.database.runtime import (get_current_user,
                                           get_default_store)
     log.debug('Logging out the current user')
     try:
         user = get_current_user(get_default_store())
         if user:
             user.logout()
     except StoqlibError:
         pass
Exemple #37
0
    def increase_stock(self,
                       quantity,
                       branch,
                       type,
                       object_id,
                       unit_cost=None,
                       batch=None):
        """When receiving a product, update the stock reference for this new
        item on a specific |branch|.

        :param quantity: amount to increase
        :param branch: |branch| that stores the stock
        :param type: the type of the stock increase. One of the
            StockTransactionHistory.types
        :param object_id: the id of the object responsible for the transaction
        :param unit_cost: unit cost of the new stock or `None`
        :param batch: The batch of the storable. Should be not ``None`` if
            self.is_batch is ``True``
        """
        assert isinstance(type, int)

        if quantity <= 0:
            raise ValueError(_(u"quantity must be a positive number"))
        if branch is None:
            raise ValueError(u"branch cannot be None")

        stock_item = self.get_stock_item(branch, batch)
        # If the stock_item is missing create a new one
        if stock_item is None:
            store = self.store
            stock_item = ProductStockItem(store=store,
                                          storable=self,
                                          batch=batch,
                                          branch=store.fetch(branch))

        # Unit cost must be updated here as
        # 1) we need the stock item which might not exist
        # 2) it needs to be updated before we change the quantity of the
        #    stock item
        if unit_cost is not None:
            stock_item.update_cost(quantity, unit_cost)

        old_quantity = stock_item.quantity
        stock_item.quantity += quantity

        StockTransactionHistory(product_stock_item=stock_item,
                                quantity=quantity,
                                stock_cost=stock_item.stock_cost,
                                responsible=get_current_user(self.store),
                                type=type,
                                object_id=object_id,
                                store=self.store)

        ProductStockUpdateEvent.emit(self.product, branch, old_quantity,
                                     stock_item.quantity)
Exemple #38
0
    def decrease_stock(self, quantity, branch, type, object_id,
                       cost_center=None):
        """When receiving a product, update the stock reference for the sold item
        this on a specific |branch|. Returns the stock item that was
        decreased.

        :param quantity: amount to decrease
        :param branch: a |branch|
        :param type: the type of the stock increase. One of the
            StockTransactionHistory.types
        :param object_id: the id of the object responsible for the transaction
        :param cost_center: the |costcenter| to which this stock decrease is
            related, if any
        """
        # FIXME: Put this back once 1.6 is released
        #assert isinstance(type, int)

        if quantity <= 0:
            raise ValueError(_(u"quantity must be a positive number"))
        if branch is None:
            raise ValueError(u"branch cannot be None")

        stock_item = self.get_stock_item(branch)
        if stock_item is None or quantity > stock_item.quantity:
            raise StockError(
                _('Quantity to sell is greater than the available stock.'))

        old_quantity = stock_item.quantity
        stock_item.quantity -= quantity

        # We emptied the entire stock in all branches, we need to change
        # the status of the sellable to unavailable as we cannot sell
        # it anymore
        if not self.store.find(ProductStockItem,
                    storable=self).sum(ProductStockItem.quantity):
            sellable = self.product.sellable
            if sellable:
                sellable.set_unavailable()

        stock_transaction = StockTransactionHistory(
                                product_stock_item=stock_item,
                                quantity=-quantity,
                                stock_cost=stock_item.stock_cost,
                                responsible=get_current_user(self.store),
                                type=type,
                                object_id=object_id,
                                store=self.store)

        if cost_center is not None:
            cost_center.add_stock_transaction(stock_transaction)

        ProductStockUpdateEvent.emit(self.product, branch, old_quantity,
                                     stock_item.quantity)

        return stock_item
Exemple #39
0
    def _on_object_added(self, obj_info):
        store = obj_info.get("store")
        store.block_implicit_flushes()
        user = get_current_user(store)
        station = get_current_station(store)
        store.unblock_implicit_flushes()

        self.te = TransactionEntry(store=store,
                                   te_time=StatementTimestamp(),
                                   user_id=user and user.id,
                                   station_id=station and station.id)
Exemple #40
0
    def decrease_stock(self,
                       quantity,
                       branch,
                       type,
                       object_id,
                       cost_center=None,
                       batch=None):
        """When receiving a product, update the stock reference for the sold item
        this on a specific |branch|. Returns the stock item that was
        decreased.

        :param quantity: amount to decrease
        :param branch: a |branch|
        :param type: the type of the stock increase. One of the
            StockTransactionHistory.types
        :param object_id: the id of the object responsible for the transaction
        :param cost_center: the |costcenter| to which this stock decrease is
            related, if any
        :param batch: The batch of the storable. Should be not ``None`` if
            self.is_batch is ``True``
        """
        # FIXME: Put this back once 1.6 is released
        # assert isinstance(type, int)

        if quantity <= 0:
            raise ValueError(_(u"quantity must be a positive number"))
        if branch is None:
            raise ValueError(u"branch cannot be None")

        stock_item = self.get_stock_item(branch, batch)
        if stock_item is None or quantity > stock_item.quantity:
            raise StockError(
                _('Quantity to sell is greater than the available stock.'))

        old_quantity = stock_item.quantity
        stock_item.quantity -= quantity

        stock_transaction = StockTransactionHistory(
            product_stock_item=stock_item,
            quantity=-quantity,
            stock_cost=stock_item.stock_cost,
            responsible=get_current_user(self.store),
            type=type,
            object_id=object_id,
            store=self.store)

        if cost_center is not None:
            cost_center.add_stock_transaction(stock_transaction)

        ProductStockUpdateEvent.emit(self.product, branch, old_quantity,
                                     stock_item.quantity)

        return stock_item
Exemple #41
0
def test_api():
    store = api.get_default_store()

    assert store is get_default_store()
    assert api.get_current_user(store) is get_current_user(store)
    assert api.db_settings is db_settings
    assert api.user_settings is get_settings()
    assert isinstance(api.device_manager, DeviceManager)
    with pytest.raises(NotImplementedError):
        assert isinstance(api.config, IStoqConfig)
    assert api.is_developer_mode() is is_developer_mode()
    assert api.get_l10n_field('CPF') is get_l10n_field('CPF')
Exemple #42
0
    def increase_stock(self, quantity, branch, type, object_id, unit_cost=None):
        """When receiving a product, update the stock reference for this new
        item on a specific |branch|.

        :param quantity: amount to increase
        :param branch: |branch| that stores the stock
        :param type: the type of the stock increase. One of the
            StockTransactionHistory.types
        :param object_id: the id of the object responsible for the transaction
        :param unit_cost: unit cost of the new stock or `None`
        """
        assert isinstance(type, int)

        if quantity <= 0:
            raise ValueError(_(u"quantity must be a positive number"))
        if branch is None:
            raise ValueError(u"branch cannot be None")
        stock_item = self.get_stock_item(branch)
        # If the stock_item is missing create a new one
        if stock_item is None:
            store = self.store
            stock_item = ProductStockItem(
                storable=self,
                branch=store.fetch(branch),
                store=store)

        # Unit cost must be updated here as
        # 1) we need the stock item which might not exist
        # 2) it needs to be updated before we change the quantity of the
        #    stock item
        if unit_cost is not None:
            stock_item.update_cost(quantity, unit_cost)

        old_quantity = stock_item.quantity
        stock_item.quantity += quantity

        # If previously lacked quantity change the status of the sellable
        if not old_quantity:
            sellable = self.product.sellable
            if sellable:
                sellable.can_sell()

        StockTransactionHistory(product_stock_item=stock_item,
                                quantity=quantity,
                                stock_cost=stock_item.stock_cost,
                                responsible=get_current_user(self.store),
                                type=type,
                                object_id=object_id,
                                store=self.store)

        ProductStockUpdateEvent.emit(self.product, branch, old_quantity,
                                     stock_item.quantity)
Exemple #43
0
    def create_stock_decrease(self, branch=None, user=None, reason=u'', group=None):
        from stoqlib.domain.stockdecrease import StockDecrease

        employee = self.create_employee()
        cfop = self.create_cfop_data()
        return StockDecrease(responsible=user or get_current_user(self.store),
                             removed_by=employee,
                             branch=branch or get_current_branch(self.store),
                             status=StockDecrease.STATUS_INITIAL,
                             cfop=cfop,
                             reason=reason,
                             group=group,
                             store=self.store)
Exemple #44
0
 def create_stock_transaction_history(self, product_stock_item=None,
                                    stock_cost=0,
                                    quantity=0,
                                    type=StockTransactionHistory.TYPE_SELL):
     from stoqlib.domain.product import StockTransactionHistory
     if product_stock_item is None:
         product_stock_item = self.create_product_stock_item()
     return StockTransactionHistory(product_stock_item=product_stock_item,
                             responsible=get_current_user(store=self.store),
                             stock_cost=stock_cost,
                             quantity=quantity,
                             type=type,
                             store=self.store)
Exemple #45
0
 def create_receiving_order(self, purchase_order=None, branch=None, user=None):
     from stoqlib.domain.receiving import ReceivingOrder
     if purchase_order is None:
         purchase_order = self.create_purchase_order()
     cfop = self.create_cfop_data()
     cfop.code = u'1.102'
     return ReceivingOrder(store=self.store,
                           invoice_number=222,
                           supplier=purchase_order.supplier,
                           responsible=user or get_current_user(self.store),
                           purchase=purchase_order,
                           branch=branch or get_current_branch(self.store),
                           cfop=cfop)
Exemple #46
0
    def create_stock_decrease(self, branch=None, user=None, reason=u'', group=None):
        from stoqlib.domain.stockdecrease import StockDecrease

        employee = self.create_employee()
        cfop = self.create_cfop_data()
        return StockDecrease(responsible=user or get_current_user(self.store),
                             removed_by=employee,
                             branch=branch or get_current_branch(self.store),
                             status=StockDecrease.STATUS_INITIAL,
                             cfop=cfop,
                             reason=reason,
                             group=group,
                             store=self.store)
Exemple #47
0
    def _on_object_added(self, obj_info):
        store = obj_info.get("store")
        store.block_implicit_flushes()
        user = get_current_user(store)
        station = get_current_station(store)
        store.unblock_implicit_flushes()

        self.te = TransactionEntry(store=store,
                                   te_time=StatementTimestamp(),
                                   user_id=user and user.id,
                                   station_id=station and station.id)

        store.add_created_object(self)
Exemple #48
0
 def create_stock_transaction_history(self, product_stock_item=None,
                                      stock_cost=0,
                                      quantity=0,
                                      type=StockTransactionHistory.TYPE_SELL):
     from stoqlib.domain.product import StockTransactionHistory
     if product_stock_item is None:
         product_stock_item = self.create_product_stock_item()
     return StockTransactionHistory(product_stock_item=product_stock_item,
                                    responsible=get_current_user(store=self.store),
                                    stock_cost=stock_cost,
                                    quantity=quantity,
                                    type=type,
                                    store=self.store)
Exemple #49
0
 def create_receiving_order(self, purchase_order=None, branch=None, user=None):
     from stoqlib.domain.receiving import ReceivingOrder
     if purchase_order is None:
         purchase_order = self.create_purchase_order()
     cfop = self.create_cfop_data()
     cfop.code = u'1.102'
     return ReceivingOrder(store=self.store,
                           invoice_number=222,
                           supplier=purchase_order.supplier,
                           responsible=user or get_current_user(self.store),
                           purchase=purchase_order,
                           branch=branch or get_current_branch(self.store),
                           cfop=cfop)
 def test_branch_combo_items(self):
     branch = get_current_branch(self.store)
     user = get_current_user(self.store)
     product = self.create_product(with_supplier=True)
     supplier_info = product.get_main_supplier_info()
     with mock.patch.object(user.profile, 'check_app_permission') as is_admin:
         # Admin user can set the supplier for any branch
         is_admin.side_effect = [True, False]
         editor = ProductSupplierEditor(self.store, supplier_info)
         self.assertEqual(len(editor.branch_combo.get_model_items()), 2)
         # Regular user can only set to the current branch
         editor = ProductSupplierEditor(self.store, supplier_info)
         items = list(editor.branch_combo.get_model_items().values())
         self.assertEqual(len(items), 1)
         self.assertEqual(items[0], branch)
 def test_branch_combo_items(self):
     branch = get_current_branch(self.store)
     user = get_current_user(self.store)
     product = self.create_product(with_supplier=True)
     supplier_info = product.get_main_supplier_info()
     with mock.patch.object(user.profile, 'check_app_permission') as is_admin:
         # Admin user can set the supplier for any branch
         is_admin.side_effect = [True, False]
         editor = ProductSupplierEditor(self.store, supplier_info)
         self.assertEqual(len(editor.branch_combo.get_model_items()), 2)
         # Regular user can only set to the current branch
         editor = ProductSupplierEditor(self.store, supplier_info)
         items = list(editor.branch_combo.get_model_items().values())
         self.assertEqual(len(items), 1)
         self.assertEqual(items[0], branch)
Exemple #52
0
    def decrease_stock(self, quantity, branch, type, object_id,
                       cost_center=None, batch=None):
        """When receiving a product, update the stock reference for the sold item
        this on a specific |branch|. Returns the stock item that was
        decreased.

        :param quantity: amount to decrease
        :param branch: a |branch|
        :param type: the type of the stock increase. One of the
            StockTransactionHistory.types
        :param object_id: the id of the object responsible for the transaction
        :param cost_center: the |costcenter| to which this stock decrease is
            related, if any
        :param batch: The batch of the storable. Should be not ``None`` if
            self.is_batch is ``True``
        """
        # FIXME: Put this back once 1.6 is released
        # assert isinstance(type, int)

        if quantity <= 0:
            raise ValueError(_(u"quantity must be a positive number"))
        if branch is None:
            raise ValueError(u"branch cannot be None")

        stock_item = self.get_stock_item(branch, batch)
        if stock_item is None or quantity > stock_item.quantity:
            raise StockError(
                _('Quantity to sell is greater than the available stock.'))

        old_quantity = stock_item.quantity
        stock_item.quantity -= quantity

        stock_transaction = StockTransactionHistory(
            product_stock_item=stock_item,
            quantity=-quantity,
            stock_cost=stock_item.stock_cost,
            responsible=get_current_user(self.store),
            type=type,
            object_id=object_id,
            store=self.store)

        if cost_center is not None:
            cost_center.add_stock_transaction(stock_transaction)

        ProductStockUpdateEvent.emit(self.product, branch, old_quantity,
                                     stock_item.quantity)

        return stock_item
Exemple #53
0
    def _create_domain(self):
        self.clean_domain([
            StockTransactionHistory, ProductSupplierInfo, ProductStockItem,
            Storable, Product
        ])

        branch = get_current_branch(self.store)
        user = get_current_user(self.store)
        self.today = localtoday()

        product = self.create_product()
        Storable(store=self.store,
                 product=product,
                 minimum_quantity=3,
                 maximum_quantity=20)
        product.sellable.code = u'1'
        product.sellable.description = u'Luvas'
        product.brand = u'Rawlings'
        product.internal_use = True

        product2 = self.create_product()
        Storable(store=self.store,
                 product=product2,
                 minimum_quantity=4,
                 maximum_quantity=20)
        product2.sellable.code = u'2'
        product2.sellable.description = u'Botas'
        product2.brand = u'Aventura'

        # Purchase
        order = self.create_purchase_order(branch=branch)
        order.identifier = 111
        order.open_date = self.today
        order.status = PurchaseOrder.ORDER_PENDING
        p_item = order.add_item(product.sellable, 10)
        p2_item = order.add_item(product2.sellable, 15)
        order.confirm(self.current_user)

        # Receiving
        receiving = self.create_receiving_order(order, branch, user)
        receiving.identifier = 222
        receiving.receival_date = self.today
        self.create_receiving_order_item(receiving, product.sellable, p_item,
                                         8)
        self.create_receiving_order_item(receiving, product2.sellable, p2_item,
                                         12)
        receiving.confirm(self.current_user)
Exemple #54
0
    def create_trade(self, trade_value=100):
        from stoqlib.domain.returnedsale import ReturnedSale, ReturnedSaleItem
        branch = get_current_branch(self.store)
        returned_sale = ReturnedSale(store=self.store,
                                     responsible=get_current_user(self.store),
                                     branch=branch)
        ReturnedSaleItem(store=self.store,
                         quantity=1,
                         price=trade_value,
                         sellable=self.create_sellable(),
                         returned_sale=returned_sale)

        new_sale = self.create_sale()
        product_price = trade_value * 2
        self.add_product(new_sale, price=product_price)
        new_sale.discount_value = trade_value
        returned_sale.new_sale = new_sale
        return returned_sale
Exemple #55
0
    def _create_domain(self):
        self.clean_domain([ProductHistory])

        branch = get_current_branch(self.store)
        user = get_current_user(self.store)
        self.today = localtoday()

        product = self.create_product()
        Storable(store=self.store, product=product)
        product.sellable.code = u'1'
        product.sellable.description = u'Luvas'
        product2 = self.create_product()
        Storable(store=self.store, product=product2)
        product2.sellable.code = u'2'
        product2.sellable.description = u'Botas'

        # Purchase
        order = self.create_purchase_order(branch=branch)
        order.identifier = 111
        order.open_date = self.today
        order.status = PurchaseOrder.ORDER_PENDING
        p_item = order.add_item(product.sellable, 10)
        p2_item = order.add_item(product2.sellable, 15)
        order.confirm(self.current_user)

        # Receiving
        receiving = self.create_receiving_order(order, branch, user)
        receiving.identifier = 222
        receiving.receival_date = self.today
        self.create_receiving_order_item(receiving, product.sellable, p_item,
                                         8)
        self.create_receiving_order_item(receiving, product2.sellable, p2_item,
                                         12)
        receiving.confirm(self.current_user)

        # Sale
        sale = self.create_sale(branch=branch)
        sale.identifier = 123
        sale.open_date = self.today
        sale.add_sellable(product.sellable, 3)
        sale.add_sellable(product2.sellable, 5)
        sale.order(self.current_user)
        self.add_payments(sale, date=self.today)
        sale.confirm(self.current_user)
Exemple #56
0
    def _create_domain(self):
        self.clean_domain([ProductHistory])

        branch = get_current_branch(self.store)
        user = get_current_user(self.store)
        self.today = localtoday()

        product = self.create_product()
        Storable(store=self.store, product=product)
        product.sellable.code = u'1'
        product.sellable.description = u'Luvas'
        product2 = self.create_product()
        Storable(store=self.store, product=product2)
        product2.sellable.code = u'2'
        product2.sellable.description = u'Botas'

        # Purchase
        order = self.create_purchase_order(branch=branch)
        order.identifier = 111
        order.open_date = self.today
        order.status = PurchaseOrder.ORDER_PENDING
        p_item = order.add_item(product.sellable, 10)
        p2_item = order.add_item(product2.sellable, 15)
        order.confirm()

        # Receiving
        receiving = self.create_receiving_order(order, branch, user)
        receiving.identifier = 222
        receiving.receival_date = self.today
        self.create_receiving_order_item(receiving, product.sellable, p_item, 8)
        self.create_receiving_order_item(receiving, product2.sellable, p2_item,
                                         12)
        receiving.confirm()

        # Sale
        sale = self.create_sale(branch=branch)
        sale.identifier = 123
        sale.open_date = self.today
        sale.add_sellable(product.sellable, 3)
        sale.add_sellable(product2.sellable, 5)
        sale.order()
        self.add_payments(sale, date=self.today)
        sale.confirm()
Exemple #57
0
    def close_till(self, observations=u""):
        """This method close the current till operation with the confirmed
        sales associated. If there is a sale with a differente status than
        SALE_CONFIRMED, a new 'pending' till operation is created and
        these sales are associated with the current one.
        """

        if self.status == Till.STATUS_CLOSED:
            raise TillError(_("Till is already closed"))

        if self.get_balance() < 0:
            raise ValueError(_("Till balance is negative, but this should not "
                               "happen. Contact Stoq Team if you need "
                               "assistance"))

        self.final_cash_amount = self.get_balance()
        self.closing_date = TransactionTimestamp()
        self.status = Till.STATUS_CLOSED
        self.observations = observations
        self.responsible_close = get_current_user(self.store)
Exemple #58
0
    def close_till(self, observations=u""):
        """This method close the current till operation with the confirmed
        sales associated. If there is a sale with a differente status than
        SALE_CONFIRMED, a new 'pending' till operation is created and
        these sales are associated with the current one.
        """

        if self.status == Till.STATUS_CLOSED:
            raise TillError(_("Till is already closed"))

        if self.get_balance() < 0:
            raise ValueError(
                _("Till balance is negative, but this should not "
                  "happen. Contact Stoq Team if you need "
                  "assistance"))

        self.final_cash_amount = self.get_balance()
        self.closing_date = TransactionTimestamp()
        self.status = Till.STATUS_CLOSED
        self.observations = observations
        self.responsible_close = get_current_user(self.store)
Exemple #59
0
    def open_till(self):
        """Open the till.

        It can only be done once per day.
        The final cash amount of the previous till will be used
        as the initial value in this one after opening it.
        """
        if self.status == Till.STATUS_OPEN:
            raise TillError(_('Till is already open'))

        manager = get_plugin_manager()
        # The restriction to only allow opening the till only once per day comes from
        # the (soon to be obsolete) ECF devices.
        if manager.is_active('ecf'):
            # Make sure that the till has not been opened today
            today = localtoday().date()
            if not self.store.find(
                    Till,
                    And(
                        Date(Till.opening_date) >= today, Till.station_id
                        == self.station.id)).is_empty():
                raise TillError(_("A till has already been opened today"))

        last_till = self._get_last_closed_till()
        if last_till:
            if not last_till.closing_date:
                raise TillError(_("Previous till was not closed"))

            initial_cash_amount = last_till.final_cash_amount
        else:
            initial_cash_amount = 0

        self.initial_cash_amount = initial_cash_amount

        self.opening_date = TransactionTimestamp()
        self.status = Till.STATUS_OPEN
        self.responsible_open = get_current_user(self.store)
        assert self.responsible_open is not None
        TillOpenedEvent.emit(self)