@@ -56,7 +59,12 @@ export const Modal: FC
= ({
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
-
+
{
diff --git a/app/javascript/src/components/Table/Table.tsx b/app/javascript/src/components/Table/Table.tsx
new file mode 100644
index 0000000..252e826
--- /dev/null
+++ b/app/javascript/src/components/Table/Table.tsx
@@ -0,0 +1,27 @@
+import type { FC } from "react";
+import React from "react";
+
+type Props = {
+ columns: string[];
+};
+
+export const Table: FC = ({ columns, children }) => {
+ return (
+
+
+
+ {columns.map((column, index) => (
+ |
+ {column}
+ |
+ ))}
+
+
+ {children}
+
+ );
+};
diff --git a/app/javascript/src/components/Table/TableRow.tsx b/app/javascript/src/components/Table/TableRow.tsx
new file mode 100644
index 0000000..6bab7bb
--- /dev/null
+++ b/app/javascript/src/components/Table/TableRow.tsx
@@ -0,0 +1,29 @@
+import type { FC, ReactNode } from "react";
+import React from "react";
+
+type Props = {
+ items?: Array;
+ id?: string;
+ onClick?: (itemId: string) => void;
+};
+
+export const TableRow: FC = ({ items, id, onClick }) => {
+ const handleClick = () => {
+ if (onClick && id) {
+ onClick(id);
+ }
+ };
+
+ return (
+
+ {items?.map((item, index) => (
+ |
+ {item}
+ |
+ ))}
+
+ );
+};
diff --git a/app/javascript/src/components/Table/index.ts b/app/javascript/src/components/Table/index.ts
new file mode 100644
index 0000000..c26fc70
--- /dev/null
+++ b/app/javascript/src/components/Table/index.ts
@@ -0,0 +1,2 @@
+export * from "./Table";
+export * from "./TableRow";
diff --git a/app/javascript/src/components/index.ts b/app/javascript/src/components/index.ts
index 90b1af0..b9980c2 100644
--- a/app/javascript/src/components/index.ts
+++ b/app/javascript/src/components/index.ts
@@ -4,3 +4,4 @@ export * from "./Modal";
export * from "./Input";
export * from "./Button";
export * from "./Spinner";
+export * from "./Table";
diff --git a/app/javascript/src/pages/Orders/Deposit/Deposit.tsx b/app/javascript/src/pages/Orders/Deposit/Deposit.tsx
new file mode 100644
index 0000000..b507458
--- /dev/null
+++ b/app/javascript/src/pages/Orders/Deposit/Deposit.tsx
@@ -0,0 +1,37 @@
+import { graphql } from "babel-plugin-relay/macro";
+import type { FC } from "react";
+import React from "react";
+import { useLazyLoadQuery } from "react-relay";
+
+import type { DepositQuery } from "./__generated__/DepositQuery.graphql";
+import { Messages } from "../../../messages";
+import { History } from "./History";
+
+export const Deposit: FC = () => {
+ const { depositOrders } = useLazyLoadQuery(
+ graphql`
+ query DepositQuery {
+ depositOrders {
+ totalCount
+ ...History_depositOrders
+ }
+ }
+ `,
+ {}
+ );
+
+ if (!depositOrders.totalCount)
+ return ;
+
+ return (
+
+ );
+};
diff --git a/app/javascript/src/pages/Orders/Deposit/History/History.tsx b/app/javascript/src/pages/Orders/Deposit/History/History.tsx
new file mode 100644
index 0000000..a6882d9
--- /dev/null
+++ b/app/javascript/src/pages/Orders/Deposit/History/History.tsx
@@ -0,0 +1,87 @@
+import { graphql } from "babel-plugin-relay/macro";
+import type { FC } from "react";
+import React, { useState } from "react";
+import cs from "classnames";
+import { useFragment } from "react-relay";
+
+import { Table, TableRow } from "../../../../components";
+import { getStatusTextAndColors } from "../../utils/processStatus";
+import { centsToUnit } from "../../../../utils/fiatMoney";
+import type { History_depositOrders$key } from "./__generated__/History_depositOrders.graphql";
+import { Show } from "../Show";
+
+type Props = {
+ ordersRef: History_depositOrders$key;
+};
+
+export const History: FC = ({ ordersRef }) => {
+ const [openOrderId, setOpenOrderId] = useState(null);
+
+ const { edges } = useFragment(
+ graphql`
+ fragment History_depositOrders on DepositOrderConnection {
+ edges {
+ node {
+ id
+ status
+ createdAt
+ paidAmountCents
+ receivedAmountCents
+ ...Show_deposit_order
+ }
+ }
+ }
+ `,
+ ordersRef
+ );
+
+ const openOrder = edges.find(({ node }) => node.id === openOrderId);
+ const onClose = () => setOpenOrderId(null);
+
+ return (
+ <>
+ {openOrder && }
+
+ {edges.map(({ node }) => {
+ const [label, textStyles, bgStyles] = getStatusTextAndColors(
+ node.status
+ );
+
+ const status = (
+
+
+ {label}
+
+ );
+
+ return (
+ setOpenOrderId(orderId)}
+ id={node.id}
+ items={[
+ `${centsToUnit(node.paidAmountCents)} BRL`,
+ `${centsToUnit(node.receivedAmountCents)} BRL`,
+ new Date(node.createdAt as string).toLocaleTimeString(),
+ status,
+ ]}
+ />
+ );
+ })}
+
+ >
+ );
+};
diff --git a/app/javascript/src/pages/Orders/Deposit/History/__generated__/History_depositOrders.graphql.ts b/app/javascript/src/pages/Orders/Deposit/History/__generated__/History_depositOrders.graphql.ts
new file mode 100644
index 0000000..f177211
--- /dev/null
+++ b/app/javascript/src/pages/Orders/Deposit/History/__generated__/History_depositOrders.graphql.ts
@@ -0,0 +1,102 @@
+/* tslint:disable */
+/* eslint-disable */
+// @ts-nocheck
+
+import { ReaderFragment } from "relay-runtime";
+import { FragmentRefs } from "relay-runtime";
+export type ProcessStatus = "CANCELED" | "COMPLETED" | "PROCESSING" | "%future added value";
+export type History_depositOrders = {
+ readonly edges: ReadonlyArray<{
+ readonly node: {
+ readonly id: string;
+ readonly status: ProcessStatus;
+ readonly createdAt: unknown;
+ readonly paidAmountCents: number;
+ readonly receivedAmountCents: number;
+ readonly " $fragmentRefs": FragmentRefs<"Show_deposit_order">;
+ };
+ }>;
+ readonly " $refType": "History_depositOrders";
+};
+export type History_depositOrders$data = History_depositOrders;
+export type History_depositOrders$key = {
+ readonly " $data"?: History_depositOrders$data;
+ readonly " $fragmentRefs": FragmentRefs<"History_depositOrders">;
+};
+
+
+
+const node: ReaderFragment = {
+ "argumentDefinitions": [],
+ "kind": "Fragment",
+ "metadata": null,
+ "name": "History_depositOrders",
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "DepositOrderEdge",
+ "kind": "LinkedField",
+ "name": "edges",
+ "plural": true,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "DepositOrder",
+ "kind": "LinkedField",
+ "name": "node",
+ "plural": false,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "id",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "status",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "createdAt",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "paidAmountCents",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "receivedAmountCents",
+ "storageKey": null
+ },
+ {
+ "args": null,
+ "kind": "FragmentSpread",
+ "name": "Show_deposit_order"
+ }
+ ],
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ }
+ ],
+ "type": "DepositOrderConnection",
+ "abstractKey": null
+};
+(node as any).hash = 'f810eed214d3beb7c443588e670d8f39';
+export default node;
diff --git a/app/javascript/src/pages/Orders/Deposit/History/index.ts b/app/javascript/src/pages/Orders/Deposit/History/index.ts
new file mode 100644
index 0000000..a54747e
--- /dev/null
+++ b/app/javascript/src/pages/Orders/Deposit/History/index.ts
@@ -0,0 +1 @@
+export * from "./History";
diff --git a/app/javascript/src/pages/Orders/Deposit/Show/Show.tsx b/app/javascript/src/pages/Orders/Deposit/Show/Show.tsx
new file mode 100644
index 0000000..5f61dae
--- /dev/null
+++ b/app/javascript/src/pages/Orders/Deposit/Show/Show.tsx
@@ -0,0 +1,94 @@
+import { graphql } from "babel-plugin-relay/macro";
+import type { FC } from "react";
+import React from "react";
+import { useFragment } from "react-relay";
+import copy from "copy-to-clipboard";
+
+import { Button, Modal } from "../../../../components";
+import { usePixQr } from "./hooks/usePixQr";
+import type { Show_deposit_order$key } from "./__generated__/Show_deposit_order.graphql";
+import { centsToUnit } from "../../../../utils/fiatMoney";
+import { getStatusTextAndColors } from "../../utils/processStatus";
+
+type Props = {
+ orderRef: Show_deposit_order$key;
+ onClose: () => void;
+};
+
+export const Show: FC = ({ orderRef, onClose }) => {
+ const order = useFragment(
+ graphql`
+ fragment Show_deposit_order on DepositOrder {
+ transactionId
+ paidAmountCents
+ receivedAmountCents
+ status
+ createdAt
+ }
+ `,
+ orderRef
+ );
+
+ const { qr, payload } = usePixQr({
+ value: order.paidAmountCents / 100,
+ transactionId: order.transactionId,
+ });
+
+ const handleClose = (_value: boolean) => {
+ onClose();
+ };
+
+ const handleCopy = () => {
+ copy(payload);
+ };
+
+ const [statusLabel] = getStatusTextAndColors(order.status);
+
+ return (
+
+
+
+
+ -
+ Montante pago:{" "}
+
+ {centsToUnit(order.paidAmountCents)} BRL
+
+
+ -
+ Montante recebido:{" "}
+
+ {centsToUnit(order.receivedAmountCents)}
+
+
+ -
+ Pedido feito em:{" "}
+
+ {new Date(order.createdAt as string).toLocaleTimeString()}
+
+
+ -
+ Metodo de pagamento: PIX
+
+ -
+ Status: {statusLabel}
+
+
+
+
+

+
+
+
+
+ );
+};
diff --git a/app/javascript/src/pages/Orders/Deposit/Show/__generated__/Show_deposit_order.graphql.ts b/app/javascript/src/pages/Orders/Deposit/Show/__generated__/Show_deposit_order.graphql.ts
new file mode 100644
index 0000000..8ffbd48
--- /dev/null
+++ b/app/javascript/src/pages/Orders/Deposit/Show/__generated__/Show_deposit_order.graphql.ts
@@ -0,0 +1,70 @@
+/* tslint:disable */
+/* eslint-disable */
+// @ts-nocheck
+
+import { ReaderFragment } from "relay-runtime";
+import { FragmentRefs } from "relay-runtime";
+export type ProcessStatus = "CANCELED" | "COMPLETED" | "PROCESSING" | "%future added value";
+export type Show_deposit_order = {
+ readonly transactionId: string;
+ readonly paidAmountCents: number;
+ readonly receivedAmountCents: number;
+ readonly status: ProcessStatus;
+ readonly createdAt: unknown;
+ readonly " $refType": "Show_deposit_order";
+};
+export type Show_deposit_order$data = Show_deposit_order;
+export type Show_deposit_order$key = {
+ readonly " $data"?: Show_deposit_order$data;
+ readonly " $fragmentRefs": FragmentRefs<"Show_deposit_order">;
+};
+
+
+
+const node: ReaderFragment = {
+ "argumentDefinitions": [],
+ "kind": "Fragment",
+ "metadata": null,
+ "name": "Show_deposit_order",
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "transactionId",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "paidAmountCents",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "receivedAmountCents",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "status",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "createdAt",
+ "storageKey": null
+ }
+ ],
+ "type": "DepositOrder",
+ "abstractKey": null
+};
+(node as any).hash = '73e84cef63c17faa3087f19ba2c73e69';
+export default node;
diff --git a/app/javascript/src/pages/Orders/Deposit/Show/hooks/usePixQr.ts b/app/javascript/src/pages/Orders/Deposit/Show/hooks/usePixQr.ts
new file mode 100644
index 0000000..dfbc310
--- /dev/null
+++ b/app/javascript/src/pages/Orders/Deposit/Show/hooks/usePixQr.ts
@@ -0,0 +1,33 @@
+import { useEffect, useState } from "react";
+import { QrCodePix } from "qrcode-pix";
+
+type Props = {
+ value: number;
+ transactionId: string;
+};
+
+export const usePixQr = ({ value, transactionId }: Props) => {
+ const [qr, setQr] = useState();
+
+ const qrCodePix = QrCodePix({
+ version: "01",
+ key: "joao.geonizeli@gmail.com",
+ name: "X Stake",
+ city: "TERESOPOLIS",
+ transactionId,
+ value,
+ notRepeatPayment: true,
+ });
+
+ useEffect(() => {
+ qrCodePix.base64().then((result) => {
+ setQr(result);
+ });
+ }, []);
+
+ return {
+ payload: qrCodePix.payload(),
+ loading: !qr,
+ qr,
+ };
+};
diff --git a/app/javascript/src/pages/Orders/Deposit/Show/index.ts b/app/javascript/src/pages/Orders/Deposit/Show/index.ts
new file mode 100644
index 0000000..af83ede
--- /dev/null
+++ b/app/javascript/src/pages/Orders/Deposit/Show/index.ts
@@ -0,0 +1 @@
+export * from "./Show";
diff --git a/app/javascript/src/pages/Orders/Deposit/__generated__/DepositQuery.graphql.ts b/app/javascript/src/pages/Orders/Deposit/__generated__/DepositQuery.graphql.ts
new file mode 100644
index 0000000..0bcf7ef
--- /dev/null
+++ b/app/javascript/src/pages/Orders/Deposit/__generated__/DepositQuery.graphql.ts
@@ -0,0 +1,182 @@
+/* tslint:disable */
+/* eslint-disable */
+// @ts-nocheck
+
+import { ConcreteRequest } from "relay-runtime";
+import { FragmentRefs } from "relay-runtime";
+export type DepositQueryVariables = {};
+export type DepositQueryResponse = {
+ readonly depositOrders: {
+ readonly totalCount: number;
+ readonly " $fragmentRefs": FragmentRefs<"History_depositOrders">;
+ };
+};
+export type DepositQuery = {
+ readonly response: DepositQueryResponse;
+ readonly variables: DepositQueryVariables;
+};
+
+
+
+/*
+query DepositQuery {
+ depositOrders {
+ totalCount
+ ...History_depositOrders
+ }
+}
+
+fragment History_depositOrders on DepositOrderConnection {
+ edges {
+ node {
+ id
+ status
+ createdAt
+ paidAmountCents
+ receivedAmountCents
+ ...Show_deposit_order
+ }
+ }
+}
+
+fragment Show_deposit_order on DepositOrder {
+ transactionId
+ paidAmountCents
+ receivedAmountCents
+ status
+ createdAt
+}
+*/
+
+const node: ConcreteRequest = (function(){
+var v0 = {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "totalCount",
+ "storageKey": null
+};
+return {
+ "fragment": {
+ "argumentDefinitions": [],
+ "kind": "Fragment",
+ "metadata": null,
+ "name": "DepositQuery",
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "DepositOrderConnection",
+ "kind": "LinkedField",
+ "name": "depositOrders",
+ "plural": false,
+ "selections": [
+ (v0/*: any*/),
+ {
+ "args": null,
+ "kind": "FragmentSpread",
+ "name": "History_depositOrders"
+ }
+ ],
+ "storageKey": null
+ }
+ ],
+ "type": "Query",
+ "abstractKey": null
+ },
+ "kind": "Request",
+ "operation": {
+ "argumentDefinitions": [],
+ "kind": "Operation",
+ "name": "DepositQuery",
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "DepositOrderConnection",
+ "kind": "LinkedField",
+ "name": "depositOrders",
+ "plural": false,
+ "selections": [
+ (v0/*: any*/),
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "DepositOrderEdge",
+ "kind": "LinkedField",
+ "name": "edges",
+ "plural": true,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "DepositOrder",
+ "kind": "LinkedField",
+ "name": "node",
+ "plural": false,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "id",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "status",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "createdAt",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "paidAmountCents",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "receivedAmountCents",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "transactionId",
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ }
+ ]
+ },
+ "params": {
+ "cacheID": "99f3fbbd023ef8a38b0490275cb58aa6",
+ "id": null,
+ "metadata": {},
+ "name": "DepositQuery",
+ "operationKind": "query",
+ "text": "query DepositQuery {\n depositOrders {\n totalCount\n ...History_depositOrders\n }\n}\n\nfragment History_depositOrders on DepositOrderConnection {\n edges {\n node {\n id\n status\n createdAt\n paidAmountCents\n receivedAmountCents\n ...Show_deposit_order\n }\n }\n}\n\nfragment Show_deposit_order on DepositOrder {\n transactionId\n paidAmountCents\n receivedAmountCents\n status\n createdAt\n}\n"
+ }
+};
+})();
+(node as any).hash = '8394525008fabe782ee41126e50d63b1';
+export default node;
diff --git a/app/javascript/src/pages/Orders/Deposit/index.ts b/app/javascript/src/pages/Orders/Deposit/index.ts
new file mode 100644
index 0000000..e131aa2
--- /dev/null
+++ b/app/javascript/src/pages/Orders/Deposit/index.ts
@@ -0,0 +1 @@
+export * from "./Deposit";
diff --git a/app/javascript/src/pages/Orders/Exchange/ExchangeHistory/ExchangeHistory.tsx b/app/javascript/src/pages/Orders/Exchange/ExchangeHistory/ExchangeHistory.tsx
index 1e9370e..5037dde 100644
--- a/app/javascript/src/pages/Orders/Exchange/ExchangeHistory/ExchangeHistory.tsx
+++ b/app/javascript/src/pages/Orders/Exchange/ExchangeHistory/ExchangeHistory.tsx
@@ -3,6 +3,7 @@ import type { FC } from "react";
import React from "react";
import { useFragment } from "react-relay";
+import { Table } from "../../../../components";
import { Messages } from "../../../../messages";
import { centsToUnit } from "../../../../utils/fiatMoney";
import type { CryptoExchangeOrderProps } from "./components/CryptoExchangeOrder";
@@ -119,41 +120,13 @@ export const ExchangeHistory: FC = ({
-
-
-
- |
- Valor pago
- |
-
- Valor recebido
- |
-
- Criado em
- |
-
- Status
- |
-
-
-
- {orderRows.map((order) => {
- return ;
- })}
-
-
+
+ {orderRows.map((order) => {
+ return ;
+ })}
+
diff --git a/app/javascript/src/pages/Orders/Stake/Stake.tsx b/app/javascript/src/pages/Orders/Stake/Stake.tsx
index ee88cf2..9a24b1a 100644
--- a/app/javascript/src/pages/Orders/Stake/Stake.tsx
+++ b/app/javascript/src/pages/Orders/Stake/Stake.tsx
@@ -7,6 +7,7 @@ import cx from "classnames";
import { getStatusTextAndColors } from "../utils/processStatus";
import type { StakeQuery } from "./__generated__/StakeQuery.graphql";
import { Messages } from "../../../messages";
+import { Table, TableRow } from "../../../components";
export const Stake: FC = () => {
const { stakeOrders } = useLazyLoadQuery(
@@ -36,82 +37,43 @@ export const Stake: FC = () => {
-
-
-
- |
- Pool
- |
-
- Montante
- |
-
- Criado em
- |
-
- Status
- |
-
-
-
- {stakeOrders.edges.map(({ node }) => {
- const [label, textStyles, bgStyles] = getStatusTextAndColors(
- node.status
- );
+
+ {stakeOrders.edges.map(({ node }) => {
+ const [label, textStyles, bgStyles] = getStatusTextAndColors(
+ node.status
+ );
- return (
-
- |
-
- {node.poolName}
-
- |
-
-
- {node.amount}
-
- |
-
-
- {new Date(
- node.createdAt as string
- ).toLocaleTimeString()}
-
- |
-
-
-
- {label}
-
- |
-
- );
- })}
-
-
+ const status = (
+
+
+ {label}
+
+ );
+
+ return (
+
+ );
+ })}
+
diff --git a/app/javascript/src/pages/Orders/index.ts b/app/javascript/src/pages/Orders/index.ts
index 7c2f26f..b62d13d 100644
--- a/app/javascript/src/pages/Orders/index.ts
+++ b/app/javascript/src/pages/Orders/index.ts
@@ -1,7 +1,9 @@
import { Exchange } from "./Exchange";
import { Stake } from "./Stake";
+import { Deposit } from "./Deposit";
export const Orders = {
+ Deposit,
Exchange,
Stake,
};
diff --git a/app/models/deposit_order.rb b/app/models/deposit_order.rb
new file mode 100644
index 0000000..4998f82
--- /dev/null
+++ b/app/models/deposit_order.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+# == Schema Information
+#
+# Table name: deposit_orders
+#
+# id :bigint not null, primary key
+# paid_amount_cents :integer default(0), not null
+# received_amount_cents :integer default(0), not null
+# status :string not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# transaction_id :uuid not null
+# user_id :bigint not null
+#
+# Indexes
+#
+# index_deposit_orders_on_user_id (user_id)
+#
+# Foreign Keys
+#
+# fk_rails_... (user_id => users.id)
+#
+class DepositOrder < ApplicationRecord
+ include Processable
+ include Trackable
+
+ belongs_to :user
+
+ monetize :paid_amount_cents
+ monetize :received_amount_cents
+end
diff --git a/app/policies/deposit_order_policy.rb b/app/policies/deposit_order_policy.rb
new file mode 100644
index 0000000..e6e254c
--- /dev/null
+++ b/app/policies/deposit_order_policy.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+class DepositOrderPolicy < ApplicationPolicy
+ class Scope < Scope
+ def resolve
+ return scope.none if user.nil?
+
+ scope.where(user_id: user.id)
+ end
+ end
+end
diff --git a/app/services/build_deposit_order.rb b/app/services/build_deposit_order.rb
new file mode 100644
index 0000000..9f19023
--- /dev/null
+++ b/app/services/build_deposit_order.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+class BuildDepositOrder
+ DEPOSIT_FEE = 0.05
+
+ attr_reader :paid_amount_cents, :user_id
+
+ def initilize(paid_amount_cents:, user_id:)
+ @paid_amount_cents = paid_amount_cents
+ @user_id = user_id
+ end
+
+ def build
+ DepositOrder.new(
+ user_id: user_id,
+ paid_amount_cents: paid_amount_cents,
+ received_amount_cents: paid_amount_cents + (paid_amount_cents * DEPOSIT_FEE)
+ )
+ end
+end
diff --git a/db/migrate/20210905234913_create_deposit_orders.rb b/db/migrate/20210905234913_create_deposit_orders.rb
new file mode 100644
index 0000000..0a31d59
--- /dev/null
+++ b/db/migrate/20210905234913_create_deposit_orders.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+class CreateDepositOrders < ActiveRecord::Migration[6.1]
+ def change
+ create_table(:deposit_orders) do |t|
+ t.references(:user, null: false, foreign_key: true)
+ t.string(:status, null: false)
+
+ t.integer(:received_amount_cents, null: false, default: 0)
+ t.integer(:paid_amount_cents, null: false, default: 0)
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20210906021555_enable_uuid.rb b/db/migrate/20210906021555_enable_uuid.rb
new file mode 100644
index 0000000..558ea52
--- /dev/null
+++ b/db/migrate/20210906021555_enable_uuid.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+class EnableUuid < ActiveRecord::Migration[6.1]
+ def change
+ enable_extension("pgcrypto")
+ end
+end
diff --git a/db/migrate/20210906021610_add_transaction_id_to_despoit_order.rb b/db/migrate/20210906021610_add_transaction_id_to_despoit_order.rb
new file mode 100644
index 0000000..dc32e32
--- /dev/null
+++ b/db/migrate/20210906021610_add_transaction_id_to_despoit_order.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+class AddTransactionIdToDespoitOrder < ActiveRecord::Migration[6.1]
+ def change
+ add_column(:deposit_orders, :transaction_id, :uuid, default: "gen_random_uuid()", null: false)
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 0dccd51..ee33d14 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,9 +10,10 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2021_08_28_041104) do
+ActiveRecord::Schema.define(version: 2021_09_06_021610) do
# These are extensions that must be enabled in order to support this database
+ enable_extension "pgcrypto"
enable_extension "plpgsql"
create_table "active_storage_attachments", force: :cascade do |t|
@@ -73,6 +74,17 @@ ActiveRecord::Schema.define(version: 2021_08_28_041104) do
t.index ["user_id"], name: "index_buy_crypto_orders_on_user_id"
end
+ create_table "deposit_orders", force: :cascade do |t|
+ t.bigint "user_id", null: false
+ t.string "status", null: false
+ t.integer "received_amount_cents", default: 0, null: false
+ t.integer "paid_amount_cents", default: 0, null: false
+ t.datetime "created_at", precision: 6, null: false
+ t.datetime "updated_at", precision: 6, null: false
+ t.uuid "transaction_id", default: -> { "gen_random_uuid()" }, null: false
+ t.index ["user_id"], name: "index_deposit_orders_on_user_id"
+ end
+
create_table "fiat_balances", force: :cascade do |t|
t.bigint "user_id", null: false
t.integer "amount_cents", default: 0, null: false
@@ -139,6 +151,7 @@ ActiveRecord::Schema.define(version: 2021_08_28_041104) do
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
add_foreign_key "balances", "users"
add_foreign_key "buy_crypto_orders", "users"
+ add_foreign_key "deposit_orders", "users"
add_foreign_key "fiat_balances", "users"
add_foreign_key "sell_crypto_orders", "users"
add_foreign_key "stake_orders", "users"
diff --git a/erd.svg b/erd.svg
index 77ee004..1c4f24f 100644
--- a/erd.svg
+++ b/erd.svg
@@ -1,83 +1,106 @@
-
-