fix: pickup display — detect from source_orders.ship, show correct labels, hide placeholder address
- orderGroupRepository: detect pickup from source_orders.ship='САМОВЫВОЗ' and address='САМОВЫВОЗ' - orderGroupRepository: set effectiveDeliveryType='pickup' when source data indicates pickup even if DB says 'delivery' - orderGroupRepository: clear deliveryAddress when it's just 'САМОВЫВОЗ' placeholder - OrderDetailPanel: dynamic header 'Карточка группы самовывоза' vs 'Карточка группы доставки' - OrderDetailPanel: subtitle now includes orderNumbers for visibility - OrderDetailPanel: label changed from 'Номер счёта' to 'Заказ' with '+N сч.' for sub-bills - GroupDetailPage: neutral 'Группа не найдена' instead of 'Группа доставки не найдена' - Added pickup-specific test case
This commit is contained in:
parent
ec9b28fa6f
commit
9aef4d49c0
|
|
@ -642,7 +642,7 @@ export const OrderDetailPanel = ({
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result?.success) {
|
if (result?.success) {
|
||||||
setFormMessage("Доставка согласована вручную.");
|
setFormMessage(deliveryType === "pickup" ? "Самовывоз согласован вручную." : "Доставка согласована вручную.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -682,36 +682,57 @@ export const OrderDetailPanel = ({
|
||||||
<div className="flex flex-wrap items-start justify-between gap-4">
|
<div className="flex flex-wrap items-start justify-between gap-4">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm uppercase tracking-[0.2em] text-[var(--color-text-muted)]">
|
<p className="text-sm uppercase tracking-[0.2em] text-[var(--color-text-muted)]">
|
||||||
Карточка группы доставки
|
{(order.deliveryType === "pickup" || order.deliveryStatus === "pickup" || order.delivery_status === "pickup") ? "Карточка группы самовывоза" : "Карточка группы доставки"}
|
||||||
</p>
|
</p>
|
||||||
<h2 className="mt-2 text-2xl font-semibold">
|
<h2 className="mt-2 text-2xl font-semibold">
|
||||||
{order.displayTitle || order.customerName || order.groupKey}
|
{order.displayTitle || order.customerName || order.groupKey}
|
||||||
</h2>
|
</h2>
|
||||||
<p className="mt-1 text-sm text-[var(--color-text-muted)]">
|
<p className="mt-1 text-sm text-[var(--color-text-muted)]">
|
||||||
{order.displaySubtitle || [order.customerPhone, order.customerDate].filter(Boolean).join(" · ") || "Не указано"}
|
{(() => {
|
||||||
|
const parts = [];
|
||||||
|
if (order.orderNumbers && order.orderNumbers.length > 0) parts.push(order.orderNumbers.join(", "));
|
||||||
|
const sub = order.displaySubtitle || [order.customerPhone, order.customerDate].filter(Boolean).join(" · ");
|
||||||
|
if (sub) parts.push(sub);
|
||||||
|
return parts.join(" · ") || "Не указано";
|
||||||
|
})()}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Badge tone={getOrderGroupStatusTone(order)}>{getOrderGroupDisplayStatusLabel(order)}</Badge>
|
<Badge tone={getOrderGroupStatusTone(order)}>{getOrderGroupDisplayStatusLabel(order)}</Badge>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{(() => {
|
||||||
|
const isPickup = order.deliveryType === "pickup" || order.deliveryStatus === "pickup" || order.delivery_status === "pickup";
|
||||||
|
const deliveryTypeLabel = isPickup
|
||||||
|
? "Самовывоз"
|
||||||
|
: (order.deliveryStatus === "requires_address" || order.delivery_status === "requires_address")
|
||||||
|
? "Доставка (требуется адрес)"
|
||||||
|
: "Доставка";
|
||||||
|
const dateLabel = isPickup ? "Дата самовывоза" : "Дата доставки";
|
||||||
|
const timeLabel = isPickup ? "Время самовывоза" : "Время доставки";
|
||||||
|
const addressLabel = isPickup ? "Адрес самовывоза" : "Адрес доставки";
|
||||||
|
// For pickup orders, hide the delivery address if it's just a placeholder like "Самовывоз"
|
||||||
|
const effectiveAddress = isPickup
|
||||||
|
? (order.deliveryAddress && order.deliveryAddress !== "Самовывоз" && order.deliveryAddress !== "самовывоз" ? order.deliveryAddress : "")
|
||||||
|
: order.deliveryAddress;
|
||||||
|
return (
|
||||||
<div className="grid gap-3 rounded-[24px] border border-[var(--color-border)] bg-[var(--color-surface-strong)] p-4 md:grid-cols-4">
|
<div className="grid gap-3 rounded-[24px] border border-[var(--color-border)] bg-[var(--color-surface-strong)] p-4 md:grid-cols-4">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-[var(--color-text-muted)]">
|
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-[var(--color-text-muted)]">
|
||||||
Дата доставки
|
{dateLabel}
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-1 text-base font-medium !text-[var(--color-text)]">{formatDeliveryDateDisplay(order.deliveryDate)}</p>
|
<p className="mt-1 text-base font-medium !text-[var(--color-text)]">{formatDeliveryDateDisplay(order.deliveryDate)}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-[var(--color-text-muted)]">
|
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-[var(--color-text-muted)]">
|
||||||
Время доставки
|
{timeLabel}
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-1 text-base font-medium !text-[var(--color-text)]">{renderValue(order.deliveryTime || order.deliveryHalfDay)}</p>
|
<p className="mt-1 text-base font-medium !text-[var(--color-text)]">{renderValue(order.deliveryTime || order.deliveryHalfDay)}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-[var(--color-text-muted)]">
|
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-[var(--color-text-muted)]">
|
||||||
Тип доставки
|
Тип
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-1 text-base font-medium !text-[var(--color-text)]">{order.deliveryType === "pickup" ? "Самовывоз" : order.deliveryStatus === "requires_address" || order.delivery_status === "requires_address" ? "Доставка (требуется адрес)" : "Доставка"}</p>
|
<p className="mt-1 text-base font-medium !text-[var(--color-text)]">{deliveryTypeLabel}</p>
|
||||||
{(order.deliveryStatus === "requires_address" || order.delivery_status === "requires_address") && (
|
{(order.deliveryStatus === "requires_address" || order.delivery_status === "requires_address") && (
|
||||||
<div className="mt-2 flex items-start gap-2 rounded-xl border border-[rgba(239,68,68,0.3)] bg-[rgba(239,68,68,0.08)] p-3">
|
<div className="mt-2 flex items-start gap-2 rounded-xl border border-[rgba(239,68,68,0.3)] bg-[rgba(239,68,68,0.08)] p-3">
|
||||||
<span className="text-lg">📍</span>
|
<span className="text-lg">📍</span>
|
||||||
|
|
@ -726,7 +747,7 @@ export const OrderDetailPanel = ({
|
||||||
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-[var(--color-text-muted)]">
|
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-[var(--color-text-muted)]">
|
||||||
Водитель
|
Водитель
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-1 text-base font-medium !text-[var(--color-text)]">{order.assignedDriverId ? renderValue(order.assignedDriverName) : "Не назначен"}</p>
|
<p className="mt-1 text-base font-medium !text-[var(--color-text)]">{order.assignedDriverId ? renderValue(order.assignedDriverName) : (isPickup ? "Не нужен" : "Не назначен")}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-[var(--color-text-muted)]">
|
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-[var(--color-text-muted)]">
|
||||||
|
|
@ -739,18 +760,38 @@ export const OrderDetailPanel = ({
|
||||||
{renderValue(order.customerPhone)}
|
{renderValue(order.customerPhone)}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div className="">
|
{!isPickup || effectiveAddress ? (
|
||||||
|
<div>
|
||||||
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-[var(--color-text-muted)]">
|
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-[var(--color-text-muted)]">
|
||||||
Адрес доставки
|
{addressLabel}
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-1 text-base font-medium !text-[var(--color-text)]">{renderValue(order.deliveryAddress)}</p>
|
<p className="mt-1 text-base font-medium !text-[var(--color-text)]">{renderValue(effectiveAddress)}</p>
|
||||||
</div>
|
</div>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
|
|
||||||
<div className="grid gap-x-4 gap-y-2 grid-cols-2 md:grid-cols-4">
|
<div className="grid gap-x-4 gap-y-2 grid-cols-2 md:grid-cols-4">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs text-[var(--color-text-muted)]">Номер счёта</p>
|
<p className="text-xs text-[var(--color-text-muted)]">Заказ</p>
|
||||||
<p className="font-medium !text-[var(--color-text)]">{renderValue(order.orderNumberSummary)}</p>
|
<p className="font-medium !text-[var(--color-text)]">{(() => {
|
||||||
|
const mainNumbers = order.orderNumbers || [];
|
||||||
|
const allNumbers = order.allBillNumbers || [];
|
||||||
|
const mainSet = new Set(mainNumbers.map(String));
|
||||||
|
const extraNumbers = allNumbers.filter((n) => !mainSet.has(String(n)));
|
||||||
|
if (mainNumbers.length > 0) {
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
<span className="font-bold">{mainNumbers.join(", ")}</span>
|
||||||
|
{extraNumbers.length > 0 && (
|
||||||
|
<span className="text-[var(--color-text-muted)]"> +{extraNumbers.length} сч.</span>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return renderValue(order.orderNumberSummary);
|
||||||
|
})()}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs text-[var(--color-text-muted)]">Клиент</p>
|
<p className="text-xs text-[var(--color-text-muted)]">Клиент</p>
|
||||||
|
|
@ -777,7 +818,7 @@ export const OrderDetailPanel = ({
|
||||||
<p className="font-medium !text-[var(--color-text)]">{formatDateTime(order.updatedAt)}</p>
|
<p className="font-medium !text-[var(--color-text)]">{formatDateTime(order.updatedAt)}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs text-[var(--color-text-muted)]">Статус доставки</p>
|
<p className="text-xs text-[var(--color-text-muted)]">{(order.deliveryType === "pickup" || order.deliveryStatus === "pickup" || order.delivery_status === "pickup") ? "Статус самовывоза" : "Статус доставки"}</p>
|
||||||
<p className="font-medium !text-[var(--color-text)]">{getOrderGroupDeliveryStatusLabel(order.deliveryStatus || order.delivery_status)}</p>
|
<p className="font-medium !text-[var(--color-text)]">{getOrderGroupDeliveryStatusLabel(order.deliveryStatus || order.delivery_status)}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -786,11 +827,11 @@ export const OrderDetailPanel = ({
|
||||||
{canManageDelivery ? (
|
{canManageDelivery ? (
|
||||||
<Panel className="space-y-4 p-5">
|
<Panel className="space-y-4 p-5">
|
||||||
<div>
|
<div>
|
||||||
<strong>Ручное согласование доставки</strong>
|
<strong>Ручное согласование</strong>
|
||||||
<p className="mt-1 text-sm text-[var(--color-text-muted)]">
|
<p className="mt-1 text-sm text-[var(--color-text-muted)]">
|
||||||
{isDeliveryAgreed
|
{isDeliveryAgreed
|
||||||
? "Дата и половина дня доставки уже зафиксированы."
|
? "Дата и время уже зафиксированы."
|
||||||
: "Если клиент согласовал доставку по телефону, сохраните дату и половину дня здесь."}
|
: "Если клиент согласовал доставку или самовывоз по телефону, сохраните дату и время здесь."}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{/* Delivery type tabs */}
|
{/* Delivery type tabs */}
|
||||||
|
|
@ -831,7 +872,7 @@ export const OrderDetailPanel = ({
|
||||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-[var(--color-accent)]">
|
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-[var(--color-accent)]">
|
||||||
Доставка согласована
|
{(order.deliveryType === "pickup" || order.deliveryStatus === "pickup" || order.delivery_status === "pickup") ? "Самовывоз согласован" : "Доставка согласована"}
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-1 text-lg font-semibold">
|
<p className="mt-1 text-lg font-semibold">
|
||||||
{agreedDeliveryLabel || "Дата и время сохранены"}
|
{agreedDeliveryLabel || "Дата и время сохранены"}
|
||||||
|
|
@ -847,7 +888,7 @@ export const OrderDetailPanel = ({
|
||||||
disabled={isSavingDeliveryChoice}
|
disabled={isSavingDeliveryChoice}
|
||||||
className="text-sm"
|
className="text-sm"
|
||||||
>
|
>
|
||||||
Изменить дату доставки
|
Изменить {(order.deliveryType === "pickup" || order.deliveryStatus === "pickup" || order.delivery_status === "pickup") ? "дату самовывоза" : "дату доставки"}
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1292,7 +1333,39 @@ export const OrderDetailPanel = ({
|
||||||
|
|
||||||
<Panel className="space-y-4 p-5">
|
<Panel className="space-y-4 p-5">
|
||||||
<strong>Счета</strong>
|
<strong>Счета</strong>
|
||||||
{renderList(getAllBillNumbers(order))}
|
{(() => {
|
||||||
|
const mainNumbers = order.orderNumbers || [];
|
||||||
|
const allNumbers = getAllBillNumbers(order);
|
||||||
|
const mainSet = new Set(mainNumbers.map(String));
|
||||||
|
const extraNumbers = allNumbers.filter((n) => !mainSet.has(String(n)));
|
||||||
|
return (
|
||||||
|
<div className="space-y-2">
|
||||||
|
{mainNumbers.length > 0 && (
|
||||||
|
<div>
|
||||||
|
<p className="text-xs text-[var(--color-text-muted)]">Основной счёт</p>
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{mainNumbers.map((num, idx) => (
|
||||||
|
<span key={idx} className="rounded-full bg-[var(--color-accent-soft)] px-3 py-1 text-sm font-semibold text-[var(--color-accent)]">{num}</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{extraNumbers.length > 0 && (
|
||||||
|
<div>
|
||||||
|
<p className="text-xs text-[var(--color-text-muted)]">{mainNumbers.length > 0 ? "Составные заказы" : "Все счета"}</p>
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{extraNumbers.map((num, idx) => (
|
||||||
|
<span key={idx} className="rounded-full bg-[var(--color-surface)] px-3 py-1 text-xs text-[var(--color-text-muted)]">{num}</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{mainNumbers.length === 0 && extraNumbers.length === 0 && (
|
||||||
|
<p className="text-sm text-[var(--color-text-muted)]">Нет данных</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
</Panel>
|
</Panel>
|
||||||
|
|
||||||
<Panel className="space-y-4 p-5">
|
<Panel className="space-y-4 p-5">
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ describe("OrderDetailPanel", () => {
|
||||||
<OrderDetailPanel order={order} />,
|
<OrderDetailPanel order={order} />,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(markup).toContain("Карточка группы доставки");
|
expect(markup).toContain("Карточка группы");
|
||||||
expect(markup).toContain("Мария Волкова");
|
expect(markup).toContain("Мария Волкова");
|
||||||
expect(markup).toContain("Адрес доставки");
|
expect(markup).toContain("Адрес доставки");
|
||||||
expect(markup).toContain("Симферополь, ул. Ленина, 10");
|
expect(markup).toContain("Симферополь, ул. Ленина, 10");
|
||||||
|
|
@ -109,4 +109,22 @@ describe("OrderDetailPanel", () => {
|
||||||
it("skips weekends when selecting the default manual delivery date", () => {
|
it("skips weekends when selecting the default manual delivery date", () => {
|
||||||
expect(getNextSelectableDateKey(new Date("2026-05-15T12:00:00Z"))).toBe("2026-05-18");
|
expect(getNextSelectableDateKey(new Date("2026-05-15T12:00:00Z"))).toBe("2026-05-18");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("shows pickup labels for pickup orders", () => {
|
||||||
|
const markup = renderToStaticMarkup(
|
||||||
|
<OrderDetailPanel
|
||||||
|
order={{
|
||||||
|
...order,
|
||||||
|
deliveryType: "pickup",
|
||||||
|
deliveryStatus: "pickup",
|
||||||
|
deliveryAddress: "",
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
expect(markup).toContain("Карточка группы самовывоза");
|
||||||
|
expect(markup).toContain("Самовывоз");
|
||||||
|
expect(markup).toContain("Дата самовывоза");
|
||||||
|
expect(markup).toContain("Статус самовывоза");
|
||||||
|
expect(markup).not.toContain("Адрес доставки");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ export const GroupDetailPage = () => {
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Panel className="p-6 text-sm text-[var(--color-text-muted)]">
|
<Panel className="p-6 text-sm text-[var(--color-text-muted)]">
|
||||||
Группа доставки не найдена.
|
Группа не найдена.
|
||||||
</Panel>
|
</Panel>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,24 @@ export const mapOrderGroupRowToDeliveryGroup = (row) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const deliveryAddress = normalizeText(row.delivery_address) || extractAddressFromSourceOrders(row.source_orders);
|
const deliveryAddress = normalizeText(row.delivery_address) || extractAddressFromSourceOrders(row.source_orders);
|
||||||
|
|
||||||
|
// Detect pickup from source_orders ship field (1C sends "САМОВЫВОЗ")
|
||||||
|
const isPickupFromSource = Array.isArray(row.source_orders) && row.source_orders.length > 0
|
||||||
|
&& normalizeText(row.source_orders[0].ship || "").toUpperCase() === "САМОВЫВОЗ";
|
||||||
|
// Also treat address equal to "САМОВЫВОЗ" as pickup indicator
|
||||||
|
const isPickupAddress = deliveryAddress.toUpperCase() === "САМОВЫВОЗ";
|
||||||
|
|
||||||
|
// Resolve effective delivery type: DB field takes precedence, but if it says "delivery"
|
||||||
|
// while source data clearly indicates pickup, treat as pickup
|
||||||
|
const effectiveDeliveryType = (row.delivery_type === "pickup" || deliveryStatus === "pickup" || isPickupFromSource || isPickupAddress)
|
||||||
|
? "pickup"
|
||||||
|
: (row.delivery_type || "delivery");
|
||||||
|
|
||||||
|
// Clear placeholder pickup address
|
||||||
|
const resolvedDeliveryAddress = (effectiveDeliveryType === "pickup" && (deliveryAddress.toUpperCase() === "САМОВЫВОЗ" || !deliveryAddress))
|
||||||
|
? ""
|
||||||
|
: deliveryAddress;
|
||||||
|
|
||||||
const customerAddress = normalizeText(row.customer_address) || "";
|
const customerAddress = normalizeText(row.customer_address) || "";
|
||||||
|
|
||||||
const extractCity = (addr) => {
|
const extractCity = (addr) => {
|
||||||
|
|
@ -151,7 +169,7 @@ export const mapOrderGroupRowToDeliveryGroup = (row) => {
|
||||||
customerPhone,
|
customerPhone,
|
||||||
customerPhoneNormalized: parsedKey.phone || normalizePhone(customerPhone),
|
customerPhoneNormalized: parsedKey.phone || normalizePhone(customerPhone),
|
||||||
customerDate,
|
customerDate,
|
||||||
deliveryAddress,
|
deliveryAddress: resolvedDeliveryAddress,
|
||||||
customerAddress,
|
customerAddress,
|
||||||
city,
|
city,
|
||||||
assignedDriverId: row.assigned_driver_id || null,
|
assignedDriverId: row.assigned_driver_id || null,
|
||||||
|
|
@ -189,7 +207,7 @@ export const mapOrderGroupRowToDeliveryGroup = (row) => {
|
||||||
deliveryDate,
|
deliveryDate,
|
||||||
deliveryTime,
|
deliveryTime,
|
||||||
deliveryDateSource: row.delivery_date_source || null,
|
deliveryDateSource: row.delivery_date_source || null,
|
||||||
deliveryType: row.delivery_type || "delivery",
|
deliveryType: effectiveDeliveryType,
|
||||||
pickupDate: row.pickup_date || null,
|
pickupDate: row.pickup_date || null,
|
||||||
pickupTimeSlot: row.pickup_time_slot || null,
|
pickupTimeSlot: row.pickup_time_slot || null,
|
||||||
driverShipmentData: row.driver_shipment_data || null,
|
driverShipmentData: row.driver_shipment_data || null,
|
||||||
|
|
@ -205,7 +223,7 @@ export const mapOrderGroupRowToDeliveryGroup = (row) => {
|
||||||
customerName,
|
customerName,
|
||||||
customerPhone,
|
customerPhone,
|
||||||
customerDate,
|
customerDate,
|
||||||
deliveryAddress,
|
resolvedDeliveryAddress,
|
||||||
customerAddress,
|
customerAddress,
|
||||||
city,
|
city,
|
||||||
rawDeliveryHalfDay,
|
rawDeliveryHalfDay,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue