def test_set_client_with_some_store_credit(self): slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN) client = self.create_client() client.credit_limit = 10 slave.set_client(client, 100) self.check_slave( slave, 'slave-select-payment-method-client-with-some-store-credit')
def test_set_client_without_credit_and_store_credit(self): slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN) client = self.create_client() slave.set_client(client, 100) self.check_slave( slave, 'slave-select-payment-method-client-without-credit-and-store-credit')
def test_set_client_with_enough_store_credit(self): slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN) client = self.create_client() client.credit_limit = 100 slave.set_client(client, 100) self.check_slave( slave, 'slave-select-payment-method-client-with-enough-store-credit')
def _setup_widgets(self): register_payment_slaves() self._ms = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_OUT, default_method=self._method) self._ms.connect_after('method-changed', self._after_method_select__method_changed) self.attach_slave('method_select_holder', self._ms) self._update_payment_method_slave()
def setup_slaves(self): marker('SelectPaymentMethodSlave') self.pm_slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN) self.pm_slave.connect('method-changed', self.on_payment_method_changed) self.attach_slave('select_method_holder', self.pm_slave) marker('CashChangeSlave') self.cash_change_slave = CashChangeSlave(self.store, self.model, self.wizard) self.attach_slave('cash_change_holder', self.cash_change_slave) self.cash_change_slave.received_value.connect( 'activate', lambda entry: self.wizard.go_to_next())
def test_default_method(self): method = self.store.find(PaymentMethod, method_name=u'multiple').one() with self.sysparam(DEFAULT_PAYMENT_METHOD=method): slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN) self.assertEqual( slave.get_selected_method().method_name, u'multiple') # If the default method is not created (setting is_active to False # does the trick), it should fallback to money method.is_active = False slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN) self.assertEqual( slave.get_selected_method().method_name, u'money')
def test_set_client_with_enough_credit(self): slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN) client = self.create_client() method = self.store.find(PaymentMethod, method_name=u'credit').one() payment = self.create_payment(payment_type=Payment.TYPE_OUT, value=100, method=method) payment.group.payer = client.person payment.set_pending() payment.pay() slave.set_client(client, 100) self.check_slave( slave, 'slave-select-payment-method-client-with-enough-credit')
def test_created_methods(self): # Payment.TYPE_IN slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN) methods = ['bill', 'card', 'check', 'credit', 'deposit', 'money', 'multiple', 'store_credit'] self.assertEqual(set(slave._widgets.keys()), set(methods)) for method in methods: widget = slave._widgets.get(method) self.assertTrue(widget.get_visible()) # Payment.TYPE_OUT slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_OUT) methods = ['bill', 'check', 'deposit', 'money'] self.assertEqual(set(slave._widgets.keys()), set(methods)) for method in methods: widget = slave._widgets.get(method) self.assertTrue(widget.get_visible()) # Only 1 method available for method in self.store.find(PaymentMethod, PaymentMethod.method_name != u'money'): method.is_active = False slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN) self.assertEqual(set(slave._widgets.keys()), set([u'money'])) self.assertEqual(slave.get_selected_method().method_name, u'money')
def _setup_widgets(self): register_payment_slaves() self._ms = SelectPaymentMethodSlave( store=self.store, payment_type=Payment.TYPE_OUT, default_method=self._method, no_payments=True ) self._ms.connect_after("method-changed", self._after_method_select__method_changed) self.attach_slave("method_select_holder", self._ms) self._update_payment_method_slave()
def test_method_set_sensitive(self): inactive = self.store.find(PaymentMethod, method_name=u'bill').one() inactive.is_active = False slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN, default_method=u'check') self.assertEqual(slave.get_selected_method().method_name, u'check') slave.method_set_sensitive(u'check', False) self.assertFalse(slave._widgets[u'check'].get_sensitive()) self.assertEqual(slave.get_selected_method().method_name, u'money') # Test when the widget is not there slave.method_set_sensitive(u'bill', True)
def test_method_set_sensitive(self): inactive = self.store.find(PaymentMethod, method_name=u'bill').one() inactive.is_active = False slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN, default_method=u'check') self.assertEqual( slave.get_selected_method().method_name, u'check') slave.method_set_sensitive(u'check', False) self.assertFalse(slave._widgets[u'check'].get_sensitive()) self.assertEqual( slave.get_selected_method().method_name, u'money') # Test when the widget is not there slave.method_set_sensitive(u'bill', True)
def test_default_method(self): method = self.store.find(PaymentMethod, method_name=u'multiple').one() with self.sysparam(DEFAULT_PAYMENT_METHOD=method): slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN) self.assertEqual(slave.get_selected_method().method_name, u'multiple') # If the default method is not created (setting is_active to False # does the trick), it should fallback to money method.is_active = False slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN) self.assertEqual(slave.get_selected_method().method_name, u'money')
class PurchasePaymentStep(WizardEditorStep): gladefile = 'PurchasePaymentStep' model_type = PaymentGroup def __init__(self, wizard, previous, store, model, outstanding_value=currency(0)): self.order = model self.slave = None self.discount_surcharge_slave = None self.outstanding_value = outstanding_value if not model.payments.count(): # Default values self._installments_number = None self._first_duedate = None self._method = 'bill' else: # FIXME: SqlObject returns count as long, but we need it as int. self._installments_number = int(model.payments.count()) self._method = model.payments[0].method.method_name # due_date is datetime.datetime. Converting it to datetime.date due_date = model.payments[0].due_date.date() self._first_duedate = (due_date >= localtoday().date() and due_date or None) WizardEditorStep.__init__(self, store, wizard, model.group, previous) def _setup_widgets(self): register_payment_slaves() self._ms = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_OUT, default_method=self._method, no_payments=True) self._ms.connect_after('method-changed', self._after_method_select__method_changed) self.attach_slave('method_select_holder', self._ms) self._update_payment_method_slave() def _set_method_slave(self): """Sets the payment method slave""" method = self._ms.get_selected_method() if not method: return domain_mapper = get_utility(IDomainSlaveMapper) slave_class = domain_mapper.get_slave_class(method) if slave_class: self.wizard.payment_group = self.model self.slave = slave_class(self.wizard, self, self.store, self.order, method, outstanding_value=self.outstanding_value, first_duedate=self._first_duedate, installments_number=self._installments_number, temporary_identifiers=self.wizard.is_for_another_branch()) self.attach_slave('method_slave_holder', self.slave) def _update_payment_method_slave(self): """Updates the payment method slave """ holder_name = 'method_slave_holder' if self.get_slave(holder_name): self.slave.get_toplevel().hide() self.detach_slave(holder_name) self.slave = None # remove all payments created last time, if any self.model.clear_unused() if not self.slave: self._set_method_slave() # # WizardStep hooks # def validate_step(self): if self.slave: return self.slave.finish() return True def next_step(self): return FinishPurchaseStep(self.store, self.wizard, self.order, self) def post_init(self): self.model.clear_unused() self.main_box.set_focus_chain([self.method_select_holder, self.method_slave_holder]) self.register_validate_function(self.wizard.refresh_next) self.force_validation() def setup_proxies(self): self._setup_widgets() # # callbacks # def _after_method_select__method_changed(self, slave, method): self._update_payment_method_slave()
class BaseMethodSelectionStep(object): """Base class for method selection when doing client sales Classes using this base class should have a select_method_holder EventBox and a cash_change_holder EventBox in the glade file """ # # Private API # def _update_next_step(self, method): if method and method.method_name == u'money': self.wizard.enable_finish() if self.wizard.need_create_payment(): self.cash_change_slave.enable_cash_change() else: self.cash_change_slave.disable_cash_change() else: self.wizard.disable_finish() self.cash_change_slave.disable_cash_change() # # Public API # def get_selected_method(self): return self.pm_slave.get_selected_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() return money_method.create_inpayment(self.model.group, self.model.branch, total) # # WizardStep hooks # def post_init(self): if not self.wizard.need_create_payment(): for widget in [self.select_method_holder, self.subtotal_expander]: widget.hide() self._update_next_step(self.pm_slave.get_selected_method()) def setup_slaves(self): marker('SelectPaymentMethodSlave') self.pm_slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN) self.pm_slave.connect('method-changed', self.on_payment_method_changed) self.attach_slave('select_method_holder', self.pm_slave) marker('CashChangeSlave') self.cash_change_slave = CashChangeSlave(self.store, self.model, self.wizard) self.attach_slave('cash_change_holder', self.cash_change_slave) self.cash_change_slave.received_value.connect( 'activate', lambda entry: self.wizard.go_to_next()) def next_step(self): if not self.wizard.need_create_payment(): return selected_method = self.get_selected_method() if selected_method.method_name == u'money': if not self.cash_change_slave.can_finish(): warning(_(u"Invalid value, please verify if it was " "properly typed.")) self.cash_change_slave.received_value.select_region( 0, len(self.cash_change_slave.received_value.get_text())) self.cash_change_slave.received_value.grab_focus() return self # We have to modify the payment, so the fiscal printer can # calculate and print the payback, if necessary. payment = self.setup_cash_payment() total = self.cash_change_slave.get_received_value() payment.base_value = total # Return None here means call wizard.finish, which is exactly # what we need return None elif selected_method.method_name == u'store_credit': client = self.model.client total = self.wizard.get_total_amount() assert client.can_purchase(selected_method, total) step_class = PaymentMethodStep elif selected_method.method_name == 'card': providers = CreditProvider.get_card_providers(self.store) if providers.is_empty(): warning(_("You need active credit providers to use the " "card payment method.")) return self step_class = PaymentMethodStep else: step_class = PaymentMethodStep retval = CreatePaymentEvent.emit(selected_method, self.model, self.store) # None means no one catched this event if retval is None or retval == CreatePaymentStatus.UNHANDLED: # FIXME: We cannot send outstanding_value to multiple editor # since if we have a trade going on, it will be calculated wrong if selected_method.method_name == 'multiple': outstanding_value = None else: outstanding_value = self.wizard.get_total_to_pay() return step_class(self.wizard, self, self.store, self.model, selected_method, outstanding_value=outstanding_value) # finish the wizard if retval == CreatePaymentStatus.SUCCESS: return None # returning self to stay on this step return self # # Callbacks # def on_payment_method_changed(self, slave, method_name): self._update_next_step(method_name)
class BaseMethodSelectionStep(object): """Base class for method selection when doing client sales Classes using this base class should have a select_method_holder EventBox and a cash_change_holder EventBox in the glade file """ # # Private API # def _update_next_step(self, method): if method and method.method_name == u'money': self.wizard.enable_finish() if self.wizard.need_create_payment(): self.cash_change_slave.enable_cash_change() else: self.cash_change_slave.disable_cash_change() elif method and method.method_name == u'credit': self.wizard.enable_finish() self.cash_change_slave.disable_cash_change() else: self.wizard.disable_finish() self.cash_change_slave.disable_cash_change() # # Public API # def get_selected_method(self): return self.pm_slave.get_selected_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() return money_method.create_payment(Payment.TYPE_IN, self.model.group, self.model.branch, total) # # WizardStep hooks # def post_init(self): if not self.wizard.need_create_payment(): for widget in [self.select_method_holder, self.subtotal_expander]: widget.hide() self._update_next_step(self.pm_slave.get_selected_method()) def setup_slaves(self): marker('SelectPaymentMethodSlave') self.pm_slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN) self.pm_slave.connect('method-changed', self.on_payment_method_changed) self.attach_slave('select_method_holder', self.pm_slave) marker('CashChangeSlave') self.cash_change_slave = CashChangeSlave(self.store, self.model, self.wizard) self.attach_slave('cash_change_holder', self.cash_change_slave) self.cash_change_slave.received_value.connect( 'activate', lambda entry: self.wizard.go_to_next()) def next_step(self): if not self.wizard.need_create_payment(): return selected_method = self.get_selected_method() if selected_method.method_name == u'money': if not self.cash_change_slave.can_finish(): warning( _(u"Invalid value, please verify if it was " "properly typed.")) self.cash_change_slave.received_value.select_region( 0, len(self.cash_change_slave.received_value.get_text())) self.cash_change_slave.received_value.grab_focus() return self # We have to modify the payment, so the fiscal printer can # calculate and print the payback, if necessary. payment = self.setup_cash_payment() total = self.cash_change_slave.get_received_value() payment.base_value = total # Return None here means call wizard.finish, which is exactly # what we need return None elif selected_method.method_name == u'credit': client = self.model.client total = self.wizard.get_total_to_pay() assert client.can_purchase(selected_method, total) payment = selected_method.create_payment(Payment.TYPE_IN, self.model.group, self.model.branch, total) # Return None here means call wizard.finish, which is exactly # what we need return None elif selected_method.method_name == u'store_credit': client = self.model.client total = self.wizard.get_total_to_pay() assert client.can_purchase(selected_method, total) step_class = PaymentMethodStep elif selected_method.method_name == 'card': providers = CreditProvider.get_card_providers(self.store) if providers.is_empty(): warning( _("You need active credit providers to use the " "card payment method.")) return self step_class = PaymentMethodStep else: step_class = PaymentMethodStep retval = CreatePaymentEvent.emit(selected_method, self.model, self.store) # None means no one catched this event if retval is None or retval == CreatePaymentStatus.UNHANDLED: # FIXME: We cannot send outstanding_value to multiple editor # since if we have a trade going on, it will be calculated wrong if selected_method.method_name == 'multiple': outstanding_value = None else: outstanding_value = self.wizard.get_total_to_pay() manager = get_plugin_manager() return step_class(self.wizard, self, self.store, self.model, selected_method, outstanding_value=outstanding_value, finish_on_total=manager.is_active('tef')) # finish the wizard if retval == CreatePaymentStatus.SUCCESS: return None # returning self to stay on this step return self # # Callbacks # def on_payment_method_changed(self, slave, method_name): self._update_next_step(method_name)
def test_init_default_method(self): check_method = self.store.find(PaymentMethod, method_name=u'check').one() multiple_method = self.store.find(PaymentMethod, method_name=u'multiple').one() money_method = self.store.find(PaymentMethod, method_name=u'money').one() # Check should be selected here since it was passed as default ethod slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN, default_method=u'check') self.assertEqual(slave.get_selected_method(), check_method) with self.sysparam(DEFAULT_PAYMENT_METHOD=multiple_method): # Even with multiple as default, the constructor default # should overwrite it slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN, default_method=u'check') self.assertEqual(slave.get_selected_method(), check_method) # Making check inactive should make the DEFAULT_PAYMENT_METHOD # the default one on the slave check_method.is_active = False slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN, default_method=u'check') self.assertEqual(slave.get_selected_method(), multiple_method) # Making check and the DEFAULT_PAYMENT_METHOD inactive, # the default should fallback to money multiple_method.is_active = False slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN, default_method=u'check') self.assertEqual(slave.get_selected_method(), money_method)
def test_init(self): with self.assertRaisesRegexp(ValueError, "payment_type must be set"): SelectPaymentMethodSlave(payment_type=None)
def test_set_client_none(self): slave = SelectPaymentMethodSlave(store=self.store, payment_type=Payment.TYPE_IN) slave.set_client(None, 100) self.check_slave(slave, 'slave-select-payment-method-client-none')