mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-16 19:16:49 +00:00
Compare commits
326 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9b76fadbd | ||
|
|
64f44b8a9b | ||
|
|
5dfb7645cb | ||
|
|
74927dd03d | ||
|
|
71dd398131 | ||
|
|
245f0caedb | ||
|
|
18bc95c6a3 | ||
|
|
0ecfc23c67 | ||
|
|
ff16b575c4 | ||
|
|
faa826a76e | ||
|
|
1e02084f95 | ||
|
|
44cca40db6 | ||
|
|
52174b1e06 | ||
|
|
cdf0777d8e | ||
|
|
9cb7c46b44 | ||
|
|
4c6d894bc0 | ||
|
|
27975252f5 | ||
|
|
9fc82776ec | ||
|
|
2c8bf82426 | ||
|
|
121019411c | ||
|
|
1a5eb5b39a | ||
|
|
2bd536298b | ||
|
|
7415503b63 | ||
|
|
cc35d118eb | ||
|
|
e09d78dfb2 | ||
|
|
dad7cfc180 | ||
|
|
678497914f | ||
|
|
852e7fa81e | ||
|
|
fb437fb34d | ||
|
|
025f8b25b1 | ||
|
|
3017f61047 | ||
|
|
8cb3d06f7c | ||
|
|
8f442e82ed | ||
|
|
b28886dd38 | ||
|
|
bd4f115185 | ||
|
|
c43650034f | ||
|
|
94bc787283 | ||
|
|
58851a8e67 | ||
|
|
c3e2382600 | ||
|
|
802878b4eb | ||
|
|
69d8fc3cad | ||
|
|
6a226e476d | ||
|
|
479d52a2bb | ||
|
|
8afd6eb0ab | ||
|
|
73688b9544 | ||
|
|
02ea3cb61c | ||
|
|
c7d0594257 | ||
|
|
4eee7ad603 | ||
|
|
23f7f2974a | ||
|
|
8105b919e0 | ||
|
|
53ef5148e9 | ||
|
|
93e6f9034c | ||
|
|
125a92346c | ||
|
|
31b8fe16cb | ||
|
|
cbffea8d30 | ||
|
|
be9da62d98 | ||
|
|
7320fa3f09 | ||
|
|
9f6c149735 | ||
|
|
50578647ee | ||
|
|
a28f05fddc | ||
|
|
c4c266246c | ||
|
|
d6c044fd5b | ||
|
|
a75ea5b506 | ||
|
|
7f937fd4b1 | ||
|
|
b4a64185dd | ||
|
|
a905acb56e | ||
|
|
067fa80d0f | ||
|
|
667ce5eda2 | ||
|
|
980cc9c724 | ||
|
|
c72f9477cd | ||
|
|
8787eed863 | ||
|
|
e2b6199f26 | ||
|
|
49d345e608 | ||
|
|
12a6f9ac40 | ||
|
|
7d4efe75c3 | ||
|
|
2cd41f3b8f | ||
|
|
436d919fc3 | ||
|
|
7a12e7426f | ||
|
|
bd58969fb5 | ||
|
|
0a385cc67c | ||
|
|
be5a630b9d | ||
|
|
98889365f1 | ||
|
|
9227660faf | ||
|
|
bdafc1ff02 | ||
|
|
9457b0505d | ||
|
|
755116e713 | ||
|
|
4852ee2c6e | ||
|
|
9ba215316b | ||
|
|
084f7a8a47 | ||
|
|
7c60dfb75c | ||
|
|
e2410105ce | ||
|
|
8b0207f4b1 | ||
|
|
d3319cfd69 | ||
|
|
378b5e656e | ||
|
|
b2da57b496 | ||
|
|
c6a34cfe34 | ||
|
|
591a279927 | ||
|
|
86774b3e4e | ||
|
|
2761cee5e6 | ||
|
|
9460d17417 | ||
|
|
404c07a590 | ||
|
|
f2f0d954c6 | ||
|
|
1028d42e35 | ||
|
|
91ad63d1ed | ||
|
|
2780ae78f7 | ||
|
|
bf661159c6 | ||
|
|
ad78ef14ef | ||
|
|
c7efa43cdb | ||
|
|
df6e553661 | ||
|
|
4d59343f6c | ||
|
|
44d29e98e0 | ||
|
|
06c27d6aaf | ||
|
|
cb9edfaed8 | ||
|
|
51a3085452 | ||
|
|
8ccceccd92 | ||
|
|
5e58f11006 | ||
|
|
5d8ecc5e5c | ||
|
|
12e70d729a | ||
|
|
dc61580da1 | ||
|
|
b956d6f21b | ||
|
|
b5e3681eab | ||
|
|
c45ac93a12 | ||
|
|
60ee33053d | ||
|
|
a4ea311439 | ||
|
|
5b383237ea | ||
|
|
de8029f877 | ||
|
|
d818162a9f | ||
|
|
9bd4d29027 | ||
|
|
742d442929 | ||
|
|
f08f744077 | ||
|
|
72ab0ba3f5 | ||
|
|
bb4b483469 | ||
|
|
585073a326 | ||
|
|
c3189892af | ||
|
|
417011909c | ||
|
|
9ed612410f | ||
|
|
7098cf2224 | ||
|
|
4713e9046c | ||
|
|
037030cf60 | ||
|
|
286f05d05c | ||
|
|
e9a750ce6d | ||
|
|
8942f3c72b | ||
|
|
23b2c8e11b | ||
|
|
9a9e9763cc | ||
|
|
90cd2e0ba2 | ||
|
|
8c02bde7f2 | ||
|
|
8c1e0bae92 | ||
|
|
09c7288b11 | ||
|
|
d27ffe5fca | ||
|
|
6c94650e51 | ||
|
|
79bb469332 | ||
|
|
2c4df63879 | ||
|
|
9f5d73184f | ||
|
|
4a5938c0f7 | ||
|
|
f414e04dea | ||
|
|
ef4d3ec138 | ||
|
|
0a9eb173ea | ||
|
|
f5a9ec7fa9 | ||
|
|
e190b87f12 | ||
|
|
ff2e0f4d45 | ||
|
|
d50bcbb70a | ||
|
|
782f813a15 | ||
|
|
9b0545c33f | ||
|
|
55f162ff4a | ||
|
|
ede7650fc9 | ||
|
|
7631fd422e | ||
|
|
c2c2a9503c | ||
|
|
bc1823e276 | ||
|
|
01d5830480 | ||
|
|
bad7369e67 | ||
|
|
ab65b2d745 | ||
|
|
f38aa73434 | ||
|
|
3862e0206c | ||
|
|
3a0722f39c | ||
|
|
42f7f2606b | ||
|
|
9d9f7e8717 | ||
|
|
0cf244b211 | ||
|
|
646ba18b8a | ||
|
|
8bd631fbb7 | ||
|
|
5c3acf38d7 | ||
|
|
afdc40d230 | ||
|
|
771573af1c | ||
|
|
953122b6f6 | ||
|
|
75325e2935 | ||
|
|
7e48007d09 | ||
|
|
50ab0a494c | ||
|
|
d3ef744daf | ||
|
|
ccdd12bf59 | ||
|
|
b66b033999 | ||
|
|
35d37639af | ||
|
|
6790cad089 | ||
|
|
7087d1b290 | ||
|
|
8f0cdf8722 | ||
|
|
25f6db09a5 | ||
|
|
11006c3a60 | ||
|
|
b2a3715a8b | ||
|
|
693789d526 | ||
|
|
d26b407801 | ||
|
|
6d284023fe | ||
|
|
570b72868b | ||
|
|
286d9f8e7d | ||
|
|
b0c3265cdb | ||
|
|
6bb709e85e | ||
|
|
fe257162b7 | ||
|
|
b510736a8d | ||
|
|
2df0078ea9 | ||
|
|
ca079e6e26 | ||
|
|
ac06126f59 | ||
|
|
aecb5f49c9 | ||
|
|
a18fd54916 | ||
|
|
626b802ea7 | ||
|
|
28ab41c47f | ||
|
|
17a85e9c1c | ||
|
|
9e746d1b40 | ||
|
|
273f78b214 | ||
|
|
bd1d9892a2 | ||
|
|
cb825df75b | ||
|
|
bfcadfd7c0 | ||
|
|
255b5f1cd5 | ||
|
|
dffcd446fd | ||
|
|
1987f0b667 | ||
|
|
0b5efae8c4 | ||
|
|
36bb7cb317 | ||
|
|
49dbe1d039 | ||
|
|
c326aa6b23 | ||
|
|
ec91d717c7 | ||
|
|
da843d1ba1 | ||
|
|
2c4b3ab8fc | ||
|
|
1c7fbd1d2d | ||
|
|
8042dac74f | ||
|
|
ad1ce00223 | ||
|
|
d916ed2c96 | ||
|
|
da66a2947c | ||
|
|
646d3b8ed9 | ||
|
|
1f15f094ce | ||
|
|
adddee2c3c | ||
|
|
74e7bd5172 | ||
|
|
66859f44ca | ||
|
|
6f7a547e15 | ||
|
|
c057c72321 | ||
|
|
7a3b4d394b | ||
|
|
32e3fc0175 | ||
|
|
23c9410a25 | ||
|
|
7e9c5ea58b | ||
|
|
6c313a1b5a | ||
|
|
244a88a1cd | ||
|
|
589315780c | ||
|
|
1654bb2b0a | ||
|
|
9f396a40b7 | ||
|
|
4bf1b7ac08 | ||
|
|
2910082584 | ||
|
|
70b5fda632 | ||
|
|
8bc82685ae | ||
|
|
63125705ac | ||
|
|
9bf2dad343 | ||
|
|
05b3417f77 | ||
|
|
403aa6ac6f | ||
|
|
fbad3ee9f4 | ||
|
|
ddb8b2d08f | ||
|
|
42c9ee033a | ||
|
|
524634b4ea | ||
|
|
0b97171bb0 | ||
|
|
b0c7e29b0d | ||
|
|
3d7799df19 | ||
|
|
5f02d88a86 | ||
|
|
bdae8e6478 | ||
|
|
053ef05baf | ||
|
|
7fcb31d563 | ||
|
|
31a7374808 | ||
|
|
e5ce06ae39 | ||
|
|
5f64204d51 | ||
|
|
94b75540e4 | ||
|
|
6e489d7770 | ||
|
|
81b1169e77 | ||
|
|
4b558b4820 | ||
|
|
e224b8f63b | ||
|
|
80bb0606b4 | ||
|
|
499fcc791e | ||
|
|
30dae3c3ea | ||
|
|
af247c32a3 | ||
|
|
6f9dcf7e27 | ||
|
|
2d064bab64 | ||
|
|
b69eb9bdff | ||
|
|
f79c1879bd | ||
|
|
646d538a3d | ||
|
|
b95d798a27 | ||
|
|
e1e4aeac1f | ||
|
|
c7ae47053e | ||
|
|
5892ae1800 | ||
|
|
d3a2c09f66 | ||
|
|
d596e692d8 | ||
|
|
2df95dcbab | ||
|
|
7aa9b164e6 | ||
|
|
74368f939b | ||
|
|
cb02cd39fe | ||
|
|
118e18a78e | ||
|
|
cbced144d5 | ||
|
|
1d2115766a | ||
|
|
6814ef43f4 | ||
|
|
c9e8294561 | ||
|
|
82d0e1bf68 | ||
|
|
b16e541a81 | ||
|
|
c12d494de3 | ||
|
|
9be27842e1 | ||
|
|
2a7754edbf | ||
|
|
cfeafbfc51 | ||
|
|
05b00f16ad | ||
|
|
78fdaa68c8 | ||
|
|
e8813833fa | ||
|
|
a5f44cb9b2 | ||
|
|
97d21d8cbe | ||
|
|
7afdd13b64 | ||
|
|
54c446f0a3 | ||
|
|
4454c90575 | ||
|
|
dd3a61acdf | ||
|
|
6d8ddd1eda | ||
|
|
b8e8ab15d1 | ||
|
|
bf1d2f3620 | ||
|
|
43026ddc6a | ||
|
|
18b83d2423 | ||
|
|
3750898c44 | ||
|
|
d34f8900d7 | ||
|
|
addf36a304 | ||
|
|
6a912b7d8c | ||
|
|
8011449ce7 | ||
|
|
be0894653a |
@@ -20,7 +20,6 @@ STRIPE_INSTANCE_SECRET_KEY="bogus_key"
|
||||
STRIPE_CUSTOMER="bogus_customer"
|
||||
STRIPE_ACCOUNT="bogus_account"
|
||||
STRIPE_CLIENT_ID="bogus_client_id"
|
||||
STRIPE_PUBLIC_TEST_API_KEY="bogus_stripe_publishable_key"
|
||||
|
||||
SITE_URL="test.host"
|
||||
|
||||
|
||||
15
.github/test-events/dependabot-pr.json
vendored
Normal file
15
.github/test-events/dependabot-pr.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"pull_request": {
|
||||
"number": 13545,
|
||||
"title": "Bump test from 7.0.4 to 7.0.8",
|
||||
"user": {
|
||||
"login": "dependabot[bot]"
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"owner": {
|
||||
"login": "openfoodfoundation"
|
||||
},
|
||||
"name": "openfoodnetwork"
|
||||
}
|
||||
}
|
||||
3
.github/workflows/linters.yml
vendored
3
.github/workflows/linters.yml
vendored
@@ -1,7 +1,8 @@
|
||||
name: Linters
|
||||
on: [push, pull_request]
|
||||
on: [pull_request]
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
checks: write # to post check annotations
|
||||
jobs:
|
||||
lint:
|
||||
name: prettier and rubocop
|
||||
|
||||
151
.github/workflows/move-dependency-pr-to-code-review.yml
vendored
Normal file
151
.github/workflows/move-dependency-pr-to-code-review.yml
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
name: Auto-move Dependabot PRs to Code Review
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
move-pr-to-code-review:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.pull_request.user.login == 'dependabot[bot]' || startsWith(github.event.pull_request.title, 'Bump')
|
||||
steps:
|
||||
- name: Generate GitHub App Token
|
||||
id: app-token
|
||||
uses: tibdex/github-app-token@v2
|
||||
with:
|
||||
app_id: ${{ secrets.DEPENDABOT_PR_APP_ID }}
|
||||
private_key: ${{ secrets.DEPENDABOT_PR_APP_PRIVATE_KEY }}
|
||||
installation_retrieval_mode: id
|
||||
installation_retrieval_payload: ${{ secrets.DEPENDABOT_PR_APP_INSTALLATION_ID }}
|
||||
|
||||
- name: Move PR to Code Review in Project v2
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ steps.app-token.outputs.token }}
|
||||
script: |
|
||||
const projectNumber = 8; // for "OFN Delivery board"
|
||||
const org = "openfoodfoundation";
|
||||
const repo = context.repo.repo;
|
||||
const prNumber = context.payload.pull_request.number;
|
||||
const statusFieldName = "Status";
|
||||
const statusValue = "Code review 🔎";
|
||||
|
||||
// ---- Helper: Get PR Node ID ----
|
||||
async function getPrNodeId(owner, repo, number) {
|
||||
const res = await github.graphql(`
|
||||
query($owner: String!, $repo: String!, $number: Int!) {
|
||||
repository(owner: $owner, name: $repo) {
|
||||
pullRequest(number: $number) {
|
||||
id
|
||||
number
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
`, { owner, repo, number });
|
||||
return res.repository.pullRequest.id;
|
||||
}
|
||||
|
||||
console.log("🚀 Starting ProjectV2 automation...");
|
||||
|
||||
// ---- Step 1: Get Project and Fields ----
|
||||
const projectRes = await github.graphql(`
|
||||
query($org: String!, $number: Int!) {
|
||||
organization(login: $org) {
|
||||
projectV2(number: $number) {
|
||||
id
|
||||
title
|
||||
fields(first: 50) {
|
||||
nodes {
|
||||
... on ProjectV2Field {
|
||||
id
|
||||
name
|
||||
}
|
||||
... on ProjectV2SingleSelectField {
|
||||
id
|
||||
name
|
||||
options {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`, { org, number: projectNumber });
|
||||
|
||||
const project = projectRes.organization.projectV2;
|
||||
if (!project) throw new Error(`❌ Project #${projectNumber} not found`);
|
||||
|
||||
console.log(`✅ Found project: ${project.title} (${project.id})`);
|
||||
|
||||
const statusField = project.fields.nodes.find(f => f.name === statusFieldName);
|
||||
if (!statusField) throw new Error(`❌ Field '${statusFieldName}' not found`);
|
||||
|
||||
const option = statusField.options.find(o => o.name === statusValue);
|
||||
if (!option) throw new Error(`❌ Option '${statusValue}' not found in '${statusFieldName}'`);
|
||||
|
||||
console.log(`✅ Found field '${statusFieldName}' and option '${statusValue}'`);
|
||||
|
||||
// ---- Step 2: Get PR Node ID ----
|
||||
const prNodeId = await getPrNodeId(org, repo, prNumber);
|
||||
console.log(`✅ PR #${prNumber} node ID: ${prNodeId}`);
|
||||
|
||||
// ---- Step 3: Check if PR is already in Project ----
|
||||
const itemRes = await github.graphql(`
|
||||
query($prId: ID!) {
|
||||
node(id: $prId) {
|
||||
... on PullRequest {
|
||||
projectItems(first: 50) {
|
||||
nodes {
|
||||
id
|
||||
project { id title }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`, { prId: prNodeId });
|
||||
|
||||
let projectItem = itemRes.node.projectItems.nodes.find(i => i.project.id === project.id);
|
||||
|
||||
if (!projectItem) {
|
||||
console.log("ℹ️ PR not yet in project, adding...");
|
||||
const addRes = await github.graphql(`
|
||||
mutation($projectId: ID!, $contentId: ID!) {
|
||||
addProjectV2ItemById(input: {projectId: $projectId, contentId: $contentId}) {
|
||||
item { id }
|
||||
}
|
||||
}
|
||||
`, { projectId: project.id, contentId: prNodeId });
|
||||
projectItem = addRes.addProjectV2ItemById.item;
|
||||
console.log(`✅ Added PR to project: ${projectItem.id}`);
|
||||
} else {
|
||||
console.log(`ℹ️ PR already in project: ${projectItem.id}`);
|
||||
}
|
||||
|
||||
// ---- Step 4: Update Status ----
|
||||
await github.graphql(`
|
||||
mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $optionId: String!) {
|
||||
updateProjectV2ItemFieldValue(input: {
|
||||
projectId: $projectId,
|
||||
itemId: $itemId,
|
||||
fieldId: $fieldId,
|
||||
value: { singleSelectOptionId: $optionId }
|
||||
}) {
|
||||
projectV2Item { id }
|
||||
}
|
||||
}
|
||||
`, {
|
||||
projectId: project.id,
|
||||
itemId: projectItem.id,
|
||||
fieldId: statusField.id,
|
||||
optionId: option.id,
|
||||
});
|
||||
|
||||
console.log(`🎉 Moved PR #${prNumber} → '${statusValue}'`);
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -59,3 +59,4 @@ yarn-debug.log*
|
||||
|
||||
/config/credentials.yml.enc
|
||||
/config/master.key
|
||||
.secrets
|
||||
|
||||
@@ -1 +1 @@
|
||||
17.9.1
|
||||
24.10.0
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
# The configuration is split into three files. Look into those files for more details.
|
||||
#
|
||||
require:
|
||||
plugins:
|
||||
- rubocop-capybara
|
||||
- rubocop-factory_bot
|
||||
- rubocop-rails
|
||||
|
||||
@@ -94,7 +94,7 @@ Metrics/PerceivedComplexity:
|
||||
Enabled: true
|
||||
Max: 14 # default 8
|
||||
|
||||
Naming/PredicateName:
|
||||
Naming/PredicatePrefix:
|
||||
Enabled: false
|
||||
|
||||
Naming/VariableNumber:
|
||||
|
||||
@@ -1,11 +1,44 @@
|
||||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 1400 --no-auto-gen-timestamp`
|
||||
# using RuboCop version 1.64.1.
|
||||
# using RuboCop version 1.81.6.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
# versions of RuboCop, may require this file to be generated again.
|
||||
|
||||
# Offense count: 1
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: RequireParenthesesForMethodChains.
|
||||
Lint/AmbiguousRange:
|
||||
Exclude:
|
||||
- 'app/models/concerns/permalink_generator.rb'
|
||||
|
||||
# Offense count: 6
|
||||
Lint/CopDirectiveSyntax:
|
||||
Exclude:
|
||||
- 'app/services/orders/bulk_cancel_service.rb'
|
||||
- 'lib/tasks/simplecov.rake'
|
||||
- 'spec/models/database_spec.rb'
|
||||
- 'spec/system/admin/bulk_order_management_spec.rb'
|
||||
- 'spec/system/admin/enterprise_relationships_spec.rb'
|
||||
|
||||
# Offense count: 2
|
||||
Lint/DuplicateMethods:
|
||||
Exclude:
|
||||
- 'app/models/spree/order.rb'
|
||||
- 'engines/order_management/app/services/order_management/subscriptions/form.rb'
|
||||
|
||||
# Offense count: 3
|
||||
Lint/UselessConstantScoping:
|
||||
Exclude:
|
||||
- 'app/services/weights_and_measures.rb'
|
||||
- 'lib/reporting/report_metadata_builder.rb'
|
||||
|
||||
# Offense count: 1
|
||||
Lint/UselessOr:
|
||||
Exclude:
|
||||
- 'app/models/product_import/entry_validator.rb'
|
||||
|
||||
# Offense count: 24
|
||||
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
||||
Metrics/AbcSize:
|
||||
@@ -42,12 +75,12 @@ Metrics/BlockLength:
|
||||
- 'lib/tasks/data.rake'
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: CountBlocks, Max.
|
||||
# Configuration parameters: CountBlocks, CountModifierForms, Max.
|
||||
Metrics/BlockNesting:
|
||||
Exclude:
|
||||
- 'app/models/spree/payment/processing.rb'
|
||||
|
||||
# Offense count: 47
|
||||
# Offense count: 48
|
||||
# Configuration parameters: CountComments, Max, CountAsOne.
|
||||
Metrics/ClassLength:
|
||||
Exclude:
|
||||
@@ -88,6 +121,7 @@ Metrics/ClassLength:
|
||||
- 'app/services/cart_service.rb'
|
||||
- 'app/services/order_cycles/form_service.rb'
|
||||
- 'app/services/orders/sync_service.rb'
|
||||
- 'app/services/permissions/order.rb'
|
||||
- 'app/services/sets/product_set.rb'
|
||||
- 'engines/order_management/app/services/order_management/order/updater.rb'
|
||||
- 'lib/open_food_network/enterprise_fee_calculator.rb'
|
||||
@@ -98,9 +132,8 @@ Metrics/ClassLength:
|
||||
- 'lib/reporting/reports/enterprise_fee_summary/enterprise_fees_with_tax_report_by_producer.rb'
|
||||
- 'lib/reporting/reports/enterprise_fee_summary/scope.rb'
|
||||
- 'lib/reporting/reports/xero_invoices/base.rb'
|
||||
- 'app/services/permissions/order.rb'
|
||||
|
||||
# Offense count: 30
|
||||
# Offense count: 35
|
||||
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
||||
Metrics/CyclomaticComplexity:
|
||||
Exclude:
|
||||
@@ -123,20 +156,24 @@ Metrics/CyclomaticComplexity:
|
||||
- 'app/models/spree/tax_rate.rb'
|
||||
- 'app/models/spree/zone.rb'
|
||||
- 'lib/open_food_network/enterprise_issue_validator.rb'
|
||||
- 'lib/reporting/reports/orders_and_fulfillment/order_cycle_customer_totals.rb'
|
||||
- 'lib/reporting/reports/orders_and_fulfillment/order_cycle_supplier_totals.rb'
|
||||
- 'lib/reporting/reports/payments/itemised_payment_totals.rb'
|
||||
- 'lib/reporting/reports/payments/payment_totals.rb'
|
||||
- 'lib/reporting/reports/sales_tax/sales_tax_totals_by_producer.rb'
|
||||
- 'lib/reporting/reports/xero_invoices/base.rb'
|
||||
- 'lib/spree/core/controller_helpers/order.rb'
|
||||
- 'lib/spree/core/controller_helpers/respond_with.rb'
|
||||
- 'lib/spree/localized_number.rb'
|
||||
- 'spec/models/product_importer_spec.rb'
|
||||
|
||||
# Offense count: 23
|
||||
# Offense count: 22
|
||||
# Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns.
|
||||
Metrics/MethodLength:
|
||||
Exclude:
|
||||
- 'app/controllers/admin/enterprises_controller.rb'
|
||||
- 'app/controllers/payment_gateways/paypal_controller.rb'
|
||||
- 'app/controllers/spree/orders_controller.rb'
|
||||
- 'app/helpers/spree/admin/navigation_helper.rb'
|
||||
- 'app/models/spree/ability.rb'
|
||||
- 'app/models/spree/gateway/pay_pal_express.rb'
|
||||
- 'app/models/spree/order/checkout.rb'
|
||||
@@ -149,7 +186,7 @@ Metrics/MethodLength:
|
||||
- 'lib/spree/localized_number.rb'
|
||||
- 'lib/tasks/sample_data/product_factory.rb'
|
||||
|
||||
# Offense count: 47
|
||||
# Offense count: 10
|
||||
# Configuration parameters: CountComments, Max, CountAsOne.
|
||||
Metrics/ModuleLength:
|
||||
Exclude:
|
||||
@@ -174,7 +211,7 @@ Metrics/ParameterLists:
|
||||
- 'spec/support/controller_requests_helper.rb'
|
||||
- 'spec/system/admin/reports_spec.rb'
|
||||
|
||||
# Offense count: 3
|
||||
# Offense count: 4
|
||||
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
||||
Metrics/PerceivedComplexity:
|
||||
Exclude:
|
||||
@@ -182,16 +219,147 @@ Metrics/PerceivedComplexity:
|
||||
- 'app/models/spree/ability.rb'
|
||||
- 'app/models/spree/order/checkout.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: EnforcedStyle, AllowedPatterns, ForbiddenIdentifiers, ForbiddenPatterns.
|
||||
# SupportedStyles: snake_case, camelCase
|
||||
# ForbiddenIdentifiers: __id__, __send__
|
||||
Naming/MethodName:
|
||||
Exclude:
|
||||
- 'engines/dfc_provider/lib/dfc_provider/catalog_item.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
|
||||
# AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
|
||||
Naming/MethodParameterName:
|
||||
Exclude:
|
||||
- 'engines/dfc_provider/lib/dfc_provider/catalog_item.rb'
|
||||
|
||||
# Offense count: 59
|
||||
# Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates.
|
||||
# AllowedMethods: call
|
||||
# WaywardPredicates: nonzero?
|
||||
Naming/PredicateMethod:
|
||||
Exclude:
|
||||
- 'app/controllers/admin/product_import_controller.rb'
|
||||
- 'app/controllers/api/v0/order_cycles_controller.rb'
|
||||
- 'app/controllers/spree/admin/overview_controller.rb'
|
||||
- 'app/controllers/spree/admin/payments_controller.rb'
|
||||
- 'app/controllers/voucher_adjustments_controller.rb'
|
||||
- 'app/forms/enterprise_fees_bulk_update.rb'
|
||||
- 'app/forms/schedule_form.rb'
|
||||
- 'app/helpers/spree/orders_helper.rb'
|
||||
- 'app/models/concerns/variant_stock.rb'
|
||||
- 'app/models/enterprise.rb'
|
||||
- 'app/models/enterprise_fee.rb'
|
||||
- 'app/models/invoice/data_presenter.rb'
|
||||
- 'app/models/order_cycle.rb'
|
||||
- 'app/models/product_import/entry_processor.rb'
|
||||
- 'app/models/product_import/entry_validator.rb'
|
||||
- 'app/models/spree/order.rb'
|
||||
- 'app/models/spree/order_contents.rb'
|
||||
- 'app/models/spree/payment.rb'
|
||||
- 'app/models/spree/payment/processing.rb'
|
||||
- 'app/models/spree/state_change.rb'
|
||||
- 'app/models/spree/user.rb'
|
||||
- 'app/reflexes/admin/orders_reflex.rb'
|
||||
- 'app/serializers/api/admin/for_order_cycle/enterprise_serializer.rb'
|
||||
- 'app/serializers/api/admin/index_enterprise_serializer.rb'
|
||||
- 'app/serializers/api/admin/index_order_cycle_serializer.rb'
|
||||
- 'app/serializers/api/admin/order_cycle_serializer.rb'
|
||||
- 'app/serializers/api/admin/order_serializer.rb'
|
||||
- 'app/serializers/api/admin/schedule_serializer.rb'
|
||||
- 'app/serializers/api/admin/subscription_line_item_serializer.rb'
|
||||
- 'app/serializers/api/admin/user_serializer.rb'
|
||||
- 'app/serializers/api/admin/variant_serializer.rb'
|
||||
- 'app/serializers/api/enterprise_shopfront_serializer.rb'
|
||||
- 'app/serializers/api/enterprise_thin_serializer.rb'
|
||||
- 'app/serializers/api/order_serializer.rb'
|
||||
- 'app/serializers/api/uncached_enterprise_serializer.rb'
|
||||
- 'app/services/cart_service.rb'
|
||||
- 'app/services/orders/fetch_adjustments_service.rb'
|
||||
- 'app/services/orders/workflow_service.rb'
|
||||
- 'app/services/sets/model_set.rb'
|
||||
- 'app/services/sets/order_cycle_set.rb'
|
||||
- 'app/services/sets/product_set.rb'
|
||||
- 'engines/dfc_provider/app/controllers/dfc_provider/addresses_controller.rb'
|
||||
- 'lib/open_food_network/order_cycle_form_applicator.rb'
|
||||
- 'lib/open_food_network/order_cycle_permissions.rb'
|
||||
- 'lib/reporting/reports/enterprise_fee_summary/enterprise_fees_with_tax_report_by_order.rb'
|
||||
- 'lib/reporting/reports/enterprise_fee_summary/enterprise_fees_with_tax_report_by_producer.rb'
|
||||
- 'lib/tasks/data/check_invalid_address_used.rake'
|
||||
|
||||
# Offense count: 3
|
||||
# Configuration parameters: EnforcedStyle, AllowedIdentifiers, AllowedPatterns, ForbiddenIdentifiers, ForbiddenPatterns.
|
||||
# SupportedStyles: snake_case, camelCase
|
||||
Naming/VariableName:
|
||||
Exclude:
|
||||
- 'engines/dfc_provider/lib/dfc_provider/catalog_item.rb'
|
||||
|
||||
# Offense count: 6
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Rails/FindByOrAssignmentMemoization:
|
||||
Exclude:
|
||||
- 'app/controllers/admin/customers_controller.rb'
|
||||
- 'app/controllers/admin/resource_controller.rb'
|
||||
- 'app/controllers/api/v0/enterprise_fees_controller.rb'
|
||||
- 'app/controllers/api/v0/order_cycles_controller.rb'
|
||||
- 'lib/stripe/account_connector.rb'
|
||||
|
||||
# Offense count: 32
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Rails/OrderArguments:
|
||||
Exclude:
|
||||
- 'app/controllers/admin/enterprise_fees_controller.rb'
|
||||
- 'app/controllers/admin/enterprises_controller.rb'
|
||||
- 'app/controllers/admin/order_cycles_controller.rb'
|
||||
- 'app/controllers/admin/product_import_controller.rb'
|
||||
- 'app/controllers/api/v0/states_controller.rb'
|
||||
- 'app/controllers/spree/admin/overview_controller.rb'
|
||||
- 'app/controllers/spree/admin/products_controller.rb'
|
||||
- 'app/helpers/enterprises_helper.rb'
|
||||
- 'app/models/enterprise.rb'
|
||||
- 'app/models/enterprise_group.rb'
|
||||
- 'app/models/enterprise_relationship_permission.rb'
|
||||
- 'app/models/order_cycle.rb'
|
||||
- 'app/models/product_import/product_importer.rb'
|
||||
- 'app/models/schedule.rb'
|
||||
- 'app/models/spree/country.rb'
|
||||
- 'app/models/spree/order.rb'
|
||||
- 'app/models/spree/shipping_rate.rb'
|
||||
- 'app/models/spree/user.rb'
|
||||
- 'app/models/spree/zone.rb'
|
||||
- 'app/models/subscription_line_item.rb'
|
||||
- 'app/models/tag_rule.rb'
|
||||
- 'app/models/variant_override.rb'
|
||||
- 'lib/open_food_network/address_finder.rb'
|
||||
- 'spec/services/orders/generate_invoice_service_spec.rb'
|
||||
- 'spec/system/admin/order_cycles/simple_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: TransactionMethods.
|
||||
Rails/TransactionExitStatement:
|
||||
Exclude:
|
||||
- 'app/services/place_proxy_order.rb'
|
||||
|
||||
# Offense count: 3
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Style/ArrayIntersect:
|
||||
Exclude:
|
||||
- 'app/models/spree/ability.rb'
|
||||
- 'app/models/spree/variant.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Style/BitwisePredicate:
|
||||
Exclude:
|
||||
- 'app/helpers/admin/enterprises_helper.rb'
|
||||
|
||||
# Offense count: 23
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
# Configuration parameters: EnforcedStyle, EnforcedStyleForClasses, EnforcedStyleForModules.
|
||||
# SupportedStyles: nested, compact
|
||||
# SupportedStylesForClasses: ~, nested, compact
|
||||
# SupportedStylesForModules: ~, nested, compact
|
||||
Style/ClassAndModuleChildren:
|
||||
Exclude:
|
||||
- 'app/models/calculator/flat_percent_per_item.rb'
|
||||
@@ -217,13 +385,33 @@ Style/ClassAndModuleChildren:
|
||||
- 'lib/open_food_network/locking.rb'
|
||||
- 'spec/models/spree/payment_method_spec.rb'
|
||||
|
||||
# Offense count: 4
|
||||
# Offense count: 14
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Style/CollectionQuerying:
|
||||
Exclude:
|
||||
- 'app/controllers/spree/credit_cards_controller.rb'
|
||||
- 'app/models/product_import/product_importer.rb'
|
||||
- 'app/models/product_import/spreadsheet_entry.rb'
|
||||
- 'app/models/spree/order.rb'
|
||||
- 'app/models/spree/order_inventory.rb'
|
||||
- 'app/models/spree/payment_method.rb'
|
||||
- 'app/models/spree/user.rb'
|
||||
- 'app/models/stripe_account.rb'
|
||||
- 'app/services/order_cycles/warning_service.rb'
|
||||
- 'lib/reporting/report_renderer.rb'
|
||||
- 'lib/tasks/sample_data.rake'
|
||||
|
||||
# Offense count: 2
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Style/HashSlice:
|
||||
Exclude:
|
||||
- 'app/services/product_filters.rb'
|
||||
- 'lib/reporting/report_row_builder.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Style/MapToHash:
|
||||
Exclude:
|
||||
- 'lib/reporting/report_query_template.rb'
|
||||
- 'lib/reporting/report_row_builder.rb'
|
||||
- 'lib/reporting/reports/enterprise_fee_summary/fee_summary.rb'
|
||||
- 'lib/tasks/sample_data/user_factory.rb'
|
||||
|
||||
# Offense count: 38
|
||||
@@ -254,3 +442,22 @@ Style/OptionalBooleanParameter:
|
||||
- 'engines/order_management/app/services/order_management/stock/estimator.rb'
|
||||
- 'lib/spree/core/controller_helpers/order.rb'
|
||||
- 'spec/support/request/web_helper.rb'
|
||||
|
||||
# Offense count: 3
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Style/RedundantFormat:
|
||||
Exclude:
|
||||
- 'spec/models/product_importer_spec.rb'
|
||||
- 'spec/requests/checkout/stripe_sca_spec.rb'
|
||||
- 'spec/system/consumer/account/cards_spec.rb'
|
||||
|
||||
# Offense count: 8
|
||||
# Configuration parameters: Max.
|
||||
Style/SafeNavigationChainLength:
|
||||
Exclude:
|
||||
- 'app/controllers/concerns/extra_fields.rb'
|
||||
- 'app/services/customer_syncer.rb'
|
||||
- 'app/services/fdc_offer_broker.rb'
|
||||
- 'engines/dfc_provider/app/services/dfc_catalog.rb'
|
||||
- 'engines/dfc_provider/app/services/image_builder.rb'
|
||||
- 'engines/dfc_provider/app/services/quantitative_value_builder.rb'
|
||||
|
||||
@@ -1 +1 @@
|
||||
3.1.4
|
||||
3.1.7
|
||||
|
||||
4
.secrets.example
Normal file
4
.secrets.example
Normal file
@@ -0,0 +1,4 @@
|
||||
# .secrets file define github secrets value locally
|
||||
DEPENDABOT_PR_APP_ID=123456
|
||||
DEPENDABOT_PR_APP_INSTALLATION_ID=123456
|
||||
DEPENDABOT_PR_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n....\n-----END RSA PRIVATE KEY-----"
|
||||
11
.simplecov
11
.simplecov
@@ -2,10 +2,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
SimpleCov.start 'rails' do
|
||||
# The rails profile contains some filters already:
|
||||
#
|
||||
# - "/test/"
|
||||
# - "/features/"
|
||||
# - "/spec/"
|
||||
# - "/autotest/"
|
||||
# - /^\/config\//
|
||||
# - /^\/db\//
|
||||
add_filter '/bin/'
|
||||
add_filter '/config/'
|
||||
add_filter '/config/' # to include engine config
|
||||
add_filter '/script'
|
||||
add_filter '/db'
|
||||
|
||||
formatter SimpleCov::Formatter::SimpleFormatter
|
||||
end
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
#!/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
-c master
|
||||
--compare master
|
||||
|
||||
# This shouldn't be needed in undercover > 0.7.4
|
||||
#
|
||||
# * https://github.com/grodowski/undercover/issues/233
|
||||
--exclude-files "bin/*,db/*,config/*,spec/*,engines/*/config/*,engines/*/spec/*"
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
FROM ruby:3.1.4-alpine3.19 AS base
|
||||
FROM ruby:3.1.7-alpine3.19 AS base
|
||||
ENV LANG=C.UTF-8 \
|
||||
LC_ALL=C.UTF-8 \
|
||||
TZ=Europe/London \
|
||||
RAILS_ROOT=/usr/src/app
|
||||
RAILS_ROOT=/usr/src/app \
|
||||
BUNDLE_PATH=/bundles \
|
||||
BUNDLE_APP_CONFIG=/bundles
|
||||
RUN apk --no-cache upgrade && \
|
||||
apk add --no-cache tzdata postgresql-client imagemagick imagemagick-jpeg && \
|
||||
apk add --no-cache --virtual wkhtmltopdf
|
||||
@@ -14,7 +16,7 @@ FROM base AS development-base
|
||||
RUN apk add --no-cache --virtual .build-deps \
|
||||
build-base postgresql-dev git nodejs yarn && \
|
||||
apk add --no-cache --virtual .dev-utils \
|
||||
bash curl less vim chromium-chromedriver zlib-dev openssl-dev \
|
||||
bash curl less vim chromium-chromedriver zlib-dev openssl-dev cmake\
|
||||
readline-dev yaml-dev sqlite-dev libxml2-dev libxslt-dev libffi-dev vips-dev && \
|
||||
curl -o /usr/local/bin/wait-for-it https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh && \
|
||||
chmod +x /usr/local/bin/wait-for-it
|
||||
|
||||
@@ -25,7 +25,8 @@ RUN apt-get update && apt-get install -y \
|
||||
libjemalloc-dev \
|
||||
libssl-dev \
|
||||
ca-certificates \
|
||||
gnupg
|
||||
gnupg \
|
||||
cmake
|
||||
|
||||
# Setup ENV variables
|
||||
ENV PATH /usr/local/src/rbenv/shims:/usr/local/src/rbenv/bin:/usr/local/src/nodenv/shims:/usr/local/src/nodenv/bin:$PATH
|
||||
|
||||
@@ -73,7 +73,7 @@ To login as the default user, use:
|
||||
email: ofn@example.com
|
||||
password: ofn123
|
||||
|
||||
Seee [Locale and sample data] about loading data.
|
||||
See [Locale and sample data] about loading data.
|
||||
|
||||
### Testing
|
||||
|
||||
|
||||
9
Gemfile
9
Gemfile
@@ -20,10 +20,13 @@ gem 'ransack', '~> 4.1.0'
|
||||
gem 'responders'
|
||||
gem 'webpacker', '~> 5'
|
||||
|
||||
# Indirect dependency but we access it directly in JS specs.
|
||||
# It turns out to be hard to upgrade but please do if you can.
|
||||
gem 'sprockets', '~> 3.7'
|
||||
|
||||
gem 'i18n'
|
||||
gem 'i18n-js', '~> 3.9.0'
|
||||
gem 'rails-i18n'
|
||||
gem 'rails_safe_tasks', '~> 1.0'
|
||||
|
||||
gem "activerecord-import"
|
||||
gem "db2fog", github: "openfoodfoundation/db2fog", branch: "rails-7"
|
||||
@@ -167,7 +170,6 @@ group :test, :development do
|
||||
gem 'rswag'
|
||||
gem 'shoulda-matchers'
|
||||
gem 'stimulus_reflex_testing', github: "podia/stimulus_reflex_testing", branch: :main
|
||||
gem 'timecop'
|
||||
end
|
||||
|
||||
group :test do
|
||||
@@ -191,8 +193,11 @@ group :development do
|
||||
gem 'query_count'
|
||||
gem 'rails-erd'
|
||||
gem 'rubocop'
|
||||
gem 'rubocop-capybara'
|
||||
gem 'rubocop-factory_bot'
|
||||
gem 'rubocop-rails'
|
||||
gem 'rubocop-rspec'
|
||||
gem 'rubocop-rspec_rails'
|
||||
gem 'spring'
|
||||
gem 'spring-commands-rspec'
|
||||
gem 'spring-commands-rubocop'
|
||||
|
||||
238
Gemfile.lock
238
Gemfile.lock
@@ -122,7 +122,7 @@ GEM
|
||||
activemodel (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
timeout (>= 0.4.0)
|
||||
activerecord-import (1.6.0)
|
||||
activerecord-import (2.2.0)
|
||||
activerecord (>= 4.2)
|
||||
activerecord-postgresql-adapter (0.0.1)
|
||||
pg
|
||||
@@ -156,8 +156,8 @@ GEM
|
||||
activerecord (>= 6.1, < 7.2)
|
||||
acts_as_list (1.0.4)
|
||||
activerecord (>= 4.2)
|
||||
addressable (2.8.6)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
addressable (2.8.7)
|
||||
public_suffix (>= 2.0.2, < 7.0)
|
||||
aes_key_wrap (1.1.0)
|
||||
afm (0.2.2)
|
||||
angular-rails-templates (1.2.1)
|
||||
@@ -192,15 +192,15 @@ GEM
|
||||
base64 (0.3.0)
|
||||
bcp47_spec (0.2.1)
|
||||
bcrypt (3.1.20)
|
||||
benchmark (0.4.1)
|
||||
bigdecimal (3.2.2)
|
||||
benchmark (0.5.0)
|
||||
bigdecimal (3.3.1)
|
||||
bindata (2.5.0)
|
||||
bindex (0.8.1)
|
||||
bootsnap (1.18.3)
|
||||
msgpack (~> 1.2)
|
||||
bugsnag (6.26.4)
|
||||
concurrent-ruby (~> 1.0)
|
||||
builder (3.2.4)
|
||||
builder (3.3.0)
|
||||
bullet (8.0.8)
|
||||
activesupport (>= 3.0.0)
|
||||
uniform_notifier (~> 1.11)
|
||||
@@ -228,7 +228,7 @@ GEM
|
||||
marcel (~> 1.0)
|
||||
nokogiri (~> 1.10, >= 1.10.4)
|
||||
rubyzip (>= 1.3.0, < 3)
|
||||
cgi (0.3.7)
|
||||
cgi (0.5.0)
|
||||
childprocess (5.0.0)
|
||||
choice (0.2.0)
|
||||
chronic (0.10.2)
|
||||
@@ -244,7 +244,7 @@ GEM
|
||||
matrix
|
||||
ruby-rc4 (>= 0.1.5)
|
||||
concurrent-ruby (1.3.5)
|
||||
connection_pool (2.5.3)
|
||||
connection_pool (2.5.4)
|
||||
cookiejar (0.3.4)
|
||||
crack (1.0.0)
|
||||
bigdecimal
|
||||
@@ -281,9 +281,9 @@ GEM
|
||||
devise (>= 4.9.0)
|
||||
devise-token_authenticatable (1.1.0)
|
||||
devise (>= 4.0.0, < 5.0.0)
|
||||
diff-lcs (1.5.1)
|
||||
digest (3.1.1)
|
||||
docile (1.4.0)
|
||||
diff-lcs (1.6.2)
|
||||
digest (3.2.0)
|
||||
docile (1.4.1)
|
||||
dotenv (3.1.2)
|
||||
drb (2.2.3)
|
||||
em-http-request (1.1.7)
|
||||
@@ -299,7 +299,9 @@ GEM
|
||||
eventmachine (>= 1.0.0.beta.1)
|
||||
email_validator (2.2.4)
|
||||
activemodel
|
||||
erubi (1.12.0)
|
||||
erb (4.0.4)
|
||||
cgi (>= 0.3.3)
|
||||
erubi (1.13.1)
|
||||
et-orbi (1.3.0)
|
||||
tzinfo
|
||||
eventmachine (1.2.7)
|
||||
@@ -324,7 +326,7 @@ GEM
|
||||
websocket-driver (>= 0.6, < 0.8)
|
||||
ffaker (2.23.0)
|
||||
ffi (1.16.3)
|
||||
flipper (1.3.0)
|
||||
flipper (1.3.6)
|
||||
concurrent-ruby (< 2)
|
||||
flipper-active_record (1.3.0)
|
||||
activerecord (>= 4.2, < 8)
|
||||
@@ -372,13 +374,13 @@ GEM
|
||||
temple (>= 0.8.2)
|
||||
thor
|
||||
tilt
|
||||
hashdiff (1.1.0)
|
||||
hashdiff (1.2.1)
|
||||
hashery (2.1.2)
|
||||
hashie (5.0.0)
|
||||
highline (2.0.3)
|
||||
htmlentities (4.3.4)
|
||||
http_parser.rb (0.8.0)
|
||||
i18n (1.14.5)
|
||||
i18n (1.14.7)
|
||||
concurrent-ruby (~> 1.0)
|
||||
i18n-js (3.9.2)
|
||||
i18n (>= 0.6.6)
|
||||
@@ -401,10 +403,11 @@ GEM
|
||||
activerecord (>= 3.0)
|
||||
invisible_captcha (2.3.0)
|
||||
rails (>= 5.2)
|
||||
io-console (0.7.2)
|
||||
io-console (0.8.1)
|
||||
ipaddress (0.8.3)
|
||||
irb (1.12.0)
|
||||
rdoc
|
||||
irb (1.15.2)
|
||||
pp (>= 0.6.0)
|
||||
rdoc (>= 4.0.0)
|
||||
reline (>= 0.4.2)
|
||||
jmespath (1.6.2)
|
||||
jquery-rails (4.4.0)
|
||||
@@ -413,7 +416,7 @@ GEM
|
||||
thor (>= 0.14, < 2.0)
|
||||
jquery-ui-rails (4.2.1)
|
||||
railties (>= 3.2.16)
|
||||
json (2.7.2)
|
||||
json (2.15.2)
|
||||
json-canonicalization (1.0.0)
|
||||
json-jwt (1.16.6)
|
||||
activesupport (>= 4.2)
|
||||
@@ -439,15 +442,16 @@ GEM
|
||||
activesupport (>= 4.2)
|
||||
jwt (2.8.1)
|
||||
base64
|
||||
knapsack_pro (8.1.2)
|
||||
knapsack_pro (8.4.0)
|
||||
rake
|
||||
language_server-protocol (3.17.0.3)
|
||||
language_server-protocol (3.17.0.5)
|
||||
launchy (3.0.0)
|
||||
addressable (~> 2.8)
|
||||
childprocess (~> 5.0)
|
||||
letter_opener (1.10.0)
|
||||
launchy (>= 2.2, < 4)
|
||||
link_header (0.0.8)
|
||||
lint_roller (1.1.0)
|
||||
listen (3.9.0)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
@@ -463,16 +467,17 @@ GEM
|
||||
marcel (1.0.4)
|
||||
matrix (0.4.2)
|
||||
method_source (1.1.0)
|
||||
mime-types (3.5.2)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2023.1205)
|
||||
mime-types (3.7.0)
|
||||
logger
|
||||
mime-types-data (~> 3.2025, >= 3.2025.0507)
|
||||
mime-types-data (3.2025.0924)
|
||||
mimemagic (0.4.3)
|
||||
nokogiri (~> 1)
|
||||
rake
|
||||
mini_magick (4.11.0)
|
||||
mini_magick (4.13.2)
|
||||
mini_mime (1.1.5)
|
||||
mini_portile2 (2.8.6)
|
||||
minitest (5.25.5)
|
||||
minitest (5.26.0)
|
||||
monetize (1.13.0)
|
||||
money (~> 6.12)
|
||||
money (6.16.0)
|
||||
@@ -492,9 +497,9 @@ GEM
|
||||
timeout
|
||||
net-smtp (0.5.0)
|
||||
net-protocol
|
||||
newrelic_rpm (9.9.0)
|
||||
newrelic_rpm (9.22.0)
|
||||
nio4r (2.7.1)
|
||||
nokogiri (1.18.9)
|
||||
nokogiri (1.18.10)
|
||||
mini_portile2 (~> 2.8.2)
|
||||
racc (~> 1.4)
|
||||
nokogiri-html5-inference (0.3.0)
|
||||
@@ -535,10 +540,10 @@ GEM
|
||||
paper_trail (15.1.0)
|
||||
activerecord (>= 6.1)
|
||||
request_store (~> 1.4)
|
||||
parallel (1.24.0)
|
||||
parallel (1.27.0)
|
||||
paranoia (2.6.3)
|
||||
activerecord (>= 5.1, < 7.2)
|
||||
parser (3.3.8.0)
|
||||
parser (3.3.10.0)
|
||||
ast (~> 2.4.1)
|
||||
racc
|
||||
paypal-sdk-core (0.3.4)
|
||||
@@ -553,13 +558,18 @@ GEM
|
||||
ruby-rc4
|
||||
ttfunk
|
||||
pg (1.2.3)
|
||||
pp (0.6.2)
|
||||
prettyprint
|
||||
prettyprint (0.2.0)
|
||||
prism (1.6.0)
|
||||
private_address_check (0.5.0)
|
||||
pry (0.13.1)
|
||||
coderay (~> 1.1)
|
||||
method_source (~> 1.0)
|
||||
psych (5.1.2)
|
||||
psych (5.2.6)
|
||||
date
|
||||
stringio
|
||||
public_suffix (5.0.5)
|
||||
public_suffix (6.0.2)
|
||||
puffing-billy (4.0.2)
|
||||
addressable (~> 2.5)
|
||||
em-http-request (~> 1.1, >= 1.1.0)
|
||||
@@ -575,7 +585,7 @@ GEM
|
||||
railties (>= 4.2)
|
||||
raabro (1.4.0)
|
||||
racc (1.8.1)
|
||||
rack (2.2.14)
|
||||
rack (2.2.20)
|
||||
rack-mini-profiler (2.3.4)
|
||||
rack (>= 1.2.0)
|
||||
rack-oauth2 (2.2.1)
|
||||
@@ -593,7 +603,7 @@ GEM
|
||||
rack-rewrite (1.5.1)
|
||||
rack-session (1.0.2)
|
||||
rack (< 3)
|
||||
rack-test (2.1.0)
|
||||
rack-test (2.2.0)
|
||||
rack (>= 1.3)
|
||||
rack-timeout (0.7.0)
|
||||
rackup (1.0.1)
|
||||
@@ -617,7 +627,7 @@ GEM
|
||||
actionpack (>= 5.0.1.rc1)
|
||||
actionview (>= 5.0.1.rc1)
|
||||
activesupport (>= 5.0.1.rc1)
|
||||
rails-dom-testing (2.2.0)
|
||||
rails-dom-testing (2.3.0)
|
||||
activesupport (>= 5.0.0)
|
||||
minitest
|
||||
nokogiri (>= 1.6)
|
||||
@@ -626,13 +636,12 @@ GEM
|
||||
activesupport (>= 4.2)
|
||||
choice (~> 0.2.0)
|
||||
ruby-graphviz (~> 1.2)
|
||||
rails-html-sanitizer (1.6.1)
|
||||
rails-html-sanitizer (1.6.2)
|
||||
loofah (~> 2.21)
|
||||
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
||||
rails-i18n (7.0.9)
|
||||
rails-i18n (7.0.10)
|
||||
i18n (>= 0.7, < 2)
|
||||
railties (>= 6.0.0, < 8)
|
||||
rails_safe_tasks (1.0.0)
|
||||
railties (7.1.5.2)
|
||||
actionpack (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
@@ -642,7 +651,7 @@ GEM
|
||||
thor (~> 1.0, >= 1.2.2)
|
||||
zeitwerk (~> 2.6)
|
||||
rainbow (3.1.1)
|
||||
rake (13.2.1)
|
||||
rake (13.3.0)
|
||||
ransack (4.1.1)
|
||||
activerecord (>= 6.1.5)
|
||||
activesupport (>= 6.1.5)
|
||||
@@ -654,15 +663,17 @@ GEM
|
||||
bcp47_spec (~> 0.2)
|
||||
bigdecimal (~> 3.1, >= 3.1.5)
|
||||
link_header (~> 0.0, >= 0.0.8)
|
||||
rdoc (6.6.3.1)
|
||||
rdoc (6.15.0)
|
||||
erb
|
||||
psych (>= 4.0.0)
|
||||
tsort
|
||||
redcarpet (3.6.0)
|
||||
redis (5.2.0)
|
||||
redis (5.4.1)
|
||||
redis-client (>= 0.22.0)
|
||||
redis-client (0.22.1)
|
||||
redis-client (0.26.1)
|
||||
connection_pool
|
||||
regexp_parser (2.9.2)
|
||||
reline (0.5.0)
|
||||
regexp_parser (2.11.3)
|
||||
reline (0.6.2)
|
||||
io-console (~> 0.5)
|
||||
request_store (1.5.1)
|
||||
rack (>= 1.4)
|
||||
@@ -687,18 +698,18 @@ GEM
|
||||
rspec-core (~> 3.13.0)
|
||||
rspec-expectations (~> 3.13.0)
|
||||
rspec-mocks (~> 3.13.0)
|
||||
rspec-core (3.13.0)
|
||||
rspec-core (3.13.5)
|
||||
rspec-support (~> 3.13.0)
|
||||
rspec-expectations (3.13.0)
|
||||
rspec-expectations (3.13.5)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.13.0)
|
||||
rspec-mocks (3.13.0)
|
||||
rspec-mocks (3.13.5)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.13.0)
|
||||
rspec-rails (6.1.2)
|
||||
actionpack (>= 6.1)
|
||||
activesupport (>= 6.1)
|
||||
railties (>= 6.1)
|
||||
rspec-rails (7.1.1)
|
||||
actionpack (>= 7.0)
|
||||
activesupport (>= 7.0)
|
||||
railties (>= 7.0)
|
||||
rspec-core (~> 3.13)
|
||||
rspec-expectations (~> 3.13)
|
||||
rspec-mocks (~> 3.13)
|
||||
@@ -708,51 +719,55 @@ GEM
|
||||
rspec-sql (0.0.3)
|
||||
activesupport
|
||||
rspec
|
||||
rspec-support (3.13.1)
|
||||
rswag (2.13.0)
|
||||
rswag-api (= 2.13.0)
|
||||
rswag-specs (= 2.13.0)
|
||||
rswag-ui (= 2.13.0)
|
||||
rswag-api (2.13.0)
|
||||
activesupport (>= 3.1, < 7.2)
|
||||
railties (>= 3.1, < 7.2)
|
||||
rswag-specs (2.13.0)
|
||||
activesupport (>= 3.1, < 7.2)
|
||||
json-schema (>= 2.2, < 5.0)
|
||||
railties (>= 3.1, < 7.2)
|
||||
rspec-support (3.13.6)
|
||||
rswag (2.16.0)
|
||||
rswag-api (= 2.16.0)
|
||||
rswag-specs (= 2.16.0)
|
||||
rswag-ui (= 2.16.0)
|
||||
rswag-api (2.16.0)
|
||||
activesupport (>= 5.2, < 8.1)
|
||||
railties (>= 5.2, < 8.1)
|
||||
rswag-specs (2.16.0)
|
||||
activesupport (>= 5.2, < 8.1)
|
||||
json-schema (>= 2.2, < 6.0)
|
||||
railties (>= 5.2, < 8.1)
|
||||
rspec-core (>= 2.14)
|
||||
rswag-ui (2.13.0)
|
||||
actionpack (>= 3.1, < 7.2)
|
||||
railties (>= 3.1, < 7.2)
|
||||
rubocop (1.64.1)
|
||||
rswag-ui (2.16.0)
|
||||
actionpack (>= 5.2, < 8.1)
|
||||
railties (>= 5.2, < 8.1)
|
||||
rubocop (1.81.6)
|
||||
json (~> 2.3)
|
||||
language_server-protocol (>= 3.17.0)
|
||||
language_server-protocol (~> 3.17.0.2)
|
||||
lint_roller (~> 1.1.0)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 3.3.0.2)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 1.8, < 3.0)
|
||||
rexml (>= 3.2.5, < 4.0)
|
||||
rubocop-ast (>= 1.31.1, < 2.0)
|
||||
regexp_parser (>= 2.9.3, < 3.0)
|
||||
rubocop-ast (>= 1.47.1, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 2.4.0, < 3.0)
|
||||
rubocop-ast (1.31.3)
|
||||
parser (>= 3.3.1.0)
|
||||
rubocop-capybara (2.20.0)
|
||||
rubocop (~> 1.41)
|
||||
rubocop-factory_bot (2.25.1)
|
||||
rubocop (~> 1.41)
|
||||
rubocop-rails (2.28.0)
|
||||
unicode-display_width (>= 2.4.0, < 4.0)
|
||||
rubocop-ast (1.47.1)
|
||||
parser (>= 3.3.7.2)
|
||||
prism (~> 1.4)
|
||||
rubocop-capybara (2.22.1)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.72, >= 1.72.1)
|
||||
rubocop-factory_bot (2.27.1)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.72, >= 1.72.1)
|
||||
rubocop-rails (2.33.4)
|
||||
activesupport (>= 4.2.0)
|
||||
lint_roller (~> 1.1)
|
||||
rack (>= 1.1)
|
||||
rubocop (>= 1.52.0, < 2.0)
|
||||
rubocop-ast (>= 1.31.1, < 2.0)
|
||||
rubocop-rspec (2.29.2)
|
||||
rubocop (~> 1.40)
|
||||
rubocop-capybara (~> 2.17)
|
||||
rubocop-factory_bot (~> 2.22)
|
||||
rubocop-rspec_rails (~> 2.28)
|
||||
rubocop-rspec_rails (2.28.3)
|
||||
rubocop (~> 1.40)
|
||||
rubocop (>= 1.75.0, < 2.0)
|
||||
rubocop-ast (>= 1.44.0, < 2.0)
|
||||
rubocop-rspec (3.7.0)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.72, >= 1.72.1)
|
||||
rubocop-rspec_rails (2.31.0)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.72, >= 1.72.1)
|
||||
rubocop-rspec (~> 3.5)
|
||||
ruby-graphviz (1.2.5)
|
||||
rexml
|
||||
ruby-progressbar (1.13.0)
|
||||
@@ -791,7 +806,7 @@ GEM
|
||||
docile (~> 1.1)
|
||||
simplecov-html (~> 0.11)
|
||||
simplecov_json_formatter (~> 0.1)
|
||||
simplecov-html (0.12.3)
|
||||
simplecov-html (0.13.2)
|
||||
simplecov_json_formatter (0.1.4)
|
||||
spreadsheet_architect (5.0.0)
|
||||
caxlsx (>= 3.3.0, < 4)
|
||||
@@ -801,20 +816,21 @@ GEM
|
||||
spring (>= 0.9.1)
|
||||
spring-commands-rubocop (0.4.0)
|
||||
spring (>= 1.0)
|
||||
sprockets (3.7.2)
|
||||
sprockets (3.7.5)
|
||||
base64
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
sprockets-rails (3.4.2)
|
||||
actionpack (>= 5.2)
|
||||
activesupport (>= 5.2)
|
||||
sprockets (>= 3.0.0)
|
||||
state_machines (0.6.0)
|
||||
state_machines-activemodel (0.9.0)
|
||||
activemodel (>= 6.0)
|
||||
state_machines (>= 0.6.0)
|
||||
state_machines-activerecord (0.9.0)
|
||||
activerecord (>= 6.0)
|
||||
state_machines-activemodel (>= 0.9.0)
|
||||
state_machines (0.20.0)
|
||||
state_machines-activemodel (0.10.0)
|
||||
activemodel (>= 7.1)
|
||||
state_machines (>= 0.10.0)
|
||||
state_machines-activerecord (0.31.0)
|
||||
activerecord (>= 7.1)
|
||||
state_machines-activemodel (>= 0.10.0)
|
||||
stimulus_reflex (3.5.5)
|
||||
actioncable (>= 5.2)
|
||||
actionpack (>= 5.2)
|
||||
@@ -828,9 +844,9 @@ GEM
|
||||
railties (>= 5.2)
|
||||
redis (>= 4.0, < 6.0)
|
||||
stringex (2.8.6)
|
||||
stringio (3.1.0)
|
||||
stringio (3.1.7)
|
||||
stripe (11.1.0)
|
||||
strscan (3.1.2)
|
||||
strscan (3.1.5)
|
||||
swd (2.0.3)
|
||||
activesupport (>= 3)
|
||||
attr_required (>= 0.0.5)
|
||||
@@ -842,8 +858,8 @@ GEM
|
||||
thor (1.4.0)
|
||||
thread-local (1.1.0)
|
||||
tilt (2.3.0)
|
||||
timecop (0.9.10)
|
||||
timeout (0.4.3)
|
||||
tsort (0.2.0)
|
||||
ttfunk (1.8.0)
|
||||
bigdecimal (~> 3.1)
|
||||
turbo-rails (2.0.5)
|
||||
@@ -854,7 +870,7 @@ GEM
|
||||
turbo-rails (>= 1.3.0)
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
undercover (0.7.4)
|
||||
undercover (0.8.1)
|
||||
base64
|
||||
bigdecimal
|
||||
imagen (>= 0.2.0)
|
||||
@@ -862,7 +878,9 @@ GEM
|
||||
rugged (>= 0.27, < 1.10)
|
||||
simplecov
|
||||
simplecov_json_formatter
|
||||
unicode-display_width (2.5.0)
|
||||
unicode-display_width (3.2.0)
|
||||
unicode-emoji (~> 4.1)
|
||||
unicode-emoji (4.1.0)
|
||||
uniform_notifier (1.17.0)
|
||||
uri (0.13.2)
|
||||
valid_email2 (5.2.3)
|
||||
@@ -895,7 +913,7 @@ GEM
|
||||
activesupport
|
||||
faraday (~> 2.0)
|
||||
faraday-follow_redirects
|
||||
webmock (3.23.1)
|
||||
webmock (3.25.1)
|
||||
addressable (>= 2.8.0)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff (>= 0.4.0, < 2.0.0)
|
||||
@@ -904,7 +922,7 @@ GEM
|
||||
rack-proxy (>= 0.6.1)
|
||||
railties (>= 5.2)
|
||||
semantic_range (>= 2.3.0)
|
||||
webrick (1.8.2)
|
||||
webrick (1.9.1)
|
||||
websocket-driver (0.7.6)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.5)
|
||||
@@ -912,11 +930,11 @@ GEM
|
||||
chronic (>= 0.6.3)
|
||||
wicked_pdf (2.8.1)
|
||||
activesupport
|
||||
wkhtmltopdf-binary (0.12.6.7)
|
||||
wkhtmltopdf-binary (0.12.6.10)
|
||||
xml-simple (1.1.8)
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
zeitwerk (2.6.15)
|
||||
zeitwerk (2.6.18)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
@@ -1018,7 +1036,6 @@ DEPENDENCIES
|
||||
rails-controller-testing
|
||||
rails-erd
|
||||
rails-i18n
|
||||
rails_safe_tasks (~> 1.0)
|
||||
ransack (~> 4.1.0)
|
||||
redcarpet
|
||||
redis
|
||||
@@ -1032,8 +1049,11 @@ DEPENDENCIES
|
||||
rswag-api
|
||||
rswag-ui
|
||||
rubocop
|
||||
rubocop-capybara
|
||||
rubocop-factory_bot
|
||||
rubocop-rails
|
||||
rubocop-rspec
|
||||
rubocop-rspec_rails
|
||||
sd_notify
|
||||
select2-rails!
|
||||
shoulda-matchers
|
||||
@@ -1044,12 +1064,12 @@ DEPENDENCIES
|
||||
spring
|
||||
spring-commands-rspec
|
||||
spring-commands-rubocop
|
||||
sprockets (~> 3.7)
|
||||
state_machines-activerecord
|
||||
stimulus_reflex
|
||||
stimulus_reflex_testing!
|
||||
stringex (~> 2.8.5)
|
||||
stripe
|
||||
timecop
|
||||
turbo-rails
|
||||
turbo_power
|
||||
undercover
|
||||
@@ -1067,7 +1087,7 @@ DEPENDENCIES
|
||||
wkhtmltopdf-binary
|
||||
|
||||
RUBY VERSION
|
||||
ruby 3.1.4p223
|
||||
ruby 3.1.7p261
|
||||
|
||||
BUNDLED WITH
|
||||
2.4.3
|
||||
|
||||
@@ -6,7 +6,6 @@ angular.module("admin.enterprises", [
|
||||
"admin.side_menu",
|
||||
"admin.taxons",
|
||||
'admin.indexUtils',
|
||||
'admin.tagRules',
|
||||
'admin.dropdown',
|
||||
'ngSanitize']
|
||||
)
|
||||
|
||||
@@ -15,4 +15,4 @@ angular.module("admin.paymentMethods").controller "StripeController", ($scope, $
|
||||
permalink = shops.filter((shop) ->
|
||||
shop.id == $scope.paymentMethod.preferred_enterprise_id
|
||||
)[0].permalink
|
||||
"/admin/enterprises/#{permalink}/edit#/payment_methods"
|
||||
"/admin/enterprises/#{permalink}/edit#/payment_methods_panel"
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
angular.module("admin.tagRules").controller "TagRulesCtrl", ($scope, $http, $filter, enterprise) ->
|
||||
$scope.tagGroups = enterprise.tag_groups
|
||||
$scope.defaultTagGroup = enterprise.default_tag_group
|
||||
|
||||
$scope.visibilityOptions = [ { id: "visible", name: t('js.tag_rules.visible') }, { id: "hidden", name: t('js.tag_rules.not_visible') } ]
|
||||
|
||||
$scope.updateRuleCounts = ->
|
||||
index = $scope.defaultTagGroup.rules.length
|
||||
for tagGroup in $filter('orderBy')($scope.tagGroups, 'position')
|
||||
tagGroup.startIndex = index
|
||||
index = index + tagGroup.rules.length
|
||||
|
||||
$scope.updateRuleCounts()
|
||||
|
||||
$scope.updateTagsRulesFor = (tagGroup) ->
|
||||
for tagRule in tagGroup.rules
|
||||
tagRule.preferred_customer_tags = (tag.text for tag in tagGroup.tags).join(",")
|
||||
|
||||
$scope.addNewRuleTo = (tagGroup, ruleType) ->
|
||||
newRule =
|
||||
id: null
|
||||
is_default: tagGroup == $scope.defaultTagGroup
|
||||
preferred_customer_tags: (tag.text for tag in tagGroup.tags).join(",")
|
||||
type: "TagRule::#{ruleType}"
|
||||
switch ruleType
|
||||
when "FilterShippingMethods"
|
||||
newRule.peferred_shipping_method_tags = []
|
||||
newRule.preferred_matched_shipping_methods_visibility = "visible"
|
||||
when "FilterPaymentMethods"
|
||||
newRule.peferred_payment_method_tags = []
|
||||
newRule.preferred_matched_payment_methods_visibility = "visible"
|
||||
when "FilterProducts"
|
||||
newRule.peferred_variant_tags = []
|
||||
newRule.preferred_matched_variants_visibility = "visible"
|
||||
when "FilterOrderCycles"
|
||||
newRule.peferred_exchange_tags = []
|
||||
newRule.preferred_matched_order_cycles_visibility = "visible"
|
||||
tagGroup.rules.push(newRule)
|
||||
$scope.updateRuleCounts()
|
||||
|
||||
$scope.addNewTag = ->
|
||||
$scope.tagGroups.push { tags: [], rules: [], position: $scope.tagGroups.length + 1 }
|
||||
|
||||
$scope.deleteTagRule = (tagGroup, tagRule) ->
|
||||
index = tagGroup.rules.indexOf(tagRule)
|
||||
return unless index >= 0
|
||||
if tagRule.id is null
|
||||
tagGroup.rules.splice(index, 1)
|
||||
$scope.updateRuleCounts()
|
||||
else
|
||||
if confirm("Are you sure?")
|
||||
$http
|
||||
method: "DELETE"
|
||||
url: "/admin/enterprises/#{enterprise.id}/tag_rules/#{tagRule.id}.json"
|
||||
.then ->
|
||||
tagGroup.rules.splice(index, 1)
|
||||
$scope.updateRuleCounts()
|
||||
$scope.enterprise_form.$setDirty()
|
||||
@@ -1,11 +0,0 @@
|
||||
angular.module("admin.tagRules").directive "invertNumber", ->
|
||||
restrict: "A"
|
||||
require: "ngModel"
|
||||
link: (scope, element, attrs, ngModel) ->
|
||||
ngModel.$parsers.push (viewValue) ->
|
||||
return -parseInt(viewValue) unless isNaN(parseInt(viewValue))
|
||||
viewValue
|
||||
|
||||
ngModel.$formatters.push (modelValue) ->
|
||||
return -parseInt(modelValue) unless isNaN(parseInt(modelValue))
|
||||
modelValue
|
||||
@@ -1,26 +0,0 @@
|
||||
angular.module("admin.tagRules").directive 'newTagRuleDialog', ($rootScope, $compile, $templateCache, DialogDefaults, ruleTypes) ->
|
||||
restrict: 'A'
|
||||
scope:
|
||||
tagGroup: '='
|
||||
addNewRuleTo: '='
|
||||
link: (scope, element, attr) ->
|
||||
# Compile modal template
|
||||
template = $compile($templateCache.get('admin/new_tag_rule_dialog.html'))(scope)
|
||||
|
||||
scope.ruleTypes = ruleTypes
|
||||
|
||||
scope.ruleType = scope.ruleTypes[0].id
|
||||
|
||||
# Set Dialog options
|
||||
template.dialog(DialogDefaults)
|
||||
|
||||
# Link opening of dialog to click event on element
|
||||
element.bind 'click', (e) ->
|
||||
template.dialog('open')
|
||||
$rootScope.$evalAsync()
|
||||
|
||||
scope.addRule = (tagGroup, ruleType) ->
|
||||
scope.addNewRuleTo(tagGroup, ruleType)
|
||||
template.dialog('close')
|
||||
$rootScope.$evalAsync()
|
||||
return
|
||||
@@ -1,41 +0,0 @@
|
||||
angular.module("admin.tagRules").directive "tagRule", ->
|
||||
restrict: "C"
|
||||
templateUrl: "admin/tag_rules/tag_rule.html"
|
||||
link: (scope, element, attrs) ->
|
||||
scope.opt =
|
||||
"TagRule::FilterShippingMethods":
|
||||
textTop: t('js.admin.tag_rules.shipping_method_tagged_top')
|
||||
textBottom: t('js.admin.tag_rules.shipping_method_tagged_bottom')
|
||||
taggable: "shipping_method"
|
||||
tagsAttr: "shipping_method_tags"
|
||||
tagListAttr: "preferred_shipping_method_tags"
|
||||
inputTemplate: "admin/tag_rules/filter_shipping_methods_input.html"
|
||||
tagListFor: (rule) ->
|
||||
rule.preferred_shipping_method_tags
|
||||
"TagRule::FilterPaymentMethods":
|
||||
textTop: t('js.admin.tag_rules.payment_method_tagged_top')
|
||||
textBottom: t('js.admin.tag_rules.payment_method_tagged_bottom')
|
||||
taggable: "payment_method"
|
||||
tagsAttr: "payment_method_tags"
|
||||
tagListAttr: "preferred_payment_method_tags"
|
||||
inputTemplate: "admin/tag_rules/filter_payment_methods_input.html"
|
||||
tagListFor: (rule) ->
|
||||
rule.preferred_payment_method_tags
|
||||
"TagRule::FilterOrderCycles":
|
||||
textTop: t('js.admin.tag_rules.order_cycle_tagged_top')
|
||||
textBottom: t('js.admin.tag_rules.order_cycle_tagged_bottom')
|
||||
taggable: "exchange"
|
||||
tagsAttr: "exchange_tags"
|
||||
tagListAttr: "preferred_exchange_tags"
|
||||
inputTemplate: "admin/tag_rules/filter_order_cycles_input.html"
|
||||
tagListFor: (rule) ->
|
||||
rule.preferred_exchange_tags
|
||||
"TagRule::FilterProducts":
|
||||
textTop: t('js.admin.tag_rules.inventory_tagged_top')
|
||||
textBottom: t('js.admin.tag_rules.inventory_tagged_bottom')
|
||||
taggable: "variant"
|
||||
tagsAttr: "variant_tags"
|
||||
tagListAttr: "preferred_variant_tags"
|
||||
inputTemplate: "admin/tag_rules/filter_products_input.html"
|
||||
tagListFor: (rule) ->
|
||||
rule.preferred_variant_tags
|
||||
@@ -1,6 +1,6 @@
|
||||
angular.module('Darkswarm').directive "activeTableHubLink", (CurrentHub, CurrentOrder) ->
|
||||
# Change the text of the hub link based on CurrentHub
|
||||
# To be used with ofnEmptiesCart
|
||||
# To be used with ofnChangeHub
|
||||
# Takes "change" and "shop" as text string attributes
|
||||
restrict: "A"
|
||||
scope:
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
angular.module('Darkswarm').directive "darkerBackground", ->
|
||||
restrict: "A"
|
||||
link: (scope, elm, attr)->
|
||||
toggleClass = (value) ->
|
||||
elm.closest('.page-view').toggleClass("with-darker-background", value)
|
||||
|
||||
toggleClass(true)
|
||||
|
||||
# if an OrderCycle is selected, disable darker background
|
||||
scope.$watch 'order_cycle.order_cycle_id', (newvalue, oldvalue) ->
|
||||
toggleClass(false) if newvalue
|
||||
@@ -1,14 +0,0 @@
|
||||
# Allows disabling of link buttons via disabled attribute.
|
||||
# This is normally ignored, ie the link appears disabled but is still clickable.
|
||||
|
||||
angular.module('Darkswarm').directive "disableDynamically", ->
|
||||
restrict: 'A'
|
||||
|
||||
link: (scope, element, attrs) ->
|
||||
element.on 'click', (e) ->
|
||||
if attrs.disabled
|
||||
e.preventDefault()
|
||||
return
|
||||
|
||||
scope.$on "$destroy", ->
|
||||
element.off("click")
|
||||
@@ -1,7 +0,0 @@
|
||||
angular.module('Darkswarm').directive "ofnInlineAlert", ->
|
||||
restrict: 'A'
|
||||
scope: true
|
||||
link: (scope, elem, attrs) ->
|
||||
scope.visible = true
|
||||
scope.close = ->
|
||||
scope.visible = false
|
||||
@@ -1,21 +0,0 @@
|
||||
angular.module('Darkswarm').directive "ofnPageAlert", ($timeout) ->
|
||||
restrict: 'A'
|
||||
scope: true
|
||||
link: (scope, elem, attrs) ->
|
||||
moveSelectors = [".off-canvas-wrap .inner-wrap",
|
||||
".off-canvas-wrap .inner-wrap .fixed",
|
||||
".off-canvas-fixed .top-bar",
|
||||
".off-canvas-fixed ofn-flash",
|
||||
".off-canvas-fixed nav.tab-bar",
|
||||
".off-canvas-fixed .page-alert"]
|
||||
|
||||
container_elems = $(moveSelectors.join(", "))
|
||||
|
||||
# Wait a moment after page load before showing the alert. Otherwise we often miss the
|
||||
# start of the animation.
|
||||
$timeout ->
|
||||
container_elems.addClass("move-up")
|
||||
, 1000
|
||||
|
||||
scope.close = ->
|
||||
container_elems.removeClass("move-up")
|
||||
@@ -1,10 +0,0 @@
|
||||
#new-tag-rule-dialog
|
||||
.text-normal.margin-bottom-30.text-center
|
||||
{{ 'js.admin.new_tag_rule_dialog.select_rule_type' | t }}
|
||||
|
||||
.text-center.margin-bottom-30
|
||||
-# %select.fullwidth{ 'select2-min-search' => 5, 'ng-model' => 'newRuleType', 'ng-options' => 'ruleType.id as ruleType.name for ruleType in availableRuleTypes' }
|
||||
%input.ofn-select2.fullwidth{ id: 'rule_type_selector', data: "ruleTypes", "min-search": "5", "ng-model": "ruleType" }
|
||||
|
||||
.text-center
|
||||
%input.button.red.icon-plus{ type: 'button', value: "{{ 'js.admin.new_tag_rule_dialog.add_rule' | t }}", "ng-click": 'addRule(tagGroup, ruleType)' }
|
||||
@@ -3,4 +3,4 @@
|
||||
%span.text-normal
|
||||
{{ 'admin.tags' | t }}
|
||||
%br
|
||||
%tags-with-translation.fullwidth{ object: 'object' }
|
||||
%tags-with-translation.fullwidth{ object: 'object', form: 'order_cycle_form', id: 'tags_with_translation'}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
%div
|
||||
%input{ type: "number", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_calculator_attributes_preferred_flat_percent", min: -100, max: 100, "invert-number": true, "ng-model": "rule.calculator.preferred_flat_percent" }
|
||||
%span.text-normal %
|
||||
@@ -1,5 +0,0 @@
|
||||
%div
|
||||
%input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_order_cycles_visibility", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_order_cycles_visibility]", data: 'visibilityOptions', "min-search": 5, "ng-model": "rule.preferred_matched_order_cycles_visibility", "ng-if": "!rule.is_default" }
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_order_cycles_visibility", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_order_cycles_visibility]", "ng-value": "'hidden'", "ng-if": "rule.is_default" }
|
||||
%span.text-normal{ "ng-if": "rule.is_default" }
|
||||
=t(:not_visible)
|
||||
@@ -1,5 +0,0 @@
|
||||
%div
|
||||
%input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_payment_methods_visibility", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_payment_methods_visibility]", data: 'visibilityOptions', "min-search": 5, "ng-model": "rule.preferred_matched_payment_methods_visibility", "ng-if": "!rule.is_default" }
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_payment_methods_visibility", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_payment_methods_visibility]", "ng-value": "'hidden'", "ng-if": "rule.is_default" }
|
||||
%span.text-normal{ "ng-if": "rule.is_default" }
|
||||
= t(:not_visible)
|
||||
@@ -1,5 +0,0 @@
|
||||
%div
|
||||
%input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_variants_visibility", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_variants_visibility]", data: 'visibilityOptions', "min-search": 5, "ng-model": "rule.preferred_matched_variants_visibility", "ng-if": "!rule.is_default" }
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_variants_visibility", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_variants_visibility]", "ng-value": "'hidden'", "ng-if": "rule.is_default" }
|
||||
%span.text-normal{ "ng-if": "rule.is_default" }
|
||||
= t(:not_visible)
|
||||
@@ -1,6 +0,0 @@
|
||||
%div
|
||||
%input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_shipping_methods_visibility", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_shipping_methods_visibility]", data: 'visibilityOptions', "min-search": 5, "ng-model": "rule.preferred_matched_shipping_methods_visibility", "ng-if": "!rule.is_default" }
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_shipping_methods_visibility", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_shipping_methods_visibility]", "ng-value": "'hidden'", "ng-if": "rule.is_default" }
|
||||
%span.text-normal{ "ng-if": "rule.is_default" }
|
||||
= t(:not_visible)
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
%div{ id: "tr_{{tagGroup.startIndex + $index}}" }
|
||||
%table
|
||||
%colgroup
|
||||
%col.text{ width: "35%" }
|
||||
%col.inputs{ width: "55%" }
|
||||
%col.actions{ width: "10%" }
|
||||
%tr
|
||||
%td
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_id", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][id]", "ng-value": "rule.id" }
|
||||
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_type", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][type]", "ng-value": "rule.type" }
|
||||
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_priority", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][priority]", "ng-value": "tagGroup.startIndex + $index" }
|
||||
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_is_default", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][is_default]", "ng-value": "rule.is_default" }
|
||||
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_customer_tags", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_customer_tags]", "ng-value": "rule.preferred_customer_tags" }
|
||||
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_{{opt[rule.type].taggable}}_tags", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_{{opt[rule.type].taggable}}_tags]", "ng-value": "opt[rule.type].tagListFor(rule)" }
|
||||
|
||||
%span.text-normal {{ opt[rule.type].textTop }}
|
||||
%td
|
||||
%tags-with-translation{ object: "rule", max: 1, "tags-attr" => "{{opt[rule.type].tagsAttr}}", "tag-list-attr" => "{{opt[rule.type].tagListAttr}}" }
|
||||
%td.actions{ rowspan: 2 }
|
||||
%a{ class: "delete-tag-rule icon-trash no-text", "ng-click": "deleteTagRule(tagGroup || defaultTagGroup, rule)" }
|
||||
%tr
|
||||
%td
|
||||
%span.text-normal {{ opt[rule.type].textBottom }}
|
||||
%td
|
||||
%div{ "ng-include": "opt[rule.type].inputTemplate" }
|
||||
|
||||
%hr
|
||||
@@ -12,7 +12,7 @@
|
||||
.row
|
||||
.columns.small-12
|
||||
%a.cta-hub{"ng-repeat" => "hub in enterprise.hubs | filter:{id: '!'+enterprise.id} | orderBy:'-active'",
|
||||
"ng-href" => "{{::hub.path}}#/shop_panel", "ofn-empties-cart" => "hub",
|
||||
"ng-href" => "{{::hub.path}}#/shop_panel",
|
||||
"ng-class" => "::{primary: hub.active, secondary: !hub.active}",
|
||||
"ng-click" => "$close()",
|
||||
"ofn-change-hub" => "hub"}
|
||||
|
||||
21
app/components/add_tag_rule_modal_component.rb
Normal file
21
app/components/add_tag_rule_modal_component.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class AddTagRuleModalComponent < ModalComponent
|
||||
def initialize(id:, tag_rule_types:, current_index:, div_id:, is_default: false,
|
||||
customer_tag: "", hidden_field_customer_tag_options: {} )
|
||||
super
|
||||
|
||||
@close_button = false
|
||||
@modal_class = "tiny"
|
||||
|
||||
@tag_rule_types = tag_rule_types
|
||||
@current_index = current_index
|
||||
@div_id = div_id
|
||||
@is_default = is_default
|
||||
@customer_tag = customer_tag
|
||||
@hidden_field_customer_tag_options = hidden_field_customer_tag_options
|
||||
end
|
||||
|
||||
attr_reader :tag_rule_types, :current_index, :div_id, :is_default, :customer_tag,
|
||||
:hidden_field_customer_tag_options
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
-# as far as I can tell we can't pass content to the parent template while rendering ie: something like :
|
||||
-# = render_parent do
|
||||
-# .something
|
||||
-# my content
|
||||
-# Workarount is to copy the ModalComponent template
|
||||
%div{ id: @id, "data-controller": @data_controller, "data-action": @data_action, "data-modal-instant-value": @instant, **@options }
|
||||
.reveal-modal-bg.fade{ "data-modal-target": "background", "data-action": "click->modal#close" }
|
||||
.reveal-modal.fade.modal-component{ "data-modal-target": "modal", class: @modal_class }
|
||||
#new-tag-rule-dialog{ "data-controller": "add-tag-rule-modal",
|
||||
"data-add-tag-rule-modal-index-value": current_index }
|
||||
|
||||
-# Ideally we would use event to communicate the update of customer tag, but we would need
|
||||
-# the element with "data-controller": "add-tag-rule-modal"
|
||||
-# to be parent of the element with "data-controller": "tag-rule-group-form"
|
||||
-# so it could respond to event generated by "tag-rule-group-form".
|
||||
-# Here we are in the opposite situation so we use a hidden field to store the value of
|
||||
-# the customer tag, so it can be updated by "tag-rule-group-form"
|
||||
= hidden_field_tag "customer_tag", customer_tag, { "data-add-tag-rule-modal-target": "ruleCustomerTag" }.merge(hidden_field_customer_tag_options)
|
||||
.text-normal.margin-bottom-30.text-center
|
||||
= t('components.add_tag_rule_modal.select_rule_type')
|
||||
.text-center.margin-bottom-30
|
||||
= select_tag :rule_type_selector, options_for_select(tag_rule_types), { "data-controller": "tom-select", "data-add-tag-rule-modal-target": "rule", class: "primary no-search" }
|
||||
.text-center
|
||||
%input.button.red.icon-plus{ type: 'button',
|
||||
value: "#{t('components.add_tag_rule_modal.add_rule')}",
|
||||
"data-action": "click->add-tag-rule-modal#add click->modal#close",
|
||||
"data-add-tag-rule-modal-div-id-param": div_id,
|
||||
"data-add-tag-rule-modal-is-default-param": "#{is_default}"}
|
||||
|
||||
- if close_button?
|
||||
.text-center
|
||||
%input{ class: "button icon-plus #{close_button_class}", type: 'button', value: t('js.admin.modals.close'), "data-action": "click->modal#close" }
|
||||
@@ -0,0 +1,46 @@
|
||||
import { Controller } from "stimulus";
|
||||
import showHttpError from "../../webpacker/js/services/show_http_error";
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["rule", "ruleCustomerTag"];
|
||||
static values = { index: Number };
|
||||
|
||||
add({ params }) {
|
||||
const rule_type = this.ruleTarget.value;
|
||||
const index = this.indexValue;
|
||||
const divId = params["divId"];
|
||||
const isDefault = params["isDefault"];
|
||||
const customerTags = this.hasRuleCustomerTagTarget
|
||||
? this.ruleCustomerTagTarget.value
|
||||
: undefined;
|
||||
|
||||
const urlParams = new URLSearchParams();
|
||||
urlParams.append("rule_type", rule_type);
|
||||
urlParams.append("index", index);
|
||||
urlParams.append("div_id", divId);
|
||||
urlParams.append("is_default", isDefault);
|
||||
if (customerTags != undefined) {
|
||||
urlParams.append("customer_tags", customerTags);
|
||||
}
|
||||
|
||||
// fetch from backend
|
||||
fetch(`tag_rules/new?${urlParams}`, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Accept: "text/vnd.turbo-stream.html",
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
showHttpError(response.status);
|
||||
throw response;
|
||||
}
|
||||
return response.text();
|
||||
})
|
||||
.then((html) => {
|
||||
Turbo.renderStreamMessage(html);
|
||||
this.indexValue = parseInt(index) + 1;
|
||||
})
|
||||
.catch((error) => console.error(error));
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
// This controller will be called "example-component--example", ie "component-subdirectory--js-file-name"
|
||||
// This controller will be called "example", ie "js-file-name" minus the "_controller.js"
|
||||
// see controller/index.js for more info
|
||||
import { Controller } from "stimulus";
|
||||
|
||||
export default class extends Controller {}
|
||||
|
||||
@@ -30,7 +30,7 @@ class SearchableDropdownComponent < ViewComponent::Base
|
||||
:aria_label, :other_attrs
|
||||
|
||||
def classes
|
||||
"fullwidth #{remove_search_plugin? ? 'no-input' : ''}"
|
||||
"fullwidth #{'no-input' if remove_search_plugin?}"
|
||||
end
|
||||
|
||||
def data
|
||||
|
||||
@@ -1,16 +1,26 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class TagListInputComponent < ViewComponent::Base
|
||||
# method in a "hidden_field" form helper and is the method used to get a list of tag on the model
|
||||
def initialize(form:, method:, tags:,
|
||||
def initialize(name:, tags:,
|
||||
placeholder: I18n.t("components.tag_list_input.default_placeholder"),
|
||||
aria_label: nil)
|
||||
@f = form
|
||||
@method = method
|
||||
only_one: false,
|
||||
aria_label: nil,
|
||||
hidden_field_data_options: {})
|
||||
@name = name
|
||||
@tags = tags
|
||||
@placeholder = placeholder
|
||||
@only_one = only_one
|
||||
@aria_label_option = aria_label ? { 'aria-label': aria_label } : {}
|
||||
@hidden_field_data_options = hidden_field_data_options
|
||||
end
|
||||
|
||||
attr_reader :f, :method, :tags, :placeholder, :aria_label_option
|
||||
attr_reader :name, :tags, :placeholder, :only_one, :aria_label_option, :hidden_field_data_options
|
||||
|
||||
private
|
||||
|
||||
def display
|
||||
return "none" if tags.length >= 1 && only_one == true
|
||||
|
||||
"block"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
%div{ "data-controller": "tag-list-input-component--tag-list-input" }
|
||||
%div{ "data-controller": "tag-list-input", "data-tag-list-input-only-one-value": "#{only_one}" }
|
||||
.tags-input
|
||||
.tags
|
||||
- # We use display:none instead of hidden field, so changes to the value can be picked up by the bulkFormController
|
||||
= f.text_field method.to_sym, value: tags.join(","), "data-tag-list-input-component--tag-list-input-target": "tagList", "style": "display: none"
|
||||
%ul.tag-list{"data-tag-list-input-component--tag-list-input-target": "list"}
|
||||
%template{"data-tag-list-input-component--tag-list-input-target": "template"}
|
||||
= text_field_tag name, tags.join(","), {"data-tag-list-input-target": "tagList", "style": "display: none"}.merge(hidden_field_data_options)
|
||||
%ul.tag-list{"data-tag-list-input-target": "list"}
|
||||
%template{"data-tag-list-input-target": "template"}
|
||||
%li.tag-item
|
||||
.tag-template
|
||||
%span
|
||||
%a.remove-button{ "data-action": "click->tag-list-input-component--tag-list-input#removeTag" }
|
||||
%a.remove-button{ "data-action": "click->tag-list-input#removeTag" }
|
||||
×
|
||||
- tags.each do |tag|
|
||||
%li.tag-item
|
||||
.tag-template
|
||||
%span=tag
|
||||
%a.remove-button{ "data-action": "click->tag-list-input-component--tag-list-input#removeTag" }
|
||||
%a.remove-button{ "data-action": "click->tag-list-input#removeTag" }
|
||||
×
|
||||
= text_field_tag "variant_add_tag_#{f.object.id}".to_sym, nil, class: "input", placeholder: placeholder, "data-action": "keydown.enter->tag-list-input-component--tag-list-input#addTag keyup->tag-list-input-component--tag-list-input#filterInput", "data-tag-list-input-component--tag-list-input-target": "newTag", **aria_label_option
|
||||
= text_field_tag "variant_add_tag", nil, class: "input", placeholder: placeholder, "data-action": "keydown.enter->tag-list-input#addTag keyup->tag-list-input#filterInput blur->tag-list-input#addTag", "data-tag-list-input-target": "newTag", **aria_label_option, style: "display: #{display};"
|
||||
|
||||
@@ -2,17 +2,18 @@ import { Controller } from "stimulus";
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["tagList", "newTag", "template", "list"];
|
||||
static values = { onlyOne: Boolean };
|
||||
|
||||
addTag(event) {
|
||||
// prevent hotkey form submitting the form (default action for "enter" key)
|
||||
event.preventDefault();
|
||||
|
||||
// Check if tag already exist
|
||||
const newTagName = this.newTagTarget.value.trim();
|
||||
const newTagName = this.newTagTarget.value.trim().replaceAll(" ", "-");
|
||||
if (newTagName.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if tag already exist
|
||||
const tags = this.tagListTarget.value.split(",");
|
||||
const index = tags.indexOf(newTagName);
|
||||
if (index != -1) {
|
||||
@@ -22,7 +23,13 @@ export default class extends Controller {
|
||||
}
|
||||
|
||||
// add to tagList
|
||||
this.tagListTarget.value = this.tagListTarget.value.concat(`,${newTagName}`);
|
||||
if (this.tagListTarget.value == "") {
|
||||
this.tagListTarget.value = newTagName;
|
||||
} else {
|
||||
this.tagListTarget.value = this.tagListTarget.value.concat(`,${newTagName}`);
|
||||
}
|
||||
// manualy dispatch an Input event so the change can get picked up by other controllers
|
||||
this.tagListTarget.dispatchEvent(new InputEvent("input"));
|
||||
|
||||
// Create new li component with value
|
||||
const newTagElement = this.templateTarget.content.cloneNode(true);
|
||||
@@ -32,6 +39,11 @@ export default class extends Controller {
|
||||
|
||||
// Clear new tag value
|
||||
this.newTagTarget.value = "";
|
||||
|
||||
// hide tag input if limited to one tag
|
||||
if (this.tagListTarget.value.split(",").length == 1 && this.onlyOneValue == true) {
|
||||
this.newTagTarget.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
removeTag(event) {
|
||||
@@ -40,13 +52,18 @@ export default class extends Controller {
|
||||
|
||||
// Remove tag from list
|
||||
const tags = this.tagListTarget.value.split(",");
|
||||
this.tagListTarget.value = tags.filter(tag => tag != tagName).join(",");
|
||||
this.tagListTarget.value = tags.filter((tag) => tag != tagName).join(",");
|
||||
|
||||
// manualy dispatch an Input event so the change gets picked up by the bulk form controller
|
||||
this.tagListTarget.dispatchEvent(new InputEvent("input"));
|
||||
|
||||
// Remove HTML element from the list
|
||||
event.srcElement.parentElement.parentElement.remove();
|
||||
|
||||
// Make sure the tag input is displayed
|
||||
if (this.tagListTarget.value.length == 0) {
|
||||
this.newTagTarget.style.display = "block";
|
||||
}
|
||||
}
|
||||
|
||||
filterInput(event) {
|
||||
|
||||
59
app/components/tag_rule_form_component.rb
Normal file
59
app/components/tag_rule_form_component.rb
Normal file
@@ -0,0 +1,59 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class TagRuleFormComponent < ViewComponent::Base
|
||||
def initialize(rule:, index:, customer_tags: "",
|
||||
hidden_field_customer_tag_options: {})
|
||||
@rule = rule
|
||||
@index = index
|
||||
@customer_tags = customer_tags
|
||||
@hidden_field_customer_tag_options = hidden_field_customer_tag_options
|
||||
end
|
||||
|
||||
attr_reader :rule, :index, :customer_tags, :hidden_field_customer_tag_options
|
||||
|
||||
private
|
||||
|
||||
def element_name(name)
|
||||
"enterprise[tag_rules_attributes][#{index}][#{name}]"
|
||||
end
|
||||
|
||||
def rule_data # rubocop:disable Metrics/MethodLength
|
||||
case rule.type
|
||||
when "TagRule::FilterShippingMethods"
|
||||
{
|
||||
text_top: t('components.tag_rule_form.tag_rules.shipping_method_tagged_top'),
|
||||
text_bottom: t('components.tag_rule_form.tag_rules.shipping_method_tagged_bottom'),
|
||||
taggable: "shipping_method",
|
||||
visibility_field: "preferred_matched_shipping_methods_visibility",
|
||||
}
|
||||
when "TagRule::FilterPaymentMethods"
|
||||
{
|
||||
text_top: t('components.tag_rule_form.tag_rules.payment_method_tagged_top'),
|
||||
text_bottom: t('components.tag_rule_form.tag_rules.payment_method_tagged_bottom'),
|
||||
taggable: "payment_method",
|
||||
visibility_field: "preferred_matched_payment_methods_visibility",
|
||||
}
|
||||
when "TagRule::FilterOrderCycles"
|
||||
{
|
||||
text_top: t('components.tag_rule_form.tag_rules.order_cycle_tagged_top'),
|
||||
text_bottom: t('components.tag_rule_form.tag_rules.order_cycle_tagged_bottom'),
|
||||
taggable: "exchange",
|
||||
visibility_field: "preferred_matched_order_cycles_visibility",
|
||||
}
|
||||
when "TagRule::FilterProducts"
|
||||
{
|
||||
text_top: t('components.tag_rule_form.tag_rules.inventory_tagged_top'),
|
||||
text_bottom: t('components.tag_rule_form.tag_rules.inventory_tagged_bottom'),
|
||||
taggable: "variant",
|
||||
visibility_field: "preferred_matched_variants_visibility",
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def visibility_options
|
||||
[
|
||||
[t('components.tag_rule_form.tag_rules.visible'), "visible"],
|
||||
[t('components.tag_rule_form.tag_rules.not_visible'), "hidden"]
|
||||
]
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,35 @@
|
||||
%div{ id: "tr_#{index}" }
|
||||
%table
|
||||
%colgroup
|
||||
%col.text{ width: "35%" }
|
||||
%col.inputs{ width: "55%" }
|
||||
%col.actions{ width: "10%" }
|
||||
%tr
|
||||
%td
|
||||
= hidden_field_tag element_name("id"), rule.id
|
||||
= hidden_field_tag element_name("type"), rule.type
|
||||
= hidden_field_tag element_name("priority"), index
|
||||
= hidden_field_tag element_name("is_default"), rule.is_default
|
||||
= hidden_field_tag element_name("preferred_customer_tags"), customer_tags, hidden_field_customer_tag_options
|
||||
%span.text-normal
|
||||
= rule_data[:text_top]
|
||||
%td
|
||||
= render TagListInputComponent.new(name: element_name("preferred_#{rule_data[:taggable]}_tags"), tags: rule.tags.split(","), only_one: true)
|
||||
%td.actions{ rowspan: 2 , "data-controller": "delete-tag-rule", "data-delete-tag-rule-index-value": index }
|
||||
- if rule.new_record?
|
||||
= link_to("", "#", { "data-action": "click->delete-tag-rule#delete" ,class: "delete-tag-rule icon-trash no-text"})
|
||||
- else
|
||||
= link_to("", "#{admin_enterprise_tag_rule_url(rule.enterprise_id, rule.id)}?index=#{index}", { "data-turbo-method": "delete", "data-turbo-confirm": t("admin.tag_rules.confirm_delete"), class: "delete-tag-rule icon-trash no-text" })
|
||||
%tr
|
||||
%td
|
||||
%span.text-normal
|
||||
= rule_data[:text_bottom]
|
||||
%td
|
||||
%div
|
||||
%div
|
||||
- if rule.is_default
|
||||
= hidden_field_tag "enterprise[tag_rules_attributes][#{index}][#{rule_data[:visibility_field]}]", "hidden"
|
||||
%span.text-normal
|
||||
= t(:not_visible)
|
||||
- else
|
||||
= select_tag "enterprise[tag_rules_attributes][#{index}][#{rule_data[:visibility_field]}]", options_for_select(visibility_options, rule.public_send(rule_data[:visibility_field].to_sym) ), { "data-controller": "tom-select", class: "primary no-search" }
|
||||
26
app/components/tag_rule_group_form_component.rb
Normal file
26
app/components/tag_rule_group_form_component.rb
Normal file
@@ -0,0 +1,26 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class TagRuleGroupFormComponent < ViewComponent::Base
|
||||
def initialize(group:, index:, customer_rule_index:, tag_rule_types:)
|
||||
@group = group
|
||||
@index = index
|
||||
@customer_rule_index = customer_rule_index
|
||||
@tag_rule_types = tag_rule_types
|
||||
end
|
||||
|
||||
attr_reader :group, :index, :customer_rule_index, :tag_rule_types
|
||||
|
||||
private
|
||||
|
||||
def form_id
|
||||
"tg_#{index}"
|
||||
end
|
||||
|
||||
def customer_tag_rule_div_id
|
||||
"new-customer-tag-rule-#{index}"
|
||||
end
|
||||
|
||||
def tag_list_input_name
|
||||
"group[#{index}][preferred_customer_tags]"
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,39 @@
|
||||
%div{ id: form_id, "data-controller": "tag-rule-group-form" }
|
||||
- rule_index = customer_rule_index
|
||||
.customer_tag
|
||||
.header
|
||||
%table
|
||||
%colgroup
|
||||
%col{width: '35%'}
|
||||
%col{width: '65%'}
|
||||
%tr
|
||||
%td
|
||||
%h5
|
||||
= t('components.tag_rule_group_form.for_customers_tagged')
|
||||
%td
|
||||
= render(TagListInputComponent.new(name: tag_list_input_name,
|
||||
tags: group[:tags],
|
||||
only_one: true,
|
||||
hidden_field_data_options: { "data-action": "input->tag-rule-group-form#updatePreferredCustomerTag", "data-tag-rule-group-form-target": "customerTag" }))
|
||||
%div{ id: customer_tag_rule_div_id }
|
||||
- if group[:rules].empty?
|
||||
.no_rules
|
||||
= t('components.tag_rule_group_form.no_rules_yet')
|
||||
- else
|
||||
- group[:rules].each do |rule|
|
||||
- rule_index += 1
|
||||
= render(TagRuleFormComponent.new(rule: rule,
|
||||
index: rule_index,
|
||||
customer_tags: group[:tags],
|
||||
hidden_field_customer_tag_options: { "data-tag-rule-group-form-target": "ruleCustomerTag" }))
|
||||
|
||||
%hr
|
||||
.add_rule.text-center
|
||||
%input.button{ type: 'button', value: t('components.tag_rule_group_form.add_new_rule'), "data-controller": "modal-link", "data-action": "click->modal-link#open", "data-modal-link-target-value": "tag_rule_add_new_rule_#{index}" }
|
||||
|
||||
= render AddTagRuleModalComponent.new(id: "tag_rule_add_new_rule_#{index}",
|
||||
tag_rule_types: tag_rule_types,
|
||||
current_index: (rule_index + 1),
|
||||
div_id: customer_tag_rule_div_id,
|
||||
customer_tag: group[:tags],
|
||||
hidden_field_customer_tag_options: { "data-tag-rule-group-form-target": "ruleCustomerTag" })
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Controller } from "stimulus";
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["customerTag", "ruleCustomerTag"];
|
||||
|
||||
updatePreferredCustomerTag() {
|
||||
const customerTag = this.customerTagTarget.value;
|
||||
|
||||
this.ruleCustomerTagTargets.forEach((element) => (element.value = customerTag));
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module VerticalEllipsisMenu
|
||||
class Component < ViewComponent::Base
|
||||
end
|
||||
end
|
||||
4
app/components/vertical_ellipsis_menu_component.rb
Normal file
4
app/components/vertical_ellipsis_menu_component.rb
Normal file
@@ -0,0 +1,4 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class VerticalEllipsisMenuComponent < ViewComponent::Base
|
||||
end
|
||||
@@ -1,4 +1,4 @@
|
||||
.vertical-ellipsis-menu{ "data-controller": "vertical-ellipsis-menu--component" }
|
||||
%i.fa.fa-ellipsis-v{ "data-action": "click->vertical-ellipsis-menu--component#toggle" }
|
||||
.vertical-ellipsis-menu-content{ "data-vertical-ellipsis-menu--component-target": "content" }
|
||||
.vertical-ellipsis-menu{ "data-controller": "vertical-ellipsis-menu" }
|
||||
%i.fa.fa-ellipsis-v{ "data-action": "click->vertical-ellipsis-menu#toggle" }
|
||||
.vertical-ellipsis-menu-content{ "data-vertical-ellipsis-menu-target": "content" }
|
||||
= content
|
||||
@@ -3,6 +3,7 @@
|
||||
module Admin
|
||||
class BulkLineItemsController < Spree::Admin::BaseController
|
||||
include PaginationData
|
||||
|
||||
# GET /admin/bulk_line_items.json
|
||||
#
|
||||
def index
|
||||
|
||||
@@ -83,6 +83,7 @@ module Admin
|
||||
format.turbo_stream
|
||||
end
|
||||
else
|
||||
load_tag_rule_types
|
||||
respond_with(@object) do |format|
|
||||
format.json {
|
||||
render json: { errors: @object.errors.messages }, status: :unprocessable_entity
|
||||
@@ -147,6 +148,18 @@ module Admin
|
||||
end
|
||||
end
|
||||
|
||||
def new_tag_rule_group
|
||||
load_tag_rule_types
|
||||
|
||||
@index = params[:index]
|
||||
@customer_rule_index = params[:customer_rule_index].to_i
|
||||
@group = { tags: [], rules: [] }
|
||||
|
||||
respond_to do |format|
|
||||
format.turbo_stream
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def delete_custom_tab
|
||||
@@ -379,16 +392,15 @@ module Admin
|
||||
end
|
||||
|
||||
def load_tag_rule_types
|
||||
# Load rule types
|
||||
@tag_rule_types = [
|
||||
{ id: "FilterShippingMethods", name: t('js.tag_rules.show_hide_shipping') },
|
||||
{ id: "FilterPaymentMethods", name: t('js.tag_rules.show_hide_payment') },
|
||||
{ id: "FilterOrderCycles", name: t('js.tag_rules.show_hide_order_cycles') }
|
||||
[t(".form.tag_rules.show_hide_shipping"), "FilterShippingMethods"],
|
||||
[t(".form.tag_rules.show_hide_payment"), "FilterPaymentMethods"],
|
||||
[t(".form.tag_rules.show_hide_order_cycles"), "FilterOrderCycles"]
|
||||
]
|
||||
|
||||
return unless helpers.feature?(:inventory, @object)
|
||||
|
||||
@tag_rule_types.prepend({ id: "FilterProducts", name: t('js.tag_rules.show_hide_variants') })
|
||||
@tag_rule_types.prepend([t(".form.tag_rules.show_hide_variants"), "FilterProducts"])
|
||||
end
|
||||
|
||||
def setup_property
|
||||
|
||||
@@ -49,7 +49,7 @@ module Admin
|
||||
errors: @importer.errors.full_messages
|
||||
}
|
||||
|
||||
if helpers.feature?(:inventory, spree_current_user.enterprises)
|
||||
if helpers.feature?(:inventory, *spree_current_user.enterprises)
|
||||
json[:results][:inventory_created] = @importer.inventory_created_count
|
||||
json[:results][:inventory_updated] = @importer.inventory_updated_count
|
||||
end
|
||||
@@ -175,7 +175,7 @@ module Admin
|
||||
|
||||
# Return an error if trying to import into inventories when inventory is disable
|
||||
def can_import_into_inventories?
|
||||
return true if helpers.feature?(:inventory, spree_current_user.enterprises) ||
|
||||
return true if helpers.feature?(:inventory, *spree_current_user.enterprises) ||
|
||||
params.dig(:settings, "import_into") != 'inventories'
|
||||
|
||||
redirect_to admin_product_import_url, notice: I18n.t(:product_import_inventory_disable)
|
||||
|
||||
@@ -123,6 +123,13 @@ module Admin
|
||||
@page = params[:page].presence || 1
|
||||
@per_page = params[:per_page].presence || 15
|
||||
@q = params.permit(q: {})[:q] || { s: 'name asc' }
|
||||
|
||||
# Transform on_hand sorting to include backorderable_priority (on-demand) for proper ordering
|
||||
if @q[:s] == 'on_hand asc'
|
||||
@q[:s] = ['backorderable_priority asc', @q[:s]]
|
||||
elsif @q[:s] == 'on_hand desc'
|
||||
@q[:s] = ['backorderable_priority desc', @q[:s]]
|
||||
end
|
||||
end
|
||||
|
||||
def producers
|
||||
@@ -155,8 +162,27 @@ module Admin
|
||||
product_query = OpenFoodNetwork::Permissions.new(spree_current_user)
|
||||
.editable_products.merge(product_scope_with_includes).ransack(ransack_query).result
|
||||
|
||||
@pagy, @products = pagy(product_query.order(:name), limit: @per_page, page: @page,
|
||||
size: [1, 2, 2, 1])
|
||||
# Postgres requires ORDER BY expressions to appear in the SELECT list when using DISTINCT.
|
||||
# When the current ransack sort uses the computed stock columns, include them in the select
|
||||
# so the generated COUNT/DISTINCT query is valid.
|
||||
sort_columns = Array(@q && @q[:s]).flatten
|
||||
if sort_columns.any? { |s|
|
||||
s.to_s.include?('on_hand') || s.to_s.include?('backorderable_priority')
|
||||
}
|
||||
|
||||
product_query = product_query.select(
|
||||
Arel.sql('spree_products.*'),
|
||||
Spree::Product.backorderable_priority_sql,
|
||||
Spree::Product.on_hand_sql
|
||||
)
|
||||
end
|
||||
|
||||
@pagy, @products = pagy(
|
||||
product_query.order(:name),
|
||||
limit: @per_page,
|
||||
page: @page,
|
||||
size: [1, 2, 2, 1]
|
||||
)
|
||||
end
|
||||
|
||||
def product_scope
|
||||
|
||||
@@ -4,6 +4,7 @@ module Admin
|
||||
class ReportsController < Spree::Admin::BaseController
|
||||
include ActiveStorage::SetCurrent
|
||||
include ReportsActions
|
||||
|
||||
helper ReportsHelper
|
||||
|
||||
before_action :authorize_report, only: [:show, :create]
|
||||
@@ -22,14 +23,12 @@ module Admin
|
||||
def show
|
||||
@report = report_class.new(spree_current_user, params, render: false)
|
||||
@rendering_options = rendering_options
|
||||
|
||||
show_report
|
||||
end
|
||||
|
||||
def create
|
||||
@report = report_class.new(spree_current_user, params, render: true)
|
||||
update_rendering_options
|
||||
|
||||
render_in_background
|
||||
end
|
||||
|
||||
@@ -61,7 +60,9 @@ module Admin
|
||||
@blob = ReportBlob.create_for_upload_later!(report_filename)
|
||||
|
||||
ReportJob.perform_later(
|
||||
report_class:, user: spree_current_user, params:,
|
||||
report_class:,
|
||||
user: spree_current_user,
|
||||
params:,
|
||||
format: report_format,
|
||||
blob: @blob,
|
||||
channel: ScopedChannel.for_id(params[:uuid]),
|
||||
|
||||
@@ -1,12 +1,45 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class TagRulesController < Admin::ResourceController
|
||||
class TagRulesController < Spree::Admin::BaseController
|
||||
respond_to :json
|
||||
|
||||
respond_override destroy: { json: {
|
||||
success: lambda { head :no_content }
|
||||
} }
|
||||
def new
|
||||
@index = params[:index]
|
||||
@div_id = params[:div_id]
|
||||
is_default = params[:is_default]
|
||||
@customer_tags = params[:customer_tags]
|
||||
|
||||
status = :ok
|
||||
if permitted_tag_rule_type.include?(params[:rule_type])
|
||||
@default_rule = "TagRule::#{params[:rule_type]}".constantize.new(is_default:)
|
||||
else
|
||||
flash.now[:error] = t(".not_supported_type")
|
||||
status = :internal_server_error
|
||||
end
|
||||
|
||||
respond_with do |format|
|
||||
format.turbo_stream { render :new, status: }
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@rule = TagRule.find(params[:id])
|
||||
@index = params[:index]
|
||||
authorize! :destroy, @rule
|
||||
|
||||
status = :ok
|
||||
if @rule.destroy
|
||||
flash[:success] = Spree.t(:successfully_removed, resource: "Tag Rule")
|
||||
else
|
||||
flash.now[:error] = t(".destroy_error")
|
||||
status = :internal_server_error
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.turbo_stream { render :destroy, status: }
|
||||
end
|
||||
end
|
||||
|
||||
def map_by_tag
|
||||
respond_to do |format|
|
||||
@@ -39,5 +72,13 @@ module Admin
|
||||
Enterprise.managed_by(spree_current_user)
|
||||
end
|
||||
end
|
||||
|
||||
def model_class
|
||||
TagRule
|
||||
end
|
||||
|
||||
def permitted_tag_rule_type
|
||||
%w{FilterOrderCycles FilterPaymentMethods FilterProducts FilterShippingMethods}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,6 +7,7 @@ module Api
|
||||
module V0
|
||||
class ExchangeProductsController < Api::V0::BaseController
|
||||
include PaginationData
|
||||
|
||||
DEFAULT_PER_PAGE = 100
|
||||
|
||||
skip_authorization_check only: [:index]
|
||||
|
||||
@@ -7,6 +7,7 @@ module Api
|
||||
module V0
|
||||
class ProductsController < Api::V0::BaseController
|
||||
include PaginationData
|
||||
|
||||
respond_to :json
|
||||
DEFAULT_PER_PAGE = 15
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ module ReportsActions
|
||||
else
|
||||
params[:fields_to_show]
|
||||
end,
|
||||
display_metadata_rows: false,
|
||||
display_summary_row: request.get?,
|
||||
display_header_row: false
|
||||
}
|
||||
@@ -94,6 +95,7 @@ module ReportsActions
|
||||
rendering_options.update(
|
||||
options: {
|
||||
fields_to_show: params[:fields_to_show],
|
||||
display_metadata_rows: params[:display_metadata_rows].present?,
|
||||
display_summary_row: params[:display_summary_row].present?,
|
||||
display_header_row: params[:display_header_row].present?
|
||||
}
|
||||
|
||||
@@ -9,11 +9,7 @@ class PaymentsController < BaseController
|
||||
@payment = Spree::Payment.find(params[:id])
|
||||
authorize! :show, @payment.order
|
||||
|
||||
if (url = @payment.cvv_response_message)
|
||||
redirect_to url
|
||||
else
|
||||
redirect_to order_url(@payment.order)
|
||||
end
|
||||
redirect_to(@payment.redirect_auth_url || order_url(@payment.order))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -6,6 +6,7 @@ module Spree
|
||||
module Admin
|
||||
class OrdersController < Spree::Admin::BaseController
|
||||
include OpenFoodNetwork::SpreeApiKeyLoader
|
||||
|
||||
helper CheckoutHelper
|
||||
|
||||
before_action :load_order, only: [:edit, :update, :fire, :resend, :invoice, :print]
|
||||
|
||||
@@ -10,6 +10,7 @@ module Spree
|
||||
include OpenFoodNetwork::SpreeApiKeyLoader
|
||||
include OrderCyclesHelper
|
||||
include EnterprisesHelper
|
||||
|
||||
helper ::Admin::ProductsHelper
|
||||
helper Spree::Admin::TaxCategoriesHelper
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ module Spree
|
||||
include Spree::Core::ControllerHelpers::Order
|
||||
|
||||
include I18nHelper
|
||||
|
||||
before_action :set_locale
|
||||
|
||||
# Devise::PasswordsController allows for blank passwords.
|
||||
|
||||
13
app/controllers/well_known_controller.rb
Normal file
13
app/controllers/well_known_controller.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class WellKnownController < ApplicationController
|
||||
layout nil
|
||||
|
||||
def dfc
|
||||
base = "https://github.com/datafoodconsortium/taxonomies/releases/latest/download/scopes.rdf#"
|
||||
render json: {
|
||||
"#{base}ReadEnterprise" => "/api/dfc/enterprises/",
|
||||
"#{base}ReadProducts" => "/api/dfc/supplied_products/",
|
||||
}
|
||||
end
|
||||
end
|
||||
@@ -36,9 +36,7 @@ class ScheduleForm
|
||||
false unless @schedule.update(permitted_resource_params)
|
||||
end
|
||||
|
||||
def order_cycle_ids
|
||||
@schedule.order_cycle_ids
|
||||
end
|
||||
delegate :order_cycle_ids, to: :@schedule
|
||||
|
||||
private
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
module EnterprisesHelper
|
||||
module EnterprisesHelper # rubocop:disable Metrics/ModuleLength
|
||||
def add_check_if_single(count)
|
||||
if count == 1
|
||||
{ checked: true }
|
||||
@@ -28,7 +28,7 @@ module Admin
|
||||
show_connected_apps = can?(:manage_connected_apps, enterprise) &&
|
||||
(connected_apps_enabled(enterprise).present? ||
|
||||
dfc_platforms_available?)
|
||||
show_inventory_settings = feature?(:inventory, spree_current_user.enterprises) && is_shop
|
||||
show_inventory_settings = feature?(:inventory, *spree_current_user.enterprises) && is_shop
|
||||
|
||||
show_options = {
|
||||
show_properties:,
|
||||
@@ -50,7 +50,7 @@ module Admin
|
||||
end
|
||||
|
||||
def dfc_platforms_available?
|
||||
DfcProvider::PlatformsController::PLATFORM_IDS.keys.any? do |id|
|
||||
ApiUser::PLATFORMS.keys.any? do |id|
|
||||
feature?(id, spree_current_user)
|
||||
end
|
||||
end
|
||||
@@ -71,8 +71,35 @@ module Admin
|
||||
"#{enterprise_attachment_removal_panel}_panel"
|
||||
end
|
||||
|
||||
def enterprise_sells_options
|
||||
scope = "admin.enterprises.admin_index.sells_options"
|
||||
Enterprise::SELLS.map { |s| [I18n.t(s, scope:), s] }
|
||||
end
|
||||
|
||||
# Group tag rules per rule.preferred_customer_tags
|
||||
def tag_groups(tag_rules)
|
||||
tag_rules.each_with_object([]) do |tag_rule, tag_groups|
|
||||
tag_group = find_match(tag_groups, tag_rule.preferred_customer_tags.split(","))
|
||||
|
||||
if tag_group[:rules].blank?
|
||||
tag_groups << tag_group
|
||||
tag_group[:position] = tag_groups.count
|
||||
end
|
||||
|
||||
tag_group[:rules] << tag_rule
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_match(tag_groups, tags)
|
||||
tag_groups.each do |tag_group|
|
||||
return tag_group if tag_group[:tags].length == tags.length &&
|
||||
(tag_group[:tags] & tags) == tag_group[:tags]
|
||||
end
|
||||
{ tags:, rules: [] }
|
||||
end
|
||||
|
||||
def build_enterprise_side_menu_items(is_shop:, show_options: ) # rubocop:disable Metrics/MethodLength
|
||||
[
|
||||
{ name: 'primary_details', icon_class: "icon-home", show: true, selected: 'selected' },
|
||||
|
||||
@@ -120,7 +120,7 @@ module InjectionHelper
|
||||
|
||||
def inject_enterprise_attributes(enterprise_attributes)
|
||||
render partial: "json/injection_ams",
|
||||
locals: { name: 'enterpriseAttributes', json: enterprise_attributes.to_json.to_s }
|
||||
locals: { name: 'enterpriseAttributes', json: enterprise_attributes.to_json }
|
||||
end
|
||||
|
||||
def inject_saved_credit_cards
|
||||
|
||||
@@ -1,6 +1,29 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module LinkHelper
|
||||
def link_to_or_disabled(name = nil, options = nil, html_options = nil, &block)
|
||||
html_options, options, name = options, name, block if block_given?
|
||||
html_options ||= {}
|
||||
|
||||
if !!html_options.delete(:disabled)
|
||||
# https://www.scottohara.me/blog/2021/05/28/disabled-links.html
|
||||
html_options.merge!(
|
||||
'aria-disabled': true,
|
||||
class: (html_options[:class].to_s.split + ["disabled"]).uniq.join(" "),
|
||||
role: "link"
|
||||
)
|
||||
if block_given?
|
||||
content_tag("a", name, **html_options, &block)
|
||||
else
|
||||
content_tag("a", name, **html_options)
|
||||
end
|
||||
elsif block_given?
|
||||
link_to options, html_options, &block
|
||||
else
|
||||
link_to name, options, html_options
|
||||
end
|
||||
end
|
||||
|
||||
def link_to_service(baseurl, name, html_options = {}, &)
|
||||
return if name.blank?
|
||||
|
||||
|
||||
@@ -44,9 +44,7 @@ module ReportsHelper
|
||||
.pluck(:name, :id)
|
||||
end
|
||||
|
||||
def currency_symbol
|
||||
Spree::Money.currency_symbol
|
||||
end
|
||||
delegate :currency_symbol, to: :'Spree::Money'
|
||||
|
||||
def enterprise_fee_owner_ids(orders)
|
||||
EnterpriseFee.where(id: enterprise_fee_ids(orders))
|
||||
|
||||
@@ -62,6 +62,12 @@ module ShopHelper
|
||||
true
|
||||
end
|
||||
|
||||
def shop_tab_class(tab)
|
||||
return unless (tab == "home" && show_home_tab?) || current_order(false)&.order_cycle.nil?
|
||||
|
||||
"with-darker-background"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def show_groups_tabs?
|
||||
|
||||
@@ -10,9 +10,7 @@ module TermsAndConditionsHelper
|
||||
TermsOfService.required?(distributor)
|
||||
end
|
||||
|
||||
def platform_terms_required?
|
||||
TermsOfService.platform_terms_required?
|
||||
end
|
||||
delegate :platform_terms_required?, to: :TermsOfService
|
||||
|
||||
def distributor_terms_required?
|
||||
TermsOfService.distributor_terms_required?(current_order.distributor)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
class BulkInvoiceJob < ApplicationJob
|
||||
include CableReady::Broadcaster
|
||||
|
||||
delegate :render, to: ActionController::Base
|
||||
attr_reader :options
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# Renders a report and stores it in a given blob.
|
||||
class ReportJob < ApplicationJob
|
||||
include CableReady::Broadcaster
|
||||
|
||||
delegate :render, to: ActionController::Base
|
||||
|
||||
before_perform :enable_active_storage_urls
|
||||
|
||||
@@ -9,6 +9,7 @@ class ApplicationRecord < ActiveRecord::Base
|
||||
include ArelHelpers::JoinAssociation
|
||||
|
||||
self.abstract_class = true
|
||||
self.include_root_in_json = true
|
||||
|
||||
def self.image_service
|
||||
ENV["S3_BUCKET"].present? ? :amazon_public : :local
|
||||
|
||||
@@ -4,6 +4,7 @@ require 'active_support/concern'
|
||||
|
||||
module LogDestroyPerformer
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
attr_accessor :destroyed_by
|
||||
|
||||
|
||||
35
app/models/concerns/product_sort_by_stocks.rb
Normal file
35
app/models/concerns/product_sort_by_stocks.rb
Normal file
@@ -0,0 +1,35 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module ProductSortByStocks
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
@on_hand_sql = Arel.sql("(
|
||||
SELECT COALESCE(SUM(si.count_on_hand), 0)
|
||||
FROM spree_variants v
|
||||
JOIN spree_stock_items si ON si.variant_id = v.id
|
||||
WHERE v.product_id = spree_products.id
|
||||
GROUP BY v.product_id
|
||||
)")
|
||||
|
||||
@backorderable_priority_sql = Arel.sql("(
|
||||
SELECT BOOL_OR(si.backorderable)
|
||||
FROM spree_variants v
|
||||
JOIN spree_stock_items si ON si.variant_id = v.id
|
||||
WHERE v.product_id = spree_products.id
|
||||
GROUP BY v.product_id
|
||||
)")
|
||||
|
||||
class << self
|
||||
attr_reader :on_hand_sql, :backorderable_priority_sql
|
||||
end
|
||||
|
||||
ransacker :on_hand do
|
||||
@on_hand_sql
|
||||
end
|
||||
|
||||
ransacker :backorderable_priority do
|
||||
@backorderable_priority_sql
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -75,6 +75,7 @@ class Enterprise < ApplicationRecord
|
||||
has_one :stripe_account, dependent: :destroy
|
||||
has_many :vouchers, dependent: :restrict_with_exception
|
||||
has_many :connected_apps, dependent: :destroy
|
||||
has_many :dfc_permissions, dependent: :destroy
|
||||
has_one :custom_tab, dependent: :destroy
|
||||
|
||||
delegate :latitude, :longitude, :city, :state_name, to: :address
|
||||
@@ -407,7 +408,7 @@ class Enterprise < ApplicationRecord
|
||||
def category
|
||||
# Make this crazy logic human readable so we can argue about it sanely.
|
||||
cat = is_primary_producer ? "producer_" : "non_producer_"
|
||||
cat << ("sells_#{sells}")
|
||||
cat << "sells_#{sells}"
|
||||
|
||||
# Map backend cases to front end cases.
|
||||
case cat
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
class Invoice
|
||||
class DataPresenter
|
||||
include ::ActionView::Helpers::NumberHelper
|
||||
|
||||
attr_reader :invoice
|
||||
|
||||
delegate :display_number, :data, :previous_invoice, to: :invoice
|
||||
@@ -142,7 +143,7 @@ class Invoice
|
||||
end
|
||||
|
||||
def paid?
|
||||
data[:payment_state] == 'paid' || data[:payment_state] == 'credit_owed'
|
||||
['paid', 'credit_owed'].include?(data[:payment_state])
|
||||
end
|
||||
|
||||
def outstanding_balance?
|
||||
|
||||
@@ -4,6 +4,7 @@ class Invoice
|
||||
class DataPresenter
|
||||
class Base
|
||||
include ::ActionView::Helpers::NumberHelper
|
||||
|
||||
attr_reader :data
|
||||
|
||||
def initialize(data)
|
||||
|
||||
@@ -81,17 +81,13 @@ module ProductImport
|
||||
@reset_counts
|
||||
end
|
||||
|
||||
def enterprises_index
|
||||
@spreadsheet_data.enterprises_index
|
||||
end
|
||||
delegate :enterprises_index, to: :@spreadsheet_data
|
||||
|
||||
def enterprise_products
|
||||
@processor&.enterprise_products
|
||||
end
|
||||
|
||||
def total_enterprise_products
|
||||
@processor.total_enterprise_products
|
||||
end
|
||||
delegate :total_enterprise_products, to: :@processor
|
||||
|
||||
def entries_json
|
||||
entries = {}
|
||||
@@ -130,13 +126,9 @@ module ProductImport
|
||||
@processor.inventory_updated
|
||||
end
|
||||
|
||||
def products_reset_count
|
||||
@processor.products_reset_count
|
||||
end
|
||||
delegate :products_reset_count, to: :@processor
|
||||
|
||||
def total_saved_count
|
||||
@processor.total_saved_count
|
||||
end
|
||||
delegate :total_saved_count, to: :@processor
|
||||
|
||||
def import_results
|
||||
{ entries: entries_json, reset_counts: }
|
||||
@@ -183,7 +175,7 @@ module ProductImport
|
||||
end
|
||||
|
||||
def staged_import?
|
||||
@import_settings&.key?(:start) && @import_settings&.key?(:end)
|
||||
@import_settings&.key?(:start) && @import_settings.key?(:end)
|
||||
end
|
||||
|
||||
def init_permissions
|
||||
@@ -193,7 +185,7 @@ module ProductImport
|
||||
order('is_primary_producer ASC, name').
|
||||
map { |e| @editable_enterprises[e.name] = e.id }
|
||||
|
||||
return unless OpenFoodNetwork::FeatureToggle.enabled?(:inventory, @current_user.enterprises)
|
||||
return unless OpenFoodNetwork::FeatureToggle.enabled?(:inventory, *@current_user.enterprises)
|
||||
|
||||
@inventory_permissions = permissions.variant_override_enterprises_per_hub
|
||||
end
|
||||
|
||||
@@ -142,6 +142,7 @@ module Spree
|
||||
|
||||
can [:admin, :index, :read, :create, :edit, :update_positions, :destroy], ProducerProperty
|
||||
|
||||
can :new, TagRule
|
||||
can [:admin, :map_by_tag, :destroy], TagRule do |tag_rule|
|
||||
user.enterprises.include? tag_rule.enterprise
|
||||
end
|
||||
@@ -149,7 +150,7 @@ module Spree
|
||||
can [:admin, :index, :create], Enterprise
|
||||
can [:read, :edit, :update,
|
||||
:remove_logo, :remove_promo_image, :remove_terms_and_conditions,
|
||||
:bulk_update, :resend_confirmation], Enterprise do |enterprise|
|
||||
:bulk_update, :resend_confirmation, :new_tag_rule_group], Enterprise do |enterprise|
|
||||
OpenFoodNetwork::Permissions.new(user).editable_enterprises.include? enterprise
|
||||
end
|
||||
can [:welcome, :register], Enterprise do |enterprise|
|
||||
@@ -213,7 +214,7 @@ module Spree
|
||||
managed_product_enterprises.include? variant.supplier
|
||||
end
|
||||
|
||||
if OpenFoodNetwork::FeatureToggle.enabled?(:inventory, user.enterprises)
|
||||
if OpenFoodNetwork::FeatureToggle.enabled?(:inventory, *user.enterprises)
|
||||
can [:admin, :index, :read, :update, :bulk_update, :bulk_reset], VariantOverride do |vo|
|
||||
next false unless vo.hub.present? && vo.variant&.supplier.present?
|
||||
|
||||
|
||||
@@ -31,9 +31,7 @@ module Spree
|
||||
self.class.name.titleize.gsub("Calculator/", "")
|
||||
end
|
||||
|
||||
def description
|
||||
self.class.description
|
||||
end
|
||||
delegate :description, to: :class
|
||||
|
||||
def available?(_object)
|
||||
true
|
||||
|
||||
@@ -97,7 +97,7 @@ module Spree
|
||||
}
|
||||
validate :disallow_guest_order
|
||||
validates :email, presence: true,
|
||||
format: /\A([\w.%+\-']+)@([\w\-]+\.)+(\w{2,})\z/i,
|
||||
format: /\A([\w.%+\-']+)@([\w-]+\.)+(\w{2,})\z/i,
|
||||
if: :require_email
|
||||
|
||||
validates :order_cycle, presence: true, on: :require_distribution
|
||||
@@ -417,7 +417,7 @@ module Spree
|
||||
|
||||
# Helper methods for checkout steps
|
||||
def paid?
|
||||
payment_state == 'paid' || payment_state == 'credit_owed'
|
||||
['paid', 'credit_owed'].include?(payment_state)
|
||||
end
|
||||
|
||||
# "Checkout" is the initial state and, for card payments, "pending" is the state after auth
|
||||
|
||||
@@ -57,7 +57,7 @@ module Spree
|
||||
scope :failed, -> { with_state('failed') }
|
||||
scope :valid, -> { where.not(state: %w(failed invalid)) }
|
||||
scope :void, -> { with_state('void') }
|
||||
scope :authorization_action_required, -> { where.not(cvv_response_message: nil) }
|
||||
scope :authorization_action_required, -> { where.not(redirect_auth_url: nil) }
|
||||
scope :requires_authorization, -> { with_state("requires_authorization") }
|
||||
scope :with_payment_intent, ->(code) { where(response_code: code) }
|
||||
|
||||
@@ -164,7 +164,7 @@ module Spree
|
||||
end
|
||||
|
||||
def clear_authorization_url
|
||||
update_attribute(:cvv_response_message, nil)
|
||||
update_attribute(:redirect_auth_url, nil)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -241,7 +241,8 @@ module Spree
|
||||
if response.cvv_result
|
||||
self.cvv_response_code = response.cvv_result['code']
|
||||
self.cvv_response_message = response.cvv_result['message']
|
||||
if cvv_response_message.present?
|
||||
self.redirect_auth_url = response.cvv_result['redirect_auth_url']
|
||||
if redirect_auth_url.present?
|
||||
return require_authorization!
|
||||
end
|
||||
end
|
||||
|
||||
@@ -19,6 +19,7 @@ require 'open_food_network/property_merge'
|
||||
module Spree
|
||||
class Product < ApplicationRecord
|
||||
include LogDestroyPerformer
|
||||
include ProductSortByStocks
|
||||
|
||||
self.belongs_to_required_by_default = false
|
||||
# These columns have been moved to variant. Currently this is only for documentation purposes,
|
||||
@@ -30,7 +31,7 @@ module Spree
|
||||
|
||||
acts_as_paranoid
|
||||
|
||||
searchable_attributes :meta_keywords, :sku
|
||||
searchable_attributes :meta_keywords, :sku, :on_hand, :backorderable_priority
|
||||
searchable_associations :properties, :variants
|
||||
searchable_scopes :active, :with_properties
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
module Spree
|
||||
class ShippingMethod < ApplicationRecord
|
||||
include CalculatedAdjustments
|
||||
|
||||
DISPLAY_ON_OPTIONS = {
|
||||
both: "",
|
||||
back_end: "back_end"
|
||||
|
||||
@@ -19,4 +19,9 @@ class TagRule < ApplicationRecord
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# The following method must be overriden in a concrete tagRule
|
||||
def tags
|
||||
raise NotImplementedError, 'please use concrete TagRule'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,6 +14,10 @@ class TagRule::FilterOrderCycles < TagRule
|
||||
preferred_matched_order_cycles_visibility != "visible"
|
||||
end
|
||||
|
||||
def tags
|
||||
preferred_exchange_tags
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def exchange_for(order_cycle)
|
||||
|
||||
@@ -13,4 +13,8 @@ class TagRule::FilterPaymentMethods < TagRule
|
||||
def reject_matched?
|
||||
preferred_matched_payment_methods_visibility != "visible"
|
||||
end
|
||||
|
||||
def tags
|
||||
preferred_payment_method_tags
|
||||
end
|
||||
end
|
||||
|
||||
@@ -18,5 +18,9 @@ class TagRule
|
||||
def reject_matched?
|
||||
preferred_matched_variants_visibility != "visible"
|
||||
end
|
||||
|
||||
def tags
|
||||
preferred_variant_tags
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,4 +13,8 @@ class TagRule::FilterShippingMethods < TagRule
|
||||
preferred_tags = preferred_shipping_method_tags.split(",")
|
||||
shipping_method_tags.intersect?(preferred_tags)
|
||||
end
|
||||
|
||||
def tags
|
||||
preferred_shipping_method_tags
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,8 +10,8 @@ module Api
|
||||
:preferred_shopfront_taxon_order, :preferred_shopfront_producer_order,
|
||||
:preferred_shopfront_order_cycle_order, :show_customer_names_to_suppliers,
|
||||
:show_customer_contacts_to_suppliers,
|
||||
:preferred_shopfront_product_sorting_method, :owner, :contact, :users, :tag_groups,
|
||||
:default_tag_group, :require_login, :allow_guest_orders, :allow_order_changes,
|
||||
:preferred_shopfront_product_sorting_method, :owner, :contact, :users,
|
||||
:require_login, :allow_guest_orders, :allow_order_changes,
|
||||
:logo, :promo_image, :terms_and_conditions,
|
||||
:terms_and_conditions_file_name, :terms_and_conditions_updated_at,
|
||||
:preferred_invoice_order_by_supplier, :preferred_product_low_stock_display,
|
||||
@@ -50,41 +50,8 @@ module Api
|
||||
object.terms_and_conditions_blob&.created_at&.to_s
|
||||
end
|
||||
|
||||
def tag_groups
|
||||
prioritized_tag_rules.each_with_object([]) do |tag_rule, tag_groups|
|
||||
tag_group = find_match(tag_groups, tag_rule.preferred_customer_tags.
|
||||
split(",").
|
||||
map{ |t| { text: t } })
|
||||
if tag_group[:rules].blank?
|
||||
tag_groups << tag_group
|
||||
tag_group[:position] = tag_groups.count
|
||||
end
|
||||
tag_group[:rules] << Api::Admin::TagRuleSerializer.new(tag_rule).serializable_hash
|
||||
end
|
||||
end
|
||||
|
||||
def default_tag_group
|
||||
default_rules = object.tag_rules.select(&:is_default)
|
||||
serialized_rules =
|
||||
ActiveModel::ArraySerializer.new(default_rules,
|
||||
each_serializer: Api::Admin::TagRuleSerializer)
|
||||
{ tags: [], rules: serialized_rules }
|
||||
end
|
||||
|
||||
def find_match(tag_groups, tags)
|
||||
tag_groups.each do |tag_group|
|
||||
return tag_group if tag_group[:tags].length == tags.length &&
|
||||
(tag_group[:tags] & tags) == tag_group[:tags]
|
||||
end
|
||||
{ tags:, rules: [] }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def prioritized_tag_rules
|
||||
object.tag_rules.prioritised.reject(&:is_default)
|
||||
end
|
||||
|
||||
# Returns a hash of URLs for specified versions of an attachment.
|
||||
#
|
||||
# Example result:
|
||||
|
||||
@@ -8,24 +8,14 @@ module Api
|
||||
:open_street_map_default_latitude,
|
||||
:open_street_map_default_longitude
|
||||
|
||||
def open_street_map_enabled
|
||||
ContentConfig.open_street_map_enabled
|
||||
end
|
||||
delegate :open_street_map_enabled, to: :ContentConfig
|
||||
|
||||
def open_street_map_provider_name
|
||||
ContentConfig.open_street_map_provider_name
|
||||
end
|
||||
delegate :open_street_map_provider_name, to: :ContentConfig
|
||||
|
||||
def open_street_map_provider_options
|
||||
ContentConfig.open_street_map_provider_options
|
||||
end
|
||||
delegate :open_street_map_provider_options, to: :ContentConfig
|
||||
|
||||
def open_street_map_default_latitude
|
||||
ContentConfig.open_street_map_default_latitude
|
||||
end
|
||||
delegate :open_street_map_default_latitude, to: :ContentConfig
|
||||
|
||||
def open_street_map_default_longitude
|
||||
ContentConfig.open_street_map_default_longitude
|
||||
end
|
||||
delegate :open_street_map_default_longitude, to: :ContentConfig
|
||||
end
|
||||
end
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user