Skip to content

Commit

Permalink
wip #1281 assign user to plans see also #1305
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisjsimpson committed Feb 17, 2024
1 parent 81bfbb7 commit d1c6b77
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 46 deletions.
36 changes: 36 additions & 0 deletions migrations/versions/9083452d3a80_add_catagory_user_associations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""add catagory_user_associations
Revision ID: 9083452d3a80
Revises: 48074e6225c6
Create Date: 2024-02-16 21:38:11.302398
"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = "9083452d3a80"
down_revision = "48074e6225c6"
branch_labels = None
depends_on = None


def upgrade():
op.create_table(
"catagory_user_associations",
sa.Column("category_uuid", sa.String(), nullable=True),
sa.Column("user_id", sa.String(), nullable=True),
sa.ForeignKeyConstraint(
["category_uuid"],
["category.uuid"],
),
sa.ForeignKeyConstraint(
["user_id"],
["user.id"],
),
)


def downgrade():
pass
27 changes: 27 additions & 0 deletions subscribie/blueprints/admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,33 @@ def assign_managers_to_plan():
return render_template("admin/assign_managers_to_plan.html", users=users)


@admin.route("/assign-managers-to-plans/<user_id>/assign-plan", methods=["GET", "POST"])
@login_required
def user_assign_to_plans(user_id):
user = User.query.get(user_id)
plans = Plan.query.execution_options(include_archived=True)

if request.method == "POST":
# Remove if not selected
for plan in plans:
if plan in user.plans:
user.plans.remove(plan)

for plan_id in request.form.getlist("assign"):
plan = Plan.query.execution_options(include_archived=True).get(plan_id)
plan.managers.append(user)

database.session.commit()
flash("User has been assigned the selected plan(s) as a manager of them")
return redirect(url_for("admin.assign_managers_to_plan"))

return render_template(
"admin/user_assign_plan.html",
user=user,
plans=plans,
)


@admin.route("/list-documents", methods=["get"])
@login_required
def list_documents():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ <h2 class="text-center text-dark mb-3">Assign manager(s) to plans</h2>
<ul class="breadcrumb">
<li class="breadcrumb-item"><a href="/">Shop</a></li>
<li class="breadcrumb-item"><a href="{{ url_for('admin.dashboard') }}">Manage My Shop</a></li>
<li class="breadcrumb-item"><a href="{{ url_for('admin.list_choice_groups') }}">Choice Groups</a></li>
<li class="breadcrumb-item active" aria-current="page"> Add / Edit / Delete Choice Group</li>
<li class="breadcrumb-item active"><a href="{{ url_for('admin.assign_managers_to_plan') }}">Assign Manager(s) to plan(s)</a></li>
</ul>
</div>

Expand Down Expand Up @@ -38,44 +37,29 @@ <h3>Allow managers to quickly see plans they're responsible for</h3>

</div>

{% if confirm is sameas false %}
<div class="card mx-auto my-3 py-3 col-md-7">
<h3 class="card-title mx-auto">Are you sure?</h3>
<div class="mx-auto">
<a href="{{ url_for('admin.delete_choice_group', id=choice_group.id) }}"
class="btn btn-danger mx-3 px-5" role="button">
Yes
<table class="table table-hover table-scroll">
<thead>
<th>User</th>
<th>Number of plans managing</th>
<th>Action</th>
</thead>
{% for user in users %}
<tr>
<td>
{{ user.email}}
</td>
<td>
{{ user.plans | length }}
</td>
<td>
<a href="{{ url_for('admin.user_assign_to_plans', user_id=user.id) }}"
class="btn btn-success btn-block" style="display: inline-block" role="button">
Assign Plan(s)
</a>
<a href="{{ url_for('admin.list_choice_groups', cancel=1) }}"
class="btn btn-success mx-3 px-5" role="button">
No
</a>
</div>
</div>
{% else %}
<table class="table table-hover table-scroll">
<thead>
<th>Title</th>
<th></th>
<th></th>
<th></th>
<th></th>
</thead>
{% for user in users %}
<tr>
<td>
{{ user.email}}
</td>
<td>
<a href="{# url_for('admin.choice_group_assign_plan', choice_group_id=choice_group.id) #}"
class="btn btn-success btn-block" style="display: inline-block" role="button">
Assign Plan(s)
</a>
</td>
</tr>
{% endfor %}
</table>
{% endif %}
</td>
</tr>
{% endfor %}
</table>

</div><!--end container-->
</div><!--end section-->
Expand Down
61 changes: 61 additions & 0 deletions subscribie/blueprints/admin/templates/admin/user_assign_plan.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{% extends "admin/layout.html" %}
{% block title %} {{ title }} {% endblock %}

{% block body %}

<h2 class="text-center text-dark mb-3">Choice Group - Assign Plan</h2>

<div class="container">
<ul class="breadcrumb">
<li class="breadcrumb-item"><a href="/">Shop</a></li>
<li class="breadcrumb-item"><a href="{{ url_for('admin.dashboard') }}">Manage My Shop</a></li>
<li class="breadcrumb-item"><a href="{{ url_for('admin.assign_managers_to_plan') }}">Assign Manager(s) to Plan(s)</a></li>
<li class="breadcrumb-item active" aria-current="page">Assign user to plan(s)</li>
</ul>
</div>

<main>
<div class="section">
<div class="container">

<h3>Assign Plan(s) to user: <em>{{ user.email }}</em></h3>
<p class="card-subtitle text-muted">Tick which plan(s) you want to assign the user to</p>
<p class="card-subtitle text-muted mb-3">Doing so will make these plans(s) and any associated subscriptions appear more prominently for them when they login.</p>

<hr>
<div class="btn btn-success mb-4" onclick="toggleCheckboxes(true)">Check all</div>
<div class="btn btn-success mb-4" onclick="toggleCheckboxes(false)">Check none</div>
<form action="" method="POST" class="col-md-7 py-3">
{% for plan in plans %}
{% if plan.subscriptions | length > 0 %}
<div class="input-group mb-3">
<div class="input-group-prepend">
<div class="input-group-text">
<input type="checkbox" name="assign" class="assign-plan-to-manager-checkbox" value="{{ plan.id }}" id="{{ plan.id }}"
{% if user in plan.managers %}
checked
{% endif %}>
</div>
</div>
<label class="form-control" for="{{ plan.id }}">{{ plan.title }}</label> {{ plan.archived }}| Subscriptions: {{ plan.subscriptions|length }}
</div>
{% endif %}
{% endfor %}

<input type="submit" class="btn btn-success btn-block" value="Save" />
</form>

</div><!--end container-->
</div><!--end section-->
</main>

<script>
function toggleCheckboxes(toggle) {
checkboxes = document.getElementsByClassName('assign-plan-to-manager-checkbox')
for (i=0; i<checkboxes.length;i++) {
checkboxes[i].checked = toggle;
}
}
</script>

{% endblock body %}
22 changes: 15 additions & 7 deletions subscribie/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ def filter_archived(query):
if desc["type"] is Person and "archived-subscribers" in request.path:
query = query.filter(entity.archived == 1)
return query
elif desc["type"] is User and "assign-managers-to-plan" in request.path:
query = query.execution_options(include_archived=True)
return query
elif (
desc["type"] is Person
and request.path != "/"
Expand Down Expand Up @@ -108,6 +111,13 @@ class HasReadOnly(object):
read_only = Column(Boolean, nullable=False, default=0)


association_table_plan_to_users = database.Table(
"plan_user_associations",
database.Column("plan_uuid", database.String, ForeignKey("plan.uuid")),
database.Column("user_id", database.String, ForeignKey("user.id")),
)


class User(database.Model):
__tablename__ = "user"
id = database.Column(database.Integer(), primary_key=True)
Expand All @@ -118,6 +128,7 @@ class User(database.Model):
login_token = database.Column(database.String)
password_reset_string = database.Column(database.String())
password_expired = database.Column(database.Boolean(), default=0)
plans = relationship("Plan", secondary=association_table_plan_to_users)

def set_password(self, password):
self.password = generate_password_hash(password)
Expand Down Expand Up @@ -604,12 +615,6 @@ class Company(database.Model):
),
)

association_table_plan_to_users = database.Table(
"plan_user_associations",
database.Column("plan_uuid", database.String, ForeignKey("plan.uuid")),
database.Column("user_id", database.String, ForeignKey("user.id")),
)


class INTERVAL_UNITS(Enum):
DAILY = _("daily")
Expand Down Expand Up @@ -672,10 +677,13 @@ class Plan(database.Model, HasArchived):
price_lists = relationship(
"PriceList", secondary=association_table_plan_to_price_lists
)
subscriptions = relationship(
"Subscription", primaryjoin="foreign(Subscription.sku_uuid)==Plan.uuid"
)
managers = relationship(
"User",
secondary=association_table_plan_to_users,
backref=database.backref("plans", lazy="dynamic"),
backref=database.backref("managers", lazy="dynamic"),
)

def getPrice(self, currency):
Expand Down

0 comments on commit d1c6b77

Please sign in to comment.