@jytextiles/medusa-plugin-faire-store-sync 0.2.11 → 0.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -619,213 +619,6 @@ const config = adminSdk.defineRouteConfig({
|
|
|
619
619
|
const handle$3 = {
|
|
620
620
|
breadcrumb: () => "Faire Sync"
|
|
621
621
|
};
|
|
622
|
-
const STATUS_KEY = ["faire", "status"];
|
|
623
|
-
const TAXONOMY_KEY = ["faire", "taxonomy"];
|
|
624
|
-
const PARENT$1 = "/settings/faire";
|
|
625
|
-
const NONE = "__none__";
|
|
626
|
-
const cleanSettings = (form) => {
|
|
627
|
-
const out = { ...form };
|
|
628
|
-
for (const key of [
|
|
629
|
-
"default_brand_id",
|
|
630
|
-
"default_category"
|
|
631
|
-
]) {
|
|
632
|
-
if (!out[key] || out[key] === NONE) out[key] = null;
|
|
633
|
-
}
|
|
634
|
-
if (out.default_wholesale_markup_percent === "" || out.default_wholesale_markup_percent === NONE) {
|
|
635
|
-
out.default_wholesale_markup_percent = null;
|
|
636
|
-
}
|
|
637
|
-
if (out.default_lead_time_days === "" || out.default_lead_time_days === NONE) {
|
|
638
|
-
out.default_lead_time_days = null;
|
|
639
|
-
}
|
|
640
|
-
return out;
|
|
641
|
-
};
|
|
642
|
-
const FaireSyncSettingsDrawer = () => {
|
|
643
|
-
const navigate = reactRouterDom.useNavigate();
|
|
644
|
-
const queryClient = reactQuery.useQueryClient();
|
|
645
|
-
const [open, setOpen] = react.useState(true);
|
|
646
|
-
const [form, setForm] = react.useState({});
|
|
647
|
-
const close = () => {
|
|
648
|
-
setOpen(false);
|
|
649
|
-
navigate(PARENT$1);
|
|
650
|
-
};
|
|
651
|
-
const statusQuery = reactQuery.useQuery({
|
|
652
|
-
queryKey: STATUS_KEY,
|
|
653
|
-
queryFn: () => faireApi.status()
|
|
654
|
-
});
|
|
655
|
-
const status = statusQuery.data;
|
|
656
|
-
const connected = !!(status == null ? void 0 : status.connected);
|
|
657
|
-
const taxonomyQuery = reactQuery.useQuery({
|
|
658
|
-
queryKey: TAXONOMY_KEY,
|
|
659
|
-
queryFn: async () => (await faireApi.taxonomy().catch(() => ({ taxonomy: [] }))).taxonomy || []
|
|
660
|
-
});
|
|
661
|
-
const taxonomy = taxonomyQuery.data ?? [];
|
|
662
|
-
react.useEffect(() => {
|
|
663
|
-
if (status == null ? void 0 : status.settings) setForm(status.settings);
|
|
664
|
-
}, [status == null ? void 0 : status.settings]);
|
|
665
|
-
const saveMutation = reactQuery.useMutation({
|
|
666
|
-
mutationFn: (payload) => faireApi.saveSettings(payload),
|
|
667
|
-
onSuccess: () => {
|
|
668
|
-
queryClient.invalidateQueries({ queryKey: STATUS_KEY });
|
|
669
|
-
ui.toast.success("Sync settings saved");
|
|
670
|
-
close();
|
|
671
|
-
},
|
|
672
|
-
onError: (err) => ui.toast.error("Failed to save settings", { description: err.message })
|
|
673
|
-
});
|
|
674
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Drawer, { open, onOpenChange: (o) => o ? setOpen(true) : close(), children: [
|
|
675
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Drawer.Content, { children: [
|
|
676
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Drawer.Header, { children: [
|
|
677
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Title, { children: "Sync settings" }),
|
|
678
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Description, { children: "Publish readiness and the defaults applied to every product pushed to Faire." })
|
|
679
|
-
] }),
|
|
680
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Body, { className: "flex flex-col gap-6 overflow-y-auto", children: statusQuery.isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-3", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-10 w-full" }, i)) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
681
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
682
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
683
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Publish readiness" }),
|
|
684
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", size: "small", children: "Faire needs a brand and a wholesale-pricing strategy to publish products. Missing fields sync products as drafts." })
|
|
685
|
-
] }),
|
|
686
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
687
|
-
/* @__PURE__ */ jsxRuntime.jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.connected, label: "Faire connected" }),
|
|
688
|
-
/* @__PURE__ */ jsxRuntime.jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.brand, label: "Brand configured" }),
|
|
689
|
-
/* @__PURE__ */ jsxRuntime.jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.wholesale_pricing, label: "Wholesale pricing" }),
|
|
690
|
-
/* @__PURE__ */ jsxRuntime.jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.taxonomy, label: "Default category" })
|
|
691
|
-
] })
|
|
692
|
-
] }),
|
|
693
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
694
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
695
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Sync defaults" }),
|
|
696
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", size: "small", children: "Applied to every product unless overridden in product metadata." })
|
|
697
|
-
] }),
|
|
698
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4", children: [
|
|
699
|
-
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Brand ID", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
700
|
-
ui.Input,
|
|
701
|
-
{
|
|
702
|
-
value: String(form.default_brand_id ?? ""),
|
|
703
|
-
onChange: (e) => setForm({ ...form, default_brand_id: e.target.value || null }),
|
|
704
|
-
disabled: !connected,
|
|
705
|
-
placeholder: "b_..."
|
|
706
|
-
}
|
|
707
|
-
) }),
|
|
708
|
-
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Wholesale markup % (off retail)", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: "Wholesale price = retail × (100 − markup%) / 100. E.g. 50 → half of retail.", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
709
|
-
ui.Input,
|
|
710
|
-
{
|
|
711
|
-
type: "number",
|
|
712
|
-
value: String(form.default_wholesale_markup_percent ?? ""),
|
|
713
|
-
onChange: (e) => setForm({
|
|
714
|
-
...form,
|
|
715
|
-
default_wholesale_markup_percent: e.target.value ? Number(e.target.value) : null
|
|
716
|
-
}),
|
|
717
|
-
disabled: !connected,
|
|
718
|
-
placeholder: "e.g. 50"
|
|
719
|
-
}
|
|
720
|
-
) }) }),
|
|
721
|
-
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Default min order quantity", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
722
|
-
ui.Input,
|
|
723
|
-
{
|
|
724
|
-
type: "number",
|
|
725
|
-
value: String(form.default_min_order_quantity ?? 1),
|
|
726
|
-
onChange: (e) => setForm({
|
|
727
|
-
...form,
|
|
728
|
-
default_min_order_quantity: e.target.value ? Number(e.target.value) : 1
|
|
729
|
-
}),
|
|
730
|
-
disabled: !connected
|
|
731
|
-
}
|
|
732
|
-
) }),
|
|
733
|
-
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Default lead time (days)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
734
|
-
ui.Input,
|
|
735
|
-
{
|
|
736
|
-
type: "number",
|
|
737
|
-
value: String(form.default_lead_time_days ?? ""),
|
|
738
|
-
onChange: (e) => setForm({
|
|
739
|
-
...form,
|
|
740
|
-
default_lead_time_days: e.target.value ? Number(e.target.value) : null
|
|
741
|
-
}),
|
|
742
|
-
disabled: !connected,
|
|
743
|
-
placeholder: "e.g. 14"
|
|
744
|
-
}
|
|
745
|
-
) }),
|
|
746
|
-
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Fallback category (taxonomy)", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: "Faire requires a category per product. Resolution order: product metadata → the product's Type (matched by name) → this fallback. Set the product Type or pick a category on the product page for accuracy.", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
747
|
-
SelectField,
|
|
748
|
-
{
|
|
749
|
-
value: String(form.default_category ?? ""),
|
|
750
|
-
onValueChange: (v) => setForm({ ...form, default_category: v || null }),
|
|
751
|
-
disabled: !connected,
|
|
752
|
-
options: taxonomy.map((t) => ({ value: t.id, label: t.name }))
|
|
753
|
-
}
|
|
754
|
-
) }) }),
|
|
755
|
-
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Follow product status", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: "If on, published Medusa products are published on Faire; draft products sync as drafts.", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
756
|
-
ui.Switch,
|
|
757
|
-
{
|
|
758
|
-
checked: form.follow_product_status !== false,
|
|
759
|
-
onCheckedChange: (v) => setForm({ ...form, follow_product_status: v })
|
|
760
|
-
}
|
|
761
|
-
) }) }),
|
|
762
|
-
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Auto publish", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: "Publish products to Faire automatically on sync (otherwise create as draft).", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
763
|
-
ui.Switch,
|
|
764
|
-
{
|
|
765
|
-
checked: !!form.auto_publish,
|
|
766
|
-
onCheckedChange: (v) => setForm({ ...form, auto_publish: v })
|
|
767
|
-
}
|
|
768
|
-
) }) })
|
|
769
|
-
] })
|
|
770
|
-
] })
|
|
771
|
-
] }) }),
|
|
772
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Drawer.Footer, { children: [
|
|
773
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: close, children: "Cancel" }),
|
|
774
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
775
|
-
ui.Button,
|
|
776
|
-
{
|
|
777
|
-
onClick: () => saveMutation.mutate(cleanSettings(form)),
|
|
778
|
-
isLoading: saveMutation.isPending,
|
|
779
|
-
disabled: !connected,
|
|
780
|
-
children: "Save settings"
|
|
781
|
-
}
|
|
782
|
-
)
|
|
783
|
-
] })
|
|
784
|
-
] }),
|
|
785
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Toaster, {})
|
|
786
|
-
] });
|
|
787
|
-
};
|
|
788
|
-
const Field = ({ label, children }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
789
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { children: label }),
|
|
790
|
-
children
|
|
791
|
-
] });
|
|
792
|
-
const SelectField = ({
|
|
793
|
-
value,
|
|
794
|
-
onValueChange,
|
|
795
|
-
options,
|
|
796
|
-
disabled
|
|
797
|
-
}) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
798
|
-
ui.Select,
|
|
799
|
-
{
|
|
800
|
-
value: value ? value : NONE,
|
|
801
|
-
onValueChange: (v) => onValueChange(v === NONE ? "" : v),
|
|
802
|
-
disabled,
|
|
803
|
-
size: "small",
|
|
804
|
-
children: [
|
|
805
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, { placeholder: "Not set" }) }),
|
|
806
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Select.Content, { children: [
|
|
807
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: NONE, children: "Not set" }),
|
|
808
|
-
options.map((o) => /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: o.value, children: o.label }, o.value))
|
|
809
|
-
] })
|
|
810
|
-
]
|
|
811
|
-
}
|
|
812
|
-
);
|
|
813
|
-
const ChecklistItem = ({ ok, label }) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
814
|
-
"div",
|
|
815
|
-
{
|
|
816
|
-
className: ui.clx(
|
|
817
|
-
"flex items-center gap-2 rounded-lg border px-3 py-2",
|
|
818
|
-
ok ? "border-ui-tag-green-border bg-ui-tag-green-bg" : "border-ui-tag-red-border bg-ui-tag-red-bg"
|
|
819
|
-
),
|
|
820
|
-
children: [
|
|
821
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.StatusBadge, { color: ok ? "green" : "red", children: ok ? "Ready" : "Missing" }),
|
|
822
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: label })
|
|
823
|
-
]
|
|
824
|
-
}
|
|
825
|
-
);
|
|
826
|
-
const handle$2 = {
|
|
827
|
-
breadcrumb: () => "Sync settings"
|
|
828
|
-
};
|
|
829
622
|
const Root = ({ prev = "..", children }) => {
|
|
830
623
|
const navigate = reactRouterDom.useNavigate();
|
|
831
624
|
const [open, setOpen] = react.useState(false);
|
|
@@ -1135,9 +928,216 @@ const FaireBulkPage = () => {
|
|
|
1135
928
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Toaster, {})
|
|
1136
929
|
] });
|
|
1137
930
|
};
|
|
1138
|
-
const handle$
|
|
931
|
+
const handle$2 = {
|
|
1139
932
|
breadcrumb: () => "Bulk sync"
|
|
1140
933
|
};
|
|
934
|
+
const STATUS_KEY = ["faire", "status"];
|
|
935
|
+
const TAXONOMY_KEY = ["faire", "taxonomy"];
|
|
936
|
+
const PARENT$1 = "/settings/faire";
|
|
937
|
+
const NONE = "__none__";
|
|
938
|
+
const cleanSettings = (form) => {
|
|
939
|
+
const out = { ...form };
|
|
940
|
+
for (const key of [
|
|
941
|
+
"default_brand_id",
|
|
942
|
+
"default_category"
|
|
943
|
+
]) {
|
|
944
|
+
if (!out[key] || out[key] === NONE) out[key] = null;
|
|
945
|
+
}
|
|
946
|
+
if (out.default_wholesale_markup_percent === "" || out.default_wholesale_markup_percent === NONE) {
|
|
947
|
+
out.default_wholesale_markup_percent = null;
|
|
948
|
+
}
|
|
949
|
+
if (out.default_lead_time_days === "" || out.default_lead_time_days === NONE) {
|
|
950
|
+
out.default_lead_time_days = null;
|
|
951
|
+
}
|
|
952
|
+
return out;
|
|
953
|
+
};
|
|
954
|
+
const FaireSyncSettingsDrawer = () => {
|
|
955
|
+
const navigate = reactRouterDom.useNavigate();
|
|
956
|
+
const queryClient = reactQuery.useQueryClient();
|
|
957
|
+
const [open, setOpen] = react.useState(true);
|
|
958
|
+
const [form, setForm] = react.useState({});
|
|
959
|
+
const close = () => {
|
|
960
|
+
setOpen(false);
|
|
961
|
+
navigate(PARENT$1);
|
|
962
|
+
};
|
|
963
|
+
const statusQuery = reactQuery.useQuery({
|
|
964
|
+
queryKey: STATUS_KEY,
|
|
965
|
+
queryFn: () => faireApi.status()
|
|
966
|
+
});
|
|
967
|
+
const status = statusQuery.data;
|
|
968
|
+
const connected = !!(status == null ? void 0 : status.connected);
|
|
969
|
+
const taxonomyQuery = reactQuery.useQuery({
|
|
970
|
+
queryKey: TAXONOMY_KEY,
|
|
971
|
+
queryFn: async () => (await faireApi.taxonomy().catch(() => ({ taxonomy: [] }))).taxonomy || []
|
|
972
|
+
});
|
|
973
|
+
const taxonomy = taxonomyQuery.data ?? [];
|
|
974
|
+
react.useEffect(() => {
|
|
975
|
+
if (status == null ? void 0 : status.settings) setForm(status.settings);
|
|
976
|
+
}, [status == null ? void 0 : status.settings]);
|
|
977
|
+
const saveMutation = reactQuery.useMutation({
|
|
978
|
+
mutationFn: (payload) => faireApi.saveSettings(payload),
|
|
979
|
+
onSuccess: () => {
|
|
980
|
+
queryClient.invalidateQueries({ queryKey: STATUS_KEY });
|
|
981
|
+
ui.toast.success("Sync settings saved");
|
|
982
|
+
close();
|
|
983
|
+
},
|
|
984
|
+
onError: (err) => ui.toast.error("Failed to save settings", { description: err.message })
|
|
985
|
+
});
|
|
986
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Drawer, { open, onOpenChange: (o) => o ? setOpen(true) : close(), children: [
|
|
987
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Drawer.Content, { children: [
|
|
988
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Drawer.Header, { children: [
|
|
989
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Title, { children: "Sync settings" }),
|
|
990
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Description, { children: "Publish readiness and the defaults applied to every product pushed to Faire." })
|
|
991
|
+
] }),
|
|
992
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Body, { className: "flex flex-col gap-6 overflow-y-auto", children: statusQuery.isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-3", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-10 w-full" }, i)) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
993
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
994
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
995
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Publish readiness" }),
|
|
996
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", size: "small", children: "Faire needs a brand and a wholesale-pricing strategy to publish products. Missing fields sync products as drafts." })
|
|
997
|
+
] }),
|
|
998
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
999
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.connected, label: "Faire connected" }),
|
|
1000
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.brand, label: "Brand configured" }),
|
|
1001
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.wholesale_pricing, label: "Wholesale pricing" }),
|
|
1002
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.taxonomy, label: "Default category" })
|
|
1003
|
+
] })
|
|
1004
|
+
] }),
|
|
1005
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
1006
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1007
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Sync defaults" }),
|
|
1008
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", size: "small", children: "Applied to every product unless overridden in product metadata." })
|
|
1009
|
+
] }),
|
|
1010
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4", children: [
|
|
1011
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Brand ID", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1012
|
+
ui.Input,
|
|
1013
|
+
{
|
|
1014
|
+
value: String(form.default_brand_id ?? ""),
|
|
1015
|
+
onChange: (e) => setForm({ ...form, default_brand_id: e.target.value || null }),
|
|
1016
|
+
disabled: !connected,
|
|
1017
|
+
placeholder: "b_..."
|
|
1018
|
+
}
|
|
1019
|
+
) }),
|
|
1020
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Wholesale markup % (off retail)", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: "Wholesale price = retail × (100 − markup%) / 100. E.g. 50 → half of retail.", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1021
|
+
ui.Input,
|
|
1022
|
+
{
|
|
1023
|
+
type: "number",
|
|
1024
|
+
value: String(form.default_wholesale_markup_percent ?? ""),
|
|
1025
|
+
onChange: (e) => setForm({
|
|
1026
|
+
...form,
|
|
1027
|
+
default_wholesale_markup_percent: e.target.value ? Number(e.target.value) : null
|
|
1028
|
+
}),
|
|
1029
|
+
disabled: !connected,
|
|
1030
|
+
placeholder: "e.g. 50"
|
|
1031
|
+
}
|
|
1032
|
+
) }) }),
|
|
1033
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Default min order quantity", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1034
|
+
ui.Input,
|
|
1035
|
+
{
|
|
1036
|
+
type: "number",
|
|
1037
|
+
value: String(form.default_min_order_quantity ?? 1),
|
|
1038
|
+
onChange: (e) => setForm({
|
|
1039
|
+
...form,
|
|
1040
|
+
default_min_order_quantity: e.target.value ? Number(e.target.value) : 1
|
|
1041
|
+
}),
|
|
1042
|
+
disabled: !connected
|
|
1043
|
+
}
|
|
1044
|
+
) }),
|
|
1045
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Default lead time (days)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1046
|
+
ui.Input,
|
|
1047
|
+
{
|
|
1048
|
+
type: "number",
|
|
1049
|
+
value: String(form.default_lead_time_days ?? ""),
|
|
1050
|
+
onChange: (e) => setForm({
|
|
1051
|
+
...form,
|
|
1052
|
+
default_lead_time_days: e.target.value ? Number(e.target.value) : null
|
|
1053
|
+
}),
|
|
1054
|
+
disabled: !connected,
|
|
1055
|
+
placeholder: "e.g. 14"
|
|
1056
|
+
}
|
|
1057
|
+
) }),
|
|
1058
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Fallback category (taxonomy)", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: "Faire requires a category per product. Resolution order: product metadata → the product's Type (matched by name) → this fallback. Set the product Type or pick a category on the product page for accuracy.", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1059
|
+
SelectField,
|
|
1060
|
+
{
|
|
1061
|
+
value: String(form.default_category ?? ""),
|
|
1062
|
+
onValueChange: (v) => setForm({ ...form, default_category: v || null }),
|
|
1063
|
+
disabled: !connected,
|
|
1064
|
+
options: taxonomy.map((t) => ({ value: t.id, label: t.name }))
|
|
1065
|
+
}
|
|
1066
|
+
) }) }),
|
|
1067
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Follow product status", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: "If on, published Medusa products are published on Faire; draft products sync as drafts.", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1068
|
+
ui.Switch,
|
|
1069
|
+
{
|
|
1070
|
+
checked: form.follow_product_status !== false,
|
|
1071
|
+
onCheckedChange: (v) => setForm({ ...form, follow_product_status: v })
|
|
1072
|
+
}
|
|
1073
|
+
) }) }),
|
|
1074
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Auto publish", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: "Publish products to Faire automatically on sync (otherwise create as draft).", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1075
|
+
ui.Switch,
|
|
1076
|
+
{
|
|
1077
|
+
checked: !!form.auto_publish,
|
|
1078
|
+
onCheckedChange: (v) => setForm({ ...form, auto_publish: v })
|
|
1079
|
+
}
|
|
1080
|
+
) }) })
|
|
1081
|
+
] })
|
|
1082
|
+
] })
|
|
1083
|
+
] }) }),
|
|
1084
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Drawer.Footer, { children: [
|
|
1085
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: close, children: "Cancel" }),
|
|
1086
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1087
|
+
ui.Button,
|
|
1088
|
+
{
|
|
1089
|
+
onClick: () => saveMutation.mutate(cleanSettings(form)),
|
|
1090
|
+
isLoading: saveMutation.isPending,
|
|
1091
|
+
disabled: !connected,
|
|
1092
|
+
children: "Save settings"
|
|
1093
|
+
}
|
|
1094
|
+
)
|
|
1095
|
+
] })
|
|
1096
|
+
] }),
|
|
1097
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Toaster, {})
|
|
1098
|
+
] });
|
|
1099
|
+
};
|
|
1100
|
+
const Field = ({ label, children }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
1101
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { children: label }),
|
|
1102
|
+
children
|
|
1103
|
+
] });
|
|
1104
|
+
const SelectField = ({
|
|
1105
|
+
value,
|
|
1106
|
+
onValueChange,
|
|
1107
|
+
options,
|
|
1108
|
+
disabled
|
|
1109
|
+
}) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1110
|
+
ui.Select,
|
|
1111
|
+
{
|
|
1112
|
+
value: value ? value : NONE,
|
|
1113
|
+
onValueChange: (v) => onValueChange(v === NONE ? "" : v),
|
|
1114
|
+
disabled,
|
|
1115
|
+
size: "small",
|
|
1116
|
+
children: [
|
|
1117
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, { placeholder: "Not set" }) }),
|
|
1118
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Select.Content, { children: [
|
|
1119
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: NONE, children: "Not set" }),
|
|
1120
|
+
options.map((o) => /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: o.value, children: o.label }, o.value))
|
|
1121
|
+
] })
|
|
1122
|
+
]
|
|
1123
|
+
}
|
|
1124
|
+
);
|
|
1125
|
+
const ChecklistItem = ({ ok, label }) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1126
|
+
"div",
|
|
1127
|
+
{
|
|
1128
|
+
className: ui.clx(
|
|
1129
|
+
"flex items-center gap-2 rounded-lg border px-3 py-2",
|
|
1130
|
+
ok ? "border-ui-tag-green-border bg-ui-tag-green-bg" : "border-ui-tag-red-border bg-ui-tag-red-bg"
|
|
1131
|
+
),
|
|
1132
|
+
children: [
|
|
1133
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.StatusBadge, { color: ok ? "green" : "red", children: ok ? "Ready" : "Missing" }),
|
|
1134
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: label })
|
|
1135
|
+
]
|
|
1136
|
+
}
|
|
1137
|
+
);
|
|
1138
|
+
const handle$1 = {
|
|
1139
|
+
breadcrumb: () => "Sync settings"
|
|
1140
|
+
};
|
|
1141
1141
|
const PARENT = "/settings/faire";
|
|
1142
1142
|
const STATUS_COLORS = {
|
|
1143
1143
|
success: "green",
|
|
@@ -1332,13 +1332,13 @@ const routeModule = {
|
|
|
1332
1332
|
handle: handle$3,
|
|
1333
1333
|
children: [
|
|
1334
1334
|
{
|
|
1335
|
-
Component:
|
|
1336
|
-
path: "/settings/faire/
|
|
1335
|
+
Component: FaireBulkPage,
|
|
1336
|
+
path: "/settings/faire/bulk",
|
|
1337
1337
|
handle: handle$2
|
|
1338
1338
|
},
|
|
1339
1339
|
{
|
|
1340
|
-
Component:
|
|
1341
|
-
path: "/settings/faire/
|
|
1340
|
+
Component: FaireSyncSettingsDrawer,
|
|
1341
|
+
path: "/settings/faire/settings",
|
|
1342
1342
|
handle: handle$1
|
|
1343
1343
|
}
|
|
1344
1344
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { defineWidgetConfig, defineRouteConfig } from "@medusajs/admin-sdk";
|
|
3
|
-
import { toast, Container, Heading, Text, StatusBadge, Alert, Badge, Button, Tooltip, Drawer, Input, clx, createDataTableColumnHelper, createDataTableFilterHelper, useDataTable, Skeleton, DropdownMenu, DataTable, Label, Toaster, Switch, Select,
|
|
3
|
+
import { toast, Container, Heading, Text, StatusBadge, Alert, Badge, Button, Tooltip, Drawer, Input, clx, createDataTableColumnHelper, createDataTableFilterHelper, useDataTable, Skeleton, DropdownMenu, DataTable, Label, Toaster, FocusModal, Switch, Select, IconButton } from "@medusajs/ui";
|
|
4
4
|
import { useQueryClient, useQuery, useMutation, keepPreviousData } from "@tanstack/react-query";
|
|
5
5
|
import { useState, useEffect, useMemo } from "react";
|
|
6
6
|
import Medusa from "@medusajs/js-sdk";
|
|
@@ -616,213 +616,6 @@ const config = defineRouteConfig({
|
|
|
616
616
|
const handle$3 = {
|
|
617
617
|
breadcrumb: () => "Faire Sync"
|
|
618
618
|
};
|
|
619
|
-
const STATUS_KEY = ["faire", "status"];
|
|
620
|
-
const TAXONOMY_KEY = ["faire", "taxonomy"];
|
|
621
|
-
const PARENT$1 = "/settings/faire";
|
|
622
|
-
const NONE = "__none__";
|
|
623
|
-
const cleanSettings = (form) => {
|
|
624
|
-
const out = { ...form };
|
|
625
|
-
for (const key of [
|
|
626
|
-
"default_brand_id",
|
|
627
|
-
"default_category"
|
|
628
|
-
]) {
|
|
629
|
-
if (!out[key] || out[key] === NONE) out[key] = null;
|
|
630
|
-
}
|
|
631
|
-
if (out.default_wholesale_markup_percent === "" || out.default_wholesale_markup_percent === NONE) {
|
|
632
|
-
out.default_wholesale_markup_percent = null;
|
|
633
|
-
}
|
|
634
|
-
if (out.default_lead_time_days === "" || out.default_lead_time_days === NONE) {
|
|
635
|
-
out.default_lead_time_days = null;
|
|
636
|
-
}
|
|
637
|
-
return out;
|
|
638
|
-
};
|
|
639
|
-
const FaireSyncSettingsDrawer = () => {
|
|
640
|
-
const navigate = useNavigate();
|
|
641
|
-
const queryClient = useQueryClient();
|
|
642
|
-
const [open, setOpen] = useState(true);
|
|
643
|
-
const [form, setForm] = useState({});
|
|
644
|
-
const close = () => {
|
|
645
|
-
setOpen(false);
|
|
646
|
-
navigate(PARENT$1);
|
|
647
|
-
};
|
|
648
|
-
const statusQuery = useQuery({
|
|
649
|
-
queryKey: STATUS_KEY,
|
|
650
|
-
queryFn: () => faireApi.status()
|
|
651
|
-
});
|
|
652
|
-
const status = statusQuery.data;
|
|
653
|
-
const connected = !!(status == null ? void 0 : status.connected);
|
|
654
|
-
const taxonomyQuery = useQuery({
|
|
655
|
-
queryKey: TAXONOMY_KEY,
|
|
656
|
-
queryFn: async () => (await faireApi.taxonomy().catch(() => ({ taxonomy: [] }))).taxonomy || []
|
|
657
|
-
});
|
|
658
|
-
const taxonomy = taxonomyQuery.data ?? [];
|
|
659
|
-
useEffect(() => {
|
|
660
|
-
if (status == null ? void 0 : status.settings) setForm(status.settings);
|
|
661
|
-
}, [status == null ? void 0 : status.settings]);
|
|
662
|
-
const saveMutation = useMutation({
|
|
663
|
-
mutationFn: (payload) => faireApi.saveSettings(payload),
|
|
664
|
-
onSuccess: () => {
|
|
665
|
-
queryClient.invalidateQueries({ queryKey: STATUS_KEY });
|
|
666
|
-
toast.success("Sync settings saved");
|
|
667
|
-
close();
|
|
668
|
-
},
|
|
669
|
-
onError: (err) => toast.error("Failed to save settings", { description: err.message })
|
|
670
|
-
});
|
|
671
|
-
return /* @__PURE__ */ jsxs(Drawer, { open, onOpenChange: (o) => o ? setOpen(true) : close(), children: [
|
|
672
|
-
/* @__PURE__ */ jsxs(Drawer.Content, { children: [
|
|
673
|
-
/* @__PURE__ */ jsxs(Drawer.Header, { children: [
|
|
674
|
-
/* @__PURE__ */ jsx(Drawer.Title, { children: "Sync settings" }),
|
|
675
|
-
/* @__PURE__ */ jsx(Drawer.Description, { children: "Publish readiness and the defaults applied to every product pushed to Faire." })
|
|
676
|
-
] }),
|
|
677
|
-
/* @__PURE__ */ jsx(Drawer.Body, { className: "flex flex-col gap-6 overflow-y-auto", children: statusQuery.isLoading ? /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-full" }, i)) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
678
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
679
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
680
|
-
/* @__PURE__ */ jsx(Heading, { level: "h2", children: "Publish readiness" }),
|
|
681
|
-
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", size: "small", children: "Faire needs a brand and a wholesale-pricing strategy to publish products. Missing fields sync products as drafts." })
|
|
682
|
-
] }),
|
|
683
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
684
|
-
/* @__PURE__ */ jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.connected, label: "Faire connected" }),
|
|
685
|
-
/* @__PURE__ */ jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.brand, label: "Brand configured" }),
|
|
686
|
-
/* @__PURE__ */ jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.wholesale_pricing, label: "Wholesale pricing" }),
|
|
687
|
-
/* @__PURE__ */ jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.taxonomy, label: "Default category" })
|
|
688
|
-
] })
|
|
689
|
-
] }),
|
|
690
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
691
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
692
|
-
/* @__PURE__ */ jsx(Heading, { level: "h2", children: "Sync defaults" }),
|
|
693
|
-
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", size: "small", children: "Applied to every product unless overridden in product metadata." })
|
|
694
|
-
] }),
|
|
695
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4", children: [
|
|
696
|
-
/* @__PURE__ */ jsx(Field, { label: "Brand ID", children: /* @__PURE__ */ jsx(
|
|
697
|
-
Input,
|
|
698
|
-
{
|
|
699
|
-
value: String(form.default_brand_id ?? ""),
|
|
700
|
-
onChange: (e) => setForm({ ...form, default_brand_id: e.target.value || null }),
|
|
701
|
-
disabled: !connected,
|
|
702
|
-
placeholder: "b_..."
|
|
703
|
-
}
|
|
704
|
-
) }),
|
|
705
|
-
/* @__PURE__ */ jsx(Field, { label: "Wholesale markup % (off retail)", children: /* @__PURE__ */ jsx(Tooltip, { content: "Wholesale price = retail × (100 − markup%) / 100. E.g. 50 → half of retail.", children: /* @__PURE__ */ jsx(
|
|
706
|
-
Input,
|
|
707
|
-
{
|
|
708
|
-
type: "number",
|
|
709
|
-
value: String(form.default_wholesale_markup_percent ?? ""),
|
|
710
|
-
onChange: (e) => setForm({
|
|
711
|
-
...form,
|
|
712
|
-
default_wholesale_markup_percent: e.target.value ? Number(e.target.value) : null
|
|
713
|
-
}),
|
|
714
|
-
disabled: !connected,
|
|
715
|
-
placeholder: "e.g. 50"
|
|
716
|
-
}
|
|
717
|
-
) }) }),
|
|
718
|
-
/* @__PURE__ */ jsx(Field, { label: "Default min order quantity", children: /* @__PURE__ */ jsx(
|
|
719
|
-
Input,
|
|
720
|
-
{
|
|
721
|
-
type: "number",
|
|
722
|
-
value: String(form.default_min_order_quantity ?? 1),
|
|
723
|
-
onChange: (e) => setForm({
|
|
724
|
-
...form,
|
|
725
|
-
default_min_order_quantity: e.target.value ? Number(e.target.value) : 1
|
|
726
|
-
}),
|
|
727
|
-
disabled: !connected
|
|
728
|
-
}
|
|
729
|
-
) }),
|
|
730
|
-
/* @__PURE__ */ jsx(Field, { label: "Default lead time (days)", children: /* @__PURE__ */ jsx(
|
|
731
|
-
Input,
|
|
732
|
-
{
|
|
733
|
-
type: "number",
|
|
734
|
-
value: String(form.default_lead_time_days ?? ""),
|
|
735
|
-
onChange: (e) => setForm({
|
|
736
|
-
...form,
|
|
737
|
-
default_lead_time_days: e.target.value ? Number(e.target.value) : null
|
|
738
|
-
}),
|
|
739
|
-
disabled: !connected,
|
|
740
|
-
placeholder: "e.g. 14"
|
|
741
|
-
}
|
|
742
|
-
) }),
|
|
743
|
-
/* @__PURE__ */ jsx(Field, { label: "Fallback category (taxonomy)", children: /* @__PURE__ */ jsx(Tooltip, { content: "Faire requires a category per product. Resolution order: product metadata → the product's Type (matched by name) → this fallback. Set the product Type or pick a category on the product page for accuracy.", children: /* @__PURE__ */ jsx(
|
|
744
|
-
SelectField,
|
|
745
|
-
{
|
|
746
|
-
value: String(form.default_category ?? ""),
|
|
747
|
-
onValueChange: (v) => setForm({ ...form, default_category: v || null }),
|
|
748
|
-
disabled: !connected,
|
|
749
|
-
options: taxonomy.map((t) => ({ value: t.id, label: t.name }))
|
|
750
|
-
}
|
|
751
|
-
) }) }),
|
|
752
|
-
/* @__PURE__ */ jsx(Field, { label: "Follow product status", children: /* @__PURE__ */ jsx(Tooltip, { content: "If on, published Medusa products are published on Faire; draft products sync as drafts.", children: /* @__PURE__ */ jsx(
|
|
753
|
-
Switch,
|
|
754
|
-
{
|
|
755
|
-
checked: form.follow_product_status !== false,
|
|
756
|
-
onCheckedChange: (v) => setForm({ ...form, follow_product_status: v })
|
|
757
|
-
}
|
|
758
|
-
) }) }),
|
|
759
|
-
/* @__PURE__ */ jsx(Field, { label: "Auto publish", children: /* @__PURE__ */ jsx(Tooltip, { content: "Publish products to Faire automatically on sync (otherwise create as draft).", children: /* @__PURE__ */ jsx(
|
|
760
|
-
Switch,
|
|
761
|
-
{
|
|
762
|
-
checked: !!form.auto_publish,
|
|
763
|
-
onCheckedChange: (v) => setForm({ ...form, auto_publish: v })
|
|
764
|
-
}
|
|
765
|
-
) }) })
|
|
766
|
-
] })
|
|
767
|
-
] })
|
|
768
|
-
] }) }),
|
|
769
|
-
/* @__PURE__ */ jsxs(Drawer.Footer, { children: [
|
|
770
|
-
/* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: close, children: "Cancel" }),
|
|
771
|
-
/* @__PURE__ */ jsx(
|
|
772
|
-
Button,
|
|
773
|
-
{
|
|
774
|
-
onClick: () => saveMutation.mutate(cleanSettings(form)),
|
|
775
|
-
isLoading: saveMutation.isPending,
|
|
776
|
-
disabled: !connected,
|
|
777
|
-
children: "Save settings"
|
|
778
|
-
}
|
|
779
|
-
)
|
|
780
|
-
] })
|
|
781
|
-
] }),
|
|
782
|
-
/* @__PURE__ */ jsx(Toaster, {})
|
|
783
|
-
] });
|
|
784
|
-
};
|
|
785
|
-
const Field = ({ label, children }) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
786
|
-
/* @__PURE__ */ jsx(Label, { children: label }),
|
|
787
|
-
children
|
|
788
|
-
] });
|
|
789
|
-
const SelectField = ({
|
|
790
|
-
value,
|
|
791
|
-
onValueChange,
|
|
792
|
-
options,
|
|
793
|
-
disabled
|
|
794
|
-
}) => /* @__PURE__ */ jsxs(
|
|
795
|
-
Select,
|
|
796
|
-
{
|
|
797
|
-
value: value ? value : NONE,
|
|
798
|
-
onValueChange: (v) => onValueChange(v === NONE ? "" : v),
|
|
799
|
-
disabled,
|
|
800
|
-
size: "small",
|
|
801
|
-
children: [
|
|
802
|
-
/* @__PURE__ */ jsx(Select.Trigger, { children: /* @__PURE__ */ jsx(Select.Value, { placeholder: "Not set" }) }),
|
|
803
|
-
/* @__PURE__ */ jsxs(Select.Content, { children: [
|
|
804
|
-
/* @__PURE__ */ jsx(Select.Item, { value: NONE, children: "Not set" }),
|
|
805
|
-
options.map((o) => /* @__PURE__ */ jsx(Select.Item, { value: o.value, children: o.label }, o.value))
|
|
806
|
-
] })
|
|
807
|
-
]
|
|
808
|
-
}
|
|
809
|
-
);
|
|
810
|
-
const ChecklistItem = ({ ok, label }) => /* @__PURE__ */ jsxs(
|
|
811
|
-
"div",
|
|
812
|
-
{
|
|
813
|
-
className: clx(
|
|
814
|
-
"flex items-center gap-2 rounded-lg border px-3 py-2",
|
|
815
|
-
ok ? "border-ui-tag-green-border bg-ui-tag-green-bg" : "border-ui-tag-red-border bg-ui-tag-red-bg"
|
|
816
|
-
),
|
|
817
|
-
children: [
|
|
818
|
-
/* @__PURE__ */ jsx(StatusBadge, { color: ok ? "green" : "red", children: ok ? "Ready" : "Missing" }),
|
|
819
|
-
/* @__PURE__ */ jsx(Text, { children: label })
|
|
820
|
-
]
|
|
821
|
-
}
|
|
822
|
-
);
|
|
823
|
-
const handle$2 = {
|
|
824
|
-
breadcrumb: () => "Sync settings"
|
|
825
|
-
};
|
|
826
619
|
const Root = ({ prev = "..", children }) => {
|
|
827
620
|
const navigate = useNavigate();
|
|
828
621
|
const [open, setOpen] = useState(false);
|
|
@@ -1132,9 +925,216 @@ const FaireBulkPage = () => {
|
|
|
1132
925
|
/* @__PURE__ */ jsx(Toaster, {})
|
|
1133
926
|
] });
|
|
1134
927
|
};
|
|
1135
|
-
const handle$
|
|
928
|
+
const handle$2 = {
|
|
1136
929
|
breadcrumb: () => "Bulk sync"
|
|
1137
930
|
};
|
|
931
|
+
const STATUS_KEY = ["faire", "status"];
|
|
932
|
+
const TAXONOMY_KEY = ["faire", "taxonomy"];
|
|
933
|
+
const PARENT$1 = "/settings/faire";
|
|
934
|
+
const NONE = "__none__";
|
|
935
|
+
const cleanSettings = (form) => {
|
|
936
|
+
const out = { ...form };
|
|
937
|
+
for (const key of [
|
|
938
|
+
"default_brand_id",
|
|
939
|
+
"default_category"
|
|
940
|
+
]) {
|
|
941
|
+
if (!out[key] || out[key] === NONE) out[key] = null;
|
|
942
|
+
}
|
|
943
|
+
if (out.default_wholesale_markup_percent === "" || out.default_wholesale_markup_percent === NONE) {
|
|
944
|
+
out.default_wholesale_markup_percent = null;
|
|
945
|
+
}
|
|
946
|
+
if (out.default_lead_time_days === "" || out.default_lead_time_days === NONE) {
|
|
947
|
+
out.default_lead_time_days = null;
|
|
948
|
+
}
|
|
949
|
+
return out;
|
|
950
|
+
};
|
|
951
|
+
const FaireSyncSettingsDrawer = () => {
|
|
952
|
+
const navigate = useNavigate();
|
|
953
|
+
const queryClient = useQueryClient();
|
|
954
|
+
const [open, setOpen] = useState(true);
|
|
955
|
+
const [form, setForm] = useState({});
|
|
956
|
+
const close = () => {
|
|
957
|
+
setOpen(false);
|
|
958
|
+
navigate(PARENT$1);
|
|
959
|
+
};
|
|
960
|
+
const statusQuery = useQuery({
|
|
961
|
+
queryKey: STATUS_KEY,
|
|
962
|
+
queryFn: () => faireApi.status()
|
|
963
|
+
});
|
|
964
|
+
const status = statusQuery.data;
|
|
965
|
+
const connected = !!(status == null ? void 0 : status.connected);
|
|
966
|
+
const taxonomyQuery = useQuery({
|
|
967
|
+
queryKey: TAXONOMY_KEY,
|
|
968
|
+
queryFn: async () => (await faireApi.taxonomy().catch(() => ({ taxonomy: [] }))).taxonomy || []
|
|
969
|
+
});
|
|
970
|
+
const taxonomy = taxonomyQuery.data ?? [];
|
|
971
|
+
useEffect(() => {
|
|
972
|
+
if (status == null ? void 0 : status.settings) setForm(status.settings);
|
|
973
|
+
}, [status == null ? void 0 : status.settings]);
|
|
974
|
+
const saveMutation = useMutation({
|
|
975
|
+
mutationFn: (payload) => faireApi.saveSettings(payload),
|
|
976
|
+
onSuccess: () => {
|
|
977
|
+
queryClient.invalidateQueries({ queryKey: STATUS_KEY });
|
|
978
|
+
toast.success("Sync settings saved");
|
|
979
|
+
close();
|
|
980
|
+
},
|
|
981
|
+
onError: (err) => toast.error("Failed to save settings", { description: err.message })
|
|
982
|
+
});
|
|
983
|
+
return /* @__PURE__ */ jsxs(Drawer, { open, onOpenChange: (o) => o ? setOpen(true) : close(), children: [
|
|
984
|
+
/* @__PURE__ */ jsxs(Drawer.Content, { children: [
|
|
985
|
+
/* @__PURE__ */ jsxs(Drawer.Header, { children: [
|
|
986
|
+
/* @__PURE__ */ jsx(Drawer.Title, { children: "Sync settings" }),
|
|
987
|
+
/* @__PURE__ */ jsx(Drawer.Description, { children: "Publish readiness and the defaults applied to every product pushed to Faire." })
|
|
988
|
+
] }),
|
|
989
|
+
/* @__PURE__ */ jsx(Drawer.Body, { className: "flex flex-col gap-6 overflow-y-auto", children: statusQuery.isLoading ? /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-full" }, i)) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
990
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
991
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
992
|
+
/* @__PURE__ */ jsx(Heading, { level: "h2", children: "Publish readiness" }),
|
|
993
|
+
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", size: "small", children: "Faire needs a brand and a wholesale-pricing strategy to publish products. Missing fields sync products as drafts." })
|
|
994
|
+
] }),
|
|
995
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
996
|
+
/* @__PURE__ */ jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.connected, label: "Faire connected" }),
|
|
997
|
+
/* @__PURE__ */ jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.brand, label: "Brand configured" }),
|
|
998
|
+
/* @__PURE__ */ jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.wholesale_pricing, label: "Wholesale pricing" }),
|
|
999
|
+
/* @__PURE__ */ jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.taxonomy, label: "Default category" })
|
|
1000
|
+
] })
|
|
1001
|
+
] }),
|
|
1002
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
1003
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1004
|
+
/* @__PURE__ */ jsx(Heading, { level: "h2", children: "Sync defaults" }),
|
|
1005
|
+
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", size: "small", children: "Applied to every product unless overridden in product metadata." })
|
|
1006
|
+
] }),
|
|
1007
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4", children: [
|
|
1008
|
+
/* @__PURE__ */ jsx(Field, { label: "Brand ID", children: /* @__PURE__ */ jsx(
|
|
1009
|
+
Input,
|
|
1010
|
+
{
|
|
1011
|
+
value: String(form.default_brand_id ?? ""),
|
|
1012
|
+
onChange: (e) => setForm({ ...form, default_brand_id: e.target.value || null }),
|
|
1013
|
+
disabled: !connected,
|
|
1014
|
+
placeholder: "b_..."
|
|
1015
|
+
}
|
|
1016
|
+
) }),
|
|
1017
|
+
/* @__PURE__ */ jsx(Field, { label: "Wholesale markup % (off retail)", children: /* @__PURE__ */ jsx(Tooltip, { content: "Wholesale price = retail × (100 − markup%) / 100. E.g. 50 → half of retail.", children: /* @__PURE__ */ jsx(
|
|
1018
|
+
Input,
|
|
1019
|
+
{
|
|
1020
|
+
type: "number",
|
|
1021
|
+
value: String(form.default_wholesale_markup_percent ?? ""),
|
|
1022
|
+
onChange: (e) => setForm({
|
|
1023
|
+
...form,
|
|
1024
|
+
default_wholesale_markup_percent: e.target.value ? Number(e.target.value) : null
|
|
1025
|
+
}),
|
|
1026
|
+
disabled: !connected,
|
|
1027
|
+
placeholder: "e.g. 50"
|
|
1028
|
+
}
|
|
1029
|
+
) }) }),
|
|
1030
|
+
/* @__PURE__ */ jsx(Field, { label: "Default min order quantity", children: /* @__PURE__ */ jsx(
|
|
1031
|
+
Input,
|
|
1032
|
+
{
|
|
1033
|
+
type: "number",
|
|
1034
|
+
value: String(form.default_min_order_quantity ?? 1),
|
|
1035
|
+
onChange: (e) => setForm({
|
|
1036
|
+
...form,
|
|
1037
|
+
default_min_order_quantity: e.target.value ? Number(e.target.value) : 1
|
|
1038
|
+
}),
|
|
1039
|
+
disabled: !connected
|
|
1040
|
+
}
|
|
1041
|
+
) }),
|
|
1042
|
+
/* @__PURE__ */ jsx(Field, { label: "Default lead time (days)", children: /* @__PURE__ */ jsx(
|
|
1043
|
+
Input,
|
|
1044
|
+
{
|
|
1045
|
+
type: "number",
|
|
1046
|
+
value: String(form.default_lead_time_days ?? ""),
|
|
1047
|
+
onChange: (e) => setForm({
|
|
1048
|
+
...form,
|
|
1049
|
+
default_lead_time_days: e.target.value ? Number(e.target.value) : null
|
|
1050
|
+
}),
|
|
1051
|
+
disabled: !connected,
|
|
1052
|
+
placeholder: "e.g. 14"
|
|
1053
|
+
}
|
|
1054
|
+
) }),
|
|
1055
|
+
/* @__PURE__ */ jsx(Field, { label: "Fallback category (taxonomy)", children: /* @__PURE__ */ jsx(Tooltip, { content: "Faire requires a category per product. Resolution order: product metadata → the product's Type (matched by name) → this fallback. Set the product Type or pick a category on the product page for accuracy.", children: /* @__PURE__ */ jsx(
|
|
1056
|
+
SelectField,
|
|
1057
|
+
{
|
|
1058
|
+
value: String(form.default_category ?? ""),
|
|
1059
|
+
onValueChange: (v) => setForm({ ...form, default_category: v || null }),
|
|
1060
|
+
disabled: !connected,
|
|
1061
|
+
options: taxonomy.map((t) => ({ value: t.id, label: t.name }))
|
|
1062
|
+
}
|
|
1063
|
+
) }) }),
|
|
1064
|
+
/* @__PURE__ */ jsx(Field, { label: "Follow product status", children: /* @__PURE__ */ jsx(Tooltip, { content: "If on, published Medusa products are published on Faire; draft products sync as drafts.", children: /* @__PURE__ */ jsx(
|
|
1065
|
+
Switch,
|
|
1066
|
+
{
|
|
1067
|
+
checked: form.follow_product_status !== false,
|
|
1068
|
+
onCheckedChange: (v) => setForm({ ...form, follow_product_status: v })
|
|
1069
|
+
}
|
|
1070
|
+
) }) }),
|
|
1071
|
+
/* @__PURE__ */ jsx(Field, { label: "Auto publish", children: /* @__PURE__ */ jsx(Tooltip, { content: "Publish products to Faire automatically on sync (otherwise create as draft).", children: /* @__PURE__ */ jsx(
|
|
1072
|
+
Switch,
|
|
1073
|
+
{
|
|
1074
|
+
checked: !!form.auto_publish,
|
|
1075
|
+
onCheckedChange: (v) => setForm({ ...form, auto_publish: v })
|
|
1076
|
+
}
|
|
1077
|
+
) }) })
|
|
1078
|
+
] })
|
|
1079
|
+
] })
|
|
1080
|
+
] }) }),
|
|
1081
|
+
/* @__PURE__ */ jsxs(Drawer.Footer, { children: [
|
|
1082
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: close, children: "Cancel" }),
|
|
1083
|
+
/* @__PURE__ */ jsx(
|
|
1084
|
+
Button,
|
|
1085
|
+
{
|
|
1086
|
+
onClick: () => saveMutation.mutate(cleanSettings(form)),
|
|
1087
|
+
isLoading: saveMutation.isPending,
|
|
1088
|
+
disabled: !connected,
|
|
1089
|
+
children: "Save settings"
|
|
1090
|
+
}
|
|
1091
|
+
)
|
|
1092
|
+
] })
|
|
1093
|
+
] }),
|
|
1094
|
+
/* @__PURE__ */ jsx(Toaster, {})
|
|
1095
|
+
] });
|
|
1096
|
+
};
|
|
1097
|
+
const Field = ({ label, children }) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
1098
|
+
/* @__PURE__ */ jsx(Label, { children: label }),
|
|
1099
|
+
children
|
|
1100
|
+
] });
|
|
1101
|
+
const SelectField = ({
|
|
1102
|
+
value,
|
|
1103
|
+
onValueChange,
|
|
1104
|
+
options,
|
|
1105
|
+
disabled
|
|
1106
|
+
}) => /* @__PURE__ */ jsxs(
|
|
1107
|
+
Select,
|
|
1108
|
+
{
|
|
1109
|
+
value: value ? value : NONE,
|
|
1110
|
+
onValueChange: (v) => onValueChange(v === NONE ? "" : v),
|
|
1111
|
+
disabled,
|
|
1112
|
+
size: "small",
|
|
1113
|
+
children: [
|
|
1114
|
+
/* @__PURE__ */ jsx(Select.Trigger, { children: /* @__PURE__ */ jsx(Select.Value, { placeholder: "Not set" }) }),
|
|
1115
|
+
/* @__PURE__ */ jsxs(Select.Content, { children: [
|
|
1116
|
+
/* @__PURE__ */ jsx(Select.Item, { value: NONE, children: "Not set" }),
|
|
1117
|
+
options.map((o) => /* @__PURE__ */ jsx(Select.Item, { value: o.value, children: o.label }, o.value))
|
|
1118
|
+
] })
|
|
1119
|
+
]
|
|
1120
|
+
}
|
|
1121
|
+
);
|
|
1122
|
+
const ChecklistItem = ({ ok, label }) => /* @__PURE__ */ jsxs(
|
|
1123
|
+
"div",
|
|
1124
|
+
{
|
|
1125
|
+
className: clx(
|
|
1126
|
+
"flex items-center gap-2 rounded-lg border px-3 py-2",
|
|
1127
|
+
ok ? "border-ui-tag-green-border bg-ui-tag-green-bg" : "border-ui-tag-red-border bg-ui-tag-red-bg"
|
|
1128
|
+
),
|
|
1129
|
+
children: [
|
|
1130
|
+
/* @__PURE__ */ jsx(StatusBadge, { color: ok ? "green" : "red", children: ok ? "Ready" : "Missing" }),
|
|
1131
|
+
/* @__PURE__ */ jsx(Text, { children: label })
|
|
1132
|
+
]
|
|
1133
|
+
}
|
|
1134
|
+
);
|
|
1135
|
+
const handle$1 = {
|
|
1136
|
+
breadcrumb: () => "Sync settings"
|
|
1137
|
+
};
|
|
1138
1138
|
const PARENT = "/settings/faire";
|
|
1139
1139
|
const STATUS_COLORS = {
|
|
1140
1140
|
success: "green",
|
|
@@ -1329,13 +1329,13 @@ const routeModule = {
|
|
|
1329
1329
|
handle: handle$3,
|
|
1330
1330
|
children: [
|
|
1331
1331
|
{
|
|
1332
|
-
Component:
|
|
1333
|
-
path: "/settings/faire/
|
|
1332
|
+
Component: FaireBulkPage,
|
|
1333
|
+
path: "/settings/faire/bulk",
|
|
1334
1334
|
handle: handle$2
|
|
1335
1335
|
},
|
|
1336
1336
|
{
|
|
1337
|
-
Component:
|
|
1338
|
-
path: "/settings/faire/
|
|
1337
|
+
Component: FaireSyncSettingsDrawer,
|
|
1338
|
+
path: "/settings/faire/settings",
|
|
1339
1339
|
handle: handle$1
|
|
1340
1340
|
}
|
|
1341
1341
|
]
|
|
@@ -29,6 +29,8 @@ const geoForCurrency = (currency, country) => {
|
|
|
29
29
|
return { country: "GB" };
|
|
30
30
|
case "USD":
|
|
31
31
|
return { country: "US" };
|
|
32
|
+
case "INR":
|
|
33
|
+
return { country: "IN" };
|
|
32
34
|
case "CAD":
|
|
33
35
|
return { country: "CA" };
|
|
34
36
|
case "AUD":
|
|
@@ -153,12 +155,54 @@ const prepareProductStep = (0, workflows_sdk_1.createStep)("faire-prepare-produc
|
|
|
153
155
|
}
|
|
154
156
|
return Number.isFinite(available) ? Math.max(0, available) : 0;
|
|
155
157
|
};
|
|
158
|
+
const wholesaleFrom = (retailMinor) => markupPercent > 0
|
|
159
|
+
? Math.round((retailMinor * (100 - markupPercent)) / 100)
|
|
160
|
+
: retailMinor;
|
|
161
|
+
// Faire prices are geo-scoped and a variant may carry several — one per
|
|
162
|
+
// currency the product is priced in. Emit a price for EVERY currency present
|
|
163
|
+
// (INR → India, USD → US, EUR → the EU group, etc.) so buyers in each region
|
|
164
|
+
// see their own currency, and fall back to the chosen/default currency +
|
|
165
|
+
// geo (EUR by default) when the product has no multi-currency prices.
|
|
166
|
+
const buildPrices = (variantPrices) => {
|
|
167
|
+
const byCurrency = new Map();
|
|
168
|
+
for (const p of variantPrices || []) {
|
|
169
|
+
const c = String(p.currency_code || "").toUpperCase();
|
|
170
|
+
if (!c)
|
|
171
|
+
continue;
|
|
172
|
+
// First price row per currency wins (Medusa may hold several tiers).
|
|
173
|
+
if (!byCurrency.has(c))
|
|
174
|
+
byCurrency.set(c, p);
|
|
175
|
+
}
|
|
176
|
+
const rows = [];
|
|
177
|
+
for (const [c, p] of byCurrency) {
|
|
178
|
+
const retailMinor = toMinor(p.amount);
|
|
179
|
+
if (retailMinor <= 0)
|
|
180
|
+
continue;
|
|
181
|
+
// The explicit metadata override only applies to the brand's primary
|
|
182
|
+
// currency; every other currency is scoped by its natural geo.
|
|
183
|
+
const geo = c === currency ? geoConstraint : geoForCurrency(c, input.country);
|
|
184
|
+
rows.push({
|
|
185
|
+
geo_constraint: geo,
|
|
186
|
+
wholesale_price: { amount_minor: wholesaleFrom(retailMinor), currency: c },
|
|
187
|
+
retail_price: { amount_minor: retailMinor, currency: c },
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
// Guarantee at least the chosen-currency price so a create never ships a
|
|
191
|
+
// variant with no price at all.
|
|
192
|
+
if (!rows.length) {
|
|
193
|
+
const retail = pickPrice(variantPrices || []);
|
|
194
|
+
const retailMinor = retail ? toMinor(retail.amount) : 0;
|
|
195
|
+
if (retailMinor > 0) {
|
|
196
|
+
rows.push({
|
|
197
|
+
geo_constraint: geoConstraint,
|
|
198
|
+
wholesale_price: { amount_minor: wholesaleFrom(retailMinor), currency },
|
|
199
|
+
retail_price: { amount_minor: retailMinor, currency },
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return rows.length ? rows : undefined;
|
|
204
|
+
};
|
|
156
205
|
const buildVariant = (v, idx) => {
|
|
157
|
-
const retail = pickPrice(v.prices || []);
|
|
158
|
-
const retailMinor = retail ? toMinor(retail.amount) : 0;
|
|
159
|
-
const wholesaleMinor = markupPercent > 0
|
|
160
|
-
? Math.round((retailMinor * (100 - markupPercent)) / 100)
|
|
161
|
-
: retailMinor;
|
|
162
206
|
const sku = v.sku || v.id;
|
|
163
207
|
const options = (v.options || [])
|
|
164
208
|
.map((o) => ({
|
|
@@ -172,15 +216,7 @@ const prepareProductStep = (0, workflows_sdk_1.createStep)("faire-prepare-produc
|
|
|
172
216
|
idempotence_token: `${product.id}:${v.id || sku}`,
|
|
173
217
|
options: options.length ? options : undefined,
|
|
174
218
|
available_quantity: variantQuantity(v),
|
|
175
|
-
prices:
|
|
176
|
-
? [
|
|
177
|
-
{
|
|
178
|
-
geo_constraint: geoConstraint,
|
|
179
|
-
wholesale_price: { amount_minor: wholesaleMinor, currency },
|
|
180
|
-
retail_price: { amount_minor: retailMinor, currency },
|
|
181
|
-
},
|
|
182
|
-
]
|
|
183
|
-
: undefined,
|
|
219
|
+
prices: buildPrices(v.prices || []),
|
|
184
220
|
};
|
|
185
221
|
};
|
|
186
222
|
const images = (product.images || [])
|
|
@@ -280,17 +316,26 @@ const syncProductStep = (0, workflows_sdk_1.createStep)("faire-sync-product-step
|
|
|
280
316
|
warnings.push(`Product create/update failed: ${err?.message || err}`);
|
|
281
317
|
throw err;
|
|
282
318
|
}
|
|
283
|
-
// Push inventory levels for
|
|
319
|
+
// Push inventory levels — but ONLY for variants with a real SKU. When a
|
|
320
|
+
// Medusa variant has no SKU we fall back to its id for the create payload
|
|
321
|
+
// (Faire needs *something*), but that synthetic id (`variant_…` / `prod_…`)
|
|
322
|
+
// is NOT a Faire SKU, so `PATCH product-inventory/by-skus` 404s on it. Those
|
|
323
|
+
// variants are already stocked via the create payload's `available_quantity`,
|
|
324
|
+
// so skip them here rather than push an id Faire will reject.
|
|
284
325
|
if (product_input.variants?.length) {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
326
|
+
const levels = product_input.variants
|
|
327
|
+
.filter((v) => v.sku && !/^(prod|variant)_/.test(v.sku))
|
|
328
|
+
.map((v) => ({
|
|
329
|
+
sku: v.sku,
|
|
330
|
+
on_hand_quantity: v.available_quantity ?? 0,
|
|
331
|
+
}));
|
|
332
|
+
if (levels.length) {
|
|
333
|
+
try {
|
|
334
|
+
await client.updateInventory(access_token, levels);
|
|
335
|
+
}
|
|
336
|
+
catch (err) {
|
|
337
|
+
warnings.push(`Inventory push failed: ${err?.message || err}`);
|
|
338
|
+
}
|
|
294
339
|
}
|
|
295
340
|
}
|
|
296
341
|
// Publish decision: follow product status.
|
|
@@ -386,4 +431,4 @@ exports.syncProductToFaireWorkflow = (0, workflows_sdk_1.createWorkflow)(exports
|
|
|
386
431
|
warnings: result.warnings,
|
|
387
432
|
});
|
|
388
433
|
});
|
|
389
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1wcm9kdWN0LXRvLWZhaXJlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9zeW5jLXByb2R1Y3QtdG8tZmFpcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBTzBDO0FBQzFDLHFEQUEyRjtBQUczRixzREFBeUQ7QUFPNUMsUUFBQSxxQkFBcUIsR0FBRyxvQkFBb0IsQ0FBQTtBQThCekQ7OztHQUdHO0FBQ0gsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLE9BQXdCLEVBQWlCLEVBQUU7SUFDcEUsSUFBSSxPQUFPLENBQUMsR0FBRztRQUFFLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQTtJQUNuQyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWE7UUFBRSxPQUFPLElBQUksQ0FBQTtJQUN2QyxPQUFPLHdDQUF3QyxPQUFPLENBQUMsYUFBYSxFQUFFLENBQUE7QUFDeEUsQ0FBQyxDQUFBO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sY0FBYyxHQUFHLENBQ3JCLFFBQWdCLEVBQ2hCLE9BQXNCLEVBQ3dCLEVBQUU7SUFDaEQsUUFBUSxRQUFRLEVBQUUsQ0FBQztRQUNqQixLQUFLLEtBQUs7WUFDUixPQUFPLEVBQUUsYUFBYSxFQUFFLGdCQUFnQixFQUFFLENBQUE7UUFDNUMsS0FBSyxLQUFLO1lBQ1IsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQTtRQUMxQixLQUFLLEtBQUs7WUFDUixPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFBO1FBQzFCLEtBQUssS0FBSztZQUNSLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUE7UUFDMUIsS0FBSyxLQUFLO1lBQ1IsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQTtRQUMxQjtZQUNFLE9BQU8sT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLGFB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
|
|
434
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1wcm9kdWN0LXRvLWZhaXJlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9zeW5jLXByb2R1Y3QtdG8tZmFpcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBTzBDO0FBQzFDLHFEQUEyRjtBQUczRixzREFBeUQ7QUFPNUMsUUFBQSxxQkFBcUIsR0FBRyxvQkFBb0IsQ0FBQTtBQThCekQ7OztHQUdHO0FBQ0gsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLE9BQXdCLEVBQWlCLEVBQUU7SUFDcEUsSUFBSSxPQUFPLENBQUMsR0FBRztRQUFFLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQTtJQUNuQyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWE7UUFBRSxPQUFPLElBQUksQ0FBQTtJQUN2QyxPQUFPLHdDQUF3QyxPQUFPLENBQUMsYUFBYSxFQUFFLENBQUE7QUFDeEUsQ0FBQyxDQUFBO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sY0FBYyxHQUFHLENBQ3JCLFFBQWdCLEVBQ2hCLE9BQXNCLEVBQ3dCLEVBQUU7SUFDaEQsUUFBUSxRQUFRLEVBQUUsQ0FBQztRQUNqQixLQUFLLEtBQUs7WUFDUixPQUFPLEVBQUUsYUFBYSxFQUFFLGdCQUFnQixFQUFFLENBQUE7UUFDNUMsS0FBSyxLQUFLO1lBQ1IsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQTtRQUMxQixLQUFLLEtBQUs7WUFDUixPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFBO1FBQzFCLEtBQUssS0FBSztZQUNSLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUE7UUFDMUIsS0FBSyxLQUFLO1lBQ1IsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQTtRQUMxQixLQUFLLEtBQUs7WUFDUixPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFBO1FBQzFCO1lBQ0UsT0FBTyxP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
|
package/package.json
CHANGED
|
@@ -72,6 +72,8 @@ const geoForCurrency = (
|
|
|
72
72
|
return { country: "GB" }
|
|
73
73
|
case "USD":
|
|
74
74
|
return { country: "US" }
|
|
75
|
+
case "INR":
|
|
76
|
+
return { country: "IN" }
|
|
75
77
|
case "CAD":
|
|
76
78
|
return { country: "CA" }
|
|
77
79
|
case "AUD":
|
|
@@ -234,13 +236,61 @@ const prepareProductStep = createStep(
|
|
|
234
236
|
return Number.isFinite(available) ? Math.max(0, available) : 0
|
|
235
237
|
}
|
|
236
238
|
|
|
239
|
+
const wholesaleFrom = (retailMinor: number): number =>
|
|
240
|
+
markupPercent > 0
|
|
241
|
+
? Math.round((retailMinor * (100 - markupPercent)) / 100)
|
|
242
|
+
: retailMinor
|
|
243
|
+
|
|
244
|
+
// Faire prices are geo-scoped and a variant may carry several — one per
|
|
245
|
+
// currency the product is priced in. Emit a price for EVERY currency present
|
|
246
|
+
// (INR → India, USD → US, EUR → the EU group, etc.) so buyers in each region
|
|
247
|
+
// see their own currency, and fall back to the chosen/default currency +
|
|
248
|
+
// geo (EUR by default) when the product has no multi-currency prices.
|
|
249
|
+
const buildPrices = (variantPrices: any[]) => {
|
|
250
|
+
const byCurrency = new Map<string, any>()
|
|
251
|
+
for (const p of variantPrices || []) {
|
|
252
|
+
const c = String(p.currency_code || "").toUpperCase()
|
|
253
|
+
if (!c) continue
|
|
254
|
+
// First price row per currency wins (Medusa may hold several tiers).
|
|
255
|
+
if (!byCurrency.has(c)) byCurrency.set(c, p)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const rows: {
|
|
259
|
+
geo_constraint: { country?: string; country_group?: string }
|
|
260
|
+
wholesale_price: { amount_minor: number; currency: string }
|
|
261
|
+
retail_price: { amount_minor: number; currency: string }
|
|
262
|
+
}[] = []
|
|
263
|
+
for (const [c, p] of byCurrency) {
|
|
264
|
+
const retailMinor = toMinor(p.amount)
|
|
265
|
+
if (retailMinor <= 0) continue
|
|
266
|
+
// The explicit metadata override only applies to the brand's primary
|
|
267
|
+
// currency; every other currency is scoped by its natural geo.
|
|
268
|
+
const geo =
|
|
269
|
+
c === currency ? geoConstraint : geoForCurrency(c, input.country)
|
|
270
|
+
rows.push({
|
|
271
|
+
geo_constraint: geo,
|
|
272
|
+
wholesale_price: { amount_minor: wholesaleFrom(retailMinor), currency: c },
|
|
273
|
+
retail_price: { amount_minor: retailMinor, currency: c },
|
|
274
|
+
})
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Guarantee at least the chosen-currency price so a create never ships a
|
|
278
|
+
// variant with no price at all.
|
|
279
|
+
if (!rows.length) {
|
|
280
|
+
const retail = pickPrice(variantPrices || [])
|
|
281
|
+
const retailMinor = retail ? toMinor(retail.amount) : 0
|
|
282
|
+
if (retailMinor > 0) {
|
|
283
|
+
rows.push({
|
|
284
|
+
geo_constraint: geoConstraint,
|
|
285
|
+
wholesale_price: { amount_minor: wholesaleFrom(retailMinor), currency },
|
|
286
|
+
retail_price: { amount_minor: retailMinor, currency },
|
|
287
|
+
})
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return rows.length ? rows : undefined
|
|
291
|
+
}
|
|
292
|
+
|
|
237
293
|
const buildVariant = (v: any, idx: number) => {
|
|
238
|
-
const retail = pickPrice(v.prices || [])
|
|
239
|
-
const retailMinor = retail ? toMinor(retail.amount) : 0
|
|
240
|
-
const wholesaleMinor =
|
|
241
|
-
markupPercent > 0
|
|
242
|
-
? Math.round((retailMinor * (100 - markupPercent)) / 100)
|
|
243
|
-
: retailMinor
|
|
244
294
|
const sku = v.sku || v.id
|
|
245
295
|
const options =
|
|
246
296
|
(v.options || [])
|
|
@@ -255,16 +305,7 @@ const prepareProductStep = createStep(
|
|
|
255
305
|
idempotence_token: `${product.id}:${v.id || sku}`,
|
|
256
306
|
options: options.length ? options : undefined,
|
|
257
307
|
available_quantity: variantQuantity(v),
|
|
258
|
-
prices:
|
|
259
|
-
retailMinor > 0
|
|
260
|
-
? [
|
|
261
|
-
{
|
|
262
|
-
geo_constraint: geoConstraint,
|
|
263
|
-
wholesale_price: { amount_minor: wholesaleMinor, currency },
|
|
264
|
-
retail_price: { amount_minor: retailMinor, currency },
|
|
265
|
-
},
|
|
266
|
-
]
|
|
267
|
-
: undefined,
|
|
308
|
+
prices: buildPrices(v.prices || []),
|
|
268
309
|
}
|
|
269
310
|
}
|
|
270
311
|
|
|
@@ -396,16 +437,25 @@ const syncProductStep = createStep(
|
|
|
396
437
|
throw err
|
|
397
438
|
}
|
|
398
439
|
|
|
399
|
-
// Push inventory levels for
|
|
440
|
+
// Push inventory levels — but ONLY for variants with a real SKU. When a
|
|
441
|
+
// Medusa variant has no SKU we fall back to its id for the create payload
|
|
442
|
+
// (Faire needs *something*), but that synthetic id (`variant_…` / `prod_…`)
|
|
443
|
+
// is NOT a Faire SKU, so `PATCH product-inventory/by-skus` 404s on it. Those
|
|
444
|
+
// variants are already stocked via the create payload's `available_quantity`,
|
|
445
|
+
// so skip them here rather than push an id Faire will reject.
|
|
400
446
|
if (product_input.variants?.length) {
|
|
401
|
-
|
|
402
|
-
|
|
447
|
+
const levels = product_input.variants
|
|
448
|
+
.filter((v) => v.sku && !/^(prod|variant)_/.test(v.sku))
|
|
449
|
+
.map((v) => ({
|
|
403
450
|
sku: v.sku,
|
|
404
451
|
on_hand_quantity: v.available_quantity ?? 0,
|
|
405
452
|
}))
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
453
|
+
if (levels.length) {
|
|
454
|
+
try {
|
|
455
|
+
await client.updateInventory(access_token, levels)
|
|
456
|
+
} catch (err: any) {
|
|
457
|
+
warnings.push(`Inventory push failed: ${err?.message || err}`)
|
|
458
|
+
}
|
|
409
459
|
}
|
|
410
460
|
}
|
|
411
461
|
|