SlideShare une entreprise Scribd logo
1  sur  56
PROJECTIONS
EXPLAINED
{ YVES REYNHOUT }
AGENDA
Meet the domain
Projections
Terminology
Designing
Authoring
Testing
WELCOME @
BEAUFORMA (FR)
YOU ARE THE PRODUCT
ON THE OUTSIDE
ON THE INSIDE
THAT IS ...
IF YOU CAN AFFORD US
;-)
CHALLENGES
CONTEXT MAP
REWARD
WHAT'S NOT TO LIKE ABOUT
BEAUFORMA?
BUT, DUDE ... WE'RE
HERE FOR
PROJECTIONS,
REMEMBER?
TERMINOLOGY
Event: a fact, something that happened, a message, a
datastructure
Stream: a sequence of events, partitioned by something
Event store: a collection of streams (simplified)
Disclaimer: not authoritive, just my take
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
open System 
type GuestStartedShopping = {  
  SubsidiaryId : Guid; 
  FeelGoodCartId : Guid;  
  GuestId : Guid; 
  StartDateAndTime : DateTime; 
} 
type GuestCheckedOutCart = {  
  FeelGoodPackageId : Guid; 
  FeelGoodCartId : Guid;  
  GuestId : Guid; 
  Items : Guid array; 
} 
type GuestAbandonedCart = {  
  FeelGoodCartId : Guid;  
  GuestId : Guid; 
  LastSeenDateAndTime : DateTime; 
} 
1:
2:
3:
4:
5:
6:
7:
8:
type ItemWasAddedToCart = {  
  FeelGoodCartId : Guid;  
  ItemId : Guid; 
} 
type ItemWasRemovedFromCart = {  
  FeelGoodCartId : Guid;  
  ItemId : Guid; 
} 
VANILLA CQRS+ES
TERMINOLOGY
ProjectionHandler: a function that projects an event
Projection: a collection of handlers that form a unit
Projector: a function that dispatches an event or a batch
of events to the matching handler(s)
[Optional] ProjectionHandlerResolver: a function that
returns the handlers that match an event
Disclaimer: not authoritive, just my take
EXAMPLE
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
open StackExchange.Redis 
let inline (!>) (x:^a) : ^b =  
  ((^a or ^b) : (static member op_Implicit : ^a ­> ^b) x)  
let activeShoppersProjection (connection:IDatabase, message:Object) = 
  match message with 
  | :? GuestStartedShopping ­>  
    connection.StringIncrement(!> "ActiveShoppers", 1L) |> ignore 
  | :? GuestAbandonedCart ­>  
    connection.StringDecrement(!> "ActiveShoppers", 1L) |> ignore 
  | :? GuestCheckedOutCart ­>  
    connection.StringDecrement(!> "ActiveShoppers", 1L) |> ignore 
  | _ ­> () 
EXAMPLE
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
public class ActiveShoppersProjection : ConnectedProjection<IDatabase> 
{ 
  public ActiveShoppersProjection() 
  { 
    When<GuestStartedShopping>((connection, message) =>  
      connection.StringIncrementAsync("ActiveShoppers")); 
    When<GuestAbandonedCart>((connection, message) =>  
      connection.StringDecrementAsync("ActiveShoppers")); 
    When<GuestCheckedOutCart>((connection, message) =>  
      connection.StringDecrementAsync("ActiveShoppers")); 
  } 
} 
EXAMPLE
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
public interface IHandler<TMessage> 
{ 
  void Handle(IDatabase connection, TMessage message); 
} 
public class ActiveShoppersProjection : IHandler<GuestStartedShopping>, 
  IHandler<GuestAbandonedCart>, IHandler<GuestCheckedOutCart>  
{ 
  public void Handle(IDatabase connection, GuestStartedShopping message) 
  { 
    connection.StringIncrement("ActiveShoppers"); 
  } 
  public void Handle(IDatabase connection, GuestAbandonedCart message) 
  { 
    connection.StringDecrement("ActiveShoppers"); 
  } 
  public void Handle(IDatabase connection, GuestCheckedOutCart message) 
  { 
    connection.StringDecrement("ActiveShoppers"); 
  } 
} 
VANILLA CQRS+ES
VANILLA DDD
DESIGNING
PROJECTIONS
consumer driven (by screen, api, model, ...)
affected by the choice of store (e.g. required querying
capabilities, non-functional requirements, ...)
DATASTRUCTURES
EXERCISE
Define a datastructure for this widget
POSSIBLE SOLUTION
1:
2:
3:
4:
5:
6:
7:
8:
type GuestsArrivingRecord = {  
  RecordId: string; 
  SubsidairyId: Guid; 
  Date: DateTime; 
  AppointmentId : Guid; 
  GuestName : string;  
  AppointmentDateAndTime : DateTime  
} 
POSSIBLE SOLUTION
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
type GuestsArrivingDocument = {  
  DocumentId: string; 
  SubsidairyId: Guid; 
  Date: DateTime; 
  Appointments : Appointment array 
} 
type Appointment = { 
  AppointmentId : Guid; 
  GuestName : string;  
  AppointmentDateAndTime : DateTime  
} 
EVENTS
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
type GuestBookedAppointment = {  
  AppointmentId : Guid;  
  GuestId : Guid; 
  AppointmentDateAndTime : DateTime;  
  FeelGoodPackageId : Guid;  
  SubsidiaryId : Guid  
} 
type GuestRescheduledAppointment = {  
  AppointmentId : Guid;  
  GuestId : Guid;  
  AppointmentDateAndTime : DateTime;  
  FeelGoodPackageId : Guid;  
  SubsidiaryId : Guid  
} 
type GuestSwappedAppointmentFeelGoodPackage = {  
  AppointmentId : Guid;  
  GuestId : Guid;  
  FeelGoodPackageId : Guid;  
  SubsidiaryId : Guid  
} 
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
type GuestCancelledAppointment = {  
  AppointmentId : Guid; 
  GuestId : Guid; 
  Reason : string;  
  SubsidiaryId : Guid  
} 
type SubsidiaryCancelledAppointment = {  
  AppointmentId : Guid; 
  GuestId : Guid; 
  Reason : string;  
  SubsidiaryId : Guid  
} 
EXERCISE
Fill your datastructure using these events
- booking.fshttps://goo.gl/BTBTfi
OBSERVATIONS
Not all events are useful,
Information might be missing from events,
Not all data is for viewing
Events challenge the datastructure
What about your observations?
OBSERVATIONS
Not all data comes from one projection,
Not all data is owned by one model
ONE EXTRA EVENT TO TAKE INTO ACCOUNT
1:
2:
3:
4:
5:
type GuestRegistered = {  
  GuestId : Guid; 
  FullName : string; 
  DateOfRegistration: DateTime; 
} 
EXERCISE
Extend your projection with the event
- booking|guests.fshttps://goo.gl/BTBTfi
POSSIBLE SOLUTION
1:
2:
3:
4:
5:
type GuestDocument = {  
  DocumentId: string; 
  GuestId: Guid; 
  FullName: string; 
} 
AUTHORING
PROJECTIONS
EXERCISE
Express the projection in your language and store of choice
- booking|guests.fshttps://goo.gl/BTBTfi
RECIPE?
define message types in code (for statically typed
languages)
define and implement projection handlers for each
message type
define and implement a dispatcher to those projection
handlers
test drive in the program's main
NOT CHALLENGING ENOUGH?
EVENTSTORE
IP Address: 178.62.229.196
Http Port: 2113
Tcp Port: 1113
Login: admin
Password: changeit
REDIS
IP Address: 178.62.229.196
Port: 6379
ELASTICSEARCH
IP Address: 178.62.229.196
Port: 9200
POSTGRES
IP Address: 46.101.161.64
Port: 5432
Login: dddeu16
Password: dddeu16
Database: dddeu16
SslMode: required
Server Certificate: see online environment file
- online-
environment.md
https://goo.gl/BTBTfi
TESTING PROJECTIONS
EXAMPLE
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
public class ActiveShoppersProjectionScenarios 
{ 
  public Task when_multiple_active_shoppers() 
  { 
    return MemoryCacheProjection.For(new ActiveShoppersProjection()) 
      .Given( 
        new GuestStartedShopping {  
          SubsidiaryId = BonifacioId,  
          FeelGoodCartId = RandomCartId(), 
          GuestId = OliverMartinezId, 
          StartDateAndTime = Today.At(6.PM()) 
        },
        new GuestStartedShopping {  
          SubsidiaryId = BonifacioId,  
          FeelGoodCartId = RandomCartId(), 
          GuestId = RodriguezId, 
          StartDateAndTime = Today.At(4.PM()) 
        })
      .Expect(new CacheItem("ActiveShoppersCount", 2)); 
  } 
} 

Contenu connexe

En vedette

Get Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsGet Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsDavey Shafik
 
Techniques d'accélération des pages web
Techniques d'accélération des pages webTechniques d'accélération des pages web
Techniques d'accélération des pages webJean-Pierre Vincent
 
Automation using-phing
Automation using-phingAutomation using-phing
Automation using-phingRajat Pandit
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP GeneratorsMark Baker
 
The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)Matthias Noback
 
Top tips my_sql_performance
Top tips my_sql_performanceTop tips my_sql_performance
Top tips my_sql_performanceafup Paris
 
Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Marcello Duarte
 
Why elasticsearch rocks!
Why elasticsearch rocks!Why elasticsearch rocks!
Why elasticsearch rocks!tlrx
 
Writing infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQLWriting infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQLGabriele Bartolini
 
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Bruno Boucard
 
L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)Arnauld Loyer
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016CiaranMcNulty
 
Performance serveur et apache
Performance serveur et apachePerformance serveur et apache
Performance serveur et apacheafup Paris
 
The Wonderful World of Symfony Components
The Wonderful World of Symfony ComponentsThe Wonderful World of Symfony Components
The Wonderful World of Symfony ComponentsRyan Weaver
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersKacper Gunia
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mockingKonstantin Kudryashov
 

En vedette (20)

Get Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsGet Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP Streams
 
Techniques d'accélération des pages web
Techniques d'accélération des pages webTechniques d'accélération des pages web
Techniques d'accélération des pages web
 
Automation using-phing
Automation using-phingAutomation using-phing
Automation using-phing
 
PHP5.5 is Here
PHP5.5 is HerePHP5.5 is Here
PHP5.5 is Here
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
 
The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)
 
Top tips my_sql_performance
Top tips my_sql_performanceTop tips my_sql_performance
Top tips my_sql_performance
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
 
Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015
 
Why elasticsearch rocks!
Why elasticsearch rocks!Why elasticsearch rocks!
Why elasticsearch rocks!
 
Writing infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQLWriting infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQL
 
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
 
L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)
 
Behat 3.0 meetup (March)
Behat 3.0 meetup (March)Behat 3.0 meetup (March)
Behat 3.0 meetup (March)
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016
 
Caching on the Edge
Caching on the EdgeCaching on the Edge
Caching on the Edge
 
Performance serveur et apache
Performance serveur et apachePerformance serveur et apache
Performance serveur et apache
 
The Wonderful World of Symfony Components
The Wonderful World of Symfony ComponentsThe Wonderful World of Symfony Components
The Wonderful World of Symfony Components
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 

Dernier

Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfLivetecs LLC
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noidabntitsolutionsrishis
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 

Dernier (20)

Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdf
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 

Projections explained