feat: integer cents money handling, order page fixes, and vendor filter persistence
Money Handling Architecture: - Store all monetary values as integer cents (€105.91 = 10591) - Add app/utils/money.py with Money class and conversion helpers - Add static/shared/js/money.js for frontend formatting - Update all database models to use _cents columns (Product, Order, etc.) - Update CSV processor to convert prices to cents on import - Add Alembic migration for Float to Integer conversion - Create .architecture-rules/money.yaml with 7 validation rules - Add docs/architecture/money-handling.md documentation Order Details Page Fixes: - Fix customer name showing 'undefined undefined' - use flat field names - Fix vendor info empty - add vendor_name/vendor_code to OrderDetailResponse - Fix shipping address using wrong nested object structure - Enrich order detail API response with vendor info Vendor Filter Persistence Fixes: - Fix orders.js: restoreSavedVendor now sets selectedVendor and filters - Fix orders.js: init() only loads orders if no saved vendor to restore - Fix marketplace-letzshop.js: restoreSavedVendor calls selectVendor() - Fix marketplace-letzshop.js: clearVendorSelection clears TomSelect dropdown - Align vendor selector placeholder text between pages 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -35,6 +35,32 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Test Mode -->
|
||||
<div class="mb-4">
|
||||
<label class="flex items-center cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
x-model="settingsForm.test_mode_enabled"
|
||||
class="form-checkbox h-5 w-5 text-orange-600 rounded border-gray-300 dark:border-gray-600 dark:bg-gray-700 focus:ring-orange-500"
|
||||
/>
|
||||
<span class="ml-3 text-sm font-medium text-gray-700 dark:text-gray-400">Test Mode</span>
|
||||
</label>
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400 ml-8">
|
||||
When enabled, operations (confirm, reject, tracking) will NOT be sent to Letzshop API
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Test Mode Warning -->
|
||||
<div x-show="settingsForm.test_mode_enabled" class="mb-4 p-3 bg-orange-50 dark:bg-orange-900/20 border border-orange-200 dark:border-orange-800 rounded-lg">
|
||||
<div class="flex items-center">
|
||||
<span x-html="$icon('exclamation', 'w-5 h-5 text-orange-500 mr-2')"></span>
|
||||
<span class="text-sm text-orange-700 dark:text-orange-300 font-medium">Test Mode Active</span>
|
||||
</div>
|
||||
<p class="mt-1 text-xs text-orange-600 dark:text-orange-400 ml-7">
|
||||
All Letzshop API mutations are disabled. Orders can be imported but confirmations/rejections will only be saved locally.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Auto Sync -->
|
||||
<div class="mb-4">
|
||||
<label class="flex items-center cursor-pointer">
|
||||
@@ -209,4 +235,106 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Carrier Settings Card -->
|
||||
<div class="bg-white rounded-lg shadow-xs dark:bg-gray-800 lg:col-span-2">
|
||||
<div class="p-6">
|
||||
<h3 class="mb-4 text-lg font-semibold text-gray-700 dark:text-gray-200">
|
||||
Carrier Settings
|
||||
</h3>
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400 mb-6">
|
||||
Configure default carrier and label URL prefixes for shipping labels.
|
||||
</p>
|
||||
|
||||
<form @submit.prevent="saveCarrierSettings()">
|
||||
<div class="grid gap-6 lg:grid-cols-2">
|
||||
<!-- Default Carrier -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-400 mb-2">
|
||||
Default Carrier
|
||||
</label>
|
||||
<select
|
||||
x-model="settingsForm.default_carrier"
|
||||
class="block w-full px-3 py-2 text-sm text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md focus:border-purple-400 focus:outline-none"
|
||||
>
|
||||
<option value="">-- Select carrier --</option>
|
||||
<option value="greco">Greco</option>
|
||||
<option value="colissimo">Colissimo</option>
|
||||
<option value="xpresslogistics">XpressLogistics</option>
|
||||
</select>
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
Letzshop automatically assigns carriers based on shipment data
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Placeholder for alignment -->
|
||||
<div></div>
|
||||
|
||||
<!-- Greco Label URL -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-400 mb-2">
|
||||
<span class="inline-flex items-center">
|
||||
<span class="w-3 h-3 rounded-full bg-blue-500 mr-2"></span>
|
||||
Greco Label URL Prefix
|
||||
</span>
|
||||
</label>
|
||||
<input
|
||||
x-model="settingsForm.carrier_greco_label_url"
|
||||
type="url"
|
||||
placeholder="https://dispatchweb.fr/Tracky/Home/"
|
||||
class="block w-full px-3 py-2 text-sm text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md focus:border-purple-400 focus:outline-none"
|
||||
/>
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
Label URL = Prefix + Shipment Number (e.g., H74683403433)
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Colissimo Label URL -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-400 mb-2">
|
||||
<span class="inline-flex items-center">
|
||||
<span class="w-3 h-3 rounded-full bg-yellow-500 mr-2"></span>
|
||||
Colissimo Label URL Prefix
|
||||
</span>
|
||||
</label>
|
||||
<input
|
||||
x-model="settingsForm.carrier_colissimo_label_url"
|
||||
type="url"
|
||||
placeholder="https://..."
|
||||
class="block w-full px-3 py-2 text-sm text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md focus:border-purple-400 focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- XpressLogistics Label URL -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-400 mb-2">
|
||||
<span class="inline-flex items-center">
|
||||
<span class="w-3 h-3 rounded-full bg-green-500 mr-2"></span>
|
||||
XpressLogistics Label URL Prefix
|
||||
</span>
|
||||
</label>
|
||||
<input
|
||||
x-model="settingsForm.carrier_xpresslogistics_label_url"
|
||||
type="url"
|
||||
placeholder="https://..."
|
||||
class="block w-full px-3 py-2 text-sm text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md focus:border-purple-400 focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Save Button -->
|
||||
<div class="mt-6">
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="savingCarrierSettings"
|
||||
class="flex items-center px-4 py-2 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-lg hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple disabled:opacity-50"
|
||||
>
|
||||
<span x-show="!savingCarrierSettings" x-html="$icon('save', 'w-4 h-4 mr-2')"></span>
|
||||
<span x-show="savingCarrierSettings" x-html="$icon('spinner', 'w-4 h-4 mr-2')"></span>
|
||||
<span x-text="savingCarrierSettings ? 'Saving...' : 'Save Carrier Settings'"></span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user