Skip to content

Commit 5d80227

Browse files
authored
Merge pull request #855 from karrioapi/hotfix/commodity-form-metadata-editor
hotfix/commodity form - metadata editor
2 parents 35ab1c1 + 81c6d11 commit 5d80227

2 files changed

Lines changed: 83 additions & 83 deletions

File tree

packages/core/modules/Orders/draft_order.tsx

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,43 @@ export default function Page(pageProps: { params: Promise<{ id?: string }> }) {
7070
setKey(`${id}-${Date.now()}`);
7171
};
7272

73+
// Helper function to analyze currencies in line items
74+
const analyzeCurrencies = () => {
75+
if (!order?.line_items || order.line_items.length === 0) {
76+
return { currencies: [], hasMixedCurrencies: false, hasValues: false };
77+
}
78+
79+
const itemsWithValues = order.line_items.filter(
80+
item => item.value_currency && item.value_amount && item.value_amount > 0
81+
);
82+
83+
if (itemsWithValues.length === 0) {
84+
return { currencies: [], hasMixedCurrencies: false, hasValues: false };
85+
}
86+
87+
const currencies = Array.from(new Set(
88+
itemsWithValues.map(item => item.value_currency)
89+
));
90+
91+
return {
92+
currencies,
93+
hasMixedCurrencies: currencies.length > 1,
94+
hasValues: true
95+
};
96+
};
97+
98+
// Currency validation logic
99+
const getCurrencyValidationErrors = () => {
100+
const errors: string[] = [];
101+
const { hasMixedCurrencies } = analyzeCurrencies();
102+
103+
if (hasMixedCurrencies) {
104+
errors.push("Please standardize currency - your order contains items with different currencies");
105+
}
106+
107+
return errors;
108+
};
109+
73110
// Validation logic
74111
const getValidationErrors = () => {
75112
const errors: string[] = [];
@@ -102,7 +139,7 @@ export default function Page(pageProps: { params: Promise<{ id?: string }> }) {
102139
return errors;
103140
};
104141

105-
const validationErrors = getValidationErrors();
142+
const validationErrors = [...getValidationErrors(), ...getCurrencyValidationErrors()];
106143
useEffect(() => {
107144
if (
108145
!ready &&
@@ -416,18 +453,30 @@ export default function Page(pageProps: { params: Promise<{ id?: string }> }) {
416453
<p className="font-semibold text-xs">
417454
TOTAL:{" "}
418455
{
419-
<span>
420-
{(order.line_items || []).reduce(
421-
(_, { quantity, value_amount }) =>
422-
_ +
456+
(() => {
457+
const { hasMixedCurrencies, hasValues, currencies } = analyzeCurrencies();
458+
459+
// If no items have values, show 0
460+
if (!hasValues) {
461+
return <span>0</span>;
462+
}
463+
464+
// If mixed currencies, show warning message
465+
if (hasMixedCurrencies) {
466+
return <span className="text-yellow-600">Mixed currencies</span>;
467+
}
468+
469+
// Single currency - calculate normally
470+
const total = (order.line_items || []).reduce(
471+
(sum, { quantity, value_amount }) =>
472+
sum +
423473
(isNone(quantity) ? 1 : (quantity as any)) *
424-
(isNone(value_amount)
425-
? 1.0
426-
: (value_amount as any)),
474+
(isNone(value_amount) ? 0 : (value_amount as any)),
427475
0.0,
428-
)}{" "}
429-
{(order.line_items || [])[0]?.value_currency}
430-
</span>
476+
);
477+
478+
return <span>{total} {currencies[0]}</span>;
479+
})()
431480
}
432481
</p>
433482
<p className="font-semibold text-xs">

packages/ui/components/commodity-edit-dialog.tsx

Lines changed: 23 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,9 @@ import {
99
import {
1010
CurrencyCodeEnum,
1111
DEFAULT_COMMODITY_CONTENT,
12-
MetadataObjectTypeEnum,
1312
WeightUnitEnum,
1413
} from "@karrio/types";
15-
import {
16-
MetadataEditor,
17-
MetadataEditorContext,
18-
} from "@karrio/ui/core/forms/metadata-editor";
14+
import { EnhancedMetadataEditor } from "@karrio/ui/components/enhanced-metadata-editor";
1915
import { isEqual, isNone } from "@karrio/lib";
2016
import { CommodityType, CURRENCY_OPTIONS, WEIGHT_UNITS } from "@karrio/types";
2117
import { useAPIMetadata } from "@karrio/hooks/api-metadata";
@@ -26,8 +22,6 @@ import { Label } from "@karrio/ui/components/ui/label";
2622
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@karrio/ui/components/ui/select";
2723
import { CountrySelect } from "@karrio/ui/components/country-select";
2824
import { Textarea } from "@karrio/ui/components/ui/textarea";
29-
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@karrio/ui/components/ui/collapsible";
30-
import { ChevronDown, ChevronUp } from "lucide-react";
3125
import { useOrders } from "@karrio/hooks/order";
3226

3327
export interface CommodityEditDialogProps {
@@ -38,6 +32,7 @@ export interface CommodityEditDialogProps {
3832
disableOrderLinking?: boolean;
3933
}
4034

35+
4136
export const CommodityEditDialog = ({
4237
trigger,
4338
commodity: initialCommodity,
@@ -65,18 +60,16 @@ export const CommodityEditDialog = ({
6560
setCommodity(initialCommodity || DEFAULT_COMMODITY_CONTENT);
6661
}, [initialCommodity]);
6762

63+
// always provide fresh state for new operations
6864
React.useEffect(() => {
69-
if (isOpen && !initialCommodity) {
70-
const timestamp = Date.now();
71-
const randomId = Math.random().toString(36).substr(2, 9);
72-
const tempId = `temp_${timestamp}_${randomId}`;
73-
74-
setCommodity({
75-
...DEFAULT_COMMODITY_CONTENT,
76-
id: tempId, // Assign temporary ID to prevent unwanted merging
77-
});
78-
setMaxQty(undefined);
79-
setAdvancedExpanded(false);
65+
if (isOpen) {
66+
// always set commodity state when opening
67+
const commodityData = initialCommodity || DEFAULT_COMMODITY_CONTENT;
68+
setCommodity(commodityData);
69+
// Reset maxQty for new operations
70+
if (!initialCommodity) {
71+
setMaxQty(undefined);
72+
}
8073
}
8174
}, [isOpen, initialCommodity]);
8275

@@ -235,9 +228,7 @@ export const CommodityEditDialog = ({
235228
</div>
236229

237230
<div className="space-y-2">
238-
<Label htmlFor="origin_country" className="text-sm font-medium">
239-
Origin Country <span className="text-red-500">*</span>
240-
</Label>
231+
<Label htmlFor="origin_country" className="text-sm font-medium">Origin Country</Label>
241232
<CountrySelect
242233
value={commodity?.origin_country || ""}
243234
onValueChange={(value) => handleChange("origin_country", value)}
@@ -354,56 +345,16 @@ export const CommodityEditDialog = ({
354345
/>
355346
</div>
356347

357-
{/* Advanced Fields */}
358-
<Collapsible open={advancedExpanded} onOpenChange={setAdvancedExpanded}>
359-
<CollapsibleTrigger asChild>
360-
<Button
361-
type="button"
362-
variant="ghost"
363-
className="flex items-center gap-2 text-sm font-medium text-blue-600 hover:text-blue-700 p-0 h-auto"
364-
>
365-
Advanced Options
366-
{advancedExpanded ? (
367-
<ChevronUp className="h-4 w-4" />
368-
) : (
369-
<ChevronDown className="h-4 w-4" />
370-
)}
371-
</Button>
372-
</CollapsibleTrigger>
373-
<CollapsibleContent className="space-y-6 mt-6 pl-4 border-l-2 border-gray-200">
374-
<MetadataEditor
375-
id={commodity?.id}
376-
object_type={MetadataObjectTypeEnum.commodity}
377-
metadata={commodity?.metadata}
378-
onChange={(value) => handleChange("metadata", value)}
379-
>
380-
{(() => {
381-
const { isEditing, editMetadata } = React.useContext(
382-
MetadataEditorContext,
383-
);
384-
385-
return (
386-
<>
387-
<div className="flex justify-between">
388-
<Label className="text-sm font-medium">Metadata</Label>
389-
390-
<Button
391-
type="button"
392-
variant="link"
393-
size="sm"
394-
disabled={isEditing}
395-
onClick={() => editMetadata()}
396-
className="text-blue-600 hover:text-blue-800 p-1 h-auto"
397-
>
398-
Edit metadata
399-
</Button>
400-
</div>
401-
</>
402-
);
403-
})()}
404-
</MetadataEditor>
405-
</CollapsibleContent>
406-
</Collapsible>
348+
{/* Metadata Editor */}
349+
<EnhancedMetadataEditor
350+
value={commodity?.metadata || {}}
351+
onChange={(metadata) => setCommodity({ ...commodity, metadata })}
352+
className="w-full"
353+
placeholder="No metadata configured"
354+
emptyStateMessage="Add key-value pairs to configure commodity metadata"
355+
showTypeInference={true}
356+
maxHeight="300px"
357+
/>
407358
</div>
408359
</div>
409360

@@ -431,4 +382,4 @@ export const CommodityEditDialog = ({
431382
);
432383
};
433384

434-
CommodityEditDialog.displayName = "CommodityEditDialog";
385+
CommodityEditDialog.displayName = "CommodityEditDialog";

0 commit comments

Comments
 (0)