Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Internal] Shopify Contributions #26819

Open
JesperSchulz opened this issue Jul 10, 2024 · 3 comments · Fixed by #26185, #26216, #26708, #26712 or #26728
Open

[Internal] Shopify Contributions #26819

JesperSchulz opened this issue Jul 10, 2024 · 3 comments · Fixed by #26185, #26216, #26708, #26712 or #26728
Labels
approved The issue is approved Integration GitHub request for Integration area

Comments

@JesperSchulz
Copy link
Contributor

JesperSchulz commented Jul 10, 2024

Placeholder issue for work on the Shopify connector.

@JesperSchulz JesperSchulz added bcidea Issue is created based on a BC Idea approved The issue is approved and removed bcidea Issue is created based on a BC Idea labels Jul 10, 2024
onbuyuka pushed a commit that referenced this issue Jul 29, 2024
This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

Quick summary:

The Shopify Shipping Method Mapping page/table was extended to include a
new Shipping Charges Type field, allowing users to select from GL, Item,
or Item Charge. Depending on this selection, the Shipping Charges No.
field opens the related table (item, GL, or item charges), and when an
order is created, the shipping charge line reflects the new type and
number. For Item Charges, a default allocation process is run for all
item lines. The settings in the Shopify Shipping Method Mapping now take
priority over those in the Shopify Shop - GL Account settings.
Additionally, if the Shipping Agent Code and Shipping Agent Service
fields are populated, they are automatically populated in the sales
order as well.

Fixes #26819

[AB#449477](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/449477)

---------

Co-authored-by: aidasberesinevicius <[email protected]>
Co-authored-by: Tine Staric <[email protected]>
@onbuyuka onbuyuka reopened this Jul 30, 2024
onbuyuka added a commit that referenced this issue Aug 1, 2024
This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

Added an action to Variants subpage to add BC Items as additional
Variants to an existing Shopify Product.
If the parent product only had a default variant before the addition, it
is deleted from both Shopify and BC.
The variants are added under the existing the Product Option (ex. Color,
Material, or Title, if product only had the default variant)

Items cannot be added if the shop has "UOM as Variant" enabled, or if
the parent product has more than one option defined.

Fixes #26819
Fixes
[AB#468218](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/468218)

---------

Co-authored-by: Tine Staric <[email protected]>
Co-authored-by: Jesper Schulz-Wedde <[email protected]>
Co-authored-by: Onat Buyukakkus <[email protected]>
@JesperSchulz JesperSchulz reopened this Aug 5, 2024
@JesperSchulz
Copy link
Contributor Author

This one is still needed, as further open PRs exist.

@JesperSchulz
Copy link
Contributor Author

More PRs coming. Reopening.

@JesperSchulz JesperSchulz reopened this Aug 20, 2024
@JesperSchulz JesperSchulz reopened this Aug 23, 2024
JesperSchulz added a commit that referenced this issue Aug 23, 2024
…rs (#26748)

This pull request does not have a related issue as it's part of the
delivery for development agreed directly
with [@AndreiPanko](https://github.com/AndreiPanko)

Here's a quick summary:

### Created a report to export Posted Sales Invoices to Shopify as
Orders.

Shopify Shop has a **new action "Payment Terms Mapping"** that takes the
user to the **new page "Shopify Payment Terms Mapping"**. Shopify
Payment Terms cannot be manually inserted or deleted, they can only be
refreshed with an action that pulls them from Shopify. By default
**FIXED** Payment Term is selected as primary during the synchronization
of the Payment Terms.
Before Posted Sales Invoices can be synced, a payment term code from
Shopify needs to be mapped to the Business Central one or a primary
Shopify Payment Term needs to be selected with a Boolean "Is Primary" -
this payment term will be used if the Posted Sales Invoice payment terms
code doesn't have a mapping to Shopify. This payment term code will also
be filled during the sync of Shopify orders.
  
A new Scope is required. To update payment terms on a draft order –
write_payment_terms (read_payment_terms scope was removed because it
causes strange behavior - every time a Shopify shop card is opened it
states that the scope has changed and requires authorization.
write_payment_terms overwrites read_payment_terms). To create a draft
order - write_draft_orders.

### To export Posted Sales Invoices, here are some conditions that they
need to meet:

- The **new Boolean field "Posted Invoice Sync"** needs to be enabled.
- The "Shopify Order Id" field on the Posted Sales Invoice needs to be
0.
- Posted Sales Invoice "Bill-To Customer" has been mapped to the Shopify
Customer or Shopify Companies table.
- Posted Sales Invoice "Bill-To Customer" is not a customer used as a
Default Customer in the Shopify Shop Card or Shopify Customer Template.
- There are no lines of type non-comment (or type is populated but No.
is empty).
- There are no fraction quantities.
- There must be a mapped Payment Terms Code or a selected Primary
Payment Terms Code on the new "Shopify Payment Terms Mapping" page.
- If there is at least one line of type "Item" where the selected
item/variant doesn’t have a link to Shopify Product/Shopify variant and
the **new Boolean field "Items must be mapped to Products"** on the
Shopify Shop card is selected - the Posted Sales Invoice will not be
exported.
- Posted Sales Invoice currency code matches Shopify shop currency code
(explanation at the bottom).

If one of the previous conditions is not met, the Posted Sales Invoice
"Shopify Order Id" field will be marked with -2. If the GraphQL request
fails, then the field will be marked with -1. If everything goes
correctly, the field will be filled with the created Shopify Order ID.
Users can modify the "Shopify Order Id" field in the posted document
(allowed changes from -1 or -2 to 0. The functionality works the same as
in the Update Posted Shipment document.)
 
This export can be executed with a new action that is added to Shopify
Shop - "Sync Posted Sales Invoices" or just by running the report "Sync
Invoices to Shopify". The draft order in Shopify is created with the
values from the Posted Sales Invoice order and lines. If the Remaining
Amount of the Posted Sales Invoice is 0, then the order is marked as
paid, otherwise, the status will be "Payment pending" and a mapped
Payment Terms code will be sent out. After that, the created draft order
will be completed and the Shopify order created. All orders are
automatically fulfilled. To achieve “paid” status on the Shopify order –
use the Manual payment function in the Shopify Order card. Once the
report is executed, the Inventory will be synced.

Order sync will import created orders, then check if the order is
present in the **new Shopify Invoice Header table** (this table is
filled with the Shopify order ID of the exported Posted Sales Invoice)
and if so:
- Shopify Order is marked as processed.
- A link is added to the Posted Sales Invoice (related documents).

### A few details about the mapping of the values and some additional
functionality:
- All non-comment type lines are exported as custom products (including
Items if the new Boolean field "Items must be mapped to Products"** on
the Shopify Shop card is not selected).
- Taxes from the lines are sent out as a custom product with the title
consisting of "VAT Calculation Type" + VAT %.
- Invoice discounts from the lines and the header are added up and sent
out as a discount to the whole order with the title "Invoice Discount
Amount"
- Posted Sales Invoice comments are exported as notes.
- Once the draft order is completed, an order confirmation email will be
sent out to the customer. This functionality is from Shopify itself.
- If the product/variant exists in Shopify, the price, title and other
information will be taken from Shopify and not the one in the Posted
Sales Invoice line. This is how the draftOrderCreate mutation works.

### Out of scope functionalities:
- Open orders and open invoices.
- Fulfillment/Tracking Details.
- Refund / partial refund status.
- Weight export.

**Known issues with different currencies (that's why Posted Sales
Invoices with different currencies than Shopify Shop cannot be exported
at the moment):**
- Currently sending out different currencies than the Shopify Shop
currency cannot be done because if the currency of the custom product
differs from the Shopify shop's currency, the amount sent will still be
accepted in the local Shopify shop's currency before being converted to
the order's currency and the amount will be incorrect. For example, if
the VAT amount is 100 GBP, but the Shopify shop's currency is EUR, the
custom product will be exported with an amount of 100 GBP. However, this
amount will be treated as 100 EUR and then converted to GBP according to
the currency exchange rate in Shopify.

Fixes #26819
Fixes
[AB#446399](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/446399)

---------

Co-authored-by: Jesper Schulz-Wedde <[email protected]>
Co-authored-by: Tine Staric <[email protected]>
aholstrup1 pushed a commit to aholstrup1/ALAppExtensions that referenced this issue Sep 6, 2024
Move the BCPT sample tests to
https://github.com/microsoft/BusinessCentralApps/tree/main/App/Layers/W1/Tests/BCPT-SampleTests.

Syncing with version 25.0.21703.0 (microsoft#26811)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

---------

Co-authored-by: Alexander Holstrup <[email protected]>

[Shopify] Shopify return location on refunds (microsoft#26728)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

Added a setting to the shopify shop to use original return location
(From shopify) or a default return location set in the Shopify shop when
creating Credit Memos for Refunds.

Modified the return and refund creation to pull original location from
shopify refund or return orders.
When an item on a single return order in shopify is restocked to
multiple locations, we cannot determine a single location to put on a
return line.

If there is any reason that Original location couldn't be determined
then the Default Return Location will be used during the creation of a
Credit Memo.

Fixes microsoft#26819

Fixes
[AB#540965](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/540965)

---------

Co-authored-by: Tine Staric <[email protected]>

[Shopify] Connector - Different shipping charges types (microsoft#26708)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

Quick summary:

The Shopify Shipping Method Mapping page/table was extended to include a
new Shipping Charges Type field, allowing users to select from GL, Item,
or Item Charge. Depending on this selection, the Shipping Charges No.
field opens the related table (item, GL, or item charges), and when an
order is created, the shipping charge line reflects the new type and
number. For Item Charges, a default allocation process is run for all
item lines. The settings in the Shopify Shipping Method Mapping now take
priority over those in the Shopify Shop - GL Account settings.
Additionally, if the Shipping Agent Code and Shipping Agent Service
fields are populated, they are automatically populated in the sales
order as well.

Fixes microsoft#26819

[AB#449477](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/449477)

---------

Co-authored-by: aidasberesinevicius <[email protected]>
Co-authored-by: Tine Staric <[email protected]>

[Shopify] Add items as product variants (microsoft#26712)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

Added an action to Variants subpage to add BC Items as additional
Variants to an existing Shopify Product.
If the parent product only had a default variant before the addition, it
is deleted from both Shopify and BC.
The variants are added under the existing the Product Option (ex. Color,
Material, or Title, if product only had the default variant)

Items cannot be added if the shop has "UOM as Variant" enabled, or if
the parent product has more than one option defined.

Fixes microsoft#26819
Fixes
[AB#468218](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/468218)

---------

Co-authored-by: Tine Staric <[email protected]>
Co-authored-by: Jesper Schulz-Wedde <[email protected]>
Co-authored-by: Onat Buyukakkus <[email protected]>

Update Yavrio in ConnectivityAppDefinitions.Codeunit.al (microsoft#26886)

Added US to Yavrio Open Banking

Fixes
[AB#543398](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/543398)

Syncing with version 25.0.22639.0 (microsoft#26958)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

---------

Co-authored-by: Jesper Schulz-Wedde <[email protected]>

Syncing with version 25.0.22684.0 (microsoft#26959)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

[Fix] URL maximum length in E-Document Integration (microsoft#26730)

Added a new field "Request URL" to table 6127 "E-Document Integration
Log" with a maximum string length of 2048 to allow for longer URLs when
using the "E-Document Integration" interface. The new filed replaces the
existing field URL. I marked the existing field as obsolete and updated
three (all) references from the old URL field to the new "Request URL"
field.

needs to be open and approved. Submitting PRs with no linked issues or
unapproved issues is highly discouraged. -->
Fixes microsoft#26672

Fixes
[AB#540448](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/540448)

---------

Co-authored-by: Patrick Lüthi <[email protected]>

Update InstallSECore.codeunit.al (microsoft#26883)

Update CODEOWNERS with EDocument reviewers (microsoft#27067)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

GP Updates - July 2024 (microsoft#26821)

This update enhances the GP migrations by:

- Migrating GP Kit Items as BC Assembly BOMs.
- Prevent migration error when Customer/Vendor phone numbers contain
alpha characters. The Customer/Vendors will be migrated, but the
phone/fax numbers with alpha characters will be ignored and added to the
Warning Log.
- History Gen. Journal Line - View Distributions feature.
- Updated labels in settings area to specify 'migration' instead of
'upgrade' to prevent customer confusion.

Fixes microsoft#26487
Fixes
[AB#543399](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/543399)

---------

Co-authored-by: jaymckinney <[email protected]>

[Shopify][BC Idea]: Enhancing Shopify Connector for Accurate Price Synchronization with Business Central based on Customer (microsoft#26981)

Added Customer No to the
          table 30152 "Shpfy Catalog"
          page 30159 "Shpfy Catalogs"

Added logic to use customer specific pricing from catalog
           codeunit 30182 "Shpfy Product Price Calc."

Fixes microsoft#26980
Fixes
[AB#544010](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/544010)

[Shopify] Add Translations Export to Products and Variants (microsoft#26216)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

here‘s a quick summary:

Shopify Shop has a new action that takes the user to the Languages page.
Languages cannot be manually inserted or deleted, they can only be
refreshed with an action that pulls them from Shopify.
Before a language can be enabled for syncing, a language code needs to
be mapped to it, as Shopify is using locales, and I can‘t directly map
them.

A new Scope is required to get shop locales – read_locales

On export of products and variants, an update of translations is
triggered. The translation update first collects all
TranslatableContentDigests for a resource, as these are needed when
requesting an update of a translation.
The update next collects translations for the product Title, Product
Body, and Variant „option 1“ in a temporary table for each enabled
language. It compares the translations with the translations that were
last synced. If the translation is the same, it removes it from the
buffer. Next, the buffer is used to build the query and sent to Shopify
to update translations.

Continuing with a couple of questions/considerations regarding the issue

• The way I designed Shopify Languages is that the user can‘t
insert/delete them, but has to pull them from Shopify with an action.
This uses ShopLocales query which needs a read_locales scope that‘s not
currently part of the scopes. I wasn‘t sure if that‘s an issue or not.
• I made the import of locales skip the primary language as I wanted to
keep the logic for that one on the Shop.“Langauge Code“ field.
• I‘ve refactored the CreateProductBody procedure in the Product Export
codeunit so it takes the language code as a parameter. This means I can
reuse it for translations, however, there are events in this procedure
at the start/end, which will now trigger more often if more languages
are synced. I added the language code as a parameter in the publishers,
and technically nothing is broken until additional languages are synced,
but I wanted to mention this.
• I wasn‘t sure how I should approach translations when they‘re missing.
Should I take the existing approach, take the translated text or default
text, or should I only take the translated text, and if it doesn‘t
exist, skip that property?
This is mainly an issue with the product body. If Ext. Text is
translated, but Attributes are not, should I skip on attributes or send
attributes in the default language?
Currently, I skip the Title if it‘s not translated, but I send the body
in every case. Let me know if that should be changed.
• For the update of a translation, I need to send the
TranslatableContentDigest as part of the request. Currently, I‘ve done
this in a way, that I collect all digests for a resource during an
update, but that means that every update of a product/variant now has an
additional „get“ call, before it maybe sends an update for translations.
I think this could be done better, and would appreciate your input here.
• Resource Type is almost the same enum as used in Metafields, I think
these two should be made the same.
• I‘m not a fan of what I did with Translations Mgt. Is there a better
place where I could put this procedure for retrieving the item
translation?

Fixes microsoft#26819
Fixes
[AB#460580](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/460580)

---------

Co-authored-by: Tine Staric <[email protected]>
Co-authored-by: Jesper Schulz-Wedde <[email protected]>

[Shopify] Add Metafields to Products and Variants (microsoft#26185)

This is a PR without a dedicated issue as it's part of delivery for
development agreed directly with @AndreiPanko

Here's the overview of the changes:

Obsolete fields:
• Obsoleted Value Type as it‘s no longer used in Shopify API -> Replaced
with Type field
• Obsoleted Owner Resource field. I‘m not sure why this was a free text
that was then always populated through a case statement. It‘s replaced
with an Owner Type field that is an Enum.

New enums and interfaces:
• „Shpfy Metafield Type“ and „Shpfy IMetafield Type“ – Used for handling
the metafield type. The interface defines if the type has a special
AssistEdit, logic to execute the assist edit, and validations when free
input is allowed for a value. I have a couple of questions here, see
below. Rating, Rich Text, and List Types are not included, Rating and
Rich Text options are added but commented out so it‘s clear that it was
intentional. It also has String and Integer types which are there to
support backward compatibility, if old values are still in Shopify.
• „Shpfy Metafield Owner Type“ and „Shpfy IMetafield Owner Type“ – Used
for building the full owner resource ID
(gid://shopify/<ownerType>/<ownerId>) and for retrieving metafield IDs
of a single resource (used during export, to identify which metafields
should be sent for update based on UpdatedAt)
• Metafield Dimenion/Volume/Weight Type – three enums to support a
selection of Units when assist editing these metafield types

Pages:
• „Shpfy Metafields“ – used for viewing and editing metafields for a
resource. It‘s only editable if Shop is syncing Products to Shopify and
Can update Shopify products. On Insert of a new record, it‘s immediately
sent to Shopify and is only inserted in the DB when we get back the
Shopify ID for the metafield. Types that have AssistEdit functionality
defined cannot be edited directly on the line. OnValidate of Value a
check is executed to ensure value is correct for a type.
• „Shpfy Metafield Assist Edit“ – used for assist edit of complex
metafield types. It has several groups defined, and only the appropriate
one is displayed to the user.
• Action for display metafields for a resource has been added to the
Products and Variants pages.

GraphQL query changes:
• ProductById and VariantById have been modified so that they retrieve
the first 50 metafields (previously the first 10). Previously there was
a filter to only retrieve Metafields with the
„Microsoft.Dynamics365.BusinessCentral“ namespace. I‘ve removed that to
get all the metafields of a resource.
• ProductMetafieldIds and VariantMetafieldIds were added. These are used
during the export of metafields to determine which BC metafields should
be sent for an update
• MetafieldsSet – This is used to create/update metafields for a
resource

Changes to API codeunits:
• Product API – on UpdateShopifyProductFields a metafields part of JSON
is now passed to Metafields API where it creates or updates Metafields
in BC based on information retrieved from Shopify
• Variant API – on UpdateShopifyVariantFields the metafields part of the
JSON is passed to Metafields API, same as above.
• „Shpfy Product Export“ – on UpdateProductData execute Metafields API
to update/create metafields for the product and all variants that belong
to the product
• „Metafield API“ – Implements logic to parse the „metafields“JSON that
is retrieved with products/variants during import and creates/updates
metafield records in BC.
Adds logic to export metafields for a specific resource. Only sends an
update for metafields that have a lower UpdatedAt timestamp than BC
record‘s last updated at timestamp. It batches the Metafields to 25 at a
time, as that‘s the max MetafieldsSet mutation can handle as per the
documentation.

Added logic to delete metafields on delete of a product/variant

A couple of questions or concerns:
• New metafields that get created in Shopify do not have a Metafield
Definition attached to them. Should we care about this right now? If
yes, should we also store metafield definitions in BC, or just create
new definitions if any are missing in Shopify?
• I‘ve obsoleted the two fields and one enum, should I be wrapping the
obsoletions in some preprocessing symbols? Which one?
• I‘m doing some regex validations when checking if the value of
metafield is correct. I‘m not sure if the one for mixed reference and
file reference is correct. I‘d appreciate it if someone could take a
look at that.
• If value validation fails, it throws a pretty „simple“ error message
right now, should I make this more expressive?
• Currently, the „update metafields“ has no error handling in place if
the update query fails. Technically I‘m trying to catch everything on
data input, but there can always be unexpected situations. How should I
handle this?
• The code for sending the metafield to Shopify immediately after it‘s
inserted through UI is currently on the Page‘s OnInsertRecord trigger.
I‘m not sure about it, should I move it to the table trigger? The
hesitation is because there already is some logic on the table from the
partial implementation of metafields on Customers.
• I‘ve placed interface implementations in a separate folder under
Codeunits folder, that‘s not the usual practice on MS apps, so I wanted
to double-check it.
• Money metafield type needs to have the same currency as the shop,
which leads to this completely separate code path after validating the
Value. I‘m not sure if there‘s a better approach to handle this.
• I saw that most procedures in the app have documentation triggers that
are not really beneficial. I‘ve only added them to the public or
internal procedures. I‘ve also skipped on most object documentation
triggers.

Fixes microsoft#26819
Fixes
[AB#443908](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/443908)

---------

Co-authored-by: Tine Staric <[email protected]>
Co-authored-by: Jesper Schulz-Wedde <[email protected]>
Co-authored-by: Onat Buyukakkus <[email protected]>

Syncing with version 25.0.23141.0 (microsoft#27112)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

[Shopify] Connector - Export Posted Sales Invoices to Shopify as Orders (microsoft#26748)

This pull request does not have a related issue as it's part of the
delivery for development agreed directly
with [@AndreiPanko](https://github.com/AndreiPanko)

Here's a quick summary:

Orders.

Shopify Shop has a **new action "Payment Terms Mapping"** that takes the
user to the **new page "Shopify Payment Terms Mapping"**. Shopify
Payment Terms cannot be manually inserted or deleted, they can only be
refreshed with an action that pulls them from Shopify. By default
**FIXED** Payment Term is selected as primary during the synchronization
of the Payment Terms.
Before Posted Sales Invoices can be synced, a payment term code from
Shopify needs to be mapped to the Business Central one or a primary
Shopify Payment Term needs to be selected with a Boolean "Is Primary" -
this payment term will be used if the Posted Sales Invoice payment terms
code doesn't have a mapping to Shopify. This payment term code will also
be filled during the sync of Shopify orders.

A new Scope is required. To update payment terms on a draft order –
write_payment_terms (read_payment_terms scope was removed because it
causes strange behavior - every time a Shopify shop card is opened it
states that the scope has changed and requires authorization.
write_payment_terms overwrites read_payment_terms). To create a draft
order - write_draft_orders.

need to meet:

- The **new Boolean field "Posted Invoice Sync"** needs to be enabled.
- The "Shopify Order Id" field on the Posted Sales Invoice needs to be
0.
- Posted Sales Invoice "Bill-To Customer" has been mapped to the Shopify
Customer or Shopify Companies table.
- Posted Sales Invoice "Bill-To Customer" is not a customer used as a
Default Customer in the Shopify Shop Card or Shopify Customer Template.
- There are no lines of type non-comment (or type is populated but No.
is empty).
- There are no fraction quantities.
- There must be a mapped Payment Terms Code or a selected Primary
Payment Terms Code on the new "Shopify Payment Terms Mapping" page.
- If there is at least one line of type "Item" where the selected
item/variant doesn’t have a link to Shopify Product/Shopify variant and
the **new Boolean field "Items must be mapped to Products"** on the
Shopify Shop card is selected - the Posted Sales Invoice will not be
exported.
- Posted Sales Invoice currency code matches Shopify shop currency code
(explanation at the bottom).

If one of the previous conditions is not met, the Posted Sales Invoice
"Shopify Order Id" field will be marked with -2. If the GraphQL request
fails, then the field will be marked with -1. If everything goes
correctly, the field will be filled with the created Shopify Order ID.
Users can modify the "Shopify Order Id" field in the posted document
(allowed changes from -1 or -2 to 0. The functionality works the same as
in the Update Posted Shipment document.)

This export can be executed with a new action that is added to Shopify
Shop - "Sync Posted Sales Invoices" or just by running the report "Sync
Invoices to Shopify". The draft order in Shopify is created with the
values from the Posted Sales Invoice order and lines. If the Remaining
Amount of the Posted Sales Invoice is 0, then the order is marked as
paid, otherwise, the status will be "Payment pending" and a mapped
Payment Terms code will be sent out. After that, the created draft order
will be completed and the Shopify order created. All orders are
automatically fulfilled. To achieve “paid” status on the Shopify order –
use the Manual payment function in the Shopify Order card. Once the
report is executed, the Inventory will be synced.

Order sync will import created orders, then check if the order is
present in the **new Shopify Invoice Header table** (this table is
filled with the Shopify order ID of the exported Posted Sales Invoice)
and if so:
- Shopify Order is marked as processed.
- A link is added to the Posted Sales Invoice (related documents).

functionality:
- All non-comment type lines are exported as custom products (including
Items if the new Boolean field "Items must be mapped to Products"** on
the Shopify Shop card is not selected).
- Taxes from the lines are sent out as a custom product with the title
consisting of "VAT Calculation Type" + VAT %.
- Invoice discounts from the lines and the header are added up and sent
out as a discount to the whole order with the title "Invoice Discount
Amount"
- Posted Sales Invoice comments are exported as notes.
- Once the draft order is completed, an order confirmation email will be
sent out to the customer. This functionality is from Shopify itself.
- If the product/variant exists in Shopify, the price, title and other
information will be taken from Shopify and not the one in the Posted
Sales Invoice line. This is how the draftOrderCreate mutation works.

- Open orders and open invoices.
- Fulfillment/Tracking Details.
- Refund / partial refund status.
- Weight export.

**Known issues with different currencies (that's why Posted Sales
Invoices with different currencies than Shopify Shop cannot be exported
at the moment):**
- Currently sending out different currencies than the Shopify Shop
currency cannot be done because if the currency of the custom product
differs from the Shopify shop's currency, the amount sent will still be
accepted in the local Shopify shop's currency before being converted to
the order's currency and the amount will be incorrect. For example, if
the VAT amount is 100 GBP, but the Shopify shop's currency is EUR, the
custom product will be exported with an amount of 100 GBP. However, this
amount will be treated as 100 EUR and then converted to GBP according to
the currency exchange rate in Shopify.

Fixes microsoft#26819
Fixes
[AB#446399](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/446399)

---------

Co-authored-by: Jesper Schulz-Wedde <[email protected]>
Co-authored-by: Tine Staric <[email protected]>

GP - Update migrations with 1099 data to use the new IRS Forms app. (microsoft#27100)

The update enhances the GP migration to use the new IRS Forms app, which
replaces the base app implementation of 1099 handling.

Fixes microsoft#26487

Fixes
[AB#545622](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/545622)

---------

Co-authored-by: jaymckinney <[email protected]>

Removing the Order taker app (microsoft#27221)

Fixes
[AB#539591](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/539591)
aholstrup1 pushed a commit to aholstrup1/ALAppExtensions that referenced this issue Sep 9, 2024
Move the BCPT sample tests to
https://github.com/microsoft/BusinessCentralApps/tree/main/App/Layers/W1/Tests/BCPT-SampleTests.

Syncing with version 25.0.21703.0 (microsoft#26811)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

---------

Co-authored-by: Alexander Holstrup <[email protected]>

[Shopify] Shopify return location on refunds (microsoft#26728)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

Added a setting to the shopify shop to use original return location
(From shopify) or a default return location set in the Shopify shop when
creating Credit Memos for Refunds.

Modified the return and refund creation to pull original location from
shopify refund or return orders.
When an item on a single return order in shopify is restocked to
multiple locations, we cannot determine a single location to put on a
return line.

If there is any reason that Original location couldn't be determined
then the Default Return Location will be used during the creation of a
Credit Memo.

Fixes microsoft#26819

Fixes
[AB#540965](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/540965)

---------

Co-authored-by: Tine Staric <[email protected]>

[Shopify] Connector - Different shipping charges types (microsoft#26708)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

Quick summary:

The Shopify Shipping Method Mapping page/table was extended to include a
new Shipping Charges Type field, allowing users to select from GL, Item,
or Item Charge. Depending on this selection, the Shipping Charges No.
field opens the related table (item, GL, or item charges), and when an
order is created, the shipping charge line reflects the new type and
number. For Item Charges, a default allocation process is run for all
item lines. The settings in the Shopify Shipping Method Mapping now take
priority over those in the Shopify Shop - GL Account settings.
Additionally, if the Shipping Agent Code and Shipping Agent Service
fields are populated, they are automatically populated in the sales
order as well.

Fixes microsoft#26819

[AB#449477](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/449477)

---------

Co-authored-by: aidasberesinevicius <[email protected]>
Co-authored-by: Tine Staric <[email protected]>

[Shopify] Add items as product variants (microsoft#26712)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

Added an action to Variants subpage to add BC Items as additional
Variants to an existing Shopify Product.
If the parent product only had a default variant before the addition, it
is deleted from both Shopify and BC.
The variants are added under the existing the Product Option (ex. Color,
Material, or Title, if product only had the default variant)

Items cannot be added if the shop has "UOM as Variant" enabled, or if
the parent product has more than one option defined.

Fixes microsoft#26819
Fixes
[AB#468218](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/468218)

---------

Co-authored-by: Tine Staric <[email protected]>
Co-authored-by: Jesper Schulz-Wedde <[email protected]>
Co-authored-by: Onat Buyukakkus <[email protected]>

Update Yavrio in ConnectivityAppDefinitions.Codeunit.al (microsoft#26886)

Added US to Yavrio Open Banking

Fixes
[AB#543398](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/543398)

Syncing with version 25.0.22639.0 (microsoft#26958)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

---------

Co-authored-by: Jesper Schulz-Wedde <[email protected]>

Syncing with version 25.0.22684.0 (microsoft#26959)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

[Fix] URL maximum length in E-Document Integration (microsoft#26730)

Added a new field "Request URL" to table 6127 "E-Document Integration
Log" with a maximum string length of 2048 to allow for longer URLs when
using the "E-Document Integration" interface. The new filed replaces the
existing field URL. I marked the existing field as obsolete and updated
three (all) references from the old URL field to the new "Request URL"
field.

needs to be open and approved. Submitting PRs with no linked issues or
unapproved issues is highly discouraged. -->
Fixes microsoft#26672

Fixes
[AB#540448](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/540448)

---------

Co-authored-by: Patrick Lüthi <[email protected]>

Update InstallSECore.codeunit.al (microsoft#26883)

Update CODEOWNERS with EDocument reviewers (microsoft#27067)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

GP Updates - July 2024 (microsoft#26821)

This update enhances the GP migrations by:

- Migrating GP Kit Items as BC Assembly BOMs.
- Prevent migration error when Customer/Vendor phone numbers contain
alpha characters. The Customer/Vendors will be migrated, but the
phone/fax numbers with alpha characters will be ignored and added to the
Warning Log.
- History Gen. Journal Line - View Distributions feature.
- Updated labels in settings area to specify 'migration' instead of
'upgrade' to prevent customer confusion.

Fixes microsoft#26487
Fixes
[AB#543399](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/543399)

---------

Co-authored-by: jaymckinney <[email protected]>

[Shopify][BC Idea]: Enhancing Shopify Connector for Accurate Price Synchronization with Business Central based on Customer (microsoft#26981)

Added Customer No to the
          table 30152 "Shpfy Catalog"
          page 30159 "Shpfy Catalogs"

Added logic to use customer specific pricing from catalog
           codeunit 30182 "Shpfy Product Price Calc."

Fixes microsoft#26980
Fixes
[AB#544010](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/544010)

[Shopify] Add Translations Export to Products and Variants (microsoft#26216)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

here‘s a quick summary:

Shopify Shop has a new action that takes the user to the Languages page.
Languages cannot be manually inserted or deleted, they can only be
refreshed with an action that pulls them from Shopify.
Before a language can be enabled for syncing, a language code needs to
be mapped to it, as Shopify is using locales, and I can‘t directly map
them.

A new Scope is required to get shop locales – read_locales

On export of products and variants, an update of translations is
triggered. The translation update first collects all
TranslatableContentDigests for a resource, as these are needed when
requesting an update of a translation.
The update next collects translations for the product Title, Product
Body, and Variant „option 1“ in a temporary table for each enabled
language. It compares the translations with the translations that were
last synced. If the translation is the same, it removes it from the
buffer. Next, the buffer is used to build the query and sent to Shopify
to update translations.

Continuing with a couple of questions/considerations regarding the issue

• The way I designed Shopify Languages is that the user can‘t
insert/delete them, but has to pull them from Shopify with an action.
This uses ShopLocales query which needs a read_locales scope that‘s not
currently part of the scopes. I wasn‘t sure if that‘s an issue or not.
• I made the import of locales skip the primary language as I wanted to
keep the logic for that one on the Shop.“Langauge Code“ field.
• I‘ve refactored the CreateProductBody procedure in the Product Export
codeunit so it takes the language code as a parameter. This means I can
reuse it for translations, however, there are events in this procedure
at the start/end, which will now trigger more often if more languages
are synced. I added the language code as a parameter in the publishers,
and technically nothing is broken until additional languages are synced,
but I wanted to mention this.
• I wasn‘t sure how I should approach translations when they‘re missing.
Should I take the existing approach, take the translated text or default
text, or should I only take the translated text, and if it doesn‘t
exist, skip that property?
This is mainly an issue with the product body. If Ext. Text is
translated, but Attributes are not, should I skip on attributes or send
attributes in the default language?
Currently, I skip the Title if it‘s not translated, but I send the body
in every case. Let me know if that should be changed.
• For the update of a translation, I need to send the
TranslatableContentDigest as part of the request. Currently, I‘ve done
this in a way, that I collect all digests for a resource during an
update, but that means that every update of a product/variant now has an
additional „get“ call, before it maybe sends an update for translations.
I think this could be done better, and would appreciate your input here.
• Resource Type is almost the same enum as used in Metafields, I think
these two should be made the same.
• I‘m not a fan of what I did with Translations Mgt. Is there a better
place where I could put this procedure for retrieving the item
translation?

Fixes microsoft#26819
Fixes
[AB#460580](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/460580)

---------

Co-authored-by: Tine Staric <[email protected]>
Co-authored-by: Jesper Schulz-Wedde <[email protected]>

[Shopify] Add Metafields to Products and Variants (microsoft#26185)

This is a PR without a dedicated issue as it's part of delivery for
development agreed directly with @AndreiPanko

Here's the overview of the changes:

Obsolete fields:
• Obsoleted Value Type as it‘s no longer used in Shopify API -> Replaced
with Type field
• Obsoleted Owner Resource field. I‘m not sure why this was a free text
that was then always populated through a case statement. It‘s replaced
with an Owner Type field that is an Enum.

New enums and interfaces:
• „Shpfy Metafield Type“ and „Shpfy IMetafield Type“ – Used for handling
the metafield type. The interface defines if the type has a special
AssistEdit, logic to execute the assist edit, and validations when free
input is allowed for a value. I have a couple of questions here, see
below. Rating, Rich Text, and List Types are not included, Rating and
Rich Text options are added but commented out so it‘s clear that it was
intentional. It also has String and Integer types which are there to
support backward compatibility, if old values are still in Shopify.
• „Shpfy Metafield Owner Type“ and „Shpfy IMetafield Owner Type“ – Used
for building the full owner resource ID
(gid://shopify/<ownerType>/<ownerId>) and for retrieving metafield IDs
of a single resource (used during export, to identify which metafields
should be sent for update based on UpdatedAt)
• Metafield Dimenion/Volume/Weight Type – three enums to support a
selection of Units when assist editing these metafield types

Pages:
• „Shpfy Metafields“ – used for viewing and editing metafields for a
resource. It‘s only editable if Shop is syncing Products to Shopify and
Can update Shopify products. On Insert of a new record, it‘s immediately
sent to Shopify and is only inserted in the DB when we get back the
Shopify ID for the metafield. Types that have AssistEdit functionality
defined cannot be edited directly on the line. OnValidate of Value a
check is executed to ensure value is correct for a type.
• „Shpfy Metafield Assist Edit“ – used for assist edit of complex
metafield types. It has several groups defined, and only the appropriate
one is displayed to the user.
• Action for display metafields for a resource has been added to the
Products and Variants pages.

GraphQL query changes:
• ProductById and VariantById have been modified so that they retrieve
the first 50 metafields (previously the first 10). Previously there was
a filter to only retrieve Metafields with the
„Microsoft.Dynamics365.BusinessCentral“ namespace. I‘ve removed that to
get all the metafields of a resource.
• ProductMetafieldIds and VariantMetafieldIds were added. These are used
during the export of metafields to determine which BC metafields should
be sent for an update
• MetafieldsSet – This is used to create/update metafields for a
resource

Changes to API codeunits:
• Product API – on UpdateShopifyProductFields a metafields part of JSON
is now passed to Metafields API where it creates or updates Metafields
in BC based on information retrieved from Shopify
• Variant API – on UpdateShopifyVariantFields the metafields part of the
JSON is passed to Metafields API, same as above.
• „Shpfy Product Export“ – on UpdateProductData execute Metafields API
to update/create metafields for the product and all variants that belong
to the product
• „Metafield API“ – Implements logic to parse the „metafields“JSON that
is retrieved with products/variants during import and creates/updates
metafield records in BC.
Adds logic to export metafields for a specific resource. Only sends an
update for metafields that have a lower UpdatedAt timestamp than BC
record‘s last updated at timestamp. It batches the Metafields to 25 at a
time, as that‘s the max MetafieldsSet mutation can handle as per the
documentation.

Added logic to delete metafields on delete of a product/variant

A couple of questions or concerns:
• New metafields that get created in Shopify do not have a Metafield
Definition attached to them. Should we care about this right now? If
yes, should we also store metafield definitions in BC, or just create
new definitions if any are missing in Shopify?
• I‘ve obsoleted the two fields and one enum, should I be wrapping the
obsoletions in some preprocessing symbols? Which one?
• I‘m doing some regex validations when checking if the value of
metafield is correct. I‘m not sure if the one for mixed reference and
file reference is correct. I‘d appreciate it if someone could take a
look at that.
• If value validation fails, it throws a pretty „simple“ error message
right now, should I make this more expressive?
• Currently, the „update metafields“ has no error handling in place if
the update query fails. Technically I‘m trying to catch everything on
data input, but there can always be unexpected situations. How should I
handle this?
• The code for sending the metafield to Shopify immediately after it‘s
inserted through UI is currently on the Page‘s OnInsertRecord trigger.
I‘m not sure about it, should I move it to the table trigger? The
hesitation is because there already is some logic on the table from the
partial implementation of metafields on Customers.
• I‘ve placed interface implementations in a separate folder under
Codeunits folder, that‘s not the usual practice on MS apps, so I wanted
to double-check it.
• Money metafield type needs to have the same currency as the shop,
which leads to this completely separate code path after validating the
Value. I‘m not sure if there‘s a better approach to handle this.
• I saw that most procedures in the app have documentation triggers that
are not really beneficial. I‘ve only added them to the public or
internal procedures. I‘ve also skipped on most object documentation
triggers.

Fixes microsoft#26819
Fixes
[AB#443908](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/443908)

---------

Co-authored-by: Tine Staric <[email protected]>
Co-authored-by: Jesper Schulz-Wedde <[email protected]>
Co-authored-by: Onat Buyukakkus <[email protected]>

Syncing with version 25.0.23141.0 (microsoft#27112)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

[Shopify] Connector - Export Posted Sales Invoices to Shopify as Orders (microsoft#26748)

This pull request does not have a related issue as it's part of the
delivery for development agreed directly
with [@AndreiPanko](https://github.com/AndreiPanko)

Here's a quick summary:

Orders.

Shopify Shop has a **new action "Payment Terms Mapping"** that takes the
user to the **new page "Shopify Payment Terms Mapping"**. Shopify
Payment Terms cannot be manually inserted or deleted, they can only be
refreshed with an action that pulls them from Shopify. By default
**FIXED** Payment Term is selected as primary during the synchronization
of the Payment Terms.
Before Posted Sales Invoices can be synced, a payment term code from
Shopify needs to be mapped to the Business Central one or a primary
Shopify Payment Term needs to be selected with a Boolean "Is Primary" -
this payment term will be used if the Posted Sales Invoice payment terms
code doesn't have a mapping to Shopify. This payment term code will also
be filled during the sync of Shopify orders.

A new Scope is required. To update payment terms on a draft order –
write_payment_terms (read_payment_terms scope was removed because it
causes strange behavior - every time a Shopify shop card is opened it
states that the scope has changed and requires authorization.
write_payment_terms overwrites read_payment_terms). To create a draft
order - write_draft_orders.

need to meet:

- The **new Boolean field "Posted Invoice Sync"** needs to be enabled.
- The "Shopify Order Id" field on the Posted Sales Invoice needs to be
0.
- Posted Sales Invoice "Bill-To Customer" has been mapped to the Shopify
Customer or Shopify Companies table.
- Posted Sales Invoice "Bill-To Customer" is not a customer used as a
Default Customer in the Shopify Shop Card or Shopify Customer Template.
- There are no lines of type non-comment (or type is populated but No.
is empty).
- There are no fraction quantities.
- There must be a mapped Payment Terms Code or a selected Primary
Payment Terms Code on the new "Shopify Payment Terms Mapping" page.
- If there is at least one line of type "Item" where the selected
item/variant doesn’t have a link to Shopify Product/Shopify variant and
the **new Boolean field "Items must be mapped to Products"** on the
Shopify Shop card is selected - the Posted Sales Invoice will not be
exported.
- Posted Sales Invoice currency code matches Shopify shop currency code
(explanation at the bottom).

If one of the previous conditions is not met, the Posted Sales Invoice
"Shopify Order Id" field will be marked with -2. If the GraphQL request
fails, then the field will be marked with -1. If everything goes
correctly, the field will be filled with the created Shopify Order ID.
Users can modify the "Shopify Order Id" field in the posted document
(allowed changes from -1 or -2 to 0. The functionality works the same as
in the Update Posted Shipment document.)

This export can be executed with a new action that is added to Shopify
Shop - "Sync Posted Sales Invoices" or just by running the report "Sync
Invoices to Shopify". The draft order in Shopify is created with the
values from the Posted Sales Invoice order and lines. If the Remaining
Amount of the Posted Sales Invoice is 0, then the order is marked as
paid, otherwise, the status will be "Payment pending" and a mapped
Payment Terms code will be sent out. After that, the created draft order
will be completed and the Shopify order created. All orders are
automatically fulfilled. To achieve “paid” status on the Shopify order –
use the Manual payment function in the Shopify Order card. Once the
report is executed, the Inventory will be synced.

Order sync will import created orders, then check if the order is
present in the **new Shopify Invoice Header table** (this table is
filled with the Shopify order ID of the exported Posted Sales Invoice)
and if so:
- Shopify Order is marked as processed.
- A link is added to the Posted Sales Invoice (related documents).

functionality:
- All non-comment type lines are exported as custom products (including
Items if the new Boolean field "Items must be mapped to Products"** on
the Shopify Shop card is not selected).
- Taxes from the lines are sent out as a custom product with the title
consisting of "VAT Calculation Type" + VAT %.
- Invoice discounts from the lines and the header are added up and sent
out as a discount to the whole order with the title "Invoice Discount
Amount"
- Posted Sales Invoice comments are exported as notes.
- Once the draft order is completed, an order confirmation email will be
sent out to the customer. This functionality is from Shopify itself.
- If the product/variant exists in Shopify, the price, title and other
information will be taken from Shopify and not the one in the Posted
Sales Invoice line. This is how the draftOrderCreate mutation works.

- Open orders and open invoices.
- Fulfillment/Tracking Details.
- Refund / partial refund status.
- Weight export.

**Known issues with different currencies (that's why Posted Sales
Invoices with different currencies than Shopify Shop cannot be exported
at the moment):**
- Currently sending out different currencies than the Shopify Shop
currency cannot be done because if the currency of the custom product
differs from the Shopify shop's currency, the amount sent will still be
accepted in the local Shopify shop's currency before being converted to
the order's currency and the amount will be incorrect. For example, if
the VAT amount is 100 GBP, but the Shopify shop's currency is EUR, the
custom product will be exported with an amount of 100 GBP. However, this
amount will be treated as 100 EUR and then converted to GBP according to
the currency exchange rate in Shopify.

Fixes microsoft#26819
Fixes
[AB#446399](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/446399)

---------

Co-authored-by: Jesper Schulz-Wedde <[email protected]>
Co-authored-by: Tine Staric <[email protected]>

GP - Update migrations with 1099 data to use the new IRS Forms app. (microsoft#27100)

The update enhances the GP migration to use the new IRS Forms app, which
replaces the base app implementation of 1099 handling.

Fixes microsoft#26487

Fixes
[AB#545622](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/545622)

---------

Co-authored-by: jaymckinney <[email protected]>

Removing the Order taker app (microsoft#27221)

Fixes
[AB#539591](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/539591)
aholstrup1 pushed a commit to aholstrup1/ALAppExtensions that referenced this issue Sep 9, 2024
Move the BCPT sample tests to
https://github.com/microsoft/BusinessCentralApps/tree/main/App/Layers/W1/Tests/BCPT-SampleTests.

Syncing with version 25.0.21703.0 (microsoft#26811)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

---------

Co-authored-by: Alexander Holstrup <[email protected]>

[Shopify] Shopify return location on refunds (microsoft#26728)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

Added a setting to the shopify shop to use original return location
(From shopify) or a default return location set in the Shopify shop when
creating Credit Memos for Refunds.

Modified the return and refund creation to pull original location from
shopify refund or return orders.
When an item on a single return order in shopify is restocked to
multiple locations, we cannot determine a single location to put on a
return line.

If there is any reason that Original location couldn't be determined
then the Default Return Location will be used during the creation of a
Credit Memo.

Fixes microsoft#26819

Fixes
[AB#540965](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/540965)

---------

Co-authored-by: Tine Staric <[email protected]>

[Shopify] Connector - Different shipping charges types (microsoft#26708)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

Quick summary:

The Shopify Shipping Method Mapping page/table was extended to include a
new Shipping Charges Type field, allowing users to select from GL, Item,
or Item Charge. Depending on this selection, the Shipping Charges No.
field opens the related table (item, GL, or item charges), and when an
order is created, the shipping charge line reflects the new type and
number. For Item Charges, a default allocation process is run for all
item lines. The settings in the Shopify Shipping Method Mapping now take
priority over those in the Shopify Shop - GL Account settings.
Additionally, if the Shipping Agent Code and Shipping Agent Service
fields are populated, they are automatically populated in the sales
order as well.

Fixes microsoft#26819

[AB#449477](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/449477)

---------

Co-authored-by: aidasberesinevicius <[email protected]>
Co-authored-by: Tine Staric <[email protected]>

[Shopify] Add items as product variants (microsoft#26712)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

Added an action to Variants subpage to add BC Items as additional
Variants to an existing Shopify Product.
If the parent product only had a default variant before the addition, it
is deleted from both Shopify and BC.
The variants are added under the existing the Product Option (ex. Color,
Material, or Title, if product only had the default variant)

Items cannot be added if the shop has "UOM as Variant" enabled, or if
the parent product has more than one option defined.

Fixes microsoft#26819
Fixes
[AB#468218](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/468218)

---------

Co-authored-by: Tine Staric <[email protected]>
Co-authored-by: Jesper Schulz-Wedde <[email protected]>
Co-authored-by: Onat Buyukakkus <[email protected]>

Update Yavrio in ConnectivityAppDefinitions.Codeunit.al (microsoft#26886)

Added US to Yavrio Open Banking

Fixes
[AB#543398](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/543398)

Syncing with version 25.0.22639.0 (microsoft#26958)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

---------

Co-authored-by: Jesper Schulz-Wedde <[email protected]>

Syncing with version 25.0.22684.0 (microsoft#26959)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

[Fix] URL maximum length in E-Document Integration (microsoft#26730)

Added a new field "Request URL" to table 6127 "E-Document Integration
Log" with a maximum string length of 2048 to allow for longer URLs when
using the "E-Document Integration" interface. The new filed replaces the
existing field URL. I marked the existing field as obsolete and updated
three (all) references from the old URL field to the new "Request URL"
field.

needs to be open and approved. Submitting PRs with no linked issues or
unapproved issues is highly discouraged. -->
Fixes microsoft#26672

Fixes
[AB#540448](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/540448)

---------

Co-authored-by: Patrick Lüthi <[email protected]>

Update InstallSECore.codeunit.al (microsoft#26883)

Update CODEOWNERS with EDocument reviewers (microsoft#27067)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

GP Updates - July 2024 (microsoft#26821)

This update enhances the GP migrations by:

- Migrating GP Kit Items as BC Assembly BOMs.
- Prevent migration error when Customer/Vendor phone numbers contain
alpha characters. The Customer/Vendors will be migrated, but the
phone/fax numbers with alpha characters will be ignored and added to the
Warning Log.
- History Gen. Journal Line - View Distributions feature.
- Updated labels in settings area to specify 'migration' instead of
'upgrade' to prevent customer confusion.

Fixes microsoft#26487
Fixes
[AB#543399](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/543399)

---------

Co-authored-by: jaymckinney <[email protected]>

[Shopify][BC Idea]: Enhancing Shopify Connector for Accurate Price Synchronization with Business Central based on Customer (microsoft#26981)

Added Customer No to the
          table 30152 "Shpfy Catalog"
          page 30159 "Shpfy Catalogs"

Added logic to use customer specific pricing from catalog
           codeunit 30182 "Shpfy Product Price Calc."

Fixes microsoft#26980
Fixes
[AB#544010](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/544010)

[Shopify] Add Translations Export to Products and Variants (microsoft#26216)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

here‘s a quick summary:

Shopify Shop has a new action that takes the user to the Languages page.
Languages cannot be manually inserted or deleted, they can only be
refreshed with an action that pulls them from Shopify.
Before a language can be enabled for syncing, a language code needs to
be mapped to it, as Shopify is using locales, and I can‘t directly map
them.

A new Scope is required to get shop locales – read_locales

On export of products and variants, an update of translations is
triggered. The translation update first collects all
TranslatableContentDigests for a resource, as these are needed when
requesting an update of a translation.
The update next collects translations for the product Title, Product
Body, and Variant „option 1“ in a temporary table for each enabled
language. It compares the translations with the translations that were
last synced. If the translation is the same, it removes it from the
buffer. Next, the buffer is used to build the query and sent to Shopify
to update translations.

Continuing with a couple of questions/considerations regarding the issue

• The way I designed Shopify Languages is that the user can‘t
insert/delete them, but has to pull them from Shopify with an action.
This uses ShopLocales query which needs a read_locales scope that‘s not
currently part of the scopes. I wasn‘t sure if that‘s an issue or not.
• I made the import of locales skip the primary language as I wanted to
keep the logic for that one on the Shop.“Langauge Code“ field.
• I‘ve refactored the CreateProductBody procedure in the Product Export
codeunit so it takes the language code as a parameter. This means I can
reuse it for translations, however, there are events in this procedure
at the start/end, which will now trigger more often if more languages
are synced. I added the language code as a parameter in the publishers,
and technically nothing is broken until additional languages are synced,
but I wanted to mention this.
• I wasn‘t sure how I should approach translations when they‘re missing.
Should I take the existing approach, take the translated text or default
text, or should I only take the translated text, and if it doesn‘t
exist, skip that property?
This is mainly an issue with the product body. If Ext. Text is
translated, but Attributes are not, should I skip on attributes or send
attributes in the default language?
Currently, I skip the Title if it‘s not translated, but I send the body
in every case. Let me know if that should be changed.
• For the update of a translation, I need to send the
TranslatableContentDigest as part of the request. Currently, I‘ve done
this in a way, that I collect all digests for a resource during an
update, but that means that every update of a product/variant now has an
additional „get“ call, before it maybe sends an update for translations.
I think this could be done better, and would appreciate your input here.
• Resource Type is almost the same enum as used in Metafields, I think
these two should be made the same.
• I‘m not a fan of what I did with Translations Mgt. Is there a better
place where I could put this procedure for retrieving the item
translation?

Fixes microsoft#26819
Fixes
[AB#460580](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/460580)

---------

Co-authored-by: Tine Staric <[email protected]>
Co-authored-by: Jesper Schulz-Wedde <[email protected]>

[Shopify] Add Metafields to Products and Variants (microsoft#26185)

This is a PR without a dedicated issue as it's part of delivery for
development agreed directly with @AndreiPanko

Here's the overview of the changes:

Obsolete fields:
• Obsoleted Value Type as it‘s no longer used in Shopify API -> Replaced
with Type field
• Obsoleted Owner Resource field. I‘m not sure why this was a free text
that was then always populated through a case statement. It‘s replaced
with an Owner Type field that is an Enum.

New enums and interfaces:
• „Shpfy Metafield Type“ and „Shpfy IMetafield Type“ – Used for handling
the metafield type. The interface defines if the type has a special
AssistEdit, logic to execute the assist edit, and validations when free
input is allowed for a value. I have a couple of questions here, see
below. Rating, Rich Text, and List Types are not included, Rating and
Rich Text options are added but commented out so it‘s clear that it was
intentional. It also has String and Integer types which are there to
support backward compatibility, if old values are still in Shopify.
• „Shpfy Metafield Owner Type“ and „Shpfy IMetafield Owner Type“ – Used
for building the full owner resource ID
(gid://shopify/<ownerType>/<ownerId>) and for retrieving metafield IDs
of a single resource (used during export, to identify which metafields
should be sent for update based on UpdatedAt)
• Metafield Dimenion/Volume/Weight Type – three enums to support a
selection of Units when assist editing these metafield types

Pages:
• „Shpfy Metafields“ – used for viewing and editing metafields for a
resource. It‘s only editable if Shop is syncing Products to Shopify and
Can update Shopify products. On Insert of a new record, it‘s immediately
sent to Shopify and is only inserted in the DB when we get back the
Shopify ID for the metafield. Types that have AssistEdit functionality
defined cannot be edited directly on the line. OnValidate of Value a
check is executed to ensure value is correct for a type.
• „Shpfy Metafield Assist Edit“ – used for assist edit of complex
metafield types. It has several groups defined, and only the appropriate
one is displayed to the user.
• Action for display metafields for a resource has been added to the
Products and Variants pages.

GraphQL query changes:
• ProductById and VariantById have been modified so that they retrieve
the first 50 metafields (previously the first 10). Previously there was
a filter to only retrieve Metafields with the
„Microsoft.Dynamics365.BusinessCentral“ namespace. I‘ve removed that to
get all the metafields of a resource.
• ProductMetafieldIds and VariantMetafieldIds were added. These are used
during the export of metafields to determine which BC metafields should
be sent for an update
• MetafieldsSet – This is used to create/update metafields for a
resource

Changes to API codeunits:
• Product API – on UpdateShopifyProductFields a metafields part of JSON
is now passed to Metafields API where it creates or updates Metafields
in BC based on information retrieved from Shopify
• Variant API – on UpdateShopifyVariantFields the metafields part of the
JSON is passed to Metafields API, same as above.
• „Shpfy Product Export“ – on UpdateProductData execute Metafields API
to update/create metafields for the product and all variants that belong
to the product
• „Metafield API“ – Implements logic to parse the „metafields“JSON that
is retrieved with products/variants during import and creates/updates
metafield records in BC.
Adds logic to export metafields for a specific resource. Only sends an
update for metafields that have a lower UpdatedAt timestamp than BC
record‘s last updated at timestamp. It batches the Metafields to 25 at a
time, as that‘s the max MetafieldsSet mutation can handle as per the
documentation.

Added logic to delete metafields on delete of a product/variant

A couple of questions or concerns:
• New metafields that get created in Shopify do not have a Metafield
Definition attached to them. Should we care about this right now? If
yes, should we also store metafield definitions in BC, or just create
new definitions if any are missing in Shopify?
• I‘ve obsoleted the two fields and one enum, should I be wrapping the
obsoletions in some preprocessing symbols? Which one?
• I‘m doing some regex validations when checking if the value of
metafield is correct. I‘m not sure if the one for mixed reference and
file reference is correct. I‘d appreciate it if someone could take a
look at that.
• If value validation fails, it throws a pretty „simple“ error message
right now, should I make this more expressive?
• Currently, the „update metafields“ has no error handling in place if
the update query fails. Technically I‘m trying to catch everything on
data input, but there can always be unexpected situations. How should I
handle this?
• The code for sending the metafield to Shopify immediately after it‘s
inserted through UI is currently on the Page‘s OnInsertRecord trigger.
I‘m not sure about it, should I move it to the table trigger? The
hesitation is because there already is some logic on the table from the
partial implementation of metafields on Customers.
• I‘ve placed interface implementations in a separate folder under
Codeunits folder, that‘s not the usual practice on MS apps, so I wanted
to double-check it.
• Money metafield type needs to have the same currency as the shop,
which leads to this completely separate code path after validating the
Value. I‘m not sure if there‘s a better approach to handle this.
• I saw that most procedures in the app have documentation triggers that
are not really beneficial. I‘ve only added them to the public or
internal procedures. I‘ve also skipped on most object documentation
triggers.

Fixes microsoft#26819
Fixes
[AB#443908](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/443908)

---------

Co-authored-by: Tine Staric <[email protected]>
Co-authored-by: Jesper Schulz-Wedde <[email protected]>
Co-authored-by: Onat Buyukakkus <[email protected]>

Syncing with version 25.0.23141.0 (microsoft#27112)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

[Shopify] Connector - Export Posted Sales Invoices to Shopify as Orders (microsoft#26748)

This pull request does not have a related issue as it's part of the
delivery for development agreed directly
with [@AndreiPanko](https://github.com/AndreiPanko)

Here's a quick summary:

Orders.

Shopify Shop has a **new action "Payment Terms Mapping"** that takes the
user to the **new page "Shopify Payment Terms Mapping"**. Shopify
Payment Terms cannot be manually inserted or deleted, they can only be
refreshed with an action that pulls them from Shopify. By default
**FIXED** Payment Term is selected as primary during the synchronization
of the Payment Terms.
Before Posted Sales Invoices can be synced, a payment term code from
Shopify needs to be mapped to the Business Central one or a primary
Shopify Payment Term needs to be selected with a Boolean "Is Primary" -
this payment term will be used if the Posted Sales Invoice payment terms
code doesn't have a mapping to Shopify. This payment term code will also
be filled during the sync of Shopify orders.

A new Scope is required. To update payment terms on a draft order –
write_payment_terms (read_payment_terms scope was removed because it
causes strange behavior - every time a Shopify shop card is opened it
states that the scope has changed and requires authorization.
write_payment_terms overwrites read_payment_terms). To create a draft
order - write_draft_orders.

need to meet:

- The **new Boolean field "Posted Invoice Sync"** needs to be enabled.
- The "Shopify Order Id" field on the Posted Sales Invoice needs to be
0.
- Posted Sales Invoice "Bill-To Customer" has been mapped to the Shopify
Customer or Shopify Companies table.
- Posted Sales Invoice "Bill-To Customer" is not a customer used as a
Default Customer in the Shopify Shop Card or Shopify Customer Template.
- There are no lines of type non-comment (or type is populated but No.
is empty).
- There are no fraction quantities.
- There must be a mapped Payment Terms Code or a selected Primary
Payment Terms Code on the new "Shopify Payment Terms Mapping" page.
- If there is at least one line of type "Item" where the selected
item/variant doesn’t have a link to Shopify Product/Shopify variant and
the **new Boolean field "Items must be mapped to Products"** on the
Shopify Shop card is selected - the Posted Sales Invoice will not be
exported.
- Posted Sales Invoice currency code matches Shopify shop currency code
(explanation at the bottom).

If one of the previous conditions is not met, the Posted Sales Invoice
"Shopify Order Id" field will be marked with -2. If the GraphQL request
fails, then the field will be marked with -1. If everything goes
correctly, the field will be filled with the created Shopify Order ID.
Users can modify the "Shopify Order Id" field in the posted document
(allowed changes from -1 or -2 to 0. The functionality works the same as
in the Update Posted Shipment document.)

This export can be executed with a new action that is added to Shopify
Shop - "Sync Posted Sales Invoices" or just by running the report "Sync
Invoices to Shopify". The draft order in Shopify is created with the
values from the Posted Sales Invoice order and lines. If the Remaining
Amount of the Posted Sales Invoice is 0, then the order is marked as
paid, otherwise, the status will be "Payment pending" and a mapped
Payment Terms code will be sent out. After that, the created draft order
will be completed and the Shopify order created. All orders are
automatically fulfilled. To achieve “paid” status on the Shopify order –
use the Manual payment function in the Shopify Order card. Once the
report is executed, the Inventory will be synced.

Order sync will import created orders, then check if the order is
present in the **new Shopify Invoice Header table** (this table is
filled with the Shopify order ID of the exported Posted Sales Invoice)
and if so:
- Shopify Order is marked as processed.
- A link is added to the Posted Sales Invoice (related documents).

functionality:
- All non-comment type lines are exported as custom products (including
Items if the new Boolean field "Items must be mapped to Products"** on
the Shopify Shop card is not selected).
- Taxes from the lines are sent out as a custom product with the title
consisting of "VAT Calculation Type" + VAT %.
- Invoice discounts from the lines and the header are added up and sent
out as a discount to the whole order with the title "Invoice Discount
Amount"
- Posted Sales Invoice comments are exported as notes.
- Once the draft order is completed, an order confirmation email will be
sent out to the customer. This functionality is from Shopify itself.
- If the product/variant exists in Shopify, the price, title and other
information will be taken from Shopify and not the one in the Posted
Sales Invoice line. This is how the draftOrderCreate mutation works.

- Open orders and open invoices.
- Fulfillment/Tracking Details.
- Refund / partial refund status.
- Weight export.

**Known issues with different currencies (that's why Posted Sales
Invoices with different currencies than Shopify Shop cannot be exported
at the moment):**
- Currently sending out different currencies than the Shopify Shop
currency cannot be done because if the currency of the custom product
differs from the Shopify shop's currency, the amount sent will still be
accepted in the local Shopify shop's currency before being converted to
the order's currency and the amount will be incorrect. For example, if
the VAT amount is 100 GBP, but the Shopify shop's currency is EUR, the
custom product will be exported with an amount of 100 GBP. However, this
amount will be treated as 100 EUR and then converted to GBP according to
the currency exchange rate in Shopify.

Fixes microsoft#26819
Fixes
[AB#446399](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/446399)

---------

Co-authored-by: Jesper Schulz-Wedde <[email protected]>
Co-authored-by: Tine Staric <[email protected]>

GP - Update migrations with 1099 data to use the new IRS Forms app. (microsoft#27100)

The update enhances the GP migration to use the new IRS Forms app, which
replaces the base app implementation of 1099 handling.

Fixes microsoft#26487

Fixes
[AB#545622](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/545622)

---------

Co-authored-by: jaymckinney <[email protected]>

Removing the Order taker app (microsoft#27221)

Fixes
[AB#539591](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/539591)
aholstrup1 pushed a commit to aholstrup1/ALAppExtensions that referenced this issue Sep 9, 2024
Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

---------

Co-authored-by: Alexander Holstrup <[email protected]>

[Shopify] Shopify return location on refunds (microsoft#26728)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

Added a setting to the shopify shop to use original return location
(From shopify) or a default return location set in the Shopify shop when
creating Credit Memos for Refunds.

Modified the return and refund creation to pull original location from
shopify refund or return orders.
When an item on a single return order in shopify is restocked to
multiple locations, we cannot determine a single location to put on a
return line.

If there is any reason that Original location couldn't be determined
then the Default Return Location will be used during the creation of a
Credit Memo.

Fixes microsoft#26819

Fixes
[AB#540965](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/540965)

---------

Co-authored-by: Tine Staric <[email protected]>

[Shopify] Connector - Different shipping charges types (microsoft#26708)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

Quick summary:

The Shopify Shipping Method Mapping page/table was extended to include a
new Shipping Charges Type field, allowing users to select from GL, Item,
or Item Charge. Depending on this selection, the Shipping Charges No.
field opens the related table (item, GL, or item charges), and when an
order is created, the shipping charge line reflects the new type and
number. For Item Charges, a default allocation process is run for all
item lines. The settings in the Shopify Shipping Method Mapping now take
priority over those in the Shopify Shop - GL Account settings.
Additionally, if the Shipping Agent Code and Shipping Agent Service
fields are populated, they are automatically populated in the sales
order as well.

Fixes microsoft#26819

[AB#449477](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/449477)

---------

Co-authored-by: aidasberesinevicius <[email protected]>
Co-authored-by: Tine Staric <[email protected]>

[Shopify] Add items as product variants (microsoft#26712)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

Added an action to Variants subpage to add BC Items as additional
Variants to an existing Shopify Product.
If the parent product only had a default variant before the addition, it
is deleted from both Shopify and BC.
The variants are added under the existing the Product Option (ex. Color,
Material, or Title, if product only had the default variant)

Items cannot be added if the shop has "UOM as Variant" enabled, or if
the parent product has more than one option defined.

Fixes microsoft#26819
Fixes
[AB#468218](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/468218)

---------

Co-authored-by: Tine Staric <[email protected]>
Co-authored-by: Jesper Schulz-Wedde <[email protected]>
Co-authored-by: Onat Buyukakkus <[email protected]>

Update Yavrio in ConnectivityAppDefinitions.Codeunit.al (microsoft#26886)

Added US to Yavrio Open Banking

Fixes
[AB#543398](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/543398)

Syncing with version 25.0.22639.0 (microsoft#26958)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

---------

Co-authored-by: Jesper Schulz-Wedde <[email protected]>

Syncing with version 25.0.22684.0 (microsoft#26959)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

[Fix] URL maximum length in E-Document Integration (microsoft#26730)

Added a new field "Request URL" to table 6127 "E-Document Integration
Log" with a maximum string length of 2048 to allow for longer URLs when
using the "E-Document Integration" interface. The new filed replaces the
existing field URL. I marked the existing field as obsolete and updated
three (all) references from the old URL field to the new "Request URL"
field.

needs to be open and approved. Submitting PRs with no linked issues or
unapproved issues is highly discouraged. -->
Fixes microsoft#26672

Fixes
[AB#540448](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/540448)

---------

Co-authored-by: Patrick Lüthi <[email protected]>

Update InstallSECore.codeunit.al (microsoft#26883)

Update CODEOWNERS with EDocument reviewers (microsoft#27067)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

GP Updates - July 2024 (microsoft#26821)

This update enhances the GP migrations by:

- Migrating GP Kit Items as BC Assembly BOMs.
- Prevent migration error when Customer/Vendor phone numbers contain
alpha characters. The Customer/Vendors will be migrated, but the
phone/fax numbers with alpha characters will be ignored and added to the
Warning Log.
- History Gen. Journal Line - View Distributions feature.
- Updated labels in settings area to specify 'migration' instead of
'upgrade' to prevent customer confusion.

Fixes microsoft#26487
Fixes
[AB#543399](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/543399)

---------

Co-authored-by: jaymckinney <[email protected]>

[Shopify][BC Idea]: Enhancing Shopify Connector for Accurate Price Synchronization with Business Central based on Customer (microsoft#26981)

Added Customer No to the
          table 30152 "Shpfy Catalog"
          page 30159 "Shpfy Catalogs"

Added logic to use customer specific pricing from catalog
           codeunit 30182 "Shpfy Product Price Calc."

Fixes microsoft#26980
Fixes
[AB#544010](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/544010)

[Shopify] Add Translations Export to Products and Variants (microsoft#26216)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

here‘s a quick summary:

Shopify Shop has a new action that takes the user to the Languages page.
Languages cannot be manually inserted or deleted, they can only be
refreshed with an action that pulls them from Shopify.
Before a language can be enabled for syncing, a language code needs to
be mapped to it, as Shopify is using locales, and I can‘t directly map
them.

A new Scope is required to get shop locales – read_locales

On export of products and variants, an update of translations is
triggered. The translation update first collects all
TranslatableContentDigests for a resource, as these are needed when
requesting an update of a translation.
The update next collects translations for the product Title, Product
Body, and Variant „option 1“ in a temporary table for each enabled
language. It compares the translations with the translations that were
last synced. If the translation is the same, it removes it from the
buffer. Next, the buffer is used to build the query and sent to Shopify
to update translations.

Continuing with a couple of questions/considerations regarding the issue

• The way I designed Shopify Languages is that the user can‘t
insert/delete them, but has to pull them from Shopify with an action.
This uses ShopLocales query which needs a read_locales scope that‘s not
currently part of the scopes. I wasn‘t sure if that‘s an issue or not.
• I made the import of locales skip the primary language as I wanted to
keep the logic for that one on the Shop.“Langauge Code“ field.
• I‘ve refactored the CreateProductBody procedure in the Product Export
codeunit so it takes the language code as a parameter. This means I can
reuse it for translations, however, there are events in this procedure
at the start/end, which will now trigger more often if more languages
are synced. I added the language code as a parameter in the publishers,
and technically nothing is broken until additional languages are synced,
but I wanted to mention this.
• I wasn‘t sure how I should approach translations when they‘re missing.
Should I take the existing approach, take the translated text or default
text, or should I only take the translated text, and if it doesn‘t
exist, skip that property?
This is mainly an issue with the product body. If Ext. Text is
translated, but Attributes are not, should I skip on attributes or send
attributes in the default language?
Currently, I skip the Title if it‘s not translated, but I send the body
in every case. Let me know if that should be changed.
• For the update of a translation, I need to send the
TranslatableContentDigest as part of the request. Currently, I‘ve done
this in a way, that I collect all digests for a resource during an
update, but that means that every update of a product/variant now has an
additional „get“ call, before it maybe sends an update for translations.
I think this could be done better, and would appreciate your input here.
• Resource Type is almost the same enum as used in Metafields, I think
these two should be made the same.
• I‘m not a fan of what I did with Translations Mgt. Is there a better
place where I could put this procedure for retrieving the item
translation?

Fixes microsoft#26819
Fixes
[AB#460580](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/460580)

---------

Co-authored-by: Tine Staric <[email protected]>
Co-authored-by: Jesper Schulz-Wedde <[email protected]>

[Shopify] Add Metafields to Products and Variants (microsoft#26185)

This is a PR without a dedicated issue as it's part of delivery for
development agreed directly with @AndreiPanko

Here's the overview of the changes:

Obsolete fields:
• Obsoleted Value Type as it‘s no longer used in Shopify API -> Replaced
with Type field
• Obsoleted Owner Resource field. I‘m not sure why this was a free text
that was then always populated through a case statement. It‘s replaced
with an Owner Type field that is an Enum.

New enums and interfaces:
• „Shpfy Metafield Type“ and „Shpfy IMetafield Type“ – Used for handling
the metafield type. The interface defines if the type has a special
AssistEdit, logic to execute the assist edit, and validations when free
input is allowed for a value. I have a couple of questions here, see
below. Rating, Rich Text, and List Types are not included, Rating and
Rich Text options are added but commented out so it‘s clear that it was
intentional. It also has String and Integer types which are there to
support backward compatibility, if old values are still in Shopify.
• „Shpfy Metafield Owner Type“ and „Shpfy IMetafield Owner Type“ – Used
for building the full owner resource ID
(gid://shopify/<ownerType>/<ownerId>) and for retrieving metafield IDs
of a single resource (used during export, to identify which metafields
should be sent for update based on UpdatedAt)
• Metafield Dimenion/Volume/Weight Type – three enums to support a
selection of Units when assist editing these metafield types

Pages:
• „Shpfy Metafields“ – used for viewing and editing metafields for a
resource. It‘s only editable if Shop is syncing Products to Shopify and
Can update Shopify products. On Insert of a new record, it‘s immediately
sent to Shopify and is only inserted in the DB when we get back the
Shopify ID for the metafield. Types that have AssistEdit functionality
defined cannot be edited directly on the line. OnValidate of Value a
check is executed to ensure value is correct for a type.
• „Shpfy Metafield Assist Edit“ – used for assist edit of complex
metafield types. It has several groups defined, and only the appropriate
one is displayed to the user.
• Action for display metafields for a resource has been added to the
Products and Variants pages.

GraphQL query changes:
• ProductById and VariantById have been modified so that they retrieve
the first 50 metafields (previously the first 10). Previously there was
a filter to only retrieve Metafields with the
„Microsoft.Dynamics365.BusinessCentral“ namespace. I‘ve removed that to
get all the metafields of a resource.
• ProductMetafieldIds and VariantMetafieldIds were added. These are used
during the export of metafields to determine which BC metafields should
be sent for an update
• MetafieldsSet – This is used to create/update metafields for a
resource

Changes to API codeunits:
• Product API – on UpdateShopifyProductFields a metafields part of JSON
is now passed to Metafields API where it creates or updates Metafields
in BC based on information retrieved from Shopify
• Variant API – on UpdateShopifyVariantFields the metafields part of the
JSON is passed to Metafields API, same as above.
• „Shpfy Product Export“ – on UpdateProductData execute Metafields API
to update/create metafields for the product and all variants that belong
to the product
• „Metafield API“ – Implements logic to parse the „metafields“JSON that
is retrieved with products/variants during import and creates/updates
metafield records in BC.
Adds logic to export metafields for a specific resource. Only sends an
update for metafields that have a lower UpdatedAt timestamp than BC
record‘s last updated at timestamp. It batches the Metafields to 25 at a
time, as that‘s the max MetafieldsSet mutation can handle as per the
documentation.

Added logic to delete metafields on delete of a product/variant

A couple of questions or concerns:
• New metafields that get created in Shopify do not have a Metafield
Definition attached to them. Should we care about this right now? If
yes, should we also store metafield definitions in BC, or just create
new definitions if any are missing in Shopify?
• I‘ve obsoleted the two fields and one enum, should I be wrapping the
obsoletions in some preprocessing symbols? Which one?
• I‘m doing some regex validations when checking if the value of
metafield is correct. I‘m not sure if the one for mixed reference and
file reference is correct. I‘d appreciate it if someone could take a
look at that.
• If value validation fails, it throws a pretty „simple“ error message
right now, should I make this more expressive?
• Currently, the „update metafields“ has no error handling in place if
the update query fails. Technically I‘m trying to catch everything on
data input, but there can always be unexpected situations. How should I
handle this?
• The code for sending the metafield to Shopify immediately after it‘s
inserted through UI is currently on the Page‘s OnInsertRecord trigger.
I‘m not sure about it, should I move it to the table trigger? The
hesitation is because there already is some logic on the table from the
partial implementation of metafields on Customers.
• I‘ve placed interface implementations in a separate folder under
Codeunits folder, that‘s not the usual practice on MS apps, so I wanted
to double-check it.
• Money metafield type needs to have the same currency as the shop,
which leads to this completely separate code path after validating the
Value. I‘m not sure if there‘s a better approach to handle this.
• I saw that most procedures in the app have documentation triggers that
are not really beneficial. I‘ve only added them to the public or
internal procedures. I‘ve also skipped on most object documentation
triggers.

Fixes microsoft#26819
Fixes
[AB#443908](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/443908)

---------

Co-authored-by: Tine Staric <[email protected]>
Co-authored-by: Jesper Schulz-Wedde <[email protected]>
Co-authored-by: Onat Buyukakkus <[email protected]>

Syncing with version 25.0.23141.0 (microsoft#27112)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

[Shopify] Connector - Export Posted Sales Invoices to Shopify as Orders (microsoft#26748)

This pull request does not have a related issue as it's part of the
delivery for development agreed directly
with [@AndreiPanko](https://github.com/AndreiPanko)

Here's a quick summary:

Orders.

Shopify Shop has a **new action "Payment Terms Mapping"** that takes the
user to the **new page "Shopify Payment Terms Mapping"**. Shopify
Payment Terms cannot be manually inserted or deleted, they can only be
refreshed with an action that pulls them from Shopify. By default
**FIXED** Payment Term is selected as primary during the synchronization
of the Payment Terms.
Before Posted Sales Invoices can be synced, a payment term code from
Shopify needs to be mapped to the Business Central one or a primary
Shopify Payment Term needs to be selected with a Boolean "Is Primary" -
this payment term will be used if the Posted Sales Invoice payment terms
code doesn't have a mapping to Shopify. This payment term code will also
be filled during the sync of Shopify orders.

A new Scope is required. To update payment terms on a draft order –
write_payment_terms (read_payment_terms scope was removed because it
causes strange behavior - every time a Shopify shop card is opened it
states that the scope has changed and requires authorization.
write_payment_terms overwrites read_payment_terms). To create a draft
order - write_draft_orders.

need to meet:

- The **new Boolean field "Posted Invoice Sync"** needs to be enabled.
- The "Shopify Order Id" field on the Posted Sales Invoice needs to be
0.
- Posted Sales Invoice "Bill-To Customer" has been mapped to the Shopify
Customer or Shopify Companies table.
- Posted Sales Invoice "Bill-To Customer" is not a customer used as a
Default Customer in the Shopify Shop Card or Shopify Customer Template.
- There are no lines of type non-comment (or type is populated but No.
is empty).
- There are no fraction quantities.
- There must be a mapped Payment Terms Code or a selected Primary
Payment Terms Code on the new "Shopify Payment Terms Mapping" page.
- If there is at least one line of type "Item" where the selected
item/variant doesn’t have a link to Shopify Product/Shopify variant and
the **new Boolean field "Items must be mapped to Products"** on the
Shopify Shop card is selected - the Posted Sales Invoice will not be
exported.
- Posted Sales Invoice currency code matches Shopify shop currency code
(explanation at the bottom).

If one of the previous conditions is not met, the Posted Sales Invoice
"Shopify Order Id" field will be marked with -2. If the GraphQL request
fails, then the field will be marked with -1. If everything goes
correctly, the field will be filled with the created Shopify Order ID.
Users can modify the "Shopify Order Id" field in the posted document
(allowed changes from -1 or -2 to 0. The functionality works the same as
in the Update Posted Shipment document.)

This export can be executed with a new action that is added to Shopify
Shop - "Sync Posted Sales Invoices" or just by running the report "Sync
Invoices to Shopify". The draft order in Shopify is created with the
values from the Posted Sales Invoice order and lines. If the Remaining
Amount of the Posted Sales Invoice is 0, then the order is marked as
paid, otherwise, the status will be "Payment pending" and a mapped
Payment Terms code will be sent out. After that, the created draft order
will be completed and the Shopify order created. All orders are
automatically fulfilled. To achieve “paid” status on the Shopify order –
use the Manual payment function in the Shopify Order card. Once the
report is executed, the Inventory will be synced.

Order sync will import created orders, then check if the order is
present in the **new Shopify Invoice Header table** (this table is
filled with the Shopify order ID of the exported Posted Sales Invoice)
and if so:
- Shopify Order is marked as processed.
- A link is added to the Posted Sales Invoice (related documents).

functionality:
- All non-comment type lines are exported as custom products (including
Items if the new Boolean field "Items must be mapped to Products"** on
the Shopify Shop card is not selected).
- Taxes from the lines are sent out as a custom product with the title
consisting of "VAT Calculation Type" + VAT %.
- Invoice discounts from the lines and the header are added up and sent
out as a discount to the whole order with the title "Invoice Discount
Amount"
- Posted Sales Invoice comments are exported as notes.
- Once the draft order is completed, an order confirmation email will be
sent out to the customer. This functionality is from Shopify itself.
- If the product/variant exists in Shopify, the price, title and other
information will be taken from Shopify and not the one in the Posted
Sales Invoice line. This is how the draftOrderCreate mutation works.

- Open orders and open invoices.
- Fulfillment/Tracking Details.
- Refund / partial refund status.
- Weight export.

**Known issues with different currencies (that's why Posted Sales
Invoices with different currencies than Shopify Shop cannot be exported
at the moment):**
- Currently sending out different currencies than the Shopify Shop
currency cannot be done because if the currency of the custom product
differs from the Shopify shop's currency, the amount sent will still be
accepted in the local Shopify shop's currency before being converted to
the order's currency and the amount will be incorrect. For example, if
the VAT amount is 100 GBP, but the Shopify shop's currency is EUR, the
custom product will be exported with an amount of 100 GBP. However, this
amount will be treated as 100 EUR and then converted to GBP according to
the currency exchange rate in Shopify.

Fixes microsoft#26819
Fixes
[AB#446399](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/446399)

---------

Co-authored-by: Jesper Schulz-Wedde <[email protected]>
Co-authored-by: Tine Staric <[email protected]>

GP - Update migrations with 1099 data to use the new IRS Forms app. (microsoft#27100)

The update enhances the GP migration to use the new IRS Forms app, which
replaces the base app implementation of 1099 handling.

Fixes microsoft#26487

Fixes
[AB#545622](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/545622)

---------

Co-authored-by: jaymckinney <[email protected]>

Removing the Order taker app (microsoft#27221)

Fixes
[AB#539591](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/539591)
aholstrup1 pushed a commit that referenced this issue Sep 9, 2024
Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

---------

Co-authored-by: Alexander Holstrup <[email protected]>

[Shopify] Shopify return location on refunds (#26728)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

Added a setting to the shopify shop to use original return location
(From shopify) or a default return location set in the Shopify shop when
creating Credit Memos for Refunds.

Modified the return and refund creation to pull original location from
shopify refund or return orders.
When an item on a single return order in shopify is restocked to
multiple locations, we cannot determine a single location to put on a
return line.

If there is any reason that Original location couldn't be determined
then the Default Return Location will be used during the creation of a
Credit Memo.

Fixes #26819

Fixes
[AB#540965](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/540965)

---------

Co-authored-by: Tine Staric <[email protected]>

[Shopify] Connector - Different shipping charges types (#26708)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

Quick summary:

The Shopify Shipping Method Mapping page/table was extended to include a
new Shipping Charges Type field, allowing users to select from GL, Item,
or Item Charge. Depending on this selection, the Shipping Charges No.
field opens the related table (item, GL, or item charges), and when an
order is created, the shipping charge line reflects the new type and
number. For Item Charges, a default allocation process is run for all
item lines. The settings in the Shopify Shipping Method Mapping now take
priority over those in the Shopify Shop - GL Account settings.
Additionally, if the Shipping Agent Code and Shipping Agent Service
fields are populated, they are automatically populated in the sales
order as well.

Fixes #26819

[AB#449477](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/449477)

---------

Co-authored-by: aidasberesinevicius <[email protected]>
Co-authored-by: Tine Staric <[email protected]>

[Shopify] Add items as product variants (#26712)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

Added an action to Variants subpage to add BC Items as additional
Variants to an existing Shopify Product.
If the parent product only had a default variant before the addition, it
is deleted from both Shopify and BC.
The variants are added under the existing the Product Option (ex. Color,
Material, or Title, if product only had the default variant)

Items cannot be added if the shop has "UOM as Variant" enabled, or if
the parent product has more than one option defined.

Fixes #26819
Fixes
[AB#468218](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/468218)

---------

Co-authored-by: Tine Staric <[email protected]>
Co-authored-by: Jesper Schulz-Wedde <[email protected]>
Co-authored-by: Onat Buyukakkus <[email protected]>

Update Yavrio in ConnectivityAppDefinitions.Codeunit.al (#26886)

Added US to Yavrio Open Banking

Fixes
[AB#543398](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/543398)

Syncing with version 25.0.22639.0 (#26958)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

---------

Co-authored-by: Jesper Schulz-Wedde <[email protected]>

Syncing with version 25.0.22684.0 (#26959)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

[Fix] URL maximum length in E-Document Integration (#26730)

Added a new field "Request URL" to table 6127 "E-Document Integration
Log" with a maximum string length of 2048 to allow for longer URLs when
using the "E-Document Integration" interface. The new filed replaces the
existing field URL. I marked the existing field as obsolete and updated
three (all) references from the old URL field to the new "Request URL"
field.

needs to be open and approved. Submitting PRs with no linked issues or
unapproved issues is highly discouraged. -->
Fixes #26672

Fixes
[AB#540448](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/540448)

---------

Co-authored-by: Patrick Lüthi <[email protected]>

Update InstallSECore.codeunit.al (#26883)

Update CODEOWNERS with EDocument reviewers (#27067)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

GP Updates - July 2024 (#26821)

This update enhances the GP migrations by:

- Migrating GP Kit Items as BC Assembly BOMs.
- Prevent migration error when Customer/Vendor phone numbers contain
alpha characters. The Customer/Vendors will be migrated, but the
phone/fax numbers with alpha characters will be ignored and added to the
Warning Log.
- History Gen. Journal Line - View Distributions feature.
- Updated labels in settings area to specify 'migration' instead of
'upgrade' to prevent customer confusion.

Fixes #26487
Fixes
[AB#543399](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/543399)

---------

Co-authored-by: jaymckinney <[email protected]>

[Shopify][BC Idea]: Enhancing Shopify Connector for Accurate Price Synchronization with Business Central based on Customer (#26981)

Added Customer No to the
          table 30152 "Shpfy Catalog"
          page 30159 "Shpfy Catalogs"

Added logic to use customer specific pricing from catalog
           codeunit 30182 "Shpfy Product Price Calc."

Fixes #26980
Fixes
[AB#544010](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/544010)

[Shopify] Add Translations Export to Products and Variants (#26216)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

here‘s a quick summary:

Shopify Shop has a new action that takes the user to the Languages page.
Languages cannot be manually inserted or deleted, they can only be
refreshed with an action that pulls them from Shopify.
Before a language can be enabled for syncing, a language code needs to
be mapped to it, as Shopify is using locales, and I can‘t directly map
them.

A new Scope is required to get shop locales – read_locales

On export of products and variants, an update of translations is
triggered. The translation update first collects all
TranslatableContentDigests for a resource, as these are needed when
requesting an update of a translation.
The update next collects translations for the product Title, Product
Body, and Variant „option 1“ in a temporary table for each enabled
language. It compares the translations with the translations that were
last synced. If the translation is the same, it removes it from the
buffer. Next, the buffer is used to build the query and sent to Shopify
to update translations.

Continuing with a couple of questions/considerations regarding the issue

• The way I designed Shopify Languages is that the user can‘t
insert/delete them, but has to pull them from Shopify with an action.
This uses ShopLocales query which needs a read_locales scope that‘s not
currently part of the scopes. I wasn‘t sure if that‘s an issue or not.
• I made the import of locales skip the primary language as I wanted to
keep the logic for that one on the Shop.“Langauge Code“ field.
• I‘ve refactored the CreateProductBody procedure in the Product Export
codeunit so it takes the language code as a parameter. This means I can
reuse it for translations, however, there are events in this procedure
at the start/end, which will now trigger more often if more languages
are synced. I added the language code as a parameter in the publishers,
and technically nothing is broken until additional languages are synced,
but I wanted to mention this.
• I wasn‘t sure how I should approach translations when they‘re missing.
Should I take the existing approach, take the translated text or default
text, or should I only take the translated text, and if it doesn‘t
exist, skip that property?
This is mainly an issue with the product body. If Ext. Text is
translated, but Attributes are not, should I skip on attributes or send
attributes in the default language?
Currently, I skip the Title if it‘s not translated, but I send the body
in every case. Let me know if that should be changed.
• For the update of a translation, I need to send the
TranslatableContentDigest as part of the request. Currently, I‘ve done
this in a way, that I collect all digests for a resource during an
update, but that means that every update of a product/variant now has an
additional „get“ call, before it maybe sends an update for translations.
I think this could be done better, and would appreciate your input here.
• Resource Type is almost the same enum as used in Metafields, I think
these two should be made the same.
• I‘m not a fan of what I did with Translations Mgt. Is there a better
place where I could put this procedure for retrieving the item
translation?

Fixes #26819
Fixes
[AB#460580](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/460580)

---------

Co-authored-by: Tine Staric <[email protected]>
Co-authored-by: Jesper Schulz-Wedde <[email protected]>

[Shopify] Add Metafields to Products and Variants (#26185)

This is a PR without a dedicated issue as it's part of delivery for
development agreed directly with @AndreiPanko

Here's the overview of the changes:

Obsolete fields:
• Obsoleted Value Type as it‘s no longer used in Shopify API -> Replaced
with Type field
• Obsoleted Owner Resource field. I‘m not sure why this was a free text
that was then always populated through a case statement. It‘s replaced
with an Owner Type field that is an Enum.

New enums and interfaces:
• „Shpfy Metafield Type“ and „Shpfy IMetafield Type“ – Used for handling
the metafield type. The interface defines if the type has a special
AssistEdit, logic to execute the assist edit, and validations when free
input is allowed for a value. I have a couple of questions here, see
below. Rating, Rich Text, and List Types are not included, Rating and
Rich Text options are added but commented out so it‘s clear that it was
intentional. It also has String and Integer types which are there to
support backward compatibility, if old values are still in Shopify.
• „Shpfy Metafield Owner Type“ and „Shpfy IMetafield Owner Type“ – Used
for building the full owner resource ID
(gid://shopify/<ownerType>/<ownerId>) and for retrieving metafield IDs
of a single resource (used during export, to identify which metafields
should be sent for update based on UpdatedAt)
• Metafield Dimenion/Volume/Weight Type – three enums to support a
selection of Units when assist editing these metafield types

Pages:
• „Shpfy Metafields“ – used for viewing and editing metafields for a
resource. It‘s only editable if Shop is syncing Products to Shopify and
Can update Shopify products. On Insert of a new record, it‘s immediately
sent to Shopify and is only inserted in the DB when we get back the
Shopify ID for the metafield. Types that have AssistEdit functionality
defined cannot be edited directly on the line. OnValidate of Value a
check is executed to ensure value is correct for a type.
• „Shpfy Metafield Assist Edit“ – used for assist edit of complex
metafield types. It has several groups defined, and only the appropriate
one is displayed to the user.
• Action for display metafields for a resource has been added to the
Products and Variants pages.

GraphQL query changes:
• ProductById and VariantById have been modified so that they retrieve
the first 50 metafields (previously the first 10). Previously there was
a filter to only retrieve Metafields with the
„Microsoft.Dynamics365.BusinessCentral“ namespace. I‘ve removed that to
get all the metafields of a resource.
• ProductMetafieldIds and VariantMetafieldIds were added. These are used
during the export of metafields to determine which BC metafields should
be sent for an update
• MetafieldsSet – This is used to create/update metafields for a
resource

Changes to API codeunits:
• Product API – on UpdateShopifyProductFields a metafields part of JSON
is now passed to Metafields API where it creates or updates Metafields
in BC based on information retrieved from Shopify
• Variant API – on UpdateShopifyVariantFields the metafields part of the
JSON is passed to Metafields API, same as above.
• „Shpfy Product Export“ – on UpdateProductData execute Metafields API
to update/create metafields for the product and all variants that belong
to the product
• „Metafield API“ – Implements logic to parse the „metafields“JSON that
is retrieved with products/variants during import and creates/updates
metafield records in BC.
Adds logic to export metafields for a specific resource. Only sends an
update for metafields that have a lower UpdatedAt timestamp than BC
record‘s last updated at timestamp. It batches the Metafields to 25 at a
time, as that‘s the max MetafieldsSet mutation can handle as per the
documentation.

Added logic to delete metafields on delete of a product/variant

A couple of questions or concerns:
• New metafields that get created in Shopify do not have a Metafield
Definition attached to them. Should we care about this right now? If
yes, should we also store metafield definitions in BC, or just create
new definitions if any are missing in Shopify?
• I‘ve obsoleted the two fields and one enum, should I be wrapping the
obsoletions in some preprocessing symbols? Which one?
• I‘m doing some regex validations when checking if the value of
metafield is correct. I‘m not sure if the one for mixed reference and
file reference is correct. I‘d appreciate it if someone could take a
look at that.
• If value validation fails, it throws a pretty „simple“ error message
right now, should I make this more expressive?
• Currently, the „update metafields“ has no error handling in place if
the update query fails. Technically I‘m trying to catch everything on
data input, but there can always be unexpected situations. How should I
handle this?
• The code for sending the metafield to Shopify immediately after it‘s
inserted through UI is currently on the Page‘s OnInsertRecord trigger.
I‘m not sure about it, should I move it to the table trigger? The
hesitation is because there already is some logic on the table from the
partial implementation of metafields on Customers.
• I‘ve placed interface implementations in a separate folder under
Codeunits folder, that‘s not the usual practice on MS apps, so I wanted
to double-check it.
• Money metafield type needs to have the same currency as the shop,
which leads to this completely separate code path after validating the
Value. I‘m not sure if there‘s a better approach to handle this.
• I saw that most procedures in the app have documentation triggers that
are not really beneficial. I‘ve only added them to the public or
internal procedures. I‘ve also skipped on most object documentation
triggers.

Fixes #26819
Fixes
[AB#443908](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/443908)

---------

Co-authored-by: Tine Staric <[email protected]>
Co-authored-by: Jesper Schulz-Wedde <[email protected]>
Co-authored-by: Onat Buyukakkus <[email protected]>

Syncing with version 25.0.23141.0 (#27112)

Fixes
[AB#420000](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/420000)

[Shopify] Connector - Export Posted Sales Invoices to Shopify as Orders (#26748)

This pull request does not have a related issue as it's part of the
delivery for development agreed directly
with [@AndreiPanko](https://github.com/AndreiPanko)

Here's a quick summary:

Orders.

Shopify Shop has a **new action "Payment Terms Mapping"** that takes the
user to the **new page "Shopify Payment Terms Mapping"**. Shopify
Payment Terms cannot be manually inserted or deleted, they can only be
refreshed with an action that pulls them from Shopify. By default
**FIXED** Payment Term is selected as primary during the synchronization
of the Payment Terms.
Before Posted Sales Invoices can be synced, a payment term code from
Shopify needs to be mapped to the Business Central one or a primary
Shopify Payment Term needs to be selected with a Boolean "Is Primary" -
this payment term will be used if the Posted Sales Invoice payment terms
code doesn't have a mapping to Shopify. This payment term code will also
be filled during the sync of Shopify orders.

A new Scope is required. To update payment terms on a draft order –
write_payment_terms (read_payment_terms scope was removed because it
causes strange behavior - every time a Shopify shop card is opened it
states that the scope has changed and requires authorization.
write_payment_terms overwrites read_payment_terms). To create a draft
order - write_draft_orders.

need to meet:

- The **new Boolean field "Posted Invoice Sync"** needs to be enabled.
- The "Shopify Order Id" field on the Posted Sales Invoice needs to be
0.
- Posted Sales Invoice "Bill-To Customer" has been mapped to the Shopify
Customer or Shopify Companies table.
- Posted Sales Invoice "Bill-To Customer" is not a customer used as a
Default Customer in the Shopify Shop Card or Shopify Customer Template.
- There are no lines of type non-comment (or type is populated but No.
is empty).
- There are no fraction quantities.
- There must be a mapped Payment Terms Code or a selected Primary
Payment Terms Code on the new "Shopify Payment Terms Mapping" page.
- If there is at least one line of type "Item" where the selected
item/variant doesn’t have a link to Shopify Product/Shopify variant and
the **new Boolean field "Items must be mapped to Products"** on the
Shopify Shop card is selected - the Posted Sales Invoice will not be
exported.
- Posted Sales Invoice currency code matches Shopify shop currency code
(explanation at the bottom).

If one of the previous conditions is not met, the Posted Sales Invoice
"Shopify Order Id" field will be marked with -2. If the GraphQL request
fails, then the field will be marked with -1. If everything goes
correctly, the field will be filled with the created Shopify Order ID.
Users can modify the "Shopify Order Id" field in the posted document
(allowed changes from -1 or -2 to 0. The functionality works the same as
in the Update Posted Shipment document.)

This export can be executed with a new action that is added to Shopify
Shop - "Sync Posted Sales Invoices" or just by running the report "Sync
Invoices to Shopify". The draft order in Shopify is created with the
values from the Posted Sales Invoice order and lines. If the Remaining
Amount of the Posted Sales Invoice is 0, then the order is marked as
paid, otherwise, the status will be "Payment pending" and a mapped
Payment Terms code will be sent out. After that, the created draft order
will be completed and the Shopify order created. All orders are
automatically fulfilled. To achieve “paid” status on the Shopify order –
use the Manual payment function in the Shopify Order card. Once the
report is executed, the Inventory will be synced.

Order sync will import created orders, then check if the order is
present in the **new Shopify Invoice Header table** (this table is
filled with the Shopify order ID of the exported Posted Sales Invoice)
and if so:
- Shopify Order is marked as processed.
- A link is added to the Posted Sales Invoice (related documents).

functionality:
- All non-comment type lines are exported as custom products (including
Items if the new Boolean field "Items must be mapped to Products"** on
the Shopify Shop card is not selected).
- Taxes from the lines are sent out as a custom product with the title
consisting of "VAT Calculation Type" + VAT %.
- Invoice discounts from the lines and the header are added up and sent
out as a discount to the whole order with the title "Invoice Discount
Amount"
- Posted Sales Invoice comments are exported as notes.
- Once the draft order is completed, an order confirmation email will be
sent out to the customer. This functionality is from Shopify itself.
- If the product/variant exists in Shopify, the price, title and other
information will be taken from Shopify and not the one in the Posted
Sales Invoice line. This is how the draftOrderCreate mutation works.

- Open orders and open invoices.
- Fulfillment/Tracking Details.
- Refund / partial refund status.
- Weight export.

**Known issues with different currencies (that's why Posted Sales
Invoices with different currencies than Shopify Shop cannot be exported
at the moment):**
- Currently sending out different currencies than the Shopify Shop
currency cannot be done because if the currency of the custom product
differs from the Shopify shop's currency, the amount sent will still be
accepted in the local Shopify shop's currency before being converted to
the order's currency and the amount will be incorrect. For example, if
the VAT amount is 100 GBP, but the Shopify shop's currency is EUR, the
custom product will be exported with an amount of 100 GBP. However, this
amount will be treated as 100 EUR and then converted to GBP according to
the currency exchange rate in Shopify.

Fixes #26819
Fixes
[AB#446399](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/446399)

---------

Co-authored-by: Jesper Schulz-Wedde <[email protected]>
Co-authored-by: Tine Staric <[email protected]>

GP - Update migrations with 1099 data to use the new IRS Forms app. (#27100)

The update enhances the GP migration to use the new IRS Forms app, which
replaces the base app implementation of 1099 handling.

Fixes #26487

Fixes
[AB#545622](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/545622)

---------

Co-authored-by: jaymckinney <[email protected]>

Removing the Order taker app (#27221)

Fixes
[AB#539591](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/539591)
@JesperSchulz
Copy link
Contributor Author

We've got more PRs. Re-opening issue.

@JesperSchulz JesperSchulz reopened this Oct 25, 2024
@JesperSchulz JesperSchulz added the Integration GitHub request for Integration area label Oct 25, 2024
@JesperSchulz JesperSchulz reopened this Oct 31, 2024
aholstrup1 pushed a commit that referenced this issue Nov 1, 2024
This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko
Fixes #26819

### Existing metafield engine applied to integrate Customer and Company
metafields

Changes done to apply the engine:

- Extended `ShpfyGQLCompany.Codeunit.al` and
`ShpfyGQLCustomer.Codeunit.al` GQL query to get metafields with required
properties in response. Removed the namespace from query to retreive all
metafields.
- Created 2 new GraphQL queries `Shpfy GQL CustomerMetafieldIds` and
`Shpfy GQL CompanyMetafieldIds` to make `RetrieveMetafieldsFromShopify`
function work with Company and Customer.
- Created 2 new IMetafield Owner Type implementation codeunits for
Company and Customer
- Added values to related interface enums
- Added UpdateMetafield functions in API codeunits to update metafields
if there are metafields in response
- Removed old not working code to update metafields
- Add Metafields actions to Company/Customer list and card pages.
- Add owner type Company to `GetOwnerType` procedure in `Shpfy
Metafield` table
- Changed parameters in `CollectMetafieldIds` local procedure in `Shpfy
Metafield API` codeunit to support all Ownet types in function

Fixes
[AB#556298](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/556298)

---------

Co-authored-by: Piotr Michalak <[email protected]>
aholstrup1 pushed a commit that referenced this issue Nov 1, 2024
This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko
Fixes #26819

### Add Item As Variant Test

Automated tests for changes #26712 


Fixes
[AB#555979](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/555979)

---------

Co-authored-by: Piotr Michalak <[email protected]>
@JesperSchulz JesperSchulz reopened this Nov 1, 2024
@JesperSchulz JesperSchulz reopened this Nov 11, 2024
JesperSchulz added a commit that referenced this issue Nov 11, 2024
…27570)

This pull request does not have a related issue as it's part of delivery
for development agreed directly with @AndreiPanko

Add Item As Variant Test
Automated tests for changes
#26748
Fixes #26819
Fixes
[AB#556529](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/556529)

---------

Co-authored-by: Jesper Schulz-Wedde <[email protected]>
@onbuyuka onbuyuka reopened this Nov 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment