chore(fulfillment, utils): Migrate module to DML (#10617)
**What**
- Allow to provide `foreignKeyName` option for hasOne and belongsTo relationships
- `model.hasOne(() => OtherEntity, { foreignKey: true, foreignKeyName: 'other_entity_something_id' })`
- The above will also output a generated type that takes into consideration the custom fk name 🔽
- Update types to account for defined custom foreign key name
- Fix joiner config linkable generation to account for custom linkable keys that provide a public API for their model but are not part of the list of the models included in the MedusaService
- This was supposed to be handled correctly but the implementation was not considering that custom linkable keys could reference models not part of the one provided to medusa service
- Migrate fulfillment module to DML
- Fix has one with fk behaviour and hooks (the relation should be assigned but not the fk)
- Fix has one belongsTo hooks (the relation should be assigned but not the fk)
- Fix hasOneWithFk and belongsTo non persisted fk to be selectable
- Allow to define `belongsTo` without other side definition for `ManyToOne` with no counter part defined
- Meaning that if a user defined `belongsTo` on one side andnot mapped by and no counter part on the other entity it will be considered as a `ManyToOne`
- `orphanRemoval` on `OneToOne` have been removed, this means that when assigning a new object relation to an entity, the previous one gets deconected but not deleted automatically. This prevent removing data un volountarely
**NOTE**
As per our convention here are some information to keep in mind
**HasOne <> BelongsTo**
Define `OneToOne`, The foreign key is owned by the belongs to and the relation needs to be provided to cascade if wanted
**HasMany <> BelongsTo**
Define `OneToMane` <> `ManyToOne`, the foreign key is owned by the many to one and for those relation no cascade will be performed, the foreign key must be provided. For the `HasMany` the cascade is available
**HasOne (with FK)**
Will act similarly to belongs to with **HasOne <> BelongsTo**
Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com>
This commit is contained in:
co-authored by
Carlos R. L. Rodrigues
parent
65007c49f6
commit
100da64242
@@ -8,6 +8,7 @@ import {
|
||||
FulfillmentOption,
|
||||
FulfillmentTypes,
|
||||
IFulfillmentModuleService,
|
||||
InferEntityType,
|
||||
InternalModuleDeclaration,
|
||||
Logger,
|
||||
ModuleJoinerConfig,
|
||||
@@ -19,6 +20,7 @@ import {
|
||||
} from "@medusajs/framework/types"
|
||||
import {
|
||||
arrayDifference,
|
||||
deepCopy,
|
||||
deepEqualObj,
|
||||
EmitEvents,
|
||||
getSetDifference,
|
||||
@@ -49,6 +51,7 @@ import {
|
||||
buildCreatedServiceZoneEvents,
|
||||
eventBuilders,
|
||||
isContextValid,
|
||||
Rule,
|
||||
validateAndNormalizeRules,
|
||||
} from "@utils"
|
||||
import { joinerConfig } from "../joiner-config"
|
||||
@@ -70,6 +73,7 @@ const generateMethodForModels = {
|
||||
|
||||
type InjectedDependencies = {
|
||||
baseRepository: DAL.RepositoryService
|
||||
fulfillmentAddressService: ModulesSdkTypes.IMedusaInternalService<any>
|
||||
fulfillmentSetService: ModulesSdkTypes.IMedusaInternalService<any>
|
||||
serviceZoneService: ModulesSdkTypes.IMedusaInternalService<any>
|
||||
geoZoneService: ModulesSdkTypes.IMedusaInternalService<any>
|
||||
@@ -96,15 +100,31 @@ export default class FulfillmentModuleService
|
||||
implements IFulfillmentModuleService
|
||||
{
|
||||
protected baseRepository_: DAL.RepositoryService
|
||||
protected readonly fulfillmentSetService_: ModulesSdkTypes.IMedusaInternalService<FulfillmentSet>
|
||||
protected readonly serviceZoneService_: ModulesSdkTypes.IMedusaInternalService<ServiceZone>
|
||||
protected readonly geoZoneService_: ModulesSdkTypes.IMedusaInternalService<GeoZone>
|
||||
protected readonly shippingProfileService_: ModulesSdkTypes.IMedusaInternalService<ShippingProfile>
|
||||
protected readonly shippingOptionService_: ModulesSdkTypes.IMedusaInternalService<ShippingOption>
|
||||
protected readonly shippingOptionRuleService_: ModulesSdkTypes.IMedusaInternalService<ShippingOptionRule>
|
||||
protected readonly shippingOptionTypeService_: ModulesSdkTypes.IMedusaInternalService<ShippingOptionType>
|
||||
protected readonly fulfillmentSetService_: ModulesSdkTypes.IMedusaInternalService<
|
||||
InferEntityType<typeof FulfillmentSet>
|
||||
>
|
||||
protected readonly serviceZoneService_: ModulesSdkTypes.IMedusaInternalService<
|
||||
InferEntityType<typeof ServiceZone>
|
||||
>
|
||||
protected readonly geoZoneService_: ModulesSdkTypes.IMedusaInternalService<
|
||||
InferEntityType<typeof GeoZone>
|
||||
>
|
||||
protected readonly shippingProfileService_: ModulesSdkTypes.IMedusaInternalService<
|
||||
InferEntityType<typeof ShippingProfile>
|
||||
>
|
||||
protected readonly shippingOptionService_: ModulesSdkTypes.IMedusaInternalService<
|
||||
InferEntityType<typeof ShippingOption>
|
||||
>
|
||||
protected readonly shippingOptionRuleService_: ModulesSdkTypes.IMedusaInternalService<
|
||||
InferEntityType<typeof ShippingOptionRule>
|
||||
>
|
||||
protected readonly shippingOptionTypeService_: ModulesSdkTypes.IMedusaInternalService<
|
||||
InferEntityType<typeof ShippingOptionType>
|
||||
>
|
||||
protected readonly fulfillmentProviderService_: FulfillmentProviderService
|
||||
protected readonly fulfillmentService_: ModulesSdkTypes.IMedusaInternalService<Fulfillment>
|
||||
protected readonly fulfillmentService_: ModulesSdkTypes.IMedusaInternalService<
|
||||
InferEntityType<typeof Fulfillment>
|
||||
>
|
||||
|
||||
constructor(
|
||||
{
|
||||
@@ -118,6 +138,7 @@ export default class FulfillmentModuleService
|
||||
shippingOptionTypeService,
|
||||
fulfillmentProviderService,
|
||||
fulfillmentService,
|
||||
fulfillmentAddressService,
|
||||
}: InjectedDependencies,
|
||||
protected readonly moduleDeclaration: InternalModuleDeclaration
|
||||
) {
|
||||
@@ -188,7 +209,7 @@ export default class FulfillmentModuleService
|
||||
|
||||
return isContextValid(
|
||||
context,
|
||||
shippingOption.rules.map((r) => r)
|
||||
shippingOption.rules.map((r) => r) as unknown as Rule[]
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -292,7 +313,7 @@ export default class FulfillmentModuleService
|
||||
| FulfillmentTypes.CreateFulfillmentSetDTO
|
||||
| FulfillmentTypes.CreateFulfillmentSetDTO[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<FulfillmentSet[]> {
|
||||
): Promise<InferEntityType<typeof FulfillmentSet>[]> {
|
||||
const data_ = Array.isArray(data) ? data : [data]
|
||||
|
||||
if (!data_.length) {
|
||||
@@ -358,7 +379,7 @@ export default class FulfillmentModuleService
|
||||
| FulfillmentTypes.CreateServiceZoneDTO[]
|
||||
| FulfillmentTypes.CreateServiceZoneDTO,
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<ServiceZone[]> {
|
||||
): Promise<InferEntityType<typeof ServiceZone>[]> {
|
||||
const data_ = Array.isArray(data) ? data : [data]
|
||||
|
||||
if (!data_.length) {
|
||||
@@ -422,7 +443,7 @@ export default class FulfillmentModuleService
|
||||
| FulfillmentTypes.CreateShippingOptionDTO[]
|
||||
| FulfillmentTypes.CreateShippingOptionDTO,
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<ShippingOption[]> {
|
||||
): Promise<InferEntityType<typeof ShippingOption>[]> {
|
||||
const data_ = Array.isArray(data) ? data : [data]
|
||||
|
||||
if (!data_.length) {
|
||||
@@ -491,7 +512,7 @@ export default class FulfillmentModuleService
|
||||
| FulfillmentTypes.CreateShippingProfileDTO[]
|
||||
| FulfillmentTypes.CreateShippingProfileDTO,
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<ShippingProfile[]> {
|
||||
): Promise<InferEntityType<typeof ShippingProfile>[]> {
|
||||
const data_ = Array.isArray(data) ? data : [data]
|
||||
|
||||
if (!data_.length) {
|
||||
@@ -580,7 +601,7 @@ export default class FulfillmentModuleService
|
||||
| FulfillmentTypes.CreateShippingOptionRuleDTO[]
|
||||
| FulfillmentTypes.CreateShippingOptionRuleDTO,
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<ShippingOptionRule[]> {
|
||||
): Promise<InferEntityType<typeof ShippingOptionRule>[]> {
|
||||
const data_ = Array.isArray(data) ? data : [data]
|
||||
|
||||
if (!data_.length) {
|
||||
@@ -625,7 +646,7 @@ export default class FulfillmentModuleService
|
||||
try {
|
||||
const providerResult =
|
||||
await this.fulfillmentProviderService_.createFulfillment(
|
||||
provider_id,
|
||||
provider_id!, // TODO: should we add a runtime check on provider_id being provided?
|
||||
fulfillmentData || {},
|
||||
items.map((i) => i),
|
||||
order,
|
||||
@@ -692,7 +713,7 @@ export default class FulfillmentModuleService
|
||||
try {
|
||||
const providerResult =
|
||||
await this.fulfillmentProviderService_.createReturn(
|
||||
fulfillment.provider_id,
|
||||
fulfillment.provider_id!, // TODO: should we add a runtime check on provider_id being provided?,
|
||||
fulfillment as Record<any, any>
|
||||
)
|
||||
await this.fulfillmentService_.update(
|
||||
@@ -750,7 +771,10 @@ export default class FulfillmentModuleService
|
||||
protected async updateFulfillmentSets_(
|
||||
data: UpdateFulfillmentSetDTO[] | UpdateFulfillmentSetDTO,
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<FulfillmentSet[] | FulfillmentSet> {
|
||||
): Promise<
|
||||
| InferEntityType<typeof FulfillmentSet>[]
|
||||
| InferEntityType<typeof FulfillmentSet>
|
||||
> {
|
||||
const data_ = Array.isArray(data) ? data : [data]
|
||||
|
||||
if (!data_.length) {
|
||||
@@ -789,9 +813,10 @@ export default class FulfillmentModuleService
|
||||
)
|
||||
}
|
||||
|
||||
const fulfillmentSetMap = new Map<string, FulfillmentSet>(
|
||||
fulfillmentSets.map((f) => [f.id, f])
|
||||
)
|
||||
const fulfillmentSetMap = new Map<
|
||||
string,
|
||||
InferEntityType<typeof FulfillmentSet>
|
||||
>(fulfillmentSets.map((f) => [f.id, f]))
|
||||
|
||||
const serviceZoneIdsToDelete: string[] = []
|
||||
const geoZoneIdsToDelete: string[] = []
|
||||
@@ -1013,7 +1038,9 @@ export default class FulfillmentModuleService
|
||||
| FulfillmentTypes.UpdateServiceZoneDTO[]
|
||||
| FulfillmentTypes.UpdateServiceZoneDTO,
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<ServiceZone | ServiceZone[]> {
|
||||
): Promise<
|
||||
InferEntityType<typeof ServiceZone> | InferEntityType<typeof ServiceZone>[]
|
||||
> {
|
||||
const data_ = Array.isArray(data) ? data : [data]
|
||||
|
||||
if (!data_.length) {
|
||||
@@ -1052,7 +1079,7 @@ export default class FulfillmentModuleService
|
||||
)
|
||||
}
|
||||
|
||||
const serviceZoneMap = new Map<string, ServiceZone>(
|
||||
const serviceZoneMap = new Map<string, InferEntityType<typeof ServiceZone>>(
|
||||
serviceZones.map((s) => [s.id, s])
|
||||
)
|
||||
|
||||
@@ -1209,7 +1236,9 @@ export default class FulfillmentModuleService
|
||||
| FulfillmentTypes.UpsertServiceZoneDTO[]
|
||||
| FulfillmentTypes.UpsertServiceZoneDTO,
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<ServiceZone[] | ServiceZone> {
|
||||
): Promise<
|
||||
InferEntityType<typeof ServiceZone>[] | InferEntityType<typeof ServiceZone>
|
||||
> {
|
||||
const input = Array.isArray(data) ? data : [data]
|
||||
const forUpdate = input.filter(
|
||||
(serviceZone): serviceZone is FulfillmentTypes.UpdateServiceZoneDTO =>
|
||||
@@ -1220,8 +1249,8 @@ export default class FulfillmentModuleService
|
||||
!serviceZone.id
|
||||
)
|
||||
|
||||
const created: ServiceZone[] = []
|
||||
const updated: ServiceZone[] = []
|
||||
const created: InferEntityType<typeof ServiceZone>[] = []
|
||||
const updated: InferEntityType<typeof ServiceZone>[] = []
|
||||
|
||||
if (forCreate.length) {
|
||||
const createdServiceZones = await this.createServiceZones_(
|
||||
@@ -1304,8 +1333,13 @@ export default class FulfillmentModuleService
|
||||
async updateShippingOptions_(
|
||||
data: UpdateShippingOptionsInput[] | UpdateShippingOptionsInput,
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<ShippingOption | ShippingOption[]> {
|
||||
const dataArray = Array.isArray(data) ? data : [data]
|
||||
): Promise<
|
||||
| InferEntityType<typeof ShippingOption>
|
||||
| InferEntityType<typeof ShippingOption>[]
|
||||
> {
|
||||
const dataArray = Array.isArray(data)
|
||||
? data.map((d) => deepCopy(d))
|
||||
: [deepCopy(data)]
|
||||
|
||||
if (!dataArray.length) {
|
||||
return []
|
||||
@@ -1365,7 +1399,8 @@ export default class FulfillmentModuleService
|
||||
|
||||
const existingRulesMap: Map<
|
||||
string,
|
||||
FulfillmentTypes.UpdateShippingOptionRuleDTO | ShippingOptionRule
|
||||
| FulfillmentTypes.UpdateShippingOptionRuleDTO
|
||||
| InferEntityType<typeof ShippingOptionRule>
|
||||
> = new Map(existingRules.map((rule) => [rule.id, rule]))
|
||||
|
||||
const updatedRules = shippingOption.rules
|
||||
@@ -1378,6 +1413,13 @@ export default class FulfillmentModuleService
|
||||
updatedRuleIds.push(rule.id)
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
delete rule.created_at
|
||||
// @ts-ignore
|
||||
delete rule.updated_at
|
||||
// @ts-ignore
|
||||
delete rule.deleted_at
|
||||
|
||||
const ruleData: FulfillmentTypes.UpdateShippingOptionRuleDTO = {
|
||||
...existingRule,
|
||||
...rule,
|
||||
@@ -1530,7 +1572,7 @@ export default class FulfillmentModuleService
|
||||
| FulfillmentTypes.UpsertShippingOptionDTO[]
|
||||
| FulfillmentTypes.UpsertShippingOptionDTO,
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<ShippingOption[] | ShippingOption> {
|
||||
): Promise<InferEntityType<typeof ShippingOption>[]> {
|
||||
const input = Array.isArray(data) ? data : [data]
|
||||
const forUpdate = input.filter(
|
||||
(shippingOption): shippingOption is UpdateShippingOptionsInput =>
|
||||
@@ -1543,8 +1585,8 @@ export default class FulfillmentModuleService
|
||||
!shippingOption.id
|
||||
)
|
||||
|
||||
let created: ShippingOption[] = []
|
||||
let updated: ShippingOption[] = []
|
||||
let created: InferEntityType<typeof ShippingOption>[] = []
|
||||
let updated: InferEntityType<typeof ShippingOption>[] = []
|
||||
|
||||
if (forCreate.length) {
|
||||
const createdShippingOptions = await this.createShippingOptions_(
|
||||
@@ -1649,8 +1691,8 @@ export default class FulfillmentModuleService
|
||||
(prof): prof is FulfillmentTypes.CreateShippingProfileDTO => !prof.id
|
||||
)
|
||||
|
||||
let created: ShippingProfile[] = []
|
||||
let updated: ShippingProfile[] = []
|
||||
let created: InferEntityType<typeof ShippingProfile>[] = []
|
||||
let updated: InferEntityType<typeof ShippingProfile>[] = []
|
||||
|
||||
if (forCreate.length) {
|
||||
created = await this.shippingProfileService_.create(
|
||||
@@ -1755,7 +1797,10 @@ export default class FulfillmentModuleService
|
||||
| FulfillmentTypes.UpdateShippingOptionRuleDTO[]
|
||||
| FulfillmentTypes.UpdateShippingOptionRuleDTO,
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<ShippingOptionRule | ShippingOptionRule[]> {
|
||||
): Promise<
|
||||
| InferEntityType<typeof ShippingOptionRule>
|
||||
| InferEntityType<typeof ShippingOptionRule>[]
|
||||
> {
|
||||
const data_ = Array.isArray(data) ? data : [data]
|
||||
|
||||
if (!data_.length) {
|
||||
@@ -1796,8 +1841,8 @@ export default class FulfillmentModuleService
|
||||
id: string,
|
||||
data: FulfillmentTypes.UpdateFulfillmentDTO,
|
||||
@MedusaContext() sharedContext: Context
|
||||
): Promise<Fulfillment> {
|
||||
const existingFulfillment: Fulfillment =
|
||||
): Promise<InferEntityType<typeof Fulfillment>> {
|
||||
const existingFulfillment: InferEntityType<typeof Fulfillment> =
|
||||
await this.fulfillmentService_.retrieve(
|
||||
id,
|
||||
{
|
||||
@@ -1868,7 +1913,7 @@ export default class FulfillmentModuleService
|
||||
}
|
||||
|
||||
private handleFulfillmentUpdateEvents(
|
||||
fulfillment: Fulfillment,
|
||||
fulfillment: InferEntityType<typeof Fulfillment>,
|
||||
existingLabelIds: string[],
|
||||
updatedLabelIds: string[],
|
||||
deletedLabelIds: string[],
|
||||
@@ -1919,7 +1964,7 @@ export default class FulfillmentModuleService
|
||||
if (!fulfillment.canceled_at) {
|
||||
try {
|
||||
await this.fulfillmentProviderService_.cancelFulfillment(
|
||||
fulfillment.provider_id,
|
||||
fulfillment.provider_id!, // TODO: should we add a runtime check on provider_id being provided?,
|
||||
fulfillment.data ?? {}
|
||||
)
|
||||
} catch (error) {
|
||||
@@ -2094,7 +2139,9 @@ export default class FulfillmentModuleService
|
||||
}
|
||||
}
|
||||
|
||||
protected static canCancelFulfillmentOrThrow(fulfillment: Fulfillment) {
|
||||
protected static canCancelFulfillmentOrThrow(
|
||||
fulfillment: InferEntityType<typeof Fulfillment>
|
||||
) {
|
||||
if (fulfillment.shipped_at) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
@@ -2113,7 +2160,7 @@ export default class FulfillmentModuleService
|
||||
}
|
||||
|
||||
protected static validateMissingShippingOptions_(
|
||||
shippingOptions: ShippingOption[],
|
||||
shippingOptions: InferEntityType<typeof ShippingOption>[],
|
||||
shippingOptionsData: UpdateShippingOptionsInput[]
|
||||
) {
|
||||
const missingShippingOptionIds = arrayDifference(
|
||||
@@ -2132,7 +2179,7 @@ export default class FulfillmentModuleService
|
||||
}
|
||||
|
||||
protected static validateMissingShippingOptionRules(
|
||||
shippingOption: ShippingOption,
|
||||
shippingOption: InferEntityType<typeof ShippingOption>,
|
||||
shippingOptionUpdateData: FulfillmentTypes.UpdateShippingOptionDTO
|
||||
) {
|
||||
if (!shippingOptionUpdateData.rules) {
|
||||
|
||||
Reference in New Issue
Block a user