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"))
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"))
def test_pay_money_payments(self): branch = self.create_branch() group = self.create_payment_group() method = PaymentMethod.get_by_name(self.store, u'bill') payment1 = method.create_payment(Payment.TYPE_IN, group, branch, Decimal(10)) payment2 = method.create_payment(Payment.TYPE_IN, group, branch, Decimal(10)) method = PaymentMethod.get_by_name(self.store, u'money') method.max_installments = 2 payment3 = method.create_payment(Payment.TYPE_IN, group, branch, Decimal(10)) payment4 = method.create_payment(Payment.TYPE_IN, group, branch, Decimal(10)) group.confirm() self.assertEqual(payment1.status, Payment.STATUS_PENDING) self.assertEqual(payment2.status, Payment.STATUS_PENDING) self.assertEqual(payment3.status, Payment.STATUS_PENDING) self.assertEqual(payment4.status, Payment.STATUS_PENDING) payment3.pay() self.assertEqual(payment3.status, Payment.STATUS_PAID) group.pay_method_payments(u'money') self.assertEqual(payment1.status, Payment.STATUS_PENDING) self.assertEqual(payment2.status, Payment.STATUS_PENDING) self.assertEqual(payment3.status, Payment.STATUS_PAID) self.assertEqual(payment4.status, Payment.STATUS_PAID)
def test_get_payment_by_method_name(self): group = self.create_payment_group() method = PaymentMethod.get_by_name(self.store, u'money') money_payment1 = self.create_payment(method=method) group.add_item(money_payment1) money_payment2 = self.create_payment(method=method) group.add_item(money_payment2) method = PaymentMethod.get_by_name(self.store, u'check') check_payment1 = self.create_payment(method=method) group.add_item(check_payment1) check_payment2 = self.create_payment(method=method) group.add_item(check_payment2) money_payments = group.get_payments_by_method_name(u'money') for payment in [money_payment1, money_payment2]: self.assertTrue(payment in money_payments) for payment in [check_payment1, check_payment2]: self.assertFalse(payment in money_payments) check_payments = group.get_payments_by_method_name(u'check') for payment in [check_payment1, check_payment2]: self.assertTrue(payment in check_payments) for payment in [money_payment1, money_payment2]: self.assertFalse(payment in check_payments)
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)
def test_till_daily_movement(self): date = datetime.date(2013, 1, 1) # create sale payment sale = self.create_sale() sellable = self.create_sellable() sale.add_sellable(sellable, price=100) sale.identifier = 1000 sale.order() method = PaymentMethod.get_by_name(self.store, u'money') till = Till.get_last_opened(self.store) payment = method.create_payment(Payment.TYPE_IN, sale.group, sale.branch, sale.get_sale_subtotal(), till=till) sale.confirm() sale.group.pay() sale.confirm_date = date payment.identifier = 1010 payment.paid_date = date # create lonely input payment payer = self.create_client() address = self.create_address() address.person = payer.person method = PaymentMethod.get_by_name(self.store, u'money') group = self.create_payment_group() branch = self.create_branch() payment_lonely_input = method.create_payment(Payment.TYPE_IN, group, branch, Decimal(100)) payment_lonely_input.description = u"Test receivable account" payment_lonely_input.group.payer = payer.person payment_lonely_input.set_pending() payment_lonely_input.pay() payment_lonely_input.identifier = 1001 payment_lonely_input.paid_date = date # create purchase payment drawee = self.create_supplier() address = self.create_address() address.person = drawee.person method = PaymentMethod.get_by_name(self.store, u'money') group = self.create_payment_group() branch = self.create_branch() payment = method.create_payment(Payment.TYPE_OUT, group, branch, Decimal(100)) payment.description = u"Test payable account" payment.group.recipient = drawee.person payment.set_pending() payment.pay() payment.identifier = 1002 payment.paid_date = date # create lonely output payment self._diff_expected(TillDailyMovementReport, 'till-daily-movement-report', self.store, date)
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())
def test_create(self): wizard = PurchaseWizard(self.store) method = PaymentMethod.get_by_name(self.store, u"card") order = self.create_purchase_order() slave = CardMethodSlave(wizard, None, self.store, order, method, Decimal(200)) self.check_slave(slave, "slave-card-method")
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)
def _create_payment(self): group = PaymentGroup() group.payer = self.client.person method = PaymentMethod.get_by_name(self.store, u'credit') branch = api.get_current_branch(self.store) if self.model.value < 0: payment_type = Payment.TYPE_IN else: payment_type = Payment.TYPE_OUT # Set status to PENDING now, to avoid calling set_pending on # on_confirm for payments that shoud not have its status changed. payment = Payment(store=self.store, open_date=localtoday(), branch=branch, station=api.get_current_station(self.store), status=Payment.STATUS_PENDING, description=self.model.description, value=abs(self.model.value), base_value=abs(self.model.value), due_date=localtoday(), method=method, group=group, category=None, payment_type=payment_type, bill_received=False) payment.pay() return payment
def _auto_confirm_sale_wizard_with_store_credit(self, wizard, app, store, sale, subtotal, total_paid, current_document): sale.client = self._create_client(store) payment_method = PaymentMethod.get_by_name(store, u'store_credit') return self._auto_confirm_sale(wizard, app, store, sale, subtotal, total_paid, payment_method)
def test_sale_payment_reserved(self): sale = self.create_sale() sale.identifier = 12345 self.add_product(sale, price=100) method = PaymentMethod.get_by_name(self.store, u'check') p1 = method.create_payment( Payment.TYPE_IN, sale.group, sale.branch, 50) p2 = method.create_payment( Payment.TYPE_IN, sale.group, sale.branch, 50) for p in [p1, p2]: p.set_pending() p.due_date = localdatetime(2013, 1, 1) # Pay only one payment so there are 50 paid and 50 confirmed # (waiting to be paid) totalizing in 100 that's the total here. p1.pay(paid_date=localdatetime(2013, 1, 2)) total_paid = sale.group.get_total_confirmed_value() self._create_wizard(sale=sale, total_paid=total_paid) self._check_wizard('wizard-sale-payment-reserved') self.assertNotVisible(self.step, ['select_method_holder', 'subtotal_expander']) self._go_to_next() # Make sure no payments were created self.assertEqual(set(sale.payments), set([p1, p2]))
def test_has_late_payments(self): client = self.create_client() today = localtoday().date() method = PaymentMethod.get_by_name(self.store, u'bill') # client does not have any payments self.assertFalse(InPaymentView.has_late_payments(self.store, client.person)) # client has payments that are not overdue payment = self.create_payment(Payment.TYPE_IN, today + relativedelta(days=1), method=method) payment.group = self.create_payment_group() payment.group.payer = client.person self.assertFalse(InPaymentView.has_late_payments(self.store, client.person)) # client has overdue payments payment = self.create_payment(Payment.TYPE_IN, today - relativedelta(days=2), method=method) payment.status = Payment.STATUS_PENDING payment.group = self.create_payment_group() payment.group.payer = client.person self.assertTrue(InPaymentView.has_late_payments(self.store, client.person))
def test_has_late_payments(self): client = self.create_client() today = localtoday().date() method = PaymentMethod.get_by_name(self.store, u'bill') # client does not have any payments self.assertFalse(InPaymentView.has_late_payments(self.store, client.person)) # client has payments that are not overdue payment = self.create_payment(Payment.TYPE_IN, today + relativedelta(days=1), method=method) payment.group = self.create_payment_group() payment.group.payer = client.person self.assertFalse(InPaymentView.has_late_payments(self.store, client.person)) # client has overdue payments payment = self.create_payment(Payment.TYPE_IN, today - relativedelta(days=2), method=method) payment.status = Payment.STATUS_PENDING payment.group = self.create_payment_group() payment.group.payer = client.person self.assertTrue(InPaymentView.has_late_payments(self.store, client.person))
def test_get_total_value(self): method = PaymentMethod.get_by_name(self.store, u'check') # Test for a group in a sale # On sale's group, total value should return # sum(inpayments.value) - sum(outpayments.value) sale = self.create_sale() group = sale.group self.assertEqual(group.get_total_value(), 0) method.create_payment(Payment.TYPE_IN, group, sale.branch, Decimal(100)) self.assertEqual(group.get_total_value(), Decimal(100)) method.create_payment(Payment.TYPE_IN, group, sale.branch, Decimal(200)) self.assertEqual(group.get_total_value(), Decimal(300)) method.create_payment(Payment.TYPE_OUT, group, sale.branch, Decimal(50)) self.assertEqual(group.get_total_value(), Decimal(250)) # Test for a group in a purchase # On purchase's group, total value should return # sum(inpayments.value) - sum(outpayments.value) purchase = self.create_purchase_order() group = purchase.group self.assertEqual(group.get_total_value(), 0) method.create_payment(Payment.TYPE_OUT, group, purchase.branch, Decimal(100)) self.assertEqual(group.get_total_value(), Decimal(100)) method.create_payment(Payment.TYPE_OUT, group, purchase.branch, Decimal(200)) self.assertEqual(group.get_total_value(), Decimal(300)) method.create_payment(Payment.TYPE_IN, group, purchase.branch, Decimal(50)) self.assertEqual(group.get_total_value(), Decimal(250))
def createInPayments(self, no=3): sale = self.create_sale() d = datetime.datetime.today() method = PaymentMethod.get_by_name(self.store, self.method_type) payments = method.create_inpayments(sale.group, sale.branch, Decimal(100), [d] * no) return payments
def _create_outpayment(self): purchase = self.create_purchase_order() sellable = self.create_sellable() purchase.add_item(sellable, 1) method = PaymentMethod.get_by_name(self.store, u"bill") payment = method.create_payment(Payment.TYPE_OUT, purchase.group, purchase.branch, Decimal(10)) return payment
def testPartialReturnNotEntirelyPaid(self): sale = self.create_sale() self.failIf(sale.can_return()) self.add_product(sale, price=300) sale.order() self.failIf(sale.can_return()) # Add 3 check payments of 100 each method = PaymentMethod.get_by_name(self.store, u'check') payment1 = method.create_inpayment(sale.group, sale.branch, Decimal(100)) method.create_inpayment(sale.group, sale.branch, Decimal(100)) method.create_inpayment(sale.group, sale.branch, Decimal(100)) sale.confirm() # Pay the first payment. payment = payment1 payment.pay() self.failUnless(sale.can_return()) 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()) returned_amount = 0 for payment in sale.payments: if payment.is_inpayment(): # At this point, inpayments should be either paid or cancelled self.assertTrue(payment.is_paid() or payment.is_cancelled()) if payment.is_outpayment(): returned_amount += payment.value self.assertEqual(payment.value, returned_amount)
def testBank(self): sale = self.create_sale() method = PaymentMethod.get_by_name(self.store, self.method_type) payment = method.create_outpayment(sale.group, sale.branch, Decimal(10)) check_data = method.operation.get_check_data_by_payment(payment) check_data.bank_account.bank_number = 123 self.assertEquals(payment.bank_account_number, 123)
def testPartialReturnNotPaid(self): sale = self.create_sale() self.failIf(sale.can_return()) self.add_product(sale, quantity=2, price=300) sale.order() self.failIf(sale.can_return()) method = PaymentMethod.get_by_name(self.store, u'check') payment = method.create_inpayment(sale.group, sale.branch, Decimal(600)) sale.confirm() self.failUnless(sale.can_return()) returned_sale = sale.create_sale_return_adapter() list(returned_sale.returned_items)[0].quantity = 1 # Mimic what is done on sale return wizard that is to cancel # the existing payment and create another one with the new # total (in this case, 300) method.create_inpayment(sale.group, sale.branch, Decimal(300)) payment.cancel() returned_sale.return_() self.failUnless(sale.can_return()) self.assertEqual(sale.status, Sale.STATUS_CONFIRMED) returned_amount = 0 for payment in sale.payments: if payment.is_outpayment(): returned_amount += payment.value self.assertEqual(returned_amount, currency(0))
def __init__(self, wizard, parent, store, order, payment_method, outstanding_value=currency(0), finish_on_total=True, allow_remove_paid=True): """ :param finish_on_total: finalize the payment when the total value is reached. """ self._has_modified_payments = False self._allow_remove_paid = allow_remove_paid self.finish_on_total = finish_on_total # We need a temporary object to hold the value that will be read from # the user. We will set a proxy with this temporary object to help # with the validation. self._holder = Settable(value=Decimal(0)) self._wizard = wizard # 'money' is the default payment method and it is always avaliable. self._method = PaymentMethod.get_by_name(store, u'money') BaseEditorSlave.__init__(self, store, order) self._outstanding_value = (outstanding_value or self._get_total_amount()) self._total_value = self._outstanding_value self._setup_widgets() self.register_validate_function(self._refresh_next) self.force_validation()
def test_installments_commission_amount_with_multiple_items(self): self._payComissionWhenConfirmed() sale = self.create_sale() sellable = self.add_product(sale, price=300, quantity=3) sale.order() CommissionSource(sellable=sellable, direct_value=12, installments_value=5, store=self.store) method = PaymentMethod.get_by_name(self.store, u'check') method.create_payment(Payment.TYPE_IN, sale.group, sale.branch, Decimal(300)) method.create_payment(Payment.TYPE_IN, sale.group, sale.branch, Decimal(450)) method.create_payment(Payment.TYPE_IN, sale.group, sale.branch, Decimal(150)) self.assertTrue(self.store.find(Commission, sale=sale).is_empty()) sale.confirm() commissions = self.store.find(Commission, sale=sale).order_by(Commission.value) self.assertEquals(commissions.count(), 3) for c in commissions: self.failUnless(c.commission_type == Commission.INSTALLMENTS) # the first payment represent 1/3 of the total amount # 45 / 6 => 7.50 self.assertEquals(commissions[0].value, Decimal("7.50")) # the second payment represent 1/3 of the total amount # 5% of 900: 45,00 * 1/3 => 15,00 self.assertEquals(commissions[1].value, Decimal("15.00")) # the third payment represent 1/2 of the total amount # 45 / 2 => 22,50 self.assertEquals(commissions[2].value, Decimal("22.50"))
def trade(self): """Do a trade for this return Almost the same as :meth:`.return_`, but unlike it, this won't generate reversed payments to the client. Instead, it'll generate an inpayment using :obj:`.returned_total` value, so it can be used as an "already paid quantity" on :obj:`.new_sale`. """ assert self.new_sale if self.sale: assert self.sale.can_return() self._clean_not_used_items() store = self.store group = self.group method = PaymentMethod.get_by_name(store, u'trade') description = _(u'Traded items for sale %s') % ( self.new_sale.identifier, ) value = self.returned_total payment = method.create_payment(Payment.TYPE_IN, group, self.branch, value, description=description) payment.set_pending() payment.pay() self._return_sale(payment)
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)
def _create_inpayment(self): sale = self.create_sale() sellable = self.create_sellable() sale.add_sellable(sellable, price=10) method = PaymentMethod.get_by_name(self.store, u'bill') payment = method.create_payment(Payment.TYPE_IN, sale.group, sale.branch, Decimal(10)) return payment
def undo(self, reason): """Undo this returned sale. This includes removing the returned items from stock again (updating the quantity decreased on the sale). :param reason: The reason for this operation. """ assert self.can_undo() for item in self.get_items(): item.undo() # We now need to create a new in payment for the total amount of this # returned sale. method_name = self._guess_payment_method() method = PaymentMethod.get_by_name(self.store, method_name) description = _(u'%s return undone for sale %s') % ( method.description, self.sale.identifier) payment = method.create_payment(Payment.TYPE_IN, payment_group=self.group, branch=self.branch, value=self.returned_total, description=description) payment.set_pending() payment.pay() self.status = self.STATUS_CANCELLED self.cancel_date = localnow() self.undo_reason = reason # if the sale status is returned, we must reset it to confirmed (only # confirmed sales can be returned) if self.sale.is_returned(): self.sale.set_not_returned()
def createOutPayments(self, no=3): purchase = self.create_purchase_order() d = datetime.datetime.today() method = PaymentMethod.get_by_name(self.store, self.method_type) payments = method.create_outpayments(purchase.group, purchase.branch, Decimal(100), [d] * no) return payments
def test_negative_credit(self): method = PaymentMethod.get_by_name(self.store, u'credit') client = self.create_client() group = self.create_payment_group(payer=client.person) payment = self.create_payment(method=method, payment_type=Payment.TYPE_OUT, value=6, group=group) payment.set_pending() payment.pay() editor = CreditEditor(self.store, client) editor.description.set_text('Desc') editor.value.set_text('-5') self.assertValid(editor, ['value']) self.assertSensitive(editor.main_dialog, ['ok_button']) editor.value.set_text('-6') self.assertValid(editor, ['value']) self.assertSensitive(editor.main_dialog, ['ok_button']) editor.value.set_text('-7') self.assertInvalid(editor, ['value']) self.assertNotSensitive(editor.main_dialog, ['ok_button'])
def __init__(self, wizard, previous, store, consignment, outstanding_value=Decimal(0)): self._method = PaymentMethod.get_by_name(store, u'money') BaseWizardStep.__init__(self, store, wizard, previous=None) self._consignment = consignment self._outstanding_value = outstanding_value self._setup_slaves()
def test_installments_commission_amount(self): self._payComissionWhenConfirmed() sale = self.create_sale() sellable = self.add_product(sale, price=300) sale.order() CommissionSource(sellable=sellable, direct_value=12, installments_value=5, store=self.store) method = PaymentMethod.get_by_name(self.store, u'check') method.create_payment(Payment.TYPE_IN, sale.group, sale.branch, Decimal(100)) method.create_payment(Payment.TYPE_IN, sale.group, sale.branch, Decimal(200)) self.assertTrue(self.store.find(Commission, sale=sale).is_empty()) sale.confirm() self.assertFalse(self.store.find(Commission, sale=sale).is_empty()) commissions = self.store.find(Commission, sale=sale).order_by(Commission.value) self.assertEquals(commissions.count(), 2) for c in commissions: self.failUnless(c.commission_type == Commission.INSTALLMENTS) # the first payment represent 1/3 of the total amount # 5% of 300: 15,00 * 1/3 => 5,00 self.assertEquals(commissions[0].value, Decimal("5.00")) # the second payment represent 2/3 of the total amount # $15 * 2/3 => 10,00 self.assertEquals(commissions[1].value, Decimal("10.00"))
def _create_payment(self): group = PaymentGroup() group.payer = self.client.person method = PaymentMethod.get_by_name(self.store, u'credit') branch = api.get_current_branch(self.store) if self.model.value < 0: payment_type = Payment.TYPE_IN else: payment_type = Payment.TYPE_OUT # Set status to PENDING now, to avoid calling set_pending on # on_confirm for payments that shoud not have its status changed. payment = Payment(open_date=localtoday(), branch=branch, status=Payment.STATUS_PENDING, description=self.model.description, value=abs(self.model.value), base_value=abs(self.model.value), due_date=localtoday(), method=method, group=group, till=None, category=None, payment_type=payment_type, bill_received=False) payment.pay() return payment
def _auto_confirm_sale_wizard_with_store_credit(self, wizard, app, store, sale, subtotal, total_paid, current_document): sale.client = self._create_client(store) payment_method = PaymentMethod.get_by_name(store, u'store_credit') return self._auto_confirm_sale(wizard, app, store, sale, subtotal, total_paid, payment_method)
def _setup_widgets(self): self.remove_button.hide() if isinstance(self.model, (PaymentRenegotiation, Sale, ReturnedSale, StockDecrease)): payment_type = Payment.TYPE_IN elif isinstance(self.model, PurchaseOrder): payment_type = Payment.TYPE_OUT else: raise AssertionError money_method = PaymentMethod.get_by_name(self.store, u'money') self._add_method(money_method) for method in PaymentMethod.get_creatable_methods( self.store, payment_type, separate=False): if method.method_name in [u'multiple', u'money']: continue self._add_method(method) self.payments.set_columns(self._get_columns()) self.payments.add_list(self.model.group.payments) self.total_value.set_bold(True) self.received_value.set_bold(True) self.missing_value.set_bold(True) self.total_value.update(self._total_value) self.remove_button.set_sensitive(False) self._update_values()
def createInPayments(self, no=3): sale = self.create_sale() d = localnow() method = PaymentMethod.get_by_name(self.store, self.method_type) payments = method.create_payments(Payment.TYPE_IN, sale.group, sale.branch, Decimal(100), [d] * no) return payments
def test_sale_payment_reserved(self): sale = self.create_sale() sale.identifier = 12345 self.add_product(sale, price=100) method = PaymentMethod.get_by_name(self.store, u'check') p1 = method.create_payment( Payment.TYPE_IN, sale.group, sale.branch, 50) p2 = method.create_payment( Payment.TYPE_IN, sale.group, sale.branch, 50) for p in [p1, p2]: p.set_pending() p.due_date = localdatetime(2013, 1, 1) # Pay only one payment so there are 50 paid and 50 confirmed # (waiting to be paid) totalizing in 100 that's the total here. p1.pay(paid_date=localdatetime(2013, 1, 2)) total_paid = sale.group.get_total_confirmed_value() self._create_wizard(sale=sale, total_paid=total_paid) self._check_wizard('wizard-sale-payment-reserved') self.assertNotVisible(self.step, ['select_method_holder', 'subtotal_expander']) with mock.patch.object(self.store, 'commit'): self._go_to_next() # Make sure no payments were created self.assertEqual(set(sale.payments), set([p1, p2]))
def test_bank(self): sale = self.create_sale() method = PaymentMethod.get_by_name(self.store, self.method_type) payment = method.create_payment(Payment.TYPE_OUT, sale.group, sale.branch, Decimal(10)) check_data = method.operation.get_check_data_by_payment(payment) check_data.bank_account.bank_number = 123 self.assertEqual(payment.bank_account_number, 123)
def test_create(self): wizard = PurchaseWizard(self.store) method = PaymentMethod.get_by_name(self.store, u'card') order = self.create_purchase_order() slave = CardMethodSlave(wizard, None, self.store, order, method, Decimal(200)) self.check_slave(slave, 'slave-card-method')
def setup_cash_payment(self, total=None): money_method = PaymentMethod.get_by_name(self.store, u'money') total = total or self.wizard.get_total_to_pay() try: return money_method.create_payment(Payment.TYPE_IN, self.model.group, self.model.branch, total) except PaymentMethodError as err: warning(str(err))
def createOutPayments(self, no=3): purchase = self.create_purchase_order() d = localnow() method = PaymentMethod.get_by_name(self.store, self.method_type) payments = method.create_payments(Payment.TYPE_OUT, purchase.group, purchase.branch, Decimal(100), [d] * no) return payments
def createInPayment(self, till=ValueUnset): sale = self.create_sale() method = PaymentMethod.get_by_name(self.store, self.method_type) return method.create_payment(Payment.TYPE_IN, sale.group, sale.branch, Decimal(100), till=till)
def _create_inpayment(self): sale = self.create_sale() sellable = self.create_sellable() sale.add_sellable(sellable, price=10) method = PaymentMethod.get_by_name(self.store, u'bill') payment = method.create_payment(Payment.TYPE_IN, sale.group, sale.branch, Decimal(10)) return payment
def _create_outpayment(self): purchase = self.create_purchase_order() sellable = self.create_sellable() purchase.add_item(sellable, 1) method = PaymentMethod.get_by_name(self.store, u'bill') payment = method.create_payment(Payment.TYPE_OUT, purchase.group, purchase.branch, Decimal(10)) return payment
def createOutPayment(self, till=ValueUnset): purchase = self.create_purchase_order() method = PaymentMethod.get_by_name(self.store, self.method_type) return method.create_payment(Payment.TYPE_OUT, purchase.group, purchase.branch, Decimal(100), till=till)
def return_(self, method_name=u'money', login_user=None): """Do the return of this returned sale. :param unicode method_name: The name of the payment method that will be used to create this payment. If :attr:`.total_amount` is: * > 0, the client is returning more than it paid, we will create a |payment| with that value so the |client| can be reversed. * == 0, the |client| is returning the same amount that needs to be paid, so existing payments will be cancelled and the |client| doesn't owe anything to us. * < 0, than the payments need to be readjusted before calling this. .. seealso: :meth:`stoqlib.domain.sale.Sale.return_` as that will be called after that payment logic is done. """ assert self.sale and self.sale.can_return() self._clean_not_used_items() payment = None if self.total_amount == 0: # The client does not owe anything to us self.group.cancel() elif self.total_amount < 0: # The user has paid more than it's returning for payment in self.group.get_pending_payments(): if payment.is_inpayment(): # We are returning money to client, that means he doesn't owe # us anything, we do now. Cancel pending payments payment.cancel() method = PaymentMethod.get_by_name(self.store, method_name) description = _(u'%s returned for sale %s') % ( method.description, self.sale.identifier) payment = method.create_payment(Payment.TYPE_OUT, payment_group=self.group, branch=self.branch, value=self.total_amount_abs, description=description) payment.set_pending() if method_name == u'credit': payment.pay() # FIXME: For now, we are not reverting the comission as there is a # lot of things to consider. See bug 5215 for information about it. self._revert_fiscal_entry() self.sale.return_(self) # Save invoice number, operation_nature and branch in Invoice table. self.invoice.invoice_number = self.invoice_number self.invoice.operation_nature = self.operation_nature self.invoice.branch = self.branch if self.sale.branch == self.branch: self.confirm(login_user)
def test_create(self): wizard = PurchaseWizard(self.store) method = PaymentMethod.get_by_name(self.store, u'bill') order = self.create_purchase_order() order.identifier = 12345 slave = BillMethodSlave(wizard, None, self.store, order, method, Decimal(200)) self.check_slave(slave, 'slave-bill-method')
def test_till_history_report(self): from stoqlib.gui.dialogs.tillhistory import TillHistoryDialog dialog = TillHistoryDialog(self.store) till = Till(station=self.current_station, branch=self.current_branch, store=self.store) till.open_till(self.current_user) sale = self.create_sale() sellable = self.create_sellable() sale.add_sellable(sellable, price=100) method = PaymentMethod.get_by_name(self.store, u'bill') payment = method.create_payment(sale.branch, sale.station, Payment.TYPE_IN, sale.group, Decimal(100)) TillEntry(value=25, identifier=20, description=u"Cash In", payment=None, till=till, branch=till.station.branch, station=self.current_station, date=datetime.date(2007, 1, 1), store=self.store) TillEntry(value=-5, identifier=21, description=u"Cash Out", payment=None, till=till, branch=till.station.branch, station=self.current_station, date=datetime.date(2007, 1, 1), store=self.store) TillEntry(value=100, identifier=22, description=sellable.get_description(), payment=payment, till=till, branch=till.station.branch, station=self.current_station, date=datetime.date(2007, 1, 1), store=self.store) till_entry = list(self.store.find(TillEntry, till=till)) today = datetime.date.today().strftime('%x') for item in till_entry: if today in item.description: date = datetime.date(2007, 1, 1).strftime('%x') item.description = item.description.replace(today, date) item.date = datetime.date(2007, 1, 1) dialog.results.append(item) self._diff_expected(TillHistoryReport, 'till-history-report', dialog.results, list(dialog.results))
def _create_sale(self, invoice_number, due_date=None): sale = self.create_sale() sale.invoice.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, self.current_user) 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(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(), due_date=due_date) sale.confirm(self.current_user) return sale
def _auto_confirm_sale_wizard_with_trade(self, wizard, app, store, sale, subtotal, total_paid): sale.order() total_paid = sale.group.get_total_confirmed_value() total = sale.get_total_sale_amount() - total_paid payment_method = PaymentMethod.get_by_name(store, u'money') payment_method.create_payment(Payment.TYPE_IN, sale.group, sale.branch, total) self.sale = sale return sale
def test_check_payment(self): with self.sysparam(MANDATORY_CHECK_NUMBER=False): wizard = PurchaseWizard(self.store) method = PaymentMethod.get_by_name(self.store, u'check') order = self.create_purchase_order() order.identifier = 1234567 CheckMethodSlave(wizard, None, self.store, order, method, Decimal(200)) self.assertSensitive(wizard, ['next_button'])
def test_create_with_param_mandatory_check_number_true(self): with self.sysparam(MANDATORY_CHECK_NUMBER=True): wizard = PurchaseWizard(self.store) method = PaymentMethod.get_by_name(self.store, u'money') order = self.create_purchase_order() order.identifier = 12345 slave = MoneyMethodSlave(wizard, None, self.store, order, method, Decimal(200)) self.assertEqual( slave.bank_first_check_number.get_property('mandatory'), False)
def createPayment(self, payment_type): if payment_type == Payment.TYPE_OUT: order = self.create_purchase_order() elif payment_type == Payment.TYPE_IN: order = self.create_sale() else: order = None value = Decimal(100) method = PaymentMethod.get_by_name(self.store, self.method_type) return method.create_payment(payment_type, order.group, order.branch, value)
def __init__(self, wizard, previous, store, consignment, outstanding_value=Decimal(0)): self._method = PaymentMethod.get_by_name(store, u'money') BaseWizardStep.__init__(self, store, wizard, previous=None) self._consignment = consignment self._outstanding_value = outstanding_value self._setup_slaves()
def _create_return_payment(self, method_name, value): method = PaymentMethod.get_by_name(self.store, method_name) description = _(u'%s returned for sale %s') % (method.description, self.sale.identifier) payment = method.create_payment(Payment.TYPE_OUT, payment_group=self.group, branch=self.branch, value=value, description=description) payment.set_pending() if method_name == u'credit': payment.pay()
def test_get_open_date_string(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) self.assertNotEqual(payment.get_open_date_string(), u"")
def createPayments(self, payment_type, no=3): if payment_type == Payment.TYPE_OUT: order = self.create_purchase_order() elif payment_type == Payment.TYPE_IN: order = self.create_sale() else: order = None value = Decimal(100) due_dates = [localnow()] * no method = PaymentMethod.get_by_name(self.store, self.method_type) return method.create_payments(payment_type, order.group, order.branch, value, due_dates)
def test_print_(self, warning): self.assertEqual(self.operation.print_([]), BillReport) method = PaymentMethod.get_by_name(self.store, self.method_name) payment = self.create_payment(method=method) self.assertEqual(self.operation.print_([payment]), None) account = self.create_account() account.account_type = Account.TYPE_BANK account.bank = self.create_bank_account() payment.method.destination_account = account self.assertEqual(self.operation.print_([payment]), BillReport)
def process_one(self, data, fields, store): person = store.find(Person, name=data.branch_name).one() if person is None or person.branch is None: raise ValueError(u"%s is not a valid branch" % (data.branch_name, )) branch = person.branch station = store.find(BranchStation).any() user = store.find(LoginUser).any() person = store.find(Person, name=data.client_name).one() if person is None or person.client is None: raise ValueError(u"%s is not a valid client" % (data.client_name, )) client = person.client person = store.find(Person, name=data.salesperson_name).one() if person is None or person.sales_person is None: raise ValueError(u"%s is not a valid sales person" % (data.salesperson_name, )) salesperson = person.sales_person group = PaymentGroup(store=store) sale = Sale(client=client, open_date=self.parse_date(data.open_date), coupon_id=int(data.coupon_id), salesperson=salesperson, branch=branch, station=station, cfop_id=sysparam.get_object_id('DEFAULT_SALES_CFOP'), group=group, store=store) total_price = 0 for product in self.parse_multi(Product, data.product_list, store): sale.add_sellable(product.sellable) total_price += product.sellable.price sale.order(user) method = PaymentMethod.get_by_name(store, data.payment_method) method.create_payment(branch, station, Payment.TYPE_IN, group, total_price, due_date=self.parse_date(data.due_date)) sale.confirm(user) # XXX: The payments are paid automatically when a sale is confirmed. # So, we will change all the payment paid_date to the same date # as open_date, then we can test the reports properly. for payment in sale.payments: payment.open_date = sale.open_date if payment.is_paid(): p = store.fetch(payment) p.paid_date = self.parse_date(data.open_date)
def test_get_total_confirmed_value(self): method = PaymentMethod.get_by_name(self.store, u'check') # Test for a group in a sale # On sale's group, total value should return # sum(inpayments.value) - sum(outpayments.value) sale = self.create_sale() group = sale.group self.assertEqual(group.get_total_confirmed_value(), 0) p = method.create_payment(Payment.TYPE_IN, group, sale.branch, Decimal(100)) self.assertEqual(group.get_total_confirmed_value(), 0) p.set_pending() self.assertEqual(group.get_total_confirmed_value(), 100) p = method.create_payment(Payment.TYPE_IN, group, sale.branch, Decimal(200)) self.assertEqual(group.get_total_confirmed_value(), 100) p.set_pending() self.assertEqual(group.get_total_confirmed_value(), 300) p = method.create_payment(Payment.TYPE_OUT, group, sale.branch, Decimal(50)) self.assertEqual(group.get_total_confirmed_value(), 300) p.set_pending() self.assertEqual(group.get_total_confirmed_value(), 250) # Test for a group in a purchase # On purchase's group, total value should return # sum(inpayments.value) - sum(outpayments.value) purchase = self.create_purchase_order() group = purchase.group self.assertEqual(group.get_total_confirmed_value(), 0) p = method.create_payment(Payment.TYPE_OUT, group, purchase.branch, Decimal(100)) self.assertEqual(group.get_total_confirmed_value(), 0) p.set_pending() self.assertEqual(group.get_total_confirmed_value(), 100) p = method.create_payment(Payment.TYPE_OUT, group, purchase.branch, Decimal(200)) self.assertEqual(group.get_total_confirmed_value(), 100) p.set_pending() self.assertEqual(group.get_total_confirmed_value(), 300) p = method.create_payment(Payment.TYPE_IN, group, purchase.branch, Decimal(50)) self.assertEqual(group.get_total_confirmed_value(), 300) p.set_pending() self.assertEqual(group.get_total_confirmed_value(), 250)
def test_can_purchase_disallow_all(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_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 self.assertTrue(client.can_purchase(money_method, currency("0"))) # client can pay if he has overdue payments 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("0"))) # client can not pay if he has overdue payments payment = self.create_payment(Payment.TYPE_IN, today - relativedelta(days=1), method=bill_method) payment.group = self.create_payment_group() payment.group.payer = client.person payment.status = Payment.STATUS_PENDING self.assertRaises(SellError, client.can_purchase, store_credit_method, currency("0")) self.assertRaises(SellError, client.can_purchase, check_method, currency("0")) self.assertRaises(SellError, client.can_purchase, money_method, currency("0"))
def next_step(self): if not self.wizard.create_payments: return group = PaymentGroup(store=self.store) self.model.group = group return PaymentMethodStep(self.wizard, self, self.store, self.model, PaymentMethod.get_by_name( self.store, u'multiple'), finish_on_total=False)