aa-buybackprogram 2.1.0__tar.gz → 2.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/PKG-INFO +4 -4
  2. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/README.md +2 -2
  3. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/__init__.py +1 -1
  4. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/forms.py +1 -1
  5. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/helpers.py +64 -45
  6. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/management/commands/buybackprogram_load_prices.py +4 -4
  7. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/management/commands/generate_dummy_data.py +0 -0
  8. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/migrations/0015_faq_contractnotification_header_and_more.py +0 -0
  9. aa_buybackprogram-2.3.0/buybackprogram/migrations/0016_alter_program_compression_price_dencity_modifier.py +21 -0
  10. aa_buybackprogram-2.3.0/buybackprogram/migrations/0017_alter_contract_price_alter_contract_volume_and_more.py +64 -0
  11. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/models.py +20 -14
  12. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/tasks.py +6 -8
  13. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/base/menu-management.html +0 -0
  14. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/base/menu.html +0 -0
  15. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/calculate/accepted_locations.html +0 -0
  16. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/calculate/calculation_success.html +0 -0
  17. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/calculate/contract_settings.html +2 -2
  18. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/calculate/invoice.html +7 -7
  19. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/calculate/item_details.html +23 -23
  20. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/details/contract-info.html +1 -1
  21. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/details/invoice.html +6 -6
  22. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/details/tabs/original-items.html +1 -1
  23. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/stats/summary.html +2 -2
  24. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/stats/tabs/finished.html +1 -1
  25. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/stats/tabs/outstanding.html +1 -1
  26. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/stats/tabs/untracked.html +1 -1
  27. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/views/programs.py +0 -14
  28. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/LICENSE +0 -0
  29. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/admin.py +0 -0
  30. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/app_settings.py +0 -0
  31. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/apps.py +0 -0
  32. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/auth_hooks.py +0 -0
  33. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/constants.py +0 -0
  34. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/decorators.py +0 -0
  35. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/management/__init__.py +0 -0
  36. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/management/commands/__init__.py +0 -0
  37. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/management/commands/buybackprogram_generate_test_data.py +0 -0
  38. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/management/commands/buybackprogram_link_contracts.py +0 -0
  39. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/management/commands/buybackprogram_load_data.py +0 -0
  40. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/migrations/0001_initial.py +0 -0
  41. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/migrations/0002_contractnotification.py +0 -0
  42. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/migrations/0003_statics_performance_increase.py +0 -0
  43. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/migrations/0004_auto_20220323_1331.py +0 -0
  44. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/migrations/0005_program_compression_price_dencity_modifier.py +0 -0
  45. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/migrations/0006_program_bonds_npc_price_and_more.py +0 -0
  46. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/migrations/0007_program_expiration.py +0 -0
  47. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/migrations/0008_alter_general_options_alter_program_refining_rate.py +0 -0
  48. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/migrations/0009_contract_location_name.py +0 -0
  49. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/migrations/0010_contract_no_tracking_alter_tracking_tracking_number.py +0 -0
  50. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/migrations/0011_delete_duplicated_contracts.py +0 -0
  51. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/migrations/0012_make_contract_id_unique.py +0 -0
  52. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/migrations/0013_program_discord_show_item_list.py +0 -0
  53. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/migrations/0014_program_price_type.py +0 -0
  54. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/migrations/__init__.py +0 -0
  55. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/notes.py +0 -0
  56. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/notification.py +0 -0
  57. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/providers.py +0 -0
  58. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/static/buybackprogram/css/billboards_dark.css +0 -0
  59. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/static/buybackprogram/css/billboards_light.css +0 -0
  60. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/static/buybackprogram/css/style_dark.css +0 -0
  61. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/static/buybackprogram/css/style_light.css +0 -0
  62. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/static/buybackprogram/images/help.png +0 -0
  63. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/static/buybackprogram/js/autocomplete.js +0 -0
  64. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/static/buybackprogram/js/bootstrap-autocomplete.min.js +0 -0
  65. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/swagger.json +0 -0
  66. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/base.html +0 -0
  67. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/bundles/buybackprogram-css-light.html +0 -0
  68. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/contract_details.html +0 -0
  69. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/faq.html +0 -0
  70. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/index.html +0 -0
  71. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/leaderboards.html +0 -0
  72. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/location_add.html +0 -0
  73. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/page.html +0 -0
  74. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/details/accepted-locations.html +0 -0
  75. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/details/tabs/contract-items.html +0 -0
  76. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/details/tabs/tabs-navigation.html +0 -0
  77. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/details/warning.html +0 -0
  78. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/stats/tabs/tabs-navigation.html +0 -0
  79. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/partials/stats/warning.html +0 -0
  80. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/performance.html +0 -0
  81. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/program_add.html +0 -0
  82. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/program_calculate.html +0 -0
  83. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/program_edit.html +0 -0
  84. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/program_edit_item.html +0 -0
  85. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/program_edit_marketgroup.html +0 -0
  86. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/program_special_taxes.html +0 -0
  87. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/stats.html +0 -0
  88. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templates/buybackprogram/user_settings.html +0 -0
  89. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templatetags/__init__.py +0 -0
  90. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templatetags/bs_tab_color_class.py +0 -0
  91. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templatetags/help_icons.py +0 -0
  92. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templatetags/price_formats.py +0 -0
  93. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/templatetags/program_settings.py +0 -0
  94. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/tests/__init__.py +0 -0
  95. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/tests/test_data_migrations.py +0 -0
  96. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/tests/test_helpers.py +0 -0
  97. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/tests/test_models.py +0 -0
  98. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/tests/testdata/__init__.py +0 -0
  99. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/tests/testdata/create_eveuniverse.py +0 -0
  100. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/tests/testdata/eveuniverse.json +0 -0
  101. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/tests/testdata/factories.py +0 -0
  102. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/tests/testdata/load_eveuniverse.py +0 -0
  103. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/urls.py +0 -0
  104. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/utils.py +0 -0
  105. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/views/__init__.py +0 -0
  106. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/views/calculate.py +0 -0
  107. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/views/common.py +0 -0
  108. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/views/special_taxes.py +0 -0
  109. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/buybackprogram/views/stats.py +0 -0
  110. {aa_buybackprogram-2.1.0 → aa_buybackprogram-2.3.0}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: aa-buybackprogram
3
- Version: 2.1.0
3
+ Version: 2.3.0
4
4
  Summary: Buyback program plugin app for Alliance Auth.
5
5
  Author-email: Ikarus Cesaille <contact@eve-linknet.com>
6
6
  Requires-Python: >=3.8
@@ -283,9 +283,9 @@ You can use a price density modifier which will add a additional tax on items wi
283
283
 
284
284
  > :information_source: This setting is aimer more at high sec buyback programs.
285
285
 
286
- ##### Compressible price density modifier
286
+ ##### Ore volume based on compressed volume
287
287
 
288
- You can select to ignore price density calculations for items that can be compressed. This is helpful when the compressed variants do not have proper buy orders in Jita. If you set this to True then the compressible item density will be calculated based on the isk / volume of the compression variant of the sold item.
288
+ Using this setting will calculate all items that can be compressed (mainly ore and ice) based on the compressed variant volume and use this volume instead of the raw volume to calculate the hauling and price dencity costs. This setting is mainly aimed at null sec where you might get raw ore sold to you but want to compress it before shipping as raw ore volume is very high and will cause high hauling costs.
289
289
 
290
290
  ##### Price density threshold
291
291
 
@@ -258,9 +258,9 @@ You can use a price density modifier which will add a additional tax on items wi
258
258
 
259
259
  > :information_source: This setting is aimer more at high sec buyback programs.
260
260
 
261
- ##### Compressible price density modifier
261
+ ##### Ore volume based on compressed volume
262
262
 
263
- You can select to ignore price density calculations for items that can be compressed. This is helpful when the compressed variants do not have proper buy orders in Jita. If you set this to True then the compressible item density will be calculated based on the isk / volume of the compression variant of the sold item.
263
+ Using this setting will calculate all items that can be compressed (mainly ore and ice) based on the compressed variant volume and use this volume instead of the raw volume to calculate the hauling and price dencity costs. This setting is mainly aimed at null sec where you might get raw ore sold to you but want to compress it before shipping as raw ore volume is very high and will cause high hauling costs.
264
264
 
265
265
  ##### Price density threshold
266
266
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  default_app_config = "buybackprogram.apps.BuybackProgramConfig"
4
4
 
5
- __version__ = "2.1.0"
5
+ __version__ = "2.3.0"
6
6
  __title__ = "Buyback Program"
@@ -101,7 +101,7 @@ class LocationForm(forms.Form):
101
101
  max_length=32,
102
102
  )
103
103
 
104
- structure_id = forms.CharField(
104
+ structure_id = forms.IntegerField(
105
105
  required=False,
106
106
  label="Structure/station ID",
107
107
  help_text="The ingame ID for the structure you wish to accept the contracts at. <strong>If left empty the program statistics page will not track if the contract is actually made at the correct structure or not.</strong>",
@@ -75,6 +75,10 @@ def get_or_create_prices(item_id):
75
75
  return ItemPrices.objects.get(eve_type_id=item_id)
76
76
 
77
77
  except ItemPrices.DoesNotExist:
78
+ logger.debug(
79
+ "Item %s does not have prices stored in database, fetching prices now ..."
80
+ % item_id
81
+ )
78
82
  if BUYBACKPROGRAM_PRICE_METHOD == "Fuzzwork":
79
83
  response_fuzzwork = requests.get(
80
84
  "https://market.fuzzwork.co.uk/aggregates/",
@@ -86,12 +90,14 @@ def get_or_create_prices(item_id):
86
90
 
87
91
  items_fuzzwork = response_fuzzwork.json()
88
92
 
89
- buy = int(float(items_fuzzwork[str(item_id)]["buy"]["max"]))
90
- sell = int(float(items_fuzzwork[str(item_id)]["sell"]["min"]))
91
- buy_average = int(float(items_fuzzwork[str(item_id)]["buy"]["percentile"]))
92
- sell_average = int(
93
- float(items_fuzzwork[str(item_id)]["sell"]["percentile"])
94
- )
93
+ buy = float(items_fuzzwork[str(item_id)]["buy"]["max"])
94
+ logger.debug("Buy price set to %s" % buy)
95
+ sell = float(items_fuzzwork[str(item_id)]["sell"]["min"])
96
+ logger.debug("Sell price set to %s" % sell)
97
+ buy_average = float(items_fuzzwork[str(item_id)]["buy"]["percentile"])
98
+ logger.debug("Buy average price set to %s" % buy_average)
99
+ sell_average = float(items_fuzzwork[str(item_id)]["sell"]["percentile"])
100
+ logger.debug("Sell average price set to %s" % sell_average)
95
101
 
96
102
  elif BUYBACKPROGRAM_PRICE_METHOD == "Janice":
97
103
  if valid_janice_api_key():
@@ -106,13 +112,14 @@ def get_or_create_prices(item_id):
106
112
 
107
113
  item_janice = response_janice.json()
108
114
 
109
- buy = int(float(item_janice["immediatePrices"]["buyPrice5DayMedian"]))
110
- sell = int(float(item_janice["immediatePrices"]["sellPrice5DayMedian"]))
111
- buy_average = int(
112
- float(item_janice["top5AveragePrices"]["buyPrice5DayMedian"])
115
+ buy = float(item_janice["immediatePrices"]["buyPrice5DayMedian"])
116
+ sell = float(item_janice["immediatePrices"]["sellPrice5DayMedian"])
117
+ buy_average = float(
118
+ item_janice["top5AveragePrices"]["buyPrice5DayMedian"]
113
119
  )
114
- sell_average = int(
115
- float(item_janice["top5AveragePrices"]["sellPrice5DayMedian"])
120
+
121
+ sell_average = float(
122
+ item_janice["top5AveragePrices"]["sellPrice5DayMedian"]
116
123
  )
117
124
  else:
118
125
  logger.error(
@@ -140,10 +147,12 @@ def get_or_create_prices(item_id):
140
147
  sell=sell_average,
141
148
  updated=updated,
142
149
  )
150
+ logger.debug("Price stored in database %s" % price)
143
151
  else:
144
152
  price = ItemPrices.objects.create(
145
153
  eve_type_id=item_id, buy=buy, sell=sell, updated=updated
146
154
  )
155
+ logger.debug("Price stored in database %s" % price)
147
156
 
148
157
  return price
149
158
  except Error as e:
@@ -367,28 +376,34 @@ def get_item_prices(item_type, name, quantity, program):
367
376
 
368
377
  # Get compressed versions of the ores that are not yet compressed
369
378
  if is_ore(item_type.eve_group.id):
370
- if "Compressed" in name:
371
- compresed_name = name
372
- else:
373
- compresed_name = "Compressed " + name
379
+ try:
380
+ if "Compressed" in name:
381
+ compresed_name = name
382
+ else:
383
+ compresed_name = "Compressed " + name
374
384
 
375
- compresed_type = EveType.objects.filter(name=compresed_name).first()
385
+ compresed_type = EveType.objects.filter(name=compresed_name).first()
376
386
 
377
- compression_price = get_or_create_prices(compresed_type.id)
387
+ compression_price = get_or_create_prices(compresed_type.id)
378
388
 
379
- compressed_type_prices = {
380
- "id": compression_price.eve_type_id,
381
- "quantity": quantity,
382
- "buy": compression_price.buy,
383
- "sell": compression_price.sell,
384
- }
389
+ compressed_type_prices = {
390
+ "id": compression_price.eve_type_id,
391
+ "quantity": quantity,
392
+ "buy": compression_price.buy,
393
+ "sell": compression_price.sell,
394
+ }
385
395
 
386
- has_price_variants = True
396
+ has_price_variants = True
387
397
 
388
- logger.debug(
389
- "Prices: Got compression prices %s ISK for %s based on original item %s"
390
- % (compression_price.buy, compresed_name, name)
391
- )
398
+ logger.debug(
399
+ "Prices: Got compression prices %s ISK for %s based on original item %s"
400
+ % (compression_price.buy, compresed_name, name)
401
+ )
402
+ except Exception as e:
403
+ logger.error(
404
+ f"Failed to get compression prices for {compresed_name}: {e}"
405
+ )
406
+ compressed_type_prices = False
392
407
 
393
408
  # If item can't or should not be compressed
394
409
  else:
@@ -460,8 +475,8 @@ def get_item_values(item_type, item_prices, program):
460
475
  # RAW VARIANT VALUES
461
476
  if item_prices["raw_prices"] and item_prices["raw_prices"]["raw_price_used"]:
462
477
  quantity = item_prices["raw_prices"]["quantity"]
463
- sell = item_prices["raw_prices"]["sell"]
464
- buy = item_prices["raw_prices"]["buy"]
478
+ sell = float(item_prices["raw_prices"]["sell"])
479
+ buy = float(item_prices["raw_prices"]["buy"])
465
480
  split = statistics.median([sell, buy])
466
481
 
467
482
  # Determine what price type we should use
@@ -555,12 +570,13 @@ def get_item_values(item_type, item_prices, program):
555
570
  )
556
571
 
557
572
  price_dencity = (
558
- item_prices["compression_prices"]["buy"] / compressed_version.volume
573
+ float(item_prices["compression_prices"]["buy"])
574
+ / compressed_version.volume
559
575
  )
560
576
 
561
577
  price_dencity_tax = get_price_dencity_tax(
562
578
  program,
563
- item_prices["compression_prices"]["buy"],
579
+ float(item_prices["compression_prices"]["buy"]),
564
580
  compressed_version.volume,
565
581
  item_prices["compression_prices"]["quantity"],
566
582
  is_ore(item_type.eve_group.id),
@@ -579,14 +595,14 @@ def get_item_values(item_type, item_prices, program):
579
595
 
580
596
  if not item_type.volume <= 0:
581
597
  price_dencity = (
582
- item_prices["raw_prices"]["buy"] / item_type.packaged_volume
598
+ float(item_prices["raw_prices"]["buy"]) / item_type.packaged_volume
583
599
  )
584
600
  else:
585
601
  price_dencity = False
586
602
 
587
603
  price_dencity_tax = get_price_dencity_tax(
588
604
  program,
589
- item_prices["raw_prices"]["buy"],
605
+ float(item_prices["raw_prices"]["buy"]),
590
606
  item_type.packaged_volume,
591
607
  item_prices["raw_prices"]["quantity"],
592
608
  is_ore(item_type.eve_group.id),
@@ -606,8 +622,8 @@ def get_item_values(item_type, item_prices, program):
606
622
  materials = EveType.objects.filter(id=material["id"]).first()
607
623
 
608
624
  quantity = material["quantity"]
609
- sell = material["sell"]
610
- buy = material["buy"]
625
+ sell = float(material["sell"])
626
+ buy = float(material["buy"])
611
627
  split = statistics.median([sell, buy])
612
628
 
613
629
  # Determine what price type we should use
@@ -684,8 +700,8 @@ def get_item_values(item_type, item_prices, program):
684
700
  ).first()
685
701
 
686
702
  quantity = item_prices["compression_prices"]["quantity"]
687
- buy = item_prices["compression_prices"]["buy"]
688
- sell = item_prices["compression_prices"]["sell"]
703
+ buy = float(item_prices["compression_prices"]["buy"])
704
+ sell = float(item_prices["compression_prices"]["sell"])
689
705
  split = statistics.median([sell, buy])
690
706
 
691
707
  # Determine what price type we should use
@@ -763,8 +779,8 @@ def get_item_values(item_type, item_prices, program):
763
779
  # Get value for NPC price
764
780
  if item_prices["npc_prices"]:
765
781
  quantity = item_prices["npc_prices"]["quantity"]
766
- sell = item_prices["npc_prices"]["sell"]
767
- buy = item_prices["npc_prices"]["buy"]
782
+ sell = float(item_prices["npc_prices"]["sell"])
783
+ buy = float(item_prices["npc_prices"]["buy"])
768
784
  split = statistics.median([sell, buy])
769
785
 
770
786
  # Determine what price type we should use
@@ -868,9 +884,9 @@ def get_item_values(item_type, item_prices, program):
868
884
  [raw_item["unit_value"], refined["unit_value"], compressed["unit_value"]]
869
885
  )
870
886
  else:
871
- buy_value = npc_item["value"]
872
- raw_value = npc_item["raw_value"]
873
- unit_value = npc_item["unit_value"]
887
+ buy_value = float(npc_item["value"])
888
+ raw_value = float(npc_item["raw_value"])
889
+ unit_value = float(npc_item["unit_value"])
874
890
 
875
891
  # Determine what value we will use for buy value
876
892
  if buy_value == raw_item["value"]:
@@ -1013,6 +1029,9 @@ def get_item_buy_value(buyback_data, program, donation):
1013
1029
  if (
1014
1030
  item["item_prices"]["compression_prices"]
1015
1031
  and program.use_compressed_value
1032
+ ) or (
1033
+ program.compression_price_dencity_modifier
1034
+ and is_ore(item["type_data"].eve_group.id)
1016
1035
  ):
1017
1036
  compressed_version = EveType.objects.filter(
1018
1037
  id=item["item_prices"]["compression_prices"]["id"]
@@ -1122,7 +1141,7 @@ def get_tracking_number(
1122
1141
  taxes=contract_price_data["total_tax_amount"],
1123
1142
  hauling_cost=contract_price_data["total_hauling_cost"],
1124
1143
  donation=contract_price_data["total_donation_amount"],
1125
- net_price=round(contract_price_data["contract_net_total"]),
1144
+ net_price=contract_price_data["contract_net_total"],
1126
1145
  tracking_number=tracking_number,
1127
1146
  created_at=timezone.now(),
1128
1147
  additional_notes=additional_notes,
@@ -84,15 +84,15 @@ class Command(BaseCommand):
84
84
  if not BUYBACKPROGRAM_PRICE_INSTANT_PRICES:
85
85
  item = ItemPrices(
86
86
  eve_type_id=key,
87
- buy=int(float(value["buy"]["percentile"])),
88
- sell=int(float(value["sell"]["percentile"])),
87
+ buy=float(value["buy"]["percentile"]),
88
+ sell=float(value["sell"]["percentile"]),
89
89
  updated=timezone.now(),
90
90
  )
91
91
  else:
92
92
  item = ItemPrices(
93
93
  eve_type_id=key,
94
- buy=int(float(value["buy"]["max"])),
95
- sell=int(float(value["sell"]["min"])),
94
+ buy=float(value["buy"]["max"]),
95
+ sell=float(value["sell"]["min"]),
96
96
  updated=timezone.now(),
97
97
  )
98
98
 
@@ -0,0 +1,21 @@
1
+ # Generated by Django 4.2.11 on 2024-10-02 03:59
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ dependencies = [
8
+ ("buybackprogram", "0015_faq_contractnotification_header_and_more"),
9
+ ]
10
+
11
+ operations = [
12
+ migrations.AlterField(
13
+ model_name="program",
14
+ name="compression_price_dencity_modifier",
15
+ field=models.BooleanField(
16
+ default=False,
17
+ help_text="Should we use compressed volume for items that can be compressed such as ore and ice in fuel cost and price dencity calculations. If set to False the raw volume is used for volume calculations if the item does not have a compressed price variant available from the use compressed value setting.",
18
+ verbose_name="Ore volume based on compressed volume",
19
+ ),
20
+ ),
21
+ ]
@@ -0,0 +1,64 @@
1
+ # Generated by Django 4.2.11 on 2024-11-03 04:42
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ dependencies = [
8
+ ("buybackprogram", "0016_alter_program_compression_price_dencity_modifier"),
9
+ ]
10
+
11
+ operations = [
12
+ migrations.AlterField(
13
+ model_name="contract",
14
+ name="price",
15
+ field=models.DecimalField(decimal_places=2, max_digits=20),
16
+ ),
17
+ migrations.AlterField(
18
+ model_name="contract",
19
+ name="volume",
20
+ field=models.DecimalField(decimal_places=2, max_digits=20),
21
+ ),
22
+ migrations.AlterField(
23
+ model_name="itemprices",
24
+ name="buy",
25
+ field=models.DecimalField(decimal_places=2, max_digits=20),
26
+ ),
27
+ migrations.AlterField(
28
+ model_name="itemprices",
29
+ name="sell",
30
+ field=models.DecimalField(decimal_places=2, max_digits=20),
31
+ ),
32
+ migrations.AlterField(
33
+ model_name="tracking",
34
+ name="donation",
35
+ field=models.DecimalField(
36
+ blank=True, decimal_places=2, max_digits=20, null=True
37
+ ),
38
+ ),
39
+ migrations.AlterField(
40
+ model_name="tracking",
41
+ name="hauling_cost",
42
+ field=models.DecimalField(decimal_places=2, max_digits=20),
43
+ ),
44
+ migrations.AlterField(
45
+ model_name="tracking",
46
+ name="net_price",
47
+ field=models.DecimalField(decimal_places=2, max_digits=20),
48
+ ),
49
+ migrations.AlterField(
50
+ model_name="tracking",
51
+ name="taxes",
52
+ field=models.DecimalField(decimal_places=2, max_digits=20),
53
+ ),
54
+ migrations.AlterField(
55
+ model_name="tracking",
56
+ name="value",
57
+ field=models.DecimalField(decimal_places=2, max_digits=20),
58
+ ),
59
+ migrations.AlterField(
60
+ model_name="trackingitem",
61
+ name="buy_value",
62
+ field=models.DecimalField(decimal_places=2, max_digits=20),
63
+ ),
64
+ ]
@@ -811,9 +811,13 @@ class Owner(models.Model):
811
811
  notes.append(note)
812
812
 
813
813
  # If our tracked price is different than the actual contract price
814
- if tracking.net_price >= 0 and tracking.net_price != contract.price:
814
+ # We round the numbers in here as most players do not use decimals ingame and the prices might be off by the digits
815
+ tracking_net_price = round(tracking.net_price)
816
+ contract_net_price = round(contract.price)
817
+
818
+ if tracking_net_price >= 0 and tracking_net_price != contract_net_price:
815
819
  # If contract price is bellow tracked price
816
- if contract.price > tracking.net_price:
820
+ if contract_net_price > tracking_net_price:
817
821
  note = ContractNotification(
818
822
  contract=contract,
819
823
  icon="fa-dollar-sign",
@@ -1102,9 +1106,9 @@ class Program(models.Model):
1102
1106
  )
1103
1107
 
1104
1108
  compression_price_dencity_modifier = models.BooleanField(
1105
- verbose_name="Price density modifier for compressable items",
1109
+ verbose_name="Ore volume based on compressed volume",
1106
1110
  default=False,
1107
- help_text="Should we apply price density calculations for items that can be compressed such as ore and ice. If set to False price density tax is not applied on any items that can be compressed.",
1111
+ help_text="Should we use compressed volume for items that can be compressed such as ore and ice in fuel cost and price dencity calculations. If set to False the raw volume is used for volume calculations if the item does not have a compressed price variant available from the use compressed value setting.",
1108
1112
  )
1109
1113
 
1110
1114
  price_dencity_treshold = models.IntegerField(
@@ -1284,8 +1288,8 @@ class ItemPrices(models.Model):
1284
1288
  on_delete=models.deletion.CASCADE,
1285
1289
  unique=True,
1286
1290
  )
1287
- buy = models.BigIntegerField()
1288
- sell = models.BigIntegerField()
1291
+ buy = models.DecimalField(max_digits=20, decimal_places=2)
1292
+ sell = models.DecimalField(max_digits=20, decimal_places=2)
1289
1293
  updated = models.DateTimeField()
1290
1294
 
1291
1295
 
@@ -1301,10 +1305,10 @@ class Contract(models.Model):
1301
1305
  issuer_id = models.IntegerField()
1302
1306
  start_location_id = models.BigIntegerField(null=True)
1303
1307
  location_name = models.CharField(max_length=128, null=True)
1304
- price = models.BigIntegerField()
1308
+ price = models.DecimalField(max_digits=20, decimal_places=2)
1305
1309
  status = models.CharField(max_length=30)
1306
1310
  title = models.CharField(max_length=128)
1307
- volume = models.BigIntegerField()
1311
+ volume = models.DecimalField(max_digits=20, decimal_places=2)
1308
1312
  no_tracking = models.BooleanField(default=False)
1309
1313
 
1310
1314
  def __str__(self) -> str:
@@ -1370,11 +1374,13 @@ class Tracking(models.Model):
1370
1374
  on_delete=models.deletion.CASCADE,
1371
1375
  related_name="+",
1372
1376
  )
1373
- value = models.BigIntegerField(null=False)
1374
- taxes = models.BigIntegerField(null=False)
1375
- hauling_cost = models.BigIntegerField(null=False)
1376
- donation = models.BigIntegerField(null=True, blank=True)
1377
- net_price = models.BigIntegerField(null=False)
1377
+ value = models.DecimalField(max_digits=20, decimal_places=2, null=False)
1378
+ taxes = models.DecimalField(max_digits=20, decimal_places=2, null=False)
1379
+ hauling_cost = models.DecimalField(max_digits=20, decimal_places=2, null=False)
1380
+ donation = models.DecimalField(
1381
+ max_digits=20, decimal_places=2, null=True, blank=True
1382
+ )
1383
+ net_price = models.DecimalField(max_digits=20, decimal_places=2, null=False)
1378
1384
  tracking_number = models.CharField(max_length=32)
1379
1385
  created_at = models.DateTimeField(null=True, blank=True)
1380
1386
  additional_notes = models.TextField(null=True, blank=True)
@@ -1393,7 +1399,7 @@ class TrackingItem(models.Model):
1393
1399
  help_text="Item type information",
1394
1400
  )
1395
1401
 
1396
- buy_value = models.BigIntegerField(null=False)
1402
+ buy_value = models.DecimalField(max_digits=20, decimal_places=2, null=False)
1397
1403
 
1398
1404
  quantity = models.IntegerField()
1399
1405
 
@@ -168,18 +168,16 @@ def update_all_prices():
168
168
  # Check what prices we should use either instant prices or top 5% percentile
169
169
  if not BUYBACKPROGRAM_PRICE_INSTANT_PRICES:
170
170
  # Get the price values from the API data
171
- buy = int(
172
- float(market_data[str(price.eve_type_id)]["buy"]["percentile"])
171
+ buy = float(
172
+ market_data[str(price.eve_type_id)]["buy"]["percentile"]
173
173
  )
174
- sell = int(
175
- float(market_data[str(price.eve_type_id)]["sell"]["percentile"])
174
+ sell = float(
175
+ market_data[str(price.eve_type_id)]["sell"]["percentile"]
176
176
  )
177
177
  else:
178
178
  # Get the price values from the API data
179
- buy = int(float(market_data[str(price.eve_type_id)]["buy"]["max"]))
180
- sell = int(
181
- float(market_data[str(price.eve_type_id)]["sell"]["min"])
182
- )
179
+ buy = float(market_data[str(price.eve_type_id)]["buy"]["max"])
180
+ sell = float(market_data[str(price.eve_type_id)]["sell"]["min"])
183
181
 
184
182
  # If API did not return any values we remove prices for the item
185
183
  else:
@@ -19,10 +19,10 @@
19
19
  <tr>
20
20
  <th>{% trans "I will receive:" %}</th>
21
21
  {% if contract_price_data.contract_net_total >= 0%}
22
- <td data-type="copy_value">{{contract_price_data.contract_net_total|floatformat:0|intcomma}}</td>
22
+ <td data-type="copy_value">{{contract_price_data.contract_net_total|floatformat:2|intcomma}}</td>
23
23
  <td><button data-type="copy"><i class="fa-solid fa-copy"></i></button></td>
24
24
  {% else %}
25
- <td>0 ISK <i><s>{{contract_price_data.contract_net_total|floatformat:0|intcomma}} ISK</s></i><td>
25
+ <td>0 ISK <i><s>{{contract_price_data.contract_net_total|floatformat:2|intcomma}} ISK</s></i><td>
26
26
  {% endif %}
27
27
 
28
28
 
@@ -9,34 +9,34 @@
9
9
  </tr>
10
10
  <tr>
11
11
  <th>{% trans "Price before expenses" %}</th>
12
- <td>{{contract_price_data.total_all_items_raw|floatformat:0|intcomma}} ISK</td>
12
+ <td>{{contract_price_data.total_all_items_raw|floatformat:2|intcomma}} ISK</td>
13
13
  </tr>
14
14
  <tr>
15
15
  <th>{% trans "Program taxes" %}</th>
16
- <td>{{contract_price_data.total_tax_amount|floatformat:0|intcomma}} ISK</td>
16
+ <td>{{contract_price_data.total_tax_amount|floatformat:2|intcomma}} ISK</td>
17
17
  </tr>
18
18
  <tr>
19
19
  <th>{% trans "Total volume" %}</th>
20
- <td>{{contract_price_data.contract_total_volume|floatformat:0|intcomma}} m³</td>
20
+ <td>{{contract_price_data.contract_total_volume|floatformat:2|intcomma}} m³</td>
21
21
  </tr>
22
22
  {% if program.hauling_fuel_cost > 0 %}
23
23
  <tr>
24
24
  <th>{% trans "Hauling cost" %}</th>
25
- <td>{{contract_price_data.total_hauling_cost|floatformat:0|intcomma}} ISK @ {{contract_price_data.hauling_cost|floatformat:0|intcomma}} ISK / m³</td>
25
+ <td>{{contract_price_data.total_hauling_cost|floatformat:2|intcomma}} ISK @ {{contract_price_data.hauling_cost|floatformat:2|intcomma}} ISK / m³</td>
26
26
  </tr>
27
27
  {% endif %}
28
28
  {% if contract_price_data.total_donation_amount %}
29
29
  <tr>
30
30
  <th>{% trans "Donation amount" %}</th>
31
- <td>{{contract_price_data.total_donation_amount|floatformat:0|intcomma}} ISK <i> @ {{donation}} %</i></td>
31
+ <td>{{contract_price_data.total_donation_amount|floatformat:2|intcomma}} ISK <i> @ {{donation}} %</i></td>
32
32
  </tr>
33
33
  {% endif %}
34
34
  <tr>
35
35
  <th style="border-top:2px dotted black;">Net price</th>
36
36
  {% if contract_price_data.contract_net_total >= 0%}
37
- <td style="border-top:2px dotted black;">{{contract_price_data.contract_net_total|floatformat:0|intcomma }} ISK</td>
37
+ <td style="border-top:2px dotted black;">{{contract_price_data.contract_net_total|floatformat:2|intcomma }} ISK</td>
38
38
  {% else %}
39
- <td style="border-top:2px dotted black;">0 ISK <i><s>{{contract_price_data.contract_net_total|floatformat:0|intcomma }} ISK</s></i><td>
39
+ <td style="border-top:2px dotted black;">0 ISK <i><s>{{contract_price_data.contract_net_total|floatformat:2|intcomma }} ISK</s></i><td>
40
40
  {% endif %}
41
41
  </tr>
42
42
 
@@ -32,11 +32,11 @@
32
32
 
33
33
  </td>
34
34
  <td>{{ item.item_values.quantity|intcomma }}</td>
35
- <td>{{ item.item_prices.type_prices.buy|floatformat:0|intcomma}} / {{ item.item_prices.type_prices.sell|floatformat:0|intcomma|price }}</td>
36
- <td>{{ item.item_values.raw_value|floatformat:0|intcomma|price }}</td>
35
+ <td>{{ item.item_prices.type_prices.buy|floatformat:2|intcomma}} / {{ item.item_prices.type_prices.sell|floatformat:2|intcomma|price }}</td>
36
+ <td>{{ item.item_values.raw_value|floatformat:2|intcomma|price }}</td>
37
37
  <td>{{ item.item_values.tax_value|floatformat:2|tax }}</td>
38
- <td>{{ item.item_values.unit_value|floatformat:0|intcomma|price }}</td>
39
- <td>{{ item.item_values.buy_value|floatformat:0|intcomma|price }}</td>
38
+ <td>{{ item.item_values.unit_value|floatformat:2|intcomma|price }}</td>
39
+ <td>{{ item.item_values.buy_value|floatformat:2|intcomma|price }}</td>
40
40
  <td>
41
41
  {% for note in item.item_prices.notes%}
42
42
  <i style="color: {{note.color}};" class="fas {{note.icon}}" title="{{note.message}}"></i>
@@ -54,11 +54,11 @@
54
54
  <tr class="collapse no-border" id="{{ item.item_values.normal.id }}-raw">
55
55
  <td style="padding-left: 30px;">{{ item.item_values.name }}</td>
56
56
  <td>{{ item.item_values.quantity|intcomma }}</td>
57
- <td>{{ item.item_prices.type_prices.buy|floatformat:0|intcomma }} / {{ item.item_prices.type_prices.sell|floatformat:0|intcomma|price }}</td>
58
- <td>{{ item.item_values.normal.raw_value|floatformat:0|intcomma|price }}</td>
57
+ <td>{{ item.item_prices.type_prices.buy|floatformat:2|intcomma }} / {{ item.item_prices.type_prices.sell|floatformat:2|intcomma|price }}</td>
58
+ <td>{{ item.item_values.normal.raw_value|floatformat:2|intcomma|price }}</td>
59
59
  <td>{{ item.item_values.normal.total_tax|floatformat:2|tax }}</td>
60
- <td>{{ item.item_values.normal.unit_value|floatformat:0|intcomma|price }}</td>
61
- <td class="buy-value-{{item.item_values.normal.is_buy_value}}">{{ item.item_values.normal.value|floatformat:0|intcomma|price }}</td>
60
+ <td>{{ item.item_values.normal.unit_value|floatformat:2|intcomma|price }}</td>
61
+ <td class="buy-value-{{item.item_values.normal.is_buy_value}}">{{ item.item_values.normal.value|floatformat:2|intcomma|price }}</td>
62
62
  <td>
63
63
  {% for note in item.item_values.normal.notes %}
64
64
  <i style="color: {{note.color}};" class="fas {{note.icon}}" title="{{note.message}}"></i>
@@ -77,11 +77,11 @@
77
77
  <tr class="collapse no-border" id="{{ item.item_values.normal.id }}-npc">
78
78
  <td style="padding-left: 30px;">{{item.item_values.npc.name}}</td>
79
79
  <td>{{item.item_values.npc.quantity|intcomma}}</td>
80
- <td>{{item.item_values.npc.buy|floatformat:0|intcomma}} / {{item.item_values.npc.sell|floatformat:0|intcomma|price}}</td>
81
- <td>{{ item.item_values.npc.raw_value|floatformat:0|intcomma|price }}</td>
80
+ <td>{{item.item_values.npc.buy|floatformat:2|intcomma}} / {{item.item_values.npc.sell|floatformat:2|intcomma|price}}</td>
81
+ <td>{{ item.item_values.npc.raw_value|floatformat:2|intcomma|price }}</td>
82
82
  <td>{{item.item_values.npc.total_tax|floatformat:2|tax}}</td>
83
- <td>{{item.item_values.npc.unit_value|floatformat:0|intcomma|price}}</td>
84
- <td class="buy-value-{{item.item_values.npc.is_buy_value}}">{{item.item_values.npc.value|floatformat:0|intcomma|price}}</td>
83
+ <td>{{item.item_values.npc.unit_value|floatformat:2|intcomma|price}}</td>
84
+ <td class="buy-value-{{item.item_values.npc.is_buy_value}}">{{item.item_values.npc.value|floatformat:2|intcomma|price}}</td>
85
85
  <td>
86
86
  {% for note in item.item_values.npc.notes%}
87
87
  <i style="color: {{note.color}};" class="fas {{note.icon}}" title="{{note.message}}"></i>
@@ -100,11 +100,11 @@
100
100
  <tr class="collapse no-border" id="{{ item.item_values.normal.id }}-compressed">
101
101
  <td style="padding-left: 30px;">{{item.item_values.compressed.name}}</td>
102
102
  <td>{{item.item_values.compressed.quantity|intcomma}}</td>
103
- <td>{{item.item_values.compressed.buy|floatformat:0|intcomma}} / {{item.item_values.compressed.sell|floatformat:0|intcomma|price}}</td>
104
- <td>{{item.item_values.compressed.raw_value|floatformat:0|intcomma|price}}</td>
103
+ <td>{{item.item_values.compressed.buy|floatformat:2|intcomma}} / {{item.item_values.compressed.sell|floatformat:2|intcomma|price}}</td>
104
+ <td>{{item.item_values.compressed.raw_value|floatformat:2|intcomma|price}}</td>
105
105
  <td>{{item.item_values.compressed.total_tax|floatformat:2|tax}}</td>
106
- <td>{{item.item_values.compressed.unit_value|floatformat:0|intcomma|price}}</td>
107
- <td class="buy-value-{{item.item_values.compressed.is_buy_value}}">{{item.item_values.compressed.value|floatformat:0|intcomma|price}}</td>
106
+ <td>{{item.item_values.compressed.unit_value|floatformat:2|intcomma|price}}</td>
107
+ <td class="buy-value-{{item.item_values.compressed.is_buy_value}}">{{item.item_values.compressed.value|floatformat:2|intcomma|price}}</td>
108
108
  <td>
109
109
  {% for note in item.item_values.compressed.notes%}
110
110
  <i style="color: {{note.color}};" class="fas {{note.icon}}" title="{{note.message}}"></i>
@@ -124,11 +124,11 @@
124
124
  <tr class="collapse no-border" id="{{ item.item_values.normal.id }}-refined{{ forloop.counter }}">
125
125
  <td style="padding-left: 30px;">{{material.name}}</td>
126
126
  <td>{{material.quantity|floatformat:2}}</td>
127
- <td>{{material.buy|floatformat:0|intcomma}} / {{material.sell|floatformat:0|intcomma|price}}</td>
128
- <td>{{material.raw_value|floatformat:0|intcomma|price}}</td>
127
+ <td>{{material.buy|floatformat:2|intcomma}} / {{material.sell|floatformat:2|intcomma|price}}</td>
128
+ <td>{{material.raw_value|floatformat:2|intcomma|price}}</td>
129
129
  <td>{{material.total_tax|floatformat:2|tax}}</td>
130
- <td>{{material.unit_value|floatformat:0|intcomma|price}}</td>
131
- <td>{{material.value|floatformat:0|intcomma|price}}</td>
130
+ <td>{{material.unit_value|floatformat:2|intcomma|price}}</td>
131
+ <td>{{material.value|floatformat:2|intcomma|price}}</td>
132
132
  <td>
133
133
  {% for note in material.notes%}
134
134
  <i style="color: {{note.color}};" class="fas {{note.icon}}" title="{{note.message}}"></i>
@@ -138,10 +138,10 @@
138
138
  {% endfor %}
139
139
  <tr class="collapse no-border" id="{{ item.item_values.normal.id }}-refined-total">
140
140
  <td colspan="3" style="padding-left: 30px;border-top:1px dotted grey;">{% trans "Total value" %} <i>@ {{program.refining_rate}} refining rate</i></td>
141
- <td style="border-top:1px dotted grey;">{{item.item_values.refined.raw_value|floatformat:0|intcomma|price}}</td>
141
+ <td style="border-top:1px dotted grey;">{{item.item_values.refined.raw_value|floatformat:2|intcomma|price}}</td>
142
142
  <td style="border-top:1px dotted grey;">{{item.item_values.refined.total_tax|floatformat:2|tax}}</td>
143
- <td style="border-top:1px dotted grey;">{{item.item_values.refined.unit_value|floatformat:0|intcomma|price}}</td>
144
- <td colspan="2" class="buy-value-{{item.item_values.refined.is_buy_value}}" style="border-top:1px dotted grey;">{{item.item_values.refined.value|floatformat:0|intcomma|price}}</td>
143
+ <td style="border-top:1px dotted grey;">{{item.item_values.refined.unit_value|floatformat:2|intcomma|price}}</td>
144
+ <td colspan="2" class="buy-value-{{item.item_values.refined.is_buy_value}}" style="border-top:1px dotted grey;">{{item.item_values.refined.value|floatformat:2|intcomma|price}}</td>
145
145
  </tr>
146
146
  {% endif %}
147
147
  <tr class="collapse no-border">
@@ -33,7 +33,7 @@
33
33
  </tr>
34
34
  <tr>
35
35
  <th >{% trans "Asking price" %}</th>
36
- <td>{{contract.price|floatformat:0|intcomma}} ISK</td>
36
+ <td>{{contract.price|floatformat:2|intcomma}} ISK</td>
37
37
  </tr>
38
38
  </tbody>
39
39
  </table>
@@ -6,26 +6,26 @@
6
6
  <table id="contract" class="table">
7
7
  <tr>
8
8
  <th>{% trans "Price before expenses" %}</th>
9
- <td>{{tracking.value|floatformat:0|intcomma}} ISK</td>
9
+ <td>{{tracking.value|floatformat:2|intcomma}} ISK</td>
10
10
  </tr>
11
11
  <tr>
12
12
  <th>{% trans "Program taxes" %}</th>
13
- <td>{{tracking.taxes|floatformat:0|intcomma}} ISK</td>
13
+ <td>{{tracking.taxes|floatformat:2|intcomma}} ISK</td>
14
14
  </tr>
15
15
  <tr>
16
16
  <th>{% trans "Hauling cost" %}</th>
17
- <td>{{tracking.hauling_cost|floatformat:0|intcomma}} ISK</td>
17
+ <td>{{tracking.hauling_cost|floatformat:2|intcomma}} ISK</td>
18
18
  </tr>
19
19
  <tr>
20
20
  <th>{% trans "Donation amount" %}</th>
21
- <td>{{tracking.donation|floatformat:0|intcomma}} ISK <i></i></td>
21
+ <td>{{tracking.donation|floatformat:2|intcomma}} ISK <i></i></td>
22
22
  </tr>
23
23
  <tr>
24
24
  <th style="border-top:2px dotted black;">Net price</th>
25
25
  {% if tracking.net_price >= 0 %}
26
- <td style="border-top:2px dotted black;">{{tracking.net_price|floatformat:0|intcomma }} ISK</td>
26
+ <td style="border-top:2px dotted black;">{{tracking.net_price|floatformat:2|intcomma }} ISK</td>
27
27
  {% else %}
28
- <td style="border-top:2px dotted black;">0 ISK <i><s>{{tracking.net_price|floatformat:0|intcomma }} ISK</s></i><td>
28
+ <td style="border-top:2px dotted black;">0 ISK <i><s>{{tracking.net_price|floatformat:2|intcomma }} ISK</s></i><td>
29
29
  {% endif %}
30
30
  </tr>
31
31
 
@@ -17,7 +17,7 @@
17
17
  <tr>
18
18
  <td><img class="item-icon" src="https://image.eveonline.com/Type/{{item.eve_type.id}}_64.png" />{{item.eve_type.name}}</td>
19
19
  <td>{{item.quantity|intcomma}}</td>
20
- <td>{{item.buy_value|floatformat:0|intcomma}} ISK</td>
20
+ <td>{{item.buy_value|floatformat:2|intcomma}} ISK</td>
21
21
  <td>
22
22
  {% for note in item.notes %}
23
23
  <i style="color: {{note.color}};" class="fas {{note.icon}}" title="{{note.message}}"></i>
@@ -7,13 +7,13 @@
7
7
  <th>{% trans "Outstanding count:" %}</th>
8
8
  <td>{{values.outstanding_count}}</td>
9
9
  <th>{% trans "Outstanding value:" %}</th>
10
- <td>{{values.outstanding|floatformat:0|intcomma|price}}</td>
10
+ <td>{{values.outstanding|floatformat:2|intcomma|price}}</td>
11
11
  </tr>
12
12
  <tr>
13
13
  <th>{% trans "Total bought count:" %}</th>
14
14
  <td>{{values.finished_count}}</td>
15
15
  <th>{% trans "Total bought:" %}</th>
16
- <td>{{values.finished|floatformat:0|intcomma|price}}</td>
16
+ <td>{{values.finished|floatformat:2|intcomma|price}}</td>
17
17
  </tr>
18
18
  {% if BUYBACKPROGRAM_TRACK_PREFILL_CONTRACTS %}
19
19
  <tr>
@@ -31,7 +31,7 @@
31
31
  <td>{{tracking.contract.date_issued|timesince }}</td>
32
32
  <td>{{tracking.contract.status}}</td>
33
33
  <td>{{tracking.tracking_number}}</td>
34
- <td>{{tracking.contract.price|floatformat:0|intcomma|price}}</td>
34
+ <td>{{tracking.contract.price|floatformat:2|intcomma|price}}</td>
35
35
 
36
36
  <td>
37
37
  {% for note in tracking.contract.notes %}
@@ -31,7 +31,7 @@
31
31
  <td>{{tracking.contract.date_issued|timesince }}</td>
32
32
  <td>{{tracking.contract.status}}</td>
33
33
  <td>{{tracking.tracking_number}}</td>
34
- <td>{{tracking.contract.price|floatformat:0|intcomma|price}}</td>
34
+ <td>{{tracking.contract.price|floatformat:2|intcomma|price}}</td>
35
35
 
36
36
  <td>
37
37
  {% for note in tracking.contract.notes %}
@@ -32,7 +32,7 @@
32
32
  <td>{{contract.date_issued|timesince }}</td>
33
33
  <td>{{contract.status}}</td>
34
34
  <td>{{contract.title}}</td>
35
- <td>{{contract.price|floatformat:0|intcomma|price}}</td>
35
+ <td>{{contract.price|floatformat:2|intcomma|price}}</td>
36
36
 
37
37
  <td colspan="2">
38
38
  {% for note in contract.notes %}
@@ -182,20 +182,6 @@ def location_add(request):
182
182
 
183
183
  owner = Owner.objects.filter(user=request.user).first()
184
184
 
185
- try:
186
- structure_id = int(structure_id)
187
- except ValueError:
188
- form.add_error("structure_id", "Structure ID must be a valid number.")
189
- messages_plus.error(
190
- request,
191
- "Error: Structure ID must be a valid number.",
192
- )
193
- return render(
194
- request,
195
- "buybackprogram/location_add.html",
196
- {"form": form, "locations": locations},
197
- )
198
-
199
185
  created = Location.objects.update_or_create(
200
186
  eve_solar_system=eve_solar_system,
201
187
  name=name,