Some checks failed
Build and publish / build (push) Failing after 17s
Source moved verbatim from mp/cms/ on 2026-04-29; mp was the first concrete adapter consuming the libreshop toolkit. Builds and publishes git.librete.ch/libreshop/cms on every main / v* push via the standard .gitea/workflows/build.yml shared across libreshop components.
109 lines
3.1 KiB
TypeScript
109 lines
3.1 KiB
TypeScript
import { factories } from "@strapi/strapi";
|
|
import { ID } from "@strapi/database/dist/types";
|
|
import { StructuredAddress } from "../../../../types";
|
|
|
|
// Define a detailed type for customer creation
|
|
interface CustomerCreateData {
|
|
name: string;
|
|
address: string;
|
|
email?: string;
|
|
}
|
|
|
|
export default factories.createCoreService("api::customer.customer", ({ strapi }) => ({
|
|
/**
|
|
* Extract customer name from address
|
|
* @param address Full address string
|
|
* @returns Object with name and cleaned address
|
|
*/
|
|
extractCustomerDetails(address: string): { name: string; cleanedAddress: string } {
|
|
// If address is empty or null, use default values
|
|
if (!address || address.trim() === "") {
|
|
return {
|
|
name: "Unknown Customer",
|
|
cleanedAddress: address || ""
|
|
};
|
|
}
|
|
|
|
// Split address by newline and take the first line as name
|
|
const addressLines = address.split("\n").map((line) => line.trim());
|
|
const name = addressLines[0] || "Unknown Customer";
|
|
|
|
// Remove the first line to get the cleaned address
|
|
const cleanedAddress = addressLines.slice(1).join("\n").trim();
|
|
|
|
return {
|
|
name,
|
|
cleanedAddress: cleanedAddress || address
|
|
};
|
|
},
|
|
|
|
/**
|
|
* Find or create a customer based on address
|
|
* @param address Full address string
|
|
* @param structuredAddress Optional structured address object
|
|
* @returns Customer ID
|
|
*/
|
|
/**
|
|
* Create or update customer with both legacy and structured address
|
|
*/
|
|
async findOrCreateCustomer(address: string, structuredAddress?: StructuredAddress): Promise<ID> {
|
|
try {
|
|
// Extract name and cleaned address
|
|
const { name, cleanedAddress } = this.extractCustomerDetails(address);
|
|
|
|
// Try to find by structured address first, then fallback to legacy
|
|
let existingCustomers = [];
|
|
|
|
if (structuredAddress) {
|
|
existingCustomers = await strapi.entityService.findMany("api::customer.customer", {
|
|
filters: {
|
|
$or: [
|
|
{
|
|
addressStructured: {
|
|
streetAddress: structuredAddress.streetAddress,
|
|
postalCode: structuredAddress.postalCode,
|
|
addressLevel2: structuredAddress.addressLevel2
|
|
}
|
|
},
|
|
{ address: cleanedAddress }
|
|
]
|
|
}
|
|
});
|
|
} else {
|
|
existingCustomers = await strapi.entityService.findMany("api::customer.customer", {
|
|
filters: { address: cleanedAddress }
|
|
});
|
|
}
|
|
|
|
if (existingCustomers && existingCustomers.length > 0) {
|
|
const customer = existingCustomers[0];
|
|
|
|
// Update with structured data if provided
|
|
if (structuredAddress) {
|
|
await strapi.entityService.update("api::customer.customer", customer.id, {
|
|
data: {
|
|
addressStructured: structuredAddress
|
|
}
|
|
});
|
|
}
|
|
|
|
return customer.id;
|
|
}
|
|
|
|
// Create new customer with both formats
|
|
const newCustomer = await strapi.entityService.create("api::customer.customer", {
|
|
data: {
|
|
name,
|
|
address: cleanedAddress,
|
|
...(structuredAddress && { addressStructured: structuredAddress })
|
|
}
|
|
});
|
|
|
|
return newCustomer.id;
|
|
} catch (error) {
|
|
strapi.log.error("app:e:customer-service: Error managing customer", { error, address });
|
|
throw error;
|
|
}
|
|
}
|
|
}));
|