Договор - это агрегат?
От: zelenprog  
Дата: 09.10.23 10:35
Оценка:
Здравствуйте!

Начинаю делать программу для конвертации контрагентов из старой базы в новую.
На данный момент, интересуют следующие таблицы, которые есть в базе данных: Организации, Контрагенты, Договора.
Организации — это наши организации, их несколько.

Как я понимаю, слой бизнес-логики должен состоять из следующих "элементов":
— бизнес-сущности для "объектов" из старой БД: "ОрганизацияСтарая", "КонтрагентСтарый", "ДоговорСтарый"
— бизнес-сущности для "объектов" в новой БД: "ОрганизацияНовая", "КонтрагентНовый", "ДоговорНовый"
— репозитории для этих сущностей
— метод "Конвертация", который выполняет основную работу: читает с помощью репозиториев старые данные, формирует из старых сущностей новые сущности, и с помощью других репозиториев записывает новые сущности в новую базу.

Верно?

Вопрос возник по агрегатам.
Договор — это как бы связь между нашей организацией и контрагентом. То есть он не может отдельно существовать без организации и без контрагента.
Следовательно, договор не может быть отдельным агрегатом, он должен быть одновременно частью и агрегата "Организация" и агрегата "Контрагент".
Однако, такого же не может быть?

Может быть сделать договор отдельным агрегатом? Соответственно придется делать отдельный Репозиторий.

Как лучше сделать?

Сейчас читаю статью и пытаюсь разобраться:
https://habr.com/ru/articles/660599/

Там выделение агрегата завязано на инвариантах. А какие тут инварианты?
Инвариант только один — договор не может существовать без организации и без контрагента.
А контрагент не может существовать без договора. И как это влияет на выделение агрегата?
Отредактировано 09.10.2023 10:48 zelenprog . Предыдущая версия . Еще …
Отредактировано 09.10.2023 10:37 zelenprog . Предыдущая версия .
Re: Договор - это агрегат?
От: paradok  
Дата: 09.10.23 12:34
Оценка:
Здравствуйте, zelenprog, Вы писали:

имхо договор может в пределе быть сам по себе
например оба участника договора давно перестали существовать
и были удалены из базы
Re: Договор - это агрегат?
От: RushDevion Россия  
Дата: 09.10.23 19:07
Оценка: 2 (2)
Z>Верно?
Ну в теории, допустим, верно.
Но, как кто-то из коллег уже писал в твоей предыдущей теме, пытаться прикрутить классический DDD к задаче миграции — это натягивание совы на глобус.
Здесь просто нет того уровня сложности, который раскроет преимущества DDD-подхода.
Взять данные из одной БД, преобразовать по элементарному алгоритму, положить в другую БД. В чем тут сложность?

Z>Вопрос возник по агрегатам.

Z>Договор — это как бы связь между нашей организацией и контрагентом. То есть он не может отдельно существовать без организации и без контрагента.
Z>Следовательно, договор не может быть отдельным агрегатом, он должен быть одновременно частью и агрегата "Организация" и агрегата "Контрагент".
Z>Однако, такого же не может быть?

Вот тут по DDD подходу ты должен сесть за стол в domain experts и проговаривать неясные моменты до общего просветления.
Как в системе появляется Организация? Кто ее заводит? Или бизнес-процесса заведения Организации вообще нет и предполгается, что она просто существует изначально? А организация меняется? А кто, как и почему ее меняет? А кому интересен факт этих изменений?
Как в системе появляется Контрагент? Заведение контрагента тождественно Заключению Договора с ним? Да? А договор с данным контрагентом всегда один? Один, да? Хм.. Ну тогда может у нас нет сущности Контрагент а есть cущность "Договор с контрагентом", в которой в том числе хранятся реквизиты контрагента? Что вы говорите? Договоров все же может быть несколько, а Контрагенты используются еще для выставление Счетов? Вон оно что. Похоже у нас все же будет сущность Договор (и, возможно, сущность Счет) А как Договор появляется в системе? И т.д. и т.п.
И из этого процесса пошагово формируется твоя доменная модель, понятная тебе как программисту и, что важно по DDD, понятная domain-экспертам, как представителям бизнеса.

Z>Может быть сделать договор отдельным агрегатом? Соответственно придется делать отдельный Репозиторий.

Ну да. И что?
Будет отдельная сущность "Договор", со ссылками на "Организацию" и "Контрагента" (это нормально).
Будет репозиторий договором с методами вроде "ПолучитьДоговорПоНомеру", "ПолучитьВсеДоговораОрганизации", "ПолучитьАктивныйДоговорКонтрагента" и т.п.
Re[2]: Договор - это агрегат?
От: Разраб  
Дата: 10.10.23 02:10
Оценка:
Здравствуйте, paradok, Вы писали:

P>Здравствуйте, zelenprog, Вы писали:


P>имхо договор может в пределе быть сам по себе

P>например оба участника договора давно перестали существовать
P>и были удалены из базы

нельзя удалять из базы КА иначе договор станет неполным.
только после удаления последней ссылки на КАК его можно удалять. нарушите целостность базы.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re: Договор - это агрегат?
От: Разраб  
Дата: 10.10.23 02:15
Оценка:
Здравствуйте, zelenprog, Вы писали:


Z>Следовательно, договор не может быть отдельным агрегатом, он должен быть одновременно частью и агрегата "Организация" и агрегата "Контрагент".

"Организация" -> договор -> Контрагент
если уж хотите ДДД то не мечитесь, а следуйте ему.
просто в корне мы Identity предоставляем конечному пользователю, а в значениях-свойствах прячем.
по сути в базе будет точно такая же связь
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[2]: Договор - это агрегат?
От: qaz77  
Дата: 10.10.23 07:04
Оценка:
Здравствуйте, RushDevion, Вы писали:

Z>>Может быть сделать договор отдельным агрегатом? Соответственно придется делать отдельный Репозиторий.

RD>Ну да. И что?
RD>Будет отдельная сущность "Договор", со ссылками на "Организацию" и "Контрагента" (это нормально).
RD>Будет репозиторий договором с методами вроде "ПолучитьДоговорПоНомеру", "ПолучитьВсеДоговораОрганизации", "ПолучитьАктивныйДоговорКонтрагента" и т.п.

Согласен.
С одним контрагентом запросто может быть несколько договоров по разным поводам.
Иногда заказчик хочет еще хранить в базе текст договора в виде блоба (как pdf или doc).

Пообщайтесь с заказчиками для уточнения ТЗ.
Иногда в организациях учет договоров бывает очень мудренным.
Re[2]: Договор - это агрегат?
От: zelenprog  
Дата: 10.10.23 07:30
Оценка:
RD>Здесь просто нет того уровня сложности, который раскроет преимущества DDD-подхода.
RD>Взять данные из одной БД, преобразовать по элементарному алгоритму, положить в другую БД. В чем тут сложность?

Сложность в правилах конвертации. Они достаточно сложные и неочевидные.
Где же их еще реализовавыть как не в Бизнес-слое (domain-model)?

RD>Вот тут по DDD подходу ты должен сесть за стол в domain experts и проговаривать неясные моменты до общего просветления.

RD>Как в системе появляется Организация? Кто ее заводит? Или бизнес-процесса заведения Организации вообще нет и предполгается, что она просто существует изначально? А организация меняется? А кто, как и почему ее меняет? А кому интересен факт этих изменений?
RD>Как в системе появляется Контрагент? Заведение контрагента тождественно Заключению Договора с ним? Да? А договор с данным контрагентом всегда один? Один, да? Хм.. Ну тогда может у нас нет сущности Контрагент а есть cущность "Договор с контрагентом", в которой в том числе хранятся реквизиты контрагента? Что вы говорите? Договоров все же может быть несколько, а Контрагенты используются еще для выставление Счетов? Вон оно что. Похоже у нас все же будет сущность Договор (и, возможно, сущность Счет) А как Договор появляется в системе? И т.д. и т.п.
RD>И из этого процесса пошагово формируется твоя доменная модель, понятная тебе как программисту и, что важно по DDD, понятная domain-экспертам, как представителям бизнеса.

Это все мы обсуждали с нашими "экспертами".
Схема "бизнеса" классическая. Есть несколько организаций, заводятся очень редко.
Контрагенты появляются часто. С каждым контрагентом может быть несколько договоров. На данный момент перенести нужно только тот договор, который отмечен как основной. Но вполне вероятно, что в дальнейшем потребуется перенести и остальные договора.
Вопросы создания\изменения объектов пока не интересуют, так как они не касаются данной программы конвертации. Задача программы — перенести в новую базу то, что есть на текущий момент.
Re[3]: Договор - это агрегат?
От: paradok  
Дата: 10.10.23 07:48
Оценка:
Здравствуйте, Разраб, Вы писали:



Р>нельзя удалять из базы КА иначе договор станет неполным.

Р>только после удаления последней ссылки на КАК его можно удалять. нарушите целостность базы.

на практике так часто бывает и никакая целостность не нарушается
подвисшие договора в базе — это норма
по ним все также можно делать поиск и тд.
кроме подписавших сторон у договоров есть масса других атрибутов по которым можно делать поиск и агрегацию
Re: Договор - это агрегат?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.10.23 08:03
Оценка:
Здравствуйте, zelenprog, Вы писали:

Z>Как лучше сделать?

Делай так, чтобы быстрее решить задачу

Z>Может быть сделать договор отдельным агрегатом? Соответственно придется делать отдельный Репозиторий.

На какие пользовательские характеристики это влияет?
Как будет быстрее написать?
Будет работать быстрее или медленнее?
Как повлияет на взаимодействие с программой?
Re[3]: Договор - это агрегат?
От: RushDevion Россия  
Дата: 10.10.23 08:16
Оценка: 3 (1)
Z>Сложность в правилах конвертации. Они достаточно сложные и неочевидные.
Z>Где же их еще реализовавыть как не в Бизнес-слое (domain-model)?

Опять же, допустим.
Я просто пытаюсь донести, что DDD — это не только про код, это прежде всего про shared mental model системы, выраженную в коде.
И есть у меня ощущение, что если спросить вашего доменного эксперта о правилах конвертации из старой БД в новую, то он сильно удивится.
Потому что в его картине мира есть Организации, Договора, Контрагенты. А вот БД там скорей всего нет.
Как нет и процесса конвертации из одной БД в другую.
Т.е. конвертация — это такая чисто техническая деталь, с доменом вообще никак не связанная.

Опять же, допустим, что я ошибаюсь.
И в картине мира доменного эксперта присутствуют и Договор Старого Формата, и Договор Нового Формата.
И он выдал вам вполне конкретные правила конвертации.

Тогда в терминах DDD у нас есть сущности ДоговорСтарогоФормата и ДоговорНовогоФормата и есть процесс конвертации.
А такой процесс обычно моделируется доменным сервисом, e.g.
// Это лежит в сборке Domain.dll
class ContractConvertor {
  public Contract Convert(OldContract contract) { 
    // Тут создание нового контракта
    // Применение бизнес-правил конвертации
  }
}

А где-то уровнем выше есть application service, который этим доменным сервисом оперирует:
// Это лежит в сборке Application.dll, которая рефренсит Domain.dll и, e.g. Infrastructure.Storage.Contracts - для интерфейсов репозиториев
class ConvertionService {
  private IContractRepo _contracts;
  private IOldContractRepo _oldContracts;
  private ContractConvertor _convertor;

  public Contract ConvertContract(int oldContractId) {
    var oldContract = _oldContracts.LoadById(oldContractId);
    var newContract = _convertor.Convert(oldContract);
    _contracts.Save(newContract);
    return newContract;
  }
}
Отредактировано 10.10.2023 9:00 RushDevion . Предыдущая версия . Еще …
Отредактировано 10.10.2023 8:18 RushDevion . Предыдущая версия .
Re[4]: Договор - это агрегат?
От: zelenprog  
Дата: 14.10.23 08:41
Оценка:
RD>Опять же, допустим.
RD>Я просто пытаюсь донести, что DDD — это не только про код, это прежде всего про shared mental model системы, выраженную в коде.
RD>И есть у меня ощущение, что если спросить вашего доменного эксперта о правилах конвертации из старой БД в новую, то он сильно удивится.
RD>Потому что в его картине мира есть Организации, Договора, Контрагенты. А вот БД там скорей всего нет.

Эксперт понимает про старые БД и про новую БД.
Если раньше каждый филиал работал в своей локальной базе, то теперь все должны работать в одной централизованной базе.
Перенос данных — это как раз инициатива группы экспертов. Причем они (эта группа) прекрасно понимают некоторые сложности, которые при этом переносе возникнут.

Например, вот одна из сложностей.
Один и тот же контрагент есть во всех базах: он есть во всех старых базах и даже уже есть в новой базе (был заведен вручную).
У контрагента есть реквизиты (телефон) для связи. С данным контрагентом в разных наших филиалах работали разные менеджеры, они взаимодейтсовали с разными представителями контрагента.
То есть за каждым менеджером филиала был закреплен какой-то представитель контрагента. Соответственно, в БД каждого филиала для этого контрагента вбиты разные данные представителя контрагента (ФИО, телефон и пр.).
Эксперты понимают, что "объединить" эти данные в одной новой базе не так просто.

Кроме того, в разных старых базах иногда забиты разные значения и в других реквизитах контрагента.
При последовательной загрузке контрагентов из старых баз, реквизиты будут просто перезаписываться.
И получится, что значения реквизитов у контрагента в новой базе будут просто совпадать с контрагентом из последней загруженной старой базы.

Эти сложности, мы пока совместно не придумали как решить.

Я просто к тому, что эксперты кое-что все-таки понимают.
Re[4]: Договор - это агрегат?
От: zelenprog  
Дата: 14.10.23 08:52
Оценка:
RD>Опять же, допустим, что я ошибаюсь.
RD>И в картине мира доменного эксперта присутствуют и Договор Старого Формата, и Договор Нового Формата.
RD>И он выдал вам вполне конкретные правила конвертации.

RD>Тогда в терминах DDD у нас есть сущности ДоговорСтарогоФормата и ДоговорНовогоФормата и есть процесс конвертации.

RD>А такой процесс обычно моделируется доменным сервисом, e.g.
RD>
RD>// Это лежит в сборке Domain.dll
RD>class ContractConvertor {
RD>  public Contract Convert(OldContract contract) { 
RD>    // Тут создание нового контракта
RD>    // Применение бизнес-правил конвертации
RD>  }
RD>}
RD>

RD>А где-то уровнем выше есть application service, который этим доменным сервисом оперирует:
RD>
RD>// Это лежит в сборке Application.dll, которая рефренсит Domain.dll и, e.g. Infrastructure.Storage.Contracts - для интерфейсов репозиториев
RD>class ConvertionService {
RD>  private IContractRepo _contracts;
RD>  private IOldContractRepo _oldContracts;
RD>  private ContractConvertor _convertor;

RD>  public Contract ConvertContract(int oldContractId) {
RD>    var oldContract = _oldContracts.LoadById(oldContractId);
RD>    var newContract = _convertor.Convert(oldContract);
RD>    _contracts.Save(newContract);
RD>    return newContract;
RD>  }
RD>}
RD>


Спасибо за пример кода!

В связи с этим два вопроса:
1) А как в этом коде предусмотреть ситуацию, что договор уже есть в новой базе?
2) Получается, вы считаете, что договор — это все-таки отдельный агрегат? Правильно?
Насколько я помню, Репозитории в DDD дожны работать именно с агрегатами.
Тогда как этот договор-агрегат будет связан с Сущностями "Организация" и "Контрагент"?
Re: Договор - это агрегат?
От: viellsky  
Дата: 14.10.23 08:58
Оценка:
Здравствуйте, zelenprog, Вы писали:

Z>Договор — это как бы связь между нашей организацией и контрагентом. То есть он не может отдельно существовать без организации и без контрагента.

Может. Шаблон договора, к примеру. Юристы кстати используют — т.е. это жизненная, интуитивно-понятная абстракция.

Z>Следовательно, договор не может быть отдельным агрегатом, он должен быть одновременно частью и агрегата "Организация" и агрегата "Контрагент".

Организация и контрагент — это параметры договора. См. выше — берешь шаблон, задаешь параметры.

Z>https://habr.com/ru/articles/660599/

Чего ты усложняешь? Примитивная же задача. Делай так, как будет естественно и интуитивно понятно — иначе сопровождать замахаешься ты или твой последователь — поди потом вспомни/пойми/разберись в доках, что ты имел в виду какой-то навороченной архитектурой и как при правках правильно сохранить твой замысел.
Re[2]: Договор - это агрегат?
От: zelenprog  
Дата: 14.10.23 11:33
Оценка:
Z>>Как лучше сделать?
G>Делай так, чтобы быстрее решить задачу

Так в этом то и проблема.
Если структура (архитектура) программы продумана хорошо, то и задачу получиться решить быстрее.
А если корявая архитектура, то ее доработки и исправление косяков будут бесконечны.

Z>>Может быть сделать договор отдельным агрегатом? Соответственно придется делать отдельный Репозиторий.

G>На какие пользовательские характеристики это влияет?

Как я понимаю, внутренние технические решения никак не влияют на пользовательские характеристики.
Наоборот, пользовательские характеристики задают требования для технической реализации.
Если техническая реализация выполняет эти требования — то мы получим желаемые пользовательские характеристки, и все довольны.
Если мы не смогли придумать и сделать техническую реализацию, удовлетворяющую пользовательским характеристкам, то у нас и нету рабочей программы.

G>Как будет быстрее написать?


Чтобы ответить на этот вопрос, надо сравнить несколько вариантов ("проектов") будущей программы.
А как построить эти варианты? Какие выбрать варианты? Вот тут я как раз и не имею достаточного опыта.
Но судя по рекомендациям ведущих "мыслителей" разработки ПО, правильнее и быстрее написать получится при умении создать правильную архитектуру.

G>Будет работать быстрее или медленнее?

G>Как повлияет на взаимодействие с программой?

Это второстепенные вопросы.
Самые важные вопросы — это работоспособная программы, выполняющая определенные требования, срок разработки, и возможность дальнейшей доработки при расширении исходных требований.
Re[2]: Договор - это агрегат?
От: zelenprog  
Дата: 14.10.23 11:36
Оценка:
V>Чего ты усложняешь? Примитивная же задача. Делай так, как будет естественно и интуитивно понятно — иначе сопровождать замахаешься ты или твой последователь — поди потом вспомни/пойми/разберись в доках, что ты имел в виду какой-то навороченной архитектурой и как при правках правильно сохранить твой замысел.

Нужна не навороченная, а "правильная" архитектура.
При правильной архитектуре код читается легко и понятно.
Re[5]: Договор - это агрегат?
От: RushDevion Россия  
Дата: 14.10.23 12:22
Оценка: 1 (1)
Z>Спасибо за пример кода!
Пожалуйста.

Z>В связи с этим два вопроса:

Z>1) А как в этом коде предусмотреть ситуацию, что договор уже есть в новой базе?
Ну, есть несколько вариантов.
Для начала, я бы посмотрел, есть ли у документа то, что в DDD называют "естественный идентификатор".
Например, им может быть номер договора, который, формируется по определенным правилам и глобально уникален в пределах всей вашей организации.
Если такой идентификатор есть — то все просто:
public Contract ConvertContract(string oldContractNumber) {
    var oldContract = _oldContracts.LoadByNumber(oldContractNumber);
    var existingNewContract = _contracts.LoadByNumber(oldContractNumber);
    if(existingNewContract is not null) {
      _logger.LogWarn("Contract {oldContractNumber} is already imported");
      return existingNewContract;
    }
    var newContract = _convertor.Convert(oldContract);
    _contracts.Save(newContract);
    return newContract;
}

Если же естественного идентификатора нет и им выступает какой-нибудь Identity столбец в БД + в разных БД филиалов есть пересечения по identity,
то придется научиться однозначно сопоставлять: Филиал + Id старого документа => Id нового.
Как вариант:
// Имплементация может хранить мапинг в какой-то таблице БД, e.g. ContractsConvertionHistory
// Это и для разбора проблем будет полезно
interface IConvertedContractsTracker {
    void RegisterContract(string departmentId, long oldDocumentId, long newDocumentId);
    void IsContractRegistered(string departmentId, long oldDocumentId);
}

public Contract ConvertContract(long oldContractId) {
    var oldContract = _oldContracts.LoadById(oldContractNumber);
        var isImported = _convertionTracker.IsContractRegistered(oldContract.DepartmentId, oldContract.Id);
    if (isImported) {
        // TODO: log
        return;
    }

    var newContract = _convertor.Convert(oldContract);
    _contracts.Save(newContract);
    
    _convertionTracker.RegisterContract(oldContract.DepartmentId, oldContract.Id, newContract.Id);
    
    return newContract;
}


Или можно договориться, что в новой БД номера контрактов будут составные, типа такого:
class IdentityConvertor {
   string GenerateNewContractNumber(string departmentId, long oldContractId) => $"{departmentId:oldContractId}";
}

// Тогда будет что-то типа такого
public Contract ConvertContract(long oldContractId) {
    var oldContract = _oldContracts.LoadById(oldContractId);
    var newContractNumber = _identityConvetor.GenerateNewContractNumber(oldContract.DepartmentId, oldContract.Id);
    
    var existingContract = _contracts.LoadByNumber(newContractNumber);
    if (existingContract is not null) {
        // TODO: log
        return existingContract;
    }
    
    // ...
}

Z>2) Получается, вы считаете, что договор — это все-таки отдельный агрегат? Правильно?
Да, договор — это отдельный агрегат.

Z>Насколько я помню, Репозитории в DDD дожны работать именно с агрегатами.

Z>Тогда как этот договор-агрегат будет связан с Сущностями "Организация" и "Контрагент"?
Имхо, проще всего — по Id.
class Document {
  public long OrganizationId { get; private set; }
  public long PartnerId { get; private set; }
}

Еще я встречал вот такой изврат:
class Document {
  public EntityRef<Organization, long> Organization { get; private set; }
  public EntityRef<Partner, long> Partner { get; private set; }
}

// Здесь EntityRef<Organization, long> - это read-only, lazy-loading обертка для соответствующей entity
Отредактировано 14.10.2023 13:10 RushDevion . Предыдущая версия . Еще …
Отредактировано 14.10.2023 12:57 RushDevion . Предыдущая версия .
Re[5]: Договор - это агрегат?
От: RushDevion Россия  
Дата: 14.10.23 13:08
Оценка:
Z>Один и тот же контрагент есть во всех базах: он есть во всех старых базах и даже уже есть в новой базе (был заведен вручную).
Z>У контрагента есть реквизиты (телефон) для связи. С данным контрагентом в разных наших филиалах работали разные менеджеры, они взаимодейтсовали с разными представителями контрагента.
Z>То есть за каждым менеджером филиала был закреплен какой-то представитель контрагента. Соответственно, в БД каждого филиала для этого контрагента вбиты разные данные представителя контрагента (ФИО, телефон и пр.).
Z>Эксперты понимают, что "объединить" эти данные в одной новой базе не так просто.

Конкретно тут проблемы не вижу. Просто в доменной модели появляется сущность ContactPerson
class Partner {
  private readonly List<ContactPersons> _contactPersons = new();
  public IReadOnlyCollection<ContactPersons> ContactPersons { get; } => _contactPersons.AsReadOnly();

  public void AddContact(ContactPerson person) {
    // TODO: реализация инвариантов для агрегата Patner, e.g. 
    // должен быть активный контакт, активный контакт может быть только один и с российским телефоном, 
    // последний добавленый контакт становится активным и т.д и т.п.
    _contactsPersons.Add(person);
  }
  
  public ContactPerson ActiveContact => ... 
}


Z>Кроме того, в разных старых базах иногда забиты разные значения и в других реквизитах контрагента.

Z>При последовательной загрузке контрагентов из старых баз, реквизиты будут просто перезаписываться.
Z>И получится, что значения реквизитов у контрагента в новой базе будут просто совпадать с контрагентом из последней загруженной старой базы.

Имхо, это не проблема моделирования домена. Это проблема неконсистентности данных. Ее надо решать не программными, а административными методами.
Re[5]: Договор - это агрегат?
От: binks Россия  
Дата: 14.10.23 13:26
Оценка:
Здравствуйте, zelenprog, Вы писали:

Z>Например, вот одна из сложностей.

Z>Один и тот же контрагент есть во всех базах: он есть во всех старых базах и даже уже есть в новой базе (был заведен вручную).
Z>У контрагента есть реквизиты (телефон) для связи. С данным контрагентом в разных наших филиалах работали разные менеджеры, они взаимодейтсовали с разными представителями контрагента.
Z>То есть за каждым менеджером филиала был закреплен какой-то представитель контрагента. Соответственно, в БД каждого филиала для этого контрагента вбиты разные данные представителя контрагента (ФИО, телефон и пр.).
Z>Эксперты понимают, что "объединить" эти данные в одной новой базе не так просто.

Не понял в чём сложность. Нельзя создать организационную структуру предприятия и на эту структуру делать ссылки в таблице контрагентов?
Re[3]: Договор - это агрегат?
От: viellsky  
Дата: 14.10.23 16:33
Оценка: 1 (1) +2
Здравствуйте, zelenprog, Вы писали:

Z>Нужна не навороченная, а "правильная" архитектура.

Z>При правильной архитектуре код читается легко и понятно.

Ставишь телегу впереди лошади. Наоборот — та архитектура, которая понятная и легко читается — правильная. Ты пытаешься найти некую "правильность", исходя из неких общепрограммерских принципов, которые кто-то сформулировал (ты дал ссылку). И думаешь, будто, если сделаешь "правильно" согласно этой чьей-то философии (а это именно философия, не некая точная наука), то вдруг бац — и станет легко читаться. Да ничего подобного. Просто делай сразу так, как будет легко читаться. Т.е. чтобы было интуитивно понятно исходя из конкретной прикладной задачи. Ладно бы у тебя были какие-то абстракции, которые не имеют аналогов в жизни — но тут то обычная прикладнуха, слепок из жизни, из конкретных бумажек и несложных бизнес-процессов.
Re[5]: Договор - это агрегат?
От: Janus Россия  
Дата: 14.10.23 19:00
Оценка: 1 (1)
Здравствуйте, zelenprog, Вы писали:


Z>Эксперт понимает про старые БД и про новую БД.

Z>Если раньше каждый филиал работал в своей локальной базе, то теперь все должны работать в одной централизованной базе.
Z>Перенос данных — это как раз инициатива группы экспертов. Причем они (эта группа) прекрасно понимают некоторые сложности, которые при этом переносе возникнут.

Z>Например, вот одна из сложностей.

Z>Один и тот же контрагент есть во всех базах: он есть во всех старых базах и даже уже есть в новой базе (был заведен вручную).
Z>У контрагента есть реквизиты (телефон) для связи. С данным контрагентом в разных наших филиалах работали разные менеджеры, они взаимодейтсовали с разными представителями контрагента.
Z>То есть за каждым менеджером филиала был закреплен какой-то представитель контрагента. Соответственно, в БД каждого филиала для этого контрагента вбиты разные данные представителя контрагента (ФИО, телефон и пр.).
Z>Эксперты понимают, что "объединить" эти данные в одной новой базе не так просто.

Компетентность ваших "экспертов" вызывает очень большие сомнения . То что вы описываете весьма тривиальная задача при объединении баз.

В итоговую таблицу выгружаются все записи компаний , добавляется bool поле "default" .
По таблице строится дерево значений со связями , например по ИНН , где вершина компания с выставленным значением true в поле "default"

Именно эта компания и используется в дальнейшей работе, остальные связанные компании нужны для уточнения реквизитов и архива документов.
... Хорошо уметь читать между строк. Это иногда
приносит большую пользу
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.