Skip to content

Commit 0152dc1

Browse files
committed
Add Sales Operations with 20 Reports - Multi-Channel Support
This commit adds comprehensive sales operations capabilities to the Futon Manufacturing Database, including support for Retail, Online, and Wholesale sales channels. New Features: - Multi-channel sales support (Retail, Online, Wholesale) - Retail store management with 7 sample stores - Sales territories and representative tracking - Sales quotation and conversion tracking - Sales returns and refund management - Promotional campaigns and pricing - Channel-specific price lists - 20 comprehensive sales operations reports Sales Reports (20 total): 1. Sales Performance by Channel - Multi-channel analysis 2. Store Performance - Individual store metrics 3. Sales Rep Performance - Territory and conversion tracking 4. Customer Sales Analysis - Segmentation and status 5. Product Sales Performance - By channel profitability 6. Sales Trend Analysis - MoM and YoY growth 7. Order Value Analysis - AOV and order size distribution 8. Returns Analysis - By reason, product, channel 9. Quote Conversion - Pipeline and win rates 10. Discount Analysis - Impact on margins 11. Top Products - Ranked by multiple metrics 12. Sales by Territory - Geographic performance 13. Channel Profitability - Full P&L by channel 14. Customer Lifetime Value - CLV with tiers 15. Sales Growth Analysis - Trends and patterns 16. Order Size Distribution - Basket analysis 17. Product Mix Analysis - Cross-sell opportunities 18. Time-Based Analysis - Day/hour patterns 19. Sales Pipeline - Funnel conversion rates 20. RFM Segmentation - Customer targeting Sample Data Added: - 6 sales territories across regions - 8 sales representatives - 7 retail stores (Portland, Seattle, SF, LA) - 15 sales orders across all channels - 2 sales returns with reasons - 2 sales quotes - 4 promotional campaigns - 3 channel-specific price lists Database Enhancements: - SalesChannel table (Retail, Online, Wholesale) - Store table for retail locations - SalesTerritory and SalesRep tables - SalesReturn and SalesReturnDetail tables - SalesQuote and SalesQuoteDetail tables - Promotion table for campaigns - PriceList and PriceListDetail tables - Enhanced SalesOrder with channel, store, and rep tracking - Discount tracking at order and line level Files Added: - 05-sales-schema-enhancements.sql - Sales tables and enhancements - 06-sales-sample-data.sql - Sales sample data (territories, reps, stores, orders) - 07-sales-reports.sql - 20 sales operations report views - 08-sales-sample-queries.sql - Example queries for sales analysis Documentation: - Updated README with sales reports documentation - Added sales operations use cases - Updated installation instructions - Version bumped to 2.0.0
1 parent b65ccdc commit 0152dc1

5 files changed

Lines changed: 2342 additions & 4 deletions

File tree

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
-- =============================================
2+
-- Sales Operations Schema Enhancements
3+
-- Futon Manufacturing Database
4+
-- =============================================
5+
-- Adds sales channel tracking, stores, and enhanced
6+
-- sales operations capabilities
7+
-- =============================================
8+
9+
USE FutonManufacturing;
10+
GO
11+
12+
-- =============================================
13+
-- Sales Channels and Stores
14+
-- =============================================
15+
16+
CREATE TABLE SalesChannel (
17+
SalesChannelID INT IDENTITY(1,1) PRIMARY KEY,
18+
ChannelCode NVARCHAR(20) NOT NULL UNIQUE,
19+
ChannelName NVARCHAR(100) NOT NULL,
20+
Description NVARCHAR(255),
21+
IsActive BIT NOT NULL DEFAULT 1
22+
);
23+
24+
INSERT INTO SalesChannel (ChannelCode, ChannelName, Description) VALUES
25+
('RETAIL', 'Retail Store', 'Physical retail store sales'),
26+
('ONLINE', 'Online/E-Commerce', 'Online website and marketplace sales'),
27+
('WHOLESALE', 'Wholesale', 'Bulk sales to retailers and distributors');
28+
29+
CREATE TABLE Store (
30+
StoreID INT IDENTITY(1,1) PRIMARY KEY,
31+
StoreCode NVARCHAR(20) NOT NULL UNIQUE,
32+
StoreName NVARCHAR(100) NOT NULL,
33+
SalesChannelID INT NOT NULL,
34+
Manager NVARCHAR(100),
35+
Phone NVARCHAR(20),
36+
Email NVARCHAR(100),
37+
Address NVARCHAR(255),
38+
City NVARCHAR(100),
39+
State NVARCHAR(50),
40+
ZipCode NVARCHAR(20),
41+
OpenDate DATE,
42+
IsActive BIT NOT NULL DEFAULT 1,
43+
CONSTRAINT FK_Store_SalesChannel FOREIGN KEY (SalesChannelID) REFERENCES SalesChannel(SalesChannelID)
44+
);
45+
46+
CREATE TABLE SalesTerritory (
47+
TerritoryID INT IDENTITY(1,1) PRIMARY KEY,
48+
TerritoryCode NVARCHAR(20) NOT NULL UNIQUE,
49+
TerritoryName NVARCHAR(100) NOT NULL,
50+
Region NVARCHAR(50),
51+
IsActive BIT NOT NULL DEFAULT 1
52+
);
53+
54+
CREATE TABLE SalesRep (
55+
SalesRepID INT IDENTITY(1,1) PRIMARY KEY,
56+
EmployeeCode NVARCHAR(20) NOT NULL UNIQUE,
57+
FirstName NVARCHAR(50) NOT NULL,
58+
LastName NVARCHAR(50) NOT NULL,
59+
Email NVARCHAR(100),
60+
Phone NVARCHAR(20),
61+
TerritoryID INT,
62+
HireDate DATE,
63+
IsActive BIT NOT NULL DEFAULT 1,
64+
CONSTRAINT FK_SalesRep_Territory FOREIGN KEY (TerritoryID) REFERENCES SalesTerritory(TerritoryID)
65+
);
66+
67+
-- =============================================
68+
-- Enhance Existing Tables
69+
-- =============================================
70+
71+
-- Add sales channel tracking to SalesOrder
72+
ALTER TABLE SalesOrder ADD SalesChannelID INT NULL;
73+
ALTER TABLE SalesOrder ADD StoreID INT NULL;
74+
ALTER TABLE SalesOrder ADD SalesRepID INT NULL;
75+
ALTER TABLE SalesOrder ADD DiscountAmount DECIMAL(18,2) DEFAULT 0;
76+
ALTER TABLE SalesOrder ADD NetAmount AS (TotalAmount - DiscountAmount) PERSISTED;
77+
78+
ALTER TABLE SalesOrder ADD CONSTRAINT FK_SalesOrder_SalesChannel
79+
FOREIGN KEY (SalesChannelID) REFERENCES SalesChannel(SalesChannelID);
80+
ALTER TABLE SalesOrder ADD CONSTRAINT FK_SalesOrder_Store
81+
FOREIGN KEY (StoreID) REFERENCES Store(StoreID);
82+
ALTER TABLE SalesOrder ADD CONSTRAINT FK_SalesOrder_SalesRep
83+
FOREIGN KEY (SalesRepID) REFERENCES SalesRep(SalesRepID);
84+
85+
-- Add discount tracking to SalesOrderDetail
86+
ALTER TABLE SalesOrderDetail ADD DiscountPercent DECIMAL(5,2) DEFAULT 0;
87+
ALTER TABLE SalesOrderDetail ADD DiscountAmount AS (LineTotal * DiscountPercent / 100) PERSISTED;
88+
ALTER TABLE SalesOrderDetail ADD NetAmount AS (LineTotal - (LineTotal * DiscountPercent / 100)) PERSISTED;
89+
90+
-- Add customer segmentation
91+
ALTER TABLE Customer ADD CustomerType NVARCHAR(20) DEFAULT 'Retail'; -- Retail, Wholesale, Online
92+
ALTER TABLE Customer ADD SalesRepID INT NULL;
93+
ALTER TABLE Customer ADD TerritoryID INT NULL;
94+
95+
ALTER TABLE Customer ADD CONSTRAINT FK_Customer_SalesRep
96+
FOREIGN KEY (SalesRepID) REFERENCES SalesRep(SalesRepID);
97+
ALTER TABLE Customer ADD CONSTRAINT FK_Customer_Territory
98+
FOREIGN KEY (TerritoryID) REFERENCES SalesTerritory(TerritoryID);
99+
100+
-- =============================================
101+
-- Sales Returns and Exchanges
102+
-- =============================================
103+
104+
CREATE TABLE ReturnReason (
105+
ReturnReasonID INT IDENTITY(1,1) PRIMARY KEY,
106+
ReasonCode NVARCHAR(20) NOT NULL UNIQUE,
107+
ReasonDescription NVARCHAR(255) NOT NULL,
108+
IsActive BIT NOT NULL DEFAULT 1
109+
);
110+
111+
INSERT INTO ReturnReason (ReasonCode, ReasonDescription) VALUES
112+
('DEFECT', 'Product defect or quality issue'),
113+
('DAMAGE', 'Damaged during shipping'),
114+
('WRONG', 'Wrong item received'),
115+
('NOFIT', 'Does not fit/wrong size'),
116+
('EXPECT', 'Did not meet expectations'),
117+
('CHANGE', 'Customer changed mind'),
118+
('LATE', 'Delivery too late'),
119+
('OTHER', 'Other reason');
120+
121+
CREATE TABLE SalesReturn (
122+
ReturnID INT IDENTITY(1,1) PRIMARY KEY,
123+
ReturnNumber NVARCHAR(50) NOT NULL UNIQUE,
124+
SalesOrderID INT NOT NULL,
125+
CustomerID INT NOT NULL,
126+
ReturnDate DATE NOT NULL DEFAULT CAST(GETDATE() AS DATE),
127+
ReturnReasonID INT NOT NULL,
128+
Status NVARCHAR(20) NOT NULL DEFAULT 'Pending', -- Pending, Approved, Received, Refunded, Denied
129+
RefundAmount DECIMAL(18,2) DEFAULT 0,
130+
RestockingFee DECIMAL(18,2) DEFAULT 0,
131+
Notes NVARCHAR(MAX),
132+
ApprovedBy NVARCHAR(100),
133+
ApprovedDate DATETIME2,
134+
CreatedDate DATETIME2 DEFAULT GETDATE(),
135+
CONSTRAINT FK_Return_SalesOrder FOREIGN KEY (SalesOrderID) REFERENCES SalesOrder(SalesOrderID),
136+
CONSTRAINT FK_Return_Customer FOREIGN KEY (CustomerID) REFERENCES Customer(CustomerID),
137+
CONSTRAINT FK_Return_Reason FOREIGN KEY (ReturnReasonID) REFERENCES ReturnReason(ReturnReasonID)
138+
);
139+
140+
CREATE TABLE SalesReturnDetail (
141+
ReturnDetailID INT IDENTITY(1,1) PRIMARY KEY,
142+
ReturnID INT NOT NULL,
143+
SODetailID INT NOT NULL,
144+
ItemID INT NOT NULL,
145+
QuantityReturned DECIMAL(18,2) NOT NULL,
146+
UnitPrice DECIMAL(18,4) NOT NULL,
147+
RefundAmount DECIMAL(18,2) NOT NULL,
148+
Disposition NVARCHAR(50), -- Restock, Scrap, Repair, RMA
149+
CONSTRAINT FK_ReturnDetail_Return FOREIGN KEY (ReturnID) REFERENCES SalesReturn(ReturnID),
150+
CONSTRAINT FK_ReturnDetail_SODetail FOREIGN KEY (SODetailID) REFERENCES SalesOrderDetail(SODetailID),
151+
CONSTRAINT FK_ReturnDetail_Item FOREIGN KEY (ItemID) REFERENCES Items(ItemID)
152+
);
153+
154+
-- =============================================
155+
-- Sales Quotations
156+
-- =============================================
157+
158+
CREATE TABLE SalesQuote (
159+
QuoteID INT IDENTITY(1,1) PRIMARY KEY,
160+
QuoteNumber NVARCHAR(50) NOT NULL UNIQUE,
161+
CustomerID INT NOT NULL,
162+
SalesChannelID INT,
163+
SalesRepID INT,
164+
QuoteDate DATE NOT NULL DEFAULT CAST(GETDATE() AS DATE),
165+
ExpirationDate DATE,
166+
Status NVARCHAR(20) NOT NULL DEFAULT 'Draft', -- Draft, Sent, Accepted, Declined, Expired
167+
Subtotal DECIMAL(18,2) DEFAULT 0,
168+
DiscountAmount DECIMAL(18,2) DEFAULT 0,
169+
TaxAmount DECIMAL(18,2) DEFAULT 0,
170+
TotalAmount DECIMAL(18,2) DEFAULT 0,
171+
ConvertedToOrderID INT NULL,
172+
Notes NVARCHAR(MAX),
173+
CreatedBy NVARCHAR(100),
174+
CreatedDate DATETIME2 DEFAULT GETDATE(),
175+
CONSTRAINT FK_Quote_Customer FOREIGN KEY (CustomerID) REFERENCES Customer(CustomerID),
176+
CONSTRAINT FK_Quote_SalesChannel FOREIGN KEY (SalesChannelID) REFERENCES SalesChannel(SalesChannelID),
177+
CONSTRAINT FK_Quote_SalesRep FOREIGN KEY (SalesRepID) REFERENCES SalesRep(SalesRepID),
178+
CONSTRAINT FK_Quote_ConvertedOrder FOREIGN KEY (ConvertedToOrderID) REFERENCES SalesOrder(SalesOrderID)
179+
);
180+
181+
CREATE TABLE SalesQuoteDetail (
182+
QuoteDetailID INT IDENTITY(1,1) PRIMARY KEY,
183+
QuoteID INT NOT NULL,
184+
LineNumber INT NOT NULL,
185+
ItemID INT NOT NULL,
186+
Quantity DECIMAL(18,2) NOT NULL,
187+
UnitPrice DECIMAL(18,4) NOT NULL,
188+
DiscountPercent DECIMAL(5,2) DEFAULT 0,
189+
LineTotal AS (Quantity * UnitPrice * (1 - DiscountPercent/100)) PERSISTED,
190+
CONSTRAINT FK_QuoteDetail_Quote FOREIGN KEY (QuoteID) REFERENCES SalesQuote(QuoteID),
191+
CONSTRAINT FK_QuoteDetail_Item FOREIGN KEY (ItemID) REFERENCES Items(ItemID)
192+
);
193+
194+
-- =============================================
195+
-- Promotions and Pricing
196+
-- =============================================
197+
198+
CREATE TABLE Promotion (
199+
PromotionID INT IDENTITY(1,1) PRIMARY KEY,
200+
PromotionCode NVARCHAR(50) NOT NULL UNIQUE,
201+
PromotionName NVARCHAR(255) NOT NULL,
202+
Description NVARCHAR(MAX),
203+
DiscountPercent DECIMAL(5,2),
204+
DiscountAmount DECIMAL(18,2),
205+
StartDate DATE NOT NULL,
206+
EndDate DATE NOT NULL,
207+
IsActive BIT NOT NULL DEFAULT 1,
208+
MinimumPurchase DECIMAL(18,2) DEFAULT 0,
209+
ApplicableChannels NVARCHAR(255) -- CSV: RETAIL,ONLINE,WHOLESALE
210+
);
211+
212+
CREATE TABLE PriceList (
213+
PriceListID INT IDENTITY(1,1) PRIMARY KEY,
214+
PriceListCode NVARCHAR(20) NOT NULL UNIQUE,
215+
PriceListName NVARCHAR(100) NOT NULL,
216+
SalesChannelID INT,
217+
EffectiveDate DATE NOT NULL,
218+
EndDate DATE,
219+
IsActive BIT NOT NULL DEFAULT 1,
220+
CONSTRAINT FK_PriceList_SalesChannel FOREIGN KEY (SalesChannelID) REFERENCES SalesChannel(SalesChannelID)
221+
);
222+
223+
CREATE TABLE PriceListDetail (
224+
PriceListDetailID INT IDENTITY(1,1) PRIMARY KEY,
225+
PriceListID INT NOT NULL,
226+
ItemID INT NOT NULL,
227+
UnitPrice DECIMAL(18,4) NOT NULL,
228+
MinimumQuantity DECIMAL(18,2) DEFAULT 1,
229+
CONSTRAINT FK_PriceListDetail_PriceList FOREIGN KEY (PriceListID) REFERENCES PriceList(PriceListID),
230+
CONSTRAINT FK_PriceListDetail_Item FOREIGN KEY (ItemID) REFERENCES Items(ItemID)
231+
);
232+
233+
-- =============================================
234+
-- Indexes for Performance
235+
-- =============================================
236+
237+
CREATE NONCLUSTERED INDEX IX_SalesOrder_Channel ON SalesOrder(SalesChannelID, OrderDate);
238+
CREATE NONCLUSTERED INDEX IX_SalesOrder_Store ON SalesOrder(StoreID, OrderDate);
239+
CREATE NONCLUSTERED INDEX IX_SalesOrder_SalesRep ON SalesOrder(SalesRepID, OrderDate);
240+
CREATE NONCLUSTERED INDEX IX_Customer_Type ON Customer(CustomerType);
241+
CREATE NONCLUSTERED INDEX IX_SalesReturn_Date ON SalesReturn(ReturnDate);
242+
CREATE NONCLUSTERED INDEX IX_SalesQuote_Status ON SalesQuote(Status, QuoteDate);
243+
244+
GO
245+
246+
PRINT 'Sales operations schema enhancements completed successfully!';
247+
GO

0 commit comments

Comments
 (0)