diff --git a/allocation.sql b/allocation.sql index f29d4b2..7cb9787 100644 --- a/allocation.sql +++ b/allocation.sql @@ -1,6 +1,7 @@ -INSERT INTO "allocation" VALUES(5,'Obligations',20,28.899999999999998578,74481.0); -INSERT INTO "allocation" VALUES(10,'Actions World',60,54.0,139404.14999999999418); -INSERT INTO "allocation" VALUES(12,'Cash',2,2.2000000000000001776,5591.0000000000000001); -INSERT INTO "allocation" VALUES(16,'Actions REITS',2,6.0999999999999996447,15607.200000000000727); -INSERT INTO "allocation" VALUES(17,'Actions Moment',15,8.1999999999999992894,21223.43999999999869); -INSERT INTO "allocation" VALUES(19,'Crypto',1,0.59999999999999997779,1623.349999999999909); +INSERT INTO "allocation" (no_cat, classe, pc_cible, pc_atteint, valeur, type, ordre, bg_color, pc_ecart) VALUES(5,'Obligations',22,28.30000000000000071,74481.0,'AUTRE',40,'success',6.3000000000000007105); +INSERT INTO "allocation" (no_cat, classe, pc_cible, pc_atteint, valeur, type, ordre, bg_color, pc_ecart) VALUES(10,'Actions World',60,54.200000000000002841,142781.26000000000931,'ACTION',30,'warning',-5.7999999999999971578); +INSERT INTO "allocation" (no_cat, classe, pc_cible, pc_atteint, valeur, type, ordre, bg_color, pc_ecart) VALUES(12,'Cash',2,2.1000000000000000888,5591.0000000000000001,'AUTRE',60,'success',0.10000000000000008881); +INSERT INTO "allocation" (no_cat, classe, pc_cible, pc_atteint, valeur, type, ordre, bg_color, pc_ecart) VALUES(16,'Actions REITS',5,6.2999999999999998223,16690.799999999999273,'ACTION',12,'danger',1.2999999999999998223); +INSERT INTO "allocation" (no_cat, classe, pc_cible, pc_atteint, valeur, type, ordre, bg_color, pc_ecart) VALUES(17,'Actions Moment',10,8.5,22332.240000000001601,'ACTION',5,'danger',-1.5); +INSERT INTO "allocation" (no_cat, classe, pc_cible, pc_atteint, valeur, type, ordre, bg_color, pc_ecart) VALUES(19,'Crypto',1,0.59999999999999997779,1700.6400000000001,'ACTION',31,'warning',-0.4000000000000000222); + diff --git a/cao_blogr.sqlite b/cao_blogr.sqlite index 53bf70d..228736f 100644 Binary files a/cao_blogr.sqlite and b/cao_blogr.sqlite differ diff --git a/cao_blogr/alembic/versions/20230123_19d939dbc6d0.py b/cao_blogr/alembic/versions/20230123_19d939dbc6d0.py deleted file mode 100644 index b2e81e2..0000000 --- a/cao_blogr/alembic/versions/20230123_19d939dbc6d0.py +++ /dev/null @@ -1,81 +0,0 @@ -"""add portfolio tables - -Revision ID: 19d939dbc6d0 -Revises: 7995372bd306 -Create Date: 2023-01-23 14:49:31.713228 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = '19d939dbc6d0' -down_revision = '7995372bd306' -branch_labels = None -depends_on = None - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.create_table('actifs', - sa.Column('no_id', sa.Integer(), nullable=False), - sa.Column('symbole', sa.Unicode(length=45), nullable=False), - sa.Column('libelle', sa.Unicode(length=45), nullable=False), - sa.Column('classe', sa.Unicode(length=45), nullable=False), - sa.Column('nombre', sa.Integer(), nullable=True), - sa.Column('cours', sa.Float(), nullable=True), - sa.Column('pru', sa.Float(), nullable=True), - sa.Column('valeur', sa.Float(), nullable=True), - sa.Column('plus_value', sa.Float(), nullable=True), - sa.Column('pc_plusvalue', sa.Float(), nullable=True), - sa.Column('rendement', sa.Float(), nullable=True), - sa.Column('pc_rdt', sa.Float(), nullable=True), - sa.Column('pc_allocation', sa.Float(), nullable=True), - sa.Column('ter', sa.Float(), nullable=True), - sa.Column('ter_pondere', sa.Float(), nullable=True), - sa.Column('devise', sa.Unicode(length=45), nullable=True), - sa.Column('parite', sa.Float(), nullable=True), - sa.Column('website', sa.Unicode(length=100), nullable=True), - sa.Column('modif_le', sa.DateTime(), nullable=True), - sa.PrimaryKeyConstraint('no_id', name=op.f('pk_actifs')), - sa.UniqueConstraint('symbole', name=op.f('uq_actifs_symbole')) - ) - op.create_index('symbole_index', 'actifs', ['symbole'], unique=False) - op.create_table('allocation', - sa.Column('no_cat', sa.Integer(), nullable=False), - sa.Column('classe', sa.Unicode(length=45), nullable=False), - sa.Column('pc_cible', sa.Integer(), nullable=True), - sa.Column('pc_atteint', sa.Float(), nullable=True), - sa.Column('valeur', sa.Float(), nullable=True), - sa.PrimaryKeyConstraint('no_cat', name=op.f('pk_allocation')) - ) - op.create_table('classes', - sa.Column('classe', sa.Unicode(), nullable=False), - sa.Column('type', sa.Unicode(length=45), nullable=True), - sa.Column('ordre', sa.Integer(), nullable=True), - sa.Column('bg_color', sa.Unicode(length=45), nullable=True), - sa.PrimaryKeyConstraint('classe', name=op.f('pk_classes')) - ) - op.create_index('ordre_index', 'classes', ['ordre'], unique=False) - op.create_table('histo', - sa.Column('no_id', sa.Integer(), nullable=False), - sa.Column('date', sa.DateTime(), nullable=True), - sa.Column('mvt_cash', sa.Float(), nullable=True), - sa.Column('valeur_pf', sa.Float(), nullable=True), - sa.Column('nb_part', sa.Float(), nullable=True), - sa.Column('val_part', sa.Float(), nullable=True), - sa.Column('cours_ref', sa.Float(), nullable=True), - sa.Column('val_part_ref', sa.Float(), nullable=True), - sa.PrimaryKeyConstraint('no_id', name=op.f('pk_histo')) - ) - # ### end Alembic commands ### - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.drop_table('histo') - op.drop_index('ordre_index', table_name='classes') - op.drop_table('classes') - op.drop_table('allocation') - op.drop_index('symbole_index', table_name='actifs') - op.drop_table('actifs') - # ### end Alembic commands ### diff --git a/cao_blogr/alembic/versions/20230123_7995372bd306.py b/cao_blogr/alembic/versions/20230123_7995372bd306.py deleted file mode 100644 index 60f88ff..0000000 --- a/cao_blogr/alembic/versions/20230123_7995372bd306.py +++ /dev/null @@ -1,26 +0,0 @@ -"""add portfolio tables - -Revision ID: 7995372bd306 -Revises: fe8f8a5bfdb5 -Create Date: 2023-01-23 14:43:22.632056 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = '7995372bd306' -down_revision = 'fe8f8a5bfdb5' -branch_labels = None -depends_on = None - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - pass - # ### end Alembic commands ### - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - pass - # ### end Alembic commands ### diff --git a/cao_blogr/alembic/versions/20230123_fe8f8a5bfdb5.py b/cao_blogr/alembic/versions/20230123_fe8f8a5bfdb5.py deleted file mode 100644 index b6cca3a..0000000 --- a/cao_blogr/alembic/versions/20230123_fe8f8a5bfdb5.py +++ /dev/null @@ -1,26 +0,0 @@ -"""add portfolio tables - -Revision ID: fe8f8a5bfdb5 -Revises: -Create Date: 2023-01-23 14:42:10.171291 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = 'fe8f8a5bfdb5' -down_revision = None -branch_labels = None -depends_on = None - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - pass - # ### end Alembic commands ### - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - pass - # ### end Alembic commands ### diff --git a/cao_blogr/alembic/versions/20230126_42a297861f20.py b/cao_blogr/alembic/versions/20230126_42a297861f20.py deleted file mode 100644 index ef8807b..0000000 --- a/cao_blogr/alembic/versions/20230126_42a297861f20.py +++ /dev/null @@ -1,30 +0,0 @@ -"""added relationship allocation-classe - -Revision ID: 42a297861f20 -Revises: 19d939dbc6d0 -Create Date: 2023-01-26 14:23:42.771763 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = '42a297861f20' -down_revision = '19d939dbc6d0' -branch_labels = None -depends_on = None - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.add_column('allocation', sa.Column('classe_id', sa.Unicode(length=45), nullable=True)) - op.create_foreign_key(op.f('fk_allocation_classe_id_classes'), 'allocation', 'classes', ['classe_id'], ['classe']) - op.drop_column('allocation', 'classe') - # ### end Alembic commands ### - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.add_column('allocation', sa.Column('classe', sa.VARCHAR(length=45), nullable=False)) - op.drop_constraint(op.f('fk_allocation_classe_id_classes'), 'allocation', type_='foreignkey') - op.drop_column('allocation', 'classe_id') - # ### end Alembic commands ### diff --git a/cao_blogr/alembic/versions/20230126_bbfb79cb9dad.py b/cao_blogr/alembic/versions/20230126_bbfb79cb9dad.py deleted file mode 100644 index bfadaf4..0000000 --- a/cao_blogr/alembic/versions/20230126_bbfb79cb9dad.py +++ /dev/null @@ -1,34 +0,0 @@ -"""added relationship allocation-classe - -Revision ID: bbfb79cb9dad -Revises: 42a297861f20 -Create Date: 2023-01-26 14:41:29.955558 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = 'bbfb79cb9dad' -down_revision = '42a297861f20' -branch_labels = None -depends_on = None - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.create_table('allocation', - sa.Column('no_cat', sa.Integer(), nullable=False), - sa.Column('classe_id', sa.Unicode(length=45), nullable=True), - sa.Column('pc_cible', sa.Integer(), nullable=True), - sa.Column('pc_atteint', sa.Float(), nullable=True), - sa.Column('valeur', sa.Float(), nullable=True), - sa.ForeignKeyConstraint(['classe_id'], ['classes.classe'], name=op.f('fk_allocation_classe_id_classes')), - sa.PrimaryKeyConstraint('no_cat', name=op.f('pk_allocation')) - ) - # ### end Alembic commands ### - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.drop_table('allocation') - # ### end Alembic commands ### diff --git a/cao_blogr/alembic/versions/20230129_b8f8216d72c7.py b/cao_blogr/alembic/versions/20230129_b8f8216d72c7.py new file mode 100644 index 0000000..ef6baed --- /dev/null +++ b/cao_blogr/alembic/versions/20230129_b8f8216d72c7.py @@ -0,0 +1,42 @@ +"""added foreign key to allocation + +Revision ID: b8f8216d72c7 +Revises: +Create Date: 2023-01-29 12:20:48.097107 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'b8f8216d72c7' +down_revision = None +branch_labels = None +depends_on = None + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('allocation', + sa.Column('no_cat', sa.Integer(), nullable=False), + sa.Column('classe', sa.Unicode(length=45), nullable=True), + sa.Column('pc_cible', sa.Integer(), nullable=True), + sa.Column('pc_atteint', sa.Float(), nullable=True), + sa.Column('pc_ecart', sa.Float(), nullable=True), + sa.Column('valeur', sa.Float(), nullable=True), + sa.Column('type', sa.Unicode(length=45), nullable=True), + sa.Column('ordre', sa.Integer(), nullable=True), + sa.Column('bg_color', sa.Unicode(length=45), nullable=True), + sa.ForeignKeyConstraint(['classe'], ['actifs.classe'], name=op.f('fk_allocation_classe_actifs')), + sa.PrimaryKeyConstraint('no_cat', name=op.f('pk_allocation')) + ) + op.create_index('classe_index', 'allocation', ['classe'], unique=False) + op.create_index('ordre_index', 'allocation', ['ordre'], unique=False) + # ### end Alembic commands ### + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index('ordre_index', table_name='allocation') + op.drop_index('classe_index', table_name='allocation') + op.drop_table('allocation') + # ### end Alembic commands ### diff --git a/cao_blogr/forms.py b/cao_blogr/forms.py index 35fee4c..6fcf091 100644 --- a/cao_blogr/forms.py +++ b/cao_blogr/forms.py @@ -22,13 +22,11 @@ class BlogSearchForm(Form): class TagForm(Form): id = IntegerField(widget=HiddenInput()) - tag = StringField('Tag', validators=[InputRequired(), Length(min=1, max=25)], - filters=[strip_filter]) + tag = StringField('Tag', validators=[InputRequired(), Length(min=1, max=25)], filters=[strip_filter]) class UserCreateForm(Form): - username = StringField('Nom', validators=[InputRequired(), Length(min=1, max=255)], - filters=[strip_filter]) + username = StringField('Nom', validators=[InputRequired(), Length(min=1, max=255)], filters=[strip_filter]) password = PasswordField('Mot de passe', validators=[InputRequired(), Length(min=6)]) class HistoForm(Form): @@ -37,5 +35,9 @@ class HistoForm(Form): class AllocationForm(Form): no_cat = IntegerField(widget=HiddenInput()) - classe = SelectField('Classe') + classe = StringField('Classe', validators=[InputRequired(), Length(min=1, max=25)], filters=[strip_filter]) pc_cible = IntegerField(validators=[InputRequired()]) + type = SelectField('Type', choices=[('ACTION','ACTION'),('AUTRE','AUTRE')]) + ordre = IntegerField(validators=[InputRequired()]) + bg_color = SelectField('Couleur de fond', choices=[('info','BLEU'),('danger','ROUGE'),('warning','ORANGE'),('success','VERT')]) + diff --git a/cao_blogr/models/portfolio.py b/cao_blogr/models/portfolio.py index e9b2a56..8ab4ba9 100644 --- a/cao_blogr/models/portfolio.py +++ b/cao_blogr/models/portfolio.py @@ -36,25 +36,21 @@ class Actifs(Base): modif_le = Column(DateTime, default=datetime.datetime.utcnow) __table_args__ = (Index('symbole_index', 'symbole'),) + class Allocation(Base): __tablename__ = 'allocation' no_cat = Column(Integer, primary_key=True) - classe_id = Column(Unicode(45), ForeignKey('classes.classe')) + classe = Column(Unicode(45), ForeignKey('actifs.classe')) pc_cible = Column(Integer) pc_atteint = Column(Float) + pc_ecart = Column(Float) valeur = Column(Float) - - # relationship - classe = relationship('Classes', backref="allocation") - -class Classes(Base): - __tablename__ = 'classes' - classe = Column(Unicode(45), primary_key=True) type = Column(Unicode(45), default='ACTION') ordre = Column(Integer) bg_color = Column(Unicode(45)) - __table_args__ = (Index('ordre_index', 'ordre'),) - + __table_args__ = (Index('classe_index', 'classe'), Index('ordre_index', 'ordre'),) + + class Histo(Base): __tablename__ = 'histo' no_id = Column(Integer, primary_key=True) diff --git a/cao_blogr/services/portfolio.py b/cao_blogr/services/portfolio.py index 55c7252..5ead230 100644 --- a/cao_blogr/services/portfolio.py +++ b/cao_blogr/services/portfolio.py @@ -1,6 +1,6 @@ import sqlalchemy as sa from sqlalchemy import func -from ..models.portfolio import Actifs, Allocation, Classes, Histo +from ..models.portfolio import Actifs, Allocation, Histo class PFService(object): @@ -8,7 +8,7 @@ class PFService(object): @classmethod def get_actifs(cls, request, no_id): if no_id == '0': - items = request.dbsession.query(Actifs).order_by(Actifs.classe, Actifs.libelle).all() + items = request.dbsession.query(Actifs, Allocation).join(Allocation).order_by(Allocation.ordre, Actifs.libelle).all() else: # lire une allocation par le no_id items = request.dbsession.query(Actifs).filter(Actifs.no_id == no_id).first() @@ -17,22 +17,13 @@ class PFService(object): @classmethod def get_allocation(cls, request, no_cat): if no_cat == '0': - query = request.dbsession.query(Allocation).join(Classes).filter(Classes.classe == Allocation.classe_id) - query = query.order_by(sa.asc(Allocation.classe_id)).all() + query = request.dbsession.query(Allocation) + query = query.order_by(sa.asc(Allocation.ordre)).all() else: # lire une allocation par le no_id query = request.dbsession.query(Allocation).filter(Allocation.no_cat == no_cat).first() return query - @classmethod - def get_classes(cls, request, classe): - if classe == '0': - items = request.dbsession.query(Classes).order_by(sa.asc(Classes.ordre)).all() - else: - # lire une allocation par le no_id - items = request.dbsession.query(Classes).filter(Classes.classe == classe).first() - return items - @classmethod def get_histo(cls, request, no_id): if no_id == '0': diff --git a/cao_blogr/templates/portfolio/allocation_edit.jinja2 b/cao_blogr/templates/portfolio/allocation_edit.jinja2 index 3d56cb8..8f9c7d1 100644 --- a/cao_blogr/templates/portfolio/allocation_edit.jinja2 +++ b/cao_blogr/templates/portfolio/allocation_edit.jinja2 @@ -17,6 +17,15 @@ {{form.pc_cible(class_='form-control')}} +
| Classe | @@ -118,40 +118,40 @@|||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| {{ ligne.classe }} | - {% if ligne.type=='ACTION' %} -{{ ligne.libelle }} | +{{ ligne.Allocation.classe }} | + {% if ligne.Allocation.type=='ACTION' %} +{{ ligne.Actifs.libelle }} | {% else %} -{{ ligne.libelle }} | +{{ ligne.Actifs.libelle }} | {% endif %} - {% if ligne.devise=='EUR' %} -{{ '{0:0.2f} €'.format(ligne.cours) }} | + {% if ligne.Actifs.devise=='EUR' %} +{{ '{0:0.2f} €'.format(ligne.Actifs.cours) }} | {% else %} -{{ '{0:0.2f} $'.format(ligne.cours) }} | +{{ '{0:0.2f} $'.format(ligne.Actifs.cours) }} | {% endif %} -{{ ligne.nombre }} | -{{ '{0:0.2f} €'.format(ligne.valeur) }} | - {% if ligne.plus_value >= 0 %} -{{ '{0:0.2f} €'.format(ligne.plus_value) }} | -{{ '{0:0.1f}'.format(ligne.pc_plusvalue) }} | +{{ ligne.Actifs.nombre }} | +{{ '{0:0,.2f} €'.format(ligne.Actifs.valeur).replace(',',' ') }} | + {% if ligne.Actifs.plus_value >= 0 %} +{{ '{0:0.2f} €'.format(ligne.Actifs.plus_value) }} | +{{ '{0:0.1f}'.format(ligne.Actifs.pc_plusvalue) }} | {% else %} -{{ '{0:0.2f} €'.format(ligne.plus_value) }} | -{{ '{0:0.1f}'.format(ligne.pc_plusvalue) }} | +{{ '{0:0.2f} €'.format(ligne.Actifs.plus_value) }} | +{{ '{0:0.1f}'.format(ligne.Actifs.pc_plusvalue) }} | {% endif %} -{{ '{0:0.1f}'.format(ligne.ter) }} | -{{ '{0:0.1f}'.format(ligne.pc_allocation) }} | +{{ '{0:0.1f}'.format(ligne.Actifs.ter) }} | +{{ '{0:0.1f}'.format(ligne.Actifs.pc_allocation) }} |
| Total | -{{ '{0:0.2f} €'.format(total_valeur) }} | +{{ '{0:0,.2f} €'.format(total_valeur).replace(',',' ') }} | {% if total_pv >= 0 %} -{{ '{0:0.1f}'.format(total_pv) }} | -{{ '{0:0.2f} €'.format(total_pc_value) }} | +{{ '{0:0.2f} €'.format(total_pv) }} | +{{ '{0:0.1f}'.format(total_pc_value) }} | {% else %} -{{ '{0:0.1f}'.format(total_pv) }} | -{{ '{0:0.2f} €'.format(total_pc_value) }} | +{{ '{0:0.2f} €'.format(total_pv) }} | +{{ '{0:0.1f}'.format(total_pc_value) }} | {% endif %}100.0 | @@ -172,7 +172,7 @@||||||||||||||