Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions api/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,22 @@ const startServer = async () => {
console.log(`🚀 Environment: ${process.env.NODE_ENV || 'development'}`);
console.log(`🚀 API Endpoint: http://localhost:${PORT}/api`);
console.log('🚀 =====================================');

/*
* THE SHOP'S DECLARED DEFAULT, LOOKING FOR ORDERS NOBODY ANSWERED.
*
* Started here rather than on the till, because a shop served from the
* cloud has no till and its held orders would otherwise sit for ever.
* Does nothing at all until a shop has actually asked for a rule; see
* src/services/unanswered-orders.js.
*/
try {
require('./src/services/unanswered-orders').start();
console.log('✅ Unanswered-order rule running');
} catch (e) {
/* A shop still takes orders without it. Never fatal at boot. */
console.warn('[unanswered-orders] not started:', e && e.message);
}
});

// Handle unhandled promise rejections
Expand Down
45 changes: 44 additions & 1 deletion api/src/helpers/order-attention.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,47 @@ function notifyOrderAttention(details = {}) {
}
}

module.exports = { ATTENTION_EVENT, notifyOrderAttention };
/*
* AND THAT IT NO LONGER DOES.
*
* The alarm repeats until somebody answers, and until now the only thing that
* could stop it was a person pressing something on the page. When the shop's
* own rule decides an order - "auto cancel after ten minutes" - the order IS
* answered, and an alarm still going is an alarm about nothing.
*
* The opposite failure is the one that was built in before this existed: the
* till dropped the order from its pending list the moment its policy spoke,
* without anything acting on it, so the noise stopped while the order sat
* there. A stopped alarm is a promise that something happened, so it is only
* ever sent AFTER the order has actually moved.
*/
const RESOLVED_EVENT = 'posnic:order-resolved';

/**
* Announce that an order no longer needs anybody.
*
* @param {object} details
* @param {string} [details.branchId]
* @param {string} [details.saleId]
* @param {string} [details.state] what it became: accepted or rejected
* @param {string} [details.by] 'rule' when the shop's own default fired
*/
function notifyOrderResolved(details = {}) {
try {
process.emit(RESOLVED_EVENT, {
branchId: details.branchId ? String(details.branchId) : '',
saleId: details.saleId ? String(details.saleId) : '',
state: details.state ? String(details.state) : '',
by: details.by ? String(details.by) : '',
at: new Date().toISOString(),
});
return true;
} catch (e) {
/* A silence that fails to arrive is a shop with a noise it can stop by
hand, which is where it was before. */
console.warn('[order-attention] could not announce a resolution:', e.message);
return false;
}
}

module.exports = { ATTENTION_EVENT, RESOLVED_EVENT, notifyOrderAttention, notifyOrderResolved };
19 changes: 19 additions & 0 deletions api/src/services/settings-groups.js
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,25 @@ const CHANNELS = [
kitchen that starts at once and wrong for one that batches. 0 switches
it off; after it, cancelling becomes a request the shop decides on. */
'online_order_change_seconds',
/*
* WHAT HAPPENS WHEN NOBODY ANSWERS AT ALL, and after how long.
*
* Owner: "let restaurent owner decide that. give option auto cancel or auto
* accept. based ont time he defines it. by default dont accpept or reject."
*
* '' | 'accept' | 'cancel', and a number of minutes. BOTH or neither: a
* choice with no time fires immediately and a time with no choice fires
* nothing, so either half alone is a half-written rule. Absent means nothing
* happens, on purpose - a product that cancels a customer's order because a
* shop never opened a settings page has made a decision that was not its to
* make. services/unanswered-orders.js is what acts on it.
*/
'online_order_on_silence',
'online_order_decide_after_minutes',
/* An aggregator rejects on its own timer and counts it against the shop, so
a decision of ours landing after theirs is worse than none: the order is
already gone and we have recorded the opposite. 0 means no such window. */
'online_order_partner_window_minutes',
/* [{ code, name, unit_label, address, delivery_note, ask_floor,
price_adjust_percent, commission_percent, enabled }] - hotels, offices and
anywhere else that is not the shop's own floor. The code is what a printed
Expand Down
Loading
Loading