CreateContractDialog.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <template>
  2. <q-dialog ref="dialogRef" @hide="onDialogHide">
  3. <q-card
  4. class="q-dialog-plugin overflow-hidden"
  5. style="width: 100%; max-width: 1100px"
  6. >
  7. <DefaultDialogHeader
  8. :title="() => 'Criar novo contrato'"
  9. @close="onDialogCancel"
  10. />
  11. <q-card-section>
  12. <div class="text-body2 q-mb-sm">Dados da Unidade</div>
  13. <div class="row q-col-gutter-x-sm">
  14. <DefaultInput
  15. :model-value="unitData.id"
  16. label="ID"
  17. color="secondary"
  18. label-color="secondary"
  19. class="col-md-3 col-12"
  20. disable
  21. />
  22. <DefaultInput
  23. :model-value="unitData.franchisee_name"
  24. label="Nome do Franqueado"
  25. color="secondary"
  26. label-color="secondary"
  27. class="col-md-3 col-12"
  28. disable
  29. />
  30. <DefaultInput
  31. :model-value="unitData.franchisee_document"
  32. label="CPF/CNH"
  33. color="secondary"
  34. label-color="secondary"
  35. class="col-md-3 col-12"
  36. disable
  37. />
  38. <DefaultInput
  39. :model-value="unitData.franchisee_birthday"
  40. label="Data de Nascimento"
  41. color="secondary"
  42. label-color="secondary"
  43. class="col-md-3 col-12"
  44. disable
  45. />
  46. </div>
  47. </q-card-section>
  48. <q-card-section>
  49. <div class="text-body2 q-mb-sm">Definir Valores e TBR</div>
  50. <div class="row q-col-gutter-sm">
  51. <DefaultInputDatePicker
  52. v-model:untreated-date="contractForm.start_date"
  53. label="Data de Início"
  54. color="secondary"
  55. label-color="secondary"
  56. class="col-md-3 col-12"
  57. />
  58. <DefaultInputDatePicker
  59. v-model:untreated-date="contractForm.end_date"
  60. label="Data de Fim"
  61. color="secondary"
  62. label-color="secondary"
  63. class="col-md-3 col-12"
  64. />
  65. <DefaultCurrencyInput
  66. v-model="contractForm.tbr_fixed_value"
  67. label="TBR $"
  68. color="secondary"
  69. label-color="secondary"
  70. class="col-md-3 col-12"
  71. />
  72. <DefaultInputDatePicker
  73. v-model:untreated-date="contractForm.invoice_due_date"
  74. label="Vencimento Boleto"
  75. color="secondary"
  76. label-color="secondary"
  77. class="col-md-3 col-12"
  78. />
  79. <DefaultSelect
  80. v-model="contractForm.inhabitant_classification_id"
  81. label="Faixa de Habitante"
  82. color="secondary"
  83. label-color="secondary"
  84. :options="inhabitantOptions"
  85. emit-value
  86. map-options
  87. use-input
  88. fill-input
  89. input-debounce="0"
  90. class="col-md-3 col-12"
  91. />
  92. <DefaultInput
  93. v-model="contractForm.tax_base_royalts"
  94. label="Taxa Base Royalties"
  95. color="secondary"
  96. label-color="secondary"
  97. type="number"
  98. class="col-md-3 col-12"
  99. >
  100. <template #append>
  101. <span class="text-secondary">%</span>
  102. </template>
  103. </DefaultInput>
  104. <DefaultInput
  105. v-model="contractForm.tax_base_fnm"
  106. label="Taxa Base FMN"
  107. color="secondary"
  108. label-color="secondary"
  109. type="number"
  110. class="col-md-3 col-12"
  111. >
  112. <template #append>
  113. <span class="text-secondary">%</span>
  114. </template>
  115. </DefaultInput>
  116. <DefaultInput
  117. v-model="contractForm.tax_base_maintenance"
  118. label="Taxa Base Manutenção"
  119. color="secondary"
  120. label-color="secondary"
  121. type="number"
  122. class="col-md-3 col-12"
  123. >
  124. <template #append>
  125. <span class="text-secondary">%</span>
  126. </template>
  127. </DefaultInput>
  128. </div>
  129. </q-card-section>
  130. <q-card-actions align="right">
  131. <q-btn
  132. outline
  133. color="primary"
  134. label="Cancelar"
  135. @click="onDialogCancel"
  136. />
  137. <q-btn
  138. color="primary"
  139. label="Salvar"
  140. :loading="saving"
  141. @click="save"
  142. />
  143. </q-card-actions>
  144. </q-card>
  145. </q-dialog>
  146. </template>
  147. <script setup>
  148. import { ref, reactive, onMounted } from "vue";
  149. import { useDialogPluginComponent } from "quasar";
  150. import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
  151. import DefaultInput from "src/components/defaults/DefaultInput.vue";
  152. import DefaultInputDatePicker from "src/components/defaults/DefaultInputDatePicker.vue";
  153. import DefaultCurrencyInput from "src/components/defaults/DefaultCurrencyInput.vue";
  154. import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
  155. import { getUnit } from "src/api/unit";
  156. import { getLatestTbr } from "src/api/tbr";
  157. import { getInhabitantClassificationsForSelect } from "src/api/inhabitant_classification";
  158. import { createFranchiseeContract } from "src/api/franchisee_contract";
  159. defineEmits([...useDialogPluginComponent.emits]);
  160. const props = defineProps({
  161. unitId: {
  162. type: Number,
  163. required: true,
  164. },
  165. });
  166. const { dialogRef, onDialogHide, onDialogCancel, onDialogOK } =
  167. useDialogPluginComponent();
  168. const saving = ref(false);
  169. const inhabitantOptions = ref([]);
  170. const unitData = reactive({
  171. id: null,
  172. franchisee_name: null,
  173. franchisee_document: null,
  174. franchisee_birthday: null,
  175. });
  176. const contractForm = reactive({
  177. start_date: null,
  178. end_date: null,
  179. tbr_fixed_value: null,
  180. invoice_due_date: null,
  181. inhabitant_classification_id: null,
  182. tax_base_royalts: null,
  183. tax_base_fnm: null,
  184. tax_base_maintenance: null,
  185. });
  186. async function loadData() {
  187. const [unit, latestTbr, classifications] = await Promise.all([
  188. getUnit(props.unitId),
  189. getLatestTbr(),
  190. getInhabitantClassificationsForSelect(),
  191. ]);
  192. unitData.id = unit.id;
  193. unitData.franchisee_name = unit.name_responsible;
  194. const firstPartner = unit.partners?.[0];
  195. if (firstPartner) {
  196. unitData.franchisee_document = firstPartner.cpf;
  197. unitData.franchisee_birthday = firstPartner.birth_date;
  198. }
  199. if (latestTbr) {
  200. contractForm.tbr_fixed_value = parseFloat(latestTbr.tbr_value);
  201. contractForm.tax_base_royalts = parseFloat(
  202. (latestTbr.royalties_percentage * 100).toFixed(4),
  203. );
  204. contractForm.tax_base_fnm = parseFloat(
  205. (latestTbr.fnm_percentage * 100).toFixed(4),
  206. );
  207. contractForm.tax_base_maintenance = parseFloat(
  208. (latestTbr.maintenance_percentage * 100).toFixed(4),
  209. );
  210. }
  211. inhabitantOptions.value = classifications.map((c) => ({
  212. label: `${c.description} (${c.acronym})`,
  213. value: c.id,
  214. }));
  215. }
  216. async function save() {
  217. saving.value = true;
  218. try {
  219. await createFranchiseeContract({
  220. unit_id: props.unitId,
  221. start_date: contractForm.start_date,
  222. end_date: contractForm.end_date,
  223. tbr_fixed_value: contractForm.tbr_fixed_value,
  224. invoice_due_date: contractForm.invoice_due_date,
  225. inhabitant_classification_id: contractForm.inhabitant_classification_id,
  226. tbr_fixed_value_percentage:
  227. contractForm.tax_base_royalts != null
  228. ? contractForm.tax_base_royalts / 100
  229. : null,
  230. marketing_fund_percentage:
  231. contractForm.tax_base_fnm != null
  232. ? contractForm.tax_base_fnm / 100
  233. : null,
  234. maintance_tax_percentage:
  235. contractForm.tax_base_maintenance != null
  236. ? contractForm.tax_base_maintenance / 100
  237. : null,
  238. });
  239. onDialogOK();
  240. } catch (error) {
  241. console.error(error);
  242. } finally {
  243. saving.value = false;
  244. }
  245. }
  246. onMounted(loadData);
  247. </script>