Skip to content
Open

11 #31

Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ servers:
security:
# This makes every route by default auth protected
- BearerAuthHeader: [] # Authorization header
- BearerAuthCookie: [] # Token in cookie
- BearerAuthCookie: [] # Token in cookie
components:
securitySchemes:
BearerAuthHeader:
Expand Down Expand Up @@ -59,15 +59,16 @@ components:
type: string
members:
type: array
$ref: "#/components/schemas/Member"
items:
$ref: "#/components/schemas/Member"
items:
type: array
$ref: "#/components/schemas/Item"
items:
$ref: "#/components/schemas/Item"
money_balance:
type: integer
required:
- name
- members
- money_balance
requestBodies:
register:
Expand All @@ -93,7 +94,7 @@ components:
content:
application/json:
schema:
$ref: '#/components/schemas/Item'
$ref: "#/components/schemas/Item"
schemas:
UserCredentials:
type: object
Expand Down Expand Up @@ -127,7 +128,7 @@ components:
properties:
id:
type: integer
# readOnly: true # TODO unfortunately ogen doesn't support readOnly marker. But we want to reuse this schema for posting
# readOnly: true # TODO unfortunately ogen doesn't support readOnly marker. But we want to reuse this schema for posting
# as well as getting for simplicity. So for now, the convention would be to set the id to 0 as it will get ignored either way.
timestamp:
type: integer
Expand All @@ -142,6 +143,12 @@ components:
type: integer
reimbursement:
type: boolean
# New participant list should be returned from expense_participants schema
participants:
type: array
items:
$ref: "#/components/schemas/Member"

required:
- id
- timestamp
Expand All @@ -153,7 +160,7 @@ components:
type: object
properties:
id:
type: string
type: integer
name:
type: string
displayName:
Expand Down
77 changes: 75 additions & 2 deletions server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"context"
"database/sql"
"fmt"
"log"
"net/http"
"os"
Expand Down Expand Up @@ -71,8 +72,80 @@ func (h *Handler) GroupsNonauthedGet(ctx context.Context) ([]api.Group, error) {
}

func (h *Handler) GroupsIDGet(ctx context.Context, params api.GroupsIDGetParams) (*api.GroupOverview, error) {
// TODO task #4
return nil, nil
//IDs
g_id := int64(params.ID)
userid := ctx.Value("user_id").(int64)

//authorID
group, _ := qs.GetGroupByID(ctx, g_id)

// Fetch members of the group
members, _ := qs.GetMembersOfGroup(ctx, g_id)

var apiMembers []api.Member

for _, member := range members {
apiMembers = append(apiMembers, api.Member{
ID: int(member.ID),
Name: member.Username,
})
}
// new schema EP added converting to of type memeber th query of Expense_participants
eps, _ := qs.Expense_participants(ctx, 1)
var ep_members []api.Member

for _, ep := range eps {
ep_members = append(ep_members, api.Member{
ID: int(ep.MemberID),
Name: ep.Username,
DisplayName: ep.Displayname,
})

}
// Fetch items of the group
items, _ := qs.GetItemsOfGroup(ctx, g_id)

var apiItems []api.Item

for _, item := range items {
apiItems = append(apiItems, api.Item{
ID: int(item.ID),
Timestamp: int(item.Timestamp),
Name: item.Name,
Price: item.Price,
AuthorID: int(item.AuthorID),
GroupID: int(g_id),
// The new participant list!!!!!!
Participants: ep_members,
})
}

// Calculate money balance for the group
netAmountParams := data.GetNetAmountForUserInGroupParams{
AuthorID: userid,
GroupID: g_id,
}

netAmount, err := qs.GetNetAmountForUserInGroup(ctx, netAmountParams)
if err != nil {
return nil, fmt.Errorf("failed to fetch net amount: %w", err)
}
var balance int

if netAmount.Valid {
balance = int(netAmount.Float64)
} else {
balance = 0
}

groupOverview := &api.GroupOverview{
Name: group.Name,
Members: apiMembers,
Items: apiItems,
MoneyBalance: balance,
}

return groupOverview, nil
}

func (h *Handler) GroupsIDMembersPost(ctx context.Context, req *api.GroupsIDMembersPostReq, params api.GroupsIDMembersPostParams) error {
Expand Down
22 changes: 22 additions & 0 deletions server/query.sql
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,25 @@ FROM member_groups mg1
INNER JOIN member_groups mg2 ON mg1.group_id = mg2.group_id
WHERE mg1.member_id = ? AND mg2.member_id <> 3
GROUP BY mg2.member_id;


-- name: GetGroupByID :one
SELECT
id,
name
FROM
groups
WHERE
id = ?;

-- name: Expense_participants :many
SELECT
ep.member_id,
i.name AS item_name,
m.username,
m.displayName
FROM expense_participants ep
JOIN items i ON ep.item_id = i.id
JOIN members m ON ep.member_id = m.id
WHERE ep.item_id = ?;

8 changes: 8 additions & 0 deletions server/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,11 @@ CREATE TABLE items ( --bs: medium
FOREIGN KEY (group_id) REFERENCES groups (id),
FOREIGN KEY (author_id) REFERENCES members (id)
);

CREATE TABLE expense_participants (
item_id INTEGER NOT NULL, -- Foreign key referencing the items table
member_id INTEGER NOT NULL, -- Foreign key referencing the members table
PRIMARY KEY (item_id, member_id), -- Composite primary key (ensures unique pairs)
FOREIGN KEY (item_id) REFERENCES items (id), -- Foreign key constraint to items table
FOREIGN KEY (member_id) REFERENCES members (id) -- Foreign key constraint to members table
);
16 changes: 10 additions & 6 deletions web/src/routes/g/[slug]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
import shoppingBagIcon from "@ktibow/iconset-material-symbols/shopping-bag";
import priceIcon from "@ktibow/iconset-material-symbols/price-check";
import check from "@ktibow/iconset-material-symbols/check";
import { PUBLIC_SERVER_URL } from "$env/static/public";
import { PUBLIC_SERVER_URL } from "$env/static/public";
export let data;
let name = "";
let price = "";

let addItem = (e : Event) => {
let addItem = (e: Event) => {
e.preventDefault();
const item = {
id: 14,
Expand All @@ -24,12 +24,10 @@
method: "POST",
body: JSON.stringify(item),
}).then((_) => {
data.items = [item, ...data.items]

data.items = [item, ...data.items];
});
};
let open = true;

</script>

<div class="screen">
Expand Down Expand Up @@ -68,6 +66,12 @@
<div class="fabpos">
<FAB icon={check} size="large"></FAB>
</div>
<div>
<h2>
Balance:
{data.balance}
</h2>
</div>
</form>
</SideSheet>
{/if}
Expand All @@ -78,7 +82,7 @@
display: flex;
align-items: flex-start;
height: 100%;
gap:1rem;
gap: 1rem;
}
.contents {
padding: 1rem;
Expand Down
28 changes: 15 additions & 13 deletions web/src/routes/g/[slug]/+page.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import api from '$lib/api/api';
import { error as errorOut } from '@sveltejs/kit';
import api from "$lib/api/api";
import { error as errorOut } from "@sveltejs/kit";

export async function load({ params }) {
const {
data, // only present if 2XX response
error, // only present if 4XX or 5XX response
response
} = await api.GET("/groups/{id}/items", {params:{path: { id: params.slug}}})
if (response.status != 200) {
errorOut(response.status, response.statusText);
}

return { group_id: params.slug, items: data }

const {
data, // only present if 2XX response
error,
response,
} = await api.GET("/groups/{id}", { params: { path: { id: params.slug } } });
if (response.status != 200) {
errorOut(response.status, response.statusText);
}
return {
items: data!.items,
group_id: params.slug,
balance: data?.money_balance,
};
}