mirror of
				https://github.com/RolandWH/SIPPCompare.git
				synced 2025-11-03 19:42:12 +00:00 
			
		
		
		
	Merge pull request #1 from RolandWH/testing
Implement input validation with optional fields support
This commit is contained in:
		@@ -6,20 +6,20 @@
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>480</width>
 | 
			
		||||
    <height>305</height>
 | 
			
		||||
    <width>498</width>
 | 
			
		||||
    <height>303</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="minimumSize">
 | 
			
		||||
   <size>
 | 
			
		||||
    <width>480</width>
 | 
			
		||||
    <height>305</height>
 | 
			
		||||
    <width>498</width>
 | 
			
		||||
    <height>303</height>
 | 
			
		||||
   </size>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="maximumSize">
 | 
			
		||||
   <size>
 | 
			
		||||
    <width>480</width>
 | 
			
		||||
    <height>305</height>
 | 
			
		||||
    <width>498</width>
 | 
			
		||||
    <height>303</height>
 | 
			
		||||
   </size>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
@@ -28,10 +28,10 @@
 | 
			
		||||
  <widget class="QWidget" name="gridLayoutWidget">
 | 
			
		||||
   <property name="geometry">
 | 
			
		||||
    <rect>
 | 
			
		||||
     <x>10</x>
 | 
			
		||||
     <y>10</y>
 | 
			
		||||
     <x>20</x>
 | 
			
		||||
     <y>20</y>
 | 
			
		||||
     <width>461</width>
 | 
			
		||||
     <height>251</height>
 | 
			
		||||
     <height>243</height>
 | 
			
		||||
    </rect>
 | 
			
		||||
   </property>
 | 
			
		||||
   <layout class="QGridLayout" name="gridLayout">
 | 
			
		||||
@@ -53,99 +53,166 @@
 | 
			
		||||
    <property name="verticalSpacing">
 | 
			
		||||
     <number>5</number>
 | 
			
		||||
    </property>
 | 
			
		||||
    <item row="0" column="0" colspan="2">
 | 
			
		||||
     <widget class="QLabel" name="plat_name_lab">
 | 
			
		||||
      <property name="text">
 | 
			
		||||
       <string>Platform name</string>
 | 
			
		||||
    <item row="0" column="3">
 | 
			
		||||
     <widget class="QCheckBox" name="plat_name_check">
 | 
			
		||||
      <property name="checked">
 | 
			
		||||
       <bool>true</bool>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="6" column="3">
 | 
			
		||||
     <widget class="QCheckBox" name="share_deal_fee_check">
 | 
			
		||||
      <property name="enabled">
 | 
			
		||||
       <bool>false</bool>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="checked">
 | 
			
		||||
       <bool>true</bool>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="5" column="2">
 | 
			
		||||
     <widget class="FastEditQDoubleSpinBox" name="share_plat_max_fee_box">
 | 
			
		||||
      <property name="enabled">
 | 
			
		||||
       <bool>false</bool>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="buttonSymbols">
 | 
			
		||||
       <enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="correctionMode">
 | 
			
		||||
       <enum>QAbstractSpinBox::CorrectionMode::CorrectToNearestValue</enum>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="prefix">
 | 
			
		||||
       <string>£</string>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="maximum">
 | 
			
		||||
       <double>999.000000000000000</double>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="2" column="3">
 | 
			
		||||
     <widget class="QCheckBox" name="fund_deal_fee_check">
 | 
			
		||||
      <property name="enabled">
 | 
			
		||||
       <bool>false</bool>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="checked">
 | 
			
		||||
       <bool>true</bool>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="6" column="2">
 | 
			
		||||
     <widget class="FastEditQDoubleSpinBox" name="share_deal_fee_box">
 | 
			
		||||
      <property name="buttonSymbols">
 | 
			
		||||
       <enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="correctionMode">
 | 
			
		||||
       <enum>QAbstractSpinBox::CorrectionMode::CorrectToNearestValue</enum>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="prefix">
 | 
			
		||||
       <string>£</string>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="maximum">
 | 
			
		||||
       <double>999.000000000000000</double>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="8" column="0" colspan="2">
 | 
			
		||||
     <widget class="QLabel" name="share_deal_reduce_amount_lab">
 | 
			
		||||
      <property name="text">
 | 
			
		||||
       <string>Share dealing discount amount</string>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="0" column="2">
 | 
			
		||||
     <widget class="QLineEdit" name="plat_name_box"/>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="3" column="0" colspan="2">
 | 
			
		||||
     <widget class="QLabel" name="share_plat_fee_lab">
 | 
			
		||||
      <property name="text">
 | 
			
		||||
       <string>Share platform fee*</string>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="7" column="0" colspan="2">
 | 
			
		||||
     <widget class="QLabel" name="share_deal_reduce_trades_lab">
 | 
			
		||||
      <property name="text">
 | 
			
		||||
       <string>Share dealing discount # of trades</string>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="9" column="3">
 | 
			
		||||
     <widget class="QCheckBox" name="share_deal_reduce_amount_check"/>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="5" column="0" colspan="2">
 | 
			
		||||
     <widget class="QLabel" name="share_plat_max_fee_lab">
 | 
			
		||||
      <property name="text">
 | 
			
		||||
       <string>Share platform monthly fee cap</string>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="2" column="2">
 | 
			
		||||
     <widget class="FastEditQDoubleSpinBox" name="fund_deal_fee_box">
 | 
			
		||||
      <property name="buttonSymbols">
 | 
			
		||||
       <enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="correctionMode">
 | 
			
		||||
       <enum>QAbstractSpinBox::CorrectionMode::CorrectToNearestValue</enum>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="prefix">
 | 
			
		||||
       <string>£</string>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="maximum">
 | 
			
		||||
       <double>999.000000000000000</double>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="6" column="0" colspan="2">
 | 
			
		||||
     <widget class="QLabel" name="share_deal_fee_lab">
 | 
			
		||||
      <property name="text">
 | 
			
		||||
       <string>Share dealing fee*</string>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="1" column="0" colspan="2">
 | 
			
		||||
    <item row="8" column="2">
 | 
			
		||||
     <widget class="FastEditQSpinBox" name="share_deal_reduce_trades_box">
 | 
			
		||||
      <property name="enabled">
 | 
			
		||||
       <bool>false</bool>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="buttonSymbols">
 | 
			
		||||
       <enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="correctionMode">
 | 
			
		||||
       <enum>QAbstractSpinBox::CorrectionMode::CorrectToNearestValue</enum>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="maximum">
 | 
			
		||||
       <number>999</number>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="8" column="3">
 | 
			
		||||
     <widget class="QCheckBox" name="share_deal_reduce_trades_check"/>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="4" column="3">
 | 
			
		||||
     <widget class="QCheckBox" name="share_plat_fee_check">
 | 
			
		||||
      <property name="enabled">
 | 
			
		||||
       <bool>false</bool>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="checked">
 | 
			
		||||
       <bool>true</bool>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="2" column="0" colspan="2">
 | 
			
		||||
     <widget class="QLabel" name="fund_deal_fee_lab">
 | 
			
		||||
      <property name="text">
 | 
			
		||||
       <string>Fund dealing fee*</string>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="4" column="0" colspan="2">
 | 
			
		||||
     <widget class="QLabel" name="share_plat_max_fee_lab">
 | 
			
		||||
    <item row="5" column="3">
 | 
			
		||||
     <widget class="QCheckBox" name="share_plat_max_fee_check"/>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="0" column="2">
 | 
			
		||||
     <widget class="QLineEdit" name="plat_name_box"/>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="9" column="0" colspan="2">
 | 
			
		||||
     <widget class="QLabel" name="share_deal_reduce_amount_lab">
 | 
			
		||||
      <property name="text">
 | 
			
		||||
       <string>Share platform fee cap/mth</string>
 | 
			
		||||
       <string>Share dealing discount amount</string>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="8" column="2">
 | 
			
		||||
     <widget class="QDoubleSpinBox" name="share_deal_reduce_amount_box">
 | 
			
		||||
      <property name="buttonSymbols">
 | 
			
		||||
       <enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="correctionMode">
 | 
			
		||||
       <enum>QAbstractSpinBox::CorrectionMode::CorrectToNearestValue</enum>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="prefix">
 | 
			
		||||
       <string>£</string>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="5" column="2">
 | 
			
		||||
     <widget class="QDoubleSpinBox" name="share_deal_fee_box">
 | 
			
		||||
      <property name="buttonSymbols">
 | 
			
		||||
       <enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="correctionMode">
 | 
			
		||||
       <enum>QAbstractSpinBox::CorrectionMode::CorrectToNearestValue</enum>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="prefix">
 | 
			
		||||
       <string>£</string>
 | 
			
		||||
    <item row="4" column="0" colspan="2">
 | 
			
		||||
     <widget class="QLabel" name="share_plat_fee_lab">
 | 
			
		||||
      <property name="text">
 | 
			
		||||
       <string>Share platform fee*</string>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="4" column="2">
 | 
			
		||||
     <widget class="QDoubleSpinBox" name="share_plat_max_fee_box">
 | 
			
		||||
      <property name="buttonSymbols">
 | 
			
		||||
       <enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="correctionMode">
 | 
			
		||||
       <enum>QAbstractSpinBox::CorrectionMode::CorrectToNearestValue</enum>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="prefix">
 | 
			
		||||
       <string>£</string>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="3" column="2">
 | 
			
		||||
     <widget class="QDoubleSpinBox" name="share_plat_fee_box">
 | 
			
		||||
     <widget class="FastEditQDoubleSpinBox" name="share_plat_fee_box">
 | 
			
		||||
      <property name="buttonSymbols">
 | 
			
		||||
       <enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
 | 
			
		||||
      </property>
 | 
			
		||||
@@ -155,10 +222,23 @@
 | 
			
		||||
      <property name="suffix">
 | 
			
		||||
       <string>%</string>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="maximum">
 | 
			
		||||
       <double>99.000000000000000</double>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="1" column="2">
 | 
			
		||||
     <widget class="QDoubleSpinBox" name="fund_deal_fee_box">
 | 
			
		||||
    <item row="0" column="0" colspan="2">
 | 
			
		||||
     <widget class="QLabel" name="plat_name_lab">
 | 
			
		||||
      <property name="text">
 | 
			
		||||
       <string>Platform name</string>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="9" column="2">
 | 
			
		||||
     <widget class="FastEditQDoubleSpinBox" name="share_deal_reduce_amount_box">
 | 
			
		||||
      <property name="enabled">
 | 
			
		||||
       <bool>false</bool>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="buttonSymbols">
 | 
			
		||||
       <enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
 | 
			
		||||
      </property>
 | 
			
		||||
@@ -168,15 +248,8 @@
 | 
			
		||||
      <property name="prefix">
 | 
			
		||||
       <string>£</string>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
    <item row="7" column="2">
 | 
			
		||||
     <widget class="QSpinBox" name="share_deal_reduce_trades_box">
 | 
			
		||||
      <property name="buttonSymbols">
 | 
			
		||||
       <enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="correctionMode">
 | 
			
		||||
       <enum>QAbstractSpinBox::CorrectionMode::CorrectToNearestValue</enum>
 | 
			
		||||
      <property name="maximum">
 | 
			
		||||
       <double>999.000000000000000</double>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
@@ -188,7 +261,7 @@
 | 
			
		||||
   </property>
 | 
			
		||||
   <property name="geometry">
 | 
			
		||||
    <rect>
 | 
			
		||||
     <x>330</x>
 | 
			
		||||
     <x>350</x>
 | 
			
		||||
     <y>270</y>
 | 
			
		||||
     <width>141</width>
 | 
			
		||||
     <height>24</height>
 | 
			
		||||
@@ -198,11 +271,11 @@
 | 
			
		||||
    <string>Save</string>
 | 
			
		||||
   </property>
 | 
			
		||||
  </widget>
 | 
			
		||||
  <widget class="QLabel" name="label">
 | 
			
		||||
  <widget class="QLabel" name="req_field_lab">
 | 
			
		||||
   <property name="geometry">
 | 
			
		||||
    <rect>
 | 
			
		||||
     <x>20</x>
 | 
			
		||||
     <y>270</y>
 | 
			
		||||
     <x>10</x>
 | 
			
		||||
     <y>280</y>
 | 
			
		||||
     <width>191</width>
 | 
			
		||||
     <height>21</height>
 | 
			
		||||
    </rect>
 | 
			
		||||
@@ -211,7 +284,35 @@
 | 
			
		||||
    <string>* Indicates required field</string>
 | 
			
		||||
   </property>
 | 
			
		||||
  </widget>
 | 
			
		||||
  <widget class="QLabel" name="active_lab">
 | 
			
		||||
   <property name="geometry">
 | 
			
		||||
    <rect>
 | 
			
		||||
     <x>437</x>
 | 
			
		||||
     <y>10</y>
 | 
			
		||||
     <width>61</width>
 | 
			
		||||
     <height>16</height>
 | 
			
		||||
    </rect>
 | 
			
		||||
   </property>
 | 
			
		||||
   <property name="text">
 | 
			
		||||
    <string>Active?</string>
 | 
			
		||||
   </property>
 | 
			
		||||
   <property name="alignment">
 | 
			
		||||
    <set>Qt::AlignmentFlag::AlignCenter</set>
 | 
			
		||||
   </property>
 | 
			
		||||
  </widget>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <customwidgets>
 | 
			
		||||
  <customwidget>
 | 
			
		||||
   <class>FastEditQDoubleSpinBox</class>
 | 
			
		||||
   <extends>QDoubleSpinBox</extends>
 | 
			
		||||
   <header>widgets/fastedit_spinbox</header>
 | 
			
		||||
  </customwidget>
 | 
			
		||||
  <customwidget>
 | 
			
		||||
   <class>FastEditQSpinBox</class>
 | 
			
		||||
   <extends>QSpinBox</extends>
 | 
			
		||||
   <header>widgets/fastedit_spinbox</header>
 | 
			
		||||
  </customwidget>
 | 
			
		||||
 </customwidgets>
 | 
			
		||||
 <tabstops>
 | 
			
		||||
  <tabstop>plat_name_box</tabstop>
 | 
			
		||||
  <tabstop>fund_deal_fee_box</tabstop>
 | 
			
		||||
@@ -221,6 +322,13 @@
 | 
			
		||||
  <tabstop>share_deal_reduce_trades_box</tabstop>
 | 
			
		||||
  <tabstop>share_deal_reduce_amount_box</tabstop>
 | 
			
		||||
  <tabstop>save_but</tabstop>
 | 
			
		||||
  <tabstop>plat_name_check</tabstop>
 | 
			
		||||
  <tabstop>fund_deal_fee_check</tabstop>
 | 
			
		||||
  <tabstop>share_plat_fee_check</tabstop>
 | 
			
		||||
  <tabstop>share_plat_max_fee_check</tabstop>
 | 
			
		||||
  <tabstop>share_deal_fee_check</tabstop>
 | 
			
		||||
  <tabstop>share_deal_reduce_trades_check</tabstop>
 | 
			
		||||
  <tabstop>share_deal_reduce_amount_check</tabstop>
 | 
			
		||||
 </tabstops>
 | 
			
		||||
 <resources/>
 | 
			
		||||
 <connections>
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@ class SIPPCompare(QMainWindow):
 | 
			
		||||
 | 
			
		||||
        # Initialise class variables
 | 
			
		||||
        # Inputs
 | 
			
		||||
        self.optional_boxes             = []
 | 
			
		||||
        self.fund_plat_fee              = 0.0
 | 
			
		||||
        self.plat_name                  = ""
 | 
			
		||||
        self.fund_deal_fee              = 0.0
 | 
			
		||||
@@ -39,7 +40,7 @@ class SIPPCompare(QMainWindow):
 | 
			
		||||
        self.actionEdit_Platforms.triggered.connect(self.show_platform_edit)
 | 
			
		||||
        # Update percentage mix label when slider moved
 | 
			
		||||
        self.mix_slider.valueChanged.connect(self.update_slider_lab)
 | 
			
		||||
        #self.value_input.valueChanged.connect(self.check_valid)
 | 
			
		||||
        self.value_input.valueChanged.connect(self.check_valid)
 | 
			
		||||
        self.share_trades_combo.currentTextChanged.connect(self.check_valid)
 | 
			
		||||
        self.fund_trades_combo.currentTextChanged.connect(self.check_valid)
 | 
			
		||||
 | 
			
		||||
@@ -55,24 +56,42 @@ class SIPPCompare(QMainWindow):
 | 
			
		||||
 | 
			
		||||
    def check_valid(self):
 | 
			
		||||
        if self.share_trades_combo.currentText() != "" \
 | 
			
		||||
        and self.fund_trades_combo.currentText() != "":
 | 
			
		||||
        and self.fund_trades_combo.currentText() != "" \
 | 
			
		||||
        and self.value_input.value() != 0:
 | 
			
		||||
            self.calc_but.setEnabled(True)
 | 
			
		||||
        else:
 | 
			
		||||
            self.calc_but.setEnabled(False)
 | 
			
		||||
 | 
			
		||||
    # Get variables from platform editor input fields
 | 
			
		||||
    def init_variables(self):
 | 
			
		||||
        self.plat_name                  = self.platform_win.get_plat_name()
 | 
			
		||||
        self.fund_plat_fee              = self.platform_win.get_fund_plat_fee()
 | 
			
		||||
        self.fund_deal_fee              = self.platform_win.get_fund_deal_fee()
 | 
			
		||||
        self.share_plat_fee             = self.platform_win.get_share_plat_fee()
 | 
			
		||||
        self.share_plat_max_fee         = self.platform_win.get_share_plat_max_fee()
 | 
			
		||||
        self.share_deal_fee             = self.platform_win.get_share_deal_fee()
 | 
			
		||||
        self.share_deal_reduce_trades   = self.platform_win.get_share_deal_reduce_trades()
 | 
			
		||||
        self.share_deal_reduce_amount   = self.platform_win.get_share_deal_reduce_amount()
 | 
			
		||||
        self.optional_boxes     = self.platform_win.get_optional_boxes()
 | 
			
		||||
        self.fund_plat_fee      = self.platform_win.get_fund_plat_fee()
 | 
			
		||||
        self.fund_deal_fee      = self.platform_win.get_fund_deal_fee()
 | 
			
		||||
        self.share_plat_fee     = self.platform_win.get_share_plat_fee()
 | 
			
		||||
        self.share_deal_fee     = self.platform_win.get_share_deal_fee()
 | 
			
		||||
 | 
			
		||||
        # TODO: This is HORRIBLE - find better way of doing it! (maybe enums?)
 | 
			
		||||
        if self.optional_boxes[0]:
 | 
			
		||||
            self.plat_name = self.platform_win.get_plat_name()
 | 
			
		||||
        else:
 | 
			
		||||
            self.plat_name = None
 | 
			
		||||
 | 
			
		||||
        if self.optional_boxes[1]:
 | 
			
		||||
            self.share_plat_max_fee = self.platform_win.get_share_plat_max_fee()
 | 
			
		||||
        else:
 | 
			
		||||
            self.share_plat_max_fee = None
 | 
			
		||||
 | 
			
		||||
        if self.optional_boxes[2]:
 | 
			
		||||
            self.share_deal_reduce_trades = self.platform_win.get_share_deal_reduce_trades()
 | 
			
		||||
        else:
 | 
			
		||||
            self.share_deal_reduce_trades = None
 | 
			
		||||
 | 
			
		||||
        if self.optional_boxes[3]:
 | 
			
		||||
            self.share_deal_reduce_amount = self.platform_win.get_share_deal_reduce_amount()
 | 
			
		||||
        else:
 | 
			
		||||
            self.share_deal_reduce_amount = None
 | 
			
		||||
 | 
			
		||||
    # Calculate fees
 | 
			
		||||
    # TODO: Error checking on combo boxes
 | 
			
		||||
    def calculate_fees(self):
 | 
			
		||||
        self.init_variables()
 | 
			
		||||
        # Set to zero each time to avoid persistence
 | 
			
		||||
@@ -98,13 +117,15 @@ class SIPPCompare(QMainWindow):
 | 
			
		||||
                break
 | 
			
		||||
 | 
			
		||||
        shares_value = (1 - (slider_val / 100)) * value_num
 | 
			
		||||
        if (self.share_plat_fee * shares_value / 12) > self.share_plat_max_fee:
 | 
			
		||||
        if self.share_plat_max_fee is not None and \
 | 
			
		||||
        (self.share_plat_fee * shares_value / 12) > self.share_plat_max_fee:
 | 
			
		||||
            self.share_plat_fees = self.share_plat_max_fee * 12
 | 
			
		||||
        else:
 | 
			
		||||
            self.share_plat_fees = self.share_plat_fee * shares_value
 | 
			
		||||
 | 
			
		||||
        share_trades_num = int(self.share_trades_combo.currentText())
 | 
			
		||||
        if (share_trades_num / 12) >= self.share_deal_reduce_trades:
 | 
			
		||||
        if self.share_deal_reduce_trades is not None and \
 | 
			
		||||
        (share_trades_num / 12) >= self.share_deal_reduce_trades:
 | 
			
		||||
            self.share_deal_fees = self.share_deal_reduce_amount * share_trades_num
 | 
			
		||||
        else:
 | 
			
		||||
            self.share_deal_fees = self.share_deal_fee * share_trades_num
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,12 @@ class OutputWindow(QWidget):
 | 
			
		||||
        cur_time = datetime.datetime.now()
 | 
			
		||||
        if not os.path.exists("output"):
 | 
			
		||||
            os.makedirs("output")
 | 
			
		||||
        filename_str = f"output/{self.platform_name}-{cur_time.year}.{cur_time.month}.{cur_time.day}.txt"
 | 
			
		||||
        filename_str = f"output/"
 | 
			
		||||
        if self.platform_name is not None:
 | 
			
		||||
            filename_str += f"{self.platform_name}"
 | 
			
		||||
        else:
 | 
			
		||||
            filename_str += "Unnamed"
 | 
			
		||||
        filename_str += f"-{cur_time.year}.{cur_time.month}.{cur_time.day}.txt"
 | 
			
		||||
        output_file = open(filename_str, "wt", encoding = "utf-8")
 | 
			
		||||
        output_file.write(self.results_str)
 | 
			
		||||
 | 
			
		||||
@@ -31,7 +36,10 @@ class OutputWindow(QWidget):
 | 
			
		||||
    def display_output(self, fund_plat_fees: float, fund_deal_fees: float,
 | 
			
		||||
                       share_plat_fees: float, share_deal_fees: float, plat_name: str):
 | 
			
		||||
        self.platform_name = plat_name
 | 
			
		||||
        self.results_str = f"Fees breakdown (Platform \"{self.platform_name}\"):"
 | 
			
		||||
        if self.platform_name is not None:
 | 
			
		||||
            self.results_str = f"Fees breakdown (Platform \"{self.platform_name}\"):"
 | 
			
		||||
        else:
 | 
			
		||||
            self.results_str = f"Fees breakdown:"
 | 
			
		||||
 | 
			
		||||
        self.results_str += "\n\nPlatform fees:"
 | 
			
		||||
        # :.2f is used in order to display 2 decimal places (currency form)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
from PyQt6.QtCore import QRegularExpression, QEvent, QObject, QTimer
 | 
			
		||||
from PyQt6.QtCore import QRegularExpression
 | 
			
		||||
from PyQt6.QtGui import QRegularExpressionValidator
 | 
			
		||||
from PyQt6.QtWidgets import QWidget
 | 
			
		||||
from PyQt6 import uic
 | 
			
		||||
@@ -13,6 +13,9 @@ class PlatformEdit(QWidget):
 | 
			
		||||
        uic.loadUi("gui/platform_edit.ui", self)
 | 
			
		||||
 | 
			
		||||
        # Initialise class variables
 | 
			
		||||
        # Create main window object, passing this instance as param
 | 
			
		||||
        self.main_win = main_window.SIPPCompare(self)
 | 
			
		||||
 | 
			
		||||
        # TODO: Make fund_plat_fee user-defined
 | 
			
		||||
        self.fund_plat_fee = [
 | 
			
		||||
            [0, 250000, 1000000, 2000000],
 | 
			
		||||
@@ -30,23 +33,49 @@ class PlatformEdit(QWidget):
 | 
			
		||||
        if autofill:
 | 
			
		||||
            self.save_but.setEnabled(True)
 | 
			
		||||
 | 
			
		||||
        # Create main window object, passing this instance as param
 | 
			
		||||
        self.main_win = main_window.SIPPCompare(self)
 | 
			
		||||
        self.required_fields = [
 | 
			
		||||
            self.fund_deal_fee_box,
 | 
			
		||||
            self.share_plat_fee_box,
 | 
			
		||||
            self.share_deal_fee_box
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        self.optional_fields = [
 | 
			
		||||
            self.plat_name_box,
 | 
			
		||||
            self.share_plat_max_fee_box,
 | 
			
		||||
            self.share_deal_reduce_trades_box,
 | 
			
		||||
            self.share_deal_reduce_amount_box
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        self.optional_check_boxes = [
 | 
			
		||||
            self.plat_name_check,
 | 
			
		||||
            self.share_plat_max_fee_check,
 | 
			
		||||
            self.share_deal_reduce_trades_check,
 | 
			
		||||
            self.share_deal_reduce_amount_check
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        self.check_boxes_ticked = [
 | 
			
		||||
            True,
 | 
			
		||||
            False,
 | 
			
		||||
            False,
 | 
			
		||||
            False
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        # Handle events
 | 
			
		||||
        for field in self.required_fields:
 | 
			
		||||
            field.valueChanged.connect(self.check_valid)
 | 
			
		||||
 | 
			
		||||
        for field in self.optional_fields:
 | 
			
		||||
            field_type = field.staticMetaObject.className()
 | 
			
		||||
            if field_type == "QLineEdit":
 | 
			
		||||
                field.textChanged.connect(self.check_valid)
 | 
			
		||||
            elif field_type == "FastEditQDoubleSpinBox" or field_type == "FastEditQSpinBox":
 | 
			
		||||
                field.valueChanged.connect(self.check_valid)
 | 
			
		||||
 | 
			
		||||
        for check_box in self.optional_check_boxes:
 | 
			
		||||
            check_box.checkStateChanged.connect(self.check_valid)
 | 
			
		||||
 | 
			
		||||
        # NOTE: Signal defined in UI file to close window when save button clicked
 | 
			
		||||
        self.save_but.clicked.connect(self.init_variables)
 | 
			
		||||
        self.fund_deal_fee_box.valueChanged.connect(self.check_valid)
 | 
			
		||||
        self.share_plat_fee_box.valueChanged.connect(self.check_valid)
 | 
			
		||||
        self.share_deal_fee_box.valueChanged.connect(self.check_valid)
 | 
			
		||||
 | 
			
		||||
        # Install event filter on input boxes in order to select all text on focus
 | 
			
		||||
        self.fund_deal_fee_box.installEventFilter(self)
 | 
			
		||||
        self.share_plat_fee_box.installEventFilter(self)
 | 
			
		||||
        self.share_plat_max_fee_box.installEventFilter(self)
 | 
			
		||||
        self.share_deal_fee_box.installEventFilter(self)
 | 
			
		||||
        self.share_deal_reduce_trades_box.installEventFilter(self)
 | 
			
		||||
        self.share_deal_reduce_amount_box.installEventFilter(self)
 | 
			
		||||
 | 
			
		||||
        # Set validators
 | 
			
		||||
        # Regex accepts any characters that match [a-Z], [0-9] or _
 | 
			
		||||
@@ -77,33 +106,54 @@ class PlatformEdit(QWidget):
 | 
			
		||||
        # Once user input is received show main window
 | 
			
		||||
        self.main_win.show()
 | 
			
		||||
 | 
			
		||||
    # When focus is given to an input box, select all text in it (easier to edit)
 | 
			
		||||
    def eventFilter(self, obj: QObject, event: QEvent):
 | 
			
		||||
        if event.type() == QEvent.Type.FocusIn:
 | 
			
		||||
            # Alternative condition for % suffix - currently unused
 | 
			
		||||
            #if obj.value() == 0 or obj == self.share_plat_fee_box:
 | 
			
		||||
            QTimer.singleShot(0, obj.selectAll)
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
    # Check if all required fields have valid (non-zero) input
 | 
			
		||||
    # TODO: Find a better way of doing this if possible
 | 
			
		||||
    # This method does multiple things in order to validate the user's inputs:
 | 
			
		||||
    # 1) Check all required fields have a non-zero value
 | 
			
		||||
    # 2) If an optional checkbox is toggled: toggle editing of the corresponding field
 | 
			
		||||
    # 3) Check all optional fields the user has picked have a non-zero value
 | 
			
		||||
    # 4) If the above two conditions are met (1 & 3), make the 'Save' button clickable
 | 
			
		||||
    # 5) Keep a record of which optional fields the user has chosen to fill in
 | 
			
		||||
    # It's called when an optional check box emits a checkStateChanged() signal
 | 
			
		||||
    # It's also called when any field emits a textChanged() or valueChanged() signal
 | 
			
		||||
    def check_valid(self):
 | 
			
		||||
        values = [self.fund_deal_fee_box.value(),
 | 
			
		||||
                  self.share_plat_fee_box.value(),
 | 
			
		||||
                  self.share_deal_fee_box.value()
 | 
			
		||||
                ]
 | 
			
		||||
        valid = True
 | 
			
		||||
 | 
			
		||||
        for value in values:
 | 
			
		||||
            if value == 0:
 | 
			
		||||
        # Check all required fields have a non-zero value
 | 
			
		||||
        for field in self.required_fields:
 | 
			
		||||
            if field.value() == 0:
 | 
			
		||||
                valid = False
 | 
			
		||||
 | 
			
		||||
        for i in range(len(self.optional_check_boxes)):
 | 
			
		||||
            # Find the coordinates of the input box corresponding to the checkbox
 | 
			
		||||
            # It will be on the same row, in the column to the left (-1)
 | 
			
		||||
            check_box_idx = self.gridLayout.indexOf(self.optional_check_boxes[i])
 | 
			
		||||
            check_box_pos = self.gridLayout.getItemPosition(check_box_idx)
 | 
			
		||||
            input_box_pos = list(check_box_pos)[:2]
 | 
			
		||||
            input_box_pos[1] -= 1
 | 
			
		||||
            # Return copy of input field widget from its coordinates
 | 
			
		||||
            input_box_item = self.gridLayout.itemAtPosition(input_box_pos[0], input_box_pos[1]).widget()
 | 
			
		||||
            if self.optional_check_boxes[i].isChecked():
 | 
			
		||||
                input_box_item.setEnabled(True)
 | 
			
		||||
                self.check_boxes_ticked[i] = True
 | 
			
		||||
                input_box_type = input_box_item.staticMetaObject.className()
 | 
			
		||||
                if input_box_type == "QLineEdit":
 | 
			
		||||
                    if input_box_item.text() == "":
 | 
			
		||||
                        valid = False
 | 
			
		||||
                elif input_box_type == "FastEditQDoubleSpinBox" or input_box_type == "FastEditQSpinBox":
 | 
			
		||||
                    if input_box_item.value() == 0:
 | 
			
		||||
                        valid = False
 | 
			
		||||
            else:
 | 
			
		||||
                input_box_item.setEnabled(False)
 | 
			
		||||
                self.check_boxes_ticked[i] = False
 | 
			
		||||
 | 
			
		||||
        if valid:
 | 
			
		||||
            self.save_but.setEnabled(True)
 | 
			
		||||
        else:
 | 
			
		||||
            self.save_but.setEnabled(False)
 | 
			
		||||
 | 
			
		||||
    # Getter functions (is this necessary? maybe directly reading class vars would be best...)
 | 
			
		||||
    def get_optional_boxes(self):
 | 
			
		||||
        return self.check_boxes_ticked
 | 
			
		||||
 | 
			
		||||
    def get_plat_name(self):
 | 
			
		||||
        return self.plat_name
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								src/widgets/fastedit_spinbox.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/widgets/fastedit_spinbox.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
from PyQt6.QtCore import QTimer
 | 
			
		||||
from PyQt6.QtWidgets import QSpinBox, QDoubleSpinBox
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FastEditQDoubleSpinBox(QDoubleSpinBox):
 | 
			
		||||
    def focusInEvent(self, e):
 | 
			
		||||
        QTimer.singleShot(0, self.selectAll)
 | 
			
		||||
        super(FastEditQDoubleSpinBox, self).focusInEvent(e)
 | 
			
		||||
 | 
			
		||||
class FastEditQSpinBox(QSpinBox):
 | 
			
		||||
    def focusInEvent(self, e):
 | 
			
		||||
        QTimer.singleShot(0, self.selectAll)
 | 
			
		||||
        super(FastEditQSpinBox, self).focusInEvent(e)
 | 
			
		||||
		Reference in New Issue
	
	Block a user