Example #1
0
    def testGetCashAmount(self):
        till = Till(store=self.store,
                    station=self.create_station())
        till.open_till()

        old = till.get_cash_amount()
        # money operations
        till.add_credit_entry(currency(10), u"")
        self.assertEqual(till.get_cash_amount(), old + 10)
        till.add_debit_entry(currency(5), u"")
        self.assertEqual(till.get_cash_amount(), old + 5)
        # non-money operations
        payment1 = self._create_inpayment()
        till.add_entry(payment1)
        self.assertEqual(till.get_cash_amount(), old + 5)
        payment2 = self._create_outpayment()
        till.add_entry(payment2)
        self.assertEqual(till.get_cash_amount(), old + 5)
        # money payment method operation
        payment = self.create_payment()
        payment.due_date = till.opening_date
        payment.till = till
        payment.set_pending()
        TillEntry(description=u'test', value=payment.value, till=till,
                  branch=till.station.branch, payment=payment, store=self.store)
        payment.pay()
        self.assertEqual(till.get_cash_amount(), old + 5 + payment.value)
Example #2
0
    def test_set_discount(self):
        loan_item = self.create_loan_item()
        self.assertEqual(loan_item.get_total(), currency(10))

        # It requires a currency value but is 5% of discount
        loan_item.set_discount(decimal.Decimal('4.9'))
        self.assertEqual(loan_item.get_total(), currency('9.51'))
Example #3
0
    def testGetPercentageValue(self):
        sale = self.create_sale()
        sellable = self.create_sellable()
        sale.add_sellable(sellable, quantity=5)

        self.assertEqual(sale._get_percentage_value(0), currency(0))
        self.assertEqual(sale._get_percentage_value(10), currency(5))
Example #4
0
    def get_available_discount_for_items(self, user=None, exclude_item=None):
        """Get available discount for items in this loan

        The available items discount is the total discount not used
        by items in this sale. For instance, if we have 2 products
        with a price of 100 and they can have 10% of discount, we have
        20 of discount available. If one of those products price
        is set to 98, that is, using 2 of it's discount, the available
        discount is now 18.

        :param user: passed to
            :meth:`stoqlib.domain.sellable.Sellable.get_maximum_discount`
            together with :obj:`.client_category` to check for the max
            discount for sellables on this sale
        :param exclude_item: a |saleitem| to exclude from the calculations.
            Useful if you are trying to get some extra discount for that
            item and you don't want it's discount to be considered here
        :returns: the available discount
        """
        available_discount = currency(0)
        used_discount = currency(0)

        for item in self.get_items():
            if item == exclude_item:
                continue
            # Don't put surcharges on the discount, or it can end up negative
            if item.price > item.sellable.base_price:
                continue

            used_discount += item.sellable.base_price - item.price
            max_discount = item.sellable.get_maximum_discount(
                category=self.client_category, user=user) / 100
            available_discount += item.base_price * max_discount

        return available_discount - used_discount
Example #5
0
    def test_prices_and_markups(self):
        self._category.markup = 0
        sellable = Sellable(category=self._category, cost=50,
                            description=u"Test", price=currency(100),
                            store=self.store)
        self.failUnless(sellable.price == 100,
                        u"Expected price: %r, got %r" % (100, sellable.price))
        self.failUnless(sellable.markup == 100,
                        u"Expected markup: %r, got %r" % (100, sellable.markup))
        sellable.markup = 10
        self.failUnless(sellable.price == 55,
                        u"Expected price: %r, got %r" % (55, sellable.price))
        sellable.price = 50
        self.failUnless(sellable.markup == 0,
                        u"Expected markup %r, got %r" % (0, sellable.markup))

        # When the price specified isn't equivalent to the markup specified.
        # In this case the price don't must be updated based on the markup.
        sellable = Sellable(cost=50,
                            description=u"Test", price=currency(100),
                            store=self.store)
        self.failUnless(sellable.price == 100)

        # A simple test: product without cost and price, markup must be 0
        sellable.cost = currency(0)
        sellable.price = currency(0)
        self.failUnless(sellable.markup == 0,
                        u"Expected markup %r, got %r" % (0, sellable.markup))
Example #6
0
    def test_can_purchase_allow_all(self):
        #: This parameter always allows the client to purchase, no matter if he
        #: has late payments
        sysparam(self.store).update_parameter(u'LATE_PAYMENTS_POLICY',
                                              unicode(int(LatePaymentPolicy.ALLOW_SALES)))

        client = self.create_client()
        bill_method = PaymentMethod.get_by_name(self.store, u'bill')
        check_method = PaymentMethod.get_by_name(self.store, u'check')
        money_method = PaymentMethod.get_by_name(self.store, u'money')
        store_credit_method = PaymentMethod.get_by_name(self.store,
                                                        u'store_credit')
        today = localtoday()

        # client can pay if he doesn't have any payments
        client.credit_limit = Decimal("1000")
        self.assertTrue(client.can_purchase(money_method, currency("200")))

        # client can pay if he has payments that are not overdue
        payment = self.create_payment(Payment.TYPE_IN, today, method=bill_method)
        payment.group = self.create_payment_group()
        payment.group.payer = client.person
        self.assertTrue(client.can_purchase(check_method, currency("200")))

        # client can pay even if he does have overdue payments
        payment = self.create_payment(Payment.TYPE_IN,
                                      today - relativedelta(days=1), method=check_method)
        payment.group = self.create_payment_group()
        payment.group.payer = client.person
        self.assertTrue(client.can_purchase(store_credit_method, currency("200")))

        # But he cannot pay if its above the credit limit
        self.assertRaises(SellError, client.can_purchase, store_credit_method, currency("1001"))
Example #7
0
    def __init__(self, purchase, receivings):
        freight_type_map = {
            ReceivingInvoice.FREIGHT_FOB_PAYMENT: PurchaseOrder.FREIGHT_FOB,
            ReceivingInvoice.FREIGHT_FOB_INSTALLMENTS: PurchaseOrder.FREIGHT_FOB,
            ReceivingInvoice.FREIGHT_CIF_UNKNOWN: PurchaseOrder.FREIGHT_CIF,
            ReceivingInvoice.FREIGHT_CIF_INVOICE: PurchaseOrder.FREIGHT_CIF
        }
        freight_names = PurchaseOrder.freight_types
        freight_types = set()

        if receivings.count():
            discount = surcharge = freight = subtotal = total = quantity = 0
            for receiving in receivings:
                discount += receiving.total_discounts
                surcharge += receiving.total_surcharges
                if receiving.receiving_invoice:
                    freight += receiving.receiving_invoice.freight_total
                subtotal += receiving.product_total_with_ipi
                total += receiving.total
                quantity += receiving.total_quantity

                freight_types.add(freight_type_map.get(receiving.freight_type,
                                                       purchase.freight_type))

            self.total_discounts = currency(discount)
            self.total_surcharges = currency(surcharge)
            self.received_freight = currency(freight)
            self.receiving_subtotal = currency(subtotal)
            self.receiving_total = currency(total)
            self.receiving_quantity = quantity

            if len(freight_types) == 1:
                self.received_freight_type = freight_names[freight_types.pop()]
            else:
                self.received_freight_type = _(u'Mixed Freights')
Example #8
0
    def test_trade_as_discount(self):
        sale = self.create_sale(branch=get_current_branch(self.store))
        self.assertEqual(sale.discount_value, currency(0))

        sellable = self.add_product(sale, price=50)
        storable = sellable.product_storable
        balance_before_confirm = storable.get_balance_for_branch(sale.branch)
        sale.order()

        self.add_payments(sale)
        sale.confirm()
        self.assertEqual(storable.get_balance_for_branch(sale.branch),
                         balance_before_confirm - 1)
        balance_before_trade = storable.get_balance_for_branch(sale.branch)

        returned_sale = sale.create_sale_return_adapter()
        new_sale = self.create_sale()
        returned_sale.new_sale = new_sale
        with self.sysparam(USE_TRADE_AS_DISCOUNT=True):
            returned_sale.trade()
            self.assertEqual(new_sale.discount_value, currency(50))
        self.assertEqual(returned_sale.status, ReturnedSale.STATUS_CONFIRMED)

        self.assertEqual(storable.get_balance_for_branch(sale.branch),
                         balance_before_trade + 1)
Example #9
0
    def test_can_purchase_disallow_store_credit(self):
        #: This parameter disallows the client to purchase with store credit
        #: when he has late payments
        sysparam(self.store).update_parameter(u'LATE_PAYMENTS_POLICY',
                                              unicode(int(LatePaymentPolicy.DISALLOW_STORE_CREDIT)))

        client = self.create_client()
        bill_method = PaymentMethod.get_by_name(self.store, u'bill')
        check_method = PaymentMethod.get_by_name(self.store, u'check')
        money_method = PaymentMethod.get_by_name(self.store, u'money')
        store_credit_method = PaymentMethod.get_by_name(self.store,
                                                        u'store_credit')
        today = localtoday()

        # client can pay if he doesn't have any payments
        self.assertTrue(client.can_purchase(money_method, currency("0")))

        # client can pay if he has payments that are not overdue
        payment = self.create_payment(Payment.TYPE_IN, today, method=bill_method)
        payment.group = self.create_payment_group()
        payment.group.payer = client.person
        self.assertTrue(client.can_purchase(money_method, currency("0")))

        # for a client with overdue payments
        payment = self.create_payment(Payment.TYPE_IN,
                                      today - relativedelta(days=1),
                                      method=money_method)
        payment.status = Payment.STATUS_PENDING
        payment.group = self.create_payment_group()
        payment.group.payer = client.person
        # client can pay if payment method is not store credit
        self.assertTrue(client.can_purchase(check_method, currency("0")))
        self.assertTrue(client.can_purchase(money_method, currency("0")))
        # client can not pay if payment method is store credit
        self.assertRaises(SellError, client.can_purchase, store_credit_method, currency("0"))
Example #10
0
    def _get_instrucoes(self, payment):
        instructions = []

        sale = payment.group.sale
        if sale:
            invoice_number = sale.invoice_number
        else:
            invoice_number = payment.identifier

        penalty = currency(
            (sysparam.get_decimal('BILL_PENALTY') / 100) * payment.value)
        interest = currency(
            (sysparam.get_decimal('BILL_INTEREST') / 100) * payment.value)
        discount = currency(
            (sysparam.get_decimal('BILL_DISCOUNT') / 100) * payment.value)
        data = sysparam.get_string('BILL_INSTRUCTIONS')
        for line in data.split('\n')[:4]:
            line = line.replace('$DATE', payment.due_date.strftime('%d/%m/%Y'))
            line = line.replace('$PENALTY',
                                converter.as_string(currency, penalty))
            line = line.replace('$INTEREST',
                                converter.as_string(currency, interest))
            line = line.replace('$DISCOUNT',
                                converter.as_string(currency, discount))
            line = line.replace('$INVOICE_NUMBER', str(invoice_number))
            instructions.append(line)

        instructions.append('')
        instructions.append('\n' + _('Stoq Retail Management') + ' - www.stoq.com.br')
        return instructions
Example #11
0
 def _create_model(self, purchase):
     paid_value = currency(purchase.payments.sum(Payment.paid_value) or 0)
     received_value = purchase.received_total
     return Settable(received_value=received_value,
                     paid_value=paid_value,
                     missing_value=currency(received_value - paid_value),
                     purchase=purchase)
Example #12
0
    def test_sale_total(self):
        branch = self.create_branch()

        rsale = ReturnedSale(branch=branch,
                             store=self.store)
        self.assertEquals(rsale.sale_total, currency(0))

        sale = self.create_sale(branch=branch)
        sellable = self.add_product(sale)
        self.add_payments(sale)
        rsale1 = ReturnedSale(branch=branch,
                              sale=sale,
                              store=self.store)
        rsale2 = ReturnedSale(branch=branch,
                              sale=sale,
                              store=self.store)
        self.assertEquals(rsale1.sale_total, currency(0))

        item = ReturnedSaleItem(store=self.store,
                                returned_sale=rsale2,
                                sellable=sellable)
        item.quantity = 10
        item.price = 10

        self.assertEquals(rsale1.sale_total, currency(-100))
Example #13
0
    def test_get_penalty(self):
        method = PaymentMethod.get_by_name(self.store, u"check")
        payment = Payment(
            value=currency(100),
            branch=self.create_branch(),
            due_date=localnow(),
            method=method,
            group=None,
            till=None,
            category=None,
            payment_type=Payment.TYPE_OUT,
            store=self.store,
        )

        for day, expected_value in [(0, 0), (-1, 0), (-30, 0), (30, 0)]:
            payment.due_date = self._get_relative_day(day)
            self.assertEqual(payment.get_penalty(), currency(expected_value))

        method.penalty = Decimal(20)

        for day, expected_value in [(0, 0), (-1, 20), (-30, 20), (30, 0)]:
            payment.due_date = self._get_relative_day(day)
            self.assertEqual(payment.get_penalty(), currency(expected_value))

        due_date = self._get_relative_day(-15)
        paid_date = self._get_relative_day(-5)
        payment.due_date = payment.open_date = due_date
        self.assertEqual(payment.get_penalty(paid_date.date()), currency(20))
        self.assertEqual(payment.get_penalty(due_date.date()), currency(0))

        for day in (18, -18):
            paid_date = self._get_relative_day(day)
            self.assertRaises(ValueError, payment.get_penalty, paid_date.date())
Example #14
0
    def __init__(self, orders):
        freight_type_map = {
            ReceivingOrder.FREIGHT_FOB_PAYMENT: PurchaseOrder.FREIGHT_FOB,
            ReceivingOrder.FREIGHT_FOB_INSTALLMENTS: PurchaseOrder.FREIGHT_FOB,
            ReceivingOrder.FREIGHT_CIF_UNKNOWN: PurchaseOrder.FREIGHT_CIF,
            ReceivingOrder.FREIGHT_CIF_INVOICE: PurchaseOrder.FREIGHT_CIF
        }
        freight_names = PurchaseOrder.freight_types
        freight_types = []

        if orders.count():
            discount = surcharge = freight = subtotal = total = 0
            for order in orders:
                discount += order._get_total_discounts()
                surcharge += order._get_total_surcharges()
                freight += order.freight_total
                subtotal += order.get_products_total()
                total += order.get_total()

                # If first time used, append to the list of used types
                if freight_type_map[order.freight_type] not in freight_types:
                    freight_types.append(freight_type_map[order.freight_type])

            self.total_discounts = currency(discount)
            self.total_surcharges = currency(surcharge)
            self.received_freight = currency(freight)
            self.receiving_subtotal = currency(subtotal)
            self.receiving_total = currency(total)

            if len(freight_types) == 1:
                self.received_freight_type = freight_names[freight_types[0]]
            else:
                self.received_freight_type = _(u'Mixed Freights')
Example #15
0
    def __init__(self, wizard, parent, store, order_obj, payment_method,
                 outstanding_value=currency(0), first_duedate=None,
                 installments_number=None):
        self.wizard = wizard
        self.parent = parent
        # Note that 'order' may be a Sale or a PurchaseOrder object
        self.order = order_obj
        self.method = payment_method
        self.payment_type = self._get_payment_type()
        self.total_value = outstanding_value or self._get_total_amount()
        self.payment_group = self.order.group
        self.payment_list = None
        # This is very useful when calculating the total amount outstanding
        # or overpaid of the payments
        self.interest_total = currency(0)

        self._first_duedate = first_duedate
        self._installments_number = installments_number

        BaseEditorSlave.__init__(self, store)
        self.register_validate_function(self._refresh_next)

        # Most of slaves don't have bank information
        self.bank_combo.hide()
        self.bank_label.hide()
Example #16
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)
        # 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)
Example #17
0
    def __init__(self, store=None,
                 category=None,
                 cost=None,
                 commission=None,
                 description=None,
                 price=None):
        """Creates a new sellable
        :param store: a store
        :param category: category of this sellable
        :param cost: the cost, defaults to 0
        :param commission: commission for this sellable
        :param description: readable description of the sellable
        :param price: the price, defaults to 0
        """

        Domain.__init__(self, store=store)

        if category:
            if commission is None:
                commission = category.get_commission()
            if price is None and cost is not None:
                markup = category.get_markup()
                price = self._get_price_by_markup(markup, cost=cost)

        self.category = category
        self.commission = commission or currency(0)
        self.cost = cost or currency(0)
        self.description = description
        self.price = price or currency(0)
Example #18
0
 def test_surcharge_percentage_setter(self):
     item = self.create_purchase_order_item()
     surcharge_str = item.order.surcharge_percentage
     self.assertEquals(surcharge_str, currency(0))
     surcharge = Decimal(39)
     item.order.surcharge_percentage = surcharge
     surcharge_str = item.order.surcharge_percentage
     self.assertEquals(surcharge_str, currency(surcharge))
Example #19
0
    def coupon_totalize(self, discount=currency(0), surcharge=currency(0), taxcode=TaxType.NONE):
        # The FISCnet protocol (the protocol used in this printer model)
        # doesn't have a command to totalize the coupon, so we just get
        # the discount/surcharge values and applied to the coupon.

        value = discount and (discount * -1) or surcharge
        if value:
            self._send_command("AcresceSubtotal", Cancelar=False, ValorAcrescimo=value)
        return self._get_coupon_total_value()
Example #20
0
    def test_get_balance(self):
        till = Till(store=self.store, station=self.create_station())
        till.open_till()

        old = till.get_balance()
        till.add_credit_entry(currency(10), u"")
        self.assertEqual(till.get_balance(), old + 10)
        till.add_debit_entry(currency(5), u"")
        self.assertEqual(till.get_balance(), old + 5)
Example #21
0
 def update_discount_and_surcharge(self):
     marker("update_discount_and_surcharge")
     # Here we need avoid to reset sale data defined when creating the
     # Sale in the POS application, i.e, we should not reset the
     # discount and surcharge if they are already set (this is the
     # case when CONFIRM_SALES_ON_TILL parameter is enabled).
     if not sysparam(self.store).CONFIRM_SALES_ON_TILL:
         self.model.discount_value = currency(0)
         self.model.surcharge_value = currency(0)
Example #22
0
 def test_get_total_cost(self):
     decrease = self.create_stock_decrease()
     sellable1 = self.create_sellable()
     sellable1.cost = currency('100')
     sellable2 = self.create_sellable()
     sellable2.cost = currency('10')
     decrease.add_sellable(sellable1, quantity=2)
     decrease.add_sellable(sellable2, quantity=5)
     self.assertEquals(decrease.get_total_cost(), 250)
Example #23
0
 def after_value__validate(self, widget, value):
     if not hasattr(self, "proxy"):
         return
     if value < currency(0):
         self.proxy.update("balance", currency(0))
         return ValidationError(_("Value cannot be less than zero"))
     if value > self.till.get_balance():
         self.proxy.update("balance", currency(0))
         return ValidationError(_("You can not specify an amount " "removed greater than the " "till balance."))
Example #24
0
    def test_get_debits_total(self):
        till = Till(store=self.store, station=self.create_station())
        till.open_till()

        old = till.get_debits_total()
        till.add_debit_entry(currency(10), u"")
        self.assertEqual(till.get_debits_total(), old - 10)
        # This should not affect the debit
        till.add_credit_entry(currency(5), u"")
        self.assertEqual(till.get_debits_total(), old - 10)
Example #25
0
 def update_discount_and_surcharge(self):
     marker("update_discount_and_surcharge")
     # Here we need avoid to reset sale data defined when creating the
     # Sale in the POS application, i.e, we should not reset the
     # discount and surcharge if they are already set (this is the
     # case when one of the parameters, CONFIRM_SALES_ON_TILL or
     # USE_TRADE_AS_DISCOUNT is enabled).
     if (not sysparam.get_bool('CONFIRM_SALES_ON_TILL') and
             not sysparam.get_bool('USE_TRADE_AS_DISCOUNT')):
         self.model.discount_value = currency(0)
         self.model.surcharge_value = currency(0)
Example #26
0
    def post_init(self):
        self.register_validate_function(self._validation_func)
        self.force_validation()

        before_debt = currency(self.model.sale_total - self.model.paid_total)
        now_debt = currency(before_debt - self.model.returned_total)
        info(_("The client's debt has changed. "
               "Use this step to adjust the payments."),
             _("The debt before was %s and now is %s. Cancel some unpaid "
               "installments and create new ones.") % (
             converter.as_string(currency, before_debt),
             converter.as_string(currency, now_debt)))
Example #27
0
    def testFormat(self):
        self.assertEqual(currency('100').format(), '$100')
        self.assertEqual(currency('199').format(), '$199')

        self.assertEqual(currency('0.05').format(), '$0.05')
        self.assertEqual(currency('0.10').format(), '$0.10')
        self.assertEqual(currency('1.05').format(), '$1.05')
        self.assertEqual(currency('1.99').format(), '$1.99')
        self.assertEqual(currency('1.994').format(), '$1.99')
        self.assertEqual(currency('1.995').format(), '$2')
        self.assertEqual(currency('1.996').format(), '$2')
        self.assertEqual(currency(u'1.996').format(), u'$2')
Example #28
0
    def test_can_purchase_total_amount(self):
        method = PaymentMethod.get_by_name(self.store, u'store_credit')

        # client can not buy if he does not have enough store credit
        client = self.create_client()
        client.credit_limit = currency('0')
        self.assertRaises(SellError, client.can_purchase, method, currency('1'))

        # client can buy if he has enough store credit
        client.credit_limit = currency('1000')
        self.assertTrue(client.can_purchase(method, currency('200')))
        self.assertRaises(SellError, client.can_purchase, method, currency('1001'))
    def test_paid_total(self):
        branch = self.create_branch()
        rsale = ReturnedSale(branch=branch, store=self.store)
        self.assertEquals(rsale.paid_total, currency(0))

        sale = self.create_sale(branch=branch)
        self.add_product(sale)
        rsale = ReturnedSale(branch=branch, sale=sale, store=self.store)
        self.add_payments(sale)
        sale.order()
        sale.confirm()
        self.assertEquals(rsale.paid_total, currency(10))
Example #30
0
    def _get_missing_change_value(self, with_new_payment=False):
        received = self.received_value.read()
        if received == ValueUnset:
            received = currency(0)

        if with_new_payment:
            new_payment = self.base_value.read()
            if new_payment == ValueUnset:
                new_payment = currency(0)
            received += new_payment

        return self._total_value - received
Example #31
0
 def test_till_close_more_than_balance(self):
     station = self.create_station()
     till = Till(store=self.store, station=station)
     till.open_till()
     till.add_debit_entry(currency(20), u"")
     self.assertRaises(ValueError, till.close_till)
Example #32
0
 def test_get_received_total(self):
     item = self.create_purchase_order_item()
     received = 3
     item.quantity_received = received
     total_received = item.get_received_total()
     self.assertEqual(total_received, currency(received * item.cost))
Example #33
0
    def on_about__validate(self, widget, data):
        if not 'kinda' in data.lower():
            return ValidationError("use a better language")


person = Person()
person.name = u'John Doe'
person.age = 36
person.birthdate = datetime.datetime(year=1969, month=2, day=20)
person.height = 183.0
person.weight = 86.0
person.nationality = 'Yankee'
person.about = 'Kinda fat'
person.status = True
person.gender = 'Female'
person.salary = currency(1234)

form = Form()
proxy = form.add_proxy(person, [
    'name', 'age', 'birthdate', 'height', 'weight', 'about', 'nationality',
    'status', 'gender', 'salary'
])
form.show_all()


def on_ok_btn_clicked(widget):
    print "Name:", person.name
    print "Age:", person.age
    print "Birthday:", person.birthdate
    print "Height:", person.height
    print "Weight:", person.weight
Example #34
0
 def get_calculated_interest(self, pay_penalty):
     return currency(0)
Example #35
0
 def total(self):
     return currency(self.cost * self.quantity)
Example #36
0
 def invoice_total(self):
     return currency(self.get_total_cost())
Example #37
0
 def get_received_value(self):
     return currency(self.received_value.read())
Example #38
0
    def test_post(self, hl):
        hl.sha1.return_value = hashlib.sha1(b'foo')

        with self.sysparam(DEMO_MODE=True):
            with self.fake_store() as es:
                e = es.enter_context(
                    mock.patch(
                        'stoqserver.lib.restful.SaleConfirmedRemoteEvent.emit')
                )
                d = datetime.datetime(2018, 3, 6, 4, 20, 53)
                restful_now = es.enter_context(
                    mock.patch('stoqserver.lib.restful.localnow'))
                restful_now.return_value = d
                app_now = es.enter_context(
                    mock.patch('stoqserver.app.localnow'))
                app_now.return_value = d
                tt = es.enter_context(
                    mock.patch('stoqlib.domain.sale.TransactionTimestamp'))
                tt.return_value = d
                token = self.login()

                p1 = self.create_product(price=10)
                p1.manage_stock = False
                s1 = p1.sellable

                p2 = self.create_product(price=currency('20.5'))
                p2.manage_stock = False
                s2 = p2.sellable

                c = self.create_client()
                c.person.individual.cpf = '333.341.828-27'

                # Add a till to Store
                till = self.create_till()
                user = self.create_user()
                till.open_till(user)

                rv = self.client.post(
                    '/sale',
                    headers={'Authorization': token},
                    content_type='application/json',
                    data=json.dumps({
                        'client_document':
                        '999.999.999-99',
                        'coupon_document':
                        '333.341.828-27',
                        'products': [
                            {
                                'id': s1.id,
                                'price': str(s1.price),
                                'quantity': 2
                            },
                            {
                                'id': s2.id,
                                'price': str(s2.price),
                                'quantity': 1
                            },
                        ],
                        'payments': [
                            {
                                'method': 'money',
                                'mode': None,
                                'provider': None,
                                'installments': 1,
                                'value': '10.5'
                            },
                            {
                                'method': 'card',
                                'mode': 'credit',
                                'provider': 'VISA',
                                'installments': 2,
                                'value': '30',
                                'card_type': 'credit'
                            },
                        ],
                    }),
                )

                self.assertEqual(rv.status_code, 200)
                self.assertEqual(json.loads(rv.data.decode()), True)

                # This should be the sale made by the call above
                sale = self.store.find(Sale).order_by(Desc(
                    Sale.open_date)).first()
                self.assertEqual(sale.get_total_sale_amount(),
                                 currency('40.5'))
                self.assertEqual(sale.open_date, d)
                self.assertEqual(sale.confirm_date, d)
                self.assertEqual(
                    {(i.sellable, i.quantity, i.price)
                     for i in sale.get_items()}, {(s1, 2, s1.price),
                                                  (s2, 1, s2.price)})
                self.assertEqual(
                    {(p.method.method_name, p.due_date, p.value)
                     for p in sale.group.get_items()},
                    {('card', d, currency('15')),
                     ('card', datetime.datetime(2018, 4, 6, 4, 20,
                                                53), currency('15')),
                     ('money', d, currency('10.5'))})

                self.assertEqual(e.call_count, 1)
                retval = e.call_args_list[0]
                self.assertEqual(len(retval), 2)
                self.assertEqual(retval[0][1], '333.341.828-27')

                # Test the same sale again, but this time, lets mimic an exception
                # happening in SaleConfirmedRemoteEvent
                e.side_effect = Exception('foobar exception')

                # NOTE: This will print the original traceback to stdout, that
                # doesn't mean that the test is failing (unless it really fail)
                rv = self.client.post(
                    '/sale',
                    headers={'Authorization': token},
                    content_type='application/json',
                    data=json.dumps({
                        'client_document':
                        '333.341.828-27',
                        'products': [
                            {
                                'id': s1.id,
                                'price': str(s1.price),
                                'quantity': 2
                            },
                            {
                                'id': s2.id,
                                'price': str(s2.price),
                                'quantity': 1
                            },
                        ],
                        'payments': [
                            {
                                'method': 'money',
                                'value': '40.5'
                            },
                        ],
                    }),
                )
                self.assertEqual(rv.status_code, 500)
                self.assertEqual(
                    json.loads(rv.data.decode()), {
                        'error': 'bad request!',
                        'exception': 'Exception: foobar exception\n',
                        'timestamp': '20180306-042053',
                        'traceback_hash': '0beec7b5'
                    })
Example #39
0
 def total(self):
     return currency(self.price * self.quantity)
Example #40
0
 def test_get_remaining_total(self):
     item = self.create_purchase_order_item()
     item.quantity_received = 4
     result = item.order.get_remaining_total()
     self.assertEqual(result, currency(500))
Example #41
0
 def get_subtotal(self):
     return currency(self.total + self.discount_value -
                     self.surcharge_value)
Example #42
0
 def _update_total(self):
     balance = currency(self._get_till_balance())
     text = _(u"Total: %s") % converter.as_string(currency, balance)
     self.total_label.set_text(text)
Example #43
0
 def parse_set(self, value, from_db):
     # XXX: We cannot reduce the precision when converting to currency, since
     # sometimes we need a cost of a product to have more than 2 digits
     return currency(DecimalVariable.parse_set(value, from_db))
Example #44
0
 def get_total_value(self):
     return currency(self.get_installment_value() + self.get_penalty() +
                     self.get_interest() - self.get_discount())
Example #45
0
 def get_discount(self):
     return currency(sum(p.discount or 0 for p in self.payments))
Example #46
0
    def _get_penalty(self):
        penalty = (
            self.model.paid_value -
            (self.model.value - self.model.discount + self.model.interest))

        return currency(penalty)
Example #47
0
 def _get_price_by_markup(self, markup, cost=None):
     if cost is None:
         cost = self.cost
     return currency(quantize(cost + (cost * (markup / currency(100)))))
Example #48
0
 def get_penalty(self):
     return currency(sum(p.penalty or 0 for p in self.payments))
Example #49
0
 def get_installment_value(self):
     return currency(sum(p.value for p in self.payments))
Example #50
0
 def discount_value(self):
     return currency(0)
Example #51
0
 def get_calculated_penalty(self):
     return currency(0)
Example #52
0
 def test_get_total_sold(self):
     item = self.create_purchase_order_item()
     solded = 5
     item.quantity_sold = solded
     total_sold = item.get_total_sold()
     self.assertEqual(total_sold, currency(solded * item.cost))
Example #53
0
 def set_markup(self, category, markup):
     price = self.cost + self.cost * markup / 100
     if price <= 0:
         price = Decimal('0.01')
     self.set_price(category.id, currency(price))
Example #54
0
 def _update_payment_total(self):
     balance = currency(self._get_total_paid_payment())
     text = _(u"Total payments: %s") % converter.as_string(currency, balance)
     self.total_payment_label.set_text(text)
Example #55
0
 def test_report(self):
     f = FinancialIntervalReport(self.store, 2012)
     f.run()
     data = f.get_data()
     self.assertEquals(
         data,
         {u'Banks': [[(u'Banks', 0), (u'Banco do Brasil', currency("58491.97"))],
                     [(u'Banks', 0), (u'Banco do Brasil', currency("8325.35"))],
                     [(u'Banks', 0), (u'Banco do Brasil', 0)],
                     [(u'Banks', 0), (u'Banco do Brasil', 0)],
                     [(u'Banks', 0), (u'Banco do Brasil', 0)],
                     [(u'Banks', 0), (u'Banco do Brasil', 0)],
                     [(u'Banks', 0), (u'Banco do Brasil', 0)],
                     [(u'Banks', 0), (u'Banco do Brasil', 0)],
                     [(u'Banks', 0), (u'Banco do Brasil', 0)],
                     [(u'Banks', 0), (u'Banco do Brasil', 0)],
                     [(u'Banks', 0), (u'Banco do Brasil', 0)],
                     [(u'Banks', 0), (u'Banco do Brasil', 0)]],
          u'Expenses': [[(u'Expenses', 0),
                         (u'Aluguel', currency("850")),
                         (u'Luz', currency("120.18")),
                         (u'Sal\xe1rios', currency("4692.76")),
                         (u'Telefonia', currency("232.30")),
                         (u'Impostos', currency("6843.91"))],
                        [(u'Expenses', 0),
                         (u'Aluguel', currency("850")),
                         (u'Luz', currency("138.48")),
                         (u'Sal\xe1rios', currency("4502.48")),
                         (u'Telefonia', 0),
                         (u'Impostos', currency("2834.39"))],
                        [(u'Expenses', 0),
                         (u'Aluguel', 0),
                         (u'Luz', 0),
                         (u'Sal\xe1rios', 0),
                         (u'Telefonia', 0),
                         (u'Impostos', 0)],
                        [(u'Expenses', 0),
                         (u'Aluguel', 0),
                         (u'Luz', 0),
                         (u'Sal\xe1rios', 0),
                         (u'Telefonia', 0),
                         (u'Impostos', 0)],
                        [(u'Expenses', 0),
                         (u'Aluguel', 0),
                         (u'Luz', 0),
                         (u'Sal\xe1rios', 0),
                         (u'Telefonia', 0),
                         (u'Impostos', 0)],
                        [(u'Expenses', 0),
                         (u'Aluguel', 0),
                         (u'Luz', 0),
                         (u'Sal\xe1rios', 0),
                         (u'Telefonia', 0),
                         (u'Impostos', 0)],
                        [(u'Expenses', 0),
                         (u'Aluguel', 0),
                         (u'Luz', 0),
                         (u'Sal\xe1rios', 0),
                         (u'Telefonia', 0),
                         (u'Impostos', 0)],
                        [(u'Expenses', 0),
                         (u'Aluguel', 0),
                         (u'Luz', 0),
                         (u'Sal\xe1rios', 0),
                         (u'Telefonia', 0),
                         (u'Impostos', 0)],
                        [(u'Expenses', 0),
                         (u'Aluguel', 0),
                         (u'Luz', 0),
                         (u'Sal\xe1rios', 0),
                         (u'Telefonia', 0),
                         (u'Impostos', 0)],
                        [(u'Expenses', 0),
                         (u'Aluguel', 0),
                         (u'Luz', 0),
                         (u'Sal\xe1rios', 0),
                         (u'Telefonia', 0),
                         (u'Impostos', 0)],
                        [(u'Expenses', 0),
                         (u'Aluguel', 0),
                         (u'Luz', 0),
                         (u'Sal\xe1rios', 0),
                         (u'Telefonia', 0),
                         (u'Impostos', 0)],
                        [(u'Expenses', 0),
                         (u'Aluguel', 0),
                         (u'Luz', 0),
                         (u'Sal\xe1rios', 0),
                         (u'Telefonia', 0),
                         (u'Impostos', 0)]],
          u'Income': [[(u'Income', currency("45752.82"))],
                      [(u'Income', 0)],
                      [(u'Income', 0)],
                      [(u'Income', 0)],
                      [(u'Income', 0)],
                      [(u'Income', 0)],
                      [(u'Income', 0)],
                      [(u'Income', 0)],
                      [(u'Income', 0)],
                      [(u'Income', 0)],
                      [(u'Income', 0)],
                      [(u'Income', 0)]],
          }
     )
Example #56
0
    def test_is_valid_price(self):
        def isValidPriceAssert(valid_data, expected_validity, min_price,
                               max_discount):
            self.assertEqual(valid_data['is_valid'], expected_validity)
            self.assertEqual(valid_data['min_price'], min_price)
            self.assertEqual(valid_data['max_discount'], max_discount)

        sellable = Sellable(category=self._category,
                            cost=50,
                            description=u"Test",
                            price=currency(100),
                            store=self.store)
        sellable.max_discount = 0
        cat = self.create_client_category(u'Cat 1')
        cat_price = ClientCategoryPrice(sellable=sellable,
                                        category=cat,
                                        price=150,
                                        max_discount=0,
                                        store=self.store)
        user = self.create_user()
        user.profile.max_discount = 50

        # without a category, and max_discount = 0, user = None
        valid_data = sellable.is_valid_price(-10)
        isValidPriceAssert(valid_data, False, sellable.price, 0)

        valid_data = sellable.is_valid_price(0)
        isValidPriceAssert(valid_data, False, sellable.price, 0)

        valid_data = sellable.is_valid_price(99)
        isValidPriceAssert(valid_data, False, sellable.price, 0)

        valid_data = sellable.is_valid_price(100)
        isValidPriceAssert(valid_data, True, sellable.price, 0)

        valid_data = sellable.is_valid_price(101)
        isValidPriceAssert(valid_data, True, sellable.price, 0)

        # without a category, and max_discount = 10%
        sellable.max_discount = 10

        valid_data = sellable.is_valid_price(-1)
        isValidPriceAssert(valid_data, False, currency(90), 10)

        valid_data = sellable.is_valid_price(0)
        isValidPriceAssert(valid_data, False, currency(90), 10)

        valid_data = sellable.is_valid_price(89)
        isValidPriceAssert(valid_data, False, currency(90), 10)

        valid_data = sellable.is_valid_price(90)
        isValidPriceAssert(valid_data, True, currency(90), 10)

        valid_data = sellable.is_valid_price(91)
        isValidPriceAssert(valid_data, True, currency(90), 10)

        # Now with a category, max_discount = 0
        valid_data = sellable.is_valid_price(0, cat)
        isValidPriceAssert(valid_data, False, currency(150), 0)

        valid_data = sellable.is_valid_price(-10, cat)
        isValidPriceAssert(valid_data, False, currency(150), 0)

        valid_data = sellable.is_valid_price(Decimal('149.99'), cat)
        isValidPriceAssert(valid_data, False, currency(150), 0)

        valid_data = sellable.is_valid_price(150, cat)
        isValidPriceAssert(valid_data, True, currency(150), 0)

        valid_data = sellable.is_valid_price(151, cat)
        isValidPriceAssert(valid_data, True, currency(150), 0)

        # Now with a category, max_discount = 10%
        cat_price.max_discount = 10

        valid_data = sellable.is_valid_price(Decimal('149.99'), cat)
        isValidPriceAssert(valid_data, True, currency(135), 10)

        valid_data = sellable.is_valid_price(135, cat)
        isValidPriceAssert(valid_data, True, currency(135), 10)

        valid_data = sellable.is_valid_price(134, cat)
        isValidPriceAssert(valid_data, False, currency(135), 10)

        # with a user
        valid_data = sellable.is_valid_price(49, None, user)
        isValidPriceAssert(valid_data, False, currency(50), 50)

        valid_data = sellable.is_valid_price(50, None, user)
        isValidPriceAssert(valid_data, True, currency(50), 50)

        # with discount
        valid_data = sellable.is_valid_price(50, None, user, extra_discount=10)
        isValidPriceAssert(valid_data, True, currency(40), 50)
Example #57
0
 def get_interest(self):
     return currency(sum(p.interest or 0 for p in self.payments))
Example #58
0
 def coupon_totalize(
         discount=currency(0), surcharge=currency(0), taxcode=TaxType.NONE):
     """ Closes the coupon applies addition a discount or surcharge and tax.
Example #59
0
 def test_get_total(self):
     order_item = self.create_receiving_order_item()
     self.assertEqual(order_item.get_total(), currency(1000))
Example #60
0
 def test_surcharge_percentage_getter(self):
     item = self.create_purchase_order_item()
     surcharge = Decimal(39)
     item.order.surcharge_percentage = surcharge
     surcharge_str = currency(item.order._get_percentage_value(surcharge))
     self.assertEqual(item.order.surcharge_value, surcharge_str)