diff --git a/requirements.txt b/requirements.txt
index 56c3281b..30facce8 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,4 @@
# generated from manifests external_dependencies
extendable_pydantic
fastapi
+python-amazon-sp-api
diff --git a/sale_import_amazon/__manifest__.py b/sale_import_amazon/__manifest__.py
index 9ac9e31c..48572858 100644
--- a/sale_import_amazon/__manifest__.py
+++ b/sale_import_amazon/__manifest__.py
@@ -7,16 +7,18 @@
"version": "16.0.1.0.0",
"license": "AGPL-3",
"author": "Akretion",
- "website": "http://akretion.com",
+ "website": "https://github.com/akretion/sale-import",
"depends": [
- "sale_stock",
+ "stock",
# https://github.com/akretion/sale-import/
"sale_import_base",
],
"data": [
- # 'views/amazon_marketplace.xml',
- # 'views/sale_channel.xml',
- # "views/sale_order.xml",
+ "views/amazon_marketplace.xml",
+ "views/sale_channel.xml",
+ "views/sale_order.xml",
+ "data/amazon_marketplace.xml",
+ "data/amazon_cron.xml",
"security/ir.model.access.csv",
],
"demo": [],
diff --git a/sale_import_amazon/data/amazon_cron.xml b/sale_import_amazon/data/amazon_cron.xml
new file mode 100644
index 00000000..ff0fdfac
--- /dev/null
+++ b/sale_import_amazon/data/amazon_cron.xml
@@ -0,0 +1,21 @@
+
+
+
+
+ Amazon: import orders
+
+ code
+ model.amazon_import_orders_chunk_cron()
+
+ 60
+ minutes
+ -1
+
+
+ 1000
+
+
+
diff --git a/sale_import_amazon/data/amazon_marketplace.xml b/sale_import_amazon/data/amazon_marketplace.xml
new file mode 100644
index 00000000..e0b36332
--- /dev/null
+++ b/sale_import_amazon/data/amazon_marketplace.xml
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+ Amazon.com.br
+ A2Q3Y263D00KWC
+ BR
+
+
+
+ Amazon.ca
+ A2EUQ1WTGCTBG2
+ CA
+
+
+ Amazon.com.mx
+ A1AM78C64UM0Y8
+ MX
+
+
+ Amazon.com
+ ATVPDKIKX0DER
+ US
+
+
+
+ Amazon.ae
+ A2VIGQ35RCS4UG
+ AE
+
+
+ Amazon.com.be
+ AMEN7PMS3EDWL
+ BE
+
+
+ Amazon.de
+ A1PA6795UKMFR9
+ DE
+
+
+ Amazon.eg
+ ARBP9OOSHTCHU
+ EG
+
+
+ Amazon.es
+ A1RKKUPIHCS9HS
+ ES
+
+
+ Amazon.fr
+ A13V1IB3VIYZZH
+ FR
+
+
+ Amazon.in
+ A21TJRUUN4KGV
+ IN
+
+
+ Amazon.it
+ APJ6JRA9NG5V4
+ IT
+
+
+ Amazon.nl
+ A1805IZSGTT6HS
+ NL
+
+
+ Amazon.pl
+ A1C3SOZRARQ6R3
+ PL
+
+
+ Amazon.sa
+ A17E79C6D8DWNP
+ SA
+
+
+ Amazon.se
+ A2NODRKZP88ZB9
+ SE
+
+
+ Amazon.com.tr
+ A33AVAJ2PDY3EV
+ TR
+
+
+ Amazon.co.uk
+ A1F83G8C2ARO7P
+ UK
+
+
+
+ Amazon.com.au
+ A39IBJ37TRP1C6
+ AU
+
+
+ Amazon.co.jp
+ A1VC38T7YXB528
+ JP
+
+
+ Amazon.sg
+ A19VAU5U5O7RUS
+ SG
+
+
+
diff --git a/sale_import_amazon/models/amazon_marketplace.py b/sale_import_amazon/models/amazon_marketplace.py
index ac85df9c..f5bbb343 100644
--- a/sale_import_amazon/models/amazon_marketplace.py
+++ b/sale_import_amazon/models/amazon_marketplace.py
@@ -1,15 +1,13 @@
# Copyright 2024 Akretion
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-from odoo import _, api, fields, models
+from odoo import fields, models
class AmazonMarketplace(models.Model):
_name = "amazon.marketplace"
_description = "Amazon MarketPlace"
- # List on https://developer-docs.amazon.com/sp-api/docs/marketplace-ids
- # TODO: create xml data with all the Amazon Marketplaces
name = fields.Char()
country_code = fields.Char(required=True)
- marketplace_ref = fields.Char()
+ marketplace_ref = fields.Char(help="API Marketplace's identifier")
diff --git a/sale_import_amazon/models/queue_job_chunk.py b/sale_import_amazon/models/queue_job_chunk.py
index f555279d..a13d6c93 100644
--- a/sale_import_amazon/models/queue_job_chunk.py
+++ b/sale_import_amazon/models/queue_job_chunk.py
@@ -1,7 +1,7 @@
# Copyright 2024 Akretion
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-from odoo import _, api, fields, models
+from odoo import fields, models
class QueueJobChunk(models.Model):
diff --git a/sale_import_amazon/models/sale_channel.py b/sale_import_amazon/models/sale_channel.py
index 07499995..54d66b45 100644
--- a/sale_import_amazon/models/sale_channel.py
+++ b/sale_import_amazon/models/sale_channel.py
@@ -2,28 +2,28 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
import json
-from pprint import pprint
+from datetime import timedelta
-
-from odoo import _, api, Command, fields, models
+from odoo import _, fields, models
from odoo.exceptions import ValidationError
-from odoo.addons.sale_import_amazon.utils import load_order_pages, load_order_items
+
+from odoo.addons.sale_import_amazon.utils import load_order_items, load_order_pages
class SaleChannel(models.Model):
_inherit = "sale.channel"
- # Connect to API, get raw data and create chunk with raw data and processor == sale_channel_importer_amazon
- type_channel = fields.Selection(selection_add=[("amazon", "Amazon")])
+ channel_type = fields.Selection(selection_add=[("amazon", "Amazon")])
lwa_appid = fields.Char(string="LWA App ID")
# TODO: use data_encryption to store these fields here
- sp_api_refresh_token = fields.Char()
- lwa_client_secret = fields.Char()
+ sp_api_refresh_token = fields.Char(string="SP-API Refresh Token")
+ lwa_client_secret = fields.Char(string="LWA Client Secret")
date_last_sale_update = fields.Datetime(
help="Date used to limit the API call to the last Amazon Orders updated after "
- "this choosen date"
+ "this choosen date",
+ default=lambda self: fields.Datetime.now() - timedelta(days=30),
)
marketplace_ids = fields.Many2many(
@@ -44,11 +44,14 @@ def amazon_get_credentials(self):
)
def amazon_import_orders(self):
- if self.type_channel != "amazon":
+ self.ensure_one()
+ if self.channel_type != "amazon":
raise ValidationError(_("The sale channel must be type 'Amazon'"))
orders = []
creds = self.amazon_get_credentials()
+ if not self.date_last_sale_update:
+ raise ValidationError(_("Missing Date Last Sale Update"))
date_last_sale_update = self.date_last_sale_update.isoformat(sep="T")
for marketplace_id in self.marketplace_ids:
@@ -63,7 +66,8 @@ def amazon_import_orders(self):
return orders
- def amazon_create_queue_job_chunk(self):
+ def amazon_import_orders_chunk(self):
+ self.ensure_one()
orders = self.amazon_import_orders()
chunk_vals = [
@@ -75,5 +79,15 @@ def amazon_create_queue_job_chunk(self):
}
for order in orders
]
-
- return self.env["queue.job.chunk"].create(chunk_vals)
+ chunk_ids = self.env["queue.job.chunk"].create(chunk_vals)
+ self.write({"date_last_sale_update": fields.Datetime.now()})
+ return chunk_ids
+
+ def amazon_import_orders_chunk_cron(self):
+ amazon_channel_ids = self.search([("channel_type", "=", "amazon")])
+ chunk_ids = self.env["queue.job.chunk"]
+ for channel_id in amazon_channel_ids:
+ new_chunk_ids = channel_id.amazon_import_orders_chunk()
+ chunk_ids |= new_chunk_ids
+
+ return chunk_ids
diff --git a/sale_import_amazon/models/sale_channel_importer_amazon.py b/sale_import_amazon/models/sale_channel_importer_amazon.py
index 0985b519..371f092d 100644
--- a/sale_import_amazon/models/sale_channel_importer_amazon.py
+++ b/sale_import_amazon/models/sale_channel_importer_amazon.py
@@ -1,7 +1,9 @@
# Copyright 2024 Akretion
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-from odoo import _, api, fields, models
+from odoo import _, models
+from odoo.exceptions import ValidationError
+
from odoo.addons.sale_import_amazon.utils import get_amz_date
@@ -10,8 +12,6 @@ class SaleChannelImporterAmazon(models.TransientModel):
_name = "sale.channel.importer.amazon"
_description = "Sale Channel Importer Amazon"
- # TODO: manage existing SO shipped or canceled
-
def _get_line_vals(self, item):
qty = item["QuantityOrdered"]
discount_amount = float(item.get("PromotionDiscount", {}).get("Amount", 0))
@@ -21,7 +21,7 @@ def _get_line_vals(self, item):
if discount_amount and total_incl_tax:
discount = discount_amount / total_incl_tax
- return {
+ line_vals = {
"product_code": item["SellerSKU"],
"description": item["Title"],
"qty": qty,
@@ -30,10 +30,16 @@ def _get_line_vals(self, item):
"discount": discount,
}
+ currency_code = item.get("ItemPrice", {}).get("CurrencyCode")
+ if currency_code:
+ line_vals["currency_code"] = currency_code
+
+ return line_vals
+
def _get_formatted_data(self):
raw = super()._get_formatted_data()
- # We suppose we do not have access to Personally Identifiable Information (PII)
+ # We assume we do not have access to Personally Identifiable Information (PII)
# about Amazon Buyers :
# no customer name, only an encoded email (used as Amazon's identifier),
# shipping city, zip and country code.
@@ -48,6 +54,14 @@ def _get_formatted_data(self):
"country_code": shipping.get("CountryCode", ""),
}
+ marketplace_id = self.env["amazon.marketplace"].search(
+ [("marketplace_ref", "=", raw["MarketplaceId"])], limit=1
+ )
+ if not marketplace_id:
+ raise ValidationError(
+ _("Missing Amazon MarketPlace {}").format(raw["MarketplaceId"])
+ )
+
formatted_data = {
"name": raw["AmazonOrderId"],
"date_order": get_amz_date(raw["PurchaseDate"]).date(),
@@ -60,6 +74,7 @@ def _get_formatted_data(self):
"lines": [self._get_line_vals(item) for item in raw["OrderItems"]],
"state": raw["OrderStatus"].lower(),
"is_fulfilled_by_amazon": raw["FulfillmentChannel"] == "AFN",
+ "amazon_marketplace_id": marketplace_id.id,
}
if raw.get("OrderTotal"):
@@ -73,15 +88,23 @@ def _get_formatted_data(self):
return formatted_data
def _manage_existing_so(self, existing_so, data):
+ # TODO: looks like it can be done better to avoid this native method shortcut
+
if data["state"] == "canceled" and existing_so.state != "cancel":
existing_so._action_cancel()
- if data["state"] == "shipped" and existing_so.delivery_status != "full":
+ elif data["state"] == "shipped" and existing_so.delivery_status != "full":
existing_so._deliver_order_by_amazon()
+ else:
+ super()._manage_existing_so(existing_so, data)
def _prepare_sale_vals(self, data):
so_vals = super()._prepare_sale_vals(data)
- so_vals["is_fulfilled_by_amazon"] = data["is_fulfilled_by_amazon"]
- # TODO: add markerplace_id
+ so_vals.update(
+ {
+ "is_fulfilled_by_amazon": data["is_fulfilled_by_amazon"],
+ "amazon_marketplace_id": data["amazon_marketplace_id"],
+ }
+ )
return so_vals
diff --git a/sale_import_amazon/models/sale_order.py b/sale_import_amazon/models/sale_order.py
index 7b0feaf2..6d35d8f6 100644
--- a/sale_import_amazon/models/sale_order.py
+++ b/sale_import_amazon/models/sale_order.py
@@ -1,14 +1,16 @@
# Copyright 2024 Akretion
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-from odoo import _, api, fields, models
+from odoo import fields, models
class SaleOrder(models.Model):
_inherit = "sale.order"
is_fulfilled_by_amazon = fields.Boolean()
+ amazon_marketplace_id = fields.Many2one("amazon.marketplace")
def _deliver_order_by_amazon(self):
+ self.ensure_one()
+ self.sale_channel_id.amazon_location_id
# TODO
- pass
diff --git a/sale_import_amazon/models/schemas.py b/sale_import_amazon/models/schemas.py
index 27624c79..423b7f2e 100644
--- a/sale_import_amazon/models/schemas.py
+++ b/sale_import_amazon/models/schemas.py
@@ -1,9 +1,8 @@
# Copyright (c) Akretion 2020
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
-from typing import List, Optional
+from typing import Optional
-from extendable_pydantic import ExtendableModelMeta
from odoo.addons.sale_import_base.models.schemas import SaleOrder
diff --git a/sale_import_amazon/security/ir.model.access.csv b/sale_import_amazon/security/ir.model.access.csv
index dfb7ea8c..50295c0b 100644
--- a/sale_import_amazon/security/ir.model.access.csv
+++ b/sale_import_amazon/security/ir.model.access.csv
@@ -1,3 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
sale_import_amazon.access_sale_channel_importer_amazon,access_sale_channel_importer_amazon,sale_import_amazon.model_sale_channel_importer_amazon,base.group_user,1,1,1,1
-sale_import_amazon.access_amazon_marketplace,access_amazon_marketplace,sale_import_amazon.model_amazon_marketplace,base.group_user,1,1,1,1
+sale_import_amazon.access_amazon_marketplace,access_amazon_marketplace,sale_import_amazon.model_amazon_marketplace,base.group_user,1,0,0,0
diff --git a/sale_import_amazon/tests/data.py b/sale_import_amazon/tests/data.py
index 598cb03a..f31caf8d 100644
--- a/sale_import_amazon/tests/data.py
+++ b/sale_import_amazon/tests/data.py
@@ -32,7 +32,7 @@
"PromotionDiscountTax": {"Amount": "0.00", "CurrencyCode": "EUR"},
"QuantityOrdered": 2,
"QuantityShipped": 2,
- "SellerSKU": "FURN_8888",
+ "SellerSKU": "PROD_1",
"Title": "Clever Elf - Décoration de Table de Noël",
}
],
diff --git a/sale_import_amazon/tests/test_sale_import_amazon.py b/sale_import_amazon/tests/test_sale_import_amazon.py
index 4447cb41..567ed968 100644
--- a/sale_import_amazon/tests/test_sale_import_amazon.py
+++ b/sale_import_amazon/tests/test_sale_import_amazon.py
@@ -2,20 +2,14 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
import os
-import datetime
-
-
from datetime import timedelta
from unittest.mock import patch
-from odoo import fields, Command
-
+from odoo import Command, fields
from odoo.tests import TransactionCase
-from odoo.addons.sale_import_amazon.tests import data
-from odoo.addons.sale_import_amazon.utils import get_amz_date
-
from odoo.addons.extendable.tests.common import ExtendableMixin
+from odoo.addons.sale_import_amazon.tests import data
class TestConnectorAmazon(TransactionCase, ExtendableMixin):
@@ -29,32 +23,41 @@ def setUp(self):
self.env = self.env(
context=dict(self.env.context, test_queue_job_no_delay=True)
)
- self.marketplace_id = self.env["amazon.marketplace"].create(
+ original_tax = self.env.ref("l10n_generic_coa.1_purchase_tax_template")
+ self.tax_incl = original_tax.copy({"price_include": True})
+ self.product = self.env["product.product"].create(
{
- "name": "Amazon.fr",
- "country_code": "FR",
- "marketplace_ref": "A13V1IB3VIYZZH",
+ "name": "Product",
+ "default_code": "PROD_1",
+ "invoice_policy": "order",
+ "taxes_id": [Command.set([self.tax_incl.id])],
}
)
+ self.marketplace_id = self.env.ref("sale_import_amazon.marketplace_FR")
self.team_id = self.env["crm.team"].create({"name": "Test"})
+ self.pricelist_id = self.env["product.pricelist"].create(
+ {"name": "Test EUR", "currency_id": 1}
+ )
self.channel_id = self.env["sale.channel"].create(
{
"name": "Connector Odoo-Amazon",
- "type_channel": "amazon",
+ "channel_type": "amazon",
"lwa_appid": os.environ.get("LWA_APP_ID"),
"sp_api_refresh_token": os.environ.get("SP_API_REFRESH_TOKEN"),
"lwa_client_secret": os.environ.get("LWA_CLIENT_SECRET"),
"marketplace_ids": [Command.set([self.marketplace_id.id])],
- "date_last_sale_update": fields.Datetime.now() - timedelta(days=30),
+ "date_last_sale_update": fields.Datetime.now() - timedelta(days=60),
"crm_team_id": self.team_id.id,
"sale_orders_check_amounts_total": True,
- "confirm_order": False,
- "invoice_order": False,
+ "confirm_order": True,
+ "invoice_order": True,
+ "pricelist_id": self.pricelist_id.id,
}
)
def test_create_queue_job_chunk(self):
- chunk_ids = self.channel_id.amazon_create_queue_job_chunk()
+ chunk_ids = self.env["sale.channel"].amazon_import_orders_chunk_cron()
+ self.assertTrue(chunk_ids)
for chunk_id in chunk_ids:
self.assertIn("AmazonOrderId", chunk_id.data_str)
self.assertEqual(chunk_id.processor, "sale_channel_importer_amazon")
@@ -66,19 +69,23 @@ def test_import_order_shipped(self):
return_value=data.ORDER_SHIPPED,
):
old_order_ids = self.env["sale.order"].search([])
- self.channel_id.amazon_create_queue_job_chunk()
+ self.channel_id.amazon_import_orders_chunk()
order = self.env["sale.order"].search([]) - old_order_ids
self.assertEqual(order.name, "407-6462826-9892326")
self.assertEqual(order.amount_total, 95.98)
self.assertEqual(order.si_amount_total, 95.98)
- self.assertEqual(order.date_order, datetime.datetime(2024, 1, 11))
+ # TODO: how to test the date_order value before confirmation ?
+ # self.assertEqual(order.date_order, datetime.datetime(2024, 1, 11))
self.assertEqual(order.currency_id.id, 1)
self.assertTrue(order.is_fulfilled_by_amazon)
+ self.assertEqual(order.team_id, self.team_id)
+ self.assertEqual(order.amazon_marketplace_id, self.marketplace_id)
+ self.assertEqual(order.state, "sale")
# TODO
- # self.assertEqual(order.state, "done")
# self.assertEqual(order.delivery_status, "full")
+ # self.assertEqual(order.state, "done")
partner = order.partner_id
self.assertEqual(partner.name, "Amazon Customer #407-6462826-9892326")
@@ -95,7 +102,7 @@ def test_import_order_shipped(self):
self.assertEqual(line.discount, 0)
self.assertEqual(line.price_unit, 47.99)
self.assertEqual(line.product_uom_qty, 2)
- self.assertEqual(line.product_id.default_code, "FURN_8888")
+ self.assertEqual(line.product_id.default_code, "PROD_1")
def test_import_order_canceled(self):
pass
diff --git a/sale_import_amazon/utils.py b/sale_import_amazon/utils.py
index f2fd9992..73f82043 100644
--- a/sale_import_amazon/utils.py
+++ b/sale_import_amazon/utils.py
@@ -1,8 +1,7 @@
import dateutil
-
-from sp_api.base import Marketplaces
from sp_api.api import Orders
-from sp_api.util import throttle_retry, load_all_pages
+from sp_api.base import Marketplaces
+from sp_api.util import load_all_pages, throttle_retry
@throttle_retry()
diff --git a/sale_import_amazon/views/amazon_marketplace.xml b/sale_import_amazon/views/amazon_marketplace.xml
index 10e365d2..d112e7c8 100644
--- a/sale_import_amazon/views/amazon_marketplace.xml
+++ b/sale_import_amazon/views/amazon_marketplace.xml
@@ -1,42 +1,43 @@
-
+
-
-
+
amazon.marketplace.form (in sale_import_amazon)
amazon.marketplace
-
+
amazon.marketplace.tree (in sale_import_amazon)
amazon.marketplace
-
-
+
+
+
-
- Amazon Marketplace
+
+ Amazon Marketplace
amazon.marketplace
tree,form
[]
@@ -45,9 +46,9 @@
diff --git a/sale_import_amazon/views/sale_channel.xml b/sale_import_amazon/views/sale_channel.xml
index 8513a7a9..3119bee1 100644
--- a/sale_import_amazon/views/sale_channel.xml
+++ b/sale_import_amazon/views/sale_channel.xml
@@ -1,15 +1,37 @@
-
+
-
sale.channel.form (in sale_import_amazon)
sale.channel
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sale_import_amazon/views/sale_order.xml b/sale_import_amazon/views/sale_order.xml
index 869f945d..31da45c9 100644
--- a/sale_import_amazon/views/sale_order.xml
+++ b/sale_import_amazon/views/sale_order.xml
@@ -1,15 +1,21 @@
-
+
-
sale.order.form (in sale_import_amazon)
sale.order
-
+
-
+
+
+
+
+
+
+
+
diff --git a/sale_import_base/models/sale_channel.py b/sale_import_base/models/sale_channel.py
index 758c1ef6..8d454c57 100644
--- a/sale_import_base/models/sale_channel.py
+++ b/sale_import_base/models/sale_channel.py
@@ -20,6 +20,8 @@ class SaleChannel(models.Model):
"(technical) Check total amounts against imported values"
)
pricelist_id = fields.Many2one("product.pricelist", string="Pricelist")
+ crm_team_id = fields.Many2one("crm.team")
+ company_id = fields.Many2one("res.company", default=lambda self: self.env.company)
confirm_order = fields.Boolean(help="Confirm order after import")
invoice_order = fields.Boolean(help="Generate invoice after import")
internal_naming_method = fields.Selection(
diff --git a/sale_import_base/models/sale_channel_importer.py b/sale_import_base/models/sale_channel_importer.py
index cfff36a2..06bfe57c 100644
--- a/sale_import_base/models/sale_channel_importer.py
+++ b/sale_import_base/models/sale_channel_importer.py
@@ -62,12 +62,20 @@ def _prepare_sale_vals(self, data):
"partner_shipping_id": address_shipping.id,
"client_order_ref": data["name"],
"sale_channel_id": channel.id,
+ "team_id": channel.crm_team_id.id,
}
pricelist_id = data.get("pricelist_id") or channel.pricelist_id.id
if pricelist_id:
so_vals["pricelist_id"] = pricelist_id
+ # FIXME: Not working ! currency_id is overridden on create if no pricelist_id
+ currency_id = self.env["res.currency"].search(
+ [("name", "=", data.get("currency_code"))]
+ )
+ if currency_id:
+ so_vals["currency_id"] = currency_id.id
+
amount = data.get("amount")
if amount:
so_vals.update(
@@ -201,6 +209,14 @@ def _prepare_sale_line(self, line_data, sale_order):
}
if line_data.get("description"):
vals["name"] = line_data["description"]
+
+ # FIXME: Not working ! currency_id is overridden on create
+ currency_id = self.env["res.currency"].search(
+ [("name", "=", line_data.get("currency_code"))]
+ )
+ if currency_id:
+ vals["currency_id"] = currency_id.id
+
return vals
def _finalize(self, new_sale_order, raw_import_data):
diff --git a/sale_import_base/models/schemas.py b/sale_import_base/models/schemas.py
index f522892b..9ea50e62 100644
--- a/sale_import_base/models/schemas.py
+++ b/sale_import_base/models/schemas.py
@@ -31,6 +31,7 @@ class SaleOrderLine(BaseModel, metaclass=ExtendableModelMeta):
price_unit: float
description: Optional[str] = None
discount: Optional[float] = None
+ currency_code: Optional[str] = None
class Amount(BaseModel, metaclass=ExtendableModelMeta):
@@ -62,6 +63,8 @@ class SaleOrder(BaseModel, metaclass=ExtendableModelMeta):
invoice: Optional[Invoice] = None
payment: Optional[Payment] = None
pricelist_id: Optional[int] = None
+ currency_code: Optional[str] = None
date_order: Optional[date] = None
is_fulfilled_by_amazon: Optional[bool] = False
+ amazon_marketplace_id: Optional[int] = False
state: Optional[str] = None
diff --git a/sale_import_base/views/sale_channel_view.xml b/sale_import_base/views/sale_channel_view.xml
index ac8753a7..38019ba4 100644
--- a/sale_import_base/views/sale_channel_view.xml
+++ b/sale_import_base/views/sale_channel_view.xml
@@ -6,25 +6,29 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/setup/sale_import_amazon/odoo/addons/sale_import_amazon b/setup/sale_import_amazon/odoo/addons/sale_import_amazon
new file mode 120000
index 00000000..19813b78
--- /dev/null
+++ b/setup/sale_import_amazon/odoo/addons/sale_import_amazon
@@ -0,0 +1 @@
+../../../../sale_import_amazon
\ No newline at end of file
diff --git a/setup/sale_import_amazon/setup.py b/setup/sale_import_amazon/setup.py
new file mode 100644
index 00000000..28c57bb6
--- /dev/null
+++ b/setup/sale_import_amazon/setup.py
@@ -0,0 +1,6 @@
+import setuptools
+
+setuptools.setup(
+ setup_requires=['setuptools-odoo'],
+ odoo_addon=True,
+)