From 2a73be8a57d826cf2f6b11b9f2ffda16eda0b8a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Sch=C3=B6neberg?= Date: Thu, 18 Jul 2019 18:06:01 +0200 Subject: [PATCH] 5364-app - Add Support for additional core fields - add all new properties to the change log - split JsonPersisterService into multiple java files - make sure that if one location or cantact is set to be the default, all others are unset - https://github.com/metasfresh/metasfresh/issues/5364 --- .../bpartner/impl/BpartnerRestController.java | 2 +- .../bpartner/impl/ContactRestController.java | 2 +- .../JsonRetrieverService.java | 30 +- .../bpartnercomposite/JsonServiceFactory.java | 1 + .../JsonPersisterService.java | 518 ++++++++---------- .../jsonpersister/ShortTermContactIndex.java | 161 ++++++ .../jsonpersister/ShortTermLocationIndex.java | 142 +++++ .../utils/MissingResourceException.java | 2 +- .../de/metas/bpartner/composite/BPartner.java | 21 +- .../composite/BPartnerContactType.java | 45 +- .../composite/BPartnerLocationType.java | 22 +- .../bpartner/composite/ChangeLogUtil.java | 47 +- 12 files changed, 656 insertions(+), 337 deletions(-) rename de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/{ => jsonpersister}/JsonPersisterService.java (81%) create mode 100644 de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/jsonpersister/ShortTermContactIndex.java create mode 100644 de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/jsonpersister/ShortTermLocationIndex.java diff --git a/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/BpartnerRestController.java b/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/BpartnerRestController.java index d73657e0c6e..9a97c39636c 100644 --- a/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/BpartnerRestController.java +++ b/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/BpartnerRestController.java @@ -28,8 +28,8 @@ import de.metas.rest_api.SyncAdvise.IfExists; import de.metas.rest_api.SyncAdvise.IfNotExists; import de.metas.rest_api.bpartner.BPartnerRestEndpoint; -import de.metas.rest_api.bpartner.impl.bpartnercomposite.JsonPersisterService; import de.metas.rest_api.bpartner.impl.bpartnercomposite.JsonServiceFactory; +import de.metas.rest_api.bpartner.impl.bpartnercomposite.jsonpersister.JsonPersisterService; import de.metas.rest_api.bpartner.request.JsonRequestBPartnerUpsert; import de.metas.rest_api.bpartner.request.JsonRequestBPartnerUpsertItem; import de.metas.rest_api.bpartner.request.JsonRequestContactUpsert; diff --git a/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/ContactRestController.java b/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/ContactRestController.java index 185efe901e6..825f7af26f7 100644 --- a/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/ContactRestController.java +++ b/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/ContactRestController.java @@ -26,8 +26,8 @@ import de.metas.rest_api.SyncAdvise.IfExists; import de.metas.rest_api.SyncAdvise.IfNotExists; import de.metas.rest_api.bpartner.ContactRestEndpoint; -import de.metas.rest_api.bpartner.impl.bpartnercomposite.JsonPersisterService; import de.metas.rest_api.bpartner.impl.bpartnercomposite.JsonServiceFactory; +import de.metas.rest_api.bpartner.impl.bpartnercomposite.jsonpersister.JsonPersisterService; import de.metas.rest_api.bpartner.request.JsonRequestContactUpsert; import de.metas.rest_api.bpartner.request.JsonRequestContactUpsertItem; import de.metas.rest_api.bpartner.request.JsonResponseUpsert; diff --git a/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/JsonRetrieverService.java b/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/JsonRetrieverService.java index cab467f6974..ec45e455ba8 100644 --- a/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/JsonRetrieverService.java +++ b/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/JsonRetrieverService.java @@ -93,21 +93,21 @@ public class JsonRetrieverService /** Mapping between {@link JsonResponseBPartner} property names and REST-API properties names */ private static final ImmutableMap BPARTNER_FIELD_MAP = ImmutableMap . builder() - .put("value", JsonResponseBPartner.CODE) - .put("companyName", JsonResponseBPartner.COMPANY_NAME) - .put("externalId", JsonResponseBPartner.EXTERNAL_ID) - .put("active", JsonResponseBPartner.ACTIVE) - .put("groupId", JsonResponseBPartner.GROUP) - .put("language", JsonResponseBPartner.LANGUAGE) - .put("id", JsonResponseBPartner.METASFRESH_ID) - .put("name", JsonResponseBPartner.NAME) - .put("name2", JsonResponseBPartner.NAME_2) - .put("name3", JsonResponseBPartner.NAME_3) - .put("parentId", JsonResponseBPartner.PARENT_ID) - .put("phone", JsonResponseBPartner.PHONE) - .put("url", JsonResponseBPartner.URL) - .put("url2", JsonResponseBPartner.URL_2) - .put("url3", JsonResponseBPartner.URL_3) + .put(BPartner.VALUE, JsonResponseBPartner.CODE) + .put(BPartner.COMPANY_NAME, JsonResponseBPartner.COMPANY_NAME) + .put(BPartner.EXTERNAL_ID, JsonResponseBPartner.EXTERNAL_ID) + .put(BPartner.ACTIVE, JsonResponseBPartner.ACTIVE) + .put(BPartner.GROUP_ID, JsonResponseBPartner.GROUP) + .put(BPartner.LANGUAGE, JsonResponseBPartner.LANGUAGE) + .put(BPartner.ID, JsonResponseBPartner.METASFRESH_ID) + .put(BPartner.NAME, JsonResponseBPartner.NAME) + .put(BPartner.NAME_2, JsonResponseBPartner.NAME_2) + .put(BPartner.NAME_3, JsonResponseBPartner.NAME_3) + .put(BPartner.PARENT_ID, JsonResponseBPartner.PARENT_ID) + .put(BPartner.PHONE, JsonResponseBPartner.PHONE) + .put(BPartner.URL, JsonResponseBPartner.URL) + .put(BPartner.URL_2, JsonResponseBPartner.URL_2) + .put(BPartner.URL_3, JsonResponseBPartner.URL_3) .build(); /** Mapping between {@link JsonResponseContact} property names and REST-API properties names */ diff --git a/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/JsonServiceFactory.java b/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/JsonServiceFactory.java index 0c4b3c36db9..2def869f260 100644 --- a/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/JsonServiceFactory.java +++ b/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/JsonServiceFactory.java @@ -6,6 +6,7 @@ import de.metas.bpartner.BPGroupRepository; import de.metas.bpartner.composite.BPartnerCompositeRepository; import de.metas.greeting.GreetingRepository; +import de.metas.rest_api.bpartner.impl.bpartnercomposite.jsonpersister.JsonPersisterService; import de.metas.util.lang.UIDStringUtil; import lombok.NonNull; diff --git a/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/JsonPersisterService.java b/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/jsonpersister/JsonPersisterService.java similarity index 81% rename from de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/JsonPersisterService.java rename to de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/jsonpersister/JsonPersisterService.java index 324543f5be7..c0f862e9356 100644 --- a/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/JsonPersisterService.java +++ b/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/jsonpersister/JsonPersisterService.java @@ -1,13 +1,10 @@ -package de.metas.rest_api.bpartner.impl.bpartnercomposite; +package de.metas.rest_api.bpartner.impl.bpartnercomposite.jsonpersister; import static de.metas.util.Check.assumeNotEmpty; import static de.metas.util.Check.isEmpty; import static de.metas.util.lang.CoalesceUtil.coalesce; -import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Optional; import org.compiere.util.Env; @@ -15,9 +12,7 @@ import de.metas.bpartner.BPGroup; import de.metas.bpartner.BPGroupId; import de.metas.bpartner.BPGroupRepository; -import de.metas.bpartner.BPartnerContactId; import de.metas.bpartner.BPartnerId; -import de.metas.bpartner.BPartnerLocationId; import de.metas.bpartner.composite.BPartner; import de.metas.bpartner.composite.BPartnerComposite; import de.metas.bpartner.composite.BPartnerCompositeRepository; @@ -35,6 +30,7 @@ import de.metas.rest_api.MetasfreshId; import de.metas.rest_api.SyncAdvise; import de.metas.rest_api.SyncAdvise.IfExists; +import de.metas.rest_api.bpartner.impl.bpartnercomposite.JsonRetrieverService; import de.metas.rest_api.bpartner.request.JsonRequestBPartner; import de.metas.rest_api.bpartner.request.JsonRequestComposite; import de.metas.rest_api.bpartner.request.JsonRequestContact; @@ -55,11 +51,9 @@ import de.metas.rest_api.utils.MissingResourceException; import de.metas.user.UserId; import de.metas.util.Services; -import de.metas.util.rest.ExternalId; import lombok.Getter; import lombok.NonNull; import lombok.ToString; -import lombok.Value; /* * #%L @@ -86,167 +80,6 @@ @ToString public class JsonPersisterService { - @Value - private static class ShortTermContactIndex - { - Map id2Contact; - Map externalId2Contact; - - BPartnerId bpartnerId; - BPartnerComposite bpartnerComposite; - - private ShortTermContactIndex(@NonNull final BPartnerComposite bpartnerComposite) - { - this.bpartnerComposite = bpartnerComposite; - this.bpartnerId = bpartnerComposite.getBpartner().getId(); // might be null; we synched to BPartner, but didn't yet save it - - this.id2Contact = new HashMap<>(); - this.externalId2Contact = new HashMap<>(); - - for (final BPartnerContact bpartnerContact : bpartnerComposite.getContacts()) - { - this.id2Contact.put(bpartnerContact.getId(), bpartnerContact); - this.externalId2Contact.put(bpartnerContact.getExternalId(), bpartnerContact); - } - } - - private BPartnerContact extract(@NonNull final IdentifierString contactIdentifier) - { - switch (contactIdentifier.getType()) - { - case METASFRESH_ID: - if (bpartnerId != null) - { - final BPartnerContactId bpartnerLocationId = BPartnerContactId.ofRepoId(bpartnerId, contactIdentifier.asMetasfreshId().getValue()); - return id2Contact.get(bpartnerLocationId); - } - else - { - return null; - } - case EXTERNAL_ID: - return externalId2Contact.get(contactIdentifier.asExternalId()); - default: - throw new InvalidIdentifierException(contactIdentifier.toString()); - } - } - - public void put(IdentifierString contactIdentifier, BPartnerContact contact) - { - switch (contactIdentifier.getType()) - { - case METASFRESH_ID: - if (bpartnerId != null) - { - final BPartnerContactId bpartnerLocationId = BPartnerContactId.ofRepoId(bpartnerId, contactIdentifier.asMetasfreshId().getValue()); - id2Contact.put(bpartnerLocationId, contact); - } - break; - case EXTERNAL_ID: - externalId2Contact.put(contactIdentifier.asExternalId(), contact); - break; - default: - throw new InvalidIdentifierException(contactIdentifier.toString()); - } - } - - private Collection getRemainingContacts() - { - return id2Contact.values(); - } - - private void remove(@NonNull final BPartnerContactId bpartnerContactId) - { - id2Contact.remove(bpartnerContactId); - } - - } - - @Value - private static class ShortTermLocationIndex - { - Map id2Location; - Map externalId2Location; - Map gln2Location; - BPartnerId bpartnerId; - BPartnerComposite bpartnerComposite; - - private ShortTermLocationIndex(@NonNull final BPartnerComposite bpartnerComposite) - { - this.bpartnerComposite = bpartnerComposite; - this.bpartnerId = bpartnerComposite.getBpartner().getId(); // might be null; we synched to BPartner, but didn't yet save it - this.id2Location = new HashMap<>(); - this.externalId2Location = new HashMap<>(); - this.gln2Location = new HashMap<>(); - - for (final BPartnerLocation bpartnerLocation : bpartnerComposite.getLocations()) - { - this.id2Location.put(bpartnerLocation.getId(), bpartnerLocation); - this.externalId2Location.put(bpartnerLocation.getExternalId(), bpartnerLocation); - this.gln2Location.put(bpartnerLocation.getGln(), bpartnerLocation); - } - } - - private BPartnerLocation extract(@NonNull final IdentifierString locationIdentifier) - { - switch (locationIdentifier.getType()) - { - case METASFRESH_ID: - if (bpartnerId != null) - { - final BPartnerLocationId bpartnerLocationId = BPartnerLocationId.ofRepoId(bpartnerId, locationIdentifier.asMetasfreshId().getValue()); - return id2Location.get(bpartnerLocationId); - } - else - { - return null; - } - case GLN: - return gln2Location.get(locationIdentifier.getValue()); - case EXTERNAL_ID: - return externalId2Location.get(locationIdentifier.asExternalId()); - default: - throw new InvalidIdentifierException(locationIdentifier.toString()); - - } - } - - public void put( - @NonNull final IdentifierString locationIdentifier, - @NonNull final BPartnerLocation location) - { - switch (locationIdentifier.getType()) - { - case METASFRESH_ID: - if (bpartnerId != null) - { - final BPartnerLocationId bpartnerLocationId = BPartnerLocationId.ofRepoId(bpartnerId, locationIdentifier.asMetasfreshId().getValue()); - id2Location.put(bpartnerLocationId, location); - } - break; - case GLN: - gln2Location.put(locationIdentifier.getValue(), location); - break; - case EXTERNAL_ID: - externalId2Location.put(locationIdentifier.asExternalId(), location); - break; - default: - throw new InvalidIdentifierException(locationIdentifier.toString()); - - } - - } - - private Collection getRemainingLocations() - { - return id2Location.values(); - } - - private void remove(@NonNull final BPartnerLocationId bpartnerLocationId) - { - id2Location.remove(bpartnerLocationId); - } - } private final transient BPartnerCompositeRepository bpartnerCompositeRepository; @@ -269,35 +102,11 @@ public JsonPersisterService( this.identifier = assumeNotEmpty(identifier, "Param Identifier may not be empty"); } - private BPartnerContactQuery createContactQuery(@NonNull final String contactIdentifierStr) - { - final BPartnerContactQueryBuilder contactQuery = BPartnerContactQuery.builder(); - - final IdentifierString contactIdentifier = IdentifierString.of(contactIdentifierStr); - switch (contactIdentifier.getType()) - { - case EXTERNAL_ID: - contactQuery.externalId(JsonExternalIds.toExternalIdOrNull((contactIdentifier.asJsonExternalId()))); - break; - case METASFRESH_ID: - final UserId userId = UserId.ofRepoIdOrNull(contactIdentifier.asMetasfreshId().getValue()); - contactQuery.userId(userId); - break; - case VALUE: - contactQuery.value(contactIdentifier.getValue()); - break; - default: - throw new InvalidIdentifierException(contactIdentifierStr); - } - return contactQuery.build(); - } - public BPartnerComposite persist( @NonNull final String bpartnerIdentifierStr, @NonNull final JsonRequestComposite jsonBPartnerComposite, @NonNull final SyncAdvise parentSyncAdvise) { - final Optional optionalBPartnerComposite = jsonRetrieverService.retrieveBPartnerComposite(bpartnerIdentifierStr); final SyncAdvise effectiveSyncAdvise = coalesce(jsonBPartnerComposite.getSyncAdvise(), parentSyncAdvise); @@ -373,6 +182,29 @@ public BPartnerContact persist( return contact; } + private BPartnerContactQuery createContactQuery(@NonNull final String contactIdentifierStr) + { + final BPartnerContactQueryBuilder contactQuery = BPartnerContactQuery.builder(); + + final IdentifierString contactIdentifier = IdentifierString.of(contactIdentifierStr); + switch (contactIdentifier.getType()) + { + case EXTERNAL_ID: + contactQuery.externalId(JsonExternalIds.toExternalIdOrNull((contactIdentifier.asJsonExternalId()))); + break; + case METASFRESH_ID: + final UserId userId = UserId.ofRepoIdOrNull(contactIdentifier.asMetasfreshId().getValue()); + contactQuery.userId(userId); + break; + case VALUE: + contactQuery.value(contactIdentifier.getValue()); + break; + default: + throw new InvalidIdentifierException(contactIdentifierStr); + } + return contactQuery.build(); + } + /** Adds or update a given location. Leaves all unrelated location of the same bpartner untouched */ public Optional persistForBPartner( @NonNull final String bpartnerIdentifierStr, @@ -455,69 +287,6 @@ public Optional persistForBPartner( return Optional.of(response.build()); } - private void syncJsonContact( - @NonNull final JsonRequestContactUpsertItem jsonContact, - @NonNull final SyncAdvise parentSyncAdvise, - @NonNull final ShortTermContactIndex shortTermIndex) - { - final IdentifierString contactIdentifier = IdentifierString.of(jsonContact.getContactIdentifier()); - final BPartnerContact existingContact = shortTermIndex.extract(contactIdentifier); - - final BPartnerContact contact; - if (existingContact != null) - { - contact = existingContact; - shortTermIndex.remove(existingContact.getId()); - } - else - { - if (parentSyncAdvise.isFailIfNotExists()) - { - throw new MissingResourceException("Missing contact with identifier=" + jsonContact.getContactIdentifier() + " of type=" + contactIdentifier.getType() + "; sync-advise IfNotExists=" + parentSyncAdvise.getIfNotExists()); - } - else if (Type.METASFRESH_ID.equals(contactIdentifier.getType())) - { - throw new MissingResourceException("Missing contact with identifier=" + jsonContact.getContactIdentifier() + " of type=" + contactIdentifier.getType() + "; with this type, only updates are allowed."); - } - contact = BPartnerContact.builder().build(); - shortTermIndex.getBpartnerComposite().getContacts().add(contact); - shortTermIndex.put(contactIdentifier, contact); - } - syncJsonToContact(jsonContact.getContact(), contact, parentSyncAdvise); - } - - private void syncJsonLocation( - @NonNull final JsonRequestLocationUpsertItem jsonBPartnerLocation, - @NonNull final SyncAdvise parentSyncAdvise, - @NonNull final ShortTermLocationIndex shortTermIndex) - { - final IdentifierString locationIdentifier = IdentifierString.of(jsonBPartnerLocation.getLocationIdentifier()); - final BPartnerLocation existingLocation = shortTermIndex.extract(locationIdentifier); - - final BPartnerLocation location; - if (existingLocation != null) - { - location = existingLocation; - shortTermIndex.remove(existingLocation.getId()); - } - else - { - if (parentSyncAdvise.isFailIfNotExists()) - { - throw new MissingResourceException("Missing location with identifier=" + jsonBPartnerLocation.getLocationIdentifier() + " of type=" + locationIdentifier.getType() + "; sync-advise IfNotExists=" + parentSyncAdvise.getIfNotExists()); - } - else if (Type.METASFRESH_ID.equals(locationIdentifier.getType())) - { - throw new MissingResourceException("Missing location with identifier=" + jsonBPartnerLocation.getLocationIdentifier() + " of type=" + locationIdentifier.getType() + "; with this identifier-type, only updates are allowed."); - } - location = BPartnerLocation.builder().build(); - shortTermIndex.getBpartnerComposite().getLocations().add(location); - shortTermIndex.put(locationIdentifier, location); - } - - syncJsonToLocation(jsonBPartnerLocation.getLocation(), location, parentSyncAdvise); - } - private void syncJsonToBPartnerComposite( @NonNull final JsonRequestComposite jsonBPartnerComposite, @NonNull final BPartnerComposite bpartnerComposite, @@ -527,10 +296,10 @@ private void syncJsonToBPartnerComposite( syncJsonToBPartner(jsonBPartnerComposite, bpartnerComposite, parentSyncAdvise); - syncJsonToLocations(jsonBPartnerComposite, bpartnerComposite, parentSyncAdvise); - syncJsonToContacts(jsonBPartnerComposite, bpartnerComposite, parentSyncAdvise); + syncJsonToLocations(jsonBPartnerComposite, bpartnerComposite, parentSyncAdvise); + bpartnerCompositeRepository.save(bpartnerComposite); } @@ -744,6 +513,128 @@ else if (isUpdateRemove) } } + private void syncJsonToContacts( + @NonNull final JsonRequestComposite jsonBPartnerComposite, + @NonNull final BPartnerComposite bpartnerComposite, + @NonNull final SyncAdvise parentSyncAdvise) + { + final ShortTermContactIndex shortTermIndex = new ShortTermContactIndex(bpartnerComposite); + + final SyncAdvise compositeSyncAdvise = coalesce(jsonBPartnerComposite.getSyncAdvise(), parentSyncAdvise); + + resetDefaultFlagsIfNeeded(jsonBPartnerComposite, shortTermIndex); + + final List contactRequestItems = jsonBPartnerComposite + .getContactsNotNull() + .getRequestItems(); + for (final JsonRequestContactUpsertItem contactRequestItem : contactRequestItems) + { + syncJsonContact(contactRequestItem, compositeSyncAdvise, shortTermIndex); + } + + if (compositeSyncAdvise.getIfExists().isUpdateRemove()) + { + // deactivate the remaining bpartner locations that we did not see + bpartnerComposite.getContacts().removeAll(shortTermIndex.getRemainingContacts()); + } + } + + /** + * If the json contacts have default flags set, then this method unsets all corresponding default flags of the shortTermIndex's {@link BPartnerContact}s. + */ + private void resetDefaultFlagsIfNeeded( + @NonNull final JsonRequestComposite jsonBPartnerComposite, + @NonNull final ShortTermContactIndex shortTermIndex) + { + final List contactRequestItems = jsonBPartnerComposite.getContactsNotNull().getRequestItems(); + + boolean hasDefaultContact = false; + boolean hasBillToDefault = false; + boolean hasShipToDefault = false; + boolean hasPurchaseDefault = false; + boolean hasSalesDefault = false; + for (final JsonRequestContactUpsertItem contactRequestItem : contactRequestItems) + { + final JsonRequestContact contact = contactRequestItem.getContact(); + final Boolean defaultContact = contact.getDefaultContact(); + if (!hasDefaultContact && defaultContact != null && defaultContact) + { + hasDefaultContact = true; + } + final Boolean billToDefault = contact.getBillToDefault(); + if (!hasBillToDefault && billToDefault != null && billToDefault) + { + hasBillToDefault = true; + } + final Boolean shipToDefault = contact.getShipToDefault(); + if (!hasShipToDefault && shipToDefault != null && shipToDefault) + { + hasShipToDefault = true; + } + final Boolean purchaseDefault = contact.getPurchaseDefault(); + if (!hasPurchaseDefault && purchaseDefault != null && purchaseDefault) + { + hasPurchaseDefault = true; + } + final Boolean salesDefault = contact.getSalesDefault(); + if (!hasSalesDefault && salesDefault != null && salesDefault) + { + hasSalesDefault = true; + } + } + if (hasDefaultContact) + { + shortTermIndex.resetDefaultContactFlags(); + } + if (hasBillToDefault) + { + shortTermIndex.resetBillToDefaultFlags(); + } + if (hasShipToDefault) + { + shortTermIndex.resetShipToDefaultFlags(); + } + if (hasPurchaseDefault) + { + shortTermIndex.resetPurchaseDefaultFlags(); + } + if (hasSalesDefault) + { + shortTermIndex.resetSalesDefaultFlags(); + } + } + + private void syncJsonContact( + @NonNull final JsonRequestContactUpsertItem jsonContact, + @NonNull final SyncAdvise parentSyncAdvise, + @NonNull final ShortTermContactIndex shortTermIndex) + { + final IdentifierString contactIdentifier = IdentifierString.of(jsonContact.getContactIdentifier()); + final BPartnerContact existingContact = shortTermIndex.extract(contactIdentifier); + + final BPartnerContact contact; + if (existingContact != null) + { + contact = existingContact; + shortTermIndex.remove(existingContact.getId()); + } + else + { + if (parentSyncAdvise.isFailIfNotExists()) + { + throw new MissingResourceException("Missing contact with identifier=" + jsonContact.getContactIdentifier()) + .setParameter("parentSyncAdvise", parentSyncAdvise); + } + else if (Type.METASFRESH_ID.equals(contactIdentifier.getType())) + { + throw new MissingResourceException("Missing contact with identifier=" + jsonContact.getContactIdentifier() + "; with this type, only updates are allowed.") + .setParameter("parentSyncAdvise", parentSyncAdvise); + } + contact = shortTermIndex.newContact(contactIdentifier); + } + syncJsonToContact(jsonContact.getContact(), contact, parentSyncAdvise); + } + private void syncJsonToContact( @NonNull final JsonRequestContact jsonBPartnerContact, @NonNull final BPartnerContact contact, @@ -871,26 +762,99 @@ else if (isUpdateRemove) contact.setContactType(contactType); } - private void syncJsonToContacts( + private void syncJsonToLocations( @NonNull final JsonRequestComposite jsonBPartnerComposite, @NonNull final BPartnerComposite bpartnerComposite, @NonNull final SyncAdvise parentSyncAdvise) { - final ShortTermContactIndex shortTermIndex = new ShortTermContactIndex(bpartnerComposite); + final ShortTermLocationIndex shortTermIndex = new ShortTermLocationIndex(bpartnerComposite); - final SyncAdvise compositeSyncAdvise = coalesce(jsonBPartnerComposite.getSyncAdvise(), parentSyncAdvise); + final SyncAdvise syncAdvise = coalesce(jsonBPartnerComposite.getSyncAdvise(), parentSyncAdvise); + + resetDefaultFlagsIfNeeded(jsonBPartnerComposite, shortTermIndex); + + final List locationRequestItems = jsonBPartnerComposite + .getLocationsNotNull() + .getRequestItems(); - final List requestItems = jsonBPartnerComposite.getContactsNotNull().getRequestItems(); - for (final JsonRequestContactUpsertItem requestItem : requestItems) + for (final JsonRequestLocationUpsertItem locationRequestItem : locationRequestItems) { - syncJsonContact(requestItem, compositeSyncAdvise, shortTermIndex); + syncJsonLocation(locationRequestItem, syncAdvise, shortTermIndex); } - if (compositeSyncAdvise.getIfExists().isUpdateRemove()) + if (syncAdvise.getIfExists().isUpdateRemove()) { // deactivate the remaining bpartner locations that we did not see - bpartnerComposite.getContacts().removeAll(shortTermIndex.getRemainingContacts()); + bpartnerComposite.getLocations().removeAll(shortTermIndex.getRemainingLocations()); + } + } + + /** + * If the json locations have default flags set, then this method unsets all corresponding default flags of the shortTermIndex's {@link BPartnerLocation}s. + */ + private void resetDefaultFlagsIfNeeded( + @NonNull final JsonRequestComposite jsonBPartnerComposite, + @NonNull final ShortTermLocationIndex shortTermIndex) + { + boolean hasBillToDefault = false; + boolean hasShipToDefault = false; + + final List locationRequestItems = jsonBPartnerComposite + .getLocationsNotNull() + .getRequestItems(); + for (final JsonRequestLocationUpsertItem locationRequestItem : locationRequestItems) + { + final JsonRequestLocation location = locationRequestItem.getLocation(); + final Boolean billToDefault = location.getBillToDefault(); + if (!hasBillToDefault && billToDefault != null && billToDefault) + { + hasBillToDefault = true; + } + final Boolean shipToDefault = location.getShipToDefault(); + if (!hasShipToDefault && shipToDefault != null && shipToDefault) + { + hasShipToDefault = true; + } + } + if (hasBillToDefault) + { + shortTermIndex.resetBillToDefaultFlags(); + } + if (hasShipToDefault) + { + shortTermIndex.resetShipToDefaultFlags(); + } + } + + private void syncJsonLocation( + @NonNull final JsonRequestLocationUpsertItem jsonBPartnerLocation, + @NonNull final SyncAdvise parentSyncAdvise, + @NonNull final ShortTermLocationIndex shortTermIndex) + { + final IdentifierString locationIdentifier = IdentifierString.of(jsonBPartnerLocation.getLocationIdentifier()); + final BPartnerLocation existingLocation = shortTermIndex.extract(locationIdentifier); + + final BPartnerLocation location; + if (existingLocation != null) + { + location = existingLocation; + shortTermIndex.remove(existingLocation.getId()); + } + else + { + if (parentSyncAdvise.isFailIfNotExists()) + { + throw new MissingResourceException("Missing location with identifier=" + jsonBPartnerLocation.getLocationIdentifier() + " of type=" + locationIdentifier.getType() + "; sync-advise IfNotExists=" + parentSyncAdvise.getIfNotExists()); + } + else if (Type.METASFRESH_ID.equals(locationIdentifier.getType())) + { + throw new MissingResourceException("Missing location with identifier=" + jsonBPartnerLocation.getLocationIdentifier() + " of type=" + locationIdentifier.getType() + "; with this identifier-type, only updates are allowed."); + } + + location = shortTermIndex.newLocation(locationIdentifier); } + + syncJsonToLocation(jsonBPartnerLocation.getLocation(), location, parentSyncAdvise); } private void syncJsonToLocation( @@ -1046,26 +1010,4 @@ else if (isUpdateRemove) .build(); location.setLocationType(locationType); } - - private void syncJsonToLocations( - @NonNull final JsonRequestComposite jsonBPartnerComposite, - @NonNull final BPartnerComposite bpartnerComposite, - @NonNull final SyncAdvise parentSyncAdvise) - { - final ShortTermLocationIndex shortTermIndex = new ShortTermLocationIndex(bpartnerComposite); - - final SyncAdvise syncAdvise = coalesce(jsonBPartnerComposite.getSyncAdvise(), parentSyncAdvise); - - final List requestItems = jsonBPartnerComposite.getLocationsNotNull().getRequestItems(); - for (final JsonRequestLocationUpsertItem requestItem : requestItems) - { - syncJsonLocation(requestItem, syncAdvise, shortTermIndex); - } - - if (syncAdvise.getIfExists().isUpdateRemove()) - { - // deactivate the remaining bpartner locations that we did not see - bpartnerComposite.getLocations().removeAll(shortTermIndex.getRemainingLocations()); - } - } } diff --git a/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/jsonpersister/ShortTermContactIndex.java b/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/jsonpersister/ShortTermContactIndex.java new file mode 100644 index 00000000000..801d67606a4 --- /dev/null +++ b/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/jsonpersister/ShortTermContactIndex.java @@ -0,0 +1,161 @@ +package de.metas.rest_api.bpartner.impl.bpartnercomposite.jsonpersister; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import de.metas.bpartner.BPartnerContactId; +import de.metas.bpartner.BPartnerId; +import de.metas.bpartner.composite.BPartnerComposite; +import de.metas.bpartner.composite.BPartnerContact; +import de.metas.rest_api.utils.IdentifierString; +import de.metas.rest_api.utils.InvalidIdentifierException; +import de.metas.util.rest.ExternalId; +import lombok.NonNull; +import lombok.Value; + +/* + * #%L + * de.metas.business.rest-api-impl + * %% + * Copyright (C) 2019 metas GmbH + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +@Value +public class ShortTermContactIndex +{ + Map id2Contact; + Map externalId2Contact; + + BPartnerId bpartnerId; + BPartnerComposite bpartnerComposite; + + public ShortTermContactIndex(@NonNull final BPartnerComposite bpartnerComposite) + { + this.bpartnerComposite = bpartnerComposite; + this.bpartnerId = bpartnerComposite.getBpartner().getId(); // might be null; we synched to BPartner, but didn't yet save it + + this.id2Contact = new HashMap<>(); + this.externalId2Contact = new HashMap<>(); + + for (final BPartnerContact bpartnerContact : bpartnerComposite.getContacts()) + { + this.id2Contact.put(bpartnerContact.getId(), bpartnerContact); + this.externalId2Contact.put(bpartnerContact.getExternalId(), bpartnerContact); + } + } + + public BPartnerContact extract(@NonNull final IdentifierString contactIdentifier) + { + switch (contactIdentifier.getType()) + { + case METASFRESH_ID: + if (bpartnerId != null) + { + final BPartnerContactId bpartnerLocationId = BPartnerContactId.ofRepoId(bpartnerId, contactIdentifier.asMetasfreshId().getValue()); + return id2Contact.get(bpartnerLocationId); + } + else + { + return null; + } + case EXTERNAL_ID: + return externalId2Contact.get(contactIdentifier.asExternalId()); + default: + throw new InvalidIdentifierException(contactIdentifier.toString()); + } + } + + public BPartnerContact newContact(@NonNull final IdentifierString contactIdentifier) + { + final BPartnerContact contact = BPartnerContact.builder().build(); + + switch (contactIdentifier.getType()) + { + case METASFRESH_ID: + if (bpartnerId != null) + { + final BPartnerContactId bpartnerLocationId = BPartnerContactId.ofRepoId(bpartnerId, contactIdentifier.asMetasfreshId().getValue()); + id2Contact.put(bpartnerLocationId, contact); + } + break; + case EXTERNAL_ID: + externalId2Contact.put(contactIdentifier.asExternalId(), contact); + break; + default: + throw new InvalidIdentifierException(contactIdentifier.toString()); + } + + bpartnerComposite + .getContacts() + .add(contact); + + return contact; + } + + public Collection getRemainingContacts() + { + return id2Contact.values(); + } + + public void remove(@NonNull final BPartnerContactId bpartnerContactId) + { + id2Contact.remove(bpartnerContactId); + } + + public void resetDefaultContactFlags() + { + for (final BPartnerContact bpartnerContact : bpartnerComposite.getContacts()) + { + bpartnerContact.getContactType().setDefaultContact(false); + } + } + + public void resetShipToDefaultFlags() + { + for (final BPartnerContact bpartnerContact : bpartnerComposite.getContacts()) + { + bpartnerContact.getContactType().setShipToDefault(false); + } + + } + + public void resetPurchaseDefaultFlags() + { + for (final BPartnerContact bpartnerContact : bpartnerComposite.getContacts()) + { + bpartnerContact.getContactType().setPurchaseDefault(false); + } + } + + public void resetSalesDefaultFlags() + { + for (final BPartnerContact bpartnerContact : bpartnerComposite.getContacts()) + { + bpartnerContact.getContactType().setSalesDefault(false); + } + } + + public void resetBillToDefaultFlags() + { + for (final BPartnerContact bpartnerContact : bpartnerComposite.getContacts()) + { + bpartnerContact.getContactType().setBillToDefault(false); + } + } +} diff --git a/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/jsonpersister/ShortTermLocationIndex.java b/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/jsonpersister/ShortTermLocationIndex.java new file mode 100644 index 00000000000..6e015fcbb03 --- /dev/null +++ b/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/bpartner/impl/bpartnercomposite/jsonpersister/ShortTermLocationIndex.java @@ -0,0 +1,142 @@ +package de.metas.rest_api.bpartner.impl.bpartnercomposite.jsonpersister; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import de.metas.bpartner.BPartnerId; +import de.metas.bpartner.BPartnerLocationId; +import de.metas.bpartner.composite.BPartnerComposite; +import de.metas.bpartner.composite.BPartnerLocation; +import de.metas.rest_api.utils.IdentifierString; +import de.metas.rest_api.utils.InvalidIdentifierException; +import de.metas.util.rest.ExternalId; +import lombok.NonNull; +import lombok.Value; + +/* + * #%L + * de.metas.business.rest-api-impl + * %% + * Copyright (C) 2019 metas GmbH + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +@Value +public class ShortTermLocationIndex +{ + Map id2Location; + Map externalId2Location; + Map gln2Location; + BPartnerId bpartnerId; + BPartnerComposite bpartnerComposite; + + public ShortTermLocationIndex(@NonNull final BPartnerComposite bpartnerComposite) + { + this.bpartnerComposite = bpartnerComposite; + this.bpartnerId = bpartnerComposite.getBpartner().getId(); // might be null; we synched to BPartner, but didn't yet save it + this.id2Location = new HashMap<>(); + this.externalId2Location = new HashMap<>(); + this.gln2Location = new HashMap<>(); + + for (final BPartnerLocation bpartnerLocation : bpartnerComposite.getLocations()) + { + this.id2Location.put(bpartnerLocation.getId(), bpartnerLocation); + this.externalId2Location.put(bpartnerLocation.getExternalId(), bpartnerLocation); + this.gln2Location.put(bpartnerLocation.getGln(), bpartnerLocation); + } + } + + public BPartnerLocation extract(@NonNull final IdentifierString locationIdentifier) + { + switch (locationIdentifier.getType()) + { + case METASFRESH_ID: + if (bpartnerId != null) + { + final BPartnerLocationId bpartnerLocationId = BPartnerLocationId.ofRepoId(bpartnerId, locationIdentifier.asMetasfreshId().getValue()); + return id2Location.get(bpartnerLocationId); + } + else + { + return null; + } + case GLN: + return gln2Location.get(locationIdentifier.getValue()); + case EXTERNAL_ID: + return externalId2Location.get(locationIdentifier.asExternalId()); + default: + throw new InvalidIdentifierException(locationIdentifier.toString()); + + } + } + + public BPartnerLocation newLocation(@NonNull final IdentifierString locationIdentifier) + { + final BPartnerLocation location = BPartnerLocation.builder().build(); + + switch (locationIdentifier.getType()) + { + case METASFRESH_ID: + if (bpartnerId != null) + { + final BPartnerLocationId bpartnerLocationId = BPartnerLocationId.ofRepoId(bpartnerId, locationIdentifier.asMetasfreshId().getValue()); + id2Location.put(bpartnerLocationId, location); + } + break; + case GLN: + gln2Location.put(locationIdentifier.getValue(), location); + break; + case EXTERNAL_ID: + externalId2Location.put(locationIdentifier.asExternalId(), location); + break; + default: + throw new InvalidIdentifierException(locationIdentifier.toString()); + } + + bpartnerComposite + .getLocations() + .add(location); + return location; + } + + public Collection getRemainingLocations() + { + return id2Location.values(); + } + + public void remove(@NonNull final BPartnerLocationId bpartnerLocationId) + { + id2Location.remove(bpartnerLocationId); + } + + public void resetBillToDefaultFlags() + { + for (final BPartnerLocation bpartnerLocation : bpartnerComposite.getLocations()) + { + bpartnerLocation.getLocationType().setBillToDefault(false); + } + } + + public void resetShipToDefaultFlags() + { + for (final BPartnerLocation bpartnerLocation : bpartnerComposite.getLocations()) + { + bpartnerLocation.getLocationType().setShipToDefault(false); + } + } +} diff --git a/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/utils/MissingResourceException.java b/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/utils/MissingResourceException.java index 45559d683a6..bb9bb944fe2 100644 --- a/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/utils/MissingResourceException.java +++ b/de.metas.business.rest-api-impl/src/main/java/de/metas/rest_api/utils/MissingResourceException.java @@ -43,7 +43,7 @@ public MissingResourceException( @NonNull final String resourceName, @Nullable final Object parentResource) { - super(assumeNotEmpty(resourceName, "Parameter 'resourceName may not be null")); + super(assumeNotEmpty(resourceName, "Parameter 'resourceName' may not be empty")); appendParametersToMessage(); if (parentResource != null) diff --git a/de.metas.business/src/main/java/de/metas/bpartner/composite/BPartner.java b/de.metas.business/src/main/java/de/metas/bpartner/composite/BPartner.java index da00f60ec83..d63a0ee17c5 100644 --- a/de.metas.business/src/main/java/de/metas/bpartner/composite/BPartner.java +++ b/de.metas.business/src/main/java/de/metas/bpartner/composite/BPartner.java @@ -43,19 +43,30 @@ @Data public class BPartner { + public static final String ID = "id"; + public static final String EXTERNAL_ID = "externalId"; + public static final String ACTIVE = "active"; + public static final String NAME = "name"; + public static final String NAME_2 = "name2"; + public static final String NAME_3 = "name3"; + public static final String COMPANY_NAME = "companyName"; + public static final String PARENT_ID = "parentId"; + public static final String VALUE = "value"; + public static final String PHONE = "phone"; + public static final String LANGUAGE = "language"; + public static final String URL = "url"; + public static final String URL_2 = "url2"; + public static final String URL_3 = "url3"; + public static final String GROUP_ID = "groupId"; + /** May be null if the bpartner was not yet saved. */ private BPartnerId id; private ExternalId externalId; - private boolean active; - private String value; - private String name; - private String name2; - private String name3; /** non-empty value implies that the bpartner is also a company */ diff --git a/de.metas.business/src/main/java/de/metas/bpartner/composite/BPartnerContactType.java b/de.metas.business/src/main/java/de/metas/bpartner/composite/BPartnerContactType.java index db08b054da3..ba17834f68c 100644 --- a/de.metas.business/src/main/java/de/metas/bpartner/composite/BPartnerContactType.java +++ b/de.metas.business/src/main/java/de/metas/bpartner/composite/BPartnerContactType.java @@ -10,8 +10,8 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import lombok.Builder; +import lombok.Data; import lombok.NonNull; -import lombok.Value; /* * #%L @@ -35,32 +35,32 @@ * #L% */ -@Value +@Data public class BPartnerContactType { @JsonInclude(Include.NON_ABSENT) - Optional defaultContact; + private Optional defaultContact; @JsonInclude(Include.NON_ABSENT) - Optional billToDefault; + private Optional billToDefault; @JsonInclude(Include.NON_ABSENT) - Optional shipToDefault; + private Optional shipToDefault; @JsonInclude(Include.NON_ABSENT) - Optional sales; + private final Optional sales; @JsonInclude(Include.NON_ABSENT) - Optional salesDefault; + private Optional salesDefault; @JsonInclude(Include.NON_ABSENT) - Optional purchase; + private final Optional purchase; @JsonInclude(Include.NON_ABSENT) - Optional purchaseDefault; + private Optional purchaseDefault; @JsonInclude(Include.NON_ABSENT) - Optional subjectMatter; + private final Optional subjectMatter; @Builder public BPartnerContactType( @@ -154,4 +154,29 @@ private AdempiereException createException(@NonNull final String message) .appendParametersToMessage() .setParameter("contactLocationType", this); } + + public void setDefaultContact(final boolean defaultContact) + { + this.defaultContact = Optional.of(defaultContact); + } + + public void setBillToDefault(final boolean billToDefault) + { + this.billToDefault = Optional.of(billToDefault); + } + + public void setShipToDefault(final boolean shipToDefault) + { + this.shipToDefault = Optional.of(shipToDefault); + } + + public void setPurchaseDefault(final boolean purchaseDefault) + { + this.purchaseDefault = Optional.of(purchaseDefault); + } + + public void setSalesDefault(final boolean salesDefault) + { + this.salesDefault = Optional.of(salesDefault); + } } diff --git a/de.metas.business/src/main/java/de/metas/bpartner/composite/BPartnerLocationType.java b/de.metas.business/src/main/java/de/metas/bpartner/composite/BPartnerLocationType.java index 486b72fc16d..edbffe82d45 100644 --- a/de.metas.business/src/main/java/de/metas/bpartner/composite/BPartnerLocationType.java +++ b/de.metas.business/src/main/java/de/metas/bpartner/composite/BPartnerLocationType.java @@ -10,8 +10,8 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import lombok.Builder; +import lombok.Data; import lombok.NonNull; -import lombok.Value; /* * #%L @@ -35,20 +35,20 @@ * #L% */ -@Value +@Data public class BPartnerLocationType { @JsonInclude(Include.NON_ABSENT) - Optional billTo; + private final Optional billTo; @JsonInclude(Include.NON_ABSENT) - Optional billToDefault; + private Optional billToDefault; @JsonInclude(Include.NON_ABSENT) - Optional shipTo; + private final Optional shipTo; @JsonInclude(Include.NON_ABSENT) - Optional shipToDefault; + private Optional shipToDefault; @Builder public BPartnerLocationType( @@ -108,4 +108,14 @@ private AdempiereException createException(@NonNull final String message) .appendParametersToMessage() .setParameter("bpartnerLocationType", this); } + + public void setBillToDefault(boolean billToDefault) + { + this.billToDefault = Optional.of(billToDefault); + } + + public void setShipToDefault(boolean shipToDefault) + { + this.shipToDefault = Optional.of(shipToDefault); + } } diff --git a/de.metas.business/src/main/java/de/metas/bpartner/composite/ChangeLogUtil.java b/de.metas.business/src/main/java/de/metas/bpartner/composite/ChangeLogUtil.java index 727372d1bb9..46db36155c8 100644 --- a/de.metas.business/src/main/java/de/metas/bpartner/composite/ChangeLogUtil.java +++ b/de.metas.business/src/main/java/de/metas/bpartner/composite/ChangeLogUtil.java @@ -55,16 +55,21 @@ public class ChangeLogUtil private static final ImmutableMap BPARTNER_COLUMN_MAP = ImmutableMap . builder() - .put(I_C_BPartner.COLUMNNAME_Value, "value") - .put(I_C_BPartner.COLUMNNAME_CompanyName, "companyName") - .put(I_C_BPartner.COLUMNNAME_ExternalId, "externalId") - .put(I_C_BPartner.COLUMNNAME_C_BP_Group_ID, "groupId") - .put(I_C_BPartner.COLUMNNAME_AD_Language, "language") - .put(I_C_BPartner.COLUMNNAME_C_BPartner_ID, "id") - .put(I_C_BPartner.COLUMNNAME_Name, "name") - .put(I_C_BPartner.COLUMNNAME_BPartner_Parent_ID, "parentId") - .put(I_C_BPartner.COLUMNNAME_Phone2, "phone") - .put(I_C_BPartner.COLUMNNAME_URL, "url") + .put(I_C_BPartner.COLUMNNAME_Value, BPartner.VALUE) + .put(I_C_BPartner.COLUMNNAME_CompanyName, BPartner.COMPANY_NAME) + .put(I_C_BPartner.COLUMNNAME_ExternalId, BPartner.EXTERNAL_ID) + .put(I_C_BPartner.COLUMNNAME_C_BP_Group_ID, BPartner.GROUP_ID) + .put(I_C_BPartner.COLUMNNAME_AD_Language, BPartner.LANGUAGE) + .put(I_C_BPartner.COLUMNNAME_C_BPartner_ID, BPartner.ID) + .put(I_C_BPartner.COLUMNNAME_Name, BPartner.NAME) + .put(I_C_BPartner.COLUMNNAME_Name2, BPartner.NAME_2) + .put(I_C_BPartner.COLUMNNAME_Name3, BPartner.NAME_3) + .put(I_C_BPartner.COLUMNNAME_BPartner_Parent_ID, BPartner.PARENT_ID) + .put(I_C_BPartner.COLUMNNAME_Phone2, BPartner.PHONE) + .put(I_C_BPartner.COLUMNNAME_URL, BPartner.URL) + .put(I_C_BPartner.COLUMNNAME_URL2, BPartner.URL_2) + .put(I_C_BPartner.COLUMNNAME_URL3, BPartner.URL_3) + .put(I_C_BPartner.COLUMNNAME_IsActive, BPartner.ACTIVE) .build(); private static final ImmutableMap AD_USER_COLUMN_MAP = ImmutableMap @@ -76,12 +81,28 @@ public class ChangeLogUtil .put(I_AD_User.COLUMNNAME_Lastname, "lastName") .put(I_AD_User.COLUMNNAME_Name, "name") .put(I_AD_User.COLUMNNAME_Phone, "phone") + .put(I_AD_User.COLUMNNAME_IsDefaultContact, "defaultContact") + .put(I_AD_User.COLUMNNAME_IsBillToContact_Default, "billToDefault") + .put(I_AD_User.COLUMNNAME_IsShipToContact_Default, "shipToDefault") + .put(I_AD_User.COLUMNNAME_IsSalesContact, "sales") + .put(I_AD_User.COLUMNNAME_IsSalesContact_Default, "salesDefault") + .put(I_AD_User.COLUMNNAME_IsPurchaseContact, "purchase") + .put(I_AD_User.COLUMNNAME_IsPurchaseContact_Default, "purchaseDefault") + .put(I_AD_User.COLUMNNAME_IsSubjectMatterContact, "subjectMatter") + .put(I_AD_User.COLUMNNAME_IsActive, "active") + .put(I_AD_User.COLUMNNAME_IsNewsletter, "newsletter") + .put(I_AD_User.COLUMNNAME_Fax, "fax") + .put(I_AD_User.COLUMNNAME_MobilePhone, "mobilePhone") + .put(I_AD_User.COLUMNNAME_Description, "description") + .put(I_AD_User.COLUMNNAME_C_Greeting_ID, "greetingId") .build(); private static final ImmutableMap C_LOCATION_COLUMN_MAP = ImmutableMap . builder() .put(I_C_Location.COLUMNNAME_Address1, "address1") .put(I_C_Location.COLUMNNAME_Address2, "address2") + .put(I_C_Location.COLUMNNAME_Address3, "address3") + .put(I_C_Location.COLUMNNAME_Address4, "address4") .put(I_C_Location.COLUMNNAME_City, "city") .put(I_C_Location.COLUMNNAME_POBox, "poBox") .put(I_C_Location.COLUMNNAME_Postal, "postal") @@ -93,6 +114,12 @@ public class ChangeLogUtil .put(I_C_BPartner_Location.COLUMNNAME_ExternalId, "externalId") .put(I_C_BPartner_Location.COLUMNNAME_GLN, "gln") .put(I_C_BPartner_Location.COLUMNNAME_C_BPartner_Location_ID, "id") + .put(I_C_BPartner_Location.COLUMNNAME_Name, "name") + .put(I_C_BPartner_Location.COLUMNNAME_IsBillToDefault, "billToDefault") + .put(I_C_BPartner_Location.COLUMNNAME_IsShipToDefault, "shipToDefault") + .put(I_C_BPartner_Location.COLUMNNAME_IsBillTo, "billTo") + .put(I_C_BPartner_Location.COLUMNNAME_IsShipTo, "shipTo") + .put(I_C_BPartner_Location.COLUMNNAME_IsActive, "active") .build(); private static final ImmutableMap C_POSTAL_COLUMN_MAP = ImmutableMap