Beispiel #1
0
    def send(self):
        """Send the package to the :attr:`.destination_branch`

        This will mark the package as sent. Note that it's only possible
        to call this on the same branch as :attr:`.source_branch`.

        When calling this, the work orders' :attr:`WorkOrder.current_branch`
        will be ``None``, since they are on a package and not on any branch.
        """
        assert self.can_send()

        if self.source_branch != get_current_branch(self.store):
            raise ValueError(
                _("This package's source branch is %s and you are in %s. "
                  "It's not possible to send a package outside the "
                  "source branch") % (
                      self.source_branch, get_current_branch(self.store)))

        workorders = [item.order for item in self.package_items]
        if not len(workorders):
            raise ValueError(_("There're no orders to send"))

        for order in workorders:
            assert order.current_branch == self.source_branch
            # The order is going to leave the current_branch
            order.current_branch = None

        self.send_date = localnow()
        self.status = self.STATUS_SENT
Beispiel #2
0
    def receive(self):
        """Receive the package on the :attr:`.destination_branch`

        This will mark the package as received in the branch
        to receive it there. Note that it's only possible to call this
        on the same branch as :attr:`.destination_branch`.

        When calling this, the work orders' :attr:`WorkOrder.current_branch`
        will be set to :attr:`.destination_branch`, since receiving means
        they got to their destination.
        """
        assert self.can_receive()

        if self.destination_branch != get_current_branch(self.store):
            raise ValueError(
                _("This package's destination branch is %s and you are in %s. "
                  "It's not possible to receive a package outside the "
                  "destination branch") % (
                      self.destination_branch, get_current_branch(self.store)))

        for order in [item.order for item in self.package_items]:
            assert order.current_branch is None
            # The order is in destination branch now
            order.current_branch = self.destination_branch

        self.receive_date = localnow()
        self.status = self.STATUS_RECEIVED
Beispiel #3
0
    def _create_sale(self, invoice_number, due_date=None):
        sale = self.create_sale()
        sale.invoice_number = invoice_number
        sale.branch = get_current_branch(self.store)
        tax_types = cycle(['aliq', 'nt', 'outr'])
        # [0] - Description
        # [1] - Code
        # [2] - Price
        # [3] - Quantity
        # [4] - Base price
        for tax_type, data in zip(tax_types, [
                (u"Laranja", u"1", Decimal(1), Decimal(10), Decimal('1.5')),
                (u"Limão", u"2", Decimal('0.5'), Decimal(15), Decimal('0.3')),
                (u"Abacaxi", u"3", Decimal(3), Decimal(1), Decimal('3.3')),
                (u"Cenoura", u"4", Decimal('1.5'), Decimal(6), Decimal('1.9')),
                (u"Pêssego", u"5", Decimal('3.5'), Decimal(3), Decimal('3.0'))]):
            sellable = self._create_sellable(data[0], data[1], data[2])
            storable = Storable(product=sellable.product,
                                store=self.store)
            storable.increase_stock(data[3], get_current_branch(self.store),
                                    StockTransactionHistory.TYPE_INITIAL,
                                    sale.id)

            sale_item = sale.add_sellable(sellable, data[3])
            if tax_type == 'aliq':
                self._add_aliq(sale_item)
            elif tax_type == 'nt':
                self._add_nt(sale_item)
            elif tax_type == 'outr':
                self._add_outr(sale_item)

            # Set the base price to test the discount in NF-e.
            sale_item.base_price = data[4]
            icms_info = sale_item.icms_info
            icms_info.csosn = 201
            icms_info.p_icms_st = 1

            self._update_taxes(sale_item)

        sale.client = self.create_client()
        self._create_address(sale.client.person,
                             street=u"Rua dos Tomates",
                             streetnumber=2666,
                             postal_code=u'87654-321')
        sale.order()

        method = PaymentMethod.get_by_name(self.store, u'money')
        method.create_payment(Payment.TYPE_IN, sale.group, sale.branch,
                              sale.get_sale_subtotal(),
                              due_date=due_date)
        sale.confirm()

        return sale
Beispiel #4
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
Beispiel #5
0
def print_cheques_for_payment_group(store, group):
    """ Given a instance that implements the PaymentGroup interface, iterate
    over all its items printing a cheque for them.
    """
    payments = group.get_valid_payments()
    printer = get_current_cheque_printer_settings(store)
    if not printer:
        return
    printer_banks = printer.get_banks()
    current_branch = get_current_branch(store)
    main_address = current_branch.person.get_main_address()
    if not main_address:
        raise ValueError("The cheque can not be printed since there is no "
                         "main address defined for the current branch.")

    max_len = printer.get_capability("cheque_city").max_len
    city = main_address.city_location.city[:max_len]
    for idx, payment in enumerate(payments):
        if payment.method.method_name == 'check':
            continue
        check_data = payment.method.operation.get_check_data_by_payment(
            payment)
        bank_id = check_data.bank_data.bank_id
        try:
            bank = printer_banks[bank_id]
        except KeyError:
            continue
        thirdparty = group.recipient
        info(_(u"Insert Cheque %d") % (idx + 1))
        max_len = printer.get_capability("cheque_thirdparty").max_len
        thirdparty = thirdparty and thirdparty.name[:max_len] or ""
        printer.print_cheque(bank, payment.value, thirdparty, city)
Beispiel #6
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)
Beispiel #7
0
    def test_can_remove(self):
        branch = get_current_branch(self.store)
        sellable = self.create_sellable()
        storable = Storable(product=sellable.product, store=self.store)
        self.failUnless(sellable.can_remove())

        storable.increase_stock(1, branch, 0, None)
        sale = self.create_sale()
        sale.status = Sale.STATUS_QUOTE
        sale.branch = branch
        sale.add_sellable(sellable)
        self.failIf(sellable.can_remove())

        # Can't remove the sellable if it's in a purchase.
        from stoqlib.domain.purchase import PurchaseItem
        sellable = self.create_sellable()
        Storable(product=sellable.product, store=self.store)
        self.assertTrue(sellable.can_remove())
        PurchaseItem(store=self.store,
                     quantity=8, quantity_received=0,
                     cost=125, base_cost=125,
                     sellable=sellable,
                     order=self.create_purchase_order())
        self.assertFalse(sellable.can_remove())

        # The delivery service cannot be removed.
        sellable = sysparam(self.store).DELIVERY_SERVICE.sellable
        self.failIf(sellable.can_remove())
Beispiel #8
0
    def testTotalReturn(self):
        sale = self.create_sale(branch=get_current_branch(self.store))
        sellable = self.add_product(sale)
        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_return = storable.get_balance_for_branch(sale.branch)

        self.failUnless(sale.can_return())
        returned_sale = sale.create_sale_return_adapter()
        returned_sale.return_()

        self.failIf(sale.can_return())
        self.assertEqual(sale.status, Sale.STATUS_RETURNED)
        self.assertEqual(sale.return_date.date(), datetime.date.today())
        self.assertEqual(storable.get_balance_for_branch(sale.branch),
                         balance_before_return + 1)
        # Since this is a total return, balance should be
        # as it wasn't ever confirmed
        self.assertEqual(storable.get_balance_for_branch(sale.branch),
                         balance_before_confirm)
Beispiel #9
0
    def test_select_by_branch_data(self):
        branch = get_current_branch(self.store)
        sale = self.create_sale()
        sale.branch = branch
        sellable = self.add_product(sale)
        sale.order()
        self.add_payments(sale, method_type=u"money")
        sale.confirm()

        results = SoldItemView.find_by_branch_date(self.store, None, None)
        self.assertFalse(results.is_empty())

        results = SoldItemView.find_by_branch_date(self.store, branch, None)
        self.assertFalse(results.is_empty())

        results = SoldItemView.find_by_branch_date(self.store, branch, None).find(SoldItemView.id == sellable.id)
        # FIXME: Storm does not support count() with group_by
        # self.assertEquals(results.count(), 1)
        self.assertEquals(len(list(results)), 1)

        today = localtoday()
        results = SoldItemView.find_by_branch_date(self.store, None, today).find(SoldItemView.id == sellable.id)
        self.assertEquals(len(list(results)), 1)

        yesterday = today - datetime.timedelta(days=1)
        results = SoldItemView.find_by_branch_date(self.store, None, (yesterday, today))
        results = results.find(SoldItemView.id == sellable.id)
        self.assertEquals(len(list(results)), 1)

        yesterday = today - datetime.timedelta(days=1)
        results = SoldItemView.find_by_branch_date(self.store, None, (yesterday, today))

        self.assertFalse(results.is_empty())
Beispiel #10
0
    def testIncreaseDecreaseStock(self):
        branch = get_current_branch(self.store)
        product = self.create_product()
        storable = Storable(product=product, store=self.store)
        stock_item = storable.get_stock_item(branch)
        self.failIf(stock_item is not None)

        storable.increase_stock(1, branch, 0, 0)
        stock_item = storable.get_stock_item(branch)
        self.assertEquals(stock_item.stock_cost, 0)

        storable.increase_stock(1, branch, 0, 0, unit_cost=10)
        stock_item = storable.get_stock_item(branch)
        self.assertEquals(stock_item.stock_cost, 5)

        stock_item = storable.decrease_stock(1, branch, 0, 0)
        self.assertEquals(stock_item.stock_cost, 5)

        storable.increase_stock(1, branch, 0, 0)
        stock_item = storable.get_stock_item(branch)
        self.assertEquals(stock_item.stock_cost, 5)

        storable.increase_stock(2, branch, 0, 0, unit_cost=15)
        stock_item = storable.get_stock_item(branch)
        self.assertEquals(stock_item.stock_cost, 10)
Beispiel #11
0
    def test_calculate_item_without_icms(self):
        # SP (São Paulo) as default state.
        branch = get_current_branch(self.store)
        address = branch.person.get_main_address()
        state = address.city_location.state
        assert state == "SP"
        # Product with NCM, but without ICMS
        sale = self.create_sale()
        item = self.create_sale_item(sale)
        product = item.sellable.product
        product.ncm = u'01012100'
        items = sale.get_items()
        generator = IBPTGenerator(items)
        # When there is no icms information, the value defaults to the nacional
        # tax.
        tax_values = generator._load_tax_values(item)
        federal = generator._calculate_federal_tax(item, tax_values)
        self.assertEquals(federal, Decimal("4.20"))
        state = generator._calculate_state_tax(item, tax_values)
        self.assertEquals(state, Decimal("18"))

        msg = generate_ibpt_message(items)
        expected_msg = ("Trib aprox R$: 4.20 Federal e 18.00 Estadual\n"
                        "Fonte: IBPT 5oi7eW ")
        self.assertEquals(msg, expected_msg)
    def test_branch_combo_sensitivity(self):
        branch = get_current_branch(self.store)
        # Create product with supplier info for all branches
        supplier = self.create_supplier()
        product = self.create_product()
        supplier_info = self.create_product_supplier_info(
            product=product, supplier=supplier, branch=branch)

        # We are editing another product supplier info, and since there is NOT
        # another one for all branches, it's optional to set a branch
        new_supplier_info = self.create_product_supplier_info(
            product=product, supplier=supplier)
        editor = ProductSupplierEditor(self.store, new_supplier_info)
        self.assertNotSensitive(editor, ['branch_combo'])
        self.assertSensitive(editor, ['branch_checkbutton'])
        self.assertFalse(editor.branch_checkbutton.get_active())

        # Remove branch from original supplier info. Now it's generic/default
        supplier_info.branch = None
        # We are editing another product supplier info, and since there is
        # already another one for all branches, it's mandatory to set a specific
        # branch now
        editor = ProductSupplierEditor(self.store, new_supplier_info)
        self.assertSensitive(editor, ['branch_combo'])
        self.assertNotSensitive(editor, ['branch_checkbutton'])
        self.assertTrue(editor.branch_checkbutton.get_active())
    def test_inventory(self):
        branch = get_current_branch(self.store)
        product = self.create_product(branch=branch, stock=10)
        editor = ProductStockQuantityEditor(self.store, product, branch)
        self.check_editor(editor, 'editor-product-stock-quantity-inventory-show')

        # Update editor
        editor.quantity.update(20)
        editor.reason.update('test case')

        inventories_before = self.store.find(Inventory).count()

        # Confirm
        self.click(editor.main_dialog.ok_button)

        # Check data
        inventories_after = self.store.find(Inventory).count()
        self.assertEqual(inventories_after, inventories_before + 1)

        stock_item = product.storable.get_stock_item(branch, batch=None)
        self.assertEqual(stock_item.quantity, 20)

        # Check Inventory
        inventory = self.store.find(Inventory).order_by(Inventory.te_id).last()
        # The inventory should have only one item
        item = inventory.get_items().one()

        self.assertEqual(item.recorded_quantity, 10)
        self.assertEqual(item.counted_quantity, 20)
        self.assertEqual(item.actual_quantity, 20)
        self.assertEqual(item.is_adjusted, True)
        self.assertEqual(inventory.status, Inventory.STATUS_CLOSED)
Beispiel #14
0
    def _create_domain(self):
        self.clean_domain([SaleItem])

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

        product = self.create_product()
        storable = Storable(store=self.store, product=product)
        ProductStockItem(storable=storable, branch=branch, quantity=5,
                         store=self.store)
        product.sellable.code = u'1'
        product.sellable.description = u'Luvas'

        product2 = self.create_product()
        storable2 = Storable(store=self.store, product=product2)
        ProductStockItem(storable=storable2, branch=branch, quantity=5,
                         store=self.store)
        product2.sellable.code = u'2'
        product2.sellable.description = u'Botas'

        # 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()
Beispiel #15
0
    def create_sale(self, id_=None, branch=None, client=None):
        from stoqlib.domain.sale import Sale
        from stoqlib.domain.till import Till

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

        sale = Sale(
            coupon_id=0,
            open_date=TransactionTimestamp(),
            salesperson=salesperson,
            branch=branch or get_current_branch(self.store),
            cfop=sysparam(self.store).DEFAULT_SALES_CFOP,
            group=group,
            client=client,
            store=self.store,
        )
        if id_:
            sale.id = id_
            sale.identifier = id_
        return sale
Beispiel #16
0
    def test_return_with_credit(self):
        branch = get_current_branch(self.store)
        sale_item = self.create_sale_item()
        sale = sale_item.sale
        sellable = sale_item.sellable
        self.create_storable(product=sellable.product, branch=branch, stock=10)
        payments = self.add_payments(sale, method_type=u'bill',
                                     installments=2)
        payments[0].status = Payment.STATUS_PENDING
        self.add_payments(sale, method_type=u'money')
        sale.order()
        sale.confirm()

        rsale = ReturnedSale(branch=branch,
                             sale=sale,
                             store=self.store)
        ReturnedSaleItem(store=self.store,
                         returned_sale=rsale,
                         sale_item=sale_item,
                         quantity=1)
        # Create an unused to test the removal of unused items,
        # should probably be removed.
        ReturnedSaleItem(store=self.store,
                         returned_sale=rsale,
                         sale_item=sale_item,
                         quantity=0)
        rsale.return_(u'credit')
Beispiel #17
0
    def _return_items(self):
        # We must have at least one item to return
        assert self.returned_items.count()

        branch = get_current_branch(self.store)
        for item in self.returned_items:
            item.return_(branch)
Beispiel #18
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)
Beispiel #19
0
    def _add_header(self):
        branch = get_current_branch(self.store)
        manager = branch.manager.person
        company = branch.person.company
        address = branch.person.get_main_address()

        state_registry = company.get_state_registry_number()
        state = address.get_state()

        self.sintegra.add_header(company.get_cnpj_number(),
                                 str(state_registry) or 'ISENTO',
                                 company.fancy_name,
                                 address.get_city(),
                                 state,
                                 branch.person.get_fax_number_number(),
                                 self.start,
                                 self.end)
        self.sintegra.add_complement_header(
            # If we don't have a street number, use zero for sintegra
            address.street, address.streetnumber or 0,
            address.complement,
            address.district,
            address.get_postal_code_number(),
            manager.name,
            branch.person.get_phone_number_number())

        self._add_registers(state)
Beispiel #20
0
    def testSalesPersonReport(self):
        sysparam(self.store).SALE_PAY_COMMISSION_WHEN_CONFIRMED = 1
        salesperson = self.create_sales_person()
        product = self.create_product(price=100)
        sellable = product.sellable

        sale = self.create_sale()
        sale.salesperson = salesperson
        sale.add_sellable(sellable, quantity=1)

        self.create_storable(product, get_current_branch(self.store), stock=100)

        CommissionSource(sellable=sellable,
                         direct_value=Decimal(10),
                         installments_value=1,
                         store=self.store)

        sale.order()

        method = PaymentMethod.get_by_name(self.store, u'money')
        till = Till.get_last_opened(self.store)
        method.create_inpayment(sale.group, sale.branch,
                                sale.get_sale_subtotal(),
                                till=till)
        sale.confirm()
        sale.set_paid()

        salesperson_name = salesperson.person.name
        commissions = list(self.store.find(CommissionView))
        commissions[0].identifier = 1
        commissions[1].identifier = 139

        self._diff_expected(SalesPersonReport, 'sales-person-report', commissions,
                            salesperson_name)
Beispiel #21
0
    def test_order_receive_sell(self):
        product = self.create_product()
        storable = Storable(product=product, store=self.store)
        self.failIf(self.store.find(ProductStockItem, storable=storable).one())
        purchase_order = self.create_purchase_order()
        purchase_item = purchase_order.add_item(product.sellable, 1)
        purchase_order.status = purchase_order.ORDER_PENDING
        method = PaymentMethod.get_by_name(self.store, u'money')
        method.create_payment(Payment.TYPE_OUT,
                              purchase_order.group, purchase_order.branch,
                              purchase_order.get_purchase_total())
        purchase_order.confirm()

        receiving_order = self.create_receiving_order(purchase_order)
        receiving_order.branch = get_current_branch(self.store)
        self.create_receiving_order_item(
            receiving_order=receiving_order,
            sellable=product.sellable,
            purchase_item=purchase_item,
            quantity=1)
        self.failIf(self.store.find(ProductStockItem, storable=storable).one())
        receiving_order.confirm()
        product_stock_item = self.store.find(ProductStockItem,
                                             storable=storable).one()
        self.failUnless(product_stock_item)
        self.assertEquals(product_stock_item.quantity, 1)

        sale = self.create_sale()
        sale.add_sellable(product.sellable)
        sale.order()
        method = PaymentMethod.get_by_name(self.store, u'check')
        method.create_payment(Payment.TYPE_IN, sale.group, sale.branch, Decimal(100))
        sale.confirm()
        self.assertEquals(product_stock_item.quantity, 0)
Beispiel #22
0
    def _create_sale(self):
        today = localdate(2010, 12, 1)
        client = self.create_client()

        # new sale
        sale = self.create_sale(branch=get_current_branch(self.store))
        sale.identifier = 123
        sale.client = client
        sale.open_date = today
        sale.discount_value = Decimal('15')
        sale.surcharge_value = Decimal('8')

        # Product
        item_ = self.create_sale_item(sale, product=True)
        self.create_storable(item_.sellable.product, sale.branch, 1)
        # Service
        item = self.create_sale_item(sale, product=False)
        item.estimated_fix_date = today

        # Payments
        payment = self.add_payments(sale, date=today)[0]
        payment.identifier = 999
        payment.group.payer = client.person

        sale.order()
        sale.confirm()
        sale.group.pay()

        payment.paid_date = today

        return sale
Beispiel #23
0
    def test_receive(self, localnow):
        localnow.return_value = localdate(2013, 1, 1)

        package = self.create_workorder_package(
            source_branch=self.create_branch())
        package.destination_branch = get_current_branch(self.store)
        workorder1 = self.create_workorder(current_branch=package.source_branch)
        workorder2 = self.create_workorder(current_branch=package.source_branch)

        # Mimic WorkOrderPackage.send
        for order in [workorder1, workorder2]:
            package.add_order(order)
            order.current_branch = None
        package.status = WorkOrderPackage.STATUS_SENT

        with mock.patch('stoqlib.domain.workorder.get_current_branch') as gcb:
            gcb.return_value = self.create_branch()
            with self.assertRaisesRegexp(
                    ValueError,
                    ("This package's destination branch is <Branch u'[0-9a-f-]+'> "
                     "and you are in <Branch u'[0-9a-f-]+'>. It's not possible "
                     "to receive a package outside the destination branch")):
                package.receive()

        self.assertEqual(package.receive_date, None)
        package.receive()
        self.assertEqual(package.status, WorkOrderPackage.STATUS_RECEIVED)
        self.assertEqual(package.receive_date, localdate(2013, 1, 1))

        for order in [workorder1, workorder2]:
            self.assertEqual(order.current_branch, package.destination_branch)
Beispiel #24
0
    def test_sales_person_report(self):
        sysparam.set_bool(self.store, "SALE_PAY_COMMISSION_WHEN_CONFIRMED", True)
        salesperson = self.create_sales_person()
        product = self.create_product(price=100)
        sellable = product.sellable

        sale = self.create_sale()
        sale.salesperson = salesperson
        sale.add_sellable(sellable, quantity=1)

        self.create_storable(product, get_current_branch(self.store), stock=100)

        CommissionSource(sellable=sellable, direct_value=Decimal(10), installments_value=1, store=self.store)

        sale.order()

        method = PaymentMethod.get_by_name(self.store, u"money")
        method.create_payment(Payment.TYPE_IN, sale.group, sale.branch, sale.get_sale_subtotal())
        sale.confirm()
        sale.group.pay()

        salesperson = salesperson
        commissions = list(self.store.find(CommissionView))
        commissions[0].identifier = 1
        commissions[1].identifier = 139

        self._diff_expected(SalesPersonReport, "sales-person-report", commissions, salesperson)

        # Also test when there is no salesperson selected
        self._diff_expected(SalesPersonReport, "sales-person-report-without-salesperson", commissions, None)
Beispiel #25
0
 def create_workorder(self, equipment=u''):
     from stoqlib.domain.workorder import WorkOrder
     return WorkOrder(
         store=self.store,
         equipment=equipment,
         branch=get_current_branch(self.store),
         )
Beispiel #26
0
 def create_station(self, branch=None):
     if branch is None:
         branch = get_current_branch(self.store)
     from stoqlib.domain.station import BranchStation
     return BranchStation(name=u"station",
                          branch=branch,
                          store=self.store)
Beispiel #27
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
Beispiel #28
0
    def test_get_client_credit_transactions(self):
        method = self.store.find(PaymentMethod, method_name=u'credit').one()
        client = self.create_client()
        sale = self.create_sale(client=client)
        self.add_product(sale)
        self.add_payments(sale)
        sale.order()
        sale.confirm()

        returned_sale = ReturnedSale(sale=sale,
                                     branch=get_current_branch(self.store),
                                     store=self.store)
        ReturnedSaleItem(sale_item=list(sale.get_items())[0], quantity=1,
                         returned_sale=returned_sale,
                         store=self.store)
        sale.return_(returned_sale)
        payment = self.create_payment(payment_type=Payment.TYPE_OUT,
                                      value=100, method=method,
                                      group=sale.group)
        payment.set_pending()
        payment.pay()

        payment_domain_list = list(client.get_credit_transactions())
        self.assertTrue(len(payment_domain_list) == 1)

        payment_domain = payment_domain_list[0]
        self.assertEquals(payment.identifier, payment_domain.identifier)
        self.assertEquals(payment.paid_date, payment_domain.paid_date)
        self.assertEquals(payment.description, payment_domain.description)
        self.assertEquals(payment.paid_value, payment_domain.paid_value)
Beispiel #29
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)
    def test_create(self, yesno, print_report):
        sellable = self.create_sellable(description=u"Product to transfer")
        self.create_storable(sellable.product, get_current_branch(self.store),
                             stock=10)

        wizard = StockTransferWizard(self.store)
        self.assertNotSensitive(wizard, ['next_button'])
        self.check_wizard(wizard, 'wizard-stock-transfer-create')

        step = wizard.get_current_step()
        step.destination_branch.set_active(0)
        self.assertSensitive(wizard, ['next_button'])

        self.click(wizard.next_button)
        step = wizard.get_current_step()

        # adds sellable to step
        step.sellable_selected(sellable)
        step._add_sellable()

        self.check_wizard(wizard, 'wizard-stock-transfer-products')

        module = 'stoqlib.gui.events.StockTransferWizardFinishEvent.emit'
        with mock.patch(module) as emit:
            with mock.patch.object(self.store, 'commit'):
                self.click(wizard.next_button)
            self.assertEquals(emit.call_count, 1)
            args, kwargs = emit.call_args
            self.assertTrue(isinstance(args[0], TransferOrder))

        yesno.assert_called_once_with(
            _('Would you like to print a receipt for this transfer?'),
            gtk.RESPONSE_YES, 'Print receipt', "Don't print")
        self.assertEquals(print_report.call_count, 1)
    def test_sale_return_invoice_step(self):
        main_branch = get_current_branch(self.store)
        sale = self.create_sale(branch=main_branch)
        self.add_product(sale)
        self.add_product(sale, quantity=2)
        self.add_payments(sale)
        sale.order()
        sale.confirm()
        returned_sale = sale.create_sale_return_adapter()
        wizard = SaleReturnWizard(self.store, returned_sale)
        self.click(wizard.next_button)
        step = wizard.get_current_step()

        self.check_wizard(wizard, 'wizard-sale-return-invoice-step')
        self.assertNotSensitive(wizard, ['next_button'])

        self.assertInvalid(step, ['reason'])
        step.reason.update(
            "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed\n"
            "do eiusmod tempor incididunt ut labore et dolore magna aliqua.")
        self.assertValid(step, ['reason'])

        # XXX: changed because invoice_number is no longer mandatory
        self.assertSensitive(wizard, ['next_button'])

        step.invoice_number.update(0)
        self.assertInvalid(step, ['invoice_number'])
        step.invoice_number.update(1000000000)
        self.assertInvalid(step, ['invoice_number'])
        self.assertNotSensitive(wizard, ['next_button'])

        # Check if the invoice number already exists in Invoice table
        invoice = Invoice(invoice_type=Invoice.TYPE_OUT, branch=main_branch)
        invoice.invoice_number = 123
        step.invoice_number.update(123)
        self.assertInvalid(step, ['invoice_number'])
        self.assertNotSensitive(wizard, ['next_button'])

        step.invoice_number.update(1)
        self.assertValid(step, ['invoice_number'])
        invoice.branch = self.create_branch()
        step.invoice_number.update(123)
        self.assertValid(step, ['invoice_number'])
        self.assertSensitive(wizard, ['next_button'])
Beispiel #32
0
    def test_sale_return_report(self):
        today = datetime.date(2013, 1, 1)

        client = self.create_client()

        # new sale
        sale = self.create_sale(branch=get_current_branch(self.store))
        sale.identifier = 123
        sale.client = client
        sale.open_date = today
        sale.discount_value = Decimal('15')
        sale.surcharge_value = Decimal('8')

        # Product
        item_ = self.create_sale_item(sale, product=True)
        self.create_storable(item_.sellable.product, sale.branch, 1)

        # Payments
        payment = self.add_payments(sale, date=today)[0]
        payment.identifier = 999
        payment.group.payer = client.person

        sale.order()
        sale.confirm()
        sale.group.pay()

        sale.confirm_date = today
        payment.paid_date = today

        date = datetime.date(2013, 2, 2)

        # return sale
        returned_sale = sale.create_sale_return_adapter()
        returned_sale.return_()
        returned_sale.return_date = date

        model = self.store.find(SaleView,
                                SaleView.id == returned_sale.sale.id).one()

        returned_items = list(ReturnedSaleItemsView.find_by_sale(self.store,
                                                                 sale))

        self._diff_expected(SaleReturnReport, 'sale-return-report', self.store,
                            client, model, returned_items)
Beispiel #33
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'

        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'

        # 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()
Beispiel #34
0
def load_taxes_csv():
    """ Load the fields of IBPT table.

    - Fields:
        - ncm: Nomenclatura Comum do Sul.
        - ex: Exceção fiscal da NCM.
        - tipo: Código que pertence a uma NCM.
        - descricao: Nome do produto.
        - nacionalfederal: Carga tributária para os produtos nacionais.
        - importadosfederal: Carga tributária para os produtos importados.
        - estadual: Carga tributária estadual
        - municipal: Carga tributária municipal
        - vigenciainicio: Data de início da vigência desta alíquota.
        - vigenciafim: Data de fim da vigência desta alíquota.
        - chave: Chave que associa a Tabela IBPT baixada com a empresa.
        - versao: Versão das alíquotas usadas para cálculo.
        - Fonte: Fonte
    """

    # Avoid load taxes more than once.
    if taxes_data:
        return

    store = new_store()
    branch = get_current_branch(store)
    address = branch.person.get_main_address()
    state = address.city_location.state

    # Change the version according to the updates of IBPT tables.
    version = '16.1.A'
    filename = environ.get_resource_filename(
        'stoq', 'csv', 'ibpt_tables',
        'TabelaIBPTax%s%s.csv' % (state, version))
    csv_file = (csv.reader(open(filename, "r"), delimiter=';'))

    for (ncm, ex, tipo, descricao, nacionalfederal, importadosfederal,
         estadual, municipal, vigenciainicio, vigenciafim, chave, versao,
         fonte) in csv_file:
        # Ignore service codes (NBS - Nomenclatura Brasileira de Serviços)
        if tipo == '1':
            continue
        tax_dict = taxes_data.setdefault(ncm, {})
        tax_dict[ex] = TaxInfo(nacionalfederal, importadosfederal, estadual,
                               fonte, chave)
Beispiel #35
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)
Beispiel #36
0
    def test_sync_stock(self):
        loan = self.create_loan()
        product = self.create_product()
        branch = get_current_branch(self.store)
        storable = self.create_storable(product, branch, 4)
        loan.branch = branch
        initial = storable.get_balance_for_branch(branch)
        sellable = product.sellable

        # creates a loan with 4 items of the same product
        quantity = 4
        loan_item = loan.add_sellable(sellable, quantity=quantity, price=10)
        loan_item.sync_stock()
        self.assertEqual(loan_item.quantity, quantity)
        self.assertEqual(loan_item.return_quantity, 0)
        self.assertEqual(loan_item.sale_quantity, 0)
        # The quantity loaned items should be removed from stock
        self.assertEqual(
            storable.get_balance_for_branch(branch),
            initial - quantity)

        # Sell one of the loaned items and return one item (leaving 2 in the
        # loan)
        loan_item.return_quantity = 1
        loan_item.sale_quantity = 1
        loan_item.sync_stock()
        self.assertEqual(loan_item.quantity, quantity)
        self.assertEqual(loan_item.return_quantity, 1)
        self.assertEqual(loan_item.sale_quantity, 1)
        # The return_quantity should be returned to the stock
        self.assertEqual(
            storable.get_balance_for_branch(branch),
            initial - quantity + loan_item.return_quantity)

        # Return the 2 remaining products in this loan.
        loan_item.return_quantity += 2
        loan_item.sync_stock()
        self.assertEqual(loan_item.quantity, quantity)
        self.assertEqual(loan_item.return_quantity, 3)
        self.assertEqual(loan_item.sale_quantity, 1)
        # The return_quantity should be returned to the stock
        self.assertEqual(
            storable.get_balance_for_branch(branch),
            initial - quantity + loan_item.return_quantity)
Beispiel #37
0
    def test_confirm_order(self, new_store, confirm):
        new_store.return_value = self.store

        sale = self.create_sale(branch=get_current_branch(self.store))
        self.add_product(sale)
        sale.status = Sale.STATUS_ORDERED

        app = self.create_app(TillApp, u'till')

        app.status_filter.select(Sale.STATUS_ORDERED)

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

        with mock.patch.object(self.store, 'commit'):
            with mock.patch.object(self.store, 'close'):
                self.activate(app.Confirm)
                confirm.assert_called_once_with(
                    sale, self.store, subtotal=decimal.Decimal("10.00"))
Beispiel #38
0
    def testAddSoldQuantity(self):
        sale = self.create_sale()
        sellable = self.create_sellable()
        product = sellable.product
        branch = get_current_branch(self.store)
        self.create_storable(product, branch, 100)
        sale_item = sale.add_sellable(sellable, quantity=5)

        method = PaymentMethod.get_by_name(self.store, u'money')
        method.create_payment(Payment.TYPE_IN, sale.group, sale.branch,
                              sale.get_sale_subtotal())

        self.failIf(self.store.find(ProductHistory, sellable=sellable).one())
        sale.order()
        sale.confirm()
        prod_hist = self.store.find(ProductHistory, sellable=sellable).one()
        self.failUnless(prod_hist)
        self.assertEqual(prod_hist.quantity_sold, 5)
        self.assertEqual(prod_hist.quantity_sold, sale_item.quantity)
Beispiel #39
0
    def __init__(self, filename, payments_list, salesperson_name,
                 *args, **kwargs):
        branch = get_current_branch(get_default_store()).get_description()
        self.payments_list = payments_list
        if salesperson_name:
            singular = _("payment for {salesperson} on branch {branch}").format(
                salesperson=salesperson_name, branch=branch)
            plural = _("payments for {salesperson} on branch {branch}").format(
                salesperson=salesperson_name, branch=branch)
        else:
            singular = _("payment on branch %s") % branch
            plural = _("payments on branch %s") % branch

        self.main_object_name = (singular, plural)
        self.landscape = (salesperson_name is None)
        self._sales_person = salesperson_name

        TableReport.__init__(self, filename, payments_list,
                             self.title, *args, **kwargs)
Beispiel #40
0
    def test_cancel_inventory(self, new_store, yesno):
        new_store.return_value = self.store
        yesno.return_value = True

        self.create_inventory(branch=get_current_branch(self.store))

        app = self.create_app(InventoryApp, u'inventory')

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

        with mock.patch.object(self.store, 'commit'):
            with mock.patch.object(self.store, 'close'):
                self.activate(app.Cancel)
                yesno.assert_called_once_with(
                    u'Are you sure you want to cancel '
                    u'this inventory ?', Gtk.ResponseType.NO,
                    u"Cancel inventory", u"Don't cancel")
                self.assertEqual(results[0].status, Inventory.STATUS_CANCELLED)
Beispiel #41
0
    def collect_sale_models(self, sale):
        models = [sale, sale.group, sale.invoice]
        models.extend(sale.payments)
        branch = get_current_branch(self.store)

        def _cmp(a, b):
            return cmp(a.sellable.description, b.sellable.description)

        for item in sorted(sale.get_items(), key=functools.cmp_to_key(_cmp)):
            models.append(item.sellable)
            stock_item = item.sellable.product_storable.get_stock_item(
                branch, batch=item.batch)
            models.append(stock_item)
            models.append(item)
        payments = list(sale.payments)
        if len(payments):
            p = payments[0]
            p.description = p.description.rsplit(u' ', 1)[0]
        return models
Beispiel #42
0
    def test_installments_commission_amount_when_sale_return(self):
        if True:
            raise SkipTest(
                u"See stoqlib.domain.returnedsale.ReturnedSale.return_ "
                u"and bug 5215.")

        self._payComissionWhenConfirmed()
        sale = self.create_sale()
        sellable = self.create_sellable()
        CommissionSource(sellable=sellable,
                         direct_value=12,
                         installments_value=5,
                         store=self.store)

        sale.add_sellable(sellable, quantity=3, price=300)
        product = sellable.product
        branch = get_current_branch(self.store)
        self.create_storable(product, branch, 100)

        sale.order()
        method = PaymentMethod.get_by_name(self.store, u'check')
        payment1 = method.create_payment(Payment.TYPE_IN, sale.group,
                                         sale.branch, Decimal(300))
        payment2 = method.create_payment(Payment.TYPE_IN, sale.group,
                                         sale.branch, Decimal(450))
        payment3 = method.create_payment(Payment.TYPE_IN, sale.group,
                                         sale.branch, Decimal(150))
        sale.confirm()

        # the commissions are created after the payment
        payment1.pay()
        payment2.pay()
        payment3.pay()

        returned_sale = sale.create_sale_return_adapter()
        returned_sale.return_()
        self.assertEqual(sale.status, Sale.STATUS_RETURNED)

        commissions = self.store.find(Commission, sale=sale)
        value = sum([c.value for c in commissions])
        self.assertEqual(value, Decimal(0))
        self.assertEqual(commissions.count(), 4)
        self.assertFalse(commissions[-1].value >= 0)
Beispiel #43
0
    def test_same_branch(self):
        branch = get_current_branch(self.store)
        product = self.create_product(branch=branch, stock=10)

        editor = ProductStockQuantityEditor(self.store, product, branch)
        # Using set_text because update() will not show the validation
        editor.quantity.set_text('-4')
        editor.reason.update('test')
        # Do not let the user decrease stock to a negative number
        self.assertInvalid(editor, ['quantity'])

        # Let the user decrease stock
        editor.quantity.update(9)
        self.assertValid(editor, ['quantity'])

        # Let the user increase stock
        editor.quantity.update(11)
        self.assertValid(editor, ['quantity'])
        self.click(editor.main_dialog.ok_button)
Beispiel #44
0
    def test_run_dialogs(self):
        inventory = self.create_inventory(branch=get_current_branch(self.store))

        app = self.create_app(InventoryApp, u'inventory')

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

        self._check_run_dialog(app.AdjustAction,
                               ProductsAdjustmentDialog, [inventory])

        results.select(results[0])
        self._check_run_dialog(app.CountingAction,
                               ProductCountingDialog, [inventory])

        branches = list(self.store.find(Branch))
        branches.remove(inventory.branch)
        self._check_run_dialog(app.NewInventory,
                               OpenInventoryDialog, [branches])
Beispiel #45
0
    def test_return_sale(self, new_store, return_sale):
        new_store.return_value = self.store

        with self.sysparam(ALLOW_CANCEL_CONFIRMED_SALES=True):
            sale = self.create_sale(branch=get_current_branch(self.store))
            self.add_product(sale)
            sale.status = Sale.STATUS_ORDERED

            app = self.create_app(TillApp, u'till')
            app.status_filter.select(Sale.STATUS_ORDERED)

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

            with mock.patch.object(self.store, 'commit'):
                with mock.patch.object(self.store, 'close'):
                    self.activate(app.Return)
                    return_sale.assert_called_once_with(
                        app.get_toplevel(), results[0].sale, self.store)
Beispiel #46
0
    def test_edit_component(self, run_dialog):
        run_dialog.return_value = None
        component = self.create_product_component()
        component.component.sellable.code = u'4567'
        branch = get_current_branch(self.store)
        self.create_storable(component.product,
                             branch=branch,
                             stock=1,
                             unit_cost=10)

        editor = ProductionProductEditor(self.store, component.product)
        editor.code.update("12345")
        compslave = editor.component_slave
        compslave.component_combo.select_item_by_data(component.component)
        self.click(compslave.add_button)

        self.assertEquals(run_dialog.call_count, 1)

        self.check_editor(editor, 'editor-product-prod-edit')
Beispiel #47
0
    def test_sale_order_report(self):
        # Simple sellable
        product = self.create_product(price=100)
        sellable = product.sellable
        sellable.unit = self.create_sellable_unit(description=u'UN')
        default_date = datetime.date(2007, 1, 1)

        # Package sellable
        package = self.create_product(description=u'Package', is_package=True)

        first_component = self.create_product(description=u'First Component', stock=50)
        second_component = self.create_product(description=u'Second Component',
                                               stock=50, price=20)
        p_first_component = self.create_product_component(product=package,
                                                          component=first_component,
                                                          component_quantity=2, price=15)
        p_second_component = self.create_product_component(product=package,
                                                           component=second_component,
                                                           price=10)

        # Sale
        sale = self.create_sale()
        sale.open_date = default_date
        # workaround to make the sale order number constant.
        sale.identifier = 9090

        sale.add_sellable(sellable, quantity=1)

        parent = sale.add_sellable(package.sellable, quantity=2)
        parent.price = 0
        sale.add_sellable(first_component.sellable,
                          quantity=parent.quantity * p_first_component.quantity,
                          price=p_first_component.price,
                          parent=parent)
        sale.add_sellable(second_component.sellable,
                          quantity=parent.quantity * p_second_component.quantity,
                          price=p_second_component.price,
                          parent=parent)

        self.create_storable(product, get_current_branch(self.store), stock=100)
        sale.order(self.current_user)
        self._diff_expected(SaleOrderReport, 'sale-order-report', sale)
Beispiel #48
0
    def test_booklet_with_sale_pdf(self):
        due_dates = [
            datetime.datetime(2012, 1, 5),
            datetime.datetime(2012, 2, 5),
            datetime.datetime(2012, 3, 5),
            datetime.datetime(2012, 4, 5),
            datetime.datetime(2012, 5, 5),
        ]
        items = [
            (u"Batata", 2, decimal.Decimal('10')),
            (u"Tomate", 3, decimal.Decimal('15.5')),
            (u"Banana", 1, decimal.Decimal('5.25')),
        ]

        client = self.create_client()
        client.credit_limit = decimal.Decimal('100000')
        address = self.create_address()
        address.person = client.person

        sale = self.create_sale(client=client,
                                branch=get_current_branch(self.store))
        for description, quantity, price in items:
            sellable = self.add_product(sale, price, quantity)
            sellable.description = description

        sale.order(self.current_user)
        method = PaymentMethod.get_by_name(self.store, u'store_credit')
        method.max_installments = 12
        method.create_payments(sale.branch,
                               sale.station,
                               Payment.TYPE_IN,
                               sale.group,
                               value=sale.get_total_sale_amount(),
                               due_dates=due_dates)
        sale.confirm(self.current_user)
        sale.identifier = 123

        for i, payment in enumerate(sale.group.payments):
            payment.identifier = 66 + i

        self._diff_expected(BookletReport, 'booklet-with-sale',
                            sale.group.payments)
Beispiel #49
0
    def test_can_close(self):
        sellable = self.create_sellable()
        branch = get_current_branch(self.store)
        storable = self.create_storable(sellable.product, branch, 0)
        # There's a storable, but we can still close because there's no stock
        self.assertTrue(sellable.can_close())

        storable.increase_stock(1, branch,
                                StockTransactionHistory.TYPE_INITIAL, None)
        # Now that there's stock we should not be able to close anymore
        self.assertFalse(sellable.can_close())

        storable.decrease_stock(1, branch,
                                StockTransactionHistory.TYPE_INITIAL, None)
        # But decreasing the stock should make it possible to close again
        self.assertTrue(sellable.can_close())

        # The delivery service cannot be closed.
        sellable = sysparam.get_object(self.store, 'DELIVERY_SERVICE').sellable
        self.assertFalse(sellable.can_close())
    def _create_domain(self):
        self.today = datetime.date.today()

        branch = get_current_branch(self.store)

        product = self.create_product()
        storable = Storable(store=self.store, product=product)
        self.create_product_stock_item(
            storable=storable, branch=branch, quantity=2)
        product.sellable.code = u'1'
        product.sellable.description = u'Luvas'
        product.sellable.status = Sellable.STATUS_CLOSED

        product = self.create_product()
        storable = Storable(store=self.store, product=product)
        self.create_product_stock_item(
            storable=storable, branch=branch, quantity=4)
        product.sellable.code = u'2'
        product.sellable.description = u'Botas'
        product.sellable.status = Sellable.STATUS_CLOSED
Beispiel #51
0
 def _create_fiscal_entry(cls,
                          store,
                          entry_type,
                          group,
                          cfop,
                          invoice_number,
                          iss_value=0,
                          icms_value=0,
                          ipi_value=0):
     return FiscalBookEntry(entry_type=entry_type,
                            iss_value=iss_value,
                            ipi_value=ipi_value,
                            icms_value=icms_value,
                            invoice_number=invoice_number,
                            cfop=cfop,
                            drawee=group.recipient,
                            branch=get_current_branch(store),
                            date=TransactionTimestamp(),
                            payment_group=group,
                            store=store)
Beispiel #52
0
    def _create_domain(self):
        branch = get_current_branch(self.store)

        product = self.create_product()
        storable = Storable(store=self.store, product=product)
        self.create_product_stock_item(storable=storable,
                                       branch=branch,
                                       quantity=2)
        product.brand = u''
        product.sellable.code = u'1'
        product.sellable.description = u'Luvas'

        product2 = self.create_product()
        storable2 = Storable(store=self.store, product=product2)
        self.create_product_stock_item(storable=storable2,
                                       branch=branch,
                                       quantity=4)
        product2.brand = u'brand'
        product.sellable.code = u'2'
        product.sellable.description = u'Botas'
Beispiel #53
0
    def test_sales_person_report(self):
        sysparam.set_bool(self.store, 'SALE_PAY_COMMISSION_WHEN_CONFIRMED',
                          True)
        salesperson = self.create_sales_person()
        product = self.create_product(price=100)
        sellable = product.sellable

        sale = self.create_sale()
        sale.salesperson = salesperson
        sale.add_sellable(sellable, quantity=1)

        self.create_storable(product,
                             get_current_branch(self.store),
                             stock=100)

        CommissionSource(sellable=sellable,
                         direct_value=Decimal(10),
                         installments_value=1,
                         store=self.store)

        sale.order(self.current_user)

        method = PaymentMethod.get_by_name(self.store, u'money')
        method.create_payment(sale.branch, sale.station, Payment.TYPE_IN,
                              sale.group, sale.get_sale_subtotal())
        sale.confirm(self.current_user)
        sale.group.pay()

        salesperson = salesperson
        commissions = list(self.store.find(CommissionView))
        commissions[0].identifier = 1
        commissions[1].identifier = 139

        self._diff_expected(SalesPersonReport, 'sales-person-report',
                            commissions, salesperson)

        # Also test when there is no salesperson selected
        self._diff_expected(SalesPersonReport,
                            'sales-person-report-without-salesperson',
                            commissions, None)
Beispiel #54
0
    def test_run_dialogs(self):
        inventory = self.create_inventory(
            branch=get_current_branch(self.store))

        app = self.create_app(InventoryApp, u'inventory')

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

        self._check_run_dialog(app.AdjustAction, InventoryAdjustmentEditor,
                               [inventory])

        with mock.patch.object(results[0],
                               'all_items_counted',
                               new=lambda: False):
            results.select(results[0])
            self._check_run_dialog(app.CountingAction, InventoryCountWizard,
                                   [inventory])

        inventory.close()
        app._update_widgets()
        self._check_run_dialog(app.NewInventory, InventoryOpenEditor, [])
Beispiel #55
0
def get_missing_items(order, store):
    """
    Fetch missing items, the returning object has the following attributes set:

      - storable: A |storable| for the missing item;
      - description: A description for the missing item;
      - ordered: The quantity ordered of the missing item;
      - stock: The stock available of the missing item.

    :returns: a list of Settable items with the attributes mentioned above
    """
    # Lets confirm that we can create the sale, before opening the coupon
    prod_sold = {}
    prod_desc = {}
    for item in order.get_items():
        # Skip services, since we don't need stock to sell.
        if isinstance(item, SaleItem) and item.is_service():
            continue
        storable = item.sellable.product_storable
        # There are some products that we dont control the stock
        if not storable:
            continue
        prod_sold.setdefault(storable, 0)
        prod_sold[storable] += item.quantity
        if isinstance(item, SaleItem):
            prod_sold[storable] -= item.quantity_decreased
        prod_desc[storable] = item.sellable.get_description()

    branch = get_current_branch(store)
    missing = []
    for storable in prod_sold.keys():
        stock = storable.get_balance_for_branch(branch)
        if stock < prod_sold[storable]:
            missing.append(
                Settable(storable=storable,
                         description=prod_desc[storable],
                         ordered=prod_sold[storable],
                         stock=stock))
    return missing
    def test_penalty_and_interest(self):
        sale = self.create_sale()
        sale_item = self.create_sale_item(sale=sale)
        self.create_storable(sale_item.sellable.product,
                             get_current_branch(self.store), 10)

        payment = self.create_payment(payment_type=Payment.TYPE_OUT,
                                      value=100,
                                      date=localtoday().date() -
                                      datetime.timedelta(5))

        sale.group = payment.group

        sale.order()

        payment.method.daily_interest = 1
        payment.method.penalty = 1

        slave = PurchasePaymentConfirmSlave(self.store, [payment])

        # Penalty and interest enabled
        self.assertEqual(slave.penalty.read(), currency('1'))
        self.assertEqual(slave.interest.read(), currency('5.05'))

        # Penalty disabled and interest enabled
        self.click(slave.pay_penalty)
        self.assertEqual(slave.penalty.read(), currency('0'))
        self.assertEqual(slave.interest.read(), currency('5'))

        # Penalty enabled and interest disabled
        self.click(slave.pay_penalty)
        self.click(slave.pay_interest)
        self.assertEqual(slave.penalty.read(), currency('1'))
        self.assertEqual(slave.interest.read(), currency('0'))

        # Penalty and interest disabled
        self.click(slave.pay_penalty)
        self.assertEqual(slave.penalty.read(), currency('0'))
        self.assertEqual(slave.interest.read(), currency('0'))
Beispiel #57
0
    def testGetClientCreditTransactions(self):
        method = self.store.find(PaymentMethod, method_name=u'credit').one()
        client = self.create_client()
        sale = self.create_sale(client=client)
        self.add_product(sale)
        self.add_payments(sale)
        sale.order()
        sale.confirm()

        returned_sale = ReturnedSale(sale=sale,
                                     branch=get_current_branch(self.store),
                                     store=self.store)
        ReturnedSaleItem(sale_item=list(sale.get_items())[0],
                         quantity=1,
                         returned_sale=returned_sale,
                         store=self.store)
        sale.return_(returned_sale)
        payment = self.create_payment(payment_type=Payment.TYPE_OUT,
                                      value=100,
                                      method=method,
                                      group=sale.group)
        payment.set_pending()
        payment.pay()

        payment_settable = Settable(identifier=payment.identifier,
                                    date=payment.paid_date,
                                    description=payment.description,
                                    value=Decimal(payment.paid_value))

        payment_domain_list = list(client.get_credit_transactions())
        self.assertTrue(len(payment_domain_list) == 1)

        payment_domain = payment_domain_list[0]
        self.assertEquals(payment_settable.identifier,
                          payment_domain.identifier)
        self.assertEquals(payment_settable.date, payment_domain.date)
        self.assertEquals(payment_settable.description,
                          payment_domain.description)
        self.assertEquals(payment_settable.value, payment_domain.value)
Beispiel #58
0
    def testSalesPersonReport(self):
        sysparam(self.store).SALE_PAY_COMMISSION_WHEN_CONFIRMED = 1
        salesperson = self.create_sales_person()
        product = self.create_product(price=100)
        sellable = product.sellable

        sale = self.create_sale()
        sale.salesperson = salesperson
        sale.add_sellable(sellable, quantity=1)

        self.create_storable(product,
                             get_current_branch(self.store),
                             stock=100)

        CommissionSource(sellable=sellable,
                         direct_value=Decimal(10),
                         installments_value=1,
                         store=self.store)

        sale.order()

        method = PaymentMethod.get_by_name(self.store, u'money')
        till = Till.get_last_opened(self.store)
        method.create_payment(Payment.TYPE_IN,
                              sale.group,
                              sale.branch,
                              sale.get_sale_subtotal(),
                              till=till)
        sale.confirm()
        sale.group.pay()

        salesperson_name = salesperson.person.name
        commissions = list(self.store.find(CommissionView))
        commissions[0].identifier = 1
        commissions[1].identifier = 139

        self._diff_expected(SalesPersonReport, 'sales-person-report',
                            commissions, salesperson_name)
Beispiel #59
0
    def test_return_on_another_branch(self, gcb):
        # Branch where the sale was created
        sale_branch = get_current_branch(self.store)
        # Branch where the sale was returned
        return_branch = self.create_branch()
        gcb.return_value = return_branch

        product = self.create_product(branch=sale_branch, stock=2)
        client = self.create_client()
        # Creating a sale on sale_branch
        sale = self.create_sale(branch=sale_branch, client=client)
        sale_item = sale.add_sellable(sellable=product.sellable)

        # Adding payments and confirming the sale
        payments = self.add_payments(sale, method_type=u'bill',
                                     installments=2)
        payments[0].status = Payment.STATUS_PENDING
        self.add_payments(sale, method_type=u'money')
        sale.order()
        sale.confirm()

        # Creating the returned_sale
        rsale = ReturnedSale(branch=return_branch,
                             sale=sale,
                             store=self.store)
        ReturnedSaleItem(store=self.store,
                         returned_sale=rsale,
                         sale_item=sale_item,
                         quantity=1)

        rsale.return_(u'credit')
        # Checking the status of sale and returned_sale
        self.assertEquals(rsale.status, ReturnedSale.STATUS_PENDING)
        self.assertEquals(sale.status, Sale.STATUS_RETURNED)
        # Checking the quantity on sale_branch
        self.assertEquals(product.storable.get_balance_for_branch(sale_branch), 1)
        # We should not increase the stock of that product on return_branch
        self.assertEquals(product.storable.get_balance_for_branch(return_branch), 0)
Beispiel #60
0
    def test_initial_stock(self):
        branch = get_current_branch(self.store)
        product = self.create_product(branch=branch, storable=False)
        product.manage_stock = False
        editor = ProductStockQuantityEditor(self.store, product, branch)
        self.check_editor(editor, 'editor-product-stock-quantity-initial-show')

        # Update editor
        editor.quantity.update(15)
        editor.cost.update('3.45')

        stock_items_before = self.store.find(ProductStockItem).count()

        # Confirm
        self.click(editor.main_dialog.ok_button)

        # Check data
        stock_items_after = self.store.find(ProductStockItem).count()
        self.assertEquals(stock_items_after, stock_items_before + 1)

        stock_item = product.storable.get_stock_item(branch, batch=None)
        self.assertEquals(stock_item.quantity, 15)
        self.assertEquals(stock_item.stock_cost, Decimal('3.45'))