Skip to content

Commit 2df2a13

Browse files
authored
Merge pull request #38 from Zenfulcode/development
Development
2 parents 97caf99 + 869520c commit 2df2a13

31 files changed

Lines changed: 1778 additions & 333 deletions

Makefile

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,34 @@ help: ## Show this help message
77

88
# Database commands
99
db-start: ## Start PostgreSQL database container
10-
docker-compose up -d postgres
10+
docker compose up -d postgres
1111

1212
db-stop: ## Stop PostgreSQL database container
13-
docker-compose stop postgres
13+
docker compose stop postgres
1414

1515
db-restart: ## Restart PostgreSQL database container
16-
docker-compose restart postgres
16+
docker compose restart postgres
1717

1818
db-logs: ## Show PostgreSQL database logs
19-
docker-compose logs -f postgres
19+
docker compose logs -f postgres
2020

2121
db-clean: ## Stop and remove PostgreSQL container and volumes
22-
docker-compose down postgres
22+
docker compose down postgres
2323
docker volume rm commercify_postgres_data 2>/dev/null || true
2424

2525
# Migration commands
2626
migrate-up: ## Run database migrations up
27-
docker-compose run --rm migrate -up
27+
docker compose run --rm migrate -up
2828

2929
migrate-down: ## Run database migrations down
30-
docker-compose run --rm migrate -down
30+
docker compose run --rm migrate -down
3131

3232
migrate-status: ## Show migration status
33-
docker-compose run --rm migrate -status
33+
docker compose run --rm migrate -status
3434

3535
# Seed data
3636
seed-data: ## Seed database with sample data
37-
docker-compose run --rm seed -all
37+
docker compose run --rm seed -all
3838

3939
# Application commands
4040
build: ## Build the application
@@ -48,13 +48,13 @@ run: db-start ## Run the application locally with database
4848
go run ./cmd/api
4949

5050
run-docker: ## Run the entire application stack with Docker
51-
docker-compose up -d
51+
docker compose up -d
5252

5353
stop-docker: ## Stop the entire application stack
54-
docker-compose down
54+
docker compose down
5555

5656
logs: ## Show application logs
57-
docker-compose logs -f api
57+
docker compose logs -f api
5858

5959
# Development commands
6060
test: ## Run tests

docker-compose.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ services:
66
environment:
77
POSTGRES_USER: postgres
88
POSTGRES_PASSWORD: postgres
9-
POSTGRES_DB: commercify
9+
POSTGRES_DB: commercifydb
1010
ports:
1111
- "5432:5432"
1212
volumes:
@@ -30,7 +30,7 @@ services:
3030
DB_PORT: 5432
3131
DB_USER: postgres
3232
DB_PASSWORD: postgres
33-
DB_NAME: commercify
33+
DB_NAME: commercifydb
3434

3535
# AUTH_JWT_SECRET: ${AUTH_JWT_SECRET}
3636

docs/commercify_checkout_postman_tests.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@
257257
"pm.test(\"Customer details were updated\", function () {",
258258
" pm.expect(response.customer_details).to.not.be.undefined;",
259259
" pm.expect(response.customer_details.email).to.equal(\"customer@example.com\");",
260-
" pm.expect(response.customer_details.phone).to.equal(\"+1234567890\");",
260+
" pm.expect(response.customer_details.phone).to.equal(\"1234567890\");",
261261
" pm.expect(response.customer_details.full_name).to.equal(\"John Doe\");",
262262
"});"
263263
],
@@ -275,7 +275,7 @@
275275
],
276276
"body": {
277277
"mode": "raw",
278-
"raw": "{\n \"email\": \"customer@example.com\",\n \"phone\": \"+1234567890\",\n \"full_name\": \"John Doe\"\n}"
278+
"raw": "{\n \"email\": \"customer@example.com\",\n \"phone\": \"1234567890\",\n \"full_name\": \"John Doe\"\n}"
279279
},
280280
"url": {
281281
"raw": "{{baseUrl}}/api/checkout/customer-details",

docs/product_api_examples.md

Lines changed: 179 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -599,40 +599,196 @@ Example response:
599599

600600
## Multi-Currency Product Management
601601

602-
### Setting Product Currency Prices
602+
## Multi-Currency Variant Pricing
603603

604-
When creating or updating products and their variants, you can specify prices in multiple currencies using the `currency_prices` array property. Each entry in this array should include:
604+
### Set Variant Price in Specific Currency
605605

606-
- `currency_code`: The three-letter ISO code of the currency (e.g., "USD", "EUR", "GBP")
607-
- `price`: The price in the specified currency
608-
- `compare_price` (optional): The compare price (original/before discount price) in the specified currency
606+
```plaintext
607+
POST /api/admin/variants/{variant_id}/prices
608+
```
609+
610+
**Request Body:**
611+
612+
```json
613+
{
614+
"currency_code": "DKK",
615+
"price": 250.0
616+
}
617+
```
618+
619+
**Response Body:**
620+
621+
```json
622+
{
623+
"id": 1,
624+
"product_id": 1,
625+
"sku": "PROD-001-RED",
626+
"price": 25.0,
627+
"currency": "USD",
628+
"stock": 10,
629+
"attributes": [
630+
{
631+
"name": "Color",
632+
"value": "Red"
633+
}
634+
],
635+
"images": [],
636+
"is_default": true,
637+
"created_at": "2025-06-20T10:00:00Z",
638+
"updated_at": "2025-06-20T10:30:00Z",
639+
"prices": {
640+
"USD": 25.0,
641+
"DKK": 250.0
642+
}
643+
}
644+
```
645+
646+
**Status Codes:**
647+
648+
- `200 OK`: Price set successfully
649+
- `400 Bad Request`: Invalid request body or currency not enabled
650+
- `401 Unauthorized`: Not authenticated
651+
- `403 Forbidden`: Not authorized (not an admin)
652+
- `404 Not Found`: Variant or currency not found
653+
654+
### Set Multiple Variant Prices
655+
656+
```plaintext
657+
PUT /api/admin/variants/{variant_id}/prices
658+
```
659+
660+
**Request Body:**
661+
662+
```json
663+
{
664+
"prices": {
665+
"USD": 25.0,
666+
"EUR": 21.25,
667+
"DKK": 250.0
668+
}
669+
}
670+
```
671+
672+
**Response Body:**
673+
674+
```json
675+
{
676+
"id": 1,
677+
"product_id": 1,
678+
"sku": "PROD-001-RED",
679+
"price": 25.0,
680+
"currency": "USD",
681+
"stock": 10,
682+
"attributes": [
683+
{
684+
"name": "Color",
685+
"value": "Red"
686+
}
687+
],
688+
"images": [],
689+
"is_default": true,
690+
"created_at": "2025-06-20T10:00:00Z",
691+
"updated_at": "2025-06-20T10:30:00Z",
692+
"prices": {
693+
"USD": 25.0,
694+
"EUR": 21.25,
695+
"DKK": 250.0
696+
}
697+
}
698+
```
699+
700+
**Status Codes:**
701+
702+
- `200 OK`: Prices set successfully
703+
- `400 Bad Request`: Invalid request body or one or more currencies not enabled
704+
- `401 Unauthorized`: Not authenticated
705+
- `403 Forbidden`: Not authorized (not an admin)
706+
- `404 Not Found`: Variant not found
707+
708+
### Get Variant Prices
709+
710+
```plaintext
711+
GET /api/variants/{variant_id}/prices
712+
```
713+
714+
**Response Body:**
715+
716+
```json
717+
{
718+
"prices": {
719+
"USD": 25.0,
720+
"EUR": 21.25,
721+
"DKK": 250.0
722+
}
723+
}
724+
```
609725

610-
The system always requires a price in the default currency, and additional currency prices are optional. If a currency price is not specified for a particular currency, the system will automatically convert the price from the default currency using the current exchange rate when needed.
726+
**Status Codes:**
611727

612-
### Retrieving Products with Specific Currency Prices
728+
- `200 OK`: Prices retrieved successfully
729+
- `404 Not Found`: Variant not found
613730

614-
When retrieving products, you can specify a currency code in the query parameters to get prices in that currency:
731+
### Remove Variant Price in Specific Currency
615732

733+
```plaintext
734+
DELETE /api/admin/variants/{variant_id}/prices/{currency_code}
616735
```
617-
GET /api/products/1?currency=EUR
736+
737+
**Response Body:**
738+
739+
```json
740+
{
741+
"id": 1,
742+
"product_id": 1,
743+
"sku": "PROD-001-RED",
744+
"price": 25.0,
745+
"currency": "USD",
746+
"stock": 10,
747+
"attributes": [
748+
{
749+
"name": "Color",
750+
"value": "Red"
751+
}
752+
],
753+
"images": [],
754+
"is_default": true,
755+
"created_at": "2025-06-20T10:00:00Z",
756+
"updated_at": "2025-06-20T10:30:00Z",
757+
"prices": {
758+
"USD": 25.0,
759+
"EUR": 21.25
760+
}
761+
}
618762
```
619763

620-
This will return the product with prices in euros, either using the explicitly set euro prices or converting from the default currency if no specific euro prices are set.
764+
**Status Codes:**
765+
766+
- `200 OK`: Price removed successfully
767+
- `400 Bad Request`: Cannot remove default currency price
768+
- `401 Unauthorized`: Not authenticated
769+
- `403 Forbidden`: Not authorized (not an admin)
770+
- `404 Not Found`: Variant not found or price not set for this currency
771+
772+
## Benefits of Multi-Currency Pricing
773+
774+
### Precision and Accuracy
775+
776+
- **No conversion errors**: Set exact prices in each currency to avoid floating-point precision issues
777+
- **Local pricing**: Set appropriate prices for each market without relying on exchange rate calculations
778+
- **Price consistency**: Ensure consistent pricing across all customer touchpoints
779+
780+
### Checkout Integration
621781

622-
## Example Workflow
782+
- **Automatic price selection**: When customers checkout in a specific currency, the system automatically uses the exact price set for that currency
783+
- **Fallback conversion**: If no specific price is set for a currency, the system falls back to conversion from the default currency
784+
- **Currency parameter**: API clients can specify the desired checkout currency as a parameter
623785

624-
### Product Management Flow (Seller)
786+
### Example Use Case
625787

626-
1. Seller creates a base product through the seller interface
627-
2. If the product has variants, seller adds variants with different attributes (color, size, etc.)
628-
3. Seller can update product information or variant details as needed
629-
4. Seller can manage inventory levels for products and variants
630-
5. Seller can deactivate or delete products when they're no longer available
788+
A product originally priced at 25.00 USD might be set to exactly:
631789

632-
### Product Shopping Flow (Customer)
790+
- 250.00 DKK (instead of 249.96 DKK from conversion)
791+
- 21.25 EUR (instead of 21.24 EUR from conversion)
792+
- 19.99 GBP (psychological pricing)
633793

634-
1. Customers browse products by category or use the search function
635-
2. Customers can view detailed product information including available variants
636-
3. When adding to checkout, customers select specific variants if the product has them
637-
4. Products and variants are displayed with current inventory levels
638-
5. Out-of-stock products or variants can be marked as unavailable for purchase
794+
This eliminates the reported issue where a 250 DKK product was showing as 249.89 DKK due to conversion precision problems.

0 commit comments

Comments
 (0)