Ανοίξτε ένα tip pool για περίοδο, ορίστε ποσοστιαίους διαχωρισμούς ανά ρόλο (60% σερβιτόροι / 30% κουζίνα / 10% μπαρ) και η πλατφόρμα διανέμει το σύνολο στο προσωπικό αναλογικά με τις χτυπημένες ώρες σε κάθε ρόλο. Μία συναλλαγή, ένα audit row, μηδέν spreadsheets.
Ένα tip pool είναι ένα μοναδικό γεγονός διανομής για μια καθορισμένη περίοδο — τυπικά μια βάρδια, μία ημέρα ή μια εβδομάδα. Ανοίγετε το pool με periodStart και periodEnd; η πλατφόρμα αθροίζει κάθε COMPLETED BillPayment.tipAmount σε αυτό το παράθυρο; συνδέετε ένα TipDistributionRule (παραμετροποιήσιμο ποσοστό ανά ρόλο, που αθροίζει στο 100); και στο Distribute η πλατφόρμα γράφει per-staff TipPoolDistribution γραμμές αναλογικά με τις χτυπημένες ώρες στο ρόλο τους.
Όλη η συναλλαγή είναι ατομική. Το σύνολο, ο κανόνας, οι per-staff διαχωρισμοί και η γραμμή StaffAuditLog κατεβαίνουν σε ένα μοναδικό $transaction — δεν υπάρχει half-distributed κατάσταση, partial γραμμές, 'το tip pool είναι σε παράξενη κατάσταση' bugs. Μετά τη διανομή, κλειδώστε το pool για να αποτρέψετε περαιτέρω μεταβολή.
Το pool κινείται OPEN → DISTRIBUTED σε ένα μοναδικό $transaction με τις per-staff γραμμές. Αν κάτι αποτύχει, τίποτα δεν εφαρμόζεται. Χωρίς half-distributed pools, χωρίς orphan γραμμές, χωρίς χειροκίνητες εκκαθαρίσεις.
Δύο σερβιτόροι δούλεψαν την ίδια Παρασκευή — ο ένας 4 ώρες, ο άλλος 8. Οι headcount-based διαχωρισμοί τους δίνουν το ίδιο μερίδιο, που μοιάζει άδικο. Οι hours-in-role διαχωρισμοί δίνουν στον 8-ωρο σερβιτόρο διπλό μερίδιο. Τα μαθηματικά είναι διαφανή.
Οι ποσοστιαίοι διαχωρισμοί ανά ρόλο (SERVER, KITCHEN, BAR, HOST) είναι venue-παραμετροποιήσιμοι. Το άθροισμα μεταξύ ρόλων πρέπει να είναι 100 — επιβάλλεται στο επίπεδο API. Δεν προ-φορτώνουμε 'default' διαχωρισμό επειδή η ηθική του tip-pool διαφέρει ανά χώρα και τύπο venue.
Το σύνολο pool είναι άθροισμα over completed BillPayments στην περίοδο — η ίδια κανονική πηγή που ο operator ήδη χρησιμοποιεί για αναφορές πληρωμών. Τα φιλοδωρήματα φτάνουν στο προσωπικό ακριβώς όπως τα πλήρωσε ο πελάτης.
Ανοίξτε Προσωπικό → Tip Pool → Κανόνες. Δημιουργήστε κανόνα με όνομα (π.χ. 'Standard 60/30/10'), applies-to φίλτρο (ALL / DINE_IN / DELIVERY) και τα per-role ποσοστά. Το άθροισμα γραμμών πρέπει να είναι 100.
Ανοίξτε Προσωπικό → Tip Pool, κλικ + Open period. Επιλέξτε periodStart, periodEnd και τον κανόνα προς εφαρμογή. Το pool ξεκινά σε OPEN status με totalCents = 0 — το πραγματικό άθροισμα υπολογίζεται κατά τον χρόνο διανομής.
Κλικ Distribute στην κάρτα του pool. Η πλατφόρμα αθροίζει BillPayment.tipAmount για COMPLETED πληρωμές στο παράθυρο, συγκεντρώνει χτυπημένα λεπτά ανά προσωπικό ανά ρόλο από ClockEvents, υπολογίζει per-row ποσοστιαία μερίδια και γράφει όλα ατομικά. Το pool κινείται σε DISTRIBUTED.
Αφού επανεξετάσατε τη διανομή, κλικ Lock — το pool κινείται σε LOCKED και δεν επιτρέπονται περαιτέρω μεταβολές. Εξάγετε τους per-staff διαχωρισμούς ως CSV για τον payroll provider σας.
Όλη η μαθηματική διανομή + οι inserts per-staff row + η εγγραφή StaffAuditLog κατεβαίνουν σε μία Prisma transaction. Είτε όλα commit ή τίποτα — δεν υπάρχει 'half-distributed' κατάσταση να εκκαθαρίσετε χειροκίνητα.
Μέσα σε κάθε role bucket (π.χ. SERVER: £498 από £830 pool στο 60%), το μερίδιο διασπάται αναλογικά με τα χτυπημένα λεπτά κάθε μέλους προσωπικού στο ρόλο κατά την περίοδο. Last-row residual χειρίζεται cents rounding ώστε το άθροισμα να ισούται με το bucket ακριβώς.
Οι κανόνες είναι first-class entities — ονομάστε τους, σημειώστε έναν default, αρχειοθετήστε παλιούς. Το applies-to φίλτρο (ALL / DINE_IN / DELIVERY) σας επιτρέπει να τρέχετε διαφορετικούς διαχωρισμούς για dine-in νύχτες vs delivery βάρδιες.
Αφού είστε σίγουροι ότι η διανομή είναι σωστή, κλειδώστε το pool. Το status της γραμμής γίνεται LOCKED και δεν επιτρέπονται περαιτέρω μεταβολές. Παλιά pools που έχουν πληρωθεί πρέπει πάντα να είναι κλειδωμένα — είναι το πιο καθαρό σήμα audit.
Η Παρασκευή τελειώνει με £830 σε σύνολα φιλοδωρημάτων. Ανοίξτε TipPool για την περίοδο της βάρδιας, διανείμετε έναντι του 60/30/10 κανόνα. Πέντε σερβιτόροι μοιράζονται £498 ανά ώρες, τρεις κουζίνα £249, ένας μπαρ £83.
Κάποια venues διανέμουν εβδομαδιαία σε όλες τις πηγές (dine-in + delivery + pickup φιλοδωρήματα). Ανοίξτε ένα 7ήμερο pool με κανόνα του οποίου appliesToSource = ALL. Διανείμετε Κυριακή βράδυ; το προσωπικό βλέπει το μερίδιό του Δευτέρα στο My Wages.
Οι οδηγοί παράδοσης παίρνουν 100% των φιλοδωρημάτων delivery (κανόνας A); dine-in σερβιτόροι/κουζίνα μοιράζονται dine-in φιλοδωρήματα 60/40 (κανόνας B). Ανοίξτε δύο pools ανά περίοδο.
Ένα 200-ατομο catering event περιλαμβάνει αυτόματο 18% service charge που ρέει στα σύνολα φιλοδωρημάτων. Ανοίξτε ένα one-off pool για αυτό το event, συνδέστε τον στάνταρ κανόνα σας, διανείμετε.
Ανοίξτε Προσωπικό → Tip Pool, δείτε κάθε διανεμημένο pool από τον μήνα με σύνολα, ονόματα κανόνων και per-staff διαχωρισμούς. Κλειδώστε αυτά που έχετε επανεξετάσει.
Το προσωπικό δεν χρειάζεται να ρωτά 'ποιο είναι το μερίδιό μου;'. Ανοίγουν My Wages στο κινητό και βλέπουν κάθε γραμμή TipPoolDistribution που τους αποδίδεται. Τα μαθηματικά είναι διαφανή.
Το πρόβλημα του tip pool δεν είναι 'πώς υπολογίζουμε τη διάσπαση;' — είναι 'πώς κάνουμε τη διάσπαση πιστευτή;'. Black-box payroll software που δίνει σε σερβιτόρο έναν αριθμό χωρίς ανάλυση γεννά υποψία ('πώς ξέρετε ότι είναι σωστό;'). Το tip pool του Ordering.Tools απαντά με διαφάνεια: κάθε γραμμή διανομής φέρει τις ώρες, το ρόλο, το ποσοστιαίο μερίδιο και τα cents.
Headcount-based διαχωρισμοί φιλοδωρημάτων είναι το απλούστερο νοητικό μοντέλο — 'τρεις σερβιτόροι, μοιράστε ίσα'. Αλλά τιμωρούν τον εργαζόμενο που κάλυψε επιπλέον ώρα και ανταμείβουν αυτόν που έφυγε στις 21:00 ακριβώς. Hours-in-role διαχωρισμοί αποκαθιστούν την αναλογική δικαιοσύνη.
Αν διευθυντής δημιουργήσει tip κανόνα με γραμμές που αθροίζουν στο 99% (ξέχασε ένα ρόλο), η επόμενη διανομή σιωπηρά αφήνει 1% του pool ακατανέμητο. Το Ordering.Tools επιβάλλει sum-to-100 σε τρία επίπεδα: rule-creation API απορρίπτει 99 με 400; distribution API ξανα-ελέγχει πριν τον υπολογισμό; unit tests το επιβεβαιώνουν.
Από πού πραγματικά έρχονται τα φιλοδωρήματα; Στο Ordering.Tools κάθε πληρωμή πελάτη γράφει BillPayment row με tipAmount ως ξεχωριστή decimal στήλη. Το tip pool συγκεντρώνει μόνο COMPLETED BillPayments — refunded πληρωμές εξαιρούνται αυτόματα.