Hi @ismcagdas,
I have shared the angular project with minimal code to reproduce the issue :)
Added in /angular/src/app/main/order-mapping
@ismcagdas, I commented this code and then realized that it is the same issue with all lazy loaded modules
product-mapping.module.ts
import { NgModule } from '@angular/core';
import { PaginatorModule } from 'primeng/paginator';
import { TableModule } from 'primeng/table';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { NgxDnDModule } from '@node_modules/@swimlane/ngx-dnd';
import { ModalModule } from 'ngx-bootstrap/modal';
import { TooltipModule } from 'ngx-bootstrap/tooltip';
import { NgArrayPipesModule } from '@node_modules/ngx-pipes';
import { UtilsModule } from '@shared/utils/utils.module';
import {
ProductMappingRoutingModule,
routedComponents
} from '@app/main/product-mapping/product-mapping.routing.module';
import { AppCommonModule } from '@app/shared/common/app-common.module';
import { DefaultProductMapperModalComponent } from '@app/main/product-mapping/default-product-mapper/default-product-mapper-modal.component';
@NgModule({
imports: [
FormsModule,
CommonModule,
AppCommonModule,
TableModule,
PaginatorModule,
TooltipModule,
ModalModule,
NgxDnDModule,
UtilsModule,
NgArrayPipesModule,
ProductMappingRoutingModule
],
declarations: [routedComponents, DefaultProductMapperModalComponent],
exports: [],
providers: []
})
export class ProductMappingModule {}
product-mapping.routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ProductMappingComponent } from './product-mapping.component';
const routes: Routes = [{ path: '', component: ProductMappingComponent }];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ProductMappingRoutingModule {}
export const routedComponents = [ProductMappingComponent];
product-mapping.component.ts
import { ChangeDetectorRef, Component, Injector, OnInit, ViewChild } from '@angular/core';
import { AppComponentBase } from 'shared/common/app-component-base';
import { appModuleAnimation } from 'shared/animations/routerTransition';
import {
InstalledLogisticProviderDto,
LogisticProviderCustomersServiceProxy,
PrimePenguinAdminCommonServiceProxy,
PrimePenguinCommonServiceProxy,
ProductMappingDto,
ProductMappingServiceProxy
} from 'shared/service-proxies/service-proxies';
import { LazyLoadEvent, Table, Paginator } from 'primeng';
import { flatMap } from 'lodash';
import { finalize, map } from 'rxjs/operators';
import {
AddUpdateProductMappingsInput,
LogisticProviderCustomerTenantIdNameDto,
MappingConfigurationDto
} from '@shared/service-proxies/service-proxies';
import { AppConsts } from '@shared/AppConsts';
import { MappingConfigurationType } from '@shared/service-proxies/service-proxies';
@Component({
templateUrl: './product-mapping.component.html',
animations: [appModuleAnimation()]
})
export class ProductMappingComponent extends AppComponentBase implements OnInit {
@ViewChild('dataTable', {static: true}) dataTable: Table;
@ViewChild('paginator', {static: true}) paginator: Paginator;
filter = '';
isAdmin;
isEshop;
isLogisticProvider;
mappingConfigurationTypes = AppConsts.mappingConfigurationTypes.filter(c => c.id !== MappingConfigurationType.Default);
defaultPriority = AppConsts.fixedValues.maxShort;
logisticProviderId = '';
customerTenantId = '';
logisticProviders: InstalledLogisticProviderDto[] = [];
customers: LogisticProviderCustomerTenantIdNameDto[] = [];
changedVariantMappings: { productVariantId: number; customerTenantId: number }[] = [];
constructor(
injector: Injector,
private _productMappingService: ProductMappingServiceProxy,
private _commonService: PrimePenguinCommonServiceProxy,
private _adminCommonService: PrimePenguinAdminCommonServiceProxy,
private _lpCustomerService: LogisticProviderCustomersServiceProxy,
private _cd: ChangeDetectorRef
) {
super(injector);
}
ngOnInit() {
this.isEshop = this.permission.isGranted(AppConsts.ppPermissions.salesChannelUser);
this.isLogisticProvider = this.permission.isGranted(AppConsts.ppPermissions.logisticProviderAdmin);
this.isAdmin = this.permission.isGranted(AppConsts.ppPermissions.admin.all);
if (this.isAdmin) {
this._adminCommonService.getAllLogisticProviders().subscribe(result => (this.logisticProviders = result.items));
this._commonService.getLogisticProviderCustomers(undefined).subscribe(result => (this.customers = result));
}
if (this.isLogisticProvider) {
this._lpCustomerService
.getAll(undefined)
.pipe(
map(result =>
result.items.map(
c =>
new LogisticProviderCustomerTenantIdNameDto({
id: c.customerTenantId,
name: c.customerTenantName
})
)
)
)
.subscribe(result => (this.customers = result));
}
}
getLogisticProviderId = () => (+this.logisticProviderId > 0 ? +this.logisticProviderId : undefined);
getCustomerTenantId = () => {
if (this.isAdmin || this.isLogisticProvider) {
return +this.customerTenantId > 0 ? +this.customerTenantId : undefined;
}
if (this.isEshop) {
return abp.session.tenantId;
}
return undefined;
};
isDefaultMappingSelected = mapping => MappingConfigurationType.Default === +mapping;
markVariantAsChanged = (productVariantId: number, customerTenantId: number) => {
const existing = this.changedVariantMappings.filter(
c => c.customerTenantId === customerTenantId && c.productVariantId === productVariantId
);
if (existing.length > 0) {
return;
}
this.changedVariantMappings.push({ productVariantId, customerTenantId });
};
onMappingMove(productVariantId: number, customerTenantId: number) {
this.markVariantAsChanged(productVariantId, customerTenantId);
const movedConfig = (<ProductMappingDto[]>this.primengTableHelper.records).filter(
c => c.productVariantId === productVariantId && c.customerTenantId === customerTenantId
)[0];
movedConfig.mappingConfigurationDtos
.filter(c => c.mappingConfigurationType !== MappingConfigurationType.Default)
.forEach((c, i) => (c.mappingPriority = i + 1));
this._cd.detectChanges();
}
private getVariantById(productVariantId: number, customerTenantId: number): ProductMappingDto {
const variantIndex = (<ProductMappingDto[]>this.primengTableHelper.records).findIndex(
c => c.productVariantId === productVariantId && c.customerTenantId === customerTenantId
);
return this.primengTableHelper.records[variantIndex];
}
removeMapping(productVariantId: number, customerTenantId: number, mapping: MappingConfigurationDto) {
const variant = this.getVariantById(productVariantId, customerTenantId);
variant.mappingConfigurationDtos = variant.mappingConfigurationDtos.filter(c => c !== mapping);
this.onMappingMove(productVariantId, customerTenantId);
}
addMapping(productVariantId: number, customerTenantId: number) {
const variant = this.getVariantById(productVariantId, customerTenantId);
const defaultMapping = variant.mappingConfigurationDtos.filter(
c => c.mappingConfigurationType === MappingConfigurationType.Default
)[0];
const map = this.mappingConfigurationTypes[0];
const newMapping = new MappingConfigurationDto({
...defaultMapping,
mappingConfigurationType: map.id,
mappingConfigurationTypeName: map.name,
mappingPriority: 100,
id: undefined
});
variant.mappingConfigurationDtos = variant.mappingConfigurationDtos.concat(newMapping);
this.onMappingMove(productVariantId, customerTenantId);
}
getProductMappings(event?: LazyLoadEvent) {
if (this.primengTableHelper.shouldResetPaging(event)) {
this.paginator.changePage(0);
return;
}
this.changedVariantMappings = [];
this.primengTableHelper.showLoadingIndicator();
this._productMappingService
.getProductMappings(
this.getCustomerTenantId(),
this.getLogisticProviderId(),
this.filter,
this.primengTableHelper.getSorting(this.dataTable),
this.primengTableHelper.getMaxResultCount(this.paginator, event),
this.primengTableHelper.getSkipCount(this.paginator, event)
)
.pipe(finalize(() => this.primengTableHelper.hideLoadingIndicator()))
.subscribe(result => {
this.primengTableHelper.totalRecordsCount = result.totalCount;
this.primengTableHelper.records = result.items;
this.primengTableHelper.hideLoadingIndicator();
});
}
validateForm() {
const variants: ProductMappingDto[] = this.primengTableHelper.records;
const mappings = flatMap(variants, c => c.mappingConfigurationDtos);
if (mappings.some(c => !c.logisticProviderId)) {
return false;
}
if (mappings.some(c => !c.mappingConfigurationType)) {
return false;
}
return true;
}
addUpdateMappings(updatedMappings: ProductMappingDto[]) {
const changes: AddUpdateProductMappingsInput[] = [];
updatedMappings.forEach(m => {
m.mappingConfigurationDtos.forEach(c =>
changes.push(
new AddUpdateProductMappingsInput({
customerTenantId: m.customerTenantId,
productVariantId: m.productVariantId,
logisticProviderId: c.logisticProviderId,
mappingConfigurationType: <any>c.mappingConfigurationType,
mappingConfigurationValue: c.mappingConfigurationValue,
mappingPriority: c.mappingPriority
})
)
);
});
this._productMappingService.addUpdateProductMappings(changes).subscribe(() => {
this.notify.success(this.l('SavedSuccessfully'));
this.changedVariantMappings = [];
this.getProductMappings();
});
}
saveChanges(isInvalid: boolean) {
if (isInvalid || !this.validateForm()) {
this.message.error(this.l('FillAllDetails'));
return;
}
const variants: ProductMappingDto[] = this.primengTableHelper.records;
const updatedMappings = flatMap(
this.changedVariantMappings.map(m =>
variants.filter(c => c.productVariantId === m.productVariantId && c.customerTenantId === m.customerTenantId)
)
);
this.addUpdateMappings(updatedMappings);
}
}
Thanks :)
Hi @bobingham,
Here is my code for job:
public class ShipmentAddressLocationCoordinatesWorker : PeriodicBackgroundWorkerBase, ISingletonDependency
{
public ShipmentAddressLocationCoordinatesWorker(AbpTimer timer) : base(timer)
{
Timer.Period = 1000 * 60 * 60 * 24 * 7; // 7 Days
}
[UnitOfWork]
protected override void DoWork()
{
// My Code
}
}
and I initialize this with Hangfire as:
// At 1:50 of every 7th day
RecurringJob.AddOrUpdate<ShipmentAddressLocationCoordinatesWorker>(job => job.Start(), "50 1 * * 0", TimeZoneInfo.Utc);
This is also added in ApplicationModule's PostInitialize
function
workManager.Add(IocManager.Resolve<ShipmentAddressLocationCoordinatesWorker>());
Am I doing something wrong here? Having 2 expressions for timer is really confusing. Can it be simplified?
In the example I posted above, can you provide information on when the DoWork
function will be executed in ShipmentAddressLocationCoordinatesWorker
? :)
At 1:50 of every 7th day ?
Hi @maliming,
I'm little confused here. Aren't the background jobs handled by hangfire when abp hangfire package is added?
Thanks for clarification @ismcagdas :)
@demirmusa, @smry,
I compared AspNetZero with abp commercial, and huge number of features are missing from abp commercial and it is in early phase. So best thing for us would be to stick with AspNetZero.
But is there a migration guide on how we can easily upgrade AbpTables to abp commercial? Or some migration utility?
Most importantly, what is the future of AspNetZero now, since new abp commercial is out and most of the framework developers would be more interested in the shiny new thing?