From 2ba1c4d18180bc8ed37cdd1e047b15a45b0c0116 Mon Sep 17 00:00:00 2001 From: vtexier <vit@free.fr> Date: Sun, 19 Apr 2020 16:31:46 +0200 Subject: [PATCH] [enh] #807 transfer amount can be given in current referential --- src/sakia/gui/sub/transfer/controller.py | 56 +++++++++++++++++------- src/sakia/gui/sub/transfer/model.py | 28 +++++++----- src/sakia/gui/sub/transfer/transfer.ui | 19 ++++++-- src/sakia/gui/sub/transfer/view.py | 12 ++--- src/sakia/money/base_referential.py | 7 +++ src/sakia/money/percent_of_average.py | 22 ++++++++++ src/sakia/money/quant_zerosum.py | 29 ++++++++++++ src/sakia/money/quantitative.py | 19 ++++++++ src/sakia/money/relative.py | 22 +++++++++- src/sakia/money/relative_zerosum.py | 32 ++++++++++++++ 10 files changed, 207 insertions(+), 39 deletions(-) diff --git a/src/sakia/gui/sub/transfer/controller.py b/src/sakia/gui/sub/transfer/controller.py index 25fb718a..da33d90b 100644 --- a/src/sakia/gui/sub/transfer/controller.py +++ b/src/sakia/gui/sub/transfer/controller.py @@ -52,7 +52,9 @@ class TransferController(QObject): self.change_current_connection ) self.view.spinbox_amount.valueChanged.connect(self.handle_amount_change) - self.view.spinbox_relative.valueChanged.connect(self.handle_relative_change) + self.view.spinbox_referential.valueChanged.connect( + self.handle_referential_change + ) self.view.button_source_check.clicked.connect(self.check_source_dialog) @classmethod @@ -78,6 +80,10 @@ class TransferController(QObject): controller = cls(view, model, search_user, user_information, password_input) search_user.identity_selected.connect(user_information.search_identity) + app.referential_changed.connect(controller.refresh) + controller.view.label_referential_units.setText( + app.current_ref.instance(0, app.currency, app, None).diff_units + ) view.set_keys(controller.model.available_connections()) view.set_contacts(controller.model.contacts()) @@ -116,7 +122,7 @@ class TransferController(QObject): ) controller.set_amount_value(source.amount, source.base) controller.view.spinbox_amount.setDisabled(True) - controller.view.spinbox_relative.setDisabled(True) + controller.view.spinbox_referential.setDisabled(True) result, _ = controller.check_source(source) # by default, source is unlocked, if not... if not result: @@ -293,6 +299,19 @@ class TransferController(QObject): current_base_amount = amount / pow(10, current_base) total_text = self.model.localized_amount(amount) self.view.refresh_labels(total_text) + self.view.label_referential_units.setText( + self.model.app.current_ref.instance( + amount, self.model.app.currency, self.model.app, None + ).diff_units + ) + + # if referential = units, then hide useless referential spinbox + if self.model.app.current_ref == Quantitative: + self.view.spinbox_referential.hide() + self.view.label_referential_units.hide() + else: + self.view.spinbox_referential.show() + self.view.label_referential_units.show() if amount == 0: self.view.set_button_box(TransferView.ButtonBoxState.NO_AMOUNT) @@ -310,19 +329,23 @@ class TransferController(QObject): if self.model.current_source and self.view.button_source_check.isEnabled(): self.view.set_button_box(TransferView.ButtonBoxState.SOURCE_LOCKED) - max_relative = self.model.quant_to_rel(current_base_amount / 100) + max_relative = self.model.quantitative_to_referential(amount / 100) self.view.spinbox_amount.setSuffix(Quantitative.base_str(current_base)) self.view.set_spinboxes_parameters(current_base_amount / 100, max_relative) def handle_amount_change(self, value): - relative = self.model.quant_to_rel(value) - self.view.change_relative_amount(relative) + current_base = self.model.current_base() + current_base_value = value / pow(10, current_base) + referential_amount = self.model.quantitative_to_referential(current_base_value) + self.view.change_referential_amount(referential_amount) self.refresh() - def handle_relative_change(self, value): - amount = self.model.rel_to_quant(value) - self.view.change_quantitative_amount(amount) + def handle_referential_change(self, value): + amount = self.model.referential_to_quantitative(value) + current_base = self.model.current_base() + current_base_amount = amount / 100 / pow(10, current_base) + self.view.change_quantitative_amount(current_base_amount) self.refresh() def change_current_connection(self, index): @@ -408,16 +431,17 @@ class TransferController(QObject): def set_amount_value(self, amount, base): """ - Set quantitative and relative amounts from amount and base given + Set quantitative and referential amounts from amount and base given :param int amount: Amount to display :param int base: Base of the amount given :return: """ - # calculate amount for current base + # calculate value (from money cents) for current base current_base = self.model.current_base() - current_base_amount = amount / pow(10, base - current_base) - # display quantitative and relative amounts - relative = self.model.quant_to_rel(current_base_amount / 100) - self.view.set_spinboxes_parameters(current_base_amount / 100, relative) - self.view.change_relative_amount(relative) - self.view.change_quantitative_amount(current_base_amount / 100) + current_base_value = amount / pow(10, base - current_base) / 100 + + # display quantitative and referential amounts + referential_amount = self.model.quantitative_to_referential(current_base_value) + self.view.set_spinboxes_parameters(current_base_value, referential_amount) + self.view.change_referential_amount(referential_amount) + self.view.change_quantitative_amount(current_base_value) diff --git a/src/sakia/gui/sub/transfer/model.py b/src/sakia/gui/sub/transfer/model.py index 7b2c632d..35c76f56 100644 --- a/src/sakia/gui/sub/transfer/model.py +++ b/src/sakia/gui/sub/transfer/model.py @@ -6,6 +6,7 @@ from sakia.data.processors import ( ConnectionsProcessor, ContactsProcessor, ) +from sakia.money.base_referential import BaseReferential @attr.s() @@ -33,27 +34,30 @@ class TransferModel(QObject): self._connections_processor = ConnectionsProcessor.instanciate(self.app) self._contacts_processor = ContactsProcessor.instanciate(self.app) - def rel_to_quant(self, rel_value): + def referential_to_quantitative(self, value): """ - Get the quantitative value of a relative amount - :param float rel_value: + Get the quantitative value of a referential amount + :param float value: :rtype: int """ - dividend, base = self._blockchain_processor.last_ud(self.connection.currency) - amount = rel_value * dividend + referential = self.app.current_ref( + 0, self.app.currency, self.app + ) # type: BaseReferential + referential.set_diff_referential(value) # amount is rounded to the nearest power of 10 depending of last ud base # rounded = int(pow(10, base) * round(float(amount) / pow(10, base))) - return int(amount) / 100 + return int(referential.amount) - def quant_to_rel(self, amount): + def quantitative_to_referential(self, value): """ - Get the relative value of a given amount - :param int amount: + Get the referential value of a given amount + :param int value: :rtype: float """ - dividend, base = self._blockchain_processor.last_ud(self.connection.currency) - relative = amount * 100 / dividend - return relative + referential = self.app.current_ref( + value * 100, self.app.currency, self.app + ) # type: BaseReferential + return referential.differential() def wallet_value(self): """ diff --git a/src/sakia/gui/sub/transfer/transfer.ui b/src/sakia/gui/sub/transfer/transfer.ui index 15341145..2bdc79d0 100644 --- a/src/sakia/gui/sub/transfer/transfer.ui +++ b/src/sakia/gui/sub/transfer/transfer.ui @@ -317,10 +317,7 @@ </widget> </item> <item> - <widget class="QDoubleSpinBox" name="spinbox_relative"> - <property name="suffix"> - <string> UD</string> - </property> + <widget class="QDoubleSpinBox" name="spinbox_referential"> <property name="decimals"> <number>6</number> </property> @@ -332,6 +329,13 @@ </property> </widget> </item> + <item> + <widget class="QLabel" name="label_referential_units"> + <property name="text"> + <string>Units</string> + </property> + </widget> + </item> <item> <widget class="QDoubleSpinBox" name="spinbox_amount"> <property name="wrapping"> @@ -360,6 +364,13 @@ </property> </widget> </item> + <item> + <widget class="QLabel" name="label_amount_units"> + <property name="text"> + <string>Units</string> + </property> + </widget> + </item> </layout> </item> </layout> diff --git a/src/sakia/gui/sub/transfer/view.py b/src/sakia/gui/sub/transfer/view.py index 45e1fd31..d606246a 100644 --- a/src/sakia/gui/sub/transfer/view.py +++ b/src/sakia/gui/sub/transfer/view.py @@ -159,14 +159,14 @@ class TransferView(QWidget, Ui_TransferMoneyWidget): self.spinbox_amount.setValue(amount) self.spinbox_amount.blockSignals(False) - def change_relative_amount(self, relative): + def change_referential_amount(self, referential_amount): """ Change the quantitative amount with signals blocks - :param relative: + :param referential_amount: """ - self.spinbox_relative.blockSignals(True) - self.spinbox_relative.setValue(relative) - self.spinbox_relative.blockSignals(False) + self.spinbox_referential.blockSignals(True) + self.spinbox_referential.setValue(referential_amount) + self.spinbox_referential.blockSignals(False) def set_spinboxes_parameters(self, max_quant, max_rel): """ @@ -176,7 +176,7 @@ class TransferView(QWidget, Ui_TransferMoneyWidget): :param float max_rel: """ self.spinbox_amount.setMaximum(max_quant) - self.spinbox_relative.setMaximum(max_rel) + self.spinbox_referential.setMaximum(max_rel) def refresh_labels(self, total_text): """ diff --git a/src/sakia/money/base_referential.py b/src/sakia/money/base_referential.py index 64180343..5b0b6bd6 100644 --- a/src/sakia/money/base_referential.py +++ b/src/sakia/money/base_referential.py @@ -22,6 +22,7 @@ class BaseReferential: self.currency = currency self._block_number = block_number + # todo: remove this useless class method and replace all occurence with a classic Object() creation. @classmethod def instance(cls, amount, currency, app, block_number=None): return cls(amount, currency, app, block_number) @@ -44,6 +45,12 @@ class BaseReferential: def differential(self): raise NotImplementedError() + def set_referential(self, value): + raise NotImplementedError() + + def set_diff_referential(self, value): + raise NotImplementedError() + @staticmethod def to_si(value, base): raise NotImplementedError() diff --git a/src/sakia/money/percent_of_average.py b/src/sakia/money/percent_of_average.py index 7d030121..ffcf584c 100644 --- a/src/sakia/money/percent_of_average.py +++ b/src/sakia/money/percent_of_average.py @@ -104,6 +104,28 @@ class PercentOfAverage(BaseReferential): def differential(self): return self.value() + def set_referential(self, value): + """ + Set quantitative amount from referential value + + :param value: Value in referential units + :return: + """ + mass = self._blockchain_processor.last_mass(self.currency) + members = self._blockchain_processor.last_members_count(self.currency) + average = mass / members + self.amount = value / 100 * average + return self + + def set_diff_referential(self, value): + """ + Set quantitative amount from differential referential value + + :param value: + :return: + """ + return self.set_referential(value) + def localized(self, units=False, show_base=False): value = self.value() localized_value = QLocale().toString( diff --git a/src/sakia/money/quant_zerosum.py b/src/sakia/money/quant_zerosum.py index e20f5326..26cd6bb4 100644 --- a/src/sakia/money/quant_zerosum.py +++ b/src/sakia/money/quant_zerosum.py @@ -102,6 +102,35 @@ class QuantitativeZSum(BaseReferential): def differential(self): return Quantitative(self.amount, self.currency, self.app).value() + def set_referential(self, value): + """ + Set quantitative amount from referential value + + :param value: Value in referential units + :return: + """ + last_members_count = self._blockchain_processor.last_members_count( + self.currency + ) + monetary_mass = self._blockchain_processor.current_mass(self.currency) + if last_members_count != 0: + average = int(monetary_mass / last_members_count) + else: + average = 0 + + self.amount = (value + average) * 100 + return self + + def set_diff_referential(self, value): + """ + Set quantitative amount from differential referential value + + :param value: + :return: + """ + self.amount = value * 100 + return self + def localized(self, units=False, show_base=False): value = self.value() dividend, base = self._blockchain_processor.last_ud(self.currency) diff --git a/src/sakia/money/quantitative.py b/src/sakia/money/quantitative.py index 17cd7196..d45a148b 100644 --- a/src/sakia/money/quantitative.py +++ b/src/sakia/money/quantitative.py @@ -61,6 +61,25 @@ class Quantitative(BaseReferential): def differential(self): return self.value() + def set_referential(self, value): + """ + Set quantitative amount from referential value + + :param value: Value in referential units + :return: + """ + self.amount = value * 100 + return self + + def set_diff_referential(self, value): + """ + Set quantitative amount from differential referential value + + :param value: + :return: + """ + return self.set_referential(value) + @staticmethod def base_str(base): unicodes = { diff --git a/src/sakia/money/relative.py b/src/sakia/money/relative.py index 8402fc8e..d0a11e9d 100644 --- a/src/sakia/money/relative.py +++ b/src/sakia/money/relative.py @@ -85,11 +85,31 @@ class Relative(BaseReferential): if dividend > 0: return self.amount / (float(dividend * (10 ** base))) else: - return self.amount + return self.amount / 100 def differential(self): return self.value() + def set_referential(self, value): + """ + Set quantitative amount from referential value + + :param value: Value in referential units + :return: + """ + dividend, base = self._blockchain_processor.last_ud(self.currency) + self.amount = value * (float(dividend * (10 ** base))) + return self + + def set_diff_referential(self, value): + """ + Set quantitative amount from differential referential value + + :param value: + :return: + """ + return self.set_referential(value) + def localized(self, units=False, show_base=False): value = self.value() localized_value = QLocale().toString( diff --git a/src/sakia/money/relative_zerosum.py b/src/sakia/money/relative_zerosum.py index 466f6f77..db171f87 100644 --- a/src/sakia/money/relative_zerosum.py +++ b/src/sakia/money/relative_zerosum.py @@ -93,6 +93,38 @@ class RelativeZSum(BaseReferential): def differential(self): return Relative(self.amount, self.currency, self.app).value() + def set_referential(self, value): + """ + Set quantitative amount from referential value + + :param value: Value in referential units + :return: + """ + dividend, base = self._blockchain_processor.previous_ud(self.currency) + previous_monetary_mass = self._blockchain_processor.previous_monetary_mass( + self.currency + ) + members_count = self._blockchain_processor.current_members_count(self.currency) + if previous_monetary_mass and members_count > 0: + median = previous_monetary_mass / members_count + relative_median = median / float(dividend * 10 ** base) + else: + relative_median = 0 + + self.amount = (value + relative_median) * float(dividend * 10 ** base) + return self + + def set_diff_referential(self, value): + """ + Set quantitative amount from differential referential value + + :param value: + :return: + """ + dividend, base = self._blockchain_processor.previous_ud(self.currency) + self.amount = value * float(dividend * 10 ** base) + return self + def localized(self, units=False, show_base=False): value = self.value() -- GitLab