From fd67ea216b96fdc374f509f3f8b929285618c4d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B4=D8=B1=D9=83=D8=A9=20=D8=AE=D8=A8=D9=8A=D8=B1=20?= =?UTF-8?q?=D8=A7=D9=84=D9=85=D8=AD=D8=AF=D9=88=D8=AF=D8=A9?= Date: Wed, 26 Nov 2025 14:17:52 +0200 Subject: [PATCH 1/6] Update github action file --- .github/workflows/restrict-pr-authors.yaml | 30 ++++++++++++---------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/.github/workflows/restrict-pr-authors.yaml b/.github/workflows/restrict-pr-authors.yaml index 5a8e9bab5..6f47e2da0 100644 --- a/.github/workflows/restrict-pr-authors.yaml +++ b/.github/workflows/restrict-pr-authors.yaml @@ -82,21 +82,23 @@ jobs: pull_number: pr.number }); - for (const commit of commitList.data) { - const commitAuthor = commit.author ? commit.author.login : null; + core.info("PR author is allowed."); + + # for (const commit of commitList.data) { + # const commitAuthor = commit.author ? commit.author.login : null; - if (commitAuthor && !allowed.includes(commitAuthor)) { - core.error(`Unauthorized commit author: ${commitAuthor}. Closing PR...`); + # if (commitAuthor && !allowed.includes(commitAuthor)) { + # core.error(`Unauthorized commit author: ${commitAuthor}. Closing PR...`); - await github.rest.pulls.update({ - owner, - repo, - pull_number: pr.number, - state: "closed" - }); + # await github.rest.pulls.update({ + # owner, + # repo, + # pull_number: pr.number, + # state: "closed" + # }); - return; - } - } + # return; + # } + # } - core.info("All PR authors and committers are allowed."); + # core.info("All PR authors and committers are allowed."); From 71d0b522b3012cdd3453a5ae4eae47a9095749e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B4=D8=B1=D9=83=D8=A9=20=D8=AE=D8=A8=D9=8A=D8=B1=20?= =?UTF-8?q?=D8=A7=D9=84=D9=85=D8=AD=D8=AF=D9=88=D8=AF=D8=A9?= Date: Wed, 26 Nov 2025 14:18:11 +0200 Subject: [PATCH 2/6] Update github action file --- .github/workflows/block_reserved_branches.yml | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/.github/workflows/block_reserved_branches.yml b/.github/workflows/block_reserved_branches.yml index ba3fc471b..4a73aef74 100644 --- a/.github/workflows/block_reserved_branches.yml +++ b/.github/workflows/block_reserved_branches.yml @@ -23,38 +23,38 @@ jobs: ####################################################### # 🟦 1) Allowed Users List ####################################################### - ALLOWED_USERS=( - "expsa" - "moutazmuhammad" - "ronozoro" - "Abubaker-Altaib" - "altexp" - "the5abir" - "ahmadaking" - "kchyounes19" - "abdurrahman-saber" - "maltayyar2" - "esam-sermah" - "mohammed-alkhazrji" - ) + # ALLOWED_USERS=( + # "expsa" + # "moutazmuhammad" + # "ronozoro" + # "Abubaker-Altaib" + # "altexp" + # "the5abir" + # "ahmadaking" + # "kchyounes19" + # "abdurrahman-saber" + # "maltayyar2" + # "esam-sermah" + # "mohammed-alkhazrji" + # ) - IS_ALLOWED="false" - for user in "${ALLOWED_USERS[@]}"; do - if [[ "$CREATOR" == "$user" ]]; then - IS_ALLOWED="true" - break - fi - done + # IS_ALLOWED="false" + # for user in "${ALLOWED_USERS[@]}"; do + # if [[ "$CREATOR" == "$user" ]]; then + # IS_ALLOWED="true" + # break + # fi + # done - if [[ "$IS_ALLOWED" == "false" ]]; then - echo "❌ User '$CREATOR' is NOT allowed to create branches. Deleting..." - curl -s -X DELETE \ - -H "Authorization: token $GH_TOKEN" \ - https://api.github.com/repos/$REPO/git/refs/heads/$BRANCH_NAME - exit 1 - fi + # if [[ "$IS_ALLOWED" == "false" ]]; then + # echo "❌ User '$CREATOR' is NOT allowed to create branches. Deleting..." + # curl -s -X DELETE \ + # -H "Authorization: token $GH_TOKEN" \ + # https://api.github.com/repos/$REPO/git/refs/heads/$BRANCH_NAME + # exit 1 + # fi - echo "✔ User '$CREATOR' is allowed." + # echo "✔ User '$CREATOR' is allowed." ####################################################### # 🟦 2) Reserved Branch Names (Your Existing List) From e1ade4c77f30a6da9982b592a02b57be22449078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B4=D8=B1=D9=83=D8=A9=20=D8=AE=D8=A8=D9=8A=D8=B1=20?= =?UTF-8?q?=D8=A7=D9=84=D9=85=D8=AD=D8=AF=D9=88=D8=AF=D8=A9?= Date: Wed, 26 Nov 2025 15:33:36 +0200 Subject: [PATCH 3/6] Update github action file --- .github/workflows/restrict-pr-authors.yaml | 49 ++++++++++++---------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/.github/workflows/restrict-pr-authors.yaml b/.github/workflows/restrict-pr-authors.yaml index 6f47e2da0..56f41ab06 100644 --- a/.github/workflows/restrict-pr-authors.yaml +++ b/.github/workflows/restrict-pr-authors.yaml @@ -31,6 +31,7 @@ on: - dev_odex25_helpdesk - dev_odex25_donation - dev_odex25_ensan + jobs: check_pr_author: runs-on: linting_odex25-standard-modules_runner @@ -74,31 +75,35 @@ jobs: }); return; } + core.info("All PR authors are allowed."); - // Check commit authors - const commitList = await github.rest.pulls.listCommits({ - owner, - repo, - pull_number: pr.number - }); +# // Check commit authors +# const commitList = await github.rest.pulls.listCommits({ +# owner, +# repo, +# pull_number: pr.number +# }); - core.info("PR author is allowed."); - - # for (const commit of commitList.data) { - # const commitAuthor = commit.author ? commit.author.login : null; +# core.info("PR author is allowed."); - # if (commitAuthor && !allowed.includes(commitAuthor)) { - # core.error(`Unauthorized commit author: ${commitAuthor}. Closing PR...`); +# // Uncomment below if you want to block unauthorized commit authors also +# /* +# for (const commit of commitList.data) { +# const commitAuthor = commit.author ? commit.author.login : null; - # await github.rest.pulls.update({ - # owner, - # repo, - # pull_number: pr.number, - # state: "closed" - # }); +# if (commitAuthor && !allowed.includes(commitAuthor)) { +# core.error(`Unauthorized commit author: ${commitAuthor}. Closing PR...`); - # return; - # } - # } +# await github.rest.pulls.update({ +# owner, +# repo, +# pull_number: pr.number, +# state: "closed" +# }); - # core.info("All PR authors and committers are allowed."); +# return; +# } +# } + +# core.info("All PR authors and committers are allowed."); +# */ From 9134feb645546ae0fc88da7486e4653c0a61c407 Mon Sep 17 00:00:00 2001 From: Abdurrahman Saber Date: Wed, 3 Dec 2025 11:06:08 +0400 Subject: [PATCH 4/6] [IMP] ensan_sale_management: put sms in queue instead of sending immediately --- odex25_donation/ensan_sale_management/models/sale_order.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/odex25_donation/ensan_sale_management/models/sale_order.py b/odex25_donation/ensan_sale_management/models/sale_order.py index 030715a0c..a16ccd457 100644 --- a/odex25_donation/ensan_sale_management/models/sale_order.py +++ b/odex25_donation/ensan_sale_management/models/sale_order.py @@ -110,14 +110,14 @@ class SaleOrder(models.Model): if rec.order_mobile_number: rec._message_sms_with_template( template=sms_template_id, - put_in_queue=False, + put_in_queue=True, partner_ids=rec.partner_id.ids, author_id=bot ) for donator in rec.donators_ids: donator._message_sms_with_template( template=donar_sms_template_id, - put_in_queue=False, + put_in_queue=True, sms_numbers=[donator.donator_mobile_number], author_id=bot ) From 7222104a81adda22740a4ea22f941ccae1e88138 Mon Sep 17 00:00:00 2001 From: Abdurrahman Saber Date: Wed, 3 Dec 2025 12:12:07 +0400 Subject: [PATCH 5/6] [IMP] ensan_sale_management: send confirmation message when the order is auto locked --- odex25_donation/ensan_sale_management/models/sale_order.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/odex25_donation/ensan_sale_management/models/sale_order.py b/odex25_donation/ensan_sale_management/models/sale_order.py index a16ccd457..52a126884 100644 --- a/odex25_donation/ensan_sale_management/models/sale_order.py +++ b/odex25_donation/ensan_sale_management/models/sale_order.py @@ -100,13 +100,14 @@ class SaleOrder(models.Model): }) def action_confirm(self): + old_state = self.state res = super().action_confirm() bot = self.env.ref('base.partner_root').id if res: sms_template_id = self.env.ref('ensan_sale_management.sms_template_data_donation') donar_sms_template_id = self.env.ref('ensan_sale_management.sms_template_donors_data_donation') for rec in self: - if rec.state == 'sale' and not self._context.get('skip_donation_sms'): + if old_state in ('draft', 'sent') and rec.state in ('sale', 'done') and not self._context.get('skip_donation_sms'): if rec.order_mobile_number: rec._message_sms_with_template( template=sms_template_id, From 511655de43c3278ec7a885877b15c934be905483 Mon Sep 17 00:00:00 2001 From: Abdurrahman Saber Date: Wed, 3 Dec 2025 18:42:22 +0400 Subject: [PATCH 6/6] [IMP] ensan_sale_management: use payment state instead of reconcile --- odex25_donation/ensan_sale_management/models/product.py | 2 +- odex25_donation/ensan_sale_management/models/sale_order.py | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/odex25_donation/ensan_sale_management/models/product.py b/odex25_donation/ensan_sale_management/models/product.py index 9829e813f..7cea4dd53 100644 --- a/odex25_donation/ensan_sale_management/models/product.py +++ b/odex25_donation/ensan_sale_management/models/product.py @@ -170,7 +170,7 @@ class ProductTemplate_Inherit(models.Model): line_ids = self.env['account.move.line'].search([ ('product_id.product_tmpl_id', 'in', products.ids), - ('reconciled', '=', True), + ('move_id.payment_state', '=', 'paid'), ('move_id.move_type', '=', 'out_invoice') ]) diff --git a/odex25_donation/ensan_sale_management/models/sale_order.py b/odex25_donation/ensan_sale_management/models/sale_order.py index 52a126884..6d171f04d 100644 --- a/odex25_donation/ensan_sale_management/models/sale_order.py +++ b/odex25_donation/ensan_sale_management/models/sale_order.py @@ -29,11 +29,10 @@ class SaleOrder(models.Model): def write(self, vals): if 'order_mobile_number' in vals and not self._context.get('skip_partner_mobile_sync'): vals['order_mobile_number'] = self.phone_format(vals['order_mobile_number']) - orders = self.search([('state', '=', 'sale'), ('id', 'not in', self.ids)]) - numbers = set(orders.mapped('order_mobile_number')) - if vals['order_mobile_number'] in numbers: + old_orders = self.search([('state', '=', 'sale'), ('id', 'not in', self.ids), ('order_mobile_number', '=', vals['order_mobile_number'])], limit=1, order='id desc') + if old_orders: vals['donor_type'] = 'returning' - orders.filtered(lambda o: o.order_mobile_number == vals['order_mobile_number']).write({'donor_type': 'returning'}) + old_orders.write({'donor_type': 'returning'}) else: vals['donor_type'] = 'new' partner_sudo = self.env['res.partner'].sudo()