diff --git a/apps/admin-ui/app/(drawer)/vendor-snippets/index.tsx b/apps/admin-ui/app/(drawer)/vendor-snippets/index.tsx index cd7e94b..f34cbfa 100644 --- a/apps/admin-ui/app/(drawer)/vendor-snippets/index.tsx +++ b/apps/admin-ui/app/(drawer)/vendor-snippets/index.tsx @@ -1,56 +1,68 @@ -import React, { useState } from 'react'; -import { View, ScrollView, TouchableOpacity, Alert, Dimensions, Share } from 'react-native'; -import { theme, AppContainer, MyText, tw, useManualRefresh, useMarkDataFetchers, MyTouchableOpacity } from 'common-ui'; -import { trpc, trpcClient } from '../../../src/trpc-client'; -import MaterialIcons from '@expo/vector-icons/MaterialIcons'; +import React, { useState } from "react"; +import { + View, + ScrollView, + TouchableOpacity, + Alert, + Dimensions, + Share, +} from "react-native"; +import { + theme, + AppContainer, + MyText, + tw, + useManualRefresh, + useMarkDataFetchers, + MyTouchableOpacity, +} from "common-ui"; +import { trpc, trpcClient } from "../../../src/trpc-client"; +import MaterialIcons from "@expo/vector-icons/MaterialIcons"; import { Ionicons } from "@expo/vector-icons"; import dayjs from "dayjs"; import { LinearGradient } from "expo-linear-gradient"; -import { useRouter } from 'expo-router'; +import { useRouter } from "expo-router"; -import VendorSnippetForm from '../../../components/VendorSnippetForm'; -import SnippetOrdersView from '../../../components/SnippetOrdersView'; -import { SnippetMenu } from '../../../components/SnippetMenu'; - -interface VendorSnippet { - id: number; - snippetCode: string; - slotId: number; - productIds: number[]; - validTill: string | null; - createdAt: string; - accessUrl: string; - slot?: { - id: number; - deliveryTime: string; - freezeTime: string; - isActive: boolean; - deliverySequence?: unknown; - }; -} +import VendorSnippetForm from "../../../components/VendorSnippetForm"; +import SnippetOrdersView from "../../../components/SnippetOrdersView"; +import { SnippetMenu } from "../../../components/SnippetMenu"; +import { ProductListDialog } from "../../../components/ProductListDialog"; +import { + VendorSnippet, + VendorSnippetProduct, + VendorSnippetForm as VendorSnippetFormType, +} from "../../../types/vendor-snippets"; const SnippetItem = ({ snippet, onEdit, onDelete, onViewOrders, - index + onViewProducts, + index, }: { snippet: VendorSnippet; onEdit: (snippet: VendorSnippet) => void; onDelete: (id: number) => void; onViewOrders: (snippetCode: string) => void; + onViewProducts: (products: VendorSnippetProduct[]) => void; index: number; }) => { - const isExpired = snippet.validTill && dayjs(snippet.validTill).isBefore(dayjs()); + + const isExpired = + snippet.validTill && dayjs(snippet.validTill).isBefore(dayjs()); const handleCopyLink = async () => { try { + if (!snippet.accessUrl) { + Alert.alert("Error", "No link available"); + return; + } await Share.share({ message: snippet.accessUrl, }); } catch (error) { - Alert.alert('Error', 'Failed to share link'); + Alert.alert("Error", "Failed to share link"); } }; @@ -60,24 +72,50 @@ const SnippetItem = ({ {/* Top Header: ID & Status */} - - + + - + Identifier - + {snippet.snippetCode} - - - - {isExpired ? 'Expired' : 'Active'} + + + + {isExpired ? "Expired" : "Active"} {/* Middle: Delivery Banner */} - - + + - - {snippet.slot?.deliveryTime ? dayjs(snippet.slot.deliveryTime).format('ddd, MMM DD') : 'Schedule Pending'} - - - Time: {snippet.slot?.deliveryTime ? dayjs(snippet.slot.deliveryTime).format('hh:mm A') : 'N/A'} - + {snippet.isPermanent ? ( + <> + + Permanent + + + Always Active + + + ) : snippet.slot?.deliveryTime ? ( + <> + + {dayjs(snippet.slot.deliveryTime).format("ddd, MMM DD")} + + + Time: {dayjs(snippet.slot.deliveryTime).format("hh:mm A")} + + + ) : ( + <> + + Schedule Pending + + + N/A + + + )} {snippet.validTill && ( - Expires - - {dayjs(snippet.validTill).format('MMM DD')} + + Expires + + + {dayjs(snippet.validTill).format("MMM DD")} )} @@ -115,13 +186,28 @@ const SnippetItem = ({ {/* Stats & Actions */} - + onViewProducts(snippet.products)} + style={tw`flex-row items-center mr-4`} + > - {snippet.productIds.length} Items - - - - Share + + {snippet.productIds.length} Items + + + + + + + Share + @@ -131,7 +217,11 @@ const SnippetItem = ({ activeOpacity={0.7} style={tw`flex-row items-center`} > - View Slot + + View Slot + @@ -142,7 +232,12 @@ const SnippetItem = ({ export default function VendorSnippets() { // const { data: snippets, isLoading, error, refetch } = useVendorSnippets(); - const { data: snippets, isLoading, error, refetch } = trpc.admin.vendorSnippets.getAll.useQuery(); + const { + data: snippets, + isLoading, + error, + refetch, + } = trpc.admin.vendorSnippets.getAll.useQuery(); const createSnippet = trpc.admin.vendorSnippets.create.useMutation(); const updateSnippet = trpc.admin.vendorSnippets.update.useMutation(); @@ -151,41 +246,64 @@ export default function VendorSnippets() { // const updateSnippet = useUpdateVendorSnippet(); // const deleteSnippet = useDeleteVendorSnippet(); - const router = useRouter(); +const router = useRouter(); - const [showCreateForm, setShowCreateForm] = useState(false); - const [editingSnippet, setEditingSnippet] = useState(null); - const [showOrdersView, setShowOrdersView] = useState(false); - const [ordersData, setOrdersData] = useState(null); +const [showCreateForm, setShowCreateForm] = useState(false); +const [editingSnippet, setEditingSnippet] = + useState(null); +const [showOrdersView, setShowOrdersView] = useState(false); +const [ordersData, setOrdersData] = useState(null); +const [showProductList, setShowProductList] = useState(false); +const [selectedProducts, setSelectedProducts] = useState(null); +useManualRefresh(refetch); - useManualRefresh(refetch); +useMarkDataFetchers(() => { + refetch(); +}); - useMarkDataFetchers(() => { - refetch(); - }); +const handleCreate = () => { + setShowCreateForm(true); + setEditingSnippet(null); +}; - const handleCreate = () => { - setShowCreateForm(true); - setEditingSnippet(null); - }; +const handleViewProducts = (products: VendorSnippetProduct[]) => { + setSelectedProducts(products); + setShowProductList(true); +}; const handleEdit = (snippet: VendorSnippet) => { - setEditingSnippet(snippet); + // Convert to match the form's expected type + const formSnippet: VendorSnippetFormType = { + id: snippet.id, + snippetCode: snippet.snippetCode, + slotId: snippet.slotId || 0, // Convert null to number for form + isPermanent: snippet.isPermanent, + productIds: snippet.productIds, + validTill: snippet.validTill, + createdAt: snippet.createdAt, + }; + setEditingSnippet(formSnippet); setShowCreateForm(true); }; const handleDelete = (id: number) => { - deleteSnippet.mutate({ id }, { - onSuccess: () => { - refetch(); - } - }); + deleteSnippet.mutate( + { id }, + { + onSuccess: () => { + refetch(); + }, + }, + ); }; const handleViewOrders = async (snippetCode: string) => { try { - const result = await trpcClient.admin.vendorSnippets.getOrdersBySnippet.query({ snippetCode }); + const result = + await trpcClient.admin.vendorSnippets.getOrdersBySnippet.query({ + snippetCode, + }); if (result.success) { setOrdersData({ orders: result.data, @@ -193,10 +311,10 @@ export default function VendorSnippets() { }); setShowOrdersView(true); } else { - Alert.alert('Error', 'Failed to fetch orders'); + Alert.alert("Error", "Failed to fetch orders"); } } catch (error: any) { - Alert.alert('Error', error.message || 'Failed to fetch orders'); + Alert.alert("Error", error.message || "Failed to fetch orders"); } }; @@ -251,57 +369,74 @@ export default function VendorSnippets() { } return ( - - - - {snippets && snippets.length === 0 ? ( - - - + <> + + + + {snippets && snippets.length === 0 ? ( + + + + + + No Snippets Yet + + + Start by creating your first vendor identifier using the + button below. + - No Snippets Yet - - Start by creating your first vendor identifier using the button below. - - - ) : ( - snippets?.map((snippet, index) => ( - - ( + + - {index < snippets.length - 1 && ( - - )} - - )) - )} - + {index < snippets.length - 1 && ( + + )} + + )) + )} + - {/* Global Floating Action Button */} - + + + - - - - - - + + + + setShowProductList(false)} + products={selectedProducts || []} + /> + ); -} \ No newline at end of file +} diff --git a/apps/admin-ui/components/ProductListDialog.tsx b/apps/admin-ui/components/ProductListDialog.tsx new file mode 100644 index 0000000..03d5d3a --- /dev/null +++ b/apps/admin-ui/components/ProductListDialog.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { View, ScrollView } from 'react-native'; +import { BottomDialog, MyText, tw } from 'common-ui'; + +interface VendorSnippetProduct { + id: number; + name: string; +} + +interface ProductListDialogProps { + open: boolean; + onClose: () => void; + products: VendorSnippetProduct[]; +} + +export const ProductListDialog: React.FC = ({ + open, + onClose, + products, +}) => { + return ( + + + + Products ({products.length}) + + + {products.map((product, index) => ( + + + {product.name} + + + ))} + + + + ); +}; \ No newline at end of file diff --git a/apps/admin-ui/components/SnippetMenu.tsx b/apps/admin-ui/components/SnippetMenu.tsx index 6c90367..308e127 100644 --- a/apps/admin-ui/components/SnippetMenu.tsx +++ b/apps/admin-ui/components/SnippetMenu.tsx @@ -3,6 +3,7 @@ import { View, TouchableOpacity, Alert, Clipboard } from 'react-native'; import { Entypo } from '@expo/vector-icons'; import { MyText, tw, BottomDialog } from 'common-ui'; import { SuccessToast } from '../services/toaster'; +import { VendorSnippet } from '../types/vendor-snippets'; export interface SnippetMenuOption { title: string; @@ -12,12 +13,8 @@ export interface SnippetMenuOption { } export interface SnippetMenuProps { - snippet: { - id: number; - snippetCode: string; - accessUrl: string; - }; - onEdit: (snippet: any) => void; + snippet: VendorSnippet; + onEdit: (snippet: VendorSnippet) => void; onDelete: (id: number) => void; onViewOrders: (snippetCode: string) => void; triggerStyle?: any; @@ -72,6 +69,10 @@ export const SnippetMenu: React.FC = ({ const handleCopyUrl = async () => { setIsOpen(false); + if (!snippet.accessUrl) { + Alert.alert('Error', 'No URL available to copy'); + return; + } await Clipboard.setString(snippet.accessUrl); SuccessToast('URL copied to clipboard'); }; diff --git a/apps/admin-ui/components/VendorSnippetForm.tsx b/apps/admin-ui/components/VendorSnippetForm.tsx index cbea7b7..5097228 100644 --- a/apps/admin-ui/components/VendorSnippetForm.tsx +++ b/apps/admin-ui/components/VendorSnippetForm.tsx @@ -4,27 +4,20 @@ import { useFormik } from 'formik'; import { MyText, tw, DatePicker, MyTextInput } from 'common-ui'; import BottomDropdown from 'common-ui/src/components/bottom-dropdown'; import { trpc } from '../src/trpc-client'; - - -interface VendorSnippet { - id: number; - snippetCode: string; - slotId: number; - productIds: number[]; - validTill: string | null; - createdAt: string; -} +import { VendorSnippetForm as VendorSnippetFormType, VendorSnippet } from '../types/vendor-snippets'; interface VendorSnippetFormProps { - snippet?: VendorSnippet | null; + snippet?: VendorSnippetFormType | null; onClose: () => void; onSuccess: () => void; + showIsPermanentCheckbox?: boolean; } const VendorSnippetForm: React.FC = ({ snippet, onClose, onSuccess, + showIsPermanentCheckbox = false, }) => { // Fetch slots and products @@ -40,6 +33,7 @@ const VendorSnippetForm: React.FC = ({ initialValues: { snippetCode: snippet?.snippetCode || '', slotId: snippet?.slotId?.toString() || '', + isPermanent: snippet?.isPermanent || false, productIds: snippet?.productIds?.map(id => id.toString()) || [], validTill: snippet?.validTill ? new Date(snippet.validTill) : null, }, @@ -50,7 +44,14 @@ const VendorSnippetForm: React.FC = ({ errors.snippetCode = 'Snippet code is required'; } - if (!values.slotId) { + // Validate snippet code only contains alphanumeric characters and underscore + const snippetCodeRegex = /^[a-zA-Z0-9_]+$/; + if (values.snippetCode && !snippetCodeRegex.test(values.snippetCode)) { + errors.snippetCode = 'Snippet code can only contain letters, numbers, and underscores'; + } + + // Only require slotId if isPermanent is false + if (!values.isPermanent && !values.slotId) { errors.slotId = 'Slot selection is required'; } @@ -62,11 +63,14 @@ const VendorSnippetForm: React.FC = ({ }, onSubmit: async (values) => { try { + console.log({values}) + const submitData = { snippetCode: values.snippetCode, - slotId: parseInt(values.slotId), + slotId: values.isPermanent ? undefined : parseInt(values.slotId || '0'), + isPermanent: values.isPermanent, productIds: values.productIds.map(id => parseInt(id)), - validTill: values.validTill?.toISOString(), + validTill: values.validTill ? values.validTill.toISOString() : undefined, }; if (isEditing && snippet) { @@ -93,7 +97,7 @@ const VendorSnippetForm: React.FC = ({ if (!isEditing && !formik.values.snippetCode) { const timestamp = Date.now(); const random = Math.random().toString(36).substring(2, 8); - formik.setFieldValue('snippetCode', `VS_${timestamp}_${random}`.toUpperCase()); + formik.setFieldValue('snippetCode', `VS_${timestamp}_${random}`); } }, [isEditing]); // Removed formik.values.snippetCode from deps @@ -146,21 +150,44 @@ const VendorSnippetForm: React.FC = ({ )} - {/* Slot Selection */} + {/* Is Permanent Checkbox */} - Delivery Slot - formik.setFieldValue('slotId', value)} - placeholder="Choose a delivery slot" - /> - {formik.errors.slotId && formik.touched.slotId && ( - {formik.errors.slotId} - )} + formik.setFieldValue('isPermanent', !formik.values.isPermanent)} + style={tw`flex-row items-center mb-2`} + > + + {formik.values.isPermanent && ( + + )} + + Is Permanent? + + + Check if this snippet is permanent and not tied to a specific delivery slot + + {/* Slot Selection - Only show if not permanent */} + {!formik.values.isPermanent && ( + + Delivery Slot + formik.setFieldValue('slotId', value)} + placeholder="Choose a delivery slot" + /> + {formik.errors.slotId && formik.touched.slotId && ( + {formik.errors.slotId} + )} + + )} + {/* Product Selection */} Products diff --git a/apps/admin-ui/types/vendor-snippets.ts b/apps/admin-ui/types/vendor-snippets.ts new file mode 100644 index 0000000..c62341e --- /dev/null +++ b/apps/admin-ui/types/vendor-snippets.ts @@ -0,0 +1,34 @@ +export interface VendorSnippetProduct { + id: number; + name: string; +} + +export interface VendorSnippet { + id: number; + snippetCode: string; + slotId: number | null; + isPermanent: boolean; + productIds: number[]; + products: VendorSnippetProduct[]; + validTill: string | null; + createdAt: string; + accessUrl?: string; + slot?: { + id: number; + deliveryTime: string; + freezeTime: string; + isActive: boolean; + deliverySequence?: unknown; + isFlash?: boolean; + } | null; +} + +export interface VendorSnippetForm { + id: number; + snippetCode: string; + slotId: number; + isPermanent: boolean; + productIds: number[]; + validTill: string | null; + createdAt: string; +} \ No newline at end of file diff --git a/apps/backend/drizzle/0067_messy_earthquake.sql b/apps/backend/drizzle/0067_messy_earthquake.sql new file mode 100644 index 0000000..c87f6aa --- /dev/null +++ b/apps/backend/drizzle/0067_messy_earthquake.sql @@ -0,0 +1,2 @@ +ALTER TABLE "mf"."vendor_snippets" ALTER COLUMN "slot_id" DROP NOT NULL;--> statement-breakpoint +ALTER TABLE "mf"."vendor_snippets" ADD COLUMN "is_permanent" boolean DEFAULT false NOT NULL; \ No newline at end of file diff --git a/apps/backend/drizzle/meta/0067_snapshot.json b/apps/backend/drizzle/meta/0067_snapshot.json new file mode 100644 index 0000000..9001f9d --- /dev/null +++ b/apps/backend/drizzle/meta/0067_snapshot.json @@ -0,0 +1,3600 @@ +{ + "id": "5da5eca2-307f-4098-a9c7-9fcaaac5c3e2", + "prevId": "f105c79e-a657-457d-a49a-314b998b4ed3", + "version": "7", + "dialect": "postgresql", + "tables": { + "mf.address_areas": { + "name": "address_areas", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "address_areas_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "place_name": { + "name": "place_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "zone_id": { + "name": "zone_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "address_areas_zone_id_address_zones_id_fk": { + "name": "address_areas_zone_id_address_zones_id_fk", + "tableFrom": "address_areas", + "tableTo": "address_zones", + "schemaTo": "mf", + "columnsFrom": [ + "zone_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.address_zones": { + "name": "address_zones", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "address_zones_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "zone_name": { + "name": "zone_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "added_at": { + "name": "added_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.addresses": { + "name": "addresses", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "addresses_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "phone": { + "name": "phone", + "type": "varchar(15)", + "primaryKey": false, + "notNull": true + }, + "address_line1": { + "name": "address_line1", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "address_line2": { + "name": "address_line2", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "city": { + "name": "city", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "state": { + "name": "state", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "pincode": { + "name": "pincode", + "type": "varchar(10)", + "primaryKey": false, + "notNull": true + }, + "is_default": { + "name": "is_default", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "latitude": { + "name": "latitude", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "longitude": { + "name": "longitude", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "zone_id": { + "name": "zone_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "addresses_user_id_users_id_fk": { + "name": "addresses_user_id_users_id_fk", + "tableFrom": "addresses", + "tableTo": "users", + "schemaTo": "mf", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "addresses_zone_id_address_zones_id_fk": { + "name": "addresses_zone_id_address_zones_id_fk", + "tableFrom": "addresses", + "tableTo": "address_zones", + "schemaTo": "mf", + "columnsFrom": [ + "zone_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.cart_items": { + "name": "cart_items", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "cart_items_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "product_id": { + "name": "product_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": true + }, + "added_at": { + "name": "added_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "cart_items_user_id_users_id_fk": { + "name": "cart_items_user_id_users_id_fk", + "tableFrom": "cart_items", + "tableTo": "users", + "schemaTo": "mf", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "cart_items_product_id_product_info_id_fk": { + "name": "cart_items_product_id_product_info_id_fk", + "tableFrom": "cart_items", + "tableTo": "product_info", + "schemaTo": "mf", + "columnsFrom": [ + "product_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_user_product": { + "name": "unique_user_product", + "nullsNotDistinct": false, + "columns": [ + "user_id", + "product_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.complaints": { + "name": "complaints", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "complaints_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "order_id": { + "name": "order_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "complaint_body": { + "name": "complaint_body", + "type": "varchar(1000)", + "primaryKey": false, + "notNull": true + }, + "images": { + "name": "images", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "response": { + "name": "response", + "type": "varchar(1000)", + "primaryKey": false, + "notNull": false + }, + "is_resolved": { + "name": "is_resolved", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "complaints_user_id_users_id_fk": { + "name": "complaints_user_id_users_id_fk", + "tableFrom": "complaints", + "tableTo": "users", + "schemaTo": "mf", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "complaints_order_id_orders_id_fk": { + "name": "complaints_order_id_orders_id_fk", + "tableFrom": "complaints", + "tableTo": "orders", + "schemaTo": "mf", + "columnsFrom": [ + "order_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.coupon_applicable_products": { + "name": "coupon_applicable_products", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "coupon_applicable_products_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "coupon_id": { + "name": "coupon_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "product_id": { + "name": "product_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "coupon_applicable_products_coupon_id_coupons_id_fk": { + "name": "coupon_applicable_products_coupon_id_coupons_id_fk", + "tableFrom": "coupon_applicable_products", + "tableTo": "coupons", + "schemaTo": "mf", + "columnsFrom": [ + "coupon_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "coupon_applicable_products_product_id_product_info_id_fk": { + "name": "coupon_applicable_products_product_id_product_info_id_fk", + "tableFrom": "coupon_applicable_products", + "tableTo": "product_info", + "schemaTo": "mf", + "columnsFrom": [ + "product_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_coupon_product": { + "name": "unique_coupon_product", + "nullsNotDistinct": false, + "columns": [ + "coupon_id", + "product_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.coupon_applicable_users": { + "name": "coupon_applicable_users", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "coupon_applicable_users_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "coupon_id": { + "name": "coupon_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "coupon_applicable_users_coupon_id_coupons_id_fk": { + "name": "coupon_applicable_users_coupon_id_coupons_id_fk", + "tableFrom": "coupon_applicable_users", + "tableTo": "coupons", + "schemaTo": "mf", + "columnsFrom": [ + "coupon_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "coupon_applicable_users_user_id_users_id_fk": { + "name": "coupon_applicable_users_user_id_users_id_fk", + "tableFrom": "coupon_applicable_users", + "tableTo": "users", + "schemaTo": "mf", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_coupon_user": { + "name": "unique_coupon_user", + "nullsNotDistinct": false, + "columns": [ + "coupon_id", + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.coupon_usage": { + "name": "coupon_usage", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "coupon_usage_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "coupon_id": { + "name": "coupon_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "order_id": { + "name": "order_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "order_item_id": { + "name": "order_item_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "used_at": { + "name": "used_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "coupon_usage_user_id_users_id_fk": { + "name": "coupon_usage_user_id_users_id_fk", + "tableFrom": "coupon_usage", + "tableTo": "users", + "schemaTo": "mf", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "coupon_usage_coupon_id_coupons_id_fk": { + "name": "coupon_usage_coupon_id_coupons_id_fk", + "tableFrom": "coupon_usage", + "tableTo": "coupons", + "schemaTo": "mf", + "columnsFrom": [ + "coupon_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "coupon_usage_order_id_orders_id_fk": { + "name": "coupon_usage_order_id_orders_id_fk", + "tableFrom": "coupon_usage", + "tableTo": "orders", + "schemaTo": "mf", + "columnsFrom": [ + "order_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "coupon_usage_order_item_id_order_items_id_fk": { + "name": "coupon_usage_order_item_id_order_items_id_fk", + "tableFrom": "coupon_usage", + "tableTo": "order_items", + "schemaTo": "mf", + "columnsFrom": [ + "order_item_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.coupons": { + "name": "coupons", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "coupons_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "coupon_code": { + "name": "coupon_code", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "is_user_based": { + "name": "is_user_based", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "discount_percent": { + "name": "discount_percent", + "type": "numeric(5, 2)", + "primaryKey": false, + "notNull": false + }, + "flat_discount": { + "name": "flat_discount", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": false + }, + "min_order": { + "name": "min_order", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": false + }, + "product_ids": { + "name": "product_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "max_value": { + "name": "max_value", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": false + }, + "is_apply_for_all": { + "name": "is_apply_for_all", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "valid_till": { + "name": "valid_till", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "max_limit_for_user": { + "name": "max_limit_for_user", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "is_invalidated": { + "name": "is_invalidated", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "exclusive_apply": { + "name": "exclusive_apply", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "coupons_created_by_staff_users_id_fk": { + "name": "coupons_created_by_staff_users_id_fk", + "tableFrom": "coupons", + "tableTo": "staff_users", + "schemaTo": "mf", + "columnsFrom": [ + "created_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_coupon_code": { + "name": "unique_coupon_code", + "nullsNotDistinct": false, + "columns": [ + "coupon_code" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.delivery_slot_info": { + "name": "delivery_slot_info", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "delivery_slot_info_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "delivery_time": { + "name": "delivery_time", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "freeze_time": { + "name": "freeze_time", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "is_flash": { + "name": "is_flash", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "delivery_sequence": { + "name": "delivery_sequence", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.home_banners": { + "name": "home_banners", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "home_banners_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "image_url": { + "name": "image_url", + "type": "varchar(500)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "product_ids": { + "name": "product_ids", + "type": "integer[]", + "primaryKey": false, + "notNull": false + }, + "redirect_url": { + "name": "redirect_url", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "serial_num": { + "name": "serial_num", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_updated": { + "name": "last_updated", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.key_val_store": { + "name": "key_val_store", + "schema": "mf", + "columns": { + "key": { + "name": "key", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "value": { + "name": "value", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.notif_creds": { + "name": "notif_creds", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "notif_creds_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "token": { + "name": "token", + "type": "varchar(500)", + "primaryKey": false, + "notNull": true + }, + "added_at": { + "name": "added_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "last_verified": { + "name": "last_verified", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "notif_creds_user_id_users_id_fk": { + "name": "notif_creds_user_id_users_id_fk", + "tableFrom": "notif_creds", + "tableTo": "users", + "schemaTo": "mf", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "notif_creds_token_unique": { + "name": "notif_creds_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.notifications": { + "name": "notifications", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "notifications_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "varchar(512)", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "is_read": { + "name": "is_read", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "notifications_user_id_users_id_fk": { + "name": "notifications_user_id_users_id_fk", + "tableFrom": "notifications", + "tableTo": "users", + "schemaTo": "mf", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.order_items": { + "name": "order_items", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "order_items_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "order_id": { + "name": "order_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "product_id": { + "name": "product_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "price": { + "name": "price", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": true + }, + "discounted_price": { + "name": "discounted_price", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": false + }, + "is_packaged": { + "name": "is_packaged", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_package_verified": { + "name": "is_package_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "order_items_order_id_orders_id_fk": { + "name": "order_items_order_id_orders_id_fk", + "tableFrom": "order_items", + "tableTo": "orders", + "schemaTo": "mf", + "columnsFrom": [ + "order_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "order_items_product_id_product_info_id_fk": { + "name": "order_items_product_id_product_info_id_fk", + "tableFrom": "order_items", + "tableTo": "product_info", + "schemaTo": "mf", + "columnsFrom": [ + "product_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.order_status": { + "name": "order_status", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "order_status_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "order_time": { + "name": "order_time", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "order_id": { + "name": "order_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "is_packaged": { + "name": "is_packaged", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_delivered": { + "name": "is_delivered", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_cancelled": { + "name": "is_cancelled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "cancel_reason": { + "name": "cancel_reason", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "is_cancelled_by_admin": { + "name": "is_cancelled_by_admin", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "payment_state": { + "name": "payment_state", + "type": "payment_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "cancellation_user_notes": { + "name": "cancellation_user_notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cancellation_admin_notes": { + "name": "cancellation_admin_notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cancellation_reviewed": { + "name": "cancellation_reviewed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "cancellation_reviewed_at": { + "name": "cancellation_reviewed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "refund_coupon_id": { + "name": "refund_coupon_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "order_status_user_id_users_id_fk": { + "name": "order_status_user_id_users_id_fk", + "tableFrom": "order_status", + "tableTo": "users", + "schemaTo": "mf", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "order_status_order_id_orders_id_fk": { + "name": "order_status_order_id_orders_id_fk", + "tableFrom": "order_status", + "tableTo": "orders", + "schemaTo": "mf", + "columnsFrom": [ + "order_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "order_status_refund_coupon_id_coupons_id_fk": { + "name": "order_status_refund_coupon_id_coupons_id_fk", + "tableFrom": "order_status", + "tableTo": "coupons", + "schemaTo": "mf", + "columnsFrom": [ + "refund_coupon_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.orders": { + "name": "orders", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "orders_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "address_id": { + "name": "address_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "slot_id": { + "name": "slot_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "is_cod": { + "name": "is_cod", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_online_payment": { + "name": "is_online_payment", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "payment_info_id": { + "name": "payment_info_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "total_amount": { + "name": "total_amount", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": true + }, + "delivery_charge": { + "name": "delivery_charge", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "readable_id": { + "name": "readable_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "admin_notes": { + "name": "admin_notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_notes": { + "name": "user_notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "order_group_id": { + "name": "order_group_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "order_group_proportion": { + "name": "order_group_proportion", + "type": "numeric(10, 4)", + "primaryKey": false, + "notNull": false + }, + "is_flash_delivery": { + "name": "is_flash_delivery", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "orders_user_id_users_id_fk": { + "name": "orders_user_id_users_id_fk", + "tableFrom": "orders", + "tableTo": "users", + "schemaTo": "mf", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "orders_address_id_addresses_id_fk": { + "name": "orders_address_id_addresses_id_fk", + "tableFrom": "orders", + "tableTo": "addresses", + "schemaTo": "mf", + "columnsFrom": [ + "address_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "orders_slot_id_delivery_slot_info_id_fk": { + "name": "orders_slot_id_delivery_slot_info_id_fk", + "tableFrom": "orders", + "tableTo": "delivery_slot_info", + "schemaTo": "mf", + "columnsFrom": [ + "slot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "orders_payment_info_id_payment_info_id_fk": { + "name": "orders_payment_info_id_payment_info_id_fk", + "tableFrom": "orders", + "tableTo": "payment_info", + "schemaTo": "mf", + "columnsFrom": [ + "payment_info_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.payment_info": { + "name": "payment_info", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "payment_info_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "status": { + "name": "status", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "gateway": { + "name": "gateway", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "order_id": { + "name": "order_id", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "token": { + "name": "token", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "merchant_order_id": { + "name": "merchant_order_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "payment_info_merchant_order_id_unique": { + "name": "payment_info_merchant_order_id_unique", + "nullsNotDistinct": false, + "columns": [ + "merchant_order_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.payments": { + "name": "payments", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "payments_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "status": { + "name": "status", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "gateway": { + "name": "gateway", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "order_id": { + "name": "order_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "merchant_order_id": { + "name": "merchant_order_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "payments_order_id_orders_id_fk": { + "name": "payments_order_id_orders_id_fk", + "tableFrom": "payments", + "tableTo": "orders", + "schemaTo": "mf", + "columnsFrom": [ + "order_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "payments_merchant_order_id_unique": { + "name": "payments_merchant_order_id_unique", + "nullsNotDistinct": false, + "columns": [ + "merchant_order_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.product_categories": { + "name": "product_categories", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "product_categories_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.product_group_info": { + "name": "product_group_info", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "product_group_info_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "group_name": { + "name": "group_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.product_group_membership": { + "name": "product_group_membership", + "schema": "mf", + "columns": { + "product_id": { + "name": "product_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "group_id": { + "name": "group_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "added_at": { + "name": "added_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "product_group_membership_product_id_product_info_id_fk": { + "name": "product_group_membership_product_id_product_info_id_fk", + "tableFrom": "product_group_membership", + "tableTo": "product_info", + "schemaTo": "mf", + "columnsFrom": [ + "product_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "product_group_membership_group_id_product_group_info_id_fk": { + "name": "product_group_membership_group_id_product_group_info_id_fk", + "tableFrom": "product_group_membership", + "tableTo": "product_group_info", + "schemaTo": "mf", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "product_group_membership_pk": { + "name": "product_group_membership_pk", + "nullsNotDistinct": false, + "columns": [ + "product_id", + "group_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.product_info": { + "name": "product_info", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "product_info_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "short_description": { + "name": "short_description", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "long_description": { + "name": "long_description", + "type": "varchar(1000)", + "primaryKey": false, + "notNull": false + }, + "unit_id": { + "name": "unit_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "price": { + "name": "price", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": true + }, + "market_price": { + "name": "market_price", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": false + }, + "images": { + "name": "images", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "is_out_of_stock": { + "name": "is_out_of_stock", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_suspended": { + "name": "is_suspended", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_flash_available": { + "name": "is_flash_available", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "flash_price": { + "name": "flash_price", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "increment_step": { + "name": "increment_step", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "product_quantity": { + "name": "product_quantity", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "store_id": { + "name": "store_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "product_info_unit_id_units_id_fk": { + "name": "product_info_unit_id_units_id_fk", + "tableFrom": "product_info", + "tableTo": "units", + "schemaTo": "mf", + "columnsFrom": [ + "unit_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "product_info_store_id_store_info_id_fk": { + "name": "product_info_store_id_store_info_id_fk", + "tableFrom": "product_info", + "tableTo": "store_info", + "schemaTo": "mf", + "columnsFrom": [ + "store_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.product_reviews": { + "name": "product_reviews", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "product_reviews_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "product_id": { + "name": "product_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "review_body": { + "name": "review_body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "image_urls": { + "name": "image_urls", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "review_time": { + "name": "review_time", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "ratings": { + "name": "ratings", + "type": "real", + "primaryKey": false, + "notNull": true + }, + "admin_response": { + "name": "admin_response", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "admin_response_images": { + "name": "admin_response_images", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "product_reviews_user_id_users_id_fk": { + "name": "product_reviews_user_id_users_id_fk", + "tableFrom": "product_reviews", + "tableTo": "users", + "schemaTo": "mf", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "product_reviews_product_id_product_info_id_fk": { + "name": "product_reviews_product_id_product_info_id_fk", + "tableFrom": "product_reviews", + "tableTo": "product_info", + "schemaTo": "mf", + "columnsFrom": [ + "product_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "rating_check": { + "name": "rating_check", + "value": "\"mf\".\"product_reviews\".\"ratings\" >= 1 AND \"mf\".\"product_reviews\".\"ratings\" <= 5" + } + }, + "isRLSEnabled": false + }, + "mf.product_slots": { + "name": "product_slots", + "schema": "mf", + "columns": { + "product_id": { + "name": "product_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "slot_id": { + "name": "slot_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "product_slots_product_id_product_info_id_fk": { + "name": "product_slots_product_id_product_info_id_fk", + "tableFrom": "product_slots", + "tableTo": "product_info", + "schemaTo": "mf", + "columnsFrom": [ + "product_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "product_slots_slot_id_delivery_slot_info_id_fk": { + "name": "product_slots_slot_id_delivery_slot_info_id_fk", + "tableFrom": "product_slots", + "tableTo": "delivery_slot_info", + "schemaTo": "mf", + "columnsFrom": [ + "slot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "product_slot_pk": { + "name": "product_slot_pk", + "nullsNotDistinct": false, + "columns": [ + "product_id", + "slot_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.product_tag_info": { + "name": "product_tag_info", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "product_tag_info_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "tag_name": { + "name": "tag_name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "tag_description": { + "name": "tag_description", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "image_url": { + "name": "image_url", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "is_dashboard_tag": { + "name": "is_dashboard_tag", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "product_tag_info_tag_name_unique": { + "name": "product_tag_info_tag_name_unique", + "nullsNotDistinct": false, + "columns": [ + "tag_name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.product_tags": { + "name": "product_tags", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "product_tags_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "product_id": { + "name": "product_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "tag_id": { + "name": "tag_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "assigned_at": { + "name": "assigned_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "product_tags_product_id_product_info_id_fk": { + "name": "product_tags_product_id_product_info_id_fk", + "tableFrom": "product_tags", + "tableTo": "product_info", + "schemaTo": "mf", + "columnsFrom": [ + "product_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "product_tags_tag_id_product_tag_info_id_fk": { + "name": "product_tags_tag_id_product_tag_info_id_fk", + "tableFrom": "product_tags", + "tableTo": "product_tag_info", + "schemaTo": "mf", + "columnsFrom": [ + "tag_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_product_tag": { + "name": "unique_product_tag", + "nullsNotDistinct": false, + "columns": [ + "product_id", + "tag_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.refunds": { + "name": "refunds", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "refunds_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "order_id": { + "name": "order_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "refund_amount": { + "name": "refund_amount", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": false + }, + "refund_status": { + "name": "refund_status", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false, + "default": "'none'" + }, + "merchant_refund_id": { + "name": "merchant_refund_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "refund_processed_at": { + "name": "refund_processed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "refunds_order_id_orders_id_fk": { + "name": "refunds_order_id_orders_id_fk", + "tableFrom": "refunds", + "tableTo": "orders", + "schemaTo": "mf", + "columnsFrom": [ + "order_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.reserved_coupons": { + "name": "reserved_coupons", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "reserved_coupons_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "secret_code": { + "name": "secret_code", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "coupon_code": { + "name": "coupon_code", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "discount_percent": { + "name": "discount_percent", + "type": "numeric(5, 2)", + "primaryKey": false, + "notNull": false + }, + "flat_discount": { + "name": "flat_discount", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": false + }, + "min_order": { + "name": "min_order", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": false + }, + "product_ids": { + "name": "product_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "max_value": { + "name": "max_value", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": false + }, + "valid_till": { + "name": "valid_till", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "max_limit_for_user": { + "name": "max_limit_for_user", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "exclusive_apply": { + "name": "exclusive_apply", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_redeemed": { + "name": "is_redeemed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "redeemed_by": { + "name": "redeemed_by", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "redeemed_at": { + "name": "redeemed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "reserved_coupons_redeemed_by_users_id_fk": { + "name": "reserved_coupons_redeemed_by_users_id_fk", + "tableFrom": "reserved_coupons", + "tableTo": "users", + "schemaTo": "mf", + "columnsFrom": [ + "redeemed_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "reserved_coupons_created_by_staff_users_id_fk": { + "name": "reserved_coupons_created_by_staff_users_id_fk", + "tableFrom": "reserved_coupons", + "tableTo": "staff_users", + "schemaTo": "mf", + "columnsFrom": [ + "created_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "reserved_coupons_secret_code_unique": { + "name": "reserved_coupons_secret_code_unique", + "nullsNotDistinct": false, + "columns": [ + "secret_code" + ] + }, + "unique_secret_code": { + "name": "unique_secret_code", + "nullsNotDistinct": false, + "columns": [ + "secret_code" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.special_deals": { + "name": "special_deals", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "special_deals_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "product_id": { + "name": "product_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": true + }, + "price": { + "name": "price", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": true + }, + "valid_till": { + "name": "valid_till", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "special_deals_product_id_product_info_id_fk": { + "name": "special_deals_product_id_product_info_id_fk", + "tableFrom": "special_deals", + "tableTo": "product_info", + "schemaTo": "mf", + "columnsFrom": [ + "product_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.staff_permissions": { + "name": "staff_permissions", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "staff_permissions_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "permission_name": { + "name": "permission_name", + "type": "staff_permission", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_permission_name": { + "name": "unique_permission_name", + "nullsNotDistinct": false, + "columns": [ + "permission_name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.staff_role_permissions": { + "name": "staff_role_permissions", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "staff_role_permissions_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "staff_role_id": { + "name": "staff_role_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "staff_permission_id": { + "name": "staff_permission_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "staff_role_permissions_staff_role_id_staff_roles_id_fk": { + "name": "staff_role_permissions_staff_role_id_staff_roles_id_fk", + "tableFrom": "staff_role_permissions", + "tableTo": "staff_roles", + "schemaTo": "mf", + "columnsFrom": [ + "staff_role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "staff_role_permissions_staff_permission_id_staff_permissions_id_fk": { + "name": "staff_role_permissions_staff_permission_id_staff_permissions_id_fk", + "tableFrom": "staff_role_permissions", + "tableTo": "staff_permissions", + "schemaTo": "mf", + "columnsFrom": [ + "staff_permission_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_role_permission": { + "name": "unique_role_permission", + "nullsNotDistinct": false, + "columns": [ + "staff_role_id", + "staff_permission_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.staff_roles": { + "name": "staff_roles", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "staff_roles_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "role_name": { + "name": "role_name", + "type": "staff_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_role_name": { + "name": "unique_role_name", + "nullsNotDistinct": false, + "columns": [ + "role_name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.staff_users": { + "name": "staff_users", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "staff_users_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "password": { + "name": "password", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "staff_role_id": { + "name": "staff_role_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "staff_users_staff_role_id_staff_roles_id_fk": { + "name": "staff_users_staff_role_id_staff_roles_id_fk", + "tableFrom": "staff_users", + "tableTo": "staff_roles", + "schemaTo": "mf", + "columnsFrom": [ + "staff_role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.store_info": { + "name": "store_info", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "store_info_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "image_url": { + "name": "image_url", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "owner": { + "name": "owner", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "store_info_owner_staff_users_id_fk": { + "name": "store_info_owner_staff_users_id_fk", + "tableFrom": "store_info", + "tableTo": "staff_users", + "schemaTo": "mf", + "columnsFrom": [ + "owner" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.units": { + "name": "units", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "units_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "short_notation": { + "name": "short_notation", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "full_name": { + "name": "full_name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_short_notation": { + "name": "unique_short_notation", + "nullsNotDistinct": false, + "columns": [ + "short_notation" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.upload_url_status": { + "name": "upload_url_status", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "upload_url_status_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "key": { + "name": "key", + "type": "varchar(500)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "upload_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.user_creds": { + "name": "user_creds", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "user_creds_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_password": { + "name": "user_password", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "user_creds_user_id_users_id_fk": { + "name": "user_creds_user_id_users_id_fk", + "tableFrom": "user_creds", + "tableTo": "users", + "schemaTo": "mf", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.user_details": { + "name": "user_details", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "user_details_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "bio": { + "name": "bio", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "date_of_birth": { + "name": "date_of_birth", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "gender": { + "name": "gender", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false + }, + "occupation": { + "name": "occupation", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "profile_image": { + "name": "profile_image", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "is_suspended": { + "name": "is_suspended", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "user_details_user_id_users_id_fk": { + "name": "user_details_user_id_users_id_fk", + "tableFrom": "user_details", + "tableTo": "users", + "schemaTo": "mf", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_details_user_id_unique": { + "name": "user_details_user_id_unique", + "nullsNotDistinct": false, + "columns": [ + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.users": { + "name": "users", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "users_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "mobile": { + "name": "mobile", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_email": { + "name": "unique_email", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "mf.vendor_snippets": { + "name": "vendor_snippets", + "schema": "mf", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "always", + "name": "vendor_snippets_id_seq", + "schema": "mf", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "snippet_code": { + "name": "snippet_code", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "slot_id": { + "name": "slot_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "is_permanent": { + "name": "is_permanent", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "product_ids": { + "name": "product_ids", + "type": "integer[]", + "primaryKey": false, + "notNull": true + }, + "valid_till": { + "name": "valid_till", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "vendor_snippets_slot_id_delivery_slot_info_id_fk": { + "name": "vendor_snippets_slot_id_delivery_slot_info_id_fk", + "tableFrom": "vendor_snippets", + "tableTo": "delivery_slot_info", + "schemaTo": "mf", + "columnsFrom": [ + "slot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "vendor_snippets_snippet_code_unique": { + "name": "vendor_snippets_snippet_code_unique", + "nullsNotDistinct": false, + "columns": [ + "snippet_code" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.payment_status": { + "name": "payment_status", + "schema": "public", + "values": [ + "pending", + "success", + "cod", + "failed" + ] + }, + "public.staff_permission": { + "name": "staff_permission", + "schema": "public", + "values": [ + "crud_product", + "make_coupon", + "crud_staff_users" + ] + }, + "public.staff_role": { + "name": "staff_role", + "schema": "public", + "values": [ + "super_admin", + "admin", + "marketer", + "delivery_staff" + ] + }, + "public.upload_status": { + "name": "upload_status", + "schema": "public", + "values": [ + "pending", + "claimed" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/apps/backend/drizzle/meta/_journal.json b/apps/backend/drizzle/meta/_journal.json index 8cbaba1..9236798 100644 --- a/apps/backend/drizzle/meta/_journal.json +++ b/apps/backend/drizzle/meta/_journal.json @@ -470,6 +470,13 @@ "when": 1768710657343, "tag": "0066_gorgeous_karnak", "breakpoints": true + }, + { + "idx": 67, + "version": "7", + "when": 1769280779210, + "tag": "0067_messy_earthquake", + "breakpoints": true } ] } \ No newline at end of file diff --git a/apps/backend/src/db/schema.ts b/apps/backend/src/db/schema.ts index 2516f11..5eaa87d 100755 --- a/apps/backend/src/db/schema.ts +++ b/apps/backend/src/db/schema.ts @@ -194,7 +194,8 @@ export const deliverySlotInfo = mf.table('delivery_slot_info', { export const vendorSnippets = mf.table('vendor_snippets', { id: integer().primaryKey().generatedAlwaysAsIdentity(), snippetCode: varchar('snippet_code', { length: 255 }).notNull().unique(), - slotId: integer('slot_id').notNull().references(() => deliverySlotInfo.id), + slotId: integer('slot_id').references(() => deliverySlotInfo.id), + isPermanent: boolean('is_permanent').notNull().default(false), productIds: integer('product_ids').array().notNull(), validTill: timestamp('valid_till'), createdAt: timestamp('created_at').notNull().defaultNow(), diff --git a/apps/backend/src/trpc/admin-apis/vendor-snippets.ts b/apps/backend/src/trpc/admin-apis/vendor-snippets.ts index b798c10..51793f9 100644 --- a/apps/backend/src/trpc/admin-apis/vendor-snippets.ts +++ b/apps/backend/src/trpc/admin-apis/vendor-snippets.ts @@ -2,14 +2,15 @@ import { router, publicProcedure, protectedProcedure } from '../trpc-index'; import { z } from 'zod'; import { db } from '../../db/db_index'; import { vendorSnippets, deliverySlotInfo, productInfo, orders, orderItems, users } from '../../db/schema'; -import { eq, and, inArray } from 'drizzle-orm'; +import { eq, and, inArray, isNotNull, gt, sql, asc } from 'drizzle-orm'; import { appUrl } from '../../lib/env-exporter'; const createSnippetSchema = z.object({ snippetCode: z.string().min(1, "Snippet code is required"), - slotId: z.number().int().positive("Valid slot ID is required"), + slotId: z.number().optional(), productIds: z.array(z.number().int().positive()).min(1, "At least one product is required"), validTill: z.string().optional(), + isPermanent: z.boolean().default(false) }); const updateSnippetSchema = z.object({ @@ -17,6 +18,7 @@ const updateSnippetSchema = z.object({ updates: createSnippetSchema.partial().extend({ snippetCode: z.string().min(1).optional(), productIds: z.array(z.number().int().positive()).optional(), + isPermanent: z.boolean().default(false) }), }); @@ -24,20 +26,22 @@ export const vendorSnippetsRouter = router({ create: protectedProcedure .input(createSnippetSchema) .mutation(async ({ input, ctx }) => { - const { snippetCode, slotId, productIds, validTill } = input; + const { snippetCode, slotId, productIds, validTill, isPermanent } = input; // Get staff user ID from auth middleware const staffUserId = ctx.staffUser?.id; if (!staffUserId) { throw new Error("Unauthorized"); } - + // Validate slot exists - const slot = await db.query.deliverySlotInfo.findFirst({ - where: eq(deliverySlotInfo.id, slotId), - }); - if (!slot) { - throw new Error("Invalid slot ID"); + if(slotId) { + const slot = await db.query.deliverySlotInfo.findFirst({ + where: eq(deliverySlotInfo.id, slotId), + }); + if (!slot) { + throw new Error("Invalid slot ID"); + } } // Validate products exist @@ -60,6 +64,7 @@ export const vendorSnippetsRouter = router({ snippetCode, slotId, productIds, + isPermanent, validTill: validTill ? new Date(validTill) : undefined, }).returning(); @@ -71,17 +76,29 @@ export const vendorSnippetsRouter = router({ console.log('from the vendor snipptes methods') try { - const result = await db.query.vendorSnippets.findMany({ with: { slot: true, }, orderBy: (vendorSnippets, { desc }) => [desc(vendorSnippets.createdAt)], }); - return result.map(snippet => ({ - ...snippet, - accessUrl: `${appUrl}/vendor-order-list?id=${snippet.snippetCode}` - })); + + const snippetsWithProducts = await Promise.all( + result.map(async (snippet) => { + const products = await db.query.productInfo.findMany({ + where: inArray(productInfo.id, snippet.productIds), + columns: { id: true, name: true }, + }); + + return { + ...snippet, + accessUrl: `${appUrl}/vendor-order-list?id=${snippet.snippetCode}`, + products: products.map(p => ({ id: p.id, name: p.name })), + }; + }) + ); + + return snippetsWithProducts; } catch(e) { console.log(e) @@ -112,7 +129,8 @@ export const vendorSnippetsRouter = router({ .input(updateSnippetSchema) .mutation(async ({ input }) => { const { id, updates } = input; - + console.log({updates}) + // Check if snippet exists const existingSnippet = await db.query.vendorSnippets.findFirst({ where: eq(vendorSnippets.id, id), @@ -208,7 +226,7 @@ export const vendorSnippetsRouter = router({ // Query orders that match the snippet criteria const matchingOrders = await db.query.orders.findMany({ where: and( - eq(orders.slotId, snippet.slotId), + eq(orders.slotId, snippet.slotId!), // We'll filter by products in the application logic ), with: { @@ -277,6 +295,7 @@ export const vendorSnippetsRouter = router({ productIds: snippet.productIds, validTill: snippet.validTill?.toISOString(), createdAt: snippet.createdAt.toISOString(), + isPermanent: snippet.isPermanent, }, }; }), @@ -312,6 +331,134 @@ export const vendorSnippetsRouter = router({ })); }), + getUpcomingSlots: publicProcedure + .query(async () => { + const now = new Date(); + const slots = await db.query.deliverySlotInfo.findMany({ + where: and( + eq(deliverySlotInfo.isActive, true), + gt(deliverySlotInfo.deliveryTime, now) + ), + orderBy: asc(deliverySlotInfo.deliveryTime), + }); + + return { + success: true, + data: slots.map(slot => ({ + id: slot.id, + deliveryTime: slot.deliveryTime.toISOString(), + freezeTime: slot.freezeTime.toISOString(), + deliverySequence: slot.deliverySequence, + })), + }; + }), + + getOrdersBySnippetAndSlot: publicProcedure + .input(z.object({ + snippetCode: z.string().min(1, "Snippet code is required"), + slotId: z.number().int().positive("Valid slot ID is required"), + })) + .query(async ({ input }) => { + const { snippetCode, slotId } = input; + + // Find the snippet + const snippet = await db.query.vendorSnippets.findFirst({ + where: eq(vendorSnippets.snippetCode, snippetCode), + }); + + if (!snippet) { + throw new Error("Vendor snippet not found"); + } + + // Find the slot + const slot = await db.query.deliverySlotInfo.findFirst({ + where: eq(deliverySlotInfo.id, slotId), + }); + + if (!slot) { + throw new Error("Slot not found"); + } + + // Query orders that match the slot and snippet criteria + const matchingOrders = await db.query.orders.findMany({ + where: eq(orders.slotId, slotId), + with: { + orderItems: { + with: { + product: { + with: { + unit: true, + }, + }, + }, + }, + user: true, + slot: true, + }, + orderBy: (orders, { desc }) => [desc(orders.createdAt)], + }); + + // Filter orders that contain at least one of the snippet's products + const filteredOrders = matchingOrders.filter(order => { + const orderProductIds = order.orderItems.map(item => item.productId); + return snippet.productIds.some(productId => orderProductIds.includes(productId)); + }); + + // Format the response + const formattedOrders = filteredOrders.map(order => { + // Filter orderItems to only include products attached to the snippet + const attachedOrderItems = order.orderItems.filter(item => + snippet.productIds.includes(item.productId) + ); + + const products = attachedOrderItems.map(item => ({ + orderItemId: item.id, + productId: item.productId, + productName: item.product.name, + quantity: parseFloat(item.quantity), + price: parseFloat(item.price.toString()), + unit: item.product.unit?.shortNotation || 'unit', + subtotal: parseFloat(item.price.toString()) * parseFloat(item.quantity), + is_packaged: item.is_packaged, + is_package_verified: item.is_package_verified, + })); + + return { + orderId: `ORD${order.readableId.toString().padStart(3, '0')}`, + orderDate: order.createdAt.toISOString(), + customerName: order.user.name, + totalAmount: order.totalAmount, + slotInfo: order.slot ? { + time: order.slot.deliveryTime.toISOString(), + sequence: order.slot.deliverySequence, + } : null, + products, + matchedProducts: snippet.productIds, + snippetCode: snippet.snippetCode, + }; + }); + + return { + success: true, + data: formattedOrders, + snippet: { + id: snippet.id, + snippetCode: snippet.snippetCode, + slotId: snippet.slotId, + productIds: snippet.productIds, + validTill: snippet.validTill?.toISOString(), + createdAt: snippet.createdAt.toISOString(), + isPermanent: snippet.isPermanent, + }, + selectedSlot: { + id: slot.id, + deliveryTime: slot.deliveryTime.toISOString(), + freezeTime: slot.freezeTime.toISOString(), + deliverySequence: slot.deliverySequence, + }, + }; + }), + updateOrderItemPackaging: publicProcedure .input(z.object({ orderItemId: z.number().int().positive("Valid order item ID required"), diff --git a/apps/fallback-ui/src/routes/vendor-order-list.tsx b/apps/fallback-ui/src/routes/vendor-order-list.tsx index 00f0e46..011b25b 100644 --- a/apps/fallback-ui/src/routes/vendor-order-list.tsx +++ b/apps/fallback-ui/src/routes/vendor-order-list.tsx @@ -1,4 +1,4 @@ -import { useMemo, useState } from 'react' +import { useMemo, useState, useEffect } from 'react' import { useSearch } from '@tanstack/react-router' import { trpc } from '../trpc/client' import { cn } from '@/lib/utils' @@ -20,12 +20,48 @@ interface VendorOrder { }> } +interface DeliverySlot { + id: number + deliveryTime: string + freezeTime: string + deliverySequence: any +} + export function VendorOrderListRoute() { const { id } = useSearch({ from: '/vendor-order-list' }) - const { data, error, isLoading, isFetching, refetch } = id + // Fetch snippet info + const { data: snippetInfo, isLoading: isLoadingSnippet } = id ? trpc.admin.vendorSnippets.getOrdersBySnippet.useQuery({ snippetCode: id }) - : { data: null, error: null, isLoading: false, isFetching: false, refetch: () => {} } + : { data: null, isLoading: false } + const snippet = snippetInfo?.snippet + const isPermanent = snippet?.isPermanent + + const { data: upcomingSlots } = trpc.admin.vendorSnippets.getUpcomingSlots.useQuery(undefined, { enabled: !!id }) + + // State for selected slot + const [selectedSlotId, setSelectedSlotId] = useState(null) + + // Auto-select first slot when snippets are loaded and isPermanent is true + useEffect(() => { + if (isPermanent && upcomingSlots?.data && upcomingSlots.data.length > 0 && !selectedSlotId) { + setSelectedSlotId(upcomingSlots.data[0].id) + } + }, [isPermanent, upcomingSlots, selectedSlotId]) + + // Fetch orders based on mode + const { data: slotOrdersData, error, isLoading: isLoadingOrders, isFetching, refetch } = trpc.admin.vendorSnippets.getOrdersBySnippetAndSlot.useQuery( + { snippetCode: id!, slotId: selectedSlotId! }, + { enabled: !!id && !!selectedSlotId && isPermanent } + ) + +const { data: regularOrders } = trpc.admin.vendorSnippets.getOrdersBySnippet.useQuery( + { snippetCode: id! }, + { enabled: !!id && !isPermanent } + ) + + const orders = slotOrdersData?.data || regularOrders?.data || [] + const isLoadingCurrent = isPermanent ? isLoadingOrders : isLoadingSnippet const updatePackagingMutation = trpc.admin.vendorSnippets.updateOrderItemPackaging.useMutation() @@ -52,8 +88,6 @@ export function VendorOrderListRoute() { } } - const orders = data?.success ? data.data : [] - const productSummary = useMemo(() => { const summary: Record = {}; @@ -98,6 +132,25 @@ export function VendorOrderListRoute() { {id && Snippet: {id}}

+ {isPermanent && upcomingSlots?.data && ( +
+ + +
+ )} -
- {isLoading ? ( -
- Loading orders… -
+
+ {isLoadingCurrent ? ( +
+ Loading orders… +
) : error ? (
{error.message ?? 'Unable to load vendor orders right now'} @@ -204,7 +257,7 @@ export function VendorOrderListRoute() { )}
- {isFetching && !isLoading ? ( + {isFetching && !isLoadingCurrent ? (

Refreshing…

) : null}