Skip to content

Commit

Permalink
Drop address (#416)
Browse files Browse the repository at this point in the history
  • Loading branch information
florimondmanca authored Nov 13, 2023
1 parent 16eb791 commit 13846aa
Show file tree
Hide file tree
Showing 35 changed files with 60 additions and 494 deletions.
17 changes: 1 addition & 16 deletions client/legacy/src/routes/crm/customers/_Form.svelte
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
<script>
import { _ } from 'svelte-i18n';
import { createEventDispatcher } from 'svelte';
import { codes } from 'iso-country-codes';
import Input from 'components/inputs/Input.svelte';
import SelectInput from 'components/inputs/SelectInput.svelte';
import Button from 'components/inputs/Button.svelte';
export let customer;
export let loading;
const address = customer.address;
const dispatch = createEventDispatcher();
const submit = () => {
Expand All @@ -21,20 +18,8 @@
on:submit|preventDefault={submit}
class="px-4 py-3 mb-8 bg-white rounded-lg shadow-md dark:bg-gray-800">
<Input label={$_('crm.customers.form.customer')} bind:value={customer.name} />
<Input label={$_('crm.customers.form.address')} bind:value={address.street} />
<Input
label={$_('crm.customers.form.zip_code')}
bind:value={address.zipCode} pattern={'\\d{5}'} />
<Input label={$_('crm.customers.form.city')} bind:value={address.city} />
<SelectInput
label={$_('crm.customers.form.country')}
bind:value={address.country}>
{#each codes as code}
<option value={code.alpha2}>{code.name}</option>
{/each}
</SelectInput>
<Button
value={$_('common.form.save')}
{loading}
disabled={!customer.name || !address.country || !address.zipCode || !address.city || !address.street || loading} />
disabled={!customer.name || loading} />
</form>
12 changes: 1 addition & 11 deletions client/legacy/src/routes/crm/customers/_Table.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import { _ } from 'svelte-i18n';
//import SeeLink from 'components/links/SeeLink.svelte';
import EditLink from 'components/links/EditLink.svelte';
import { byAlpha2 } from 'iso-country-codes';
export let items;
</script>
Expand All @@ -12,22 +11,13 @@
<tr
class="text-xs font-semibold tracking-wide text-left text-gray-500 uppercase border-b dark:border-gray-700 bg-gray-50 dark:text-gray-400 dark:bg-gray-800">
<th class="px-4 py-3">{$_('crm.customers.name')}</th>
<th class="px-4 py-3">{$_('crm.customers.addresse')}</th>
<th class="px-4 py-3">{$_('common.actions')}</th>
</tr>
</thead>
<tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800">
{#each items as { id, name, address } (id)}
{#each items as { id, name } (id)}
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3 text-sm">{name}</td>
<td class="px-4 py-3 text-sm">
{address.street}
<br />
{address.zipCode}
{address.city}
<br />
{byAlpha2[address.country].name}
</td>
<td class="px-4 py-3">
<div class="flex items-center space-x-4 text-sm">
<!--<SeeLink href={`/crm/customers/${id}`} />-->
Expand Down
21 changes: 21 additions & 0 deletions server/migrations/1699290758562-dropAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { MigrationInterface, QueryRunner } from "typeorm";

export class DropAddress1699290758562 implements MigrationInterface {
name = 'DropAddress1699290758562'

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "customer" DROP CONSTRAINT "FK_7697a356e1f4b79ab3819839e95"`);
await queryRunner.query(`ALTER TABLE "cooperative" DROP CONSTRAINT "FK_76076f95b4afaa794ca4a974661"`);
await queryRunner.query(`ALTER TABLE "customer" DROP COLUMN "addressId"`);
await queryRunner.query(`ALTER TABLE "cooperative" DROP COLUMN "addressId"`);
await queryRunner.query(`DROP TABLE "address"`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`CREATE TABLE "address" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "street" character varying NOT NULL, "city" character varying NOT NULL, "zipCode" character varying(6) NOT NULL, "country" character varying(2) NOT NULL, CONSTRAINT "PK_d92de1f82754668b5f5f5dd4fd5" PRIMARY KEY ("id"))`);
await queryRunner.query(`ALTER TABLE "cooperative" ADD "addressId" uuid NOT NULL`);
await queryRunner.query(`ALTER TABLE "customer" ADD "addressId" uuid`);
await queryRunner.query(`ALTER TABLE "cooperative" ADD CONSTRAINT "FK_76076f95b4afaa794ca4a974661" FOREIGN KEY ("addressId") REFERENCES "address"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "customer" ADD CONSTRAINT "FK_7697a356e1f4b79ab3819839e95" FOREIGN KEY ("addressId") REFERENCES "address"("id") ON DELETE SET NULL ON UPDATE NO ACTION`);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import { ICommand } from 'src/Application/ICommand';

export class CreateCustomerCommand implements ICommand {
constructor(
public readonly name: string,
public readonly street: string,
public readonly city: string,
public readonly zipCode: string,
public readonly country: string
) {}
constructor(public readonly name: string) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,22 @@ import { Customer } from 'src/Domain/Customer/Customer.entity';
import { CreateCustomerCommandHandler } from 'src/Application/Customer/Command/CreateCustomerCommandHandler';
import { CreateCustomerCommand } from 'src/Application/Customer/Command/CreateCustomerCommand';
import { CustomerAlreadyExistException } from 'src/Domain/Customer/Exception/CustomerAlreadyExistException';
import { AddressRepository } from 'src/Infrastructure/Customer/Repository/AddressRepository';
import { Address } from 'src/Domain/Customer/Address.entity';

describe('CreateCustomerCommandHandler', () => {
let customerRepository: CustomerRepository;
let addressRepository: AddressRepository;
let isCustomerAlreadyExist: IsCustomerAlreadyExist;
let createdCustomer: Customer;
let createdAddress: Address;
let handler: CreateCustomerCommandHandler;

const command = new CreateCustomerCommand(
'Customer',
'2 rue Dieu',
'Paris',
'75010',
'FR'
);
const command = new CreateCustomerCommand('Customer');

beforeEach(() => {
customerRepository = mock(CustomerRepository);
addressRepository = mock(AddressRepository);
isCustomerAlreadyExist = mock(IsCustomerAlreadyExist);
createdCustomer = mock(Customer);
createdAddress = mock(Address);

handler = new CreateCustomerCommandHandler(
instance(customerRepository),
instance(addressRepository),
instance(isCustomerAlreadyExist)
);
});
Expand All @@ -45,26 +32,15 @@ describe('CreateCustomerCommandHandler', () => {
);
when(createdCustomer.getName()).thenReturn('Customer');
when(
addressRepository.save(
deepEqual(new Address('2 rue Dieu', 'Paris', '75010', 'FR'))
)
).thenResolve(instance(createdAddress));
when(
customerRepository.save(
deepEqual(new Customer('Customer', instance(createdAddress)))
)
customerRepository.save(deepEqual(new Customer('Customer')))
).thenResolve(instance(createdCustomer));

expect(await handler.execute(command)).toBe(
'2d5fb4da-12c2-11ea-8d71-362b9e155667'
);

verify(isCustomerAlreadyExist.isSatisfiedBy('Customer')).once();
verify(
customerRepository.save(
deepEqual(new Customer('Customer', instance(createdAddress)))
)
).once();
verify(customerRepository.save(deepEqual(new Customer('Customer')))).once();
verify(createdCustomer.getId()).once();
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,23 @@ import { CreateCustomerCommand } from './CreateCustomerCommand';
import { ICustomerRepository } from 'src/Domain/Customer/Repository/ICustomerRepository';
import { CustomerAlreadyExistException } from 'src/Domain/Customer/Exception/CustomerAlreadyExistException';
import { IsCustomerAlreadyExist } from 'src/Domain/Customer/Specification/IsCustomerAlreadyExist';
import { IAddressRepository } from 'src/Domain/Customer/Repository/IAddressRepository';
import { Address } from 'src/Domain/Customer/Address.entity';

@CommandHandler(CreateCustomerCommand)
export class CreateCustomerCommandHandler {
constructor(
@Inject('ICustomerRepository')
private readonly customerRepository: ICustomerRepository,
@Inject('IAddressRepository')
private readonly addressRepository: IAddressRepository,
private readonly isCustomerAlreadyExist: IsCustomerAlreadyExist
) {}

public async execute(command: CreateCustomerCommand): Promise<string> {
const { name, street, city, country, zipCode } = command;
const { name } = command;

if (true === (await this.isCustomerAlreadyExist.isSatisfiedBy(name))) {
throw new CustomerAlreadyExistException();
}

const address = await this.addressRepository.save(
new Address(street, city, zipCode, country)
);

const customer = await this.customerRepository.save(
new Customer(name, address)
);
const customer = await this.customerRepository.save(new Customer(name));

return customer.getId();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
import { ICommand } from 'src/Application/ICommand';

export class UpdateCustomerCommand implements ICommand {
constructor(
public readonly id: string,
public readonly name: string,
public readonly street: string,
public readonly city: string,
public readonly zipCode: string,
public readonly country: string
) {}
constructor(public readonly id: string, public readonly name: string) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,25 @@ import { UpdateCustomerCommand } from './UpdateCustomerCommand';
import { CustomerNotFoundException } from 'src/Domain/Customer/Exception/CustomerNotFoundException';
import { CustomerAlreadyExistException } from 'src/Domain/Customer/Exception/CustomerAlreadyExistException';
import { UpdateCustomerCommandHandler } from './UpdateCustomerCommandHandler';
import { AddressRepository } from 'src/Infrastructure/Customer/Repository/AddressRepository';
import { Address } from 'src/Domain/Customer/Address.entity';

describe('UpdateCustomerCommandHandler', () => {
let customerRepository: CustomerRepository;
let addressRepository: AddressRepository;
let isCustomerAlreadyExist: IsCustomerAlreadyExist;
let updatedCustomer: Customer;
let updatedAddress: Address;
let handler: UpdateCustomerCommandHandler;

const command = new UpdateCustomerCommand(
'afda00b1-bf49-4102-9bc2-bce17f3acd48',
'Customer',
'2 rue Dieu',
'Paris',
'75010',
'FR'
'Customer'
);

beforeEach(() => {
customerRepository = mock(CustomerRepository);
addressRepository = mock(AddressRepository);
isCustomerAlreadyExist = mock(IsCustomerAlreadyExist);
updatedCustomer = mock(Customer);
updatedAddress = mock(Address);

handler = new UpdateCustomerCommandHandler(
instance(customerRepository),
instance(addressRepository),
instance(isCustomerAlreadyExist)
);
});
Expand All @@ -45,7 +34,6 @@ describe('UpdateCustomerCommandHandler', () => {
customerRepository.findOneById('afda00b1-bf49-4102-9bc2-bce17f3acd48')
).thenResolve(instance(updatedCustomer));

when(updatedCustomer.getAddress()).thenReturn(instance(updatedAddress));
when(updatedCustomer.getName()).thenReturn('Old customer');
when(isCustomerAlreadyExist.isSatisfiedBy('Customer')).thenResolve(false);

Expand All @@ -54,13 +42,7 @@ describe('UpdateCustomerCommandHandler', () => {

verify(isCustomerAlreadyExist.isSatisfiedBy('Customer')).once();
verify(customerRepository.save(instance(updatedCustomer))).once();
verify(addressRepository.save(instance(updatedAddress))).once();
verify(updatedCustomer.getAddress()).once();
verify(updatedAddress.update('2 rue Dieu', 'Paris', '75010', 'FR')).once();
verify(updatedCustomer.updateName('Customer')).once();
verify(
updatedAddress.update('2 rue Dieu', 'Paris', '75010', 'FR')
).calledBefore(addressRepository.save(instance(updatedAddress)));
verify(updatedCustomer.updateName('Customer')).calledBefore(
customerRepository.save(instance(updatedCustomer))
);
Expand All @@ -78,10 +60,6 @@ describe('UpdateCustomerCommandHandler', () => {
expect(e).toBeInstanceOf(CustomerNotFoundException);
expect(e.message).toBe('crm.customers.errors.not_found');
verify(isCustomerAlreadyExist.isSatisfiedBy(anything())).never();
verify(addressRepository.save(anything())).never();
verify(
updatedAddress.update(anything(), anything(), anything(), anything())
).never();
verify(customerRepository.save(anything())).never();
verify(updatedCustomer.updateName(anything())).never();
verify(updatedCustomer.getName()).never();
Expand All @@ -102,10 +80,6 @@ describe('UpdateCustomerCommandHandler', () => {
verify(isCustomerAlreadyExist.isSatisfiedBy('Customer')).once();
verify(customerRepository.save(anything())).never();
verify(updatedCustomer.updateName(anything())).never();
verify(addressRepository.save(anything())).never();
verify(
updatedAddress.update(anything(), anything(), anything(), anything())
).never();
verify(updatedCustomer.getName()).once();
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,17 @@ import { ICustomerRepository } from 'src/Domain/Customer/Repository/ICustomerRep
import { CustomerNotFoundException } from 'src/Domain/Customer/Exception/CustomerNotFoundException';
import { IsCustomerAlreadyExist } from 'src/Domain/Customer/Specification/IsCustomerAlreadyExist';
import { CustomerAlreadyExistException } from 'src/Domain/Customer/Exception/CustomerAlreadyExistException';
import { IAddressRepository } from 'src/Domain/Customer/Repository/IAddressRepository';

@CommandHandler(UpdateCustomerCommand)
export class UpdateCustomerCommandHandler {
constructor(
@Inject('ICustomerRepository')
private readonly customerRepository: ICustomerRepository,
@Inject('IAddressRepository')
private readonly addressRepository: IAddressRepository,
private readonly isCustomerAlreadyExist: IsCustomerAlreadyExist
) {}

public async execute(command: UpdateCustomerCommand): Promise<void> {
const { id, name, city, street, country, zipCode } = command;
const { id, name } = command;

const customer = await this.customerRepository.findOneById(id);
if (!customer) {
Expand All @@ -32,13 +29,8 @@ export class UpdateCustomerCommandHandler {
throw new CustomerAlreadyExistException();
}

const address = customer.getAddress();
customer.updateName(name);
address.update(street, city, zipCode, country);

await Promise.all([
this.customerRepository.save(customer),
this.addressRepository.save(address)
]);
await this.customerRepository.save(customer);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import { CustomerView } from 'src/Application/Customer/View/CustomerView';
import { GetCustomerByIdQueryHandler } from './GetCustomerByIdQueryHandler';
import { GetCustomerByIdQuery } from './GetCustomerByIdQuery';
import { CustomerNotFoundException } from 'src/Domain/Customer/Exception/CustomerNotFoundException';
import { Address } from 'src/Domain/Customer/Address.entity';
import { AddressView } from '../View/AddressView';

describe('GetCustomerByIdQueryHandler', () => {
const query = new GetCustomerByIdQuery(
Expand All @@ -20,26 +18,12 @@ describe('GetCustomerByIdQueryHandler', () => {
);
const expectedResult = new CustomerView(
'eb9e1d9b-dce2-48a9-b64f-f0872f3157d2',
'Radio France',
new AddressView(
'f4646506-dd8f-490f-927e-d5c54cc035d6',
'116 Avenue du Président Kennedy',
'Paris',
'75016',
'FR'
)
'Radio France'
);
const customer = mock(Customer);
const address = mock(Address);

when(address.getId()).thenReturn('f4646506-dd8f-490f-927e-d5c54cc035d6');
when(address.getCity()).thenReturn('Paris');
when(address.getStreet()).thenReturn('116 Avenue du Président Kennedy');
when(address.getZipCode()).thenReturn('75016');
when(address.getCountry()).thenReturn('FR');
when(customer.getId()).thenReturn('eb9e1d9b-dce2-48a9-b64f-f0872f3157d2');
when(customer.getName()).thenReturn('Radio France');
when(customer.getAddress()).thenReturn(instance(address));

when(
customerRepository.findOneById('eb9e1d9b-dce2-48a9-b64f-f0872f3157d2')
Expand Down
Loading

0 comments on commit 13846aa

Please sign in to comment.