Code Monkey home page Code Monkey logo

apple-slicer's Introduction

Apple Slicer

What?

This script parses App Store Connect financial reports and splits sales by Apple subsidiaries which are legally accountable for them. It may be used to help generating Reverse Charge invoices for accounting and in order to correctly issue EC Sales Lists mandatory in the EU.

Why?

In theory, selling apps is easy

You happily generate revenue with your apps on the App Store and Apple dutifully transfers the proceeds to you.

In reality, though, ...

...you have to remit taxes for your App Store sales of course. For that reason, tax authorities require some sort of receipt for your income from App Store sales. But will they accept the App Store Connect (formerly iTunes Connect) Financial Reports? Or your bank statements?

Most probably they won't. This is why you need to generate receipts by invoicing Apple using the Reverse Charge procedure. Well, in bureaucratic Germany, at least.

But wait! In Europe, there is more to do

For purchases that have been made in any member state of the European Union, Apple – in the role of your sales commissionaire – is accountable for remitting associated taxes. For that reason, your local tax authorities require you to file a periodical EC Sales List (also known as ESL or Recapitulative Statement) of those sales in order for them to be able to counter-check Apple's tax returns.

This is true if your business is based in the EU. In Germany, for example, the required tax document is called Zusammenfassende Meldung.

Now for the problem

While due to Apple's internal cash pooling the wire transfer of your App Store proceeds is issued solely by Apple's European subsidiary in Ireland, namely Apple Distribution International*), the amount transmitted doesn't necessarily consist of European sales only.

In fact, because Apple Distribution International also collects revenue of other countries (at the time being f. ex. also Chinese and generally "rest of world" sales), it would therefore be wrong to declare the whole sum paid by Apple Distribution International in your ESL.

Instead, in order to correctly declare business done between you and Apple, the sum paid by Apple Distribution International must be split into revenue made in member states of the European Union and into revenue made in Non-EU countries.

*) It used to be iTunes S.à.r.l. in Luxembourg until February 5th, 2017 when Apple merged it with their Irish subsidiary, Apple Distribution International.

This is where this script comes handy

It breaks up App Store sales by country and assigns them to the specific Apple subsidiary which is legally accountable for them – for example, Apple Canada, Inc. for Canadian or iTunes K.K. for Japanese sales. The information which country is managed by which Apple subsidiary is taken from Schedule 2, Exhibit A of Apple's Paid Applications contract you signed when starting your App Store business.

You can use the output of the script to help genereating Reverse Charge invoices for accounting and also in order to correctly issue your EC Sales Lists.

How?

In App Store Connect go to Payments & Financial Reports and download your financial reports (either as Multiple Files or Single File) of the desired billing month into an appropriately named directory. For example, if you want your sales for September, 2022 to be split, download the financial reports for 2022/09 and move the resulting *0922*.txt into a directory named 0922.

Additionally, in order to display revenue in your local currency, the script needs the currency exchange rates and tax withholding amounts that were applicable at the time of the payment. They aren't included in the financial report files, but luckily App Store Connect has them available for you in an extra file which can be downloaded by clicking on the small blue icon right above the Estimated Earnings column. Place this file in the same directory as the previously downloaded reports. It should be named financial_report.csv.

You are now ready to execute the script with the reports directory as parameter:

./slicer.py ~/Downloads/AppStoreFinancialReports/0922

Example output

The script generates tab-delimited output, more or less ready to be pasted into your favourite billing and/or tax return application.

Sales date: 31.08.2022 - 27.09.2022 

Apple Distribution International
Internet Software & Services
Hollyhill Industrial Estate
Hollyhill, Cork
Republic of Ireland
VAT ID: IE9700053D

Sales in Finland (FI)
	Quantity Product	Amount		Exchange Rate	Amount in EUR
	1	 Example App 5	EUR 12,17	1.00000		12,1700 €

		 Subtotal FI:	EUR 12,17	1.00000		12,17 €

Sales in France (FR)
	Quantity Product	Amount		Exchange Rate	Amount in EUR
	1	 Example App 5	EUR 12,17	1.00000		12,1700 €

		 Subtotal FR:	EUR 12,17	1.00000		12,17 €

Sales in Switzerland (CH)
	Quantity Product	Amount		Exchange Rate	Amount in EUR
	2	 Example App 4	CHF 1,30	0.80030		1,0404 €
	5	 Example App 2	CHF 3,25	0.80030		2,6010 €
	6	 Example App 3	CHF 7,80	0.80030		6,2423 €
	16	 Example App 1	CHF 20,80	0.80030		16,6462 €

		 Subtotal CH:	CHF 33,15	0.80030		26,53 €

Sales in Germany (DE)
	Quantity Product	Amount		Exchange Rate	Amount in EUR
	2	 Example App 6	EUR 24,34	1.00000		24,3400 €
	15	 Example App 5	EUR 158,21	1.00000		158,2100 €

		 Subtotal DE:	EUR 182,55	1.00000		182,55 €

EU Total:	 233,42 €


iTunes K.K.
〒 106-6140
6-10-1 Roppongi, Minato-ku, Tokyo
Japan

Sales in Japan (JP)
	Quantity Product	Amount		Exchange Rate	Amount in EUR
	1	 Example App 4	JPY 47,60	0.00817		0,3889 €
	1	 Example App 3	JPY 94,40	0.00817		0,7712 €

		 Subtotal JP:	JPY 142,00	0.00817		1,16 €

JP Total:	 1,16 €

You can configure your local currency (€ in this example) within the script.

One more thing…

Now, how to actually report sales handled by Apple's EU subsidiary to the tax authorities? With a little help from Steuererklärung.app, it's quite straightforward: Run the script with the -steuerapp-esl parameter and all that's left to do is to select the current reporting period on the ESL form. Your VAT ID and address data will be remembered by the app after your first successful submission.

Obligatory disclaimer

There is absolutely no warranty. I am (thankfully) not a tax advisor and therefore cannot guarantee for the correctness of the above or the Python script in any way. You need to verify for yourself if the above mentioned procedures are compatible with or even needed by your country's legislation. Also, it is your obligation alone to check if the numbers the script computes are reasonable.

Pull Requests

Neither English nor Python are my native language – corrective PRs are very welcome!

apple-slicer's People

Contributors

fedoco avatar germanmarques avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

apple-slicer's Issues

Rounding issue

Not sure if this is an issue, but the total amount from what Apple pays you is slightly different from what apple-slicer calculates in total. So if I create an invoice with the data from apple-slicer, I have a different end value than what Apple actually pays me. Thats not good.

I didn't check all the numbers by hand but I think the issue is that Apple converts the currency for the sales from each region to the destination currency (i.e. everything to Euro) and rounds it to two two decimal places. Then it sums up every result, rounds it again and has the end result that is being payed to the developer. Thats what you can see in financial_report.csv.
apple-slicer however converts the every country with the currency to the destination currency and sums it up. This can lead to an higher or lower sum than what is actually paid by apple.

In my tests, apple-slicer calculated 0,99% more than Apple did for my last payment from them. That seems not much, but its much as soon as the numbers get higher of cause.

Can someone confirm that this is an issue?

KeyError: 'USD - RoW' when doing a german report

Traceback (most recent call last):
  File "./slicer.py", line 218, in <module>
    print_sales_by_corporation(sales, currencies)
  File "./slicer.py", line 187, in print_sales_by_corporation
    exchange_rate, tax_factor = currency_data[country_currency]
KeyError: 'USD - RoW'

In slicer.py there is

            if "_WW." in filename and currency == "USD":
              currencies[countrycode] = "USD - RoW"

but in my german localized financial_report.csv the currency is actually Rest der Welt (USD), so slicer.py fails. When I comment the two lines out, it works for me.

KeyError: 'HRK'

Hi! Back again with some error:

Traceback (most recent call last): File "/Users/silviu/apple-slicer/./slicer.py", line 283, in <module> print_sales_by_corporation(sales, currencies, args.no_subtotals, args.only_subtotals) File "/Users/silviu/apple-slicer/./slicer.py", line 235, in print_sales_by_corporation exchange_rate, tax_factor = currency_data[country_currency] KeyError: 'HRK'
image

The report looks like this:

image

Thanks!

[error] decimal.DivisionByZero

Hi, thank you for this tool - using it for some months, but now I have encountered the following error:

Traceback (most recent call last): File "/Users/silviu/apple-slicer/./slicer.py", line 268, in <module> currency_data = parse_currency_data(args.directory + '/' + currency_data_filename) File "/Users/silviu/apple-slicer/./slicer.py", line 143, in parse_currency_data tax_factor = Decimal(1.0) - abs(tax / amount_pre_tax) decimal.DivisionByZero: [<class 'decimal.DivisionByZero'>]

Thank you!

Currency conversion error

The script doesn’t seem to work for me for currencies other than EUR:

Apple Inc.
1 Infinite Loop
Cupertino, CA 95014
U.S.A.

Sales in United States (US)
    Quantity    Product Amount  Exchange Rate   Amount in EUR
Traceback (most recent call last):
  File "./slicer.py", line 206, in <module>
    print_sales_by_corporation(sales, currencies)
  File "./slicer.py", line 175, in print_sales_by_corporation
    exchange_rate, tax_factor = currency_data[country_currency]
KeyError: 'USD'

What can I do to help?

USD - RoW FX Rate not used

Hello,

Thank you first of all for the very useful script which helps me a lot to prepare correct invoices.

Unfortunately after results verifications I found that for some countries the Sales reports are not match to the Payment reports. These countries are like Albania, Algeria, Kenya, etc - all of them belongs to the so called by Apple "Rest of World" region.

As I found the reason for this issue is that the sales in these countries are made in USD, but the FX Rate which Apple use is not the USD (in the FX Rate table) but "USD - RoW" (Rest of World).

In the python script all FX Rates are read-in correctly, including "USD - RoW", but it is never used later for the calculations as in the sales reports for these countries Apple do not name currency as "USD - RoW", but just as USD.

Please let me know if it is clear what I've tried to explain and thank you in advance!

KeyError: 'PHP'

Sales in Philippines (PH)
	Quantity	Product	Amount	Exchange Rate	Amount in USD
Traceback (most recent call last):
  File "/Users/silviu/apple-slicer/./slicer.py", line 286, in <module>
    print_sales_by_corporation(sales, currencies, args.no_subtotals, args.only_subtotals, args.selected_corporations)
  File "/Users/silviu/apple-slicer/./slicer.py", line 237, in print_sales_by_corporation
    exchange_rate, tax_factor = currency_data[country_currency]
KeyError: 'PHP'

🤔

No distinction between European Union and Non-EU countries

Hi,

The readme says:

the sum paid by Apple Distribution International must be split into revenue made in member states of the European Union and into revenue made in Non-EU countries

However, the script does not distinguish between European Union and Non-EU countries at all. Switzerland, China and others are included, which makes the sum for the Recapitulative Statement wrong. Compare with https://exelerus.com/mobiledev/apple/ when you include Switzerland in your financial reports.

Cheers

USD - Latin America and the Caribbean

Hey @fedoco, thanks for this awesome tool. We just recently used it to create a free Mac app that uses the App Store Connect api to fetch the reports, parses them with our swift port of this library, and exports invoices as PDFs. One user made us aware that there is an issue with the currency conversion of USD in "Latin America and the Caribbean" (similarly to USD - Rest of the World). This is also an issue with your library.

"Your sales" vs "Apple's sales"

When you join the Apple Developer program and sign the contracts, you give Apple all the rights to sell your apps. So, technically, you are not selling any apps anywhere and there are no sells to be declared anywhere.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.